1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98, 99
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey.
31 * Francesco Potorti` (pot@gnu.org) is the current maintainer.
34 char pot_etags_version[] = "@(#) pot revision number is 13.44";
43 #if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
44 # define P_(proto) proto
51 /* On some systems, Emacs defines static as nothing for the sake
52 of unexec. We don't want that here since we don't use unexec. */
54 # define ETAGS_REGEXPS /* use the regexp features */
55 # define LONG_OPTIONS /* accept long options */
56 #endif /* HAVE_CONFIG_H */
59 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
68 # define MAXPATHLEN _MAX_PATH
71 # endif /* undef HAVE_GETCWD */
72 #else /* !WIN32_NATIVE */
77 extern char *getenv ();
79 #endif /* !WIN32_NATIVE */
84 # if defined (HAVE_GETCWD) && !defined (WIN32_NATIVE)
85 extern char *getcwd (char *buf, size_t size);
87 #endif /* HAVE_UNISTD_H */
95 #include <sys/types.h>
98 #if !defined (S_ISREG) && defined (S_IFREG)
99 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
105 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
107 extern int optind, opterr;
108 #endif /* LONG_OPTIONS */
112 #endif /* ETAGS_REGEXPS */
114 /* Define CTAGS to make the program "ctags" compatible with the usual one.
115 Leave it undefined to make the program "etags", which makes emacs-style
116 tag tables and tags typedefs, #defines and struct/union/enum by default. */
124 /* Exit codes for success and failure. */
134 #define C_PLPL 0x00001 /* C++ */
135 #define C_STAR 0x00003 /* C* */
136 #define C_JAVA 0x00005 /* JAVA */
137 #define YACC 0x10000 /* yacc file */
139 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
140 && (abort (), 1)) || !strcmp (s, t))
141 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
142 && (abort (), 1)) || !strncmp (s, t, n))
144 #define lowcase(c) tolower ((char)c)
146 #define CHARS 256 /* 2^sizeof(char) */
147 #define CHAR(x) ((unsigned int)x & (CHARS - 1))
148 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
149 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
150 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
151 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
152 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
156 * xnew, xrnew -- allocate, reallocate storage
158 * SYNOPSIS: Type *xnew (int n, Type);
159 * Type *xrnew (OldPointer, int n, Type);
162 # include "chkmalloc.h"
163 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
164 (n) * sizeof (Type)))
165 # define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \
166 (op), (n) * sizeof (Type)))
168 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
169 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type)))
174 typedef void Lang_function P_((FILE *));
179 char *command; /* Takes one arg and decompresses to stdout */
185 Lang_function *function;
190 typedef struct node_st
191 { /* sorting structure */
192 char *name; /* function or type name */
193 char *file; /* file name */
194 bool is_func; /* use pattern or line no */
195 bool been_warned; /* set if noticed dup */
196 int lno; /* line number tag is on */
197 long cno; /* character number line starts on */
198 char *pat; /* search pattern */
199 struct node_st *left, *right; /* left and right sons */
203 * A `linebuffer' is a structure which holds a line of text.
204 * `readline_internal' reads a line from a stream into a linebuffer
205 * and works regardless of the length of the line.
206 * SIZE is the size of BUFFER, LEN is the length of the string in
207 * BUFFER after readline reads it.
216 /* Many compilers barf on this:
217 Lang_function Ada_funcs;
218 so let's write it this way */
219 static void Ada_funcs P_((FILE *));
220 static void Asm_labels P_((FILE *));
221 static void C_entries P_((int c_ext, FILE *));
222 static void default_C_entries P_((FILE *));
223 static void plain_C_entries P_((FILE *));
224 static void Cjava_entries P_((FILE *));
225 static void Cobol_paragraphs P_((FILE *));
226 static void Cplusplus_entries P_((FILE *));
227 static void Cstar_entries P_((FILE *));
228 static void Erlang_functions P_((FILE *));
229 static void Fortran_functions P_((FILE *));
230 static void Yacc_entries P_((FILE *));
231 static void Lisp_functions P_((FILE *));
232 static void Pascal_functions P_((FILE *));
233 static void Perl_functions P_((FILE *));
234 static void Postscript_functions P_((FILE *));
235 static void Prolog_functions P_((FILE *));
236 static void Python_functions P_((FILE *));
237 static void Scheme_functions P_((FILE *));
238 static void TeX_functions P_((FILE *));
239 static void just_read_file P_((FILE *));
241 static void print_language_names P_((void));
242 static void print_version P_((void));
243 static void print_help P_((void));
244 int main P_((int, char **));
245 static int number_len P_((long));
247 static compressor *get_compressor_from_suffix P_((char *, char **));
248 static language *get_language_from_name P_((char *));
249 static language *get_language_from_interpreter P_((char *));
250 static language *get_language_from_suffix P_((char *));
251 static int total_size_of_entries P_((node *));
252 static long readline P_((linebuffer *, FILE *));
253 static long readline_internal P_((linebuffer *, FILE *));
254 static void get_tag P_((char *));
257 static void analyse_regex P_((char *, bool));
258 static void add_regex P_((char *, bool, language *));
259 static void free_patterns P_((void));
260 #endif /* ETAGS_REGEXPS */
261 static void error P_((const char *, const char *));
262 static void suggest_asking_for_help P_((void));
263 static void fatal P_((char *, char *));
264 static void pfatal P_((char *));
265 static void add_node P_((node *, node **));
267 static void init P_((void));
268 static void initbuffer P_((linebuffer *));
269 static void find_entries P_((char *, FILE *));
270 static void free_tree P_((node *));
271 static void pfnote P_((char *, bool, char *, int, int, long));
272 static void new_pfnote P_((char *, int, bool, char *, int, int, long));
273 static void process_file P_((char *));
274 static void put_entries P_((node *));
275 static void takeprec P_((void));
277 static char *concat P_((char *, char *, char *));
278 static char *skip_spaces P_((char *));
279 static char *skip_non_spaces P_((char *));
280 static char *savenstr P_((char *, int));
281 static char *savestr P_((char *));
282 static char *etags_strchr P_((const char *, int));
283 static char *etags_strrchr P_((const char *, int));
284 static char *etags_getcwd P_((void));
285 static char *relative_filename P_((char *, char *));
286 static char *absolute_filename P_((char *, char *));
287 static char *absolute_dirname P_((char *, char *));
288 static bool filename_is_absolute P_((char *f));
289 static void canonicalize_filename P_((char *));
290 static void grow_linebuffer P_((linebuffer *, int));
291 static long *xmalloc P_((unsigned int));
292 static long *xrealloc P_((char *, unsigned int));
295 char searchar = '/'; /* use /.../ searches */
297 char *tagfile; /* output file */
298 char *progname; /* name this program was invoked with */
299 char *cwd; /* current working directory */
300 char *tagfiledir; /* directory of tagfile */
301 FILE *tagf; /* ioptr for tags file */
303 char *curfile; /* current input file name */
304 language *curlang; /* current language */
306 int lineno; /* line number of current line */
307 long charno; /* current character number */
308 long linecharno; /* charno of start of current line */
309 char *dbp; /* pointer to start of current tag */
311 node *head; /* the head of the binary tree of tags */
313 linebuffer lb; /* the current line */
314 linebuffer token_name; /* used by C_entries as a temporary area */
318 linebuffer lb; /* used by C_entries instead of lb */
321 /* boolean "functions" (see init) */
322 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
325 *white = " \f\t\n\r\v",
327 *nonam = " \f\t\n\r(=,[;",
328 /* token ending chars */
329 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
330 /* token starting chars */
331 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
332 /* valid in-token chars */
333 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
335 bool append_to_tagfile; /* -a: append to tags */
336 /* The following four default to TRUE for etags, but to FALSE for ctags. */
337 bool typedefs; /* -t: create tags for C and Ada typedefs */
338 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */
339 /* 0 struct/enum/union decls, and C++ */
340 /* member functions. */
341 bool constantypedefs; /* -d: create tags for C #define, enum */
342 /* constants and variables. */
343 /* -D: opposite of -d. Default under ctags. */
344 bool declarations; /* --declarations: tag them and extern in C&Co*/
345 bool globals; /* create tags for global variables */
346 bool members; /* create tags for C member variables */
347 bool update; /* -u: update tags */
348 bool vgrind_style; /* -v: create vgrind style index output */
349 bool no_warnings; /* -w: suppress warnings */
350 bool cxref_style; /* -x: create cxref style output */
351 bool cplusplus; /* .[hc] means C++, not C */
352 bool noindentypedefs; /* -I: ignore indentation in C */
353 bool packages_only; /* --packages-only: in Ada, only tag packages*/
356 struct option longopts[] =
358 { "packages-only", no_argument, &packages_only, TRUE },
359 { "append", no_argument, NULL, 'a' },
360 { "backward-search", no_argument, NULL, 'B' },
361 { "c++", no_argument, NULL, 'C' },
362 { "cxref", no_argument, NULL, 'x' },
363 { "defines", no_argument, NULL, 'd' },
364 { "declarations", no_argument, &declarations, TRUE },
365 { "no-defines", no_argument, NULL, 'D' },
366 { "globals", no_argument, &globals, TRUE },
367 { "no-globals", no_argument, &globals, FALSE },
368 { "help", no_argument, NULL, 'h' },
369 { "help", no_argument, NULL, 'H' },
370 { "ignore-indentation", no_argument, NULL, 'I' },
371 { "include", required_argument, NULL, 'i' },
372 { "language", required_argument, NULL, 'l' },
373 { "members", no_argument, &members, TRUE },
374 { "no-members", no_argument, &members, FALSE },
375 { "no-warn", no_argument, NULL, 'w' },
376 { "output", required_argument, NULL, 'o' },
378 { "regex", required_argument, NULL, 'r' },
379 { "no-regex", no_argument, NULL, 'R' },
380 { "ignore-case-regex", required_argument, NULL, 'c' },
381 #endif /* ETAGS_REGEXPS */
382 { "typedefs", no_argument, NULL, 't' },
383 { "typedefs-and-c++", no_argument, NULL, 'T' },
384 { "update", no_argument, NULL, 'u' },
385 { "version", no_argument, NULL, 'V' },
386 { "vgrind", no_argument, NULL, 'v' },
389 #endif /* LONG_OPTIONS */
392 /* Structure defining a regular expression. Elements are
393 the compiled pattern, and the name string. */
394 typedef struct pattern
396 struct pattern *p_next;
399 struct re_pattern_buffer *pattern;
400 struct re_registers regs;
405 /* List of all regexps. */
406 pattern *p_head = NULL;
408 /* How many characters in the character set. (From regex.c.) */
409 #define CHAR_SET_SIZE 256
410 /* Translation table for case-insensitive matching. */
411 char lc_trans[CHAR_SET_SIZE];
412 #endif /* ETAGS_REGEXPS */
414 compressor compressors[] =
416 { "z", "gzip -d -c"},
417 { "Z", "gzip -d -c"},
418 { "gz", "gzip -d -c"},
419 { "GZ", "gzip -d -c"},
420 { "bz2", "bzip2 -d -c" },
428 /* Non-NULL if language fixed. */
429 language *forced_lang = NULL;
432 char *Ada_suffixes [] =
433 { "ads", "adb", "ada", NULL };
436 char *Asm_suffixes [] = { "a", /* Unix assembler */
437 "asm", /* Microcontroller assembly */
438 "def", /* BSO/Tasking definition includes */
439 "inc", /* Microcontroller include files */
440 "ins", /* Microcontroller include files */
441 "s", "sa", /* Unix assembler */
442 "S", /* cpp-processed Unix assembler */
443 "src", /* BSO/Tasking C compiler output */
447 /* Note that .c and .h can be considered C++, if the --c++ flag was
448 given. That is why default_C_entries is called here. */
449 char *default_C_suffixes [] =
452 char *Cplusplus_suffixes [] =
453 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
454 "M", /* Objective C++ */
455 "pdb", /* Postscript with C syntax */
458 char *Cjava_suffixes [] =
461 char *Cobol_suffixes [] =
462 { "COB", "cob", NULL };
464 char *Cstar_suffixes [] =
465 { "cs", "hs", NULL };
467 char *Erlang_suffixes [] =
468 { "erl", "hrl", NULL };
470 char *Fortran_suffixes [] =
471 { "F", "f", "f90", "for", NULL };
473 char *Lisp_suffixes [] =
474 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
476 char *Pascal_suffixes [] =
477 { "p", "pas", NULL };
479 char *Perl_suffixes [] =
480 { "pl", "pm", NULL };
481 char *Perl_interpreters [] =
482 { "perl", "@PERL@", NULL };
484 char *plain_C_suffixes [] =
485 { "pc", /* Pro*C file */
486 "m", /* Objective C file */
487 "lm", /* Objective lex file */
490 char *Postscript_suffixes [] =
491 { "ps", "psw", NULL }; /* .psw is for PSWrap */
493 char *Prolog_suffixes [] =
496 char *Python_suffixes [] =
499 /* Can't do the `SCM' or `scm' prefix with a version number. */
500 char *Scheme_suffixes [] =
501 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "ss", "t", NULL };
503 char *TeX_suffixes [] =
504 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
506 char *Yacc_suffixes [] =
507 { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */
510 * Table of languages.
512 * It is ok for a given function to be listed under more than one
513 * name. I just didn't.
516 language lang_names [] =
518 { "ada", Ada_funcs, Ada_suffixes, NULL },
519 { "asm", Asm_labels, Asm_suffixes, NULL },
520 { "c", default_C_entries, default_C_suffixes, NULL },
521 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
522 { "c*", Cstar_entries, Cstar_suffixes, NULL },
523 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL },
524 { "erlang", Erlang_functions, Erlang_suffixes, NULL },
525 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
526 { "java", Cjava_entries, Cjava_suffixes, NULL },
527 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
528 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
529 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
530 { "postscript", Postscript_functions, Postscript_suffixes, NULL },
531 { "proc", plain_C_entries, plain_C_suffixes, NULL },
532 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
533 { "python", Python_functions, Python_suffixes, NULL },
534 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
535 { "tex", TeX_functions, TeX_suffixes, NULL },
536 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
537 { "auto", NULL }, /* default guessing scheme */
538 { "none", just_read_file }, /* regexp matching only */
539 { NULL, NULL } /* end of list */
543 print_language_names ()
548 puts ("\nThese are the currently supported languages, along with the\n\
549 default file name suffixes:");
550 for (lang = lang_names; lang->name != NULL; lang++)
552 printf ("\t%s\t", lang->name);
553 if (lang->suffixes != NULL)
554 for (ext = lang->suffixes; *ext != NULL; ext++)
555 printf (" .%s", *ext);
558 puts ("Where `auto' means use default language for files based on file\n\
559 name suffix, and `none' means only do regexp processing on files.\n\
560 If no language is specified and no matching suffix is found,\n\
561 the first line of the file is read for a sharp-bang (#!) sequence\n\
562 followed by the name of an interpreter. If no such sequence is found,\n\
563 Fortran is tried first; if no tags are found, C is tried next.\n\
564 Compressed files are supported using gzip and bzip2.");
568 # define EMACS_NAME "GNU Emacs"
571 # define VERSION "21"
576 printf ("%s (%s %s)\n", (CTAGS) ? "ctags" : "etags", EMACS_NAME, VERSION);
577 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
578 puts ("This program is distributed under the same terms as Emacs");
586 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
588 These are the options accepted by %s.\n", progname, progname);
590 puts ("You may use unambiguous abbreviations for the long option names.");
592 puts ("Long option names do not work with this executable, as it is not\n\
593 linked with GNU getopt.");
594 #endif /* LONG_OPTIONS */
595 puts ("A - as file name means read names from stdin (one per line).");
597 printf (" Absolute names are stored in the output file as they are.\n\
598 Relative ones are stored relative to the output file's directory.");
601 puts ("-a, --append\n\
602 Append tag entries to existing tags file.");
604 puts ("--packages-only\n\
605 For Ada files, only generate tags for packages .");
608 puts ("-B, --backward-search\n\
609 Write the search commands for the tag entries using '?', the\n\
610 backward-search command instead of '/', the forward-search command.");
613 Treat files whose name suffix defaults to C language as C++ files.");
615 puts ("--declarations\n\
616 In C and derived languages, create tags for function declarations,");
618 puts ("\tand create tags for extern variables if --globals is used.");
621 ("\tand create tags for extern variables unless --no-globals is used.");
624 puts ("-d, --defines\n\
625 Create tag entries for C #define constants and enum constants, too.");
627 puts ("-D, --no-defines\n\
628 Don't create tag entries for C #define constants and enum constants.\n\
629 This makes the tags file smaller.");
633 puts ("-i FILE, --include=FILE\n\
634 Include a note in tag file indicating that, when searching for\n\
635 a tag, one should also consult the tags file FILE after\n\
636 checking the current file.");
637 puts ("-l LANG, --language=LANG\n\
638 Force the following files to be considered as written in the\n\
639 named language up to the next --language=LANG option.");
644 Create tag entries for global variables in some languages.");
646 puts ("--no-globals\n\
647 Do not create tag entries for global variables in some\n\
648 languages. This makes the tags file smaller.");
650 Create tag entries for member variables in C and derived languages.");
653 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
654 Make a tag for each line matching pattern REGEXP in the following\n\
655 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
656 regexfile is a file containing one REGEXP per line.\n\
657 REGEXP is anchored (as if preceded by ^).\n\
658 The form /REGEXP/NAME/ creates a named tag.\n\
659 For example Tcl named tags can be created with:\n\
660 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
661 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
662 Like -r, --regex but ignore case when matching expressions.");
663 puts ("-R, --no-regex\n\
664 Don't create tags from regexps for the following files.");
665 #endif /* ETAGS_REGEXPS */
666 puts ("-o FILE, --output=FILE\n\
667 Write the tags to FILE.");
668 puts ("-I, --ignore-indentation\n\
669 Don't rely on indentation quite as much as normal. Currently,\n\
670 this means not to assume that a closing brace in the first\n\
671 column is the final brace of a function or structure\n\
672 definition in C and C++.");
676 puts ("-t, --typedefs\n\
677 Generate tag entries for C and Ada typedefs.");
678 puts ("-T, --typedefs-and-c++\n\
679 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
680 and C++ member functions.");
681 puts ("-u, --update\n\
682 Update the tag entries for the given files, leaving tag\n\
683 entries for other files in place. Currently, this is\n\
684 implemented by deleting the existing entries for the given\n\
685 files and then rewriting the new entries at the end of the\n\
686 tags file. It is often faster to simply rebuild the entire\n\
687 tag file than to use this.");
688 puts ("-v, --vgrind\n\
689 Generates an index of items intended for human consumption,\n\
690 similar to the output of vgrind. The index is sorted, and\n\
691 gives the page number of each item.");
692 puts ("-w, --no-warn\n\
693 Suppress warning messages about entries defined in multiple\n\
695 puts ("-x, --cxref\n\
696 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
697 The output uses line numbers instead of page numbers, but\n\
698 beyond that the differences are cosmetic; try both to see\n\
702 puts ("-V, --version\n\
703 Print the version of the program.\n\
705 Print this help message.");
707 print_language_names ();
710 puts ("Report bugs to bug-gnu-emacs@gnu.org");
724 /* This structure helps us allow mixing of --lang and file names. */
727 enum argument_type arg_type;
729 language *lang; /* language of the regexp */
732 #ifdef VMS /* VMS specific functions */
736 /* This is a BUG! ANY arbitrary limit is a BUG!
737 Won't someone please fix this? */
738 #define MAX_FILE_SPEC_LEN 255
741 char body[MAX_FILE_SPEC_LEN + 1];
745 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
746 returning in each successive call the next file name matching the input
747 spec. The function expects that each in_spec passed
748 to it will be processed to completion; in particular, up to and
749 including the call following that in which the last matching name
750 is returned, the function ignores the value of in_spec, and will
751 only start processing a new spec with the following call.
752 If an error occurs, on return out_spec contains the value
753 of in_spec when the error occurred.
755 With each successive file name returned in out_spec, the
756 function's return value is one. When there are no more matching
757 names the function returns zero. If on the first call no file
758 matches in_spec, or there is any other error, -1 is returned.
763 #define OUTSIZE MAX_FILE_SPEC_LEN
769 static long context = 0;
770 static struct dsc$descriptor_s o;
771 static struct dsc$descriptor_s i;
772 static bool pass1 = TRUE;
779 o.dsc$a_pointer = (char *) out;
780 o.dsc$w_length = (short)OUTSIZE;
781 i.dsc$a_pointer = in;
782 i.dsc$w_length = (short)strlen(in);
783 i.dsc$b_dtype = DSC$K_DTYPE_T;
784 i.dsc$b_class = DSC$K_CLASS_S;
785 o.dsc$b_dtype = DSC$K_DTYPE_VT;
786 o.dsc$b_class = DSC$K_CLASS_VS;
788 if ((status = lib$find_file(&i, &o, &context, 0, 0)) == RMS$_NORMAL)
790 out->body[out->curlen] = EOS;
793 else if (status == RMS$_NMF)
797 strcpy(out->body, in);
800 lib$find_file_end(&context);
806 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
807 name of each file specified by the provided arg expanding wildcards.
810 gfnames (arg, p_error)
814 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
816 switch (fn_exp (&filename, arg))
820 return filename.body;
826 return filename.body;
830 #ifndef OLD /* Newer versions of VMS do provide `system'. */
834 error ("%s", "system() function not implemented under VMS");
838 #define VERSION_DELIM ';'
839 char *massage_name (s)
845 if (*s == VERSION_DELIM)
863 unsigned int nincluded_files;
864 char **included_files;
867 int current_arg, file_count;
868 linebuffer filename_lb;
874 _fmode = O_BINARY; /* all of files are treated as binary files */
875 #endif /* WIN32_NATIVE */
879 included_files = xnew (argc, char *);
883 /* Allocate enough no matter what happens. Overkill, but each one
885 argbuffer = xnew (argc, argument);
888 /* Set syntax for regular expression routines. */
889 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS);
890 /* Translation table for case-insensitive search. */
891 for (i = 0; i < CHAR_SET_SIZE; i++)
892 lc_trans[i] = lowcase (i);
893 #endif /* ETAGS_REGEXPS */
896 * If etags, always find typedefs and structure tags. Why not?
897 * Also default is to find macro constants, enum constants and
902 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
913 optstring = "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
915 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH";
916 #endif /* ETAGS_REGEXPS */
919 optstring = optstring + 1;
920 #endif /* LONG_OPTIONS */
922 opt = getopt_long (argc, argv, optstring, longopts, 0);
929 /* If getopt returns 0, then it has already processed a
930 long-named option. We should do nothing. */
934 /* This means that a file name has been seen. Record it. */
935 argbuffer[current_arg].arg_type = at_filename;
936 argbuffer[current_arg].what = optarg;
941 /* Common options. */
942 case 'a': append_to_tagfile = TRUE; break;
943 case 'C': cplusplus = TRUE; break;
944 case 'd': constantypedefs = TRUE; break;
945 case 'D': constantypedefs = FALSE; break;
946 case 'f': /* for compatibility with old makefiles */
950 error ("-o option may only be given once.", (char *)NULL);
951 suggest_asking_for_help ();
956 case 'S': /* for backward compatibility */
957 noindentypedefs = TRUE;
961 language *lang = get_language_from_name (optarg);
964 argbuffer[current_arg].lang = lang;
965 argbuffer[current_arg].arg_type = at_language;
972 argbuffer[current_arg].arg_type = at_regexp;
973 argbuffer[current_arg].what = optarg;
977 argbuffer[current_arg].arg_type = at_regexp;
978 argbuffer[current_arg].what = NULL;
982 argbuffer[current_arg].arg_type = at_icregexp;
983 argbuffer[current_arg].what = optarg;
986 #endif /* ETAGS_REGEXPS */
998 typedefs = typedefs_and_cplusplus = TRUE;
1003 included_files[nincluded_files++] = optarg;
1006 /* Ctags options. */
1007 case 'B': searchar = '?'; break;
1008 case 'u': update = TRUE; break;
1009 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1010 case 'x': cxref_style = TRUE; break;
1011 case 'w': no_warnings = TRUE; break;
1014 suggest_asking_for_help ();
1018 for (; optind < argc; ++optind)
1020 argbuffer[current_arg].arg_type = at_filename;
1021 argbuffer[current_arg].what = argv[optind];
1026 if (nincluded_files == 0 && file_count == 0)
1028 error ("no input files specified.", (char *)NULL);
1029 suggest_asking_for_help ();
1032 if (tagfile == NULL)
1033 tagfile = CTAGS ? "tags" : "TAGS";
1034 cwd = etags_getcwd (); /* the current working directory */
1035 if (cwd[strlen (cwd) - 1] != '/')
1038 cwd = concat (oldcwd, "/", "");
1041 if (streq (tagfile, "-"))
1044 tagfiledir = absolute_dirname (tagfile, cwd);
1046 init (); /* set up boolean "functions" */
1049 initbuffer (&token_name);
1050 initbuffer (&lbs[0].lb);
1051 initbuffer (&lbs[1].lb);
1052 initbuffer (&filename_lb);
1056 if (streq (tagfile, "-"))
1060 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1061 doesn't take effect until after `stdout' is already open). */
1062 if (!isatty (fileno (stdout)))
1063 setmode (fileno (stdout), O_BINARY);
1064 #endif /* WIN32_NATIVE */
1067 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1073 * Loop through files finding functions.
1075 for (i = 0; i < current_arg; ++i)
1077 switch (argbuffer[i].arg_type)
1080 forced_lang = argbuffer[i].lang;
1082 #ifdef ETAGS_REGEXPS
1084 analyse_regex (argbuffer[i].what, FALSE);
1087 analyse_regex (argbuffer[i].what, TRUE);
1092 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1096 error ("can't find file %s\n", this_file);
1101 this_file = massage_name (this_file);
1104 this_file = argbuffer[i].what;
1106 /* Input file named "-" means read file names from stdin
1107 (one per line) and use them. */
1108 if (streq (this_file, "-"))
1109 while (readline_internal (&filename_lb, stdin) > 0)
1110 process_file (filename_lb.buffer);
1112 process_file (this_file);
1120 #ifdef ETAGS_REGEXPS
1122 #endif /* ETAGS_REGEXPS */
1126 while (nincluded_files-- > 0)
1127 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1133 /* If CTAGS, we are here. process_file did not write the tags yet,
1134 because we want them ordered. Let's do it now. */
1146 for (i = 0; i < current_arg; ++i)
1148 if (argbuffer[i].arg_type != at_filename)
1151 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1152 tagfile, argbuffer[i].what, tagfile);
1153 if (system (cmd) != GOOD)
1154 fatal ("failed to execute shell command", (char *)NULL);
1156 append_to_tagfile = TRUE;
1159 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1170 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1171 exit (system (cmd));
1179 * Return a compressor given the file name. If EXTPTR is non-zero,
1180 * return a pointer into FILE where the compressor-specific
1181 * extension begins. If no compressor is found, NULL is returned
1182 * and EXTPTR is not significant.
1183 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca>
1186 get_compressor_from_suffix (file, extptr)
1191 char *slash, *suffix;
1193 /* This relies on FN to be after canonicalize_filename,
1194 so we don't need to consider backslashes on WIN32_NATIVE. */
1195 slash = etags_strrchr (file, '/');
1196 suffix = etags_strrchr (file, '.');
1197 if (suffix == NULL || suffix < slash)
1202 /* Let those poor souls who live with DOS 8+3 file name limits get
1203 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1207 for (compr = compressors; compr->suffix != NULL; compr++)
1208 if (streq (compr->suffix, suffix))
1211 break; /* do it only once: not really a loop */
1214 } while (*suffix != '\0');
1221 * Return a language given the name.
1224 get_language_from_name (name)
1230 error ("empty language name", (char *)NULL);
1233 for (lang = lang_names; lang->name != NULL; lang++)
1234 if (streq (name, lang->name))
1236 error ("unknown language \"%s\"", name);
1244 * Return a language given the interpreter name.
1247 get_language_from_interpreter (interpreter)
1253 if (interpreter == NULL)
1255 for (lang = lang_names; lang->name != NULL; lang++)
1256 if (lang->interpreters != NULL)
1257 for (iname = lang->interpreters; *iname != NULL; iname++)
1258 if (streq (*iname, interpreter))
1267 * Return a language given the file name.
1270 get_language_from_suffix (file)
1274 char **ext, *suffix;
1276 suffix = etags_strrchr (file, '.');
1280 for (lang = lang_names; lang->name != NULL; lang++)
1281 if (lang->suffixes != NULL)
1282 for (ext = lang->suffixes; *ext != NULL; ext++)
1283 if (streq (*ext, suffix))
1291 * This routine is called on each file argument.
1297 struct stat stat_buf;
1300 char *compressed_name, *uncompressed_name;
1301 char *ext, *real_name;
1304 canonicalize_filename (file);
1305 if (streq (file, tagfile) && !streq (tagfile, "-"))
1307 error ("skipping inclusion of %s in self.", file);
1310 if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
1312 compressed_name = NULL;
1313 real_name = uncompressed_name = savestr (file);
1317 real_name = compressed_name = savestr (file);
1318 uncompressed_name = savenstr (file, ext - file);
1321 /* If the canonicalised uncompressed name has already be dealt with,
1322 skip it silently, else add it to the list. */
1324 typedef struct processed_file
1327 struct processed_file *next;
1329 static processed_file *pf_head = NULL;
1330 register processed_file *fnp;
1332 for (fnp = pf_head; fnp != NULL; fnp = fnp->next)
1333 if (streq (uncompressed_name, fnp->filename))
1336 pf_head = xnew (1, struct processed_file);
1337 pf_head->filename = savestr (uncompressed_name);
1338 pf_head->next = fnp;
1341 if (stat (real_name, &stat_buf) != 0)
1343 /* Reset real_name and try with a different name. */
1345 if (compressed_name != NULL) /* try with the given suffix */
1347 if (stat (uncompressed_name, &stat_buf) == 0)
1348 real_name = uncompressed_name;
1350 else /* try all possible suffixes */
1352 for (compr = compressors; compr->suffix != NULL; compr++)
1354 compressed_name = concat (file, ".", compr->suffix);
1355 if (stat (compressed_name, &stat_buf) != 0)
1357 /* XEmacs: delete MSDOS code */
1358 free (compressed_name);
1359 compressed_name = NULL;
1363 real_name = compressed_name;
1368 if (real_name == NULL)
1373 } /* try with a different name */
1375 if (!S_ISREG (stat_buf.st_mode))
1377 error ("skipping %s: it is not a regular file.", real_name);
1380 if (real_name == compressed_name)
1382 char *cmd = concat (compr->command, " ", real_name);
1383 inf = popen (cmd, "r");
1387 inf = fopen (real_name, "r");
1394 find_entries (uncompressed_name, inf);
1396 if (real_name == compressed_name)
1405 if (filename_is_absolute (uncompressed_name))
1407 /* file is an absolute file name. Canonicalise it. */
1408 filename = absolute_filename (uncompressed_name, cwd);
1412 /* file is a file name relative to cwd. Make it relative
1413 to the directory of the tags file. */
1414 filename = relative_filename (uncompressed_name, tagfiledir);
1416 fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head));
1424 if (compressed_name) free(compressed_name);
1425 if (uncompressed_name) free(uncompressed_name);
1430 * This routine sets up the boolean pseudo-functions which work
1431 * by setting boolean flags dependent upon the corresponding character.
1432 * Every char which is NOT in that string is not a white char. Therefore,
1433 * all of the array "_wht" is set to FALSE, and then the elements
1434 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1435 * of a char is TRUE if it is the string "white", else FALSE.
1443 for (i = 0; i < CHARS; i++)
1444 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE;
1445 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
1446 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
1447 notinname('\0') = notinname('\n');
1448 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
1449 begtoken('\0') = begtoken('\n');
1450 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
1451 intoken('\0') = intoken('\n');
1452 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
1453 endtoken('\0') = endtoken('\n');
1457 * This routine opens the specified file and calls the function
1458 * which finds the function and type definitions.
1460 node *last_node = NULL;
1463 find_entries (file, inf)
1469 node *old_last_node;
1471 /* Memory leakage here: the string pointed by curfile is
1472 never released, because curfile is copied into np->file
1473 for each node, to be used in CTAGS mode. The amount of
1474 memory leaked here is the sum of the lengths of the
1476 curfile = savestr (file);
1478 /* If user specified a language, use it. */
1480 if (lang != NULL && lang->function != NULL)
1483 lang->function (inf);
1487 /* Try to guess the language given the file name. */
1488 lang = get_language_from_suffix (file);
1489 if (lang != NULL && lang->function != NULL)
1492 lang->function (inf);
1496 /* Look for sharp-bang as the first two characters. */
1497 if (readline_internal (&lb, inf) > 0
1499 && lb.buffer[0] == '#'
1500 && lb.buffer[1] == '!')
1504 /* Set lp to point at the first char after the last slash in the
1505 line or, if no slashes, at the first nonblank. Then set cp to
1506 the first successive blank and terminate the string. */
1507 lp = etags_strrchr (lb.buffer+2, '/');
1511 lp = skip_spaces (lb.buffer + 2);
1512 cp = skip_non_spaces (lp);
1515 if (strlen (lp) > 0)
1517 lang = get_language_from_interpreter (lp);
1518 if (lang != NULL && lang->function != NULL)
1521 lang->function (inf);
1526 /* We rewind here, even if inf may be a pipe. We fail if the
1527 length of the first line is longer than the pipe block size,
1528 which is unlikely. */
1532 old_last_node = last_node;
1533 curlang = get_language_from_name ("fortran");
1534 Fortran_functions (inf);
1536 /* No Fortran entries found. Try C. */
1537 if (old_last_node == last_node)
1539 /* We do not tag if rewind fails.
1540 Only the file name will be recorded in the tags file. */
1542 curlang = get_language_from_name (cplusplus ? "c++" : "c");
1543 default_C_entries (inf);
1550 pfnote (name, is_func, linestart, linelen, lno, cno)
1551 char *name; /* tag name, or NULL if unnamed */
1552 bool is_func; /* tag is a function */
1553 char *linestart; /* start of the line where tag is */
1554 int linelen; /* length of the line where tag is */
1555 int lno; /* line number */
1556 long cno; /* character number */
1560 if (CTAGS && name == NULL)
1563 np = xnew (1, node);
1565 /* If ctags mode, change name "main" to M<thisfilename>. */
1566 if (CTAGS && !cxref_style && streq (name, "main"))
1568 register char *fp = etags_strrchr (curfile, '/');
1569 np->name = concat ("M", fp == NULL ? curfile : fp + 1, "");
1570 fp = etags_strrchr (np->name, '.');
1571 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1576 np->been_warned = FALSE;
1578 np->is_func = is_func;
1580 /* Our char numbers are 0-base, because of C language tradition?
1581 ctags compatibility? old versions compatibility? I don't know.
1582 Anyway, since emacs's are 1-base we expect etags.el to take care
1583 of the difference. If we wanted to have 1-based numbers, we would
1584 uncomment the +1 below. */
1585 np->cno = cno /* + 1 */ ;
1586 np->left = np->right = NULL;
1587 if (CTAGS && !cxref_style)
1589 if (strlen (linestart) < 50)
1590 np->pat = concat (linestart, "$", "");
1592 np->pat = savenstr (linestart, 50);
1595 np->pat = savenstr (linestart, linelen);
1597 add_node (np, &head);
1600 /* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997]
1601 * From: Sam Kendall <kendall@mv.mv.com>
1602 * Subject: Proposal for firming up the TAGS format specification
1603 * To: F.Potorti@cnuce.cnr.it
1605 * pfnote should emit the optimized form [unnamed tag] only if:
1606 * 1. name does not contain any of the characters " \t\r\n(),;";
1607 * 2. linestart contains name as either a rightmost, or rightmost but
1608 * one character, substring;
1609 * 3. the character, if any, immediately before name in linestart must
1610 * be one of the characters " \t(),;";
1611 * 4. the character, if any, immediately after name in linestart must
1612 * also be one of the characters " \t(),;".
1614 * The real implementation uses the notinname() macro, which recognises
1615 * characters slightly different form " \t\r\n(),;". See the variable
1618 #define traditional_tag_style TRUE
1620 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno)
1621 char *name; /* tag name, or NULL if unnamed */
1622 int namelen; /* tag length */
1623 bool is_func; /* tag is a function */
1624 char *linestart; /* start of the line where tag is */
1625 int linelen; /* length of the line where tag is */
1626 int lno; /* line number */
1627 long cno; /* character number */
1635 for (cp = name; !notinname (*cp); cp++)
1637 if (*cp == '\0') /* rule #1 */
1639 cp = linestart + linelen - namelen;
1640 if (notinname (linestart[linelen-1]))
1641 cp -= 1; /* rule #4 */
1642 if (cp >= linestart /* rule #2 */
1644 || notinname (cp[-1])) /* rule #3 */
1645 && strneq (name, cp, namelen)) /* rule #2 */
1646 named = FALSE; /* use unnamed tag */
1651 name = savenstr (name, namelen);
1654 pfnote (name, is_func, linestart, linelen, lno, cno);
1659 * recurse on left children, iterate on right children.
1667 register node *node_right = np->right;
1668 free_tree (np->left);
1669 if (np->name != NULL)
1679 * Adds a node to the tree of nodes. In etags mode, we don't keep
1680 * it sorted; we just keep a linear list. In ctags mode, maintain
1681 * an ordered tree, with no attempt at balancing.
1683 * add_node is the only function allowed to add nodes, so it can
1687 add_node (np, cur_node_p)
1688 node *np, **cur_node_p;
1691 register node *cur_node = *cur_node_p;
1693 if (cur_node == NULL)
1703 if (last_node == NULL)
1704 fatal ("internal error in add_node", (char *)NULL);
1705 last_node->right = np;
1711 dif = strcmp (np->name, cur_node->name);
1714 * If this tag name matches an existing one, then
1715 * do not add the node, but maybe print a warning.
1719 if (streq (np->file, cur_node->file))
1723 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
1724 np->file, lineno, np->name);
1725 fprintf (stderr, "Second entry ignored\n");
1728 else if (!cur_node->been_warned && !no_warnings)
1732 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1733 np->file, cur_node->file, np->name);
1734 cur_node->been_warned = TRUE;
1739 /* Actually add the node */
1740 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1753 /* Output subentries that precede this one */
1754 put_entries (np->left);
1756 /* Output this entry */
1760 if (np->name != NULL)
1761 fprintf (tagf, "%s\177%s\001%d,%ld\n",
1762 np->pat, np->name, np->lno, np->cno);
1764 fprintf (tagf, "%s\177%d,%ld\n",
1765 np->pat, np->lno, np->cno);
1769 if (np->name == NULL)
1770 error ("internal error: NULL name in ctags mode.", (char *)NULL);
1775 fprintf (stdout, "%s %s %d\n",
1776 np->name, np->file, (np->lno + 63) / 64);
1778 fprintf (stdout, "%-16s %3d %-16s %s\n",
1779 np->name, np->lno, np->file, np->pat);
1783 fprintf (tagf, "%s\t%s\t", np->name, np->file);
1787 putc (searchar, tagf);
1790 for (sp = np->pat; *sp; sp++)
1792 if (*sp == '\\' || *sp == searchar)
1796 putc (searchar, tagf);
1799 { /* a typedef; text pattern inadequate */
1800 fprintf (tagf, "%d", np->lno);
1806 /* Output subentries that follow this one */
1807 put_entries (np->right);
1810 /* Length of a number's decimal representation. */
1816 while ((num /= 10) > 0)
1822 * Return total number of characters that put_entries will output for
1823 * the nodes in the subtree of the specified node. Works only if
1824 * we are not ctags, but called only in that case. This count
1825 * is irrelevant with the new tags.el, but is still supplied for
1826 * backward compatibility.
1829 total_size_of_entries (np)
1837 for (total = 0; np != NULL; np = np->right)
1839 /* Count left subentries. */
1840 total += total_size_of_entries (np->left);
1842 /* Count this entry */
1843 total += strlen (np->pat) + 1;
1844 total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1;
1845 if (np->name != NULL)
1846 total += 1 + strlen (np->name); /* \001name */
1853 * The C symbol tables.
1858 st_C_objprot, st_C_objimpl, st_C_objend,
1863 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1866 static unsigned int hash P_((const char *, unsigned int));
1867 static struct C_stab_entry * in_word_set P_((const char *, unsigned int));
1868 static enum sym_type C_symtype P_((char *, int, int));
1870 /* Feed stuff between (but not including) %[ and %] lines to:
1871 gperf -c -k 1,3 -o -p -r -t
1873 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1877 while, 0, st_C_ignore
1878 switch, 0, st_C_ignore
1879 return, 0, st_C_ignore
1880 @interface, 0, st_C_objprot
1881 @protocol, 0, st_C_objprot
1882 @implementation,0, st_C_objimpl
1883 @end, 0, st_C_objend
1884 import, C_JAVA, st_C_ignore
1885 package, C_JAVA, st_C_ignore
1886 friend, C_PLPL, st_C_ignore
1887 extends, C_JAVA, st_C_javastruct
1888 implements, C_JAVA, st_C_javastruct
1889 interface, C_JAVA, st_C_struct
1890 class, C_PLPL, st_C_struct
1891 namespace, C_PLPL, st_C_struct
1892 domain, C_STAR, st_C_struct
1893 union, 0, st_C_struct
1894 struct, 0, st_C_struct
1895 extern, 0, st_C_extern
1897 typedef, 0, st_C_typedef
1898 define, 0, st_C_define
1899 operator, C_PLPL, st_C_operator
1900 bool, C_PLPL, st_C_typespec
1901 long, 0, st_C_typespec
1902 short, 0, st_C_typespec
1903 int, 0, st_C_typespec
1904 char, 0, st_C_typespec
1905 float, 0, st_C_typespec
1906 double, 0, st_C_typespec
1907 signed, 0, st_C_typespec
1908 unsigned, 0, st_C_typespec
1909 auto, 0, st_C_typespec
1910 void, 0, st_C_typespec
1911 static, 0, st_C_typespec
1912 const, 0, st_C_typespec
1913 volatile, 0, st_C_typespec
1914 explicit, C_PLPL, st_C_typespec
1915 mutable, C_PLPL, st_C_typespec
1916 typename, C_PLPL, st_C_typespec
1917 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1918 DEFUN, 0, st_C_gnumacro
1919 SYSCALL, 0, st_C_gnumacro
1920 ENTRY, 0, st_C_gnumacro
1921 PSEUDO, 0, st_C_gnumacro
1922 # These are defined inside C functions, so currently they are not met.
1923 # EXFUN used in glibc, DEFVAR_* in emacs.
1924 #EXFUN, 0, st_C_gnumacro
1925 #DEFVAR_, 0, st_C_gnumacro
1927 and replace lines between %< and %> with its output. */
1929 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
1930 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1931 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1933 #define TOTAL_KEYWORDS 46
1934 #define MIN_WORD_LENGTH 2
1935 #define MAX_WORD_LENGTH 15
1936 #define MIN_HASH_VALUE 13
1937 #define MAX_HASH_VALUE 123
1938 /* maximum key range = 111, duplicates = 0 */
1945 register const char *str;
1946 register unsigned int len;
1948 static unsigned char asso_values[] =
1950 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1951 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1952 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1953 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1954 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1955 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1956 124, 124, 124, 124, 3, 124, 124, 124, 43, 6,
1957 11, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1958 11, 124, 124, 58, 7, 124, 124, 124, 124, 124,
1959 124, 124, 124, 124, 124, 124, 124, 57, 7, 42,
1960 4, 14, 52, 0, 124, 53, 124, 124, 29, 11,
1961 6, 35, 32, 124, 29, 34, 59, 58, 51, 24,
1962 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1963 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1964 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1965 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1966 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1967 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1968 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1969 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1970 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1971 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1972 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1973 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1974 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1975 124, 124, 124, 124, 124, 124
1977 register int hval = len;
1983 hval += asso_values[(unsigned char)str[2]];
1986 hval += asso_values[(unsigned char)str[0]];
1995 static struct C_stab_entry *
1996 in_word_set (str, len)
1997 register const char *str;
1998 register unsigned int len;
2000 static struct C_stab_entry wordlist[] =
2002 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2003 {""}, {""}, {""}, {""},
2004 {"@end", 0, st_C_objend},
2005 {""}, {""}, {""}, {""},
2006 {"ENTRY", 0, st_C_gnumacro},
2007 {"@interface", 0, st_C_objprot},
2009 {"domain", C_STAR, st_C_struct},
2011 {"PSEUDO", 0, st_C_gnumacro},
2013 {"namespace", C_PLPL, st_C_struct},
2015 {"@implementation",0, st_C_objimpl},
2016 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2017 {"long", 0, st_C_typespec},
2018 {"signed", 0, st_C_typespec},
2019 {"@protocol", 0, st_C_objprot},
2020 {""}, {""}, {""}, {""},
2021 {"bool", C_PLPL, st_C_typespec},
2022 {""}, {""}, {""}, {""}, {""}, {""},
2023 {"const", 0, st_C_typespec},
2024 {"explicit", C_PLPL, st_C_typespec},
2025 {"if", 0, st_C_ignore},
2027 {"operator", C_PLPL, st_C_operator},
2029 {"DEFUN", 0, st_C_gnumacro},
2031 {"define", 0, st_C_define},
2032 {""}, {""}, {""}, {""}, {""},
2033 {"double", 0, st_C_typespec},
2034 {"struct", 0, st_C_struct},
2035 {""}, {""}, {""}, {""},
2036 {"short", 0, st_C_typespec},
2038 {"enum", 0, st_C_enum},
2039 {"mutable", C_PLPL, st_C_typespec},
2041 {"extern", 0, st_C_extern},
2042 {"extends", C_JAVA, st_C_javastruct},
2043 {"package", C_JAVA, st_C_ignore},
2044 {"while", 0, st_C_ignore},
2046 {"for", 0, st_C_ignore},
2048 {"volatile", 0, st_C_typespec},
2050 {"import", C_JAVA, st_C_ignore},
2051 {"float", 0, st_C_typespec},
2052 {"switch", 0, st_C_ignore},
2053 {"return", 0, st_C_ignore},
2054 {"implements", C_JAVA, st_C_javastruct},
2056 {"static", 0, st_C_typespec},
2057 {"typedef", 0, st_C_typedef},
2058 {"typename", C_PLPL, st_C_typespec},
2059 {"unsigned", 0, st_C_typespec},
2061 {"char", 0, st_C_typespec},
2062 {"class", C_PLPL, st_C_struct},
2064 {"void", 0, st_C_typespec},
2066 {"friend", C_PLPL, st_C_ignore},
2068 {"int", 0, st_C_typespec},
2069 {"union", 0, st_C_struct},
2071 {"auto", 0, st_C_typespec},
2072 {"interface", C_JAVA, st_C_struct},
2074 {"SYSCALL", 0, st_C_gnumacro}
2077 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
2079 register int key = hash (str, len);
2081 if (key <= MAX_HASH_VALUE && key >= 0)
2083 register const char *s = wordlist[key].name;
2085 if (*str == *s && !strncmp (str + 1, s + 1, len - 1))
2086 return &wordlist[key];
2093 static enum sym_type
2094 C_symtype (str, len, c_ext)
2099 register struct C_stab_entry *se = in_word_set (str, len);
2101 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
2107 * C functions and variables are recognized using a simple
2108 * finite automaton. fvdef is its state variable.
2112 fvnone, /* nothing seen */
2113 foperator, /* func: operator keyword seen (cplpl) */
2114 fvnameseen, /* function or variable name seen */
2115 fstartlist, /* func: just after open parenthesis */
2116 finlist, /* func: in parameter list */
2117 flistseen, /* func: after parameter list */
2118 fignore, /* func: before open brace */
2119 vignore /* var-like: ignore until ';' */
2122 bool fvextern; /* func or var: extern keyword seen; */
2125 * typedefs are recognized using a simple finite automaton.
2126 * typdef is its state variable.
2130 tnone, /* nothing seen */
2131 tkeyseen, /* typedef keyword seen */
2132 ttypeseen, /* defined type seen */
2133 tinbody, /* inside typedef body */
2134 tend, /* just before typedef tag */
2135 tignore /* junk after typedef tag */
2140 * struct-like structures (enum, struct and union) are recognized
2141 * using another simple finite automaton. `structdef' is its state
2146 snone, /* nothing seen yet */
2147 skeyseen, /* struct-like keyword seen */
2148 stagseen, /* struct-like tag seen */
2149 scolonseen, /* colon seen after struct-like tag */
2150 sinbody /* in struct body: recognize member func defs*/
2154 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
2155 * struct tag, and structtype is the type of the preceding struct-like
2158 char *structtag = "<uninited>";
2159 enum sym_type structtype;
2162 * When objdef is different from onone, objtag is the name of the class.
2164 char *objtag = "<uninited>";
2167 * Yet another little state machine to deal with preprocessor lines.
2171 dnone, /* nothing seen */
2172 dsharpseen, /* '#' seen as first char on line */
2173 ddefineseen, /* '#' and 'define' seen */
2174 dignorerest /* ignore rest of line */
2178 * State machine for Objective C protocols and implementations.
2179 * Tom R.Hageman <tom@basil.icce.rug.nl>
2183 onone, /* nothing seen */
2184 oprotocol, /* @interface or @protocol seen */
2185 oimplementation, /* @implementations seen */
2186 otagseen, /* class name seen */
2187 oparenseen, /* parenthesis before category seen */
2188 ocatseen, /* category name seen */
2189 oinbody, /* in @implementation body */
2190 omethodsign, /* in @implementation body, after +/- */
2191 omethodtag, /* after method name */
2192 omethodcolon, /* after method colon */
2193 omethodparm, /* after method parameter */
2194 oignore /* wait for @end */
2199 * Use this structure to keep info about the token read, and how it
2200 * should be tagged. Used by the make_C_tag function to build a tag.
2213 token tok; /* latest token read */
2216 * Set this to TRUE, and the next token considered is called a function.
2217 * Used only for GNU emacs's function-defining macros.
2219 bool next_token_is_func;
2222 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
2227 * methodlen is the length of the method name stored in token_name.
2231 static bool consider_token P_((char *, int, int, int, int, int, bool *));
2232 static void make_C_tag P_((bool));
2236 * checks to see if the current token is at the start of a
2237 * function or variable, or corresponds to a typedef, or
2238 * is a struct/union/enum tag, or #define, or an enum constant.
2240 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2241 * with args. C_EXT is which language we are looking at.
2249 * next_token_is_func IN OUT
2253 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2254 register char *str; /* IN: token pointer */
2255 register int len; /* IN: token length */
2256 register int c; /* IN: first char after the token */
2257 int c_ext; /* IN: C extensions mask */
2258 int cblev; /* IN: curly brace level */
2259 int parlev; /* IN: parenthesis level */
2260 bool *is_func_or_var; /* OUT: function or variable found */
2262 enum sym_type toktype = C_symtype (str, len, c_ext);
2265 * Advance the definedef state machine.
2270 /* We're not on a preprocessor line. */
2273 if (toktype == st_C_define)
2275 definedef = ddefineseen;
2279 definedef = dignorerest;
2284 * Make a tag for any macro, unless it is a constant
2285 * and constantypedefs is FALSE.
2287 definedef = dignorerest;
2288 *is_func_or_var = (c == '(');
2289 if (!*is_func_or_var && !constantypedefs)
2296 error ("internal error: definedef value.", (char *)NULL);
2305 if (toktype == st_C_typedef)
2324 /* Do not return here, so the structdef stuff has a chance. */
2338 * This structdef business is currently only invoked when cblev==0.
2339 * It should be recursively invoked whatever the curly brace level,
2340 * and a stack of states kept, to allow for definitions of structs
2343 * This structdef business is NOT invoked when we are ctags and the
2344 * file is plain C. This is because a struct tag may have the same
2345 * name as another tag, and this loses with ctags.
2349 case st_C_javastruct:
2350 if (structdef == stagseen)
2351 structdef = scolonseen;
2355 if (typdef == tkeyseen
2356 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone))
2358 structdef = skeyseen;
2359 structtype = toktype;
2364 if (structdef == skeyseen)
2366 /* Save the tag for struct/union/class, for functions and variables
2367 that may be defined inside. */
2368 if (structtype == st_C_struct)
2369 structtag = savenstr (str, len);
2371 structtag = "<enum>";
2372 structdef = stagseen;
2376 if (typdef != tnone)
2379 /* Detect GNU macros.
2381 Writers of emacs code are recommended to put the
2382 first two args of a DEFUN on the same line.
2384 The DEFUN macro, used in emacs C source code, has a first arg
2385 that is a string (the lisp function name), and a second arg that
2386 is a C function name. Since etags skips strings, the second arg
2387 is tagged. This is unfortunate, as it would be better to tag the
2388 first arg. The simplest way to deal with this problem would be
2389 to name the tag with a name built from the function name, by
2390 removing the initial 'F' character and substituting '-' for '_'.
2391 Anyway, this assumes that the conventions of naming lisp
2392 functions will never change. Currently, this method is not
2394 if (definedef == dnone && toktype == st_C_gnumacro)
2396 next_token_is_func = TRUE;
2399 if (next_token_is_func)
2401 next_token_is_func = FALSE;
2403 *is_func_or_var = TRUE;
2407 /* Detect Objective C constructs. */
2417 objdef = oimplementation;
2421 case oimplementation:
2422 /* Save the class tag for functions or variables defined inside. */
2423 objtag = savenstr (str, len);
2427 /* Save the class tag for categories. */
2428 objtag = savenstr (str, len);
2430 *is_func_or_var = TRUE;
2434 *is_func_or_var = TRUE;
2441 objdef = omethodtag;
2443 grow_linebuffer (&token_name, methodlen + 1);
2444 strncpy (token_name.buffer, str, len);
2445 token_name.buffer[methodlen] = '\0';
2446 token_name.len = methodlen;
2452 objdef = omethodparm;
2457 objdef = omethodtag;
2459 grow_linebuffer (&token_name, methodlen + 1);
2460 strncat (token_name.buffer, str, len);
2461 token_name.len = methodlen;
2466 if (toktype == st_C_objend)
2468 /* Memory leakage here: the string pointed by objtag is
2469 never released, because many tests would be needed to
2470 avoid breaking on incorrect input code. The amount of
2471 memory leaked here is the sum of the lengths of the
2479 /* A function, variable or enum constant? */
2486 if (fvdef != finlist && fvdef != fignore && fvdef != vignore)
2487 fvdef = fvnone; /* should be useless */
2495 *is_func_or_var = TRUE;
2498 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10))
2501 *is_func_or_var = TRUE;
2504 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2506 if (fvdef == fvnone)
2508 fvdef = fvnameseen; /* function or variable */
2509 *is_func_or_var = TRUE;
2520 * This routine finds functions, variables, typedefs,
2521 * #define's, enum constants and struct/union/enum definitions in
2522 * C syntax and adds them to the list.
2524 #define current_lb_is_new (newndx == curndx)
2525 #define switch_line_buffers() (curndx = 1 - curndx)
2527 #define curlb (lbs[curndx].lb)
2528 #define othlb (lbs[1-curndx].lb)
2529 #define newlb (lbs[newndx].lb)
2530 #define curlinepos (lbs[curndx].linepos)
2531 #define othlinepos (lbs[1-curndx].linepos)
2532 #define newlinepos (lbs[newndx].linepos)
2534 #define CNL_SAVE_DEFINEDEF() \
2536 curlinepos = charno; \
2538 linecharno = charno; \
2539 charno += readline (&curlb, inf); \
2540 lp = curlb.buffer; \
2547 CNL_SAVE_DEFINEDEF(); \
2548 if (savetok.valid) \
2551 savetok.valid = FALSE; \
2553 definedef = dnone; \
2561 /* This function should never be called when tok.valid is FALSE, but
2562 we must protect against invalid input or internal errors. */
2565 if (traditional_tag_style)
2567 /* This was the original code. Now we call new_pfnote instead,
2568 which uses the new method for naming tags (see new_pfnote). */
2571 if (CTAGS || tok.named)
2572 name = savestr (token_name.buffer);
2573 pfnote (name, isfun,
2574 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2577 new_pfnote (token_name.buffer, token_name.len, isfun,
2578 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2587 C_entries (c_ext, inf)
2588 int c_ext; /* extension of C */
2589 FILE *inf; /* input file */
2591 register char c; /* latest char read; '\0' for end of line */
2592 register char *lp; /* pointer one beyond the character `c' */
2593 int curndx, newndx; /* indices for current and new lb */
2594 register int tokoff; /* offset in line of start of current token */
2595 register int toklen; /* length of current token */
2596 char *qualifier; /* string used to qualify names */
2597 int qlen; /* length of qualifier */
2598 int cblev; /* current curly brace level */
2599 int parlev; /* current parenthesis level */
2600 bool incomm, inquote, inchar, quotednl, midtoken;
2601 bool purec, cplpl, cjava;
2602 token savetok; /* token saved during preprocessor handling */
2605 tokoff = toklen = 0; /* keep compiler quiet */
2606 curndx = newndx = 0;
2612 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
2613 structdef = snone; definedef = dnone; objdef = onone;
2614 next_token_is_func = yacc_rules = FALSE;
2615 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2616 tok.valid = savetok.valid = FALSE;
2619 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */
2620 cplpl = (c_ext & C_PLPL) == C_PLPL;
2621 cjava = (c_ext & C_JAVA) == C_JAVA;
2623 { qualifier = "."; qlen = 1; }
2625 { qualifier = "::"; qlen = 2; }
2632 /* If we're at the end of the line, the next character is a
2633 '\0'; don't skip it, because it's the thing that tells us
2634 to read the next line. */
2655 /* Newlines inside comments do not end macro definitions in
2657 CNL_SAVE_DEFINEDEF ();
2670 /* Newlines inside strings do not end macro definitions
2671 in traditional cpp, even though compilers don't
2672 usually accept them. */
2673 CNL_SAVE_DEFINEDEF ();
2683 /* Hmmm, something went wrong. */
2697 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2705 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2718 else if (/* cplpl && */ *lp == '/')
2726 if ((c_ext & YACC) && *lp == '%')
2728 /* entering or exiting rules section in yacc file */
2730 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2731 typdef = tnone; structdef = snone;
2732 next_token_is_func = FALSE;
2733 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2735 yacc_rules = !yacc_rules;
2741 if (definedef == dnone)
2744 bool cpptoken = TRUE;
2746 /* Look back on this line. If all blanks, or nonblanks
2747 followed by an end of comment, this is a preprocessor
2749 for (cp = newlb.buffer; cp < lp-1; cp++)
2752 if (*cp == '*' && *(cp+1) == '/')
2761 definedef = dsharpseen;
2762 } /* if (definedef == dnone) */
2768 /* Consider token only if some complicated conditions are satisfied. */
2769 if ((definedef != dnone
2770 || (cblev == 0 && structdef != scolonseen)
2771 || (cblev == 1 && cplpl && structdef == sinbody)
2772 || (structdef == sinbody && purec))
2773 && typdef != tignore
2774 && definedef != dignorerest
2775 && fvdef != finlist)
2781 bool funorvar = FALSE;
2783 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1]))
2786 * This handles :: in the middle, but not at the
2787 * beginning of an identifier. Also, space-separated
2788 * :: is not recognised.
2798 || consider_token (newlb.buffer + tokoff, toklen, c,
2799 c_ext, cblev, parlev, &funorvar))
2801 if (fvdef == foperator)
2804 lp = skip_spaces (lp-1);
2808 && !iswhite (*lp) && *lp != '(')
2811 toklen += lp - oldlp;
2816 && definedef == dnone
2817 && structdef == sinbody)
2818 /* function or var defined in C++ class body */
2820 int len = strlen (structtag) + qlen + toklen;
2821 grow_linebuffer (&token_name, len + 1);
2822 strcpy (token_name.buffer, structtag);
2823 strcat (token_name.buffer, qualifier);
2824 strncat (token_name.buffer,
2825 newlb.buffer + tokoff, toklen);
2826 token_name.len = len;
2829 else if (objdef == ocatseen)
2830 /* Objective C category */
2832 int len = strlen (objtag) + 2 + toklen;
2833 grow_linebuffer (&token_name, len + 1);
2834 strcpy (token_name.buffer, objtag);
2835 strcat (token_name.buffer, "(");
2836 strncat (token_name.buffer,
2837 newlb.buffer + tokoff, toklen);
2838 strcat (token_name.buffer, ")");
2839 token_name.len = len;
2842 else if (objdef == omethodtag
2843 || objdef == omethodparm)
2844 /* Objective C method */
2850 grow_linebuffer (&token_name, toklen + 1);
2851 strncpy (token_name.buffer,
2852 newlb.buffer + tokoff, toklen);
2853 token_name.buffer[toklen] = '\0';
2854 token_name.len = toklen;
2855 /* Name macros and members. */
2856 tok.named = (structdef == stagseen
2857 || typdef == ttypeseen
2860 && definedef == dignorerest)
2862 && definedef == dnone
2863 && structdef == sinbody));
2865 tok.lineno = lineno;
2866 tok.linelen = tokoff + toklen + 1;
2867 tok.buffer = newlb.buffer;
2868 tok.linepos = newlinepos;
2871 if (definedef == dnone
2872 && (fvdef == fvnameseen
2873 || fvdef == foperator
2874 || structdef == stagseen
2876 || objdef != onone))
2878 if (current_lb_is_new)
2879 switch_line_buffers ();
2882 make_C_tag (funorvar);
2886 } /* if (endtoken (c)) */
2887 else if (intoken (c))
2893 } /* if (midtoken) */
2894 else if (begtoken (c))
2905 make_C_tag (TRUE); /* a function */
2912 if (structdef == stagseen && !cjava)
2918 if (!yacc_rules || lp == newlb.buffer + 1)
2920 tokoff = lp - 1 - newlb.buffer;
2925 } /* if (begtoken) */
2926 } /* if must look at token */
2929 /* Detect end of line, colon, comma, semicolon and various braces
2930 after having handled a token.*/
2934 if (definedef != dnone)
2940 make_C_tag (TRUE); /* an Objective C class */
2944 objdef = omethodcolon;
2946 grow_linebuffer (&token_name, methodlen + 1);
2947 strcat (token_name.buffer, ":");
2948 token_name.len = methodlen;
2951 if (structdef == stagseen)
2952 structdef = scolonseen;
2959 make_C_tag (FALSE); /* a yacc function */
2970 if (definedef != dnone)
2976 make_C_tag (FALSE); /* a typedef */
2986 if ((members && cblev == 1)
2987 || (globals && cblev == 0 && (!fvextern || declarations)))
2988 make_C_tag (FALSE); /* a variable */
2994 if (declarations && (cblev == 0 || cblev == 1))
2995 make_C_tag (TRUE); /* a function declaration */
3000 /* The following instruction invalidates the token.
3001 Probably the token should be invalidated in all
3002 other cases where some state machine is reset. */
3005 if (structdef == stagseen)
3009 if (definedef != dnone)
3015 make_C_tag (TRUE); /* an Objective C method */
3027 if ((members && cblev == 1)
3028 || (globals && cblev == 0 && (!fvextern || declarations)))
3029 make_C_tag (FALSE); /* a variable */
3034 if (structdef == stagseen)
3038 if (definedef != dnone)
3040 if (cblev == 0 && typdef == tend)
3043 make_C_tag (FALSE); /* a typedef */
3054 if ((members && cblev == 1)
3055 || (globals && cblev == 0 && (!fvextern || declarations)))
3056 make_C_tag (FALSE); /* a variable */
3061 if (structdef == stagseen)
3065 if (definedef != dnone)
3067 if (objdef == otagseen && parlev == 0)
3068 objdef = oparenseen;
3072 if (typdef == ttypeseen
3075 && structdef != sinbody)
3077 /* This handles constructs like:
3078 typedef void OperatorFun (int fun); */
3093 if (definedef != dnone)
3095 if (objdef == ocatseen && parlev == 1)
3097 make_C_tag (TRUE); /* an Objective C category */
3109 if (cblev == 0 && (typdef == tend))
3112 make_C_tag (FALSE); /* a typedef */
3115 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
3119 if (definedef != dnone)
3121 if (typdef == ttypeseen)
3125 case skeyseen: /* unnamed struct */
3126 structdef = sinbody;
3127 structtag = "_anonymous_";
3130 case scolonseen: /* named struct */
3131 structdef = sinbody;
3132 make_C_tag (FALSE); /* a struct */
3138 make_C_tag (TRUE); /* a function */
3147 make_C_tag (TRUE); /* an Objective C class */
3152 make_C_tag (TRUE); /* an Objective C method */
3156 /* Neutralize `extern "C" {' grot. */
3157 if (cblev == 0 && structdef == snone && typdef == tnone)
3164 if (definedef != dnone)
3166 if (fvdef == fstartlist)
3167 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
3170 if (definedef != dnone)
3172 if (!noindentypedefs && lp == newlb.buffer + 1)
3174 cblev = 0; /* reset curly brace level if first column */
3175 parlev = 0; /* also reset paren level, just in case... */
3181 if (typdef == tinbody)
3183 /* Memory leakage here: the string pointed by structtag is
3184 never released, because I fear to miss something and
3185 break things while freeing the area. The amount of
3186 memory leaked here is the sum of the lengths of the
3188 if (structdef == sinbody)
3189 free (structtag); */
3192 structtag = "<error>";
3196 if (definedef != dnone)
3206 if ((members && cblev == 1)
3207 || (globals && cblev == 0 && (!fvextern || declarations)))
3208 make_C_tag (FALSE); /* a variable */
3216 if (objdef == oinbody && cblev == 0)
3218 objdef = omethodsign;
3222 case '#': case '~': case '&': case '%': case '/': case '|':
3223 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
3224 if (definedef != dnone)
3226 /* These surely cannot follow a function tag in C. */
3239 if (objdef == otagseen)
3241 make_C_tag (TRUE); /* an Objective C class */
3244 /* If a macro spans multiple lines don't reset its state. */
3246 CNL_SAVE_DEFINEDEF ();
3252 } /* while not eof */
3256 * Process either a C++ file or a C file depending on the setting
3260 default_C_entries (inf)
3263 C_entries (cplusplus ? C_PLPL : 0, inf);
3266 /* Always do plain ANSI C. */
3268 plain_C_entries (inf)
3274 /* Always do C++. */
3276 Cplusplus_entries (inf)
3279 C_entries (C_PLPL, inf);
3282 /* Always do Java. */
3287 C_entries (C_JAVA, inf);
3295 C_entries (C_STAR, inf);
3298 /* Always do Yacc. */
3303 C_entries (YACC, inf);
3306 /* A useful macro. */
3307 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3308 for (lineno = charno = 0; /* loop initialization */ \
3309 !feof (file_pointer) /* loop test */ \
3310 && (lineno++, /* instructions at start of loop */ \
3311 linecharno = charno, \
3312 charno += readline (&line_buffer, file_pointer), \
3313 char_pointer = lb.buffer, \
3319 * Read a file, but do no processing. This is used to do regexp
3320 * matching on files that have no language defined.
3323 just_read_file (inf)
3326 register char *dummy;
3328 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3332 /* Fortran parsing */
3334 static bool tail P_((char *));
3335 static void takeprec P_((void));
3336 static void getit P_((FILE *));
3342 register int len = 0;
3344 while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len]))
3346 if (*cp == '\0' && !intoken (dbp[len]))
3357 dbp = skip_spaces (dbp);
3361 dbp = skip_spaces (dbp);
3362 if (strneq (dbp, "(*)", 3))
3367 if (!isdigit ((unsigned char) *dbp))
3369 --dbp; /* force failure */
3374 while (isdigit ((unsigned char) *dbp));
3383 dbp = skip_spaces (dbp);
3387 linecharno = charno;
3388 charno += readline (&lb, inf);
3393 dbp = skip_spaces (dbp);
3395 if (!isalpha ((unsigned char) *dbp) && *dbp != '_' && *dbp != '$')
3397 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
3399 pfnote (savenstr (dbp, cp-dbp), TRUE,
3400 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3405 Fortran_functions (inf)
3408 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3411 dbp++; /* Ratfor escape to fortran */
3412 dbp = skip_spaces (dbp);
3415 switch (lowcase (*dbp))
3418 if (tail ("integer"))
3426 if (tail ("logical"))
3430 if (tail ("complex") || tail ("character"))
3434 if (tail ("double"))
3436 dbp = skip_spaces (dbp);
3439 if (tail ("precision"))
3445 dbp = skip_spaces (dbp);
3448 switch (lowcase (*dbp))
3451 if (tail ("function"))
3455 if (tail ("subroutine"))
3463 if (tail ("blockdata") || tail ("block data"))
3465 dbp = skip_spaces (dbp);
3466 if (*dbp == '\0') /* assume un-named */
3467 pfnote (savestr ("blockdata"), TRUE,
3468 lb.buffer, dbp - lb.buffer, lineno, linecharno);
3470 getit (inf); /* look for name */
3478 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24
3482 static void adagetit P_((FILE *, char *));
3484 /* Once we are positioned after an "interesting" keyword, let's get
3485 the real tag value necessary. */
3487 adagetit (inf, name_qualifier)
3489 char *name_qualifier;
3497 dbp = skip_spaces (dbp);
3499 || (dbp[0] == '-' && dbp[1] == '-'))
3502 linecharno = charno;
3503 charno += readline (&lb, inf);
3512 /* Skipping body of procedure body or package body or ....
3513 resetting qualifier to body instead of spec. */
3514 name_qualifier = "/b";
3520 /* Skipping type of task type or protected type ... */
3528 for (cp = dbp; *cp != '\0' && *cp != '"'; cp++)
3533 dbp = skip_spaces (dbp);
3536 && (isalpha ((unsigned char) *cp) || isdigit ((unsigned char) *cp) || *cp == '_' || *cp == '.'));
3544 name = concat (dbp, name_qualifier, "");
3546 pfnote (name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3557 bool inquote = FALSE;
3559 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3561 while (*dbp != '\0')
3563 /* Skip a string i.e. "abcd". */
3564 if (inquote || (*dbp == '"'))
3566 dbp = etags_strchr ((inquote) ? dbp : dbp+1, '"');
3571 continue; /* advance char */
3576 break; /* advance line */
3580 /* Skip comments. */
3581 if (dbp[0] == '-' && dbp[1] == '-')
3582 break; /* advance line */
3584 /* Skip character enclosed in single quote i.e. 'a'
3585 and skip single quote starting an attribute i.e. 'Image. */
3594 /* Search for beginning of a token. */
3595 if (!begtoken (*dbp))
3598 continue; /* advance char */
3601 /* We are at the beginning of a token. */
3606 if (!packages_only && tail ("function"))
3607 adagetit (inf, "/f");
3609 break; /* from switch */
3610 continue; /* advance char */
3613 if (!packages_only && tail ("procedure"))
3614 adagetit (inf, "/p");
3615 else if (tail ("package"))
3616 adagetit (inf, "/s");
3617 else if (tail ("protected")) /* protected type */
3618 adagetit (inf, "/t");
3620 break; /* from switch */
3621 continue; /* advance char */
3624 if (!packages_only && tail ("task"))
3625 adagetit (inf, "/k");
3626 else if (typedefs && !packages_only && tail ("type"))
3628 adagetit (inf, "/t");
3629 while (*dbp != '\0')
3633 break; /* from switch */
3634 continue; /* advance char */
3637 /* Look for the end of the token. */
3638 while (!endtoken (*dbp))
3641 } /* advance char */
3642 } /* advance line */
3646 * Bob Weiner, Motorola Inc., 4/3/94
3647 * Unix and microcontroller assembly tag handling
3648 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3656 LOOP_ON_INPUT_LINES (inf, lb, cp)
3658 /* If first char is alphabetic or one of [_.$], test for colon
3659 following identifier. */
3660 if (isalpha ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$')
3662 /* Read past label. */
3664 while (isalnum ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$')
3666 if (*cp == ':' || iswhite (*cp))
3668 /* Found end of label, so copy it and add it to the table. */
3669 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE,
3670 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3677 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3678 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3679 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3680 * Perl variable names: /^(my|local).../
3683 Perl_functions (inf)
3688 LOOP_ON_INPUT_LINES (inf, lb, cp)
3692 && *cp++ == 'b' && iswhite (*cp++))
3694 cp = skip_spaces (cp);
3699 && !iswhite (*cp) && *cp != '{' && *cp != '(')
3701 pfnote (savenstr (sp, cp-sp), TRUE,
3702 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3705 else if (globals /* only if tagging global vars is enabled */
3706 && ((cp = lb.buffer,
3715 && (*cp == '(' || iswhite (*cp)))
3717 /* After "my" or "local", but before any following paren or space. */
3718 char *varname = NULL;
3720 cp = skip_spaces (cp);
3721 if (*cp == '$' || *cp == '@' || *cp == '%')
3723 char* varstart = ++cp;
3724 while (isalnum ((unsigned char) *cp) || *cp == '_')
3726 varname = savenstr (varstart, cp-varstart);
3730 /* Should be examining a variable list at this point;
3731 could insist on seeing an open parenthesis. */
3732 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
3736 /* Perhaps I should back cp up one character, so the TAGS table
3737 doesn't mention (and so depend upon) the following char. */
3738 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
3739 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3745 * Python support by Eric S. Raymond <esr@thyrsus.com>
3746 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
3749 Python_functions (inf)
3754 LOOP_ON_INPUT_LINES (inf, lb, cp)
3758 && *cp++ == 'f' && iswhite (*cp++))
3760 cp = skip_spaces (cp);
3761 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':')
3764 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3772 && *cp++ == 's' && iswhite (*cp++))
3774 cp = skip_spaces (cp);
3775 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':')
3778 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3783 /* Idea by Corny de Souza
3784 * Cobol tag functions
3785 * We could look for anything that could be a paragraph name.
3786 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3789 Cobol_paragraphs (inf)
3792 register char *bp, *ep;
3794 LOOP_ON_INPUT_LINES (inf, lb, bp)
3800 /* If eoln, compiler option or comment ignore whole line. */
3801 if (bp[-1] != ' ' || !isalnum ((unsigned char) bp[0]))
3804 for (ep = bp; isalnum ((unsigned char) *ep) || *ep == '-'; ep++)
3807 pfnote (savenstr (bp, ep-bp), TRUE,
3808 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3812 /* Added by Mosur Mohan, 4/22/88 */
3813 /* Pascal parsing */
3816 * Locates tags for procedures & functions. Doesn't do any type- or
3817 * var-definitions. It does look for the keyword "extern" or
3818 * "forward" immediately following the procedure statement; if found,
3819 * the tag is skipped.
3822 Pascal_functions (inf)
3825 linebuffer tline; /* mostly copied from C_entries */
3827 int save_lineno, save_len;
3828 char c, *cp, *namebuf;
3830 bool /* each of these flags is TRUE iff: */
3831 incomment, /* point is inside a comment */
3832 inquote, /* point is inside '..' string */
3833 get_tagname, /* point is after PROCEDURE/FUNCTION
3834 keyword, so next item = potential tag */
3835 found_tag, /* point is after a potential tag */
3836 inparms, /* point is within parameter-list */
3837 verify_tag; /* point has passed the parm-list, so the
3838 next token will determine whether this
3839 is a FORWARD/EXTERN to be ignored, or
3840 whether it is a real tag */
3842 save_lcno = save_lineno = save_len = 0; /* keep compiler quiet */
3843 namebuf = NULL; /* keep compiler quiet */
3848 initbuffer (&tline);
3850 incomment = inquote = FALSE;
3851 found_tag = FALSE; /* have a proc name; check if extern */
3852 get_tagname = FALSE; /* have found "procedure" keyword */
3853 inparms = FALSE; /* found '(' after "proc" */
3854 verify_tag = FALSE; /* check if "extern" is ahead */
3857 while (!feof (inf)) /* long main loop to get next char */
3860 if (c == '\0') /* if end of line */
3863 linecharno = charno;
3864 charno += readline (&lb, inf);
3868 if (!((found_tag && verify_tag)
3870 c = *dbp++; /* only if don't need *dbp pointing
3871 to the beginning of the name of
3872 the procedure or function */
3876 if (c == '}') /* within { } comments */
3878 else if (c == '*' && *dbp == ')') /* within (* *) comments */
3895 inquote = TRUE; /* found first quote */
3897 case '{': /* found open { comment */
3901 if (*dbp == '*') /* found open (* comment */
3906 else if (found_tag) /* found '(' after tag, i.e., parm-list */
3909 case ')': /* end of parms list */
3914 if (found_tag && !inparms) /* end of proc or fn stmt */
3921 if (found_tag && verify_tag && (*dbp != ' '))
3923 /* check if this is an "extern" declaration */
3926 if (lowcase (*dbp == 'e'))
3928 if (tail ("extern")) /* superfluous, really! */
3934 else if (lowcase (*dbp) == 'f')
3936 if (tail ("forward")) /* check for forward reference */
3942 if (found_tag && verify_tag) /* not external proc, so make tag */
3946 pfnote (namebuf, TRUE,
3947 tline.buffer, save_len, save_lineno, save_lcno);
3951 if (get_tagname) /* grab name of proc or fn */
3956 /* save all values for later tagging */
3957 grow_linebuffer (&tline, lb.len + 1);
3958 strcpy (tline.buffer, lb.buffer);
3959 save_lineno = lineno;
3960 save_lcno = linecharno;
3962 /* grab block name */
3963 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
3965 namebuf = savenstr (dbp, cp-dbp);
3966 dbp = cp; /* set dbp to e-o-token */
3967 save_len = dbp - lb.buffer + 1;
3968 get_tagname = FALSE;
3972 /* and proceed to check for "extern" */
3974 else if (!incomment && !inquote && !found_tag)
3976 /* check for proc/fn keywords */
3977 switch (lowcase (c))
3980 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3984 if (tail ("unction"))
3989 } /* while not eof */
3991 free (tline.buffer);
3995 * lisp tag functions
3996 * look for (def or (DEF, quote or QUOTE
3999 static int L_isdef P_((char *));
4000 static int L_isquote P_((char *));
4001 static void L_getit P_((void));
4005 register char *strp;
4007 return ((strp[1] == 'd' || strp[1] == 'D')
4008 && (strp[2] == 'e' || strp[2] == 'E')
4009 && (strp[3] == 'f' || strp[3] == 'F'));
4014 register char *strp;
4016 return ((*++strp == 'q' || *strp == 'Q')
4017 && (*++strp == 'u' || *strp == 'U')
4018 && (*++strp == 'o' || *strp == 'O')
4019 && (*++strp == 't' || *strp == 'T')
4020 && (*++strp == 'e' || *strp == 'E')
4021 && iswhite (*++strp));
4029 if (*dbp == '\'') /* Skip prefix quote */
4031 else if (*dbp == '(')
4033 if (L_isquote (dbp))
4034 dbp += 7; /* Skip "(quote " */
4036 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */
4037 dbp = skip_spaces (dbp);
4040 for (cp = dbp /*+1*/;
4041 *cp != '\0' && *cp != '(' && !iswhite(*cp) && *cp != ')';
4047 pfnote (savenstr (dbp, cp-dbp), TRUE,
4048 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4052 Lisp_functions (inf)
4055 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4061 dbp = skip_non_spaces (dbp);
4062 dbp = skip_spaces (dbp);
4067 /* Check for (foo::defmumble name-defined ... */
4070 while (*dbp != '\0' && !iswhite (*dbp)
4071 && *dbp != ':' && *dbp != '(' && *dbp != ')');
4076 while (*dbp == ':');
4078 if (L_isdef (dbp - 1))
4080 dbp = skip_non_spaces (dbp);
4081 dbp = skip_spaces (dbp);
4091 * Postscript tag functions
4092 * Just look for lines where the first character is '/'
4093 * Richard Mlynarik <mly@adoc.xerox.com>
4094 * Also look at "defineps" for PSWrap
4095 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp>
4098 Postscript_functions (inf)
4101 register char *bp, *ep;
4103 LOOP_ON_INPUT_LINES (inf, lb, bp)
4108 *ep != '\0' && *ep != ' ' && *ep != '{';
4111 pfnote (savenstr (bp, ep-bp), TRUE,
4112 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4114 else if (strneq (bp, "defineps", 8))
4116 bp = skip_non_spaces (bp);
4117 bp = skip_spaces (bp);
4125 * Scheme tag functions
4126 * look for (def... xyzzy
4127 * look for (def... (xyzzy
4128 * look for (def ... ((...(xyzzy ....
4129 * look for (set! xyzzy
4133 Scheme_functions (inf)
4138 LOOP_ON_INPUT_LINES (inf, lb, bp)
4141 && (bp[1] == 'D' || bp[1] == 'd')
4142 && (bp[2] == 'E' || bp[2] == 'e')
4143 && (bp[3] == 'F' || bp[3] == 'f'))
4145 bp = skip_non_spaces (bp);
4146 /* Skip over open parens and white space */
4147 while (iswhite (*bp) || *bp == '(')
4152 && (bp[1] == 'S' || bp[1] == 's')
4153 && (bp[2] == 'E' || bp[2] == 'e')
4154 && (bp[3] == 'T' || bp[3] == 't')
4155 && (bp[4] == '!' || bp[4] == '!')
4156 && (iswhite (bp[5])))
4158 bp = skip_non_spaces (bp);
4159 bp = skip_spaces (bp);
4165 /* Find tags in TeX and LaTeX input files. */
4167 /* TEX_toktab is a table of TeX control sequences that define tags.
4168 Each TEX_tabent records one such control sequence.
4169 CONVERT THIS TO USE THE Stab TYPE!! */
4176 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
4178 /* Default set of control sequences to put into TEX_toktab.
4179 The value of environment var TEXTAGS is prepended to this. */
4181 char *TEX_defenv = "\
4182 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4183 :part:appendix:entry:index";
4185 static void TEX_mode P_((FILE *));
4186 static struct TEX_tabent *TEX_decode_env P_((char *, char *));
4187 static int TEX_Token P_((char *));
4189 char TEX_esc = '\\';
4190 char TEX_opgrp = '{';
4191 char TEX_clgrp = '}';
4194 * TeX/LaTeX scanning loop.
4203 /* Select either \ or ! as escape character. */
4206 /* Initialize token table once from environment. */
4208 TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
4210 LOOP_ON_INPUT_LINES (inf, lb, cp)
4213 /* Look at each esc in line. */
4214 while ((cp = etags_strchr (cp, TEX_esc)) != NULL)
4218 linecharno += cp - lasthit;
4220 i = TEX_Token (lasthit);
4223 /* We seem to include the TeX command in the tag name.
4225 for (p = lasthit + TEX_toktab[i].len;
4226 *p != '\0' && *p != TEX_clgrp;
4229 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL, TRUE,
4230 lb.buffer, lb.len, lineno, linecharno);
4231 break; /* We only tag a line once */
4237 #define TEX_LESC '\\'
4238 #define TEX_SESC '!'
4241 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4242 chars accordingly. */
4249 while ((c = getc (inf)) != EOF)
4251 /* Skip to next line if we hit the TeX comment char. */
4255 else if (c == TEX_LESC || c == TEX_SESC )
4271 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4272 No attempt is made to correct the situation. */
4276 /* Read environment and prepend it to the default string.
4277 Build token table. */
4278 static struct TEX_tabent *
4279 TEX_decode_env (evarname, defenv)
4283 register char *env, *p;
4285 struct TEX_tabent *tab;
4288 /* Append default string to environment. */
4289 env = getenv (evarname);
4295 env = concat (oldenv, defenv, "");
4298 /* Allocate a token table */
4299 for (size = 1, p = env; p;)
4300 if ((p = etags_strchr (p, ':')) && *++p != '\0')
4302 /* Add 1 to leave room for null terminator. */
4303 tab = xnew (size + 1, struct TEX_tabent);
4305 /* Unpack environment string into token table. Be careful about */
4306 /* zero-length strings (leading ':', "::" and trailing ':') */
4309 p = etags_strchr (env, ':');
4310 if (!p) /* End of environment string. */
4311 p = env + strlen (env);
4313 { /* Only non-zero strings. */
4314 tab[i].name = savenstr (env, p - env);
4315 tab[i].len = strlen (tab[i].name);
4322 tab[i].name = NULL; /* Mark end of table. */
4330 /* If the text at CP matches one of the tag-defining TeX command names,
4331 return the pointer to the first occurrence of that command in TEX_toktab.
4332 Otherwise return -1.
4333 Keep the capital `T' in `token' for dumb truncating compilers
4334 (this distinguishes it from `TEX_toktab' */
4341 for (i = 0; TEX_toktab[i].len > 0; i++)
4342 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
4348 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
4350 * Assumes that the predicate starts at column 0.
4351 * Only the first clause of a predicate is added.
4353 static int prolog_pred P_((char *, char *));
4354 static void prolog_skip_comment P_((linebuffer *, FILE *));
4355 static int prolog_atom P_((char *, int));
4358 Prolog_functions (inf)
4369 LOOP_ON_INPUT_LINES (inf, lb, cp)
4371 if (cp[0] == '\0') /* Empty line */
4373 else if (iswhite (cp[0])) /* Not a predicate */
4375 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
4376 prolog_skip_comment (&lb, inf);
4377 else if ((len = prolog_pred (cp, last)) > 0)
4379 /* Predicate. Store the function name so that we only
4380 generate a tag for the first clause. */
4382 last = xnew(len + 1, char);
4383 else if (len + 1 > allocated)
4384 last = xrnew (last, len + 1, char);
4385 allocated = len + 1;
4386 strncpy (last, cp, len);
4394 prolog_skip_comment (plb, inf)
4402 for (cp = plb->buffer; *cp != '\0'; cp++)
4403 if (cp[0] == '*' && cp[1] == '/')
4406 linecharno += readline (plb, inf);
4412 * A predicate definition is added if it matches:
4413 * <beginning of line><Prolog Atom><whitespace>(
4415 * It is added to the tags database if it doesn't match the
4416 * name of the previous clause header.
4418 * Return the size of the name of the predicate, or 0 if no header
4422 prolog_pred (s, last)
4424 char *last; /* Name of last clause. */
4429 pos = prolog_atom (s, 0);
4434 pos = skip_spaces (s + pos) - s;
4436 if ((s[pos] == '(') || (s[pos] == '.'))
4441 /* Save only the first clause. */
4443 || len != (int)strlen (last)
4444 || !strneq (s, last, len))
4446 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4454 * Consume a Prolog atom.
4455 * Return the number of bytes consumed, or -1 if there was an error.
4457 * A prolog atom, in this context, could be one of:
4458 * - An alphanumeric sequence, starting with a lower case letter.
4459 * - A quoted arbitrary string. Single quotes can escape themselves.
4460 * Backslash quotes everything.
4463 prolog_atom (s, pos)
4471 if (islower((unsigned char) s[pos]) || (s[pos] == '_'))
4473 /* The atom is unquoted. */
4475 while (isalnum((unsigned char) s[pos]) || (s[pos] == '_'))
4479 return pos - origpos;
4481 else if (s[pos] == '\'')
4492 pos++; /* A double quote */
4494 else if (s[pos] == '\0')
4495 /* Multiline quoted atoms are ignored. */
4497 else if (s[pos] == '\\')
4499 if (s[pos+1] == '\0')
4506 return pos - origpos;
4513 * Support for Erlang -- Anders Lindgren, Feb 1996.
4515 * Generates tags for functions, defines, and records.
4517 * Assumes that Erlang functions start at column 0.
4519 static int erlang_func P_((char *, char *));
4520 static void erlang_attribute P_((char *));
4521 static int erlang_atom P_((char *, int));
4524 Erlang_functions (inf)
4535 LOOP_ON_INPUT_LINES (inf, lb, cp)
4537 if (cp[0] == '\0') /* Empty line */
4539 else if (iswhite (cp[0])) /* Not function nor attribute */
4541 else if (cp[0] == '%') /* comment */
4543 else if (cp[0] == '"') /* Sometimes, strings start in column one */
4545 else if (cp[0] == '-') /* attribute, e.g. "-define" */
4547 erlang_attribute (cp);
4550 else if ((len = erlang_func (cp, last)) > 0)
4553 * Function. Store the function name so that we only
4554 * generates a tag for the first clause.
4557 last = xnew (len + 1, char);
4558 else if (len + 1 > allocated)
4559 last = xrnew (last, len + 1, char);
4560 allocated = len + 1;
4561 strncpy (last, cp, len);
4569 * A function definition is added if it matches:
4570 * <beginning of line><Erlang Atom><whitespace>(
4572 * It is added to the tags database if it doesn't match the
4573 * name of the previous clause header.
4575 * Return the size of the name of the function, or 0 if no function
4579 erlang_func (s, last)
4581 char *last; /* Name of last clause. */
4586 pos = erlang_atom (s, 0);
4591 pos = skip_spaces (s + pos) - s;
4593 /* Save only the first clause. */
4596 || len != (int)strlen (last)
4597 || !strneq (s, last, len)))
4599 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4608 * Handle attributes. Currently, tags are generated for defines
4611 * They are on the form:
4612 * -define(foo, bar).
4613 * -define(Foo(M, N), M+N).
4614 * -record(graph, {vtab = notable, cyclic = true}).
4617 erlang_attribute (s)
4623 if (strneq (s, "-define", 7) || strneq (s, "-record", 7))
4625 pos = skip_spaces (s + 7) - s;
4626 if (s[pos++] == '(')
4628 pos = skip_spaces (s + pos) - s;
4629 len = erlang_atom (s, pos);
4631 pfnote (savenstr (& s[pos], len), TRUE,
4632 s, pos + len, lineno, linecharno);
4640 * Consume an Erlang atom (or variable).
4641 * Return the number of bytes consumed, or -1 if there was an error.
4644 erlang_atom (s, pos)
4652 if (isalpha ((unsigned char) s[pos]) || s[pos] == '_')
4654 /* The atom is unquoted. */
4656 while (isalnum ((unsigned char) s[pos]) || s[pos] == '_')
4658 return pos - origpos;
4660 else if (s[pos] == '\'')
4671 else if (s[pos] == '\0')
4672 /* Multiline quoted atoms are ignored. */
4674 else if (s[pos] == '\\')
4676 if (s[pos+1] == '\0')
4683 return pos - origpos;
4689 #ifdef ETAGS_REGEXPS
4691 static char *scan_separators P_((char *));
4692 static void analyse_regex P_((char *, bool));
4693 static void add_regex P_((char *, bool, language *));
4694 static char *substitute P_((char *, char *, struct re_registers *));
4696 /* Take a string like "/blah/" and turn it into "blah", making sure
4697 that the first and last characters are the same, and handling
4698 quoted separator characters. Actually, stops on the occurrence of
4699 an unquoted separator. Also turns "\t" into a Tab character.
4700 Returns pointer to terminating separator. Works in place. Null
4701 terminates name string. */
4703 scan_separators (name)
4707 char *copyto = name;
4708 bool quoted = FALSE;
4710 for (++name; *name != '\0'; ++name)
4716 else if (*name == sep)
4720 /* Something else is quoted, so preserve the quote. */
4726 else if (*name == '\\')
4728 else if (*name == sep)
4734 /* Terminate copied string. */
4739 /* Look at the argument of --regex or --no-regex and do the right
4740 thing. Same for each line of a regexp file. */
4742 analyse_regex (regex_arg, ignore_case)
4746 if (regex_arg == NULL)
4747 free_patterns (); /* --no-regex: remove existing regexps */
4749 /* A real --regexp option or a line in a regexp file. */
4750 switch (regex_arg[0])
4752 /* Comments in regexp file or null arg to --regex. */
4758 /* Read a regex file. This is recursive and may result in a
4759 loop, which will stop when the file descriptors are exhausted. */
4763 linebuffer regexbuf;
4764 char *regexfile = regex_arg + 1;
4766 /* regexfile is a file containing regexps, one per line. */
4767 regexfp = fopen (regexfile, "r");
4768 if (regexfp == NULL)
4773 initbuffer (®exbuf);
4774 while (readline_internal (®exbuf, regexfp) > 0)
4775 analyse_regex (regexbuf.buffer, ignore_case);
4776 free (regexbuf.buffer);
4781 /* Regexp to be used for a specific language only. */
4785 char *lang_name = regex_arg + 1;
4788 for (cp = lang_name; *cp != '}'; cp++)
4791 error ("unterminated language name in regex: %s", regex_arg);
4795 lang = get_language_from_name (lang_name);
4798 add_regex (cp + 1, ignore_case, lang);
4802 /* Regexp to be used for any language. */
4804 add_regex (regex_arg, ignore_case, NULL);
4809 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4810 expression, into a real regular expression by compiling it. */
4812 add_regex (regexp_pattern, ignore_case, lang)
4813 char *regexp_pattern;
4819 struct re_pattern_buffer *patbuf;
4823 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0])
4825 error ("%s: unterminated regexp", regexp_pattern);
4828 name = scan_separators (regexp_pattern);
4829 if (regexp_pattern[0] == '\0')
4831 error ("null regexp", (char *)NULL);
4834 (void) scan_separators (name);
4836 patbuf = xnew (1, struct re_pattern_buffer);
4837 /* Translation table to fold case if appropriate. */
4838 patbuf->translate = (ignore_case) ? lc_trans : NULL;
4839 patbuf->fastmap = NULL;
4840 patbuf->buffer = NULL;
4841 patbuf->allocated = 0;
4843 #if 0 /* useful when debugging windows quoting convention problems */
4844 printf ("Compiling regex pattern: %s\n", regexp_pattern);
4847 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4850 error ("%s while compiling pattern", err);
4855 p_head = xnew (1, pattern);
4856 p_head->regex = savestr (regexp_pattern);
4857 p_head->p_next = pp;
4858 p_head->language = lang;
4859 p_head->pattern = patbuf;
4860 p_head->name_pattern = savestr (name);
4861 p_head->error_signaled = FALSE;
4865 * Do the substitutions indicated by the regular expression and
4869 substitute (in, out, regs)
4871 struct re_registers *regs;
4874 int size, dig, diglen;
4877 size = strlen (out);
4879 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4880 if (out[size - 1] == '\\')
4881 fatal ("pattern error in \"%s\"", out);
4882 for (t = etags_strchr (out, '\\');
4884 t = etags_strchr (t + 2, '\\'))
4885 if (isdigit ((unsigned char) t[1]))
4888 diglen = regs->end[dig] - regs->start[dig];
4894 /* Allocate space and do the substitutions. */
4895 result = xnew (size + 1, char);
4897 for (t = result; *out != '\0'; out++)
4898 if (*out == '\\' && isdigit ((unsigned char) *++out))
4900 /* Using "dig2" satisfies my debugger. Bleah. */
4902 diglen = regs->end[dig] - regs->start[dig];
4903 strncpy (t, in + regs->start[dig], diglen);
4910 if (DEBUG && (t > result + size || t - result != (int)strlen (result)))
4916 /* Deallocate all patterns. */
4921 while (p_head != NULL)
4923 pp = p_head->p_next;
4924 free (p_head->regex);
4925 free (p_head->name_pattern);
4940 /* Go till you get to white space or a syntactic break */
4942 *cp != '\0' && *cp != '(' && *cp != ')' && !iswhite (*cp);
4945 pfnote (savenstr (bp, cp-bp), TRUE,
4946 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4949 #endif /* ETAGS_REGEXPS */
4950 /* Initialize a linebuffer for use */
4956 lbp->buffer = xnew (200, char);
4960 * Read a line of text from `stream' into `lbp', excluding the
4961 * newline or CR-NL, if any. Return the number of characters read from
4962 * `stream', which is the length of the line including the newline.
4964 * On DOS or Windows we do not count the CR character, if any, before the
4965 * NL, in the returned length; this mirrors the behavior of emacs on those
4966 * platforms (for text files, it translates CR-NL to NL as it reads in the
4970 readline_internal (lbp, stream)
4972 register FILE *stream;
4974 char *buffer = lbp->buffer;
4975 register char *p = lbp->buffer;
4976 register char *pend;
4979 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
4983 register int c = getc (stream);
4986 /* We're at the end of linebuffer: expand it. */
4988 buffer = xrnew (buffer, lbp->size, char);
4989 p += buffer - lbp->buffer;
4990 pend = buffer + lbp->size;
4991 lbp->buffer = buffer;
5001 if (p > buffer && p[-1] == '\r')
5005 /* Assume CRLF->LF translation will be performed by Emacs
5006 when loading this file, so CRs won't appear in the buffer.
5007 It would be cleaner to compensate within Emacs;
5008 however, Emacs does not know how many CRs were deleted
5009 before any given point in the file. */
5024 lbp->len = p - buffer;
5026 return lbp->len + chars_deleted;
5030 * Like readline_internal, above, but in addition try to match the
5031 * input line against relevant regular expressions.
5034 readline (lbp, stream)
5038 /* Read new line. */
5039 long result = readline_internal (lbp, stream);
5040 #ifdef ETAGS_REGEXPS
5044 /* Match against relevant patterns. */
5046 for (pp = p_head; pp != NULL; pp = pp->p_next)
5048 /* Only use generic regexps or those for the current language. */
5049 if (pp->language != NULL && pp->language != curlang)
5052 match = re_match (pp->pattern, lbp->buffer, lbp->len, 0, &pp->regs);
5057 if (!pp->error_signaled)
5059 error ("error while matching \"%s\"", pp->regex);
5060 pp->error_signaled = TRUE;
5067 /* Match occurred. Construct a tag. */
5068 if (pp->name_pattern[0] != '\0')
5070 /* Make a named tag. */
5071 char *name = substitute (lbp->buffer,
5072 pp->name_pattern, &pp->regs);
5074 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
5078 /* Make an unnamed tag. */
5079 pfnote ((char *)NULL, TRUE,
5080 lbp->buffer, match, lineno, linecharno);
5085 #endif /* ETAGS_REGEXPS */
5091 * Return a pointer to a space of size strlen(cp)+1 allocated
5092 * with xnew where the string CP has been copied.
5098 return savenstr (cp, strlen (cp));
5102 * Return a pointer to a space of size LEN+1 allocated with xnew where
5103 * the string CP has been copied for at most the first LEN characters.
5112 dp = xnew (len + 1, char);
5113 strncpy (dp, cp, len);
5119 * Return the ptr in sp at which the character c last
5120 * appears; NULL if not found
5122 * Identical to POSIX strrchr, included for portability.
5125 etags_strrchr (sp, c)
5126 register const char *sp;
5129 register const char *r;
5142 * Return the ptr in sp at which the character c first
5143 * appears; NULL if not found
5145 * Identical to POSIX strchr, included for portability.
5148 etags_strchr (sp, c)
5149 register const char *sp;
5160 /* Skip spaces, return new pointer. */
5165 while (iswhite (*cp))
5170 /* Skip non spaces, return new pointer. */
5172 skip_non_spaces (cp)
5175 while (*cp != '\0' && !iswhite (*cp))
5180 /* Print error message and exit. */
5198 suggest_asking_for_help ()
5200 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
5211 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5214 const char *s1, *s2;
5216 fprintf (stderr, "%s: ", progname);
5217 fprintf (stderr, s1, s2);
5218 fprintf (stderr, "\n");
5221 /* Return a newly-allocated string whose contents
5222 concatenate those of s1, s2, s3. */
5227 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
5228 char *result = xnew (len1 + len2 + len3 + 1, char);
5230 strcpy (result, s1);
5231 strcpy (result + len1, s2);
5232 strcpy (result + len1 + len2, s3);
5233 result[len1 + len2 + len3] = '\0';
5238 /* Does the same work as the system V getcwd, but does not need to
5239 guess the buffer size in advance. */
5245 char *path = xnew (bufsize, char);
5247 while (getcwd (path, bufsize) == NULL)
5249 if (errno != ERANGE)
5253 path = xnew (bufsize, char);
5256 canonicalize_filename (path);
5259 #else /* not HAVE_GETCWD */
5264 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
5265 if (pipe == NULL || readline_internal (&path, pipe) == 0)
5270 #endif /* not HAVE_GETCWD */
5273 /* Return a newly allocated string containing the file name of FILE
5274 relative to the absolute directory DIR (which should end with a slash). */
5276 relative_filename (file, dir)
5279 char *fp, *dp, *afn, *res;
5282 /* Find the common root of file and dir (with a trailing slash). */
5283 afn = absolute_filename (file, cwd);
5286 while (*fp++ == *dp++)
5288 fp--, dp--; /* back to the first differing char */
5290 if (fp == afn && afn[0] != '/') /* cannot build a relative name */
5293 do /* look at the equal chars until '/' */
5297 /* Build a sequence of "../" strings for the resulting relative file name. */
5299 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
5301 res = xnew (3*i + strlen (fp + 1) + 1, char);
5304 strcat (res, "../");
5306 /* Add the file name relative to the common root of file and dir. */
5307 strcat (res, fp + 1);
5313 /* Return a newly allocated string containing the absolute file name
5314 of FILE given DIR (which should end with a slash). */
5316 absolute_filename (file, dir)
5319 char *slashp, *cp, *res;
5321 if (filename_is_absolute (file))
5322 res = savestr (file);
5324 /* We don't support non-absolute file names with a drive
5325 letter, like `d:NAME' (it's too much hassle). */
5326 else if (file[1] == ':')
5327 fatal ("%s: relative file names with drive letters not supported", file);
5330 res = concat (dir, file, "");
5332 /* Delete the "/dirname/.." and "/." substrings. */
5333 slashp = etags_strchr (res, '/');
5334 while (slashp != NULL && slashp[0] != '\0')
5336 if (slashp[1] == '.')
5338 if (slashp[2] == '.'
5339 && (slashp[3] == '/' || slashp[3] == '\0'))
5344 while (cp >= res && !filename_is_absolute (cp));
5346 cp = slashp; /* the absolute name begins with "/.." */
5348 /* Under Windows we get `d:/NAME' as absolute
5349 file name, so the luser could say `d:/../NAME'.
5350 We silently treat this as `d:/NAME'. */
5351 else if (cp[0] != '/')
5354 strcpy (cp, slashp + 3);
5358 else if (slashp[2] == '/' || slashp[2] == '\0')
5360 strcpy (slashp, slashp + 2);
5365 slashp = etags_strchr (slashp + 1, '/');
5369 return savestr ("/");
5374 /* Return a newly allocated string containing the absolute
5375 file name of dir where FILE resides given DIR (which should
5376 end with a slash). */
5378 absolute_dirname (file, dir)
5384 canonicalize_filename (file);
5385 slashp = etags_strrchr (file, '/');
5387 return savestr (dir);
5390 res = absolute_filename (file, dir);
5396 /* Whether the argument string is an absolute file name. The argument
5397 string must have been canonicalized with canonicalize_filename. */
5399 filename_is_absolute (fn)
5402 return (fn[0] == '/'
5404 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/')
5409 /* Translate backslashes into slashes. Works in place. */
5411 canonicalize_filename (fn)
5415 /* Canonicalize drive letter case. */
5416 if (islower (fn[0]) && fn[1] == ':')
5417 fn[0] = toupper (fn[0]);
5418 /* Convert backslashes to slashes. */
5419 for (; *fn != '\0'; fn++)
5424 fn = NULL; /* shut up the compiler */
5428 /* Increase the size of a linebuffer. */
5430 grow_linebuffer (lbp, toksize)
5434 while (lbp->size < toksize)
5436 lbp->buffer = xrnew (lbp->buffer, lbp->size, char);
5439 /* Like malloc but get fatal error if memory is exhausted. */
5444 long *result = (long *) malloc (size);
5446 fatal ("virtual memory exhausted", (char *)NULL);
5451 xrealloc (ptr, size)
5455 long *result = (long *) realloc (ptr, size);
5457 fatal ("virtual memory exhausted", (char *)NULL);