Mercurial > emacs
changeset 10404:631f1dac6f7a
Global polishing, some bugs corrected, dynamic allocation used instead
of fixed length static buffers in many places.
* etags.c (FILEPOS, GET_CHARNO, GET_FILEPOS, max, LINENO): Deleted.
(append_to_tagfile, typedefs, typedefs_and_cplusplus,
constantypedefs, update, vgrind_style, no_warnings,
cxref_style, cplusplus, noindentypedefs): Were int, now logical.
(permit_duplicates): Was a var, now a #define.
(filename_lb): Was global, now local to main.
(main): Open the tag file when in cxref mode.
Use a BUFSIZ size buffer for making the shell commands.
Look at the return value from the system routine.
Exit when cannot open the tag file.
(process_file): Open the file and pass the FILE* to find_entries.
(find_entries): Now void, because does not open the file itself.
(pfnote): Recovering from lack of memory does not work. Removed.
Use savenstr and simplify the code.
(free_tree): Only free the name space if node is named.
(structtag): Now a pointer, not a fixed length array of chars.
(consider_token): Don't take a token as argument. Use savenstr
when saving a tag in structtag. Callers changed.
(TOKEN): Structure changed. Now used only in C_entries.
(TOKEN_SAVED_P, SAVE_TOKEN, RESTORE_TOKEN): Deleted.
(C_entries): nameb and savenameb deleted. Use dinamic allocation.
(pfcnt): Deleted. Users updated.
(getit, Asm_labels, Pascal_functions, L_getit, get_scheme,
TEX_getit, prolog_getit): Use dinamic allocation for storing
the tag instead of a fixed size buffer.
author | Francesco Potortì <pot@gnu.org> |
---|---|
date | Thu, 12 Jan 1995 17:05:37 +0000 |
parents | c0e27466fb3f |
children | 609f34c0c7bc |
files | lib-src/etags.c |
diffstat | 1 files changed, 268 insertions(+), 396 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/etags.c Thu Jan 12 06:59:56 1995 +0000 +++ b/lib-src/etags.c Thu Jan 12 17:05:37 1995 +0000 @@ -31,7 +31,7 @@ * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. */ -char pot_etags_version[] = "@(#) pot revision number is 11.14"; +char pot_etags_version[] = "@(#) pot revision number is 11.15"; #ifdef MSDOS #include <fcntl.h> @@ -71,7 +71,8 @@ #include <regex.h> #endif /* ETAGS_REGEXPS */ -extern char *getenv (); +#define TRUE 1 +#define FALSE 0 /* Define CTAGS to make the program "ctags" compatible with the usual one. Let it undefined to make the program "etags", which makes emacs-style @@ -92,71 +93,29 @@ #define BAD 1 #endif -/* - * The FILEPOS abstract type, which represents a position in a file, - * plus the following accessor functions: - * - * long GET_CHARNO (pos) - * returns absolute char number. - * void SET_FILEPOS (pos, fp, charno) - * FILE *fp; long charno; - * sets `pos' from the current file - * position of `fp' and from `charno', - * which must be the absolute character - * number corresponding to the current - * position of `fp'. - * - * The `pos' parameter is an lvalue expression of type FILEPOS. - * Parameters to the accessor functions are evaluated 0 or more times, - * and so must have no side effects. - * - * FILEPOS objects can also be assigned and passed to and from - * functions in the normal C manner. - * - * Implementation notes: the `+ 0' is to enforce rvalue-ness. - */ - -#ifndef DEBUG -#define DEBUG FALSE - - /* real implementation */ -typedef long FILEPOS; -#define GET_CHARNO(pos) ((pos) + 0) -#define SET_FILEPOS(pos,fp,cno) ((void) ((pos) = (cno))) - -#else -#undef DEBUG -#define DEBUG TRUE - - /* debugging implementation */ -typedef struct -{ - long charno; -} FILEPOS; - -#define GET_CHARNO(pos) ((pos).charno + 0) -#define SET_FILEPOS(pos,fp,cno) \ - ((void) ((pos).charno = (cno), \ - (cno) != ftell (fp) ? (error ("SET_FILEPOS inconsistency"), 0) \ - : 0)) -#endif +/* C extensions. */ +#define C_PLPL 0x00001 /* C++ */ +#define C_STAR 0x00003 /* C* */ +#define YACC 0x10000 /* yacc file */ #define streq(s,t) (strcmp (s, t) == 0) #define strneq(s,t,n) (strncmp (s, t, n) == 0) -#define TRUE 1 -#define FALSE 0 - #define iswhite(arg) (_wht[arg]) /* T if char is white */ #define begtoken(arg) (_btk[arg]) /* T if char can start token */ #define intoken(arg) (_itk[arg]) /* T if char can be in token */ #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */ -#define max(I1,I2) ((I1) > (I2) ? (I1) : (I2)) +/* + * xnew -- allocate storage + * + * SYNOPSIS: Type *xnew (int n, Type); + */ +#define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) typedef int logical; -struct nd_st +typedef struct nd_st { /* sorting structure */ char *name; /* function or type name */ char *file; /* file name */ @@ -167,15 +126,9 @@ long cno; /* character number line starts on */ char *pat; /* search pattern */ struct nd_st *left, *right; /* left and right sons */ -}; - -typedef struct nd_st NODE; - -/* boolean "functions" (see init) */ -logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; - -char *cwd; /* current working directory */ -char *tagfiledir; /* directory of tagfile */ +} NODE; + +extern char *getenv (); char *concat (); char *savenstr (), *savestr (); @@ -225,7 +178,7 @@ void add_node (); void error (); void fatal (), pfatal (); -logical find_entries (); +void find_entries (); void free_tree (); void getit (); void init (); @@ -235,52 +188,45 @@ void put_entries (); void takeprec (); -/* - * MACRO - * xnew -- allocate storage - * - * SYNOPSIS - * Type *xnew (int n, Type); - */ -#define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) + +char searchar = '/'; /* use /.../ searches */ + +int lineno; /* line number of current line */ +long charno; /* current character number */ + +long linecharno; /* charno of start of line; not used by C, + but by every other language. */ + +char *curfile; /* current input file name */ +char *tagfile; /* output file */ +char *progname; /* name this program was invoked with */ +char *cwd; /* current working directory */ +char *tagfiledir; /* directory of tagfile */ + +FILE *tagf; /* ioptr for tags file */ +NODE *head; /* the head of the binary tree of tags */ /* - * Symbol table types. + * A `struct linebuffer' is a structure which holds a line of text. + * `readline' reads a line from a stream into a linebuffer and works + * regardless of the length of the line. */ -enum sym_type -{ - st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec -}; - - - -typedef int LINENO; - -typedef struct +struct linebuffer { - char *p; - int len; - LINENO lineno; - logical named; -} TOKEN; - -/* C extensions. - */ -#define C_PLPL 0x00001 /* C++ */ -#define C_STAR 0x00003 /* C* */ -#define YACC 0x10000 /* yacc file */ - -char searchar = '/'; /* use /.../ searches */ - -LINENO lineno; /* line number of current line */ -long charno; /* current character number */ - -long linecharno; /* charno of start of line; not used by C, but - * by every other language. - */ - -char *curfile, /* current input file name */ - *tagfile, /* output file */ + long size; + char *buffer; +}; + +struct linebuffer lb; /* the current line */ +struct +{ + long linepos; + struct linebuffer lb; /* used by C_entries instead of lb */ +} lbs[2]; + +/* boolean "functions" (see init) */ +logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; +char *white = " \f\t\n\013", /* white chars */ *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ /* token starting chars */ @@ -288,24 +234,22 @@ /* valid in-token chars */ *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; -int append_to_tagfile; /* -a: append to tags */ -/* The following three default to 1 for etags, but to 0 for ctags. */ -int typedefs; /* -t: create tags for typedefs */ -int typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ +logical append_to_tagfile; /* -a: append to tags */ +/* The following three default to TRUE for etags, but to FALSE for ctags. */ +logical typedefs; /* -t: create tags for typedefs */ +logical typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ /* 0 struct/enum/union decls, and C++ */ /* member functions. */ -int constantypedefs; /* -d: create tags for C #define and enum */ +logical constantypedefs; /* -d: create tags for C #define and enum */ /* constants. Enum consts not implemented. */ /* -D: opposite of -d. Default under ctags. */ -int update; /* -u: update tags */ -int vgrind_style; /* -v: create vgrind style index output */ -int no_warnings; /* -w: suppress warnings */ -int cxref_style; /* -x: create cxref style output */ -int cplusplus; /* .[hc] means C++, not C */ -int noindentypedefs; /* -S: ignore indentation in C */ - -/* Name this program was invoked with. */ -char *progname; +logical update; /* -u: update tags */ +logical vgrind_style; /* -v: create vgrind style index output */ +logical no_warnings; /* -w: suppress warnings */ +logical cxref_style; /* -x: create cxref style output */ +logical cplusplus; /* .[hc] means C++, not C */ +logical noindentypedefs; /* -S: ignore indentation in C */ +#define permit_duplicates TRUE /* allow duplicate tags */ struct option longopts[] = { @@ -332,29 +276,6 @@ { 0 } }; -FILE *tagf; /* ioptr for tags file */ -NODE *head; /* the head of the binary tree of tags */ -logical permit_duplicates = TRUE; /* allow duplicate tags */ - -/* - * A `struct linebuffer' is a structure which holds a line of text. - * `readline' reads a line from a stream into a linebuffer and works - * regardless of the length of the line. - */ -struct linebuffer -{ - long size; - char *buffer; -}; - -struct linebuffer lb; /* the current line */ -struct linebuffer filename_lb; /* used to read in filenames */ -struct -{ - FILEPOS linepos; - struct linebuffer lb; /* used by C_entries instead of lb */ -} lbs[2]; - #ifdef ETAGS_REGEXPS /* Structure defining a regular expression. Elements are the compiled pattern, and the name string. */ @@ -754,13 +675,13 @@ int argc; char *argv[]; { - char cmd[100]; int i; unsigned int nincluded_files = 0; char **included_files = xnew (argc, char *); char *this_file; ARGUMENT *argbuffer; int current_arg = 0, file_count = 0; + struct linebuffer filename_lb; #ifdef VMS logical got_err; #endif @@ -785,7 +706,7 @@ * Also default is to find macro constants. */ if (!CTAGS) - typedefs = typedefs_and_cplusplus = constantypedefs = 1; + typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; while (1) { @@ -812,16 +733,16 @@ /* Common options. */ case 'a': - append_to_tagfile++; + append_to_tagfile = TRUE; break; case 'C': - cplusplus = 1; + cplusplus = TRUE; break; case 'd': - constantypedefs = 1; + constantypedefs = TRUE; break; case 'D': - constantypedefs = 0; + constantypedefs = FALSE; break; case 'f': /* for compatibility with old makefiles */ case 'o': @@ -856,7 +777,7 @@ break; #endif /* ETAGS_REGEXPS */ case 'S': - noindentypedefs++; + noindentypedefs = TRUE; break; case 'V': print_version (); @@ -866,11 +787,10 @@ print_help (); break; case 't': - typedefs++; + typedefs = TRUE; break; case 'T': - typedefs++; - typedefs_and_cplusplus++; + typedefs = typedefs_and_cplusplus = TRUE; break; #if (!CTAGS) /* Etags options */ @@ -883,16 +803,16 @@ searchar = '?'; break; case 'u': - update++; + update = TRUE; break; case 'v': - vgrind_style++; + vgrind_style = TRUE; /*FALLTHRU*/ case 'x': - cxref_style++; + cxref_style = TRUE; break; case 'w': - no_warnings++; + no_warnings = TRUE; break; #endif /* CTAGS */ default: @@ -989,8 +909,6 @@ { while (!feof (stdin)) { - /* Use readline_internal so that regexp matching */ - /* is not done on filenames. */ (void) readline_internal (&filename_lb, stdin); if (strlen (filename_lb.buffer) > 0) process_file (filename_lb.buffer); @@ -1010,40 +928,48 @@ while (nincluded_files-- > 0) fprintf (tagf, "\f\n%s,include\n", *included_files++); - (void) fclose (tagf); + fclose (tagf); exit (GOOD); } + /* If CTAGS, we are here. process_file did not write the tags yet, + because we want them ordered. Let's do it now. */ if (cxref_style) { + tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); + if (tagf == NULL) + pfatal (tagfile); put_entries (head); exit (GOOD); } + if (update) { + char cmd[BUFSIZ]; for (i = 0; i < current_arg; ++i) { - if (argbuffer[i].arg_type == at_language) + if (argbuffer[i].arg_type != at_filename) continue; sprintf (cmd, "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", tagfile, argbuffer[i].what, tagfile); - (void) system (cmd); + if (system (cmd) != GOOD) + fatal ("failed to execute shell command"); } - append_to_tagfile++; + append_to_tagfile = TRUE; } + tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); if (tagf == NULL) - { - perror (tagfile); - exit (GOOD); - } + pfatal (tagfile); put_entries (head); - (void) fclose (tagf); + fclose (tagf); + if (update) { + char cmd[BUFSIZ]; sprintf (cmd, "sort %s -o %s", tagfile, tagfile); - (void) system (cmd); + exit (system (cmd)); } exit (GOOD); } @@ -1080,6 +1006,7 @@ char *file; { struct stat stat_buf; + FILE *inf; if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode)) { @@ -1091,10 +1018,15 @@ fprintf (stderr, "Skipping inclusion of %s in self.\n", file); return; } - if (!find_entries (file)) + inf = fopen (file, "r"); + if (inf == NULL) { + perror (file); return; } + + find_entries (file, inf); + if (!CTAGS) { char *filename; @@ -1151,22 +1083,16 @@ * This routine opens the specified file and calls the function * which finds the function and type definitions. */ -logical -find_entries (file) +void +find_entries (file, inf) char *file; + FILE *inf; { - FILE *inf; char *cp; struct lang_entry *lang; NODE *old_last_node; extern NODE *last_node; - inf = fopen (file, "r"); - if (inf == NULL) - { - perror (file); - return FALSE; - } curfile = savestr (file); cp = etags_strrchr (file, '.'); @@ -1175,7 +1101,7 @@ { lang_func (inf); fclose (inf); - return TRUE; + return; } if (cp) @@ -1187,7 +1113,7 @@ { lang->function (inf); fclose (inf); - return TRUE; + return; } } } @@ -1200,7 +1126,6 @@ if (old_last_node == last_node) default_C_entries (inf); fclose (inf); - return TRUE; } /* Record a tag. */ @@ -1208,48 +1133,33 @@ void pfnote (name, is_func, named, linestart, linelen, lno, cno) char *name; /* tag name */ - logical is_func; /* function or type name? */ - logical named; /* tag different from text of definition? */ - char *linestart; - int linelen; - int lno; - long cno; + logical is_func; /* tag is a function */ + logical named; /* tag different from text of definition */ + char *linestart; /* start of the line where tag is */ + int linelen; /* length of the line where tag is */ + int lno; /* line number */ + long cno; /* character number */ { + register NODE *np = xnew (1, NODE); register char *fp; - register NODE *np; - char tem[51]; - char c; - - np = xnew (1, NODE); - if (np == NULL) - { - if (CTAGS) - { - /* It's okay to output early in etags -- it only disrupts the - * character count of the tag entries, which is no longer used - * by tags.el anyway. - */ - error ("too many entries to sort", 0); - } - put_entries (head); - free_tree (head); - head = NULL; - np = xnew (1, NODE); - } + /* If ctags mode, change name "main" to M<thisfilename>. */ if (CTAGS && !cxref_style && streq (name, "main")) { fp = etags_strrchr (curfile, '/'); - name = concat ("M", fp == 0 ? curfile : fp + 1, ""); - fp = etags_strrchr (name, '.'); + np->name = concat ("M", fp == 0 ? curfile : fp + 1, ""); + fp = etags_strrchr (np->name, '.'); if (fp && fp[1] != '\0' && fp[2] == '\0') - *fp = 0; - named = TRUE; + fp[0] = 0; + np->named = TRUE; } - np->name = savestr (name); + else + { + np->name = name; + np->named = named; + } np->file = curfile; np->is_func = is_func; - np->named = named; np->lno = lno; /* Our char numbers are 0-base, because of C language tradition? ctags compatibility? old versions compatibility? I don't know. @@ -1257,22 +1167,8 @@ of the difference. If we wanted to have 1-based numbers, we would uncomment the +1 below. */ np->cno = cno /* + 1 */ ; - np->left = np->right = 0; - if (!CTAGS) - { - c = linestart[linelen]; - linestart[linelen] = 0; - } - else if (cxref_style == 0) - { - sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart); - linestart = tem; - } - np->pat = savestr (linestart); - if (!CTAGS) - { - linestart[linelen] = c; - } + np->left = np->right = NULL; + np->pat = savenstr (linestart, ((CTAGS && !cxref_style) ? 50 : linelen)); add_node (np, &head); } @@ -1289,7 +1185,8 @@ { register NODE *node_right = node->right; free_tree (node->left); - free (node->name); + if (node->named) + free (node->name); free (node->pat); free ((char *) node); node = node_right; @@ -1484,6 +1381,10 @@ /* * The C symbol tables. */ +enum sym_type +{ + st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec +}; /* Feed stuff between (but not including) %[ and %] lines to: gperf -c -k1,3 -o -p -r -t @@ -1680,7 +1581,7 @@ * struct tag, and structtype is the type of the preceding struct-like * keyword. */ -char structtag[BUFSIZ]; +char *structtag = "<uninited>"; enum sym_type structtype; /* @@ -1729,14 +1630,15 @@ */ logical -consider_token (c, tokp, c_ext, cblev, is_func) +consider_token (str, len, c, c_ext, cblev, is_func) + register char *str; /* IN: token pointer */ + register int len; /* IN: token length */ register char c; /* IN: first char after the token */ - register TOKEN *tokp; /* IN: token pointer */ int c_ext; /* IN: C extensions mask */ int cblev; /* IN: curly brace level */ logical *is_func; /* OUT: function found */ { - enum sym_type toktype = C_symtype(tokp->p, tokp->len, c_ext); + enum sym_type toktype = C_symtype (str, len, c_ext); /* * Advance the definedef state machine. @@ -1840,15 +1742,12 @@ } if (structdef == skeyseen) { + /* Save the tag for struct/union/class, for functions that may be + defined inside. */ if (structtype == st_C_struct) - { - strncpy (structtag, tokp->p, tokp->len); - structtag[tokp->len] = '\0'; /* for struct/union/class */ - } + structtag = savenstr (str, len); else - { - structtag[0] = '\0'; /* for enum (why is it treated differently?) */ - } + structtag = "<enum>"; structdef = stagseen; return TRUE; } @@ -1862,16 +1761,16 @@ /* Detect GNU macros. */ if (definedef == dnone) - if (strneq (tokp->p, "DEFUN", 5) /* Used in emacs */ + if (strneq (str, "DEFUN", 5) /* Used in emacs */ #if FALSE These are defined inside C functions, so currently they are not met anyway. - || strneq (tokp->p, "EXFUN", 5) /* Used in glibc */ - || strneq (tokp->p, "DEFVAR_", 7) /* Used in emacs */ + || strneq (str, "EXFUN", 5) /* Used in glibc */ + || strneq (str, "DEFVAR_", 7) /* Used in emacs */ #endif - || strneq (tokp->p, "SYSCALL", 7) /* Used in glibc (mach) */ - || strneq (tokp->p, "ENTRY", 5) /* Used in glibc */ - || strneq (tokp->p, "PSEUDO", 6)) /* Used in glibc */ + || strneq (str, "SYSCALL", 7) /* Used in glibc (mach) */ + || strneq (str, "ENTRY", 5) /* Used in glibc */ + || strneq (str, "PSEUDO", 6)) /* Used in glibc */ { next_token_is_func = TRUE; @@ -1910,6 +1809,16 @@ * struct/union/enum definitions in C syntax and adds them * to the list. */ +typedef struct +{ + char *str; + logical named; + int linelen; + int lineno; +} TOKEN; + +#define current_lb_is_new (newndx == curndx) +#define switch_line_buffers() (curndx = 1 - curndx) #define curlb (lbs[curndx].lb) #define othlb (lbs[1-curndx].lb) @@ -1918,18 +1827,9 @@ #define othlinepos (lbs[1-curndx].linepos) #define newlinepos (lbs[newndx].linepos) -/* Save and restore token state. This is used when preprocessor defines - are handled, to avoid disturbing active function/typedef/struct states. */ -#define TOKEN_SAVED_P (savetok.lineno > 0) -#define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \ - savetok.len = toklen, strcpy(savenameb, nameb)) -#define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \ - toklen = tok.len, strcpy(nameb, savenameb), \ - savetok.lineno = 0) - #define CNL_SAVE_DEFINEDEF \ do { \ - SET_FILEPOS (curlinepos, inf, charno); \ + curlinepos = charno; \ lineno++; \ charno += readline (&curlb, inf); \ lp = curlb.buffer; \ @@ -1940,15 +1840,18 @@ #define CNL \ do { \ CNL_SAVE_DEFINEDEF; \ - if (TOKEN_SAVED_P) \ - RESTORE_TOKEN; \ + if (token_saved) \ + { \ + tok = savetok; \ + token_saved = FALSE; \ + } \ definedef = dnone; \ } while (0) -#define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \ - newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos)) -#define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (nameb, isfun, tok.named, \ - othlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (othlinepos)) +#define make_tag_from_new_lb(isfun) pfnote (tok.str, isfun, tok.named, \ + newlb.buffer, tok.linelen, tok.lineno, newlinepos) +#define make_tag_from_oth_lb(isfun) pfnote (tok.str, isfun, tok.named, \ + othlb.buffer, tok.linelen, tok.lineno, othlinepos) void C_entries (c_ext, inf) @@ -1958,18 +1861,16 @@ register char c; /* latest char read; '\0' for end of line */ register char *lp; /* pointer one beyond the character `c' */ int curndx, newndx; /* indices for current and new lb */ - TOKEN tok; /* latest token read for funcdef & structdef */ - char nameb[BUFSIZ]; /* latest token name for funcdef & structdef */ - register int tokoff; /* offset in line of start of latest token */ - register int toklen; /* length of latest token */ + TOKEN tok; /* latest token read */ + register int tokoff; /* offset in line of start of current token */ + register int toklen; /* length of current token */ int cblev; /* current curly brace level */ int parlev; /* current parenthesis level */ logical incomm, inquote, inchar, quotednl, midtoken; logical cplpl; - TOKEN savetok; /* saved token during preprocessor handling */ - char savenameb[BUFSIZ]; /* ouch! */ - - savetok.lineno = 0; + logical token_saved; /* token saved */ + TOKEN savetok; /* token saved during preprocessor handling */ + curndx = newndx = 0; lineno = 0; charno = 0; @@ -1977,7 +1878,7 @@ *lp = 0; definedef = dnone; funcdef = fnone; typdef = tnone; structdef = snone; - next_token_is_func = yacc_rules = FALSE; + next_token_is_func = yacc_rules = token_saved = FALSE; midtoken = inquote = inchar = incomm = quotednl = FALSE; cblev = 0; parlev = 0; @@ -2143,45 +2044,47 @@ { logical is_func = FALSE; - tok.lineno = lineno; - tok.p = newlb.buffer + tokoff; - tok.len = toklen; - tok.named = FALSE; if (yacc_rules - || consider_token (c, &tok, c_ext, cblev, &is_func)) + || consider_token (newlb.buffer + tokoff, toklen, + c, c_ext, cblev, &is_func)) { if (structdef == sinbody && definedef == dnone && is_func) /* function defined in C++ class body */ { - sprintf (nameb, "%s::%.*s", - ((structtag[0] == '\0') - ? "_anonymous_" : structtag), - tok.len, tok.p); + char *cp = newlb.buffer + tokoff + toklen; + char c = *cp; + *cp = '\0'; + tok.str = concat (structtag, "::", + newlb.buffer + tokoff); + *cp = c; tok.named = TRUE; } else { - sprintf (nameb, "%.*s", tok.len, tok.p); + tok.str = savenstr (newlb.buffer+tokoff, toklen); + if (structdef == stagseen + || typdef == tend + || (is_func + && definedef == dignorerest)) /* macro */ + tok.named = TRUE; + else + tok.named = FALSE; } - - if (structdef == stagseen - || typdef == tend - || (is_func - && definedef == dignorerest)) /* macro */ - tok.named = TRUE; + tok.lineno = lineno; + tok.linelen = tokoff + toklen + 1; if (definedef == dnone && (funcdef == ftagseen || structdef == stagseen || typdef == tend)) { - if (newndx == curndx) - curndx = 1 - curndx; /* switch line buffers */ + if (current_lb_is_new) + switch_line_buffers (); } else - MAKE_TAG_FROM_NEW_LB (is_func); + make_tag_from_new_lb (is_func); } midtoken = FALSE; } @@ -2203,7 +2106,7 @@ funcdef = finlist; continue; case flistseen: - MAKE_TAG_FROM_OTH_LB (TRUE); + make_tag_from_oth_lb (TRUE); funcdef = fignore; break; case ftagseen: @@ -2220,7 +2123,8 @@ if (c == 'd' && strneq (lp, "efine", 5) && iswhite (*(lp + 5))) { - SAVE_TOKEN; + savetok = tok; + token_saved = TRUE; definedef = ddefineseen; lp += 6; } @@ -2254,7 +2158,7 @@ case ftagseen: if (yacc_rules) { - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); funcdef = fignore; } break; @@ -2270,7 +2174,7 @@ switch (typdef) { case tend: - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); /* FALLTHRU */ default: typdef = tnone; @@ -2294,7 +2198,7 @@ if (cblev == 0 && typdef == tend) { typdef = tignore; - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); break; } if (funcdef != finlist && funcdef != fignore) @@ -2318,7 +2222,7 @@ if (*lp != '*') { typdef = tignore; - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); } break; } /* switch (typdef) */ @@ -2347,7 +2251,7 @@ if (cblev == 0 && typdef == tend) { typdef = tignore; - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); } } else if (parlev < 0) /* can happen due to ill-conceived #if's. */ @@ -2361,19 +2265,19 @@ switch (structdef) { case skeyseen: /* unnamed struct */ - structtag[0] = '\0'; + structtag = "_anonymous_"; structdef = sinbody; break; case stagseen: case scolonseen: /* named struct */ structdef = sinbody; - MAKE_TAG_FROM_OTH_LB (FALSE); + make_tag_from_oth_lb (FALSE); break; } switch (funcdef) { case flistseen: - MAKE_TAG_FROM_OTH_LB (TRUE); + make_tag_from_oth_lb (TRUE); /* FALLTHRU */ case fignore: funcdef = fnone; @@ -2405,8 +2309,12 @@ { if (typdef == tinbody) typdef = tend; +#if FALSE /* too risky */ + if (structdef == sinbody) + free (structtag); +#endif structdef = snone; - strcpy (structtag, "<error 2>"); + structtag = "<error>"; } break; case '=': @@ -2468,7 +2376,6 @@ /* Fortran parsing */ char *dbp; -int pfcnt; logical tail (cp) @@ -2513,8 +2420,6 @@ FILE *inf; { register char *cp; - char c; - char nambuf[BUFSIZ]; while (isspace (*dbp)) dbp++; @@ -2539,13 +2444,8 @@ && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); cp++) continue; - c = *cp; - *cp = '\0'; - strcpy (nambuf, dbp); - *cp = c; - pfnote (nambuf, TRUE, FALSE, lb.buffer, + pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); - pfcnt++; } void @@ -2554,7 +2454,6 @@ { lineno = 0; charno = 0; - pfcnt = 0; while (!feof (inf)) { @@ -2639,13 +2538,10 @@ Asm_labels (inf) FILE *inf; { - char nambuf[BUFSIZ]; register char *cp; - char c; lineno = 0; charno = 0; - pfcnt = 0; while (!feof (inf)) { @@ -2665,13 +2561,8 @@ if (*cp == ':' || isspace (*cp)) { /* Found end of label, so copy it and add it to the table. */ - c = *cp; - *cp = '\0'; - strcpy (nambuf, lb.buffer); - *cp = c; - pfnote (nambuf, TRUE, FALSE, lb.buffer, - cp - lb.buffer + 1, lineno, linecharno); - pfcnt++; + pfnote (savenstr (lb.buffer, cp-lb.buffer), TRUE, FALSE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } } } @@ -2701,7 +2592,7 @@ long save_lcno; int save_lineno; char c, *cp; - char nambuf[BUFSIZ]; + char *nambuf; logical /* each of these flags is TRUE iff: */ incomment, /* point is inside a comment */ @@ -2731,16 +2622,16 @@ while (!feof (inf)) { c = *dbp++; - if (c == 0) /* if end of line */ + if (c == '\0') /* if end of line */ { GET_NEW_LINE; - if (*dbp == 0) + if (*dbp == '\0') continue; if (!((found_tag && verify_tag) || get_tagname)) c = *dbp++; /* only if don't need *dbp pointing */ - /* to the beginning of the name of */ - /* the procedure or function */ + /* to the beginning of the name of */ + /* the procedure or function */ } if (incomment) { @@ -2759,7 +2650,7 @@ inquote = FALSE; continue; } - else + else switch (c) { case '\'': @@ -2814,9 +2705,8 @@ { found_tag = FALSE; verify_tag = FALSE; - pfnote (nambuf, TRUE, FALSE, - tline.buffer, cp - tline.buffer + 1, - save_lineno, save_lcno); + pfnote (nambuf, TRUE, FALSE, tline.buffer, + cp - tline.buffer + 1, save_lineno, save_lcno); continue; } } @@ -2834,10 +2724,7 @@ /* grab block name */ for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++) continue; - c = cp[0]; - cp[0] = 0; - strcpy (nambuf, dbp); - cp[0] = c; + nambuf = savenstr (dbp, cp-dbp); dbp = cp; /* restore dbp to e-o-token */ get_tagname = FALSE; found_tag = TRUE; @@ -2845,7 +2732,7 @@ /* and proceed to check for "extern" */ } - if (!incomment && !inquote && !found_tag && !get_tagname) + else if (!incomment && !inquote && !found_tag) { /* check for proc/fn keywords */ switch (c | ' ') @@ -2865,36 +2752,33 @@ /* * lisp tag functions - * just look for (def or (DEF + * look for (def or (DEF, quote or QUOTE */ - int -L_isdef (tokp) - register char *tokp; +L_isdef (strp) + register char *strp; { - return ((tokp[1] == 'd' || tokp[1] == 'D') - && (tokp[2] == 'e' || tokp[2] == 'E') - && (tokp[3] == 'f' || tokp[3] == 'F')); + return ((strp[1] == 'd' || strp[1] == 'D') + && (strp[2] == 'e' || strp[2] == 'E') + && (strp[3] == 'f' || strp[3] == 'F')); } int -L_isquote (tokp) - register char *tokp; +L_isquote (strp) + register char *strp; { - return ((*(++tokp) == 'q' || *tokp == 'Q') - && (*(++tokp) == 'u' || *tokp == 'U') - && (*(++tokp) == 'o' || *tokp == 'O') - && (*(++tokp) == 't' || *tokp == 'T') - && (*(++tokp) == 'e' || *tokp == 'E') - && isspace(*(++tokp))); + return ((*(++strp) == 'q' || *strp == 'Q') + && (*(++strp) == 'u' || *strp == 'U') + && (*(++strp) == 'o' || *strp == 'O') + && (*(++strp) == 't' || *strp == 'T') + && (*(++strp) == 'e' || *strp == 'E') + && isspace(*(++strp))); } void L_getit () { register char *cp; - char c; - char nambuf[BUFSIZ]; if (*dbp == '\'') /* Skip prefix quote */ dbp++; @@ -2904,18 +2788,15 @@ while (isspace(*dbp)) dbp++; } - for (cp = dbp /*+1*/; *cp && *cp != '(' && *cp != ' ' && *cp != ')'; cp++) + for (cp = dbp /*+1*/; + *cp && *cp != '(' && *cp != ' ' && *cp != ')'; + cp++) continue; if (cp == dbp) return; - c = cp[0]; - cp[0] = 0; - strcpy (nambuf, dbp); - cp[0] = c; - pfnote (nambuf, TRUE, FALSE, lb.buffer, + pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); - pfcnt++; } void @@ -2924,7 +2805,6 @@ { lineno = 0; charno = 0; - pfcnt = 0; while (!feof (inf)) { @@ -2985,7 +2865,6 @@ { lineno = 0; charno = 0; - pfcnt = 0; while (!feof (inf)) { @@ -3026,24 +2905,16 @@ get_scheme () { register char *cp; - char c; - char nambuf[BUFSIZ]; if (*dbp == 0) return; /* Go till you get to white space or a syntactic break */ - for (cp = dbp + 1; *cp && *cp != '(' && *cp != ')' && !isspace (*cp); cp++) + for (cp = dbp + 1; + *cp && *cp != '(' && *cp != ')' && !isspace (*cp); + cp++) continue; - /* Null terminate the string there. */ - c = cp[0]; - cp[0] = 0; - /* Copy the string */ - strcpy (nambuf, dbp); - /* Unterminate the string */ - cp[0] = c; - /* Announce the change */ - pfnote (nambuf, TRUE, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); - pfcnt++; + pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, + lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } /* Find tags in TeX and LaTeX input files. */ @@ -3085,7 +2956,6 @@ lineno = 0; charno = 0; - pfcnt = 0; /* Select either \ or ! as escape character. */ TEX_mode (inf); @@ -3216,7 +3086,6 @@ int len; { char *p = name + len; - char nambuf[BUFSIZ]; if (*name == 0) return; @@ -3224,11 +3093,8 @@ /* Let tag name extend to next group close (or end of line) */ while (*p && *p != TEX_clgrp) p++; - strncpy (nambuf, name, p - name); - nambuf[p - name] = 0; - - pfnote (nambuf, TRUE, FALSE, lb.buffer, strlen (lb.buffer), lineno, linecharno); - pfcnt++; + pfnote (savenstr (name, p-name), TRUE, FALSE, lb.buffer, + strlen (lb.buffer), lineno, linecharno); } /* If the text at CP matches one of the tag-defining TeX command names, @@ -3256,7 +3122,7 @@ prolog_getit (s) char *s; { - char nambuf[BUFSIZ], *save_s, tmpc; + char *save_s; int insquote, npar; save_s = s; @@ -3264,21 +3130,21 @@ npar = 0; while (1) { - if (*s == '\0') /* syntax error. */ + if (s[0] == '\0') /* syntax error. */ return; - else if (insquote && *s == '\'' && *(s + 1) == '\'') + else if (insquote && s[0] == '\'' && s[1] == '\'') s += 2; - else if (*s == '\'') + else if (s[0] == '\'') { insquote = !insquote; s++; } - else if (!insquote && *s == '(') + else if (!insquote && s[0] == '(') { npar++; s++; } - else if (!insquote && *s == ')') + else if (!insquote && s[0] == ')') { npar--; s++; @@ -3287,7 +3153,8 @@ else if (npar < 0) /* syntax error. */ return; } - else if (!insquote && *s == '.' && (isspace (*(s + 1)) || *(s + 1) == '\0')) + else if (!insquote && s[0] == '.' + && (isspace (s[1]) || s[1] == '\0')) { /* fullstop. */ if (npar != 0) /* syntax error. */ return; @@ -3297,11 +3164,8 @@ else s++; } - tmpc = *s; - *s = '\0'; - strcpy (nambuf, save_s); - *s = tmpc; - pfnote (nambuf, TRUE, FALSE, save_s, strlen (nambuf), lineno, linecharno); + pfnote (savenstr (save_s, s-save_s), TRUE, FALSE, + save_s, s-save_s, lineno, linecharno); } /* It is assumed that prolog predicate starts from column 0. */ @@ -3664,6 +3528,10 @@ } +/* + * Return a pointer to a space of size strlen(cp)+1 allocated + * with xnew where the string CP has been copied. + */ char * savestr (cp) char *cp; @@ -3671,6 +3539,10 @@ return savenstr (cp, strlen (cp)); } +/* + * Return a pointer to a space of size LEN+1 allocated with xnew where + * the string CP has been copied for at most the first LEN characters. + */ char * savenstr (cp, len) char *cp;