X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/0bb2392728c10748f3376f8cef6d9ca53e29f464..5994c1836bc3c2457aa1e27c1191bf03a9be1721:/lib-src/etags.c diff --git a/lib-src/etags.c b/lib-src/etags.c index 693c999047..7141811239 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -28,7 +28,7 @@ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2011 +Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2012 Free Software Foundation, Inc. This file is not considered part of GNU Emacs. @@ -91,25 +91,7 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; # define NDEBUG /* disable assert */ #endif -#ifdef HAVE_CONFIG_H -# include - /* This is probably not necessary any more. On some systems, config.h - used to define static as nothing for the sake of unexec. We don't - want that here since we don't use unexec. None of these systems - are supported any more, but the idea is still mentioned in - etc/PROBLEMS. */ -# undef static -# ifndef PTR /* for XEmacs */ -# define PTR void * -# endif -#else /* no config.h */ -# if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C)) -# define PTR void * /* for generic pointers */ -# else /* not standard C */ -# define const /* remove const for old compilers' sake */ -# define PTR long * /* don't use void* */ -# endif -#endif /* !HAVE_CONFIG_H */ +#include #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */ @@ -129,18 +111,12 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; # include # include # include -# ifndef HAVE_CONFIG_H -# define DOS_NT -# include -# endif #else # define MSDOS FALSE #endif /* MSDOS */ #ifdef WINDOWSNT -# include # include -# include # include # include # define MAXPATHLEN _MAX_PATH @@ -151,27 +127,6 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; # define HAVE_GETCWD # endif /* undef HAVE_GETCWD */ #else /* not WINDOWSNT */ -# ifdef STDC_HEADERS -# include -# include -# else /* no standard C headers */ - extern char *getenv (const char *); - extern char *strcpy (char *, const char *); - extern char *strncpy (char *, const char *, unsigned long); - extern char *strcat (char *, const char *); - extern char *strncat (char *, const char *, unsigned long); - extern int strcmp (const char *, const char *); - extern int strncmp (const char *, const char *, unsigned long); - extern int system (const char *); - extern unsigned long strlen (const char *); - extern void *malloc (unsigned long); - extern void *realloc (void *, unsigned long); - extern void exit (int); - extern void free (void *); - extern void *memmove (void *, const void *, unsigned long); -# define EXIT_SUCCESS 0 -# define EXIT_FAILURE 1 -# endif #endif /* !WINDOWSNT */ #include @@ -181,11 +136,15 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; # endif #endif /* HAVE_UNISTD_H */ +#include +#include +#include #include #include #include #include #include +#include #include #ifdef NDEBUG @@ -203,14 +162,6 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; # include #endif /* NO_LONG_OPTIONS */ -#ifndef HAVE_CONFIG_H /* this is a standalone compilation */ -# ifdef __CYGWIN__ /* compiling on Cygwin */ - !!! NOTICE !!! - the regex.h distributed with Cygwin is not compatible with etags, alas! -If you want regular expression support, you should delete this notice and - arrange to use the GNU regex.h and regex.c. -# endif -#endif #include /* Define CTAGS to make the program "ctags" compatible with the usual one. @@ -223,25 +174,25 @@ If you want regular expression support, you should delete this notice and # define CTAGS FALSE #endif -#define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t)) -#define strcaseeq(s,t) (assert((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t)) -#define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n)) -#define strncaseeq(s,t,n) (assert((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n)) +#define streq(s,t) (assert ((s)!=NULL || (t)!=NULL), !strcmp (s, t)) +#define strcaseeq(s,t) (assert ((s)!=NULL && (t)!=NULL), !c_strcasecmp (s, t)) +#define strneq(s,t,n) (assert ((s)!=NULL || (t)!=NULL), !strncmp (s, t, n)) +#define strncaseeq(s,t,n) (assert ((s)!=NULL && (t)!=NULL), !c_strncasecmp (s, t, n)) #define CHARS 256 /* 2^sizeof(char) */ #define CHAR(x) ((unsigned int)(x) & (CHARS - 1)) -#define iswhite(c) (_wht[CHAR(c)]) /* c is white (see white) */ -#define notinname(c) (_nin[CHAR(c)]) /* c is not in a name (see nonam) */ -#define begtoken(c) (_btk[CHAR(c)]) /* c can start token (see begtk) */ -#define intoken(c) (_itk[CHAR(c)]) /* c can be in token (see midtk) */ -#define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens (see endtk) */ +#define iswhite(c) (_wht[CHAR (c)]) /* c is white (see white) */ +#define notinname(c) (_nin[CHAR (c)]) /* c is not in a name (see nonam) */ +#define begtoken(c) (_btk[CHAR (c)]) /* c can start token (see begtk) */ +#define intoken(c) (_itk[CHAR (c)]) /* c can be in token (see midtk) */ +#define endtoken(c) (_etk[CHAR (c)]) /* c ends tokens (see endtk) */ -#define ISALNUM(c) isalnum (CHAR(c)) -#define ISALPHA(c) isalpha (CHAR(c)) -#define ISDIGIT(c) isdigit (CHAR(c)) -#define ISLOWER(c) islower (CHAR(c)) +#define ISALNUM(c) isalnum (CHAR (c)) +#define ISALPHA(c) isalpha (CHAR (c)) +#define ISDIGIT(c) isdigit (CHAR (c)) +#define ISLOWER(c) islower (CHAR (c)) -#define lowcase(c) tolower (CHAR(c)) +#define lowcase(c) tolower (CHAR (c)) /* @@ -347,7 +298,7 @@ typedef struct regexp struct re_pattern_buffer *pat; /* the compiled pattern */ struct re_registers regs; /* re registers */ bool error_signaled; /* already signaled for this regexp */ - bool force_explicit_name; /* do not allow implict tag name */ + bool force_explicit_name; /* do not allow implicit tag name */ bool ignore_case; /* ignore case when matching */ bool multi_line; /* do a multi-line match on the whole file */ } regexp; @@ -401,10 +352,10 @@ static void get_tag (char *, char **); static void analyse_regex (char *); static void free_regexps (void); static void regex_tag_multiline (void); -static void error (const char *, const char *); -static void suggest_asking_for_help (void) NO_RETURN; -void fatal (const char *, const char *) NO_RETURN; -static void pfatal (const char *) NO_RETURN; +static void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); +static _Noreturn void suggest_asking_for_help (void); +_Noreturn void fatal (const char *, const char *); +static _Noreturn void pfatal (const char *); static void add_node (node *, node **); static void init (void); @@ -425,8 +376,6 @@ static char *savenstr (const char *, int); static char *savestr (const char *); static char *etags_strchr (const char *, int); static char *etags_strrchr (const char *, int); -static int etags_strcasecmp (const char *, const char *); -static int etags_strncasecmp (const char *, const char *, int); static char *etags_getcwd (void); static char *relative_filename (char *, char *); static char *absolute_filename (char *, char *); @@ -435,8 +384,8 @@ static bool filename_is_absolute (char *f); static void canonicalize_filename (char *); static void linebuffer_init (linebuffer *); static void linebuffer_setlen (linebuffer *, int); -static PTR xmalloc (unsigned int); -static PTR xrealloc (char *, unsigned int); +static void *xmalloc (size_t); +static void *xrealloc (char *, size_t); static char searchar = '/'; /* use /.../ searches */ @@ -446,6 +395,7 @@ static char *progname; /* name this program was invoked with */ static char *cwd; /* current working directory */ static char *tagfiledir; /* directory of tagfile */ static FILE *tagf; /* ioptr for tags file */ +static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */ static fdesc *fdhead; /* head of file description list */ static fdesc *curfdp; /* current file description */ @@ -631,7 +581,7 @@ using `--declarations'."; static const char *Cplusplus_suffixes [] = { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx", "M", /* Objective C++ */ - "pdb", /* Postscript with C syntax */ + "pdb", /* PostScript with C syntax */ NULL }; static const char Cplusplus_help [] = "In C++ code, all the tag constructs of C code are tagged. (Use\n\ @@ -887,7 +837,7 @@ static void print_version (void) { /* Makes it easier to update automatically. */ - char emacs_copyright[] = "Copyright (C) 2011 Free Software Foundation, Inc."; + char emacs_copyright[] = "Copyright (C) 2012 Free Software Foundation, Inc."; printf ("%s (%s %s)\n", (CTAGS) ? "ctags" : "etags", EMACS_NAME, VERSION); puts (emacs_copyright); @@ -1087,6 +1037,7 @@ main (int argc, char **argv) int current_arg, file_count; linebuffer filename_lb; bool help_asked = FALSE; + ptrdiff_t len; char *optstring; int opt; @@ -1131,6 +1082,9 @@ main (int argc, char **argv) /* This means that a file name has been seen. Record it. */ argbuffer[current_arg].arg_type = at_filename; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; break; @@ -1139,6 +1093,9 @@ main (int argc, char **argv) /* Parse standard input. Idea by Vivek . */ argbuffer[current_arg].arg_type = at_stdin; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; if (parsing_stdin) @@ -1153,7 +1110,7 @@ main (int argc, char **argv) case 'o': if (tagfile) { - error ("-o option may only be given once.", (char *)NULL); + error ("-o option may only be given once."); suggest_asking_for_help (); /* NOTREACHED */ } @@ -1181,6 +1138,9 @@ main (int argc, char **argv) case 'r': argbuffer[current_arg].arg_type = at_regexp; argbuffer[current_arg].what = optarg; + len = strlen (optarg); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; break; case 'R': @@ -1219,6 +1179,9 @@ main (int argc, char **argv) { argbuffer[current_arg].arg_type = at_filename; argbuffer[current_arg].what = argv[optind]; + len = strlen (argv[optind]); + if (whatlen_max < len) + whatlen_max = len; ++current_arg; ++file_count; } @@ -1231,7 +1194,7 @@ main (int argc, char **argv) if (nincluded_files == 0 && file_count == 0) { - error ("no input files specified.", (char *)NULL); + error ("no input files specified."); suggest_asking_for_help (); /* NOTREACHED */ } @@ -1352,7 +1315,9 @@ main (int argc, char **argv) /* From here on, we are in (CTAGS && !cxref_style) */ if (update) { - char cmd[BUFSIZ]; + char *cmd = + xmalloc (strlen (tagfile) + whatlen_max + + sizeof "mv..OTAGS;fgrep -v '\t\t' OTAGS >;rm OTAGS"); for (i = 0; i < current_arg; ++i) { switch (argbuffer[i].arg_type) @@ -1363,12 +1328,17 @@ main (int argc, char **argv) default: continue; /* the for loop */ } - sprintf (cmd, - "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", - tagfile, argbuffer[i].what, tagfile); + strcpy (cmd, "mv "); + strcat (cmd, tagfile); + strcat (cmd, " OTAGS;fgrep -v '\t"); + strcat (cmd, argbuffer[i].what); + strcat (cmd, "\t' OTAGS >"); + strcat (cmd, tagfile); + strcat (cmd, ";rm OTAGS"); if (system (cmd) != EXIT_SUCCESS) fatal ("failed to execute shell command", (char *)NULL); } + free (cmd); append_to_tagfile = TRUE; } @@ -1384,11 +1354,14 @@ main (int argc, char **argv) if (CTAGS) if (append_to_tagfile || update) { - char cmd[2*BUFSIZ+20]; + char *cmd = xmalloc (2 * strlen (tagfile) + sizeof "sort -u -o.."); /* Maybe these should be used: setenv ("LC_COLLATE", "C", 1); setenv ("LC_ALL", "C", 1); */ - sprintf (cmd, "sort -u -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile); + strcpy (cmd, "sort -u -o "); + strcat (cmd, tagfile); + strcat (cmd, " "); + strcat (cmd, tagfile); exit (system (cmd)); } return EXIT_SUCCESS; @@ -1444,7 +1417,7 @@ get_language_from_langname (const char *name) language *lang; if (name == NULL) - error ("empty language name", (char *)NULL); + error ("empty language name"); else { for (lang = lang_names; lang->name != NULL; lang++) @@ -1722,16 +1695,16 @@ init (void) register int i; for (i = 0; i < CHARS; i++) - iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE; + iswhite (i) = notinname (i) = begtoken (i) = intoken (i) = endtoken (i) = FALSE; for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE; for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE; - notinname('\0') = notinname('\n'); + notinname ('\0') = notinname ('\n'); for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE; - begtoken('\0') = begtoken('\n'); + begtoken ('\0') = begtoken ('\n'); for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE; - intoken('\0') = intoken('\n'); + intoken ('\0') = intoken ('\n'); for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE; - endtoken('\0') = endtoken('\n'); + endtoken ('\0') = endtoken ('\n'); } /* @@ -1859,10 +1832,10 @@ find_entries (FILE *inf) assert (parser != NULL); - /* Generic initialisations before reading from file. */ + /* Generic initializations before reading from file. */ linebuffer_setlen (&filebuf, 0); /* reset the file buffer */ - /* Generic initialisations before parsing file with readline. */ + /* Generic initializations before parsing file with readline. */ lineno = 0; /* reset global line number */ charno = 0; /* reset global char number */ linecharno = 0; /* reset global char number of line start */ @@ -1892,7 +1865,7 @@ find_entries (FILE *inf) * 4. the character, if any, immediately after NAME in LINESTART must * also be a character in NONAM. * - * The implementation uses the notinname() macro, which recognises the + * The implementation uses the notinname() macro, which recognizes the * characters stored in the string `nonam'. * etags.el needs to use the same characters that are in NONAM. */ @@ -2150,7 +2123,7 @@ invalidate_nodes (fdesc *badfdp, node **npp) static int total_size_of_entries (node *); -static int number_len (long); +static int number_len (long) ATTRIBUTE_CONST; /* Length of a non-negative number's decimal representation. */ static int @@ -2230,7 +2203,7 @@ put_entries (register node *np) { /* Ctags mode */ if (np->name == NULL) - error ("internal error: NULL name in ctags mode.", (char *)NULL); + error ("internal error: NULL name in ctags mode."); if (cxref_style) { @@ -2770,7 +2743,7 @@ consider_token (register char *str, register int len, register int c, int *c_ext case dignorerest: return FALSE; default: - error ("internal error: definedef value.", (char *)NULL); + error ("internal error: definedef value."); } /* @@ -3054,11 +3027,11 @@ make_C_tag (int isfun) make_tag (token_name.buffer, token_name.len, isfun, token.line, token.offset+token.length+1, token.lineno, token.linepos); else if (DEBUG) - { /* this branch is optimised away if !DEBUG */ + { /* this branch is optimized away if !DEBUG */ make_tag (concat ("INVALID TOKEN:-->", token_name.buffer, ""), token_name.len + 17, isfun, token.line, token.offset+token.length+1, token.lineno, token.linepos); - error ("INVALID TOKEN", NULL); + error ("INVALID TOKEN"); } token.valid = FALSE; @@ -3186,24 +3159,12 @@ C_entries (int c_ext, FILE *inf) } continue; } - else if (bracketlev > 0) - { - switch (c) - { - case ']': - if (--bracketlev > 0) - continue; - break; - case '\0': - CNL_SAVE_DEFINEDEF (); - break; - } - continue; - } else switch (c) { case '"': inquote = TRUE; + if (bracketlev > 0) + continue; if (inattribute) break; switch (fvdef) @@ -3221,9 +3182,11 @@ C_entries (int c_ext, FILE *inf) continue; case '\'': inchar = TRUE; + if (bracketlev > 0) + continue; if (inattribute) break; - if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) + if (fvdef != finlist && fvdef != fignore && fvdef != vignore) { fvextern = FALSE; fvdef = fvnone; @@ -3235,6 +3198,8 @@ C_entries (int c_ext, FILE *inf) incomm = TRUE; lp++; c = ' '; + if (bracketlev > 0) + continue; } else if (/* cplpl && */ *lp == '/') { @@ -3267,7 +3232,7 @@ C_entries (int c_ext, FILE *inf) for (cp = newlb.buffer; cp < lp-1; cp++) if (!iswhite (*cp)) { - if (*cp == '*' && *(cp+1) == '/') + if (*cp == '*' && cp[1] == '/') { cp++; cpptoken = TRUE; @@ -3281,7 +3246,17 @@ C_entries (int c_ext, FILE *inf) continue; case '[': bracketlev++; - continue; + continue; + default: + if (bracketlev > 0) + { + if (c == ']') + --bracketlev; + else if (c == '\0') + CNL_SAVE_DEFINEDEF (); + continue; + } + break; } /* switch (c) */ @@ -3301,7 +3276,7 @@ C_entries (int c_ext, FILE *inf) if (c == ':' && *lp == ':' && begtoken (lp[1])) /* This handles :: in the middle, but not at the beginning of an identifier. - Also, space-separated :: is not recognised. */ + Also, space-separated :: is not recognized. */ { if (c_ext & C_AUTO) /* automatic detection of C++ */ c_ext = (c_ext | C_PLPL) & ~C_AUTO; @@ -3956,16 +3931,16 @@ Yacc_entries (FILE *inf) ) #define LOOKING_AT(cp, kw) /* kw is the keyword, a literal string */ \ - ((assert("" kw), TRUE) /* syntax error if not a literal string */ \ - && strneq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \ - && notinname ((cp)[sizeof(kw)-1]) /* end of kw */ \ - && ((cp) = skip_spaces((cp)+sizeof(kw)-1))) /* skip spaces */ + ((assert ("" kw), TRUE) /* syntax error if not a literal string */ \ + && strneq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \ + && notinname ((cp)[sizeof (kw)-1]) /* end of kw */ \ + && ((cp) = skip_spaces ((cp)+sizeof (kw)-1))) /* skip spaces */ /* Similar to LOOKING_AT but does not use notinname, does not skip */ #define LOOKING_AT_NOCASE(cp, kw) /* the keyword is a literal string */ \ - ((assert("" kw), TRUE) /* syntax error if not a literal string */ \ - && strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \ - && ((cp) += sizeof(kw)-1)) /* skip spaces */ + ((assert ("" kw), TRUE) /* syntax error if not a literal string */ \ + && strncaseeq ((cp), kw, sizeof (kw)-1) /* cp points at kw */ \ + && ((cp) += sizeof (kw)-1)) /* skip spaces */ /* * Read a file, but do no processing. This is used to do regexp @@ -4045,6 +4020,12 @@ Fortran_functions (FILE *inf) if (LOOKING_AT_NOCASE (dbp, "recursive")) dbp = skip_spaces (dbp); + if (LOOKING_AT_NOCASE (dbp, "pure")) + dbp = skip_spaces (dbp); + + if (LOOKING_AT_NOCASE (dbp, "elemental")) + dbp = skip_spaces (dbp); + switch (lowcase (*dbp)) { case 'i': @@ -4132,7 +4113,7 @@ Ada_getit (FILE *inf, const char *name_qualifier) readline (&lb, inf); dbp = lb.buffer; } - switch (lowcase(*dbp)) + switch (lowcase (*dbp)) { case 'b': if (nocase_tail ("body")) @@ -4236,7 +4217,7 @@ Ada_funcs (FILE *inf) } /* We are at the beginning of a token. */ - switch (lowcase(*dbp)) + switch (lowcase (*dbp)) { case 'f': if (!packages_only && nocase_tail ("function")) @@ -4362,7 +4343,7 @@ Perl_functions (FILE *inf) *cp = '\0'; name = concat (package, "::", sp); *cp = savechar; - make_tag (name, strlen(name), TRUE, + make_tag (name, strlen (name), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); free (name); } @@ -4457,9 +4438,9 @@ PHP_functions (FILE *inf) } else if (LOOKING_AT (cp, "function")) { - if(*cp == '&') + if (*cp == '&') cp = skip_spaces (cp+1); - if(*cp != '\0') + if (*cp != '\0') { name = cp; while (!notinname (*cp)) @@ -4500,7 +4481,7 @@ PHP_functions (FILE *inf) && *cp == '$') { name = cp; - while (!notinname(*cp)) + while (!notinname (*cp)) cp++; make_tag (name, cp - name, FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); @@ -4837,7 +4818,7 @@ Lua_functions (FILE *inf) /* - * Postscript tags + * PostScript tags * Just look for lines where the first character is '/' * Also look at "defineps" for PSWrap * Ideas by: @@ -4881,13 +4862,13 @@ Forth_words (FILE *inf) LOOP_ON_INPUT_LINES (inf, lb, bp) while ((bp = skip_spaces (bp))[0] != '\0') - if (bp[0] == '\\' && iswhite(bp[1])) + if (bp[0] == '\\' && iswhite (bp[1])) break; /* read next line */ - else if (bp[0] == '(' && iswhite(bp[1])) + else if (bp[0] == '(' && iswhite (bp[1])) do /* skip to ) or eol */ bp++; while (*bp != ')' && *bp != '\0'); - else if ((bp[0] == ':' && iswhite(bp[1]) && bp++) + else if ((bp[0] == ':' && iswhite (bp[1]) && bp++) || LOOKING_AT_NOCASE (bp, "constant") || LOOKING_AT_NOCASE (bp, "code") || LOOKING_AT_NOCASE (bp, "create") @@ -5276,7 +5257,7 @@ Prolog_functions (FILE *inf) /* Predicate or rule. Store the function name so that we only generate a tag for the first clause. */ if (last == NULL) - last = xnew(len + 1, char); + last = xnew (len + 1, char); else if (len + 1 > allocated) xrnew (last, len + 1, char); allocated = len + 1; @@ -5300,7 +5281,7 @@ prolog_skip_comment (linebuffer *plb, FILE *inf) return; readline (plb, inf); } - while (!feof(inf)); + while (!feof (inf)); } /* @@ -5359,11 +5340,11 @@ prolog_atom (char *s, size_t pos) origpos = pos; - if (ISLOWER(s[pos]) || (s[pos] == '_')) + if (ISLOWER (s[pos]) || (s[pos] == '_')) { /* The atom is unquoted. */ pos++; - while (ISALNUM(s[pos]) || (s[pos] == '_')) + while (ISALNUM (s[pos]) || (s[pos] == '_')) { pos++; } @@ -5695,7 +5676,7 @@ add_regex (char *regexp_pattern, language *lang) { static struct re_pattern_buffer zeropattern; char sep, *pat, *name, *modifiers; - char empty[] = ""; + char empty = '\0'; const char *err; struct re_pattern_buffer *patbuf; regexp *rp; @@ -5706,9 +5687,9 @@ add_regex (char *regexp_pattern, language *lang) single_line = FALSE; /* dot does not match newline */ - if (strlen(regexp_pattern) < 3) + if (strlen (regexp_pattern) < 3) { - error ("null regexp", (char *)NULL); + error ("null regexp"); return; } sep = regexp_pattern[0]; @@ -5727,7 +5708,7 @@ add_regex (char *regexp_pattern, language *lang) if (modifiers == NULL) /* no terminating separator --> no name */ { modifiers = name; - name = empty; + name = ∅ } else modifiers += 1; /* skip separator */ @@ -5738,7 +5719,7 @@ add_regex (char *regexp_pattern, language *lang) { case 'N': if (modifiers == name) - error ("forcing explicit tag name but no name, ignoring", NULL); + error ("forcing explicit tag name but no name, ignoring"); force_explicit_name = TRUE; break; case 'i': @@ -5752,12 +5733,7 @@ add_regex (char *regexp_pattern, language *lang) need_filebuf = TRUE; break; default: - { - char wrongmod [2]; - wrongmod[0] = modifiers[0]; - wrongmod[1] = '\0'; - error ("invalid regexp modifier `%s', ignoring", wrongmod); - } + error ("invalid regexp modifier `%c', ignoring", modifiers[0]); break; } @@ -5891,7 +5867,7 @@ regex_tag_multiline (void) if (!rp->multi_line) continue; /* skip normal regexps */ - /* Generic initialisations before parsing file from memory. */ + /* Generic initializations before parsing file from memory. */ lineno = 1; /* reset global line number */ charno = 0; /* reset global char number */ linecharno = 0; /* reset global char number of line start */ @@ -6088,7 +6064,7 @@ readline (linebuffer *lbp, FILE *stream) lineno += 1; /* increment global line number */ charno += result; /* increment global char number */ - /* Honour #line directives. */ + /* Honor #line directives. */ if (!no_line_directive) { static bool discard_until_line_directive; @@ -6329,48 +6305,6 @@ etags_strchr (register const char *sp, register int c) return NULL; } -/* - * Compare two strings, ignoring case for alphabetic characters. - * - * Same as BSD's strcasecmp, included for portability. - */ -static int -etags_strcasecmp (register const char *s1, register const char *s2) -{ - while (*s1 != '\0' - && (ISALPHA (*s1) && ISALPHA (*s2) - ? lowcase (*s1) == lowcase (*s2) - : *s1 == *s2)) - s1++, s2++; - - return (ISALPHA (*s1) && ISALPHA (*s2) - ? lowcase (*s1) - lowcase (*s2) - : *s1 - *s2); -} - -/* - * Compare two strings, ignoring case for alphabetic characters. - * Stop after a given number of characters - * - * Same as BSD's strncasecmp, included for portability. - */ -static int -etags_strncasecmp (register const char *s1, register const char *s2, register int n) -{ - while (*s1 != '\0' && n-- > 0 - && (ISALPHA (*s1) && ISALPHA (*s2) - ? lowcase (*s1) == lowcase (*s2) - : *s1 == *s2)) - s1++, s2++; - - if (n < 0) - return 0; - else - return (ISALPHA (*s1) && ISALPHA (*s2) - ? lowcase (*s1) - lowcase (*s2) - : *s1 - *s2); -} - /* Skip spaces (end of string is not space), return new pointer. */ static char * skip_spaces (char *cp) @@ -6412,13 +6346,16 @@ suggest_asking_for_help (void) exit (EXIT_FAILURE); } -/* Print error message. `s1' is printf control string, `s2' is arg for it. */ +/* Output a diagnostic with printf-style FORMAT and args. */ static void -error (const char *s1, const char *s2) +error (const char *format, ...) { + va_list ap; + va_start (ap, format); fprintf (stderr, "%s: ", progname); - fprintf (stderr, s1, s2); + vfprintf (stderr, format, ap); fprintf (stderr, "\n"); + va_end (ap); } /* Return a newly-allocated string whose contents @@ -6567,22 +6504,13 @@ absolute_filename (char *file, char *dir) else if (cp[0] != '/') cp = slashp; #endif -#ifdef HAVE_MEMMOVE memmove (cp, slashp + 3, strlen (slashp + 2)); -#else - /* Overlapping copy isn't really okay */ - strcpy (cp, slashp + 3); -#endif slashp = cp; continue; } else if (slashp[2] == '/' || slashp[2] == '\0') { -#ifdef HAVE_MEMMOVE memmove (slashp, slashp + 2, strlen (slashp + 1)); -#else - strcpy (slashp, slashp + 2); -#endif continue; } } @@ -6626,7 +6554,7 @@ filename_is_absolute (char *fn) { return (fn[0] == '/' #ifdef DOS_NT - || (ISALPHA(fn[0]) && fn[1] == ':' && fn[2] == '/') + || (ISALPHA (fn[0]) && fn[1] == ':' && fn[2] == '/') #endif ); } @@ -6641,7 +6569,7 @@ canonicalize_filename (register char *fn) #ifdef DOS_NT /* Canonicalize drive letter case. */ -# define ISUPPER(c) isupper (CHAR(c)) +# define ISUPPER(c) isupper (CHAR (c)) if (fn[0] != '\0' && fn[1] == ':' && ISUPPER (fn[0])) fn[0] = lowcase (fn[0]); @@ -6685,19 +6613,19 @@ linebuffer_setlen (linebuffer *lbp, int toksize) } /* Like malloc but get fatal error if memory is exhausted. */ -static PTR -xmalloc (unsigned int size) +static void * +xmalloc (size_t size) { - PTR result = (PTR) malloc (size); + void *result = malloc (size); if (result == NULL) fatal ("virtual memory exhausted", (char *)NULL); return result; } -static PTR -xrealloc (char *ptr, unsigned int size) +static void * +xrealloc (char *ptr, size_t size) { - PTR result = (PTR) realloc (ptr, size); + void *result = realloc (ptr, size); if (result == NULL) fatal ("virtual memory exhausted", (char *)NULL); return result;