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.
32 * Ansified by Martin Buchholz, 19991105.
35 char pot_etags_version[] = "@(#) pot revision number is 13.33";
46 /* On some systems, Emacs defines static as nothing for the sake
47 of unexec. We don't want that here since we don't use unexec. */
49 # define ETAGS_REGEXPS /* use the regexp features */
50 # define LONG_OPTIONS /* accept long options */
51 #endif /* HAVE_CONFIG_H */
54 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
59 # include <sys/param.h>
61 # ifndef HAVE_CONFIG_H
63 # include <sys/config.h>
72 # define MAXPATHLEN _MAX_PATH
77 # endif /* not HAVE_CONFIG_H */
80 # endif /* undef HAVE_GETCWD */
81 #endif /* WINDOWSNT */
83 #if !defined (WINDOWSNT) && defined (STDC_HEADERS)
92 extern char *getcwd ();
94 #endif /* HAVE_UNISTD_H */
102 #include <sys/types.h>
103 #include <sys/stat.h>
105 #if !defined (S_ISREG) && defined (S_IFREG)
106 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
112 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
114 extern int optind, opterr;
115 #endif /* LONG_OPTIONS */
119 #endif /* ETAGS_REGEXPS */
121 /* Define CTAGS to make the program "ctags" compatible with the usual one.
122 Leave it undefined to make the program "etags", which makes emacs-style
123 tag tables and tags typedefs, #defines and struct/union/enum by default. */
131 /* Exit codes for success and failure. */
141 #define C_PLPL 0x00001 /* C++ */
142 #define C_STAR 0x00003 /* C* */
143 #define C_JAVA 0x00005 /* JAVA */
144 #define YACC 0x10000 /* yacc file */
146 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
147 && (abort (), 1)) || !strcmp (s, t))
148 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
149 && (abort (), 1)) || !strncmp (s, t, n))
151 #define lowcase(c) tolower ((char)c)
153 #define CHARS 256 /* 2^sizeof(char) */
154 #define CHAR(x) ((unsigned int)x & (CHARS - 1))
155 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
156 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
157 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
158 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
159 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
163 * xnew, xrnew -- allocate, reallocate storage
165 * SYNOPSIS: Type *xnew (int n, Type);
166 * Type *xrnew (OldPointer, int n, Type);
169 # include "chkmalloc.h"
170 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
171 (n) * sizeof (Type)))
172 # define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \
173 (op), (n) * sizeof (Type)))
175 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
176 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type)))
181 typedef void Lang_function ();
186 char *command; /* Takes one arg and decompresses to stdout */
192 Lang_function *function;
197 extern char *getenv ();
199 typedef struct node_st
200 { /* sorting structure */
201 char *name; /* function or type name */
202 char *file; /* file name */
203 bool is_func; /* use pattern or line no */
204 bool been_warned; /* set if noticed dup */
205 int lno; /* line number tag is on */
206 long cno; /* character number line starts on */
207 char *pat; /* search pattern */
208 struct node_st *left, *right; /* left and right sons */
212 * A `linebuffer' is a structure which holds a line of text.
213 * `readline_internal' reads a line from a stream into a linebuffer
214 * and works regardless of the length of the line.
215 * SIZE is the size of BUFFER, LEN is the length of the string in
216 * BUFFER after readline reads it.
225 /* Many compilers barf on this:
226 Lang_function Ada_funcs;
227 so let's write it this way */
228 void Ada_funcs (FILE *inf);
229 void Asm_labels (FILE *inf);
230 void C_entries (int c_ext, FILE *inf);
231 void default_C_entries (FILE *inf);
232 void plain_C_entries (FILE *inf);
233 void Cjava_entries (FILE *inf);
234 void Cobol_paragraphs (FILE *inf);
235 void Cplusplus_entries (FILE *inf);
236 void Cstar_entries (FILE *inf);
237 void Erlang_functions (FILE *inf);
238 void Fortran_functions (FILE *inf);
239 void Yacc_entries (FILE *inf);
240 void Lisp_functions (FILE *inf);
241 void Pascal_functions (FILE *inf);
242 void Perl_functions (FILE *inf);
243 void Postscript_functions (FILE *inf);
244 void Prolog_functions (FILE *inf);
245 void Python_functions (FILE *inf);
246 void Scheme_functions (FILE *inf);
247 void TeX_functions (FILE *inf);
248 void just_read_file (FILE *inf);
250 compressor *get_compressor_from_suffix (char *file, char **extptr);
251 language *get_language_from_name (char *name);
252 language *get_language_from_interpreter (char *interpreter);
253 language *get_language_from_suffix (char *file);
254 int total_size_of_entries (register node *np);
255 long readline (linebuffer *lbp, FILE *stream);
256 long readline_internal (linebuffer *lbp, register FILE *stream);
257 void get_tag (register char *bp);
260 void analyse_regex (char *regex_arg, bool ignore_case);
261 void add_regex (char *regexp_pattern, bool ignore_case, language *lan);
262 void free_patterns (void);
263 #endif /* ETAGS_REGEXPS */
264 void error (const char *s1, const char *s2);
265 void suggest_asking_for_help (void);
266 void fatal (char *s1, char *s2);
267 void pfatal (char *s1);
268 void add_node (node *np, node **cur_node_p);
271 void initbuffer (linebuffer *lbp);
272 void find_entries (char *file, FILE *inf);
273 void free_tree (register node *np);
274 void pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, long int cno);
275 void new_pfnote (char *name, int namelen, bool is_func, char *linestart, int linelen, int lno, long int cno);
276 void process_file (char *file);
277 void put_entries (register node *np);
278 void takeprec (void);
280 char *concat (char *s1, char *s2, char *s3);
281 char *skip_spaces (char *cp);
282 char *skip_non_spaces (char *cp);
283 char *savenstr (char *cp, int len);
284 char *savestr (char *cp);
285 char *etags_strchr (char *sp, char c);
286 char *etags_strrchr (char *sp, char c);
287 char *etags_getcwd (void);
288 char *relative_filename (char *file, char *dir);
289 char *absolute_filename (char *file, char *dir);
290 char *absolute_dirname (char *file, char *dir);
291 bool filename_is_absolute (char *fn);
292 void canonicalize_filename (register char *fn);
293 void grow_linebuffer (linebuffer *lbp, int toksize);
294 long *xmalloc (unsigned int size);
295 long *xrealloc (char *ptr, unsigned int size);
298 char searchar = '/'; /* use /.../ searches */
300 char *tagfile; /* output file */
301 char *progname; /* name this program was invoked with */
302 char *cwd; /* current working directory */
303 char *tagfiledir; /* directory of tagfile */
304 FILE *tagf; /* ioptr for tags file */
306 char *curfile; /* current input file name */
307 language *curlang; /* current language */
309 int lineno; /* line number of current line */
310 long charno; /* current character number */
311 long linecharno; /* charno of start of current line */
312 char *dbp; /* pointer to start of current tag */
314 node *head; /* the head of the binary tree of tags */
316 linebuffer lb; /* the current line */
317 linebuffer token_name; /* used by C_entries as a temporary area */
321 linebuffer lb; /* used by C_entries instead of lb */
324 /* boolean "functions" (see init) */
325 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
328 *white = " \f\t\n\r",
330 *nonam = " \f\t\n\r(=,[;",
331 /* token ending chars */
332 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
333 /* token starting chars */
334 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
335 /* valid in-token chars */
336 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
338 bool append_to_tagfile; /* -a: append to tags */
339 /* The following four default to TRUE for etags, but to FALSE for ctags. */
340 bool typedefs; /* -t: create tags for C and Ada typedefs */
341 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */
342 /* 0 struct/enum/union decls, and C++ */
343 /* member functions. */
344 bool constantypedefs; /* -d: create tags for C #define, enum */
345 /* constants and variables. */
346 /* -D: opposite of -d. Default under ctags. */
347 bool declarations; /* --declarations: tag them and extern in C&Co*/
348 bool globals; /* create tags for global variables */
349 bool members; /* create tags for C member variables */
350 bool update; /* -u: update tags */
351 bool vgrind_style; /* -v: create vgrind style index output */
352 bool no_warnings; /* -w: suppress warnings */
353 bool cxref_style; /* -x: create cxref style output */
354 bool cplusplus; /* .[hc] means C++, not C */
355 bool noindentypedefs; /* -I: ignore indentation in C */
356 bool packages_only; /* --packages-only: in Ada, only tag packages*/
359 struct option longopts[] =
361 { "packages-only", no_argument, &packages_only, TRUE },
362 { "append", no_argument, NULL, 'a' },
363 { "backward-search", no_argument, NULL, 'B' },
364 { "c++", no_argument, NULL, 'C' },
365 { "cxref", no_argument, NULL, 'x' },
366 { "defines", no_argument, NULL, 'd' },
367 { "declarations", no_argument, &declarations, TRUE },
368 { "no-defines", no_argument, NULL, 'D' },
369 { "globals", no_argument, &globals, TRUE },
370 { "no-globals", no_argument, &globals, FALSE },
371 { "help", no_argument, NULL, 'h' },
372 { "help", no_argument, NULL, 'H' },
373 { "ignore-indentation", no_argument, NULL, 'I' },
374 { "include", required_argument, NULL, 'i' },
375 { "language", required_argument, NULL, 'l' },
376 { "members", no_argument, &members, TRUE },
377 { "no-members", no_argument, &members, FALSE },
378 { "no-warn", no_argument, NULL, 'w' },
379 { "output", required_argument, NULL, 'o' },
381 { "regex", required_argument, NULL, 'r' },
382 { "no-regex", no_argument, NULL, 'R' },
383 { "ignore-case-regex", required_argument, NULL, 'c' },
384 #endif /* ETAGS_REGEXPS */
385 { "typedefs", no_argument, NULL, 't' },
386 { "typedefs-and-c++", no_argument, NULL, 'T' },
387 { "update", no_argument, NULL, 'u' },
388 { "version", no_argument, NULL, 'V' },
389 { "vgrind", no_argument, NULL, 'v' },
392 #endif /* LONG_OPTIONS */
395 /* Structure defining a regular expression. Elements are
396 the compiled pattern, and the name string. */
397 typedef struct pattern
399 struct pattern *p_next;
402 struct re_pattern_buffer *pattern;
403 struct re_registers regs;
408 /* List of all regexps. */
409 pattern *p_head = NULL;
411 /* How many characters in the character set. (From regex.c.) */
412 #define CHAR_SET_SIZE 256
413 /* Translation table for case-insensitive matching. */
414 char lc_trans[CHAR_SET_SIZE];
415 #endif /* ETAGS_REGEXPS */
417 compressor compressors[] =
419 { "z", "gzip -d -c"},
420 { "Z", "gzip -d -c"},
421 { "gz", "gzip -d -c"},
422 { "GZ", "gzip -d -c"},
423 { "bz2", "bzip2 -d -c" },
431 /* Non-NULL if language fixed. */
432 language *forced_lang = NULL;
435 char *Ada_suffixes [] =
436 { "ads", "adb", "ada", NULL };
439 char *Asm_suffixes [] = { "a", /* Unix assembler */
440 "asm", /* Microcontroller assembly */
441 "def", /* BSO/Tasking definition includes */
442 "inc", /* Microcontroller include files */
443 "ins", /* Microcontroller include files */
444 "s", "sa", /* Unix assembler */
445 "S", /* cpp-processed Unix assembler */
446 "src", /* BSO/Tasking C compiler output */
450 /* Note that .c and .h can be considered C++, if the --c++ flag was
451 given. That is why default_C_entries is called here. */
452 char *default_C_suffixes [] =
455 char *Cplusplus_suffixes [] =
456 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
457 "M", /* Objective C++ */
458 "pdb", /* Postscript with C syntax */
461 char *Cjava_suffixes [] =
464 char *Cobol_suffixes [] =
465 { "COB", "cob", NULL };
467 char *Cstar_suffixes [] =
468 { "cs", "hs", NULL };
470 char *Erlang_suffixes [] =
471 { "erl", "hrl", NULL };
473 char *Fortran_suffixes [] =
474 { "F", "f", "f90", "for", NULL };
476 char *Lisp_suffixes [] =
477 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
479 char *Pascal_suffixes [] =
480 { "p", "pas", NULL };
482 char *Perl_suffixes [] =
483 { "pl", "pm", NULL };
484 char *Perl_interpreters [] =
485 { "perl", "@PERL@", NULL };
487 char *plain_C_suffixes [] =
488 { "pc", /* Pro*C file */
489 "m", /* Objective C file */
490 "lm", /* Objective lex file */
493 char *Postscript_suffixes [] =
494 { "ps", "psw", NULL }; /* .psw is for PSWrap */
496 char *Prolog_suffixes [] =
499 char *Python_suffixes [] =
502 /* Can't do the `SCM' or `scm' prefix with a version number. */
503 char *Scheme_suffixes [] =
504 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "ss", "t", NULL };
506 char *TeX_suffixes [] =
507 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
509 char *Yacc_suffixes [] =
510 { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */
513 * Table of languages.
515 * It is ok for a given function to be listed under more than one
516 * name. I just didn't.
519 language lang_names [] =
521 { "ada", Ada_funcs, Ada_suffixes, NULL },
522 { "asm", Asm_labels, Asm_suffixes, NULL },
523 { "c", default_C_entries, default_C_suffixes, NULL },
524 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
525 { "c*", Cstar_entries, Cstar_suffixes, NULL },
526 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL },
527 { "erlang", Erlang_functions, Erlang_suffixes, NULL },
528 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
529 { "java", Cjava_entries, Cjava_suffixes, NULL },
530 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
531 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
532 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
533 { "postscript", Postscript_functions, Postscript_suffixes, NULL },
534 { "proc", plain_C_entries, plain_C_suffixes, NULL },
535 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
536 { "python", Python_functions, Python_suffixes, NULL },
537 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
538 { "tex", TeX_functions, TeX_suffixes, NULL },
539 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
540 { "auto", NULL }, /* default guessing scheme */
541 { "none", just_read_file }, /* regexp matching only */
542 { NULL, NULL } /* end of list */
546 print_language_names ()
551 puts ("\nThese are the currently supported languages, along with the\n\
552 default file name suffixes:");
553 for (lang = lang_names; lang->name != NULL; lang++)
555 printf ("\t%s\t", lang->name);
556 if (lang->suffixes != NULL)
557 for (ext = lang->suffixes; *ext != NULL; ext++)
558 printf (" .%s", *ext);
561 puts ("Where `auto' means use default language for files based on file\n\
562 name suffix, and `none' means only do regexp processing on files.\n\
563 If no language is specified and no matching suffix is found,\n\
564 the first line of the file is read for a sharp-bang (#!) sequence\n\
565 followed by the name of an interpreter. If no such sequence is found,\n\
566 Fortran is tried first; if no tags are found, C is tried next.\n\
567 Compressed files are supported using gzip and bzip2.");
571 # define EMACS_NAME "XEmacs"
573 # define EMACS_NAME "GNU Emacs"
577 # define VERSION "20"
582 printf ("%s (" EMACS_NAME " %s)\n", (CTAGS) ? "ctags" : "etags", VERSION);
583 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
584 puts ("This program is distributed under the same terms as Emacs");
592 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
594 These are the options accepted by %s.\n", progname, progname);
596 puts ("You may use unambiguous abbreviations for the long option names.");
598 puts ("Long option names do not work with this executable, as it is not\n\
599 linked with GNU getopt.");
600 #endif /* LONG_OPTIONS */
601 puts ("A - as file name means read names from stdin (one per line).");
603 printf (" Absolute names are stored in the output file as they are.\n\
604 Relative ones are stored relative to the output file's directory.");
607 puts ("-a, --append\n\
608 Append tag entries to existing tags file.");
610 puts ("--packages-only\n\
611 For Ada files, only generate tags for packages .");
614 puts ("-B, --backward-search\n\
615 Write the search commands for the tag entries using '?', the\n\
616 backward-search command instead of '/', the forward-search command.");
619 Treat files whose name suffix defaults to C language as C++ files.");
621 puts ("--declarations\n\
622 In C and derived languages, create tags for function declarations,");
624 puts ("\tand create tags for extern variables if --globals is used.");
627 ("\tand create tags for extern variables unless --no-globals is used.");
630 puts ("-d, --defines\n\
631 Create tag entries for C #define constants and enum constants, too.");
633 puts ("-D, --no-defines\n\
634 Don't create tag entries for C #define constants and enum constants.\n\
635 This makes the tags file smaller.");
639 puts ("-i FILE, --include=FILE\n\
640 Include a note in tag file indicating that, when searching for\n\
641 a tag, one should also consult the tags file FILE after\n\
642 checking the current file.");
643 puts ("-l LANG, --language=LANG\n\
644 Force the following files to be considered as written in the\n\
645 named language up to the next --language=LANG option.");
650 Create tag entries for global variables in some languages.");
652 puts ("--no-globals\n\
653 Do not create tag entries for global variables in some\n\
654 languages. This makes the tags file smaller.");
656 Create tag entries for member variables in C and derived languages.");
659 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
660 Make a tag for each line matching pattern REGEXP in the following\n\
661 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
662 regexfile is a file containing one REGEXP per line.\n\
663 REGEXP is anchored (as if preceded by ^).\n\
664 The form /REGEXP/NAME/ creates a named tag.\n\
665 For example Tcl named tags can be created with:\n\
666 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
667 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
668 Like -r, --regex but ignore case when matching expressions.");
669 puts ("-R, --no-regex\n\
670 Don't create tags from regexps for the following files.");
671 #endif /* ETAGS_REGEXPS */
672 puts ("-o FILE, --output=FILE\n\
673 Write the tags to FILE.");
674 puts ("-I, --ignore-indentation\n\
675 Don't rely on indentation quite as much as normal. Currently,\n\
676 this means not to assume that a closing brace in the first\n\
677 column is the final brace of a function or structure\n\
678 definition in C and C++.");
682 puts ("-t, --typedefs\n\
683 Generate tag entries for C and Ada typedefs.");
684 puts ("-T, --typedefs-and-c++\n\
685 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
686 and C++ member functions.");
687 puts ("-u, --update\n\
688 Update the tag entries for the given files, leaving tag\n\
689 entries for other files in place. Currently, this is\n\
690 implemented by deleting the existing entries for the given\n\
691 files and then rewriting the new entries at the end of the\n\
692 tags file. It is often faster to simply rebuild the entire\n\
693 tag file than to use this.");
694 puts ("-v, --vgrind\n\
695 Generates an index of items intended for human consumption,\n\
696 similar to the output of vgrind. The index is sorted, and\n\
697 gives the page number of each item.");
698 puts ("-w, --no-warn\n\
699 Suppress warning messages about entries defined in multiple\n\
701 puts ("-x, --cxref\n\
702 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
703 The output uses line numbers instead of page numbers, but\n\
704 beyond that the differences are cosmetic; try both to see\n\
708 puts ("-V, --version\n\
709 Print the version of the program.\n\
711 Print this help message.");
713 print_language_names ();
716 puts ("Report bugs to bug-gnu-emacs@gnu.org");
730 /* This structure helps us allow mixing of --lang and file names. */
733 enum argument_type arg_type;
735 language *lang; /* language of the regexp */
738 #ifdef VMS /* VMS specific functions */
742 /* This is a BUG! ANY arbitrary limit is a BUG!
743 Won't someone please fix this? */
744 #define MAX_FILE_SPEC_LEN 255
747 char body[MAX_FILE_SPEC_LEN + 1];
751 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
752 returning in each successive call the next file name matching the input
753 spec. The function expects that each in_spec passed
754 to it will be processed to completion; in particular, up to and
755 including the call following that in which the last matching name
756 is returned, the function ignores the value of in_spec, and will
757 only start processing a new spec with the following call.
758 If an error occurs, on return out_spec contains the value
759 of in_spec when the error occurred.
761 With each successive file name returned in out_spec, the
762 function's return value is one. When there are no more matching
763 names the function returns zero. If on the first call no file
764 matches in_spec, or there is any other error, -1 is returned.
769 #define OUTSIZE MAX_FILE_SPEC_LEN
775 static long context = 0;
776 static struct dsc$descriptor_s o;
777 static struct dsc$descriptor_s i;
778 static bool pass1 = TRUE;
785 o.dsc$a_pointer = (char *) out;
786 o.dsc$w_length = (short)OUTSIZE;
787 i.dsc$a_pointer = in;
788 i.dsc$w_length = (short)strlen(in);
789 i.dsc$b_dtype = DSC$K_DTYPE_T;
790 i.dsc$b_class = DSC$K_CLASS_S;
791 o.dsc$b_dtype = DSC$K_DTYPE_VT;
792 o.dsc$b_class = DSC$K_CLASS_VS;
794 if ((status = lib$find_file(&i, &o, &context, 0, 0)) == RMS$_NORMAL)
796 out->body[out->curlen] = EOS;
799 else if (status == RMS$_NMF)
803 strcpy(out->body, in);
806 lib$find_file_end(&context);
812 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
813 name of each file specified by the provided arg expanding wildcards.
816 gfnames (arg, p_error)
820 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
822 switch (fn_exp (&filename, arg))
826 return filename.body;
832 return filename.body;
836 #ifndef OLD /* Newer versions of VMS do provide `system'. */
840 error ("%s", "system() function not implemented under VMS");
844 #define VERSION_DELIM ';'
845 char *massage_name (s)
851 if (*s == VERSION_DELIM)
869 unsigned int nincluded_files;
870 char **included_files;
873 int current_arg, file_count;
874 linebuffer filename_lb;
880 _fmode = O_BINARY; /* all of files are treated as binary files */
885 included_files = xnew (argc, char *);
889 /* Allocate enough no matter what happens. Overkill, but each one
891 argbuffer = xnew (argc, argument);
894 /* Set syntax for regular expression routines. */
895 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS);
896 /* Translation table for case-insensitive search. */
897 for (i = 0; i < CHAR_SET_SIZE; i++)
898 lc_trans[i] = lowcase (i);
899 #endif /* ETAGS_REGEXPS */
902 * If etags, always find typedefs and structure tags. Why not?
903 * Also default is to find macro constants, enum constants and
908 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
919 optstring = "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
921 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH";
922 #endif /* ETAGS_REGEXPS */
925 optstring = optstring + 1;
926 #endif /* LONG_OPTIONS */
928 opt = getopt_long (argc, argv, optstring, longopts, 0);
935 /* If getopt returns 0, then it has already processed a
936 long-named option. We should do nothing. */
940 /* This means that a file name has been seen. Record it. */
941 argbuffer[current_arg].arg_type = at_filename;
942 argbuffer[current_arg].what = optarg;
947 /* Common options. */
948 case 'a': append_to_tagfile = TRUE; break;
949 case 'C': cplusplus = TRUE; break;
950 case 'd': constantypedefs = TRUE; break;
951 case 'D': constantypedefs = FALSE; break;
952 case 'f': /* for compatibility with old makefiles */
956 error ("-o option may only be given once.", (char *)NULL);
957 suggest_asking_for_help ();
962 case 'S': /* for backward compatibility */
963 noindentypedefs = TRUE;
967 language *lang = get_language_from_name (optarg);
970 argbuffer[current_arg].lang = lang;
971 argbuffer[current_arg].arg_type = at_language;
978 argbuffer[current_arg].arg_type = at_regexp;
979 argbuffer[current_arg].what = optarg;
983 argbuffer[current_arg].arg_type = at_regexp;
984 argbuffer[current_arg].what = NULL;
988 argbuffer[current_arg].arg_type = at_icregexp;
989 argbuffer[current_arg].what = optarg;
992 #endif /* ETAGS_REGEXPS */
1004 typedefs = typedefs_and_cplusplus = TRUE;
1009 included_files[nincluded_files++] = optarg;
1012 /* Ctags options. */
1013 case 'B': searchar = '?'; break;
1014 case 'u': update = TRUE; break;
1015 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1016 case 'x': cxref_style = TRUE; break;
1017 case 'w': no_warnings = TRUE; break;
1020 suggest_asking_for_help ();
1024 for (; optind < argc; ++optind)
1026 argbuffer[current_arg].arg_type = at_filename;
1027 argbuffer[current_arg].what = argv[optind];
1032 if (nincluded_files == 0 && file_count == 0)
1034 error ("no input files specified.", (char *)NULL);
1035 suggest_asking_for_help ();
1038 if (tagfile == NULL)
1039 tagfile = CTAGS ? "tags" : "TAGS";
1040 cwd = etags_getcwd (); /* the current working directory */
1041 if (cwd[strlen (cwd) - 1] != '/')
1044 cwd = concat (oldcwd, "/", "");
1047 if (streq (tagfile, "-"))
1050 tagfiledir = absolute_dirname (tagfile, cwd);
1052 init (); /* set up boolean "functions" */
1055 initbuffer (&token_name);
1056 initbuffer (&lbs[0].lb);
1057 initbuffer (&lbs[1].lb);
1058 initbuffer (&filename_lb);
1062 if (streq (tagfile, "-"))
1066 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1067 doesn't take effect until after `stdout' is already open). */
1068 if (!isatty (fileno (stdout)))
1069 setmode (fileno (stdout), O_BINARY);
1073 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1079 * Loop through files finding functions.
1081 for (i = 0; i < current_arg; ++i)
1083 switch (argbuffer[i].arg_type)
1086 forced_lang = argbuffer[i].lang;
1088 #ifdef ETAGS_REGEXPS
1090 analyse_regex (argbuffer[i].what, FALSE);
1093 analyse_regex (argbuffer[i].what, TRUE);
1098 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1102 error ("can't find file %s\n", this_file);
1107 this_file = massage_name (this_file);
1110 this_file = argbuffer[i].what;
1112 /* Input file named "-" means read file names from stdin
1113 (one per line) and use them. */
1114 if (streq (this_file, "-"))
1115 while (readline_internal (&filename_lb, stdin) > 0)
1116 process_file (filename_lb.buffer);
1118 process_file (this_file);
1126 #ifdef ETAGS_REGEXPS
1128 #endif /* ETAGS_REGEXPS */
1132 while (nincluded_files-- > 0)
1133 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1139 /* If CTAGS, we are here. process_file did not write the tags yet,
1140 because we want them ordered. Let's do it now. */
1152 for (i = 0; i < current_arg; ++i)
1154 if (argbuffer[i].arg_type != at_filename)
1157 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1158 tagfile, argbuffer[i].what, tagfile);
1159 if (system (cmd) != GOOD)
1160 fatal ("failed to execute shell command", (char *)NULL);
1162 append_to_tagfile = TRUE;
1165 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1176 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1177 exit (system (cmd));
1185 * Return a compressor given the file name. If EXTPTR is non-zero,
1186 * return a pointer into FILE where the compressor-specific
1187 * extension begins. If no compressor is found, NULL is returned
1188 * and EXTPTR is not significant.
1189 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca>
1192 get_compressor_from_suffix (file, extptr)
1197 char *slash, *suffix;
1199 /* This relies on FN to be after canonicalize_filename,
1200 so we don't need to consider backslashes on DOS_NT. */
1201 slash = etags_strrchr (file, '/');
1202 suffix = etags_strrchr (file, '.');
1203 if (suffix == NULL || suffix < slash)
1208 /* Let those poor souls who live with DOS 8+3 file name limits get
1209 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1210 Only the first do loop is run if not MSDOS */
1213 for (compr = compressors; compr->suffix != NULL; compr++)
1214 if (streq (compr->suffix, suffix))
1221 } while (*suffix != '\0');
1228 * Return a language given the name.
1231 get_language_from_name (name)
1237 error ("empty language name", (char *)NULL);
1240 for (lang = lang_names; lang->name != NULL; lang++)
1241 if (streq (name, lang->name))
1243 error ("unknown language \"%s\"", name);
1251 * Return a language given the interpreter name.
1254 get_language_from_interpreter (interpreter)
1260 if (interpreter == NULL)
1262 for (lang = lang_names; lang->name != NULL; lang++)
1263 if (lang->interpreters != NULL)
1264 for (iname = lang->interpreters; *iname != NULL; iname++)
1265 if (streq (*iname, interpreter))
1274 * Return a language given the file name.
1277 get_language_from_suffix (file)
1281 char **ext, *suffix;
1283 suffix = etags_strrchr (file, '.');
1287 for (lang = lang_names; lang->name != NULL; lang++)
1288 if (lang->suffixes != NULL)
1289 for (ext = lang->suffixes; *ext != NULL; ext++)
1290 if (streq (*ext, suffix))
1298 * This routine is called on each file argument.
1304 struct stat stat_buf;
1307 char *compressed_name, *uncompressed_name;
1308 char *ext, *real_name;
1311 canonicalize_filename (file);
1312 if (streq (file, tagfile) && !streq (tagfile, "-"))
1314 error ("skipping inclusion of %s in self.", file);
1317 if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
1319 compressed_name = NULL;
1320 real_name = uncompressed_name = savestr (file);
1324 real_name = compressed_name = savestr (file);
1325 uncompressed_name = savenstr (file, ext - file);
1328 /* If the canonicalised uncompressed name has already be dealt with,
1329 skip it silently, else add it to the list. */
1331 typedef struct processed_file
1334 struct processed_file *next;
1336 static processed_file *pf_head = NULL;
1337 register processed_file *fnp;
1339 for (fnp = pf_head; fnp != NULL; fnp = fnp->next)
1340 if (streq (uncompressed_name, fnp->filename))
1343 pf_head = xnew (1, struct processed_file);
1344 pf_head->filename = savestr (uncompressed_name);
1345 pf_head->next = fnp;
1348 if (stat (real_name, &stat_buf) != 0)
1350 /* Reset real_name and try with a different name. */
1352 if (compressed_name != NULL) /* try with the given suffix */
1354 if (stat (uncompressed_name, &stat_buf) == 0)
1355 real_name = uncompressed_name;
1357 else /* try all possible suffixes */
1359 for (compr = compressors; compr->suffix != NULL; compr++)
1361 compressed_name = concat (file, ".", compr->suffix);
1362 if (stat (compressed_name, &stat_buf) != 0)
1365 char *suf = compressed_name + strlen (file);
1366 size_t suflen = strlen (compr->suffix) + 1;
1367 for ( ; suf[1]; suf++, suflen--)
1369 memmove (suf, suf + 1, suflen);
1370 if (stat (compressed_name, &stat_buf) == 0)
1372 real_name = compressed_name;
1376 if (real_name != NULL)
1379 free (compressed_name);
1380 compressed_name = NULL;
1384 real_name = compressed_name;
1389 if (real_name == NULL)
1394 } /* try with a different name */
1396 if (!S_ISREG (stat_buf.st_mode))
1398 error ("skipping %s: it is not a regular file.", real_name);
1401 if (real_name == compressed_name)
1403 char *cmd = concat (compr->command, " ", real_name);
1404 inf = popen (cmd, "r");
1408 inf = fopen (real_name, "r");
1415 find_entries (uncompressed_name, inf);
1417 if (real_name == compressed_name)
1426 if (filename_is_absolute (uncompressed_name))
1428 /* file is an absolute file name. Canonicalise it. */
1429 filename = absolute_filename (uncompressed_name, cwd);
1433 /* file is a file name relative to cwd. Make it relative
1434 to the directory of the tags file. */
1435 filename = relative_filename (uncompressed_name, tagfiledir);
1437 fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head));
1445 if (compressed_name) free(compressed_name);
1446 if (uncompressed_name) free(uncompressed_name);
1451 * This routine sets up the boolean pseudo-functions which work
1452 * by setting boolean flags dependent upon the corresponding character.
1453 * Every char which is NOT in that string is not a white char. Therefore,
1454 * all of the array "_wht" is set to FALSE, and then the elements
1455 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1456 * of a char is TRUE if it is the string "white", else FALSE.
1464 for (i = 0; i < CHARS; i++)
1465 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE;
1466 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
1467 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
1468 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
1469 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
1470 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
1471 iswhite('\0') = iswhite('\n');
1472 notinname('\0') = notinname('\n');
1473 begtoken('\0') = begtoken('\n');
1474 intoken('\0') = intoken('\n');
1475 endtoken('\0') = endtoken('\n');
1479 * This routine opens the specified file and calls the function
1480 * which finds the function and type definitions.
1482 node *last_node = NULL;
1485 find_entries (file, inf)
1491 node *old_last_node;
1493 /* Memory leakage here: the string pointed by curfile is
1494 never released, because curfile is copied into np->file
1495 for each node, to be used in CTAGS mode. The amount of
1496 memory leaked here is the sum of the lengths of the
1498 curfile = savestr (file);
1500 /* If user specified a language, use it. */
1502 if (lang != NULL && lang->function != NULL)
1505 lang->function (inf);
1509 /* Try to guess the language given the file name. */
1510 lang = get_language_from_suffix (file);
1511 if (lang != NULL && lang->function != NULL)
1514 lang->function (inf);
1518 /* Look for sharp-bang as the first two characters. */
1519 if (readline_internal (&lb, inf) > 0
1521 && lb.buffer[0] == '#'
1522 && lb.buffer[1] == '!')
1526 /* Set lp to point at the first char after the last slash in the
1527 line or, if no slashes, at the first nonblank. Then set cp to
1528 the first successive blank and terminate the string. */
1529 lp = etags_strrchr (lb.buffer+2, '/');
1533 lp = skip_spaces (lb.buffer + 2);
1534 cp = skip_non_spaces (lp);
1537 if (strlen (lp) > 0)
1539 lang = get_language_from_interpreter (lp);
1540 if (lang != NULL && lang->function != NULL)
1543 lang->function (inf);
1548 /* We rewind here, even if inf may be a pipe. We fail if the
1549 length of the first line is longer than the pipe block size,
1550 which is unlikely. */
1554 old_last_node = last_node;
1555 curlang = get_language_from_name ("fortran");
1556 Fortran_functions (inf);
1558 /* No Fortran entries found. Try C. */
1559 if (old_last_node == last_node)
1561 /* We do not tag if rewind fails.
1562 Only the file name will be recorded in the tags file. */
1564 curlang = get_language_from_name (cplusplus ? "c++" : "c");
1565 default_C_entries (inf);
1572 pfnote (name, is_func, linestart, linelen, lno, cno)
1573 char *name; /* tag name, or NULL if unnamed */
1574 bool is_func; /* tag is a function */
1575 char *linestart; /* start of the line where tag is */
1576 int linelen; /* length of the line where tag is */
1577 int lno; /* line number */
1578 long cno; /* character number */
1582 if (CTAGS && name == NULL)
1585 np = xnew (1, node);
1587 /* If ctags mode, change name "main" to M<thisfilename>. */
1588 if (CTAGS && !cxref_style && streq (name, "main"))
1590 register char *fp = etags_strrchr (curfile, '/');
1591 np->name = concat ("M", fp == NULL ? curfile : fp + 1, "");
1592 fp = etags_strrchr (np->name, '.');
1593 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1598 np->been_warned = FALSE;
1600 np->is_func = is_func;
1602 /* Our char numbers are 0-base, because of C language tradition?
1603 ctags compatibility? old versions compatibility? I don't know.
1604 Anyway, since emacs's are 1-base we expect etags.el to take care
1605 of the difference. If we wanted to have 1-based numbers, we would
1606 uncomment the +1 below. */
1607 np->cno = cno /* + 1 */ ;
1608 np->left = np->right = NULL;
1609 if (CTAGS && !cxref_style)
1611 if (strlen (linestart) < 50)
1612 np->pat = concat (linestart, "$", "");
1614 np->pat = savenstr (linestart, 50);
1617 np->pat = savenstr (linestart, linelen);
1619 add_node (np, &head);
1622 /* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997]
1623 * From: Sam Kendall <kendall@mv.mv.com>
1624 * Subject: Proposal for firming up the TAGS format specification
1625 * To: F.Potorti@cnuce.cnr.it
1627 * pfnote should emit the optimized form [unnamed tag] only if:
1628 * 1. name does not contain any of the characters " \t\r\n(),;";
1629 * 2. linestart contains name as either a rightmost, or rightmost but
1630 * one character, substring;
1631 * 3. the character, if any, immediately before name in linestart must
1632 * be one of the characters " \t(),;";
1633 * 4. the character, if any, immediately after name in linestart must
1634 * also be one of the characters " \t(),;".
1636 * The real implementation uses the notinname() macro, which recognises
1637 * characters slightly different form " \t\r\n(),;". See the variable
1640 #define traditional_tag_style TRUE
1642 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno)
1643 char *name; /* tag name, or NULL if unnamed */
1644 int namelen; /* tag length */
1645 bool is_func; /* tag is a function */
1646 char *linestart; /* start of the line where tag is */
1647 int linelen; /* length of the line where tag is */
1648 int lno; /* line number */
1649 long cno; /* character number */
1657 for (cp = name; !notinname (*cp); cp++)
1659 if (*cp == '\0') /* rule #1 */
1661 cp = linestart + linelen - namelen;
1662 if (notinname (linestart[linelen-1]))
1663 cp -= 1; /* rule #4 */
1664 if (cp >= linestart /* rule #2 */
1666 || notinname (cp[-1])) /* rule #3 */
1667 && strneq (name, cp, namelen)) /* rule #2 */
1668 named = FALSE; /* use unnamed tag */
1673 name = savenstr (name, namelen);
1676 pfnote (name, is_func, linestart, linelen, lno, cno);
1681 * recurse on left children, iterate on right children.
1689 register node *node_right = np->right;
1690 free_tree (np->left);
1691 if (np->name != NULL)
1701 * Adds a node to the tree of nodes. In etags mode, we don't keep
1702 * it sorted; we just keep a linear list. In ctags mode, maintain
1703 * an ordered tree, with no attempt at balancing.
1705 * add_node is the only function allowed to add nodes, so it can
1709 add_node (np, cur_node_p)
1710 node *np, **cur_node_p;
1713 register node *cur_node = *cur_node_p;
1715 if (cur_node == NULL)
1725 if (last_node == NULL)
1726 fatal ("internal error in add_node", (char *)NULL);
1727 last_node->right = np;
1733 dif = strcmp (np->name, cur_node->name);
1736 * If this tag name matches an existing one, then
1737 * do not add the node, but maybe print a warning.
1741 if (streq (np->file, cur_node->file))
1745 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
1746 np->file, lineno, np->name);
1747 fprintf (stderr, "Second entry ignored\n");
1750 else if (!cur_node->been_warned && !no_warnings)
1754 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1755 np->file, cur_node->file, np->name);
1756 cur_node->been_warned = TRUE;
1761 /* Actually add the node */
1762 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1775 /* Output subentries that precede this one */
1776 put_entries (np->left);
1778 /* Output this entry */
1782 if (np->name != NULL)
1783 fprintf (tagf, "%s\177%s\001%d,%ld\n",
1784 np->pat, np->name, np->lno, np->cno);
1786 fprintf (tagf, "%s\177%d,%ld\n",
1787 np->pat, np->lno, np->cno);
1791 if (np->name == NULL)
1792 error ("internal error: NULL name in ctags mode.", (char *)NULL);
1797 fprintf (stdout, "%s %s %d\n",
1798 np->name, np->file, (np->lno + 63) / 64);
1800 fprintf (stdout, "%-16s %3d %-16s %s\n",
1801 np->name, np->lno, np->file, np->pat);
1805 fprintf (tagf, "%s\t%s\t", np->name, np->file);
1809 putc (searchar, tagf);
1812 for (sp = np->pat; *sp; sp++)
1814 if (*sp == '\\' || *sp == searchar)
1818 putc (searchar, tagf);
1821 { /* a typedef; text pattern inadequate */
1822 fprintf (tagf, "%d", np->lno);
1828 /* Output subentries that follow this one */
1829 put_entries (np->right);
1832 /* Length of a number's decimal representation. */
1838 while ((num /= 10) > 0)
1844 * Return total number of characters that put_entries will output for
1845 * the nodes in the subtree of the specified node. Works only if
1846 * we are not ctags, but called only in that case. This count
1847 * is irrelevant with the new tags.el, but is still supplied for
1848 * backward compatibility.
1851 total_size_of_entries (np)
1859 for (total = 0; np != NULL; np = np->right)
1861 /* Count left subentries. */
1862 total += total_size_of_entries (np->left);
1864 /* Count this entry */
1865 total += strlen (np->pat) + 1;
1866 total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1;
1867 if (np->name != NULL)
1868 total += 1 + strlen (np->name); /* \001name */
1875 * The C symbol tables.
1880 st_C_objprot, st_C_objimpl, st_C_objend,
1885 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1888 /* Feed stuff between (but not including) %[ and %] lines to:
1889 gperf -c -k 1,3 -o -p -r -t
1891 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1895 while, 0, st_C_ignore
1896 switch, 0, st_C_ignore
1897 return, 0, st_C_ignore
1898 @interface, 0, st_C_objprot
1899 @protocol, 0, st_C_objprot
1900 @implementation,0, st_C_objimpl
1901 @end, 0, st_C_objend
1902 import, C_JAVA, st_C_ignore
1903 package, C_JAVA, st_C_ignore
1904 friend, C_PLPL, st_C_ignore
1905 extends, C_JAVA, st_C_javastruct
1906 implements, C_JAVA, st_C_javastruct
1907 interface, C_JAVA, st_C_struct
1908 class, C_PLPL, st_C_struct
1909 namespace, C_PLPL, st_C_struct
1910 domain, C_STAR, st_C_struct
1911 union, 0, st_C_struct
1912 struct, 0, st_C_struct
1913 extern, 0, st_C_extern
1915 typedef, 0, st_C_typedef
1916 define, 0, st_C_define
1917 operator, C_PLPL, st_C_operator
1918 bool, C_PLPL, st_C_typespec
1919 long, 0, st_C_typespec
1920 short, 0, st_C_typespec
1921 int, 0, st_C_typespec
1922 char, 0, st_C_typespec
1923 float, 0, st_C_typespec
1924 double, 0, st_C_typespec
1925 signed, 0, st_C_typespec
1926 unsigned, 0, st_C_typespec
1927 auto, 0, st_C_typespec
1928 void, 0, st_C_typespec
1929 static, 0, st_C_typespec
1930 const, 0, st_C_typespec
1931 volatile, 0, st_C_typespec
1932 explicit, C_PLPL, st_C_typespec
1933 mutable, C_PLPL, st_C_typespec
1934 typename, C_PLPL, st_C_typespec
1935 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1936 DEFUN, 0, st_C_gnumacro
1937 SYSCALL, 0, st_C_gnumacro
1938 ENTRY, 0, st_C_gnumacro
1939 PSEUDO, 0, st_C_gnumacro
1940 # These are defined inside C functions, so currently they are not met.
1941 # EXFUN used in glibc, DEFVAR_* in emacs.
1942 #EXFUN, 0, st_C_gnumacro
1943 #DEFVAR_, 0, st_C_gnumacro
1945 and replace lines between %< and %> with its output. */
1947 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
1948 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1949 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1951 #define TOTAL_KEYWORDS 46
1952 #define MIN_WORD_LENGTH 2
1953 #define MAX_WORD_LENGTH 15
1954 #define MIN_HASH_VALUE 13
1955 #define MAX_HASH_VALUE 123
1956 /* maximum key range = 111, duplicates = 0 */
1963 register const char *str;
1964 register unsigned int len;
1966 static unsigned char asso_values[] =
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, 3, 124, 124, 124, 43, 6,
1975 11, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1976 11, 124, 124, 58, 7, 124, 124, 124, 124, 124,
1977 124, 124, 124, 124, 124, 124, 124, 57, 7, 42,
1978 4, 14, 52, 0, 124, 53, 124, 124, 29, 11,
1979 6, 35, 32, 124, 29, 34, 59, 58, 51, 24,
1980 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1981 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1982 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1983 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1984 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1985 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1986 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1987 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1988 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1989 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1990 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1991 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1992 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1993 124, 124, 124, 124, 124, 124
1995 register int hval = len;
2001 hval += asso_values[(unsigned char)str[2]];
2004 hval += asso_values[(unsigned char)str[0]];
2013 static struct C_stab_entry *
2014 in_word_set (str, len)
2015 register const char *str;
2016 register unsigned int len;
2018 static struct C_stab_entry wordlist[] =
2020 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2021 {""}, {""}, {""}, {""},
2022 {"@end", 0, st_C_objend},
2023 {""}, {""}, {""}, {""},
2024 {"ENTRY", 0, st_C_gnumacro},
2025 {"@interface", 0, st_C_objprot},
2027 {"domain", C_STAR, st_C_struct},
2029 {"PSEUDO", 0, st_C_gnumacro},
2031 {"namespace", C_PLPL, st_C_struct},
2033 {"@implementation",0, st_C_objimpl},
2034 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2035 {"long", 0, st_C_typespec},
2036 {"signed", 0, st_C_typespec},
2037 {"@protocol", 0, st_C_objprot},
2038 {""}, {""}, {""}, {""},
2039 {"bool", C_PLPL, st_C_typespec},
2040 {""}, {""}, {""}, {""}, {""}, {""},
2041 {"const", 0, st_C_typespec},
2042 {"explicit", C_PLPL, st_C_typespec},
2043 {"if", 0, st_C_ignore},
2045 {"operator", C_PLPL, st_C_operator},
2047 {"DEFUN", 0, st_C_gnumacro},
2049 {"define", 0, st_C_define},
2050 {""}, {""}, {""}, {""}, {""},
2051 {"double", 0, st_C_typespec},
2052 {"struct", 0, st_C_struct},
2053 {""}, {""}, {""}, {""},
2054 {"short", 0, st_C_typespec},
2056 {"enum", 0, st_C_enum},
2057 {"mutable", C_PLPL, st_C_typespec},
2059 {"extern", 0, st_C_extern},
2060 {"extends", C_JAVA, st_C_javastruct},
2061 {"package", C_JAVA, st_C_ignore},
2062 {"while", 0, st_C_ignore},
2064 {"for", 0, st_C_ignore},
2066 {"volatile", 0, st_C_typespec},
2068 {"import", C_JAVA, st_C_ignore},
2069 {"float", 0, st_C_typespec},
2070 {"switch", 0, st_C_ignore},
2071 {"return", 0, st_C_ignore},
2072 {"implements", C_JAVA, st_C_javastruct},
2074 {"static", 0, st_C_typespec},
2075 {"typedef", 0, st_C_typedef},
2076 {"typename", C_PLPL, st_C_typespec},
2077 {"unsigned", 0, st_C_typespec},
2079 {"char", 0, st_C_typespec},
2080 {"class", C_PLPL, st_C_struct},
2082 {"void", 0, st_C_typespec},
2084 {"friend", C_PLPL, st_C_ignore},
2086 {"int", 0, st_C_typespec},
2087 {"union", 0, st_C_struct},
2089 {"auto", 0, st_C_typespec},
2090 {"interface", C_JAVA, st_C_struct},
2092 {"SYSCALL", 0, st_C_gnumacro}
2095 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
2097 register int key = hash (str, len);
2099 if (key <= MAX_HASH_VALUE && key >= 0)
2101 register const char *s = wordlist[key].name;
2103 if (*str == *s && !strncmp (str + 1, s + 1, len - 1))
2104 return &wordlist[key];
2111 static enum sym_type
2112 C_symtype (str, len, c_ext)
2117 register struct C_stab_entry *se = in_word_set (str, len);
2119 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
2125 * C functions and variables are recognized using a simple
2126 * finite automaton. fvdef is its state variable.
2130 fvnone, /* nothing seen */
2131 foperator, /* func: operator keyword seen (cplpl) */
2132 fvnameseen, /* function or variable name seen */
2133 fstartlist, /* func: just after open parenthesis */
2134 finlist, /* func: in parameter list */
2135 flistseen, /* func: after parameter list */
2136 fignore, /* func: before open brace */
2137 vignore /* var-like: ignore until ';' */
2140 bool fvextern; /* func or var: extern keyword seen; */
2143 * typedefs are recognized using a simple finite automaton.
2144 * typdef is its state variable.
2148 tnone, /* nothing seen */
2149 tkeyseen, /* typedef keyword seen */
2150 ttypeseen, /* defined type seen */
2151 tinbody, /* inside typedef body */
2152 tend, /* just before typedef tag */
2153 tignore /* junk after typedef tag */
2158 * struct-like structures (enum, struct and union) are recognized
2159 * using another simple finite automaton. `structdef' is its state
2164 snone, /* nothing seen yet */
2165 skeyseen, /* struct-like keyword seen */
2166 stagseen, /* struct-like tag seen */
2167 scolonseen, /* colon seen after struct-like tag */
2168 sinbody /* in struct body: recognize member func defs*/
2172 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
2173 * struct tag, and structtype is the type of the preceding struct-like
2176 char *structtag = "<uninited>";
2177 enum sym_type structtype;
2180 * When objdef is different from onone, objtag is the name of the class.
2182 char *objtag = "<uninited>";
2185 * Yet another little state machine to deal with preprocessor lines.
2189 dnone, /* nothing seen */
2190 dsharpseen, /* '#' seen as first char on line */
2191 ddefineseen, /* '#' and 'define' seen */
2192 dignorerest /* ignore rest of line */
2196 * State machine for Objective C protocols and implementations.
2197 * Tom R.Hageman <tom@basil.icce.rug.nl>
2201 onone, /* nothing seen */
2202 oprotocol, /* @interface or @protocol seen */
2203 oimplementation, /* @implementations seen */
2204 otagseen, /* class name seen */
2205 oparenseen, /* parenthesis before category seen */
2206 ocatseen, /* category name seen */
2207 oinbody, /* in @implementation body */
2208 omethodsign, /* in @implementation body, after +/- */
2209 omethodtag, /* after method name */
2210 omethodcolon, /* after method colon */
2211 omethodparm, /* after method parameter */
2212 oignore /* wait for @end */
2217 * Use this structure to keep info about the token read, and how it
2218 * should be tagged. Used by the make_C_tag function to build a tag.
2231 token tok; /* latest token read */
2234 * Set this to TRUE, and the next token considered is called a function.
2235 * Used only for GNU emacs's function-defining macros.
2237 bool next_token_is_func;
2240 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
2245 * methodlen is the length of the method name stored in token_name.
2251 * checks to see if the current token is at the start of a
2252 * function or variable, or corresponds to a typedef, or
2253 * is a struct/union/enum tag, or #define, or an enum constant.
2255 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2256 * with args. C_EXT is which language we are looking at.
2264 * next_token_is_func IN OUT
2268 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2269 register char *str; /* IN: token pointer */
2270 register int len; /* IN: token length */
2271 register char c; /* IN: first char after the token */
2272 int c_ext; /* IN: C extensions mask */
2273 int cblev; /* IN: curly brace level */
2274 int parlev; /* IN: parenthesis level */
2275 bool *is_func_or_var; /* OUT: function or variable found */
2277 enum sym_type toktype = C_symtype (str, len, c_ext);
2280 * Advance the definedef state machine.
2285 /* We're not on a preprocessor line. */
2288 if (toktype == st_C_define)
2290 definedef = ddefineseen;
2294 definedef = dignorerest;
2299 * Make a tag for any macro, unless it is a constant
2300 * and constantypedefs is FALSE.
2302 definedef = dignorerest;
2303 *is_func_or_var = (c == '(');
2304 if (!*is_func_or_var && !constantypedefs)
2311 error ("internal error: definedef value.", (char *)NULL);
2320 if (toktype == st_C_typedef)
2339 /* Do not return here, so the structdef stuff has a chance. */
2353 * This structdef business is currently only invoked when cblev==0.
2354 * It should be recursively invoked whatever the curly brace level,
2355 * and a stack of states kept, to allow for definitions of structs
2358 * This structdef business is NOT invoked when we are ctags and the
2359 * file is plain C. This is because a struct tag may have the same
2360 * name as another tag, and this loses with ctags.
2364 case st_C_javastruct:
2365 if (structdef == stagseen)
2366 structdef = scolonseen;
2370 if (typdef == tkeyseen
2371 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone))
2373 structdef = skeyseen;
2374 structtype = toktype;
2379 if (structdef == skeyseen)
2381 /* Save the tag for struct/union/class, for functions and variables
2382 that may be defined inside. */
2383 if (structtype == st_C_struct)
2384 structtag = savenstr (str, len);
2386 structtag = "<enum>";
2387 structdef = stagseen;
2391 if (typdef != tnone)
2394 /* Detect GNU macros.
2396 Writers of emacs code are recommended to put the
2397 first two args of a DEFUN on the same line.
2399 The DEFUN macro, used in emacs C source code, has a first arg
2400 that is a string (the lisp function name), and a second arg that
2401 is a C function name. Since etags skips strings, the second arg
2402 is tagged. This is unfortunate, as it would be better to tag the
2403 first arg. The simplest way to deal with this problem would be
2404 to name the tag with a name built from the function name, by
2405 removing the initial 'F' character and substituting '-' for '_'.
2406 Anyway, this assumes that the conventions of naming lisp
2407 functions will never change. Currently, this method is not
2409 if (definedef == dnone && toktype == st_C_gnumacro)
2411 next_token_is_func = TRUE;
2414 if (next_token_is_func)
2416 next_token_is_func = FALSE;
2418 *is_func_or_var = TRUE;
2422 /* Detect Objective C constructs. */
2432 objdef = oimplementation;
2436 case oimplementation:
2437 /* Save the class tag for functions or variables defined inside. */
2438 objtag = savenstr (str, len);
2442 /* Save the class tag for categories. */
2443 objtag = savenstr (str, len);
2445 *is_func_or_var = TRUE;
2449 *is_func_or_var = TRUE;
2456 objdef = omethodtag;
2458 grow_linebuffer (&token_name, methodlen + 1);
2459 strncpy (token_name.buffer, str, len);
2460 token_name.buffer[methodlen] = '\0';
2461 token_name.len = methodlen;
2467 objdef = omethodparm;
2472 objdef = omethodtag;
2474 grow_linebuffer (&token_name, methodlen + 1);
2475 strncat (token_name.buffer, str, len);
2476 token_name.len = methodlen;
2481 if (toktype == st_C_objend)
2483 /* Memory leakage here: the string pointed by objtag is
2484 never released, because many tests would be needed to
2485 avoid breaking on incorrect input code. The amount of
2486 memory leaked here is the sum of the lengths of the
2494 /* A function, variable or enum constant? */
2501 if (fvdef != finlist && fvdef != fignore && fvdef != vignore)
2502 fvdef = fvnone; /* should be useless */
2510 *is_func_or_var = TRUE;
2513 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10))
2516 *is_func_or_var = TRUE;
2519 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2521 if (fvdef == fvnone)
2523 fvdef = fvnameseen; /* function or variable */
2524 *is_func_or_var = TRUE;
2535 * This routine finds functions, variables, typedefs,
2536 * #define's, enum constants and struct/union/enum definitions in
2537 * C syntax and adds them to the list.
2539 #define current_lb_is_new (newndx == curndx)
2540 #define switch_line_buffers() (curndx = 1 - curndx)
2542 #define curlb (lbs[curndx].lb)
2543 #define othlb (lbs[1-curndx].lb)
2544 #define newlb (lbs[newndx].lb)
2545 #define curlinepos (lbs[curndx].linepos)
2546 #define othlinepos (lbs[1-curndx].linepos)
2547 #define newlinepos (lbs[newndx].linepos)
2549 #define CNL_SAVE_DEFINEDEF() \
2551 curlinepos = charno; \
2553 linecharno = charno; \
2554 charno += readline (&curlb, inf); \
2555 lp = curlb.buffer; \
2562 CNL_SAVE_DEFINEDEF(); \
2563 if (savetok.valid) \
2566 savetok.valid = FALSE; \
2568 definedef = dnone; \
2576 /* This function should never be called when tok.valid is FALSE, but
2577 we must protect against invalid input or internal errors. */
2580 if (traditional_tag_style)
2582 /* This was the original code. Now we call new_pfnote instead,
2583 which uses the new method for naming tags (see new_pfnote). */
2586 if (CTAGS || tok.named)
2587 name = savestr (token_name.buffer);
2588 pfnote (name, isfun,
2589 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2592 new_pfnote (token_name.buffer, token_name.len, isfun,
2593 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2602 C_entries (c_ext, inf)
2603 int c_ext; /* extension of C */
2604 FILE *inf; /* input file */
2606 register char c; /* latest char read; '\0' for end of line */
2607 register char *lp; /* pointer one beyond the character `c' */
2608 int curndx, newndx; /* indices for current and new lb */
2609 register int tokoff; /* offset in line of start of current token */
2610 register int toklen; /* length of current token */
2611 char *qualifier; /* string used to qualify names */
2612 int qlen; /* length of qualifier */
2613 int cblev; /* current curly brace level */
2614 int parlev; /* current parenthesis level */
2615 bool incomm, inquote, inchar, quotednl, midtoken;
2616 bool purec, cplpl, cjava;
2617 token savetok; /* token saved during preprocessor handling */
2620 tokoff = toklen = 0; /* keep compiler quiet */
2621 curndx = newndx = 0;
2627 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
2628 structdef = snone; definedef = dnone; objdef = onone;
2629 next_token_is_func = yacc_rules = FALSE;
2630 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2631 tok.valid = savetok.valid = FALSE;
2634 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */
2635 cplpl = (c_ext & C_PLPL) == C_PLPL;
2636 cjava = (c_ext & C_JAVA) == C_JAVA;
2638 { qualifier = "."; qlen = 1; }
2640 { qualifier = "::"; qlen = 2; }
2647 /* If we're at the end of the line, the next character is a
2648 '\0'; don't skip it, because it's the thing that tells us
2649 to read the next line. */
2670 /* Newlines inside comments do not end macro definitions in
2672 CNL_SAVE_DEFINEDEF ();
2685 /* Newlines inside strings do not end macro definitions
2686 in traditional cpp, even though compilers don't
2687 usually accept them. */
2688 CNL_SAVE_DEFINEDEF ();
2698 /* Hmmm, something went wrong. */
2712 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2720 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2733 else if (/* cplpl && */ *lp == '/')
2741 if ((c_ext & YACC) && *lp == '%')
2743 /* entering or exiting rules section in yacc file */
2745 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2746 typdef = tnone; structdef = snone;
2747 next_token_is_func = FALSE;
2748 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2750 yacc_rules = !yacc_rules;
2756 if (definedef == dnone)
2759 bool cpptoken = TRUE;
2761 /* Look back on this line. If all blanks, or nonblanks
2762 followed by an end of comment, this is a preprocessor
2764 for (cp = newlb.buffer; cp < lp-1; cp++)
2767 if (*cp == '*' && *(cp+1) == '/')
2776 definedef = dsharpseen;
2777 } /* if (definedef == dnone) */
2783 /* Consider token only if some complicated conditions are satisfied. */
2784 if ((definedef != dnone
2785 || (cblev == 0 && structdef != scolonseen)
2786 || (cblev == 1 && cplpl && structdef == sinbody)
2787 || (structdef == sinbody && purec))
2788 && typdef != tignore
2789 && definedef != dignorerest
2790 && fvdef != finlist)
2796 bool funorvar = FALSE;
2798 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1]))
2801 * This handles :: in the middle, but not at the
2802 * beginning of an identifier. Also, space-separated
2803 * :: is not recognised.
2813 || consider_token (newlb.buffer + tokoff, toklen, c,
2814 c_ext, cblev, parlev, &funorvar))
2816 if (fvdef == foperator)
2819 lp = skip_spaces (lp-1);
2823 && !isspace (*lp) && *lp != '(')
2826 toklen += lp - oldlp;
2831 && definedef == dnone
2832 && structdef == sinbody)
2833 /* function or var defined in C++ class body */
2835 int len = strlen (structtag) + qlen + toklen;
2836 grow_linebuffer (&token_name, len + 1);
2837 strcpy (token_name.buffer, structtag);
2838 strcat (token_name.buffer, qualifier);
2839 strncat (token_name.buffer,
2840 newlb.buffer + tokoff, toklen);
2841 token_name.len = len;
2844 else if (objdef == ocatseen)
2845 /* Objective C category */
2847 int len = strlen (objtag) + 2 + toklen;
2848 grow_linebuffer (&token_name, len + 1);
2849 strcpy (token_name.buffer, objtag);
2850 strcat (token_name.buffer, "(");
2851 strncat (token_name.buffer,
2852 newlb.buffer + tokoff, toklen);
2853 strcat (token_name.buffer, ")");
2854 token_name.len = len;
2857 else if (objdef == omethodtag
2858 || objdef == omethodparm)
2859 /* Objective C method */
2865 grow_linebuffer (&token_name, toklen + 1);
2866 strncpy (token_name.buffer,
2867 newlb.buffer + tokoff, toklen);
2868 token_name.buffer[toklen] = '\0';
2869 token_name.len = toklen;
2870 /* Name macros and members. */
2871 tok.named = (structdef == stagseen
2872 || typdef == ttypeseen
2875 && definedef == dignorerest)
2877 && definedef == dnone
2878 && structdef == sinbody));
2880 tok.lineno = lineno;
2881 tok.linelen = tokoff + toklen + 1;
2882 tok.buffer = newlb.buffer;
2883 tok.linepos = newlinepos;
2886 if (definedef == dnone
2887 && (fvdef == fvnameseen
2888 || fvdef == foperator
2889 || structdef == stagseen
2891 || objdef != onone))
2893 if (current_lb_is_new)
2894 switch_line_buffers ();
2897 make_C_tag (funorvar);
2901 } /* if (endtoken (c)) */
2902 else if (intoken (c))
2908 } /* if (midtoken) */
2909 else if (begtoken (c))
2920 make_C_tag (TRUE); /* a function */
2927 if (structdef == stagseen && !cjava)
2933 if (!yacc_rules || lp == newlb.buffer + 1)
2935 tokoff = lp - 1 - newlb.buffer;
2940 } /* if (begtoken) */
2941 } /* if must look at token */
2944 /* Detect end of line, colon, comma, semicolon and various braces
2945 after having handled a token.*/
2949 if (definedef != dnone)
2955 make_C_tag (TRUE); /* an Objective C class */
2959 objdef = omethodcolon;
2961 grow_linebuffer (&token_name, methodlen + 1);
2962 strcat (token_name.buffer, ":");
2963 token_name.len = methodlen;
2966 if (structdef == stagseen)
2967 structdef = scolonseen;
2974 make_C_tag (FALSE); /* a yacc function */
2985 if (definedef != dnone)
2991 make_C_tag (FALSE); /* a typedef */
3001 if ((members && cblev == 1)
3002 || (globals && cblev == 0 && (!fvextern || declarations)))
3003 make_C_tag (FALSE); /* a variable */
3009 if (declarations && (cblev == 0 || cblev == 1))
3010 make_C_tag (TRUE); /* a function declaration */
3015 /* The following instruction invalidates the token.
3016 Probably the token should be invalidated in all
3017 other cases where some state machine is reset. */
3020 if (structdef == stagseen)
3024 if (definedef != dnone)
3030 make_C_tag (TRUE); /* an Objective C method */
3042 if ((members && cblev == 1)
3043 || (globals && cblev == 0 && (!fvextern || declarations)))
3044 make_C_tag (FALSE); /* a variable */
3049 if (structdef == stagseen)
3053 if (definedef != dnone)
3055 if (cblev == 0 && typdef == tend)
3058 make_C_tag (FALSE); /* a typedef */
3069 if ((members && cblev == 1)
3070 || (globals && cblev == 0 && (!fvextern || declarations)))
3071 make_C_tag (FALSE); /* a variable */
3076 if (structdef == stagseen)
3080 if (definedef != dnone)
3082 if (objdef == otagseen && parlev == 0)
3083 objdef = oparenseen;
3087 if (typdef == ttypeseen
3090 && structdef != sinbody)
3092 /* This handles constructs like:
3093 typedef void OperatorFun (int fun); */
3108 if (definedef != dnone)
3110 if (objdef == ocatseen && parlev == 1)
3112 make_C_tag (TRUE); /* an Objective C category */
3124 if (cblev == 0 && (typdef == tend))
3127 make_C_tag (FALSE); /* a typedef */
3130 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
3134 if (definedef != dnone)
3136 if (typdef == ttypeseen)
3140 case skeyseen: /* unnamed struct */
3141 structdef = sinbody;
3142 structtag = "_anonymous_";
3145 case scolonseen: /* named struct */
3146 structdef = sinbody;
3147 make_C_tag (FALSE); /* a struct */
3153 make_C_tag (TRUE); /* a function */
3162 make_C_tag (TRUE); /* an Objective C class */
3167 make_C_tag (TRUE); /* an Objective C method */
3171 /* Neutralize `extern "C" {' grot. */
3172 if (cblev == 0 && structdef == snone && typdef == tnone)
3179 if (definedef != dnone)
3181 if (fvdef == fstartlist)
3182 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
3185 if (definedef != dnone)
3187 if (!noindentypedefs && lp == newlb.buffer + 1)
3189 cblev = 0; /* reset curly brace level if first column */
3190 parlev = 0; /* also reset paren level, just in case... */
3196 if (typdef == tinbody)
3198 /* Memory leakage here: the string pointed by structtag is
3199 never released, because I fear to miss something and
3200 break things while freeing the area. The amount of
3201 memory leaked here is the sum of the lengths of the
3203 if (structdef == sinbody)
3204 free (structtag); */
3207 structtag = "<error>";
3211 if (definedef != dnone)
3221 if ((members && cblev == 1)
3222 || (globals && cblev == 0 && (!fvextern || declarations)))
3223 make_C_tag (FALSE); /* a variable */
3231 if (objdef == oinbody && cblev == 0)
3233 objdef = omethodsign;
3237 case '#': case '~': case '&': case '%': case '/': case '|':
3238 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
3239 if (definedef != dnone)
3241 /* These surely cannot follow a function tag in C. */
3254 if (objdef == otagseen)
3256 make_C_tag (TRUE); /* an Objective C class */
3259 /* If a macro spans multiple lines don't reset its state. */
3261 CNL_SAVE_DEFINEDEF ();
3267 } /* while not eof */
3271 * Process either a C++ file or a C file depending on the setting
3275 default_C_entries (inf)
3278 C_entries (cplusplus ? C_PLPL : 0, inf);
3281 /* Always do plain ANSI C. */
3283 plain_C_entries (inf)
3289 /* Always do C++. */
3291 Cplusplus_entries (inf)
3294 C_entries (C_PLPL, inf);
3297 /* Always do Java. */
3302 C_entries (C_JAVA, inf);
3310 C_entries (C_STAR, inf);
3313 /* Always do Yacc. */
3318 C_entries (YACC, inf);
3321 /* A useful macro. */
3322 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3323 for (lineno = charno = 0; /* loop initialization */ \
3324 !feof (file_pointer) /* loop test */ \
3325 && (lineno++, /* instructions at start of loop */ \
3326 linecharno = charno, \
3327 charno += readline (&line_buffer, file_pointer), \
3328 char_pointer = lb.buffer, \
3334 * Read a file, but do no processing. This is used to do regexp
3335 * matching on files that have no language defined.
3338 just_read_file (inf)
3341 register char *dummy;
3343 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3347 /* Fortran parsing */
3353 register int len = 0;
3355 while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len]))
3357 if (*cp == '\0' && !intoken (dbp[len]))
3368 dbp = skip_spaces (dbp);
3372 dbp = skip_spaces (dbp);
3373 if (strneq (dbp, "(*)", 3))
3378 if (!isdigit (*dbp))
3380 --dbp; /* force failure */
3385 while (isdigit (*dbp));
3394 dbp = skip_spaces (dbp);
3398 linecharno = charno;
3399 charno += readline (&lb, inf);
3404 dbp = skip_spaces (dbp);
3406 if (!isalpha (*dbp) && *dbp != '_' && *dbp != '$')
3408 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
3410 pfnote (savenstr (dbp, cp-dbp), TRUE,
3411 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3416 Fortran_functions (inf)
3419 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3422 dbp++; /* Ratfor escape to fortran */
3423 dbp = skip_spaces (dbp);
3426 switch (lowcase (*dbp))
3429 if (tail ("integer"))
3437 if (tail ("logical"))
3441 if (tail ("complex") || tail ("character"))
3445 if (tail ("double"))
3447 dbp = skip_spaces (dbp);
3450 if (tail ("precision"))
3456 dbp = skip_spaces (dbp);
3459 switch (lowcase (*dbp))
3462 if (tail ("function"))
3466 if (tail ("subroutine"))
3474 if (tail ("blockdata") || tail ("block data"))
3476 dbp = skip_spaces (dbp);
3477 if (*dbp == '\0') /* assume un-named */
3478 pfnote (savestr ("blockdata"), TRUE,
3479 lb.buffer, dbp - lb.buffer, lineno, linecharno);
3481 getit (inf); /* look for name */
3489 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24
3492 /* Once we are positioned after an "interesting" keyword, let's get
3493 the real tag value necessary. */
3495 adagetit (inf, name_qualifier)
3497 char *name_qualifier;
3505 dbp = skip_spaces (dbp);
3507 || (dbp[0] == '-' && dbp[1] == '-'))
3510 linecharno = charno;
3511 charno += readline (&lb, inf);
3520 /* Skipping body of procedure body or package body or ....
3521 resetting qualifier to body instead of spec. */
3522 name_qualifier = "/b";
3528 /* Skipping type of task type or protected type ... */
3536 for (cp = dbp; *cp != '\0' && *cp != '"'; cp++)
3541 dbp = skip_spaces (dbp);
3544 && (isalpha (*cp) || isdigit (*cp) || *cp == '_' || *cp == '.'));
3552 name = concat (dbp, name_qualifier, "");
3554 pfnote (name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3565 bool inquote = FALSE;
3567 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3569 while (*dbp != '\0')
3571 /* Skip a string i.e. "abcd". */
3572 if (inquote || (*dbp == '"'))
3574 dbp = etags_strchr ((inquote) ? dbp : dbp+1, '"');
3579 continue; /* advance char */
3584 break; /* advance line */
3588 /* Skip comments. */
3589 if (dbp[0] == '-' && dbp[1] == '-')
3590 break; /* advance line */
3592 /* Skip character enclosed in single quote i.e. 'a'
3593 and skip single quote starting an attribute i.e. 'Image. */
3602 /* Search for beginning of a token. */
3603 if (!begtoken (*dbp))
3606 continue; /* advance char */
3609 /* We are at the beginning of a token. */
3614 if (!packages_only && tail ("function"))
3615 adagetit (inf, "/f");
3617 break; /* from switch */
3618 continue; /* advance char */
3621 if (!packages_only && tail ("procedure"))
3622 adagetit (inf, "/p");
3623 else if (tail ("package"))
3624 adagetit (inf, "/s");
3625 else if (tail ("protected")) /* protected type */
3626 adagetit (inf, "/t");
3628 break; /* from switch */
3629 continue; /* advance char */
3632 if (!packages_only && tail ("task"))
3633 adagetit (inf, "/k");
3634 else if (typedefs && !packages_only && tail ("type"))
3636 adagetit (inf, "/t");
3637 while (*dbp != '\0')
3641 break; /* from switch */
3642 continue; /* advance char */
3645 /* Look for the end of the token. */
3646 while (!endtoken (*dbp))
3649 } /* advance char */
3650 } /* advance line */
3654 * Bob Weiner, Motorola Inc., 4/3/94
3655 * Unix and microcontroller assembly tag handling
3656 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3664 LOOP_ON_INPUT_LINES (inf, lb, cp)
3666 /* If first char is alphabetic or one of [_.$], test for colon
3667 following identifier. */
3668 if (isalpha (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3670 /* Read past label. */
3672 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3674 if (*cp == ':' || isspace (*cp))
3676 /* Found end of label, so copy it and add it to the table. */
3677 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE,
3678 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3685 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3686 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3687 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3688 * Perl variable names: /^(my|local).../
3691 Perl_functions (inf)
3696 LOOP_ON_INPUT_LINES (inf, lb, cp)
3700 && *cp++ == 'b' && isspace (*cp++))
3702 cp = skip_spaces (cp);
3707 && !isspace (*cp) && *cp != '{' && *cp != '(')
3709 pfnote (savenstr (sp, cp-sp), TRUE,
3710 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3713 else if (globals /* only if tagging global vars is enabled */
3714 && ((cp = lb.buffer,
3723 && (*cp == '(' || isspace (*cp)))
3725 /* After "my" or "local", but before any following paren or space. */
3726 char *varname = NULL;
3728 cp = skip_spaces (cp);
3729 if (*cp == '$' || *cp == '@' || *cp == '%')
3731 char* varstart = ++cp;
3732 while (isalnum (*cp) || *cp == '_')
3734 varname = savenstr (varstart, cp-varstart);
3738 /* Should be examining a variable list at this point;
3739 could insist on seeing an open parenthesis. */
3740 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
3744 /* Perhaps I should back cp up one character, so the TAGS table
3745 doesn't mention (and so depend upon) the following char. */
3746 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
3747 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3753 * Python support by Eric S. Raymond <esr@thyrsus.com>
3754 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
3757 Python_functions (inf)
3762 LOOP_ON_INPUT_LINES (inf, lb, cp)
3766 && *cp++ == 'f' && isspace (*cp++))
3768 cp = skip_spaces (cp);
3769 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3772 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3780 && *cp++ == 's' && isspace (*cp++))
3782 cp = skip_spaces (cp);
3783 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3786 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3791 /* Idea by Corny de Souza
3792 * Cobol tag functions
3793 * We could look for anything that could be a paragraph name.
3794 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3797 Cobol_paragraphs (inf)
3800 register char *bp, *ep;
3802 LOOP_ON_INPUT_LINES (inf, lb, bp)
3808 /* If eoln, compiler option or comment ignore whole line. */
3809 if (bp[-1] != ' ' || !isalnum (bp[0]))
3812 for (ep = bp; isalnum (*ep) || *ep == '-'; ep++)
3815 pfnote (savenstr (bp, ep-bp), TRUE,
3816 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3820 /* Added by Mosur Mohan, 4/22/88 */
3821 /* Pascal parsing */
3824 * Locates tags for procedures & functions. Doesn't do any type- or
3825 * var-definitions. It does look for the keyword "extern" or
3826 * "forward" immediately following the procedure statement; if found,
3827 * the tag is skipped.
3830 Pascal_functions (inf)
3833 linebuffer tline; /* mostly copied from C_entries */
3835 int save_lineno, save_len;
3836 char c, *cp, *namebuf;
3838 bool /* each of these flags is TRUE iff: */
3839 incomment, /* point is inside a comment */
3840 inquote, /* point is inside '..' string */
3841 get_tagname, /* point is after PROCEDURE/FUNCTION
3842 keyword, so next item = potential tag */
3843 found_tag, /* point is after a potential tag */
3844 inparms, /* point is within parameter-list */
3845 verify_tag; /* point has passed the parm-list, so the
3846 next token will determine whether this
3847 is a FORWARD/EXTERN to be ignored, or
3848 whether it is a real tag */
3850 save_lcno = save_lineno = save_len = 0; /* keep compiler quiet */
3851 namebuf = NULL; /* keep compiler quiet */
3856 initbuffer (&tline);
3858 incomment = inquote = FALSE;
3859 found_tag = FALSE; /* have a proc name; check if extern */
3860 get_tagname = FALSE; /* have found "procedure" keyword */
3861 inparms = FALSE; /* found '(' after "proc" */
3862 verify_tag = FALSE; /* check if "extern" is ahead */
3865 while (!feof (inf)) /* long main loop to get next char */
3868 if (c == '\0') /* if end of line */
3871 linecharno = charno;
3872 charno += readline (&lb, inf);
3876 if (!((found_tag && verify_tag)
3878 c = *dbp++; /* only if don't need *dbp pointing
3879 to the beginning of the name of
3880 the procedure or function */
3884 if (c == '}') /* within { } comments */
3886 else if (c == '*' && *dbp == ')') /* within (* *) comments */
3903 inquote = TRUE; /* found first quote */
3905 case '{': /* found open { comment */
3909 if (*dbp == '*') /* found open (* comment */
3914 else if (found_tag) /* found '(' after tag, i.e., parm-list */
3917 case ')': /* end of parms list */
3922 if (found_tag && !inparms) /* end of proc or fn stmt */
3929 if (found_tag && verify_tag && (*dbp != ' '))
3931 /* check if this is an "extern" declaration */
3934 if (lowcase (*dbp == 'e'))
3936 if (tail ("extern")) /* superfluous, really! */
3942 else if (lowcase (*dbp) == 'f')
3944 if (tail ("forward")) /* check for forward reference */
3950 if (found_tag && verify_tag) /* not external proc, so make tag */
3954 pfnote (namebuf, TRUE,
3955 tline.buffer, save_len, save_lineno, save_lcno);
3959 if (get_tagname) /* grab name of proc or fn */
3964 /* save all values for later tagging */
3965 grow_linebuffer (&tline, lb.len + 1);
3966 strcpy (tline.buffer, lb.buffer);
3967 save_lineno = lineno;
3968 save_lcno = linecharno;
3970 /* grab block name */
3971 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
3973 namebuf = savenstr (dbp, cp-dbp);
3974 dbp = cp; /* set dbp to e-o-token */
3975 save_len = dbp - lb.buffer + 1;
3976 get_tagname = FALSE;
3980 /* and proceed to check for "extern" */
3982 else if (!incomment && !inquote && !found_tag)
3984 /* check for proc/fn keywords */
3985 switch (lowcase (c))
3988 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3992 if (tail ("unction"))
3997 } /* while not eof */
3999 free (tline.buffer);
4003 * lisp tag functions
4004 * look for (def or (DEF, quote or QUOTE
4008 register char *strp;
4010 return ((strp[1] == 'd' || strp[1] == 'D')
4011 && (strp[2] == 'e' || strp[2] == 'E')
4012 && (strp[3] == 'f' || strp[3] == 'F'));
4017 register char *strp;
4019 return ((*++strp == 'q' || *strp == 'Q')
4020 && (*++strp == 'u' || *strp == 'U')
4021 && (*++strp == 'o' || *strp == 'O')
4022 && (*++strp == 't' || *strp == 'T')
4023 && (*++strp == 'e' || *strp == 'E')
4024 && isspace (*++strp));
4032 if (*dbp == '\'') /* Skip prefix quote */
4034 else if (*dbp == '(')
4036 if (L_isquote (dbp))
4037 dbp += 7; /* Skip "(quote " */
4039 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */
4040 dbp = skip_spaces (dbp);
4043 for (cp = dbp /*+1*/;
4044 *cp != '\0' && *cp != '(' && !isspace(*cp) && *cp != ')';
4050 pfnote (savenstr (dbp, cp-dbp), TRUE,
4051 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4055 Lisp_functions (inf)
4058 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4064 dbp = skip_non_spaces (dbp);
4065 dbp = skip_spaces (dbp);
4070 /* Check for (foo::defmumble name-defined ... */
4073 while (*dbp != '\0' && !isspace (*dbp)
4074 && *dbp != ':' && *dbp != '(' && *dbp != ')');
4079 while (*dbp == ':');
4081 if (L_isdef (dbp - 1))
4083 dbp = skip_non_spaces (dbp);
4084 dbp = skip_spaces (dbp);
4094 * Postscript tag functions
4095 * Just look for lines where the first character is '/'
4096 * Richard Mlynarik <mly@adoc.xerox.com>
4097 * Also look at "defineps" for PSWrap
4098 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp>
4101 Postscript_functions (inf)
4104 register char *bp, *ep;
4106 LOOP_ON_INPUT_LINES (inf, lb, bp)
4111 *ep != '\0' && *ep != ' ' && *ep != '{';
4114 pfnote (savenstr (bp, ep-bp), TRUE,
4115 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4117 else if (strneq (bp, "defineps", 8))
4119 bp = skip_non_spaces (bp);
4120 bp = skip_spaces (bp);
4128 * Scheme tag functions
4129 * look for (def... xyzzy
4130 * look for (def... (xyzzy
4131 * look for (def ... ((...(xyzzy ....
4132 * look for (set! xyzzy
4136 Scheme_functions (inf)
4141 LOOP_ON_INPUT_LINES (inf, lb, bp)
4144 && (bp[1] == 'D' || bp[1] == 'd')
4145 && (bp[2] == 'E' || bp[2] == 'e')
4146 && (bp[3] == 'F' || bp[3] == 'f'))
4148 bp = skip_non_spaces (bp);
4149 /* Skip over open parens and white space */
4150 while (isspace (*bp) || *bp == '(')
4155 && (bp[1] == 'S' || bp[1] == 's')
4156 && (bp[2] == 'E' || bp[2] == 'e')
4157 && (bp[3] == 'T' || bp[3] == 't')
4158 && (bp[4] == '!' || bp[4] == '!')
4159 && (isspace (bp[5])))
4161 bp = skip_non_spaces (bp);
4162 bp = skip_spaces (bp);
4168 /* Find tags in TeX and LaTeX input files. */
4170 /* TEX_toktab is a table of TeX control sequences that define tags.
4171 Each TEX_tabent records one such control sequence.
4172 CONVERT THIS TO USE THE Stab TYPE!! */
4179 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
4181 /* Default set of control sequences to put into TEX_toktab.
4182 The value of environment var TEXTAGS is prepended to this. */
4184 char *TEX_defenv = "\
4185 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4186 :part:appendix:entry:index";
4188 void TEX_mode (FILE *inf);
4189 struct TEX_tabent *TEX_decode_env (char *evarname, char *defenv);
4190 int TEX_Token (char *cp);
4192 char TEX_esc = '\\';
4193 char TEX_opgrp = '{';
4194 char TEX_clgrp = '}';
4197 * TeX/LaTeX scanning loop.
4206 /* Select either \ or ! as escape character. */
4209 /* Initialize token table once from environment. */
4211 TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
4213 LOOP_ON_INPUT_LINES (inf, lb, cp)
4216 /* Look at each esc in line. */
4217 while ((cp = etags_strchr (cp, TEX_esc)) != NULL)
4221 linecharno += cp - lasthit;
4223 i = TEX_Token (lasthit);
4226 /* We seem to include the TeX command in the tag name.
4228 for (p = lasthit + TEX_toktab[i].len;
4229 *p != '\0' && *p != TEX_clgrp;
4232 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL, TRUE,
4233 lb.buffer, lb.len, lineno, linecharno);
4234 break; /* We only tag a line once */
4240 #define TEX_LESC '\\'
4241 #define TEX_SESC '!'
4244 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4245 chars accordingly. */
4252 while ((c = getc (inf)) != EOF)
4254 /* Skip to next line if we hit the TeX comment char. */
4258 else if (c == TEX_LESC || c == TEX_SESC )
4274 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4275 No attempt is made to correct the situation. */
4279 /* Read environment and prepend it to the default string.
4280 Build token table. */
4282 TEX_decode_env (evarname, defenv)
4286 register char *env, *p;
4288 struct TEX_tabent *tab;
4291 /* Append default string to environment. */
4292 env = getenv (evarname);
4298 env = concat (oldenv, defenv, "");
4301 /* Allocate a token table */
4302 for (size = 1, p = env; p;)
4303 if ((p = etags_strchr (p, ':')) && *++p != '\0')
4305 /* Add 1 to leave room for null terminator. */
4306 tab = xnew (size + 1, struct TEX_tabent);
4308 /* Unpack environment string into token table. Be careful about */
4309 /* zero-length strings (leading ':', "::" and trailing ':') */
4312 p = etags_strchr (env, ':');
4313 if (!p) /* End of environment string. */
4314 p = env + strlen (env);
4316 { /* Only non-zero strings. */
4317 tab[i].name = savenstr (env, p - env);
4318 tab[i].len = strlen (tab[i].name);
4325 tab[i].name = NULL; /* Mark end of table. */
4333 /* If the text at CP matches one of the tag-defining TeX command names,
4334 return the pointer to the first occurrence of that command in TEX_toktab.
4335 Otherwise return -1.
4336 Keep the capital `T' in `token' for dumb truncating compilers
4337 (this distinguishes it from `TEX_toktab' */
4344 for (i = 0; TEX_toktab[i].len > 0; i++)
4345 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
4351 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
4353 * Assumes that the predicate starts at column 0.
4354 * Only the first clause of a predicate is added.
4356 int prolog_pred (char *s, char *last);
4357 void prolog_skip_comment (linebuffer *plb, FILE *inf);
4358 int prolog_atom (char *s, int pos);
4361 Prolog_functions (inf)
4372 LOOP_ON_INPUT_LINES (inf, lb, cp)
4374 if (cp[0] == '\0') /* Empty line */
4376 else if (isspace (cp[0])) /* Not a predicate */
4378 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
4379 prolog_skip_comment (&lb, inf);
4380 else if ((len = prolog_pred (cp, last)) > 0)
4382 /* Predicate. Store the function name so that we only
4383 generate a tag for the first clause. */
4385 last = xnew(len + 1, char);
4386 else if (len + 1 > allocated)
4387 last = xrnew (last, len + 1, char);
4388 allocated = len + 1;
4389 strncpy (last, cp, len);
4397 prolog_skip_comment (plb, inf)
4405 for (cp = plb->buffer; *cp != '\0'; cp++)
4406 if (cp[0] == '*' && cp[1] == '/')
4409 linecharno += readline (plb, inf);
4415 * A predicate definition is added if it matches:
4416 * <beginning of line><Prolog Atom><whitespace>(
4418 * It is added to the tags database if it doesn't match the
4419 * name of the previous clause header.
4421 * Return the size of the name of the predicate, or 0 if no header
4425 prolog_pred (s, last)
4427 char *last; /* Name of last clause. */
4432 pos = prolog_atom (s, 0);
4437 pos = skip_spaces (s + pos) - s;
4439 if ((s[pos] == '(') || (s[pos] == '.'))
4444 /* Save only the first clause. */
4446 || len != (int)strlen (last)
4447 || !strneq (s, last, len))
4449 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4457 * Consume a Prolog atom.
4458 * Return the number of bytes consumed, or -1 if there was an error.
4460 * A prolog atom, in this context, could be one of:
4461 * - An alphanumeric sequence, starting with a lower case letter.
4462 * - A quoted arbitrary string. Single quotes can escape themselves.
4463 * Backslash quotes everything.
4466 prolog_atom (s, pos)
4474 if (islower(s[pos]) || (s[pos] == '_'))
4476 /* The atom is unquoted. */
4478 while (isalnum(s[pos]) || (s[pos] == '_'))
4482 return pos - origpos;
4484 else if (s[pos] == '\'')
4495 pos++; /* A double quote */
4497 else if (s[pos] == '\0')
4498 /* Multiline quoted atoms are ignored. */
4500 else if (s[pos] == '\\')
4502 if (s[pos+1] == '\0')
4509 return pos - origpos;
4516 * Support for Erlang -- Anders Lindgren, Feb 1996.
4518 * Generates tags for functions, defines, and records.
4520 * Assumes that Erlang functions start at column 0.
4522 int erlang_func (char *s, char *last);
4523 void erlang_attribute (char *s);
4524 int erlang_atom (char *s, int pos);
4527 Erlang_functions (inf)
4538 LOOP_ON_INPUT_LINES (inf, lb, cp)
4540 if (cp[0] == '\0') /* Empty line */
4542 else if (isspace (cp[0])) /* Not function nor attribute */
4544 else if (cp[0] == '%') /* comment */
4546 else if (cp[0] == '"') /* Sometimes, strings start in column one */
4548 else if (cp[0] == '-') /* attribute, e.g. "-define" */
4550 erlang_attribute (cp);
4553 else if ((len = erlang_func (cp, last)) > 0)
4556 * Function. Store the function name so that we only
4557 * generates a tag for the first clause.
4560 last = xnew (len + 1, char);
4561 else if (len + 1 > allocated)
4562 last = xrnew (last, len + 1, char);
4563 allocated = len + 1;
4564 strncpy (last, cp, len);
4572 * A function definition is added if it matches:
4573 * <beginning of line><Erlang Atom><whitespace>(
4575 * It is added to the tags database if it doesn't match the
4576 * name of the previous clause header.
4578 * Return the size of the name of the function, or 0 if no function
4582 erlang_func (s, last)
4584 char *last; /* Name of last clause. */
4589 pos = erlang_atom (s, 0);
4594 pos = skip_spaces (s + pos) - s;
4596 /* Save only the first clause. */
4599 || len != (int)strlen (last)
4600 || !strneq (s, last, len)))
4602 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4611 * Handle attributes. Currently, tags are generated for defines
4614 * They are on the form:
4615 * -define(foo, bar).
4616 * -define(Foo(M, N), M+N).
4617 * -record(graph, {vtab = notable, cyclic = true}).
4620 erlang_attribute (s)
4626 if (strneq (s, "-define", 7) || strneq (s, "-record", 7))
4628 pos = skip_spaces (s + 7) - s;
4629 if (s[pos++] == '(')
4631 pos = skip_spaces (s + pos) - s;
4632 len = erlang_atom (s, pos);
4634 pfnote (savenstr (& s[pos], len), TRUE,
4635 s, pos + len, lineno, linecharno);
4643 * Consume an Erlang atom (or variable).
4644 * Return the number of bytes consumed, or -1 if there was an error.
4647 erlang_atom (s, pos)
4655 if (isalpha (s[pos]) || s[pos] == '_')
4657 /* The atom is unquoted. */
4659 while (isalnum (s[pos]) || s[pos] == '_')
4661 return pos - origpos;
4663 else if (s[pos] == '\'')
4674 else if (s[pos] == '\0')
4675 /* Multiline quoted atoms are ignored. */
4677 else if (s[pos] == '\\')
4679 if (s[pos+1] == '\0')
4686 return pos - origpos;
4692 #ifdef ETAGS_REGEXPS
4694 /* Take a string like "/blah/" and turn it into "blah", making sure
4695 that the first and last characters are the same, and handling
4696 quoted separator characters. Actually, stops on the occurrence of
4697 an unquoted separator. Also turns "\t" into a Tab character.
4698 Returns pointer to terminating separator. Works in place. Null
4699 terminates name string. */
4701 scan_separators (name)
4705 char *copyto = name;
4706 bool quoted = FALSE;
4708 for (++name; *name != '\0'; ++name)
4714 else if (*name == sep)
4718 /* Something else is quoted, so preserve the quote. */
4724 else if (*name == '\\')
4726 else if (*name == sep)
4732 /* Terminate copied string. */
4737 /* Look at the argument of --regex or --no-regex and do the right
4738 thing. Same for each line of a regexp file. */
4740 analyse_regex (regex_arg, ignore_case)
4744 if (regex_arg == NULL)
4745 free_patterns (); /* --no-regex: remove existing regexps */
4747 /* A real --regexp option or a line in a regexp file. */
4748 switch (regex_arg[0])
4750 /* Comments in regexp file or null arg to --regex. */
4756 /* Read a regex file. This is recursive and may result in a
4757 loop, which will stop when the file descriptors are exhausted. */
4761 linebuffer regexbuf;
4762 char *regexfile = regex_arg + 1;
4764 /* regexfile is a file containing regexps, one per line. */
4765 regexfp = fopen (regexfile, "r");
4766 if (regexfp == NULL)
4771 initbuffer (®exbuf);
4772 while (readline_internal (®exbuf, regexfp) > 0)
4773 analyse_regex (regexbuf.buffer, ignore_case);
4774 free (regexbuf.buffer);
4779 /* Regexp to be used for a specific language only. */
4783 char *lang_name = regex_arg + 1;
4786 for (cp = lang_name; *cp != '}'; cp++)
4789 error ("unterminated language name in regex: %s", regex_arg);
4793 lang = get_language_from_name (lang_name);
4796 add_regex (cp + 1, ignore_case, lang);
4800 /* Regexp to be used for any language. */
4802 add_regex (regex_arg, ignore_case, NULL);
4807 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4808 expression, into a real regular expression by compiling it. */
4810 add_regex (regexp_pattern, ignore_case, lang)
4811 char *regexp_pattern;
4817 struct re_pattern_buffer *patbuf;
4821 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0])
4823 error ("%s: unterminated regexp", regexp_pattern);
4826 name = scan_separators (regexp_pattern);
4827 if (regexp_pattern[0] == '\0')
4829 error ("null regexp", (char *)NULL);
4832 (void) scan_separators (name);
4834 patbuf = xnew (1, struct re_pattern_buffer);
4835 /* Translation table to fold case if appropriate. */
4836 patbuf->translate = (ignore_case) ? lc_trans : NULL;
4837 patbuf->fastmap = NULL;
4838 patbuf->buffer = NULL;
4839 patbuf->allocated = 0;
4841 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4844 error ("%s while compiling pattern", err);
4849 p_head = xnew (1, pattern);
4850 p_head->regex = savestr (regexp_pattern);
4851 p_head->p_next = pp;
4852 p_head->language = lang;
4853 p_head->pattern = patbuf;
4854 p_head->name_pattern = savestr (name);
4855 p_head->error_signaled = FALSE;
4859 * Do the substitutions indicated by the regular expression and
4863 substitute (in, out, regs)
4865 struct re_registers *regs;
4868 int size, dig, diglen;
4871 size = strlen (out);
4873 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4874 if (out[size - 1] == '\\')
4875 fatal ("pattern error in \"%s\"", out);
4876 for (t = etags_strchr (out, '\\');
4878 t = etags_strchr (t + 2, '\\'))
4882 diglen = regs->end[dig] - regs->start[dig];
4888 /* Allocate space and do the substitutions. */
4889 result = xnew (size + 1, char);
4891 for (t = result; *out != '\0'; out++)
4892 if (*out == '\\' && isdigit (*++out))
4894 /* Using "dig2" satisfies my debugger. Bleah. */
4896 diglen = regs->end[dig] - regs->start[dig];
4897 strncpy (t, in + regs->start[dig], diglen);
4904 if (DEBUG && (t > result + size || t - result != (int)strlen (result)))
4910 /* Deallocate all patterns. */
4915 while (p_head != NULL)
4917 pp = p_head->p_next;
4918 free (p_head->regex);
4919 free (p_head->name_pattern);
4934 /* Go till you get to white space or a syntactic break */
4936 *cp != '\0' && *cp != '(' && *cp != ')' && !isspace (*cp);
4939 pfnote (savenstr (bp, cp-bp), TRUE,
4940 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4943 #endif /* ETAGS_REGEXPS */
4944 /* Initialize a linebuffer for use */
4950 lbp->buffer = xnew (200, char);
4954 * Read a line of text from `stream' into `lbp', excluding the
4955 * newline or CR-NL, if any. Return the number of characters read from
4956 * `stream', which is the length of the line including the newline.
4958 * On DOS or Windows we do not count the CR character, if any, before the
4959 * NL, in the returned length; this mirrors the behavior of emacs on those
4960 * platforms (for text files, it translates CR-NL to NL as it reads in the
4964 readline_internal (lbp, stream)
4966 register FILE *stream;
4968 char *buffer = lbp->buffer;
4969 register char *p = lbp->buffer;
4970 register char *pend;
4973 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
4977 register int c = getc (stream);
4980 /* We're at the end of linebuffer: expand it. */
4982 buffer = xrnew (buffer, lbp->size, char);
4983 p += buffer - lbp->buffer;
4984 pend = buffer + lbp->size;
4985 lbp->buffer = buffer;
4995 if (p > buffer && p[-1] == '\r')
4999 /* Assume CRLF->LF translation will be performed by Emacs
5000 when loading this file, so CRs won't appear in the buffer.
5001 It would be cleaner to compensate within Emacs;
5002 however, Emacs does not know how many CRs were deleted
5003 before any given point in the file. */
5018 lbp->len = p - buffer;
5020 return lbp->len + chars_deleted;
5024 * Like readline_internal, above, but in addition try to match the
5025 * input line against relevant regular expressions.
5028 readline (lbp, stream)
5032 /* Read new line. */
5033 long result = readline_internal (lbp, stream);
5034 #ifdef ETAGS_REGEXPS
5038 /* Match against relevant patterns. */
5040 for (pp = p_head; pp != NULL; pp = pp->p_next)
5042 /* Only use generic regexps or those for the current language. */
5043 if (pp->language != NULL && pp->language != curlang)
5046 match = re_match (pp->pattern, lbp->buffer, lbp->len, 0, &pp->regs);
5051 if (!pp->error_signaled)
5053 error ("error while matching \"%s\"", pp->regex);
5054 pp->error_signaled = TRUE;
5061 /* Match occurred. Construct a tag. */
5062 if (pp->name_pattern[0] != '\0')
5064 /* Make a named tag. */
5065 char *name = substitute (lbp->buffer,
5066 pp->name_pattern, &pp->regs);
5068 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
5072 /* Make an unnamed tag. */
5073 pfnote ((char *)NULL, TRUE,
5074 lbp->buffer, match, lineno, linecharno);
5079 #endif /* ETAGS_REGEXPS */
5085 * Return a pointer to a space of size strlen(cp)+1 allocated
5086 * with xnew where the string CP has been copied.
5092 return savenstr (cp, strlen (cp));
5096 * Return a pointer to a space of size LEN+1 allocated with xnew where
5097 * the string CP has been copied for at most the first LEN characters.
5106 dp = xnew (len + 1, char);
5107 strncpy (dp, cp, len);
5113 * Return the ptr in sp at which the character c last
5114 * appears; NULL if not found
5116 * Identical to System V strrchr, included for portability.
5119 etags_strrchr (sp, c)
5120 register char *sp, c;
5135 * Return the ptr in sp at which the character c first
5136 * appears; NULL if not found
5138 * Identical to System V strchr, included for portability.
5141 etags_strchr (sp, c)
5142 register char *sp, c;
5152 /* Skip spaces, return new pointer. */
5157 while (isspace (*cp)) /* isspace('\0')==FALSE */
5162 /* Skip non spaces, return new pointer. */
5164 skip_non_spaces (cp)
5167 while (!iswhite (*cp)) /* iswhite('\0')==TRUE */
5172 /* Print error message and exit. */
5190 suggest_asking_for_help ()
5192 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
5203 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5206 const char *s1, *s2;
5208 fprintf (stderr, "%s: ", progname);
5209 fprintf (stderr, s1, s2);
5210 fprintf (stderr, "\n");
5213 /* Return a newly-allocated string whose contents
5214 concatenate those of s1, s2, s3. */
5219 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
5220 char *result = xnew (len1 + len2 + len3 + 1, char);
5222 strcpy (result, s1);
5223 strcpy (result + len1, s2);
5224 strcpy (result + len1 + len2, s3);
5225 result[len1 + len2 + len3] = '\0';
5230 /* Does the same work as the system V getcwd, but does not need to
5231 guess the buffer size in advance. */
5237 char *path = xnew (bufsize, char);
5239 while (getcwd (path, bufsize) == NULL)
5241 if (errno != ERANGE)
5245 path = xnew (bufsize, char);
5248 canonicalize_filename (path);
5251 #else /* not HAVE_GETCWD */
5253 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
5257 for (p = path; *p != '\0'; p++)
5263 return strdup (path);
5264 #else /* not MSDOS */
5269 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
5270 if (pipe == NULL || readline_internal (&path, pipe) == 0)
5275 #endif /* not MSDOS */
5276 #endif /* not HAVE_GETCWD */
5279 /* Return a newly allocated string containing the file name of FILE
5280 relative to the absolute directory DIR (which should end with a slash). */
5282 relative_filename (file, dir)
5285 char *fp, *dp, *afn, *res;
5288 /* Find the common root of file and dir (with a trailing slash). */
5289 afn = absolute_filename (file, cwd);
5292 while (*fp++ == *dp++)
5294 fp--, dp--; /* back to the first differing char */
5296 if (fp == afn && afn[0] != '/') /* cannot build a relative name */
5299 do /* look at the equal chars until '/' */
5303 /* Build a sequence of "../" strings for the resulting relative file name. */
5305 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
5307 res = xnew (3*i + strlen (fp + 1) + 1, char);
5310 strcat (res, "../");
5312 /* Add the file name relative to the common root of file and dir. */
5313 strcat (res, fp + 1);
5319 /* Return a newly allocated string containing the absolute file name
5320 of FILE given DIR (which should end with a slash). */
5322 absolute_filename (file, dir)
5325 char *slashp, *cp, *res;
5327 if (filename_is_absolute (file))
5328 res = savestr (file);
5330 /* We don't support non-absolute file names with a drive
5331 letter, like `d:NAME' (it's too much hassle). */
5332 else if (file[1] == ':')
5333 fatal ("%s: relative file names with drive letters not supported", file);
5336 res = concat (dir, file, "");
5338 /* Delete the "/dirname/.." and "/." substrings. */
5339 slashp = etags_strchr (res, '/');
5340 while (slashp != NULL && slashp[0] != '\0')
5342 if (slashp[1] == '.')
5344 if (slashp[2] == '.'
5345 && (slashp[3] == '/' || slashp[3] == '\0'))
5350 while (cp >= res && !filename_is_absolute (cp));
5352 cp = slashp; /* the absolute name begins with "/.." */
5354 /* Under MSDOS and NT we get `d:/NAME' as absolute
5355 file name, so the luser could say `d:/../NAME'.
5356 We silently treat this as `d:/NAME'. */
5357 else if (cp[0] != '/')
5360 strcpy (cp, slashp + 3);
5364 else if (slashp[2] == '/' || slashp[2] == '\0')
5366 strcpy (slashp, slashp + 2);
5371 slashp = etags_strchr (slashp + 1, '/');
5375 return savestr ("/");
5380 /* Return a newly allocated string containing the absolute
5381 file name of dir where FILE resides given DIR (which should
5382 end with a slash). */
5384 absolute_dirname (file, dir)
5390 canonicalize_filename (file);
5391 slashp = etags_strrchr (file, '/');
5393 return savestr (dir);
5396 res = absolute_filename (file, dir);
5402 /* Whether the argument string is an absolute file name. The argument
5403 string must have been canonicalized with canonicalize_filename. */
5405 filename_is_absolute (fn)
5408 return (fn[0] == '/'
5410 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/')
5415 /* Translate backslashes into slashes. Works in place. */
5417 canonicalize_filename (fn)
5421 /* Canonicalize drive letter case. */
5422 if (islower (fn[0]))
5423 fn[0] = toupper (fn[0]);
5424 /* Convert backslashes to slashes. */
5425 for (; *fn != '\0'; fn++)
5430 fn = NULL; /* shut up the compiler */
5434 /* Increase the size of a linebuffer. */
5436 grow_linebuffer (lbp, toksize)
5440 while (lbp->size < toksize)
5442 lbp->buffer = xrnew (lbp->buffer, lbp->size, char);
5445 /* Like malloc but get fatal error if memory is exhausted. */
5450 long *result = (long *) malloc (size);
5452 fatal ("virtual memory exhausted", (char *)NULL);
5457 xrealloc (ptr, size)
5461 long *result = (long *) realloc (ptr, size);
5463 fatal ("virtual memory exhausted", (char *)NULL);