Mercurial > hg > xemacs-beta
diff lib-src/etags.c @ 286:57709be46d1b r21-0b41
Import from CVS: tag r21-0b41
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:35:03 +0200 |
parents | c42ec1d1cded |
children | a4f53d9b3154 |
line wrap: on
line diff
--- a/lib-src/etags.c Mon Aug 13 10:34:15 2007 +0200 +++ b/lib-src/etags.c Mon Aug 13 10:35:03 2007 +0200 @@ -1,5 +1,5 @@ /* Tags file maker to go with GNU Emacs - Copyright (C) 1984, 87, 88, 89, 93, 94, 95 + Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98 Free Software Foundation, Inc. and Ken Arnold This file is not considered part of GNU Emacs. @@ -31,31 +31,7 @@ * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer. */ -char pot_etags_version[] = "@(#) pot revision number is 12.28"; - -/* Prototyping magic snarfed from gmalloc.c */ -#if defined (__cplusplus) || defined (__STDC__) -#undef PP -#define PP(args) args -#undef __ptr_t -#define __ptr_t void * -#else /* Not C++ or ANSI C. */ -#undef PP -#define PP(args) () -#undef const -#define const -#undef __ptr_t -#define __ptr_t char * -#endif /* C++ or ANSI C. */ - -#ifdef HAVE_CONFIG_H -# include <config.h> - /* On some systems, Emacs defines static as nothing for the sake - of unexec. We don't want that here since we don't use unexec. */ -# undef static -# define ETAGS_REGEXPS /* use the regexp features */ -# define LONG_OPTIONS /* accept long options */ -#endif /* HAVE_CONFIG_H */ +char pot_etags_version[] = "@(#) pot revision number is 13.7"; #define TRUE 1 #define FALSE 0 @@ -88,6 +64,15 @@ # endif /* not HAVE_CONFIG_H */ #endif /* WINDOWSNT */ +#ifdef HAVE_CONFIG_H +# include <config.h> + /* On some systems, Emacs defines static as nothing for the sake + of unexec. We don't want that here since we don't use unexec. */ +# undef static +# define ETAGS_REGEXPS /* use the regexp features */ +# define LONG_OPTIONS /* accept long options */ +#endif /* HAVE_CONFIG_H */ + #if !defined (WINDOWSNT) && defined (STDC_HEADERS) #include <stdlib.h> #include <string.h> @@ -190,111 +175,80 @@ typedef struct { + char *suffix; + int sufflen; + char *command; /* Takes one arg and decompresses to stdout */ +} compressor; + +typedef struct +{ char *name; Lang_function *function; char **suffixes; char **interpreters; } language; -typedef struct node_st -{ /* sorting structure */ - char *name; /* function or type name */ - char *file; /* file name */ - bool is_func; /* use pattern or line no */ - bool been_warned; /* set if noticed dup */ - int lno; /* line number tag is on */ - long cno; /* character number line starts on */ - char *pat; /* search pattern */ - struct node_st *left, *right; /* left and right sons */ -} node; - -/* - * A `linebuffer' is a structure which holds a line of text. - * `readline_internal' reads a line from a stream into a linebuffer - * and works regardless of the length of the line. - * SIZE is the size of BUFFER, LEN is the length of the string in - * BUFFER after readline reads it. - */ -typedef struct -{ - long size; - int len; - char *buffer; -} linebuffer; - -extern char *getenv PP ((const char *envvar)); +extern char *getenv (); /* Many compilers barf on this: Lang_function Asm_labels; so let's write it this way */ -void Asm_labels PP ((FILE *inf)); -void C_entries PP ((int c_ext, FILE *inf)); -void default_C_entries PP ((FILE *inf)); -void plain_C_entries PP ((FILE *inf)); -void Cjava_entries PP ((FILE *inf)); -void Cplusplus_entries PP ((FILE *inf)); -void Yacc_entries PP ((FILE *inf)); -void Cobol_paragraphs PP ((FILE *inf)); -void Cstar_entries PP ((FILE *inf)); -void Erlang_functions PP ((FILE *inf)); -void Fortran_functions PP ((FILE *inf)); -void Lisp_functions PP ((FILE *inf)); -void Pascal_functions PP ((FILE *inf)); -void Perl_functions PP ((FILE *inf)); -void Postscript_functions PP ((FILE *inf)); -void Prolog_functions PP ((FILE *inf)); -void Python_functions PP ((FILE *inf)); -void Scheme_functions PP ((FILE *inf)); -void TeX_functions PP ((FILE *inf)); -void just_read_file PP ((FILE *inf)); - -void print_language_names PP ((void)); -void print_version PP ((void)); -void print_help PP ((void)); - -language *get_language_from_name PP ((char *name)); -language *get_language_from_interpreter PP ((char *interpreter)); -language *get_language_from_suffix PP ((char *suffix)); -int total_size_of_entries PP ((node *np)); -long readline PP ((linebuffer *lbp, FILE *stream)); -long readline_internal PP ((linebuffer *lbp, FILE *stream)); +void Asm_labels (); +void C_entries (); +void default_C_entries (); +void plain_C_entries (); +void Cjava_entries (); +void Cobol_paragraphs (); +void Cplusplus_entries (); +void Cstar_entries (); +void Erlang_functions (); +void Fortran_functions (); +void Yacc_entries (); +void Lisp_functions (); +void Pascal_functions (); +void Perl_functions (); +void Postscript_functions (); +void Prolog_functions (); +void Python_functions (); +void Scheme_functions (); +void TeX_functions (); +void just_read_file (); + +compressor *get_compressor_from_suffix (); +language *get_language_from_name (); +language *get_language_from_interpreter (); +language *get_language_from_suffix (); +int total_size_of_entries (); +long readline (), readline_internal (); #ifdef ETAGS_REGEXPS -void analyse_regex PP ((char *regex_arg)); -void add_regex PP ((char *regexp_pattern, language *lang)); -void free_patterns PP ((void)); +void analyse_regex (); +void add_regex (); +void free_patterns (); #endif /* ETAGS_REGEXPS */ -void error PP ((const char *s1, const char *s2)); -void suggest_asking_for_help PP ((void)); -void fatal PP ((char *s1, char *s2)); -void pfatal PP ((char *s1)); -void add_node PP ((node *np, node **cur_node_p)); - -void init PP ((void)); -void initbuffer PP ((linebuffer *lbp)); -void find_entries PP ((char *file, FILE *inf)); -void free_tree PP ((node *np)); -void pfnote PP ((char *name, bool is_func, char *linestart, int linelen, int lno, long cno)); -void new_pfnote PP ((char *name, int namelen, bool is_func, char *linestart, int linelen, int lno, long cno)); -void process_file PP ((char *file)); -void put_entries PP ((node *np)); -void takeprec PP ((void)); - -char *concat PP ((char *s1, char *s2, char *s3)); -char *skip_spaces PP ((char *cp)); -char *skip_non_spaces PP ((char *cp)); -char *savenstr PP ((char *cp, int len)); -char *savestr PP ((char *cp)); -char *etags_strchr PP ((char *sp, int c)); -char *etags_strrchr PP ((char *sp, int c)); -char *etags_getcwd PP ((void)); -char *relative_filename PP ((char *file, char *dir)); -char *absolute_filename PP ((char *file, char *dir)); -char *absolute_dirname PP ((char *file, char *dir)); -bool filename_is_absolute PP ((char *fn)); -void canonicalize_filename PP ((char *fn)); -void grow_linebuffer PP ((linebuffer *lbp, int toksize)); -long *xmalloc PP ((unsigned int size)); -long *xrealloc PP ((char *ptr, unsigned int size)); +void error (); +void suggest_asking_for_help (); +void fatal (), pfatal (); +void add_node (); + +void init (); +void initbuffer (); +void find_entries (); +void free_tree (); +void pfnote (), new_pfnote (); +void process_file (); +void put_entries (); +void takeprec (); + +char *concat (); +char *skip_spaces (), *skip_non_spaces (); +char *savenstr (), *savestr (); +char *etags_strchr (), *etags_strrchr (); +char *etags_getcwd (); +char *relative_filename (), *absolute_filename (), *absolute_dirname (); +bool filename_is_absolute (); +void canonicalize_filename (); +void grow_linebuffer (); +long *xmalloc (), *xrealloc (); char searchar = '/'; /* use /.../ searches */ @@ -312,8 +266,35 @@ long charno; /* current character number */ long linecharno; /* charno of start of current line */ char *dbp; /* pointer to start of current tag */ + +typedef struct node_st +{ /* sorting structure */ + char *name; /* function or type name */ + char *file; /* file name */ + bool is_func; /* use pattern or line no */ + bool been_warned; /* set if noticed dup */ + int lno; /* line number tag is on */ + long cno; /* character number line starts on */ + char *pat; /* search pattern */ + struct node_st *left, *right; /* left and right sons */ +} node; + node *head; /* the head of the binary tree of tags */ +/* + * A `linebuffer' is a structure which holds a line of text. + * `readline_internal' reads a line from a stream into a linebuffer + * and works regardless of the length of the line. + * SIZE is the size of BUFFER, LEN is the length of the string in + * BUFFER after readline reads it. + */ +typedef struct +{ + long size; + int len; + char *buffer; +} linebuffer; + linebuffer lb; /* the current line */ linebuffer token_name; /* used by C_entries as a temporary area */ struct @@ -405,6 +386,16 @@ pattern *p_head = NULL; #endif /* ETAGS_REGEXPS */ +compressor compressors[] = +{ + { "z", 1, "gzip -d -c"}, + { "Z", 1, "gzip -d -c"}, + { "gz", 2, "gzip -d -c"}, + { "GZ", 2, "gzip -d -c"}, + { "bz2", 3, "bzip2 -d -c" }, + { NULL } +}; + /* * Language stuff. */ @@ -419,6 +410,7 @@ "inc", /* Microcontroller include files */ "ins", /* Microcontroller include files */ "s", "sa", /* Unix assembler */ + "S", /* cpp-processed Unix assembler */ "src", /* BSO/Tasking C compiler output */ NULL }; @@ -483,7 +475,7 @@ { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL }; char *Yacc_suffixes [] = - { "y", "ym", NULL }; /* .ym is Objective yacc file */ + { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */ /* * Table of languages. @@ -516,7 +508,6 @@ { "none", just_read_file }, /* regexp matching only */ { NULL, NULL } /* end of list */ }; - void print_language_names () @@ -539,7 +530,8 @@ If no language is specified and no matching suffix is found,\n\ the first line of the file is read for a sharp-bang (#!) sequence\n\ followed by the name of an interpreter. If no such sequence is found,\n\ -Fortran is tried first; if no tags are found, C is tried next."); +Fortran is tried first; if no tags are found, C is tried next.\n\ +Compressed files are supported using gzip and bzip2."); } #ifndef VERSION @@ -686,7 +678,7 @@ { enum argument_type arg_type; char *what; - language *lang; + language *lang; /* language of the regexp */ } argument; #ifdef VMS /* VMS specific functions */ @@ -904,10 +896,7 @@ case 'o': if (tagfile) { - /* convert char to string, to call error with */ - char buf[2]; - sprintf (buf, "%c", opt); - error ("-%s option may only be given once.", buf); + error ("-%c option may only be given once.", opt); suggest_asking_for_help (); } tagfile = optarg; @@ -1087,6 +1076,8 @@ if (cxref_style) { put_entries (head); + free_tree (head); + head = NULL; exit (GOOD); } @@ -1110,6 +1101,8 @@ if (tagf == NULL) pfatal (tagfile); put_entries (head); + free_tree (head); + head = NULL; fclose (tagf); if (update) @@ -1122,6 +1115,30 @@ } + +/* + * Return a compressor given the file name. + * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> + */ +compressor * +get_compressor_from_suffix (file) + char *file; +{ + compressor *compr; + char *suffix; + + suffix = etags_strrchr (file, '.'); + if (suffix == NULL) + return NULL; + suffix += 1; + for (compr = compressors; compr->suffix != NULL; compr++) + if (streq (compr->suffix, suffix)) + return compr; + return NULL; +} + + + /* * Return a language given the name. */ @@ -1169,27 +1186,29 @@ /* - * Return a language given the file suffix. + * Return a language given the file name. */ language * -get_language_from_suffix (suffix) - char *suffix; +get_language_from_suffix (file) + char *file; { language *lang; - char **ext; - + char **ext, *suffix; + + suffix = etags_strrchr (file, '.'); if (suffix == NULL) return NULL; + suffix += 1; for (lang = lang_names; lang->name != NULL; lang++) if (lang->suffixes != NULL) for (ext = lang->suffixes; *ext != NULL; ext++) if (streq (*ext, suffix)) - return lang; - + return lang; return NULL; } + /* * This routine is called on each file argument. */ @@ -1199,41 +1218,96 @@ { struct stat stat_buf; FILE *inf; + compressor *compr; + char *compressed_name, *uncompressed_name; + char *real_name; canonicalize_filename (file); - if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode)) - { - error ("skipping %s: it is not a regular file.", file); - return; - } if (streq (file, tagfile) && !streq (tagfile, "-")) { error ("skipping inclusion of %s in self.", file); return; } - inf = fopen (file, "r"); + if ((compr = get_compressor_from_suffix (file)) == NULL) + { + compressed_name = NULL; + real_name = uncompressed_name = savestr (file); + } + else + { + real_name = compressed_name = savestr (file); + uncompressed_name = savenstr (file, strlen(file) - compr->sufflen - 1); + } + if (stat (real_name, &stat_buf) != 0) + { + /* Reset real_name and try with a different name. */ + real_name = NULL; + if (compressed_name != NULL) /* try with the given suffix */ + { + if (stat (uncompressed_name, &stat_buf) == 0) + real_name = uncompressed_name; + } + else /* try all possible suffixes */ + { + for (compr = compressors; compr->suffix != NULL; compr++) + { + compressed_name = concat (file, ".", compr->suffix); + if (stat (compressed_name, &stat_buf) != 0) + free (compressed_name); + else + { + real_name = compressed_name; + break; + } + } + } + if (real_name == NULL) + { + perror (file); + goto exit; + } + } /* try with a different name */ + + if (!S_ISREG (stat_buf.st_mode)) + { + error ("skipping %s: it is not a regular file.", real_name); + goto exit; + } + if (real_name == compressed_name) + { + char *cmd = concat (compr->command, " ", real_name); + inf = popen (cmd, "r"); + free (cmd); + } + else + inf = fopen (real_name, "r"); if (inf == NULL) { - perror (file); - return; + perror (real_name); + goto exit; } - find_entries (file, inf); + find_entries (uncompressed_name, inf); + + if (real_name == compressed_name) + pclose (inf); + else + fclose (inf); if (!CTAGS) { char *filename; - if (filename_is_absolute (file)) + if (filename_is_absolute (uncompressed_name)) { /* file is an absolute file name. Canonicalise it. */ - filename = absolute_filename (file, cwd); + filename = absolute_filename (uncompressed_name, cwd); } else { /* file is a file name relative to cwd. Make it relative to the directory of the tags file. */ - filename = relative_filename (file, tagfiledir); + filename = relative_filename (uncompressed_name, tagfiledir); } fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head)); free (filename); @@ -1241,6 +1315,11 @@ free_tree (head); head = NULL; } + + exit: + if (compressed_name) free(compressed_name); + if (uncompressed_name) free(uncompressed_name); + return; } /* @@ -1286,6 +1365,11 @@ language *lang; node *old_last_node; + /* Memory leakage here: the string pointed by curfile is + never released, because curfile is copied into np->file + for each node, to be used in CTAGS mode. The amount of + memory leaked here is the sum of the lengths of the + file names. */ curfile = savestr (file); /* If user specified a language, use it. */ @@ -1294,24 +1378,16 @@ { curlang = lang; lang->function (inf); - free (curfile); - fclose (inf); return; } - cp = etags_strrchr (file, '.'); - if (cp != NULL) + /* Try to guess the language given the file name. */ + lang = get_language_from_suffix (file); + if (lang != NULL && lang->function != NULL) { - cp += 1; - lang = get_language_from_suffix (cp); - if (lang != NULL && lang->function != NULL) - { - curlang = lang; - lang->function (inf); - free (curfile); - fclose (inf); - return; - } + curlang = lang; + lang->function (inf); + return; } /* Look for sharp-bang as the first two characters. */ @@ -1340,12 +1416,13 @@ { curlang = lang; lang->function (inf); - fclose (inf); - free (curfile); return; } } } + /* We rewind here, even if inf may be a pipe. We fail if the + length of the first line is longer than the pipe block size, + which is unlikely. */ rewind (inf); /* Try Fortran. */ @@ -1356,12 +1433,12 @@ /* No Fortran entries found. Try C. */ if (old_last_node == last_node) { + /* We do not tag if rewind fails. + Only the file name will be recorded in the tags file. */ rewind (inf); curlang = get_language_from_name (cplusplus ? "c++" : "c"); default_C_entries (inf); } - free (curfile); - fclose (inf); return; } @@ -1386,10 +1463,10 @@ if (CTAGS && !cxref_style && streq (name, "main")) { register char *fp = etags_strrchr (curfile, '/'); - np->name = concat ("M", fp == 0 ? curfile : fp + 1, ""); + np->name = concat ("M", fp == NULL ? curfile : fp + 1, ""); fp = etags_strrchr (np->name, '.'); - if (fp && fp[1] != '\0' && fp[2] == '\0') - fp[0] = 0; + if (fp != NULL && fp[1] != '\0' && fp[2] == '\0') + fp[0] = '\0'; } else np->name = name; @@ -1628,7 +1705,6 @@ } /* Length of a number's decimal representation. */ -int number_len PP ((long num)); int number_len (num) long num; @@ -1680,6 +1756,7 @@ st_C_gnumacro, st_C_ignore, st_C_javastruct, + st_C_operator, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec }; @@ -1706,6 +1783,7 @@ enum, 0, st_C_enum typedef, 0, st_C_typedef define, 0, st_C_define +operator, C_PLPL, st_C_operator bool, C_PLPL, st_C_typespec long, 0, st_C_typespec short, 0, st_C_typespec @@ -1736,125 +1814,120 @@ %] and replace lines between %< and %> with its output. */ /*%<*/ -/* starting time is 10:15:51 */ -/* C code produced by gperf version 2.1 (K&R C version) */ +/* C code produced by gperf version 2.5 (GNU C++ version) */ /* Command-line: gperf -c -k 1,3 -o -p -r -t */ - - struct C_stab_entry { char *name; int c_ext; enum sym_type type; }; +#define TOTAL_KEYWORDS 41 #define MIN_WORD_LENGTH 3 #define MAX_WORD_LENGTH 15 -#define MIN_HASH_VALUE 11 -#define MAX_HASH_VALUE 117 -/* - 40 keywords - 107 is the maximum key range -*/ - -static int +#define MIN_HASH_VALUE 20 +#define MAX_HASH_VALUE 136 +/* maximum key range = 117, duplicates = 0 */ + +static unsigned int hash (str, len) register char *str; - register unsigned int len; + register int unsigned len; { - static unsigned char hash_table[] = + static unsigned char asso_values[] = { - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 1, 117, 117, 117, 2, 42, - 16, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 5, 117, 117, 21, 54, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 24, 19, 43, - 2, 35, 3, 10, 117, 26, 117, 117, 9, 20, - 35, 9, 61, 117, 40, 52, 10, 57, 3, 117, - 117, 117, 117, 117, 117, 117, 117, 117 - }; - return len + hash_table[(int) str[2]] + hash_table[(int) str[0]]; + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 58, 137, 137, 137, 38, 37, + 45, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 62, 137, 137, 14, 16, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 26, 16, 51, + 18, 61, 5, 19, 137, 23, 137, 137, 32, 63, + 54, 10, 26, 137, 24, 42, 30, 18, 46, 137, + 137, 137, 137, 137, 137, 137, 137, 137, + }; + return len + asso_values[str[2]] + asso_values[str[0]]; } -struct C_stab_entry * in_word_set PP ((char *str, unsigned int len)); struct C_stab_entry * in_word_set (str, len) register char *str; register unsigned int len; { - - static struct C_stab_entry wordlist[] = + static struct C_stab_entry wordlist[] = { {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"float", 0, st_C_typespec}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"define", 0, st_C_define}, - {"",}, {"",}, {"",}, {"",}, {"",}, - {"float", 0, st_C_typespec}, - {"",}, {"",}, - {"volatile", 0, st_C_typespec}, - {"",}, {"",}, - {"DEFUN", 0, st_C_gnumacro}, - {"",}, {"",}, {"",}, {"",}, - {"domain", C_STAR, st_C_struct}, + {"bool", C_PLPL, st_C_typespec}, {"",}, {"",}, {"",}, - {"bool", C_PLPL, st_C_typespec}, - {"void", 0, st_C_typespec}, - {"",}, {"friend", C_PLPL, st_C_ignore}, - {"@implementation", 0, st_C_objimpl}, - {"mutable", C_PLPL, st_C_typespec}, - {"auto", 0, st_C_typespec}, + {"SYSCALL", 0, st_C_gnumacro}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"double", 0, st_C_typespec}, + {"",}, {"",}, {"",}, + {"union", 0, st_C_struct}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"import", C_JAVA, st_C_ignore}, {"int", 0, st_C_typespec}, - {"@end", 0, st_C_objend}, - {"",}, {"",}, {"",}, {"",}, - {"interface", C_JAVA, st_C_struct}, - {"@interface", 0, st_C_objprot}, + {"short", 0, st_C_typespec}, + {"ENTRY", 0, st_C_gnumacro}, + {"implements", C_JAVA, st_C_javastruct}, + {"auto", 0, st_C_typespec}, {"",}, - {"long", 0, st_C_typespec}, - {"SYSCALL", 0, st_C_gnumacro}, - {"@protocol", 0, st_C_objprot}, - {"extern", 0, st_C_typespec}, - {"extends", C_JAVA, st_C_javastruct}, - {"PSEUDO", 0, st_C_gnumacro}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"",}, - {"namespace", C_PLPL, st_C_struct}, - {"double", 0, st_C_typespec}, - {"short", 0, st_C_typespec}, - {"",}, - {"signed", 0, st_C_typespec}, - {"",}, {"",}, - {"char", 0, st_C_typespec}, - {"class", C_PLPL, st_C_struct}, - {"",}, {"",}, {"",}, {"",}, {"",}, + {"interface", C_JAVA, st_C_struct}, {"typedef", 0, st_C_typedef}, {"typename", C_PLPL, st_C_typespec}, {"",}, {"",}, + {"signed", 0, st_C_typespec}, + {"unsigned", 0, st_C_typespec}, + {"",}, {"",}, {"",}, + {"struct", 0, st_C_struct}, + {"void", 0, st_C_typespec}, {"static", 0, st_C_typespec}, - {"const", 0, st_C_typespec}, {"",}, {"",}, {"",}, {"",}, - {"union", 0, st_C_struct}, - {"",}, {"",}, {"",}, {"",}, - {"import", C_JAVA, st_C_ignore}, - {"",}, {"",}, + {"operator", C_PLPL, st_C_operator}, + {"",}, + {"char", 0, st_C_typespec}, + {"class", C_PLPL, st_C_struct}, {"enum", 0, st_C_enum}, - {"implements", C_JAVA, st_C_javastruct}, - {"struct", 0, st_C_struct}, - {"",}, {"",}, - {"ENTRY", 0, st_C_gnumacro}, - {"",}, {"",}, + {"package", C_JAVA, st_C_ignore}, + {"",}, + {"volatile", 0, st_C_typespec}, + {"domain", C_STAR, st_C_struct}, + {"DEFUN", 0, st_C_gnumacro}, + {"",}, + {"long", 0, st_C_typespec}, + {"@protocol", 0, st_C_objprot}, + {"",}, {"",}, {"",}, {"explicit", C_PLPL, st_C_typespec}, - {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"package", C_JAVA, st_C_ignore}, + {"",}, + {"extern", 0, st_C_typespec}, + {"extends", C_JAVA, st_C_javastruct}, + {"",}, + {"mutable", C_PLPL, st_C_typespec}, + {"",}, {"",}, {"",}, {"",}, + {"PSEUDO", 0, st_C_gnumacro}, + {"",}, {"",}, {"",}, {"",}, + {"const", 0, st_C_typespec}, {"",}, {"",}, {"",}, {"",}, {"",}, - {"unsigned", 0, st_C_typespec}, + {"@end", 0, st_C_objend}, + {"",}, {"",}, {"",}, {"",}, {"",}, + {"@interface", 0, st_C_objprot}, + {"",}, {"",}, {"",}, + {"namespace", C_PLPL, st_C_struct}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"@implementation", 0, st_C_objimpl}, }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { register int key = hash (str, len); - if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) + if (key <= MAX_HASH_VALUE && key >= 0) { register char *s = wordlist[key].name; @@ -1864,10 +1937,8 @@ } return 0; } -/* ending time is 10:15:52 */ /*%>*/ -enum sym_type C_symtype PP ((char *str, int len, int c_ext)); enum sym_type C_symtype (str, len, c_ext) char *str; @@ -1888,6 +1959,7 @@ enum { fvnone, /* nothing seen */ + foperator, /* func: operator keyword seen (cplpl) */ fvnameseen, /* function or variable name seen */ fstartlist, /* func: just after open parenthesis */ finlist, /* func: in parameter list */ @@ -2012,11 +2084,6 @@ * *IS_FUNC gets TRUE iff the token is a function or #define macro * with args. C_EXT is which language we are looking at. * - * In the future we will need some way to adjust where the end of - * the token is; for instance, implementing the C++ keyword - * `operator' properly will adjust the end of the token to be after - * whatever follows `operator'. - * * Globals * fvdef IN OUT * structdef IN OUT @@ -2025,13 +2092,12 @@ * objdef IN OUT * next_token_is_func IN OUT */ -bool consider_token PP ((char *str, int len, int c, int c_ext, - int cblev, int parlev, bool *is_func_or_var)); + bool consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) register char *str; /* IN: token pointer */ register int len; /* IN: token length */ - register int c; /* IN: first char after the token */ + register char c; /* IN: first char after the token */ int c_ext; /* IN: C extensions mask */ int cblev; /* IN: curly brace level */ int parlev; /* IN: parenthesis level */ @@ -2267,6 +2333,10 @@ case st_C_ignore: fvdef = vignore; return FALSE; + case st_C_operator: + fvdef = foperator; + *is_func_or_var = TRUE; + return TRUE; case st_none: if (constantypedefs && structdef == sinbody && structtype == st_C_enum) return TRUE; @@ -2320,7 +2390,6 @@ } while (0) -void make_C_tag PP ((bool isfun)); void make_C_tag (isfun) bool isfun; @@ -2561,7 +2630,19 @@ && funorvar) /* function or var defined in C++ class body */ { - int len = strlen (structtag) + qlen + toklen; + int len; + if (fvdef == foperator) + { + char *oldlp = lp; + lp = skip_spaces (lp-1); + while (*lp != '\0' + && !isspace (*lp) && *lp != '(') + lp += 1; + c = *lp++; + toklen += lp - oldlp; + } + + len = strlen (structtag) + qlen + toklen; grow_linebuffer (&token_name, len + 1); strcpy (token_name.buffer, structtag); strcat (token_name.buffer, qualifier); @@ -2610,6 +2691,7 @@ if (definedef == dnone && (fvdef == fvnameseen + || fvdef == foperator || structdef == stagseen || typdef == tend || objdef != onone)) @@ -2746,6 +2828,7 @@ } switch (fvdef) { + case foperator: case finlist: case fignore: case vignore: @@ -2771,6 +2854,7 @@ } switch (fvdef) { + case foperator: case finlist: case fignore: case vignore: @@ -2807,6 +2891,7 @@ break; } /* switch (typdef) */ break; + case foperator: /* operator() is not handled */ case fvnameseen: fvdef = fstartlist; break; @@ -2924,6 +3009,7 @@ break; switch (fvdef) { + case foperator: case finlist: case fignore: case vignore: @@ -2948,9 +3034,17 @@ case '^': case '!': case '<': case '>': case '.': case '?': case ']': if (definedef != dnone) break; - /* These surely cannot follow a function tag. */ - if (fvdef != finlist && fvdef != fignore && fvdef != vignore) - fvdef = fvnone; + /* These surely cannot follow a function tag in C. */ + switch (fvdef) + { + case foperator: + case finlist: + case fignore: + case vignore: + break; + default: + fvdef = fvnone; + } break; case '\0': if (objdef == otagseen) @@ -3048,7 +3142,6 @@ /* Fortran parsing */ -bool tail PP ((char *cp)); bool tail (cp) char *cp; @@ -3088,7 +3181,6 @@ while (isdigit (*dbp)); } -void getit PP ((FILE *inf)); void getit (inf) FILE *inf; @@ -3113,7 +3205,7 @@ return; for (cp = dbp + 1; *cp && intoken (*cp); cp++) continue; - pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE, + pfnote (savenstr (dbp, cp-dbp), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } @@ -3177,13 +3269,19 @@ getit (inf); continue; case 'p': - if (tail ("program")) + if (tail ("program") || tail ("procedure")) + getit (inf); + continue; + case 'b': + if (tail ("blockdata") || tail ("block data")) { - getit (inf); - continue; + dbp = skip_spaces (dbp); + if (*dbp == '\0') /* assume un-named */ + pfnote (savestr ("blockdata"), TRUE, + lb.buffer, dbp - lb.buffer, lineno, linecharno); + else + getit (inf); /* look for name */ } - if (tail ("procedure")) - getit (inf); continue; } } @@ -3241,10 +3339,11 @@ cp = skip_spaces (cp); if (*cp != '\0') { + char *sp = cp; while (*cp != '\0' && !isspace (*cp) && *cp != '{' && *cp != '(') cp++; - pfnote ((CTAGS) ? savenstr(lb.buffer, cp-lb.buffer) : NULL, TRUE, + pfnote (savenstr (sp, cp-sp), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } } @@ -3306,7 +3405,7 @@ cp = skip_spaces (cp); while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':') cp++; - pfnote ((char *) NULL, TRUE, + pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } @@ -3320,7 +3419,7 @@ cp = skip_spaces (cp); while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':') cp++; - pfnote ((char *) NULL, TRUE, + pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } } @@ -3350,7 +3449,7 @@ for (ep = bp; isalnum (*ep) || *ep == '-'; ep++) continue; if (*ep++ == '.') - pfnote ((CTAGS) ? savenstr (bp, ep-bp) : NULL, TRUE, + pfnote (savenstr (bp, ep-bp), TRUE, lb.buffer, ep - lb.buffer + 1, lineno, linecharno); } } @@ -3508,7 +3607,7 @@ /* grab block name */ for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++) continue; - namebuf = (CTAGS) ? savenstr (dbp, cp-dbp) : NULL; + namebuf = savenstr (dbp, cp-dbp); dbp = cp; /* set dbp to e-o-token */ save_len = dbp - lb.buffer + 1; get_tagname = FALSE; @@ -3541,7 +3640,6 @@ * lisp tag functions * look for (def or (DEF, quote or QUOTE */ -int L_isdef PP ((char *strp)); int L_isdef (strp) register char *strp; @@ -3550,7 +3648,7 @@ && (strp[2] == 'e' || strp[2] == 'E') && (strp[3] == 'f' || strp[3] == 'F')); } -int L_isquote PP ((char *strp)); + int L_isquote (strp) register char *strp; @@ -3563,7 +3661,6 @@ && isspace (*++strp)); } -void L_getit PP ((void)); void L_getit () { @@ -3587,7 +3684,7 @@ if (cp == dbp) return; - pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE, + pfnote (savenstr (dbp, cp-dbp), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } @@ -3664,7 +3761,7 @@ * look for (set! xyzzy */ -void get_scheme PP ((void)); +void get_scheme (); void Scheme_functions (inf) @@ -3709,7 +3806,7 @@ *cp != '\0' && *cp != '(' && *cp != ')' && !isspace (*cp); cp++) continue; - pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE, + pfnote (savenstr (dbp, cp-dbp), TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); } @@ -3733,9 +3830,9 @@ :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ :part:appendix:entry:index"; -void TEX_mode PP ((FILE *inf)); -struct TEX_tabent *TEX_decode_env PP ((char *evarname, char *defenv)); -int TEX_Token PP ((char *cp)); +void TEX_mode (); +struct TEX_tabent *TEX_decode_env (); +int TEX_Token (); char TEX_esc = '\\'; char TEX_opgrp = '{'; @@ -3819,6 +3916,8 @@ TEX_opgrp = '<'; TEX_clgrp = '>'; } + /* If the input file is compressed, inf is a pipe, and rewind may fail. + No attempt is made to correct the situation. */ rewind (inf); } @@ -3842,7 +3941,6 @@ { char *oldenv = env; env = concat (oldenv, defenv, ""); - free (oldenv); } /* Allocate a token table */ @@ -3900,9 +3998,9 @@ * Assumes that the predicate starts at column 0. * Only the first clause of a predicate is added. */ -int prolog_pred PP ((char *s, char *last)); -void prolog_skip_comment PP ((linebuffer *plb, FILE *inf)); -int prolog_atom PP ((char *s, int pos)); +int prolog_pred (); +void prolog_skip_comment (); +int prolog_atom (); void Prolog_functions (inf) @@ -3990,7 +4088,7 @@ /* Save only the first clause. */ if (last == NULL - || len != strlen (last) + || len != (int)strlen (last) || !strneq (s, last, len)) { pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE, @@ -4067,9 +4165,9 @@ * * Assumes that Erlang functions start at column 0. */ -int erlang_func PP ((char *s, char *last)); -void erlang_attribute PP ((char *s)); -int erlang_atom PP ((char *s, int pos)); +int erlang_func (); +void erlang_attribute (); +int erlang_atom (); void Erlang_functions (inf) @@ -4144,7 +4242,7 @@ /* Save only the first clause. */ if (s[pos++] == '(' && (last == NULL - || len != strlen (last) + || len != (int)strlen (last) || !strneq (s, last, len))) { pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE, @@ -4246,7 +4344,6 @@ an unquoted separator. Also turns "\t" into a Tab character. Returns pointer to terminating separator. Works in place. Null terminates name string. */ -char * scan_separators PP ((char *name)); char * scan_separators (name) char *name; @@ -4406,7 +4503,6 @@ * Do the substitutions indicated by the regular expression and * arguments. */ -char * substitute PP ((char *in, char *out, struct re_registers *regs)); char * substitute (in, out, regs) char *in, *out; @@ -4449,7 +4545,7 @@ *t++ = *out; *t = '\0'; - if (DEBUG && (t > result + size || t - result != strlen (result))) + if (DEBUG && (t > result + size || t - result != (int)strlen (result))) abort (); return result; @@ -4648,8 +4744,7 @@ */ char * etags_strrchr (sp, c) - register char *sp; - register int c; + register char *sp, c; { register char *r; @@ -4671,8 +4766,7 @@ */ char * etags_strchr (sp, c) - register char *sp; - register int c; + register char *sp, c; { do { @@ -4736,7 +4830,7 @@ /* Print error message. `s1' is printf control string, `s2' is arg for it. */ void error (s1, s2) - const char *s1, *s2; + char *s1, *s2; { fprintf (stderr, "%s: ", progname); fprintf (stderr, s1, s2); @@ -4952,6 +5046,7 @@ *fn = '/'; #else /* No action. */ + fn = NULL; /* shut up the compiler */ #endif }