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 */
99 #include <sys/types.h>
100 #include <sys/stat.h>
102 #if !defined (S_ISREG) && defined (S_IFREG)
103 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
109 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
111 extern int optind, opterr;
112 #endif /* LONG_OPTIONS */
116 #endif /* ETAGS_REGEXPS */
118 /* Define CTAGS to make the program "ctags" compatible with the usual one.
119 Leave it undefined to make the program "etags", which makes emacs-style
120 tag tables and tags typedefs, #defines and struct/union/enum by default. */
128 /* Exit codes for success and failure. */
138 #define C_PLPL 0x00001 /* C++ */
139 #define C_STAR 0x00003 /* C* */
140 #define C_JAVA 0x00005 /* JAVA */
141 #define YACC 0x10000 /* yacc file */
143 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
144 && (abort (), 1)) || !strcmp (s, t))
145 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
146 && (abort (), 1)) || !strncmp (s, t, n))
148 #define lowcase(c) tolower ((char)c)
150 #define CHARS 256 /* 2^sizeof(char) */
151 #define CHAR(x) ((unsigned int)x & (CHARS - 1))
152 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
153 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
154 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
155 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
156 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
160 * xnew, xrnew -- allocate, reallocate storage
162 * SYNOPSIS: Type *xnew (int n, Type);
163 * Type *xrnew (OldPointer, int n, Type);
166 # include "chkmalloc.h"
167 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
168 (n) * sizeof (Type)))
169 # define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \
170 (op), (n) * sizeof (Type)))
172 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
173 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type)))
178 typedef void Lang_function ();
183 char *command; /* Takes one arg and decompresses to stdout */
189 Lang_function *function;
194 typedef struct node_st
195 { /* sorting structure */
196 char *name; /* function or type name */
197 char *file; /* file name */
198 bool is_func; /* use pattern or line no */
199 bool been_warned; /* set if noticed dup */
200 int lno; /* line number tag is on */
201 long cno; /* character number line starts on */
202 char *pat; /* search pattern */
203 struct node_st *left, *right; /* left and right sons */
207 * A `linebuffer' is a structure which holds a line of text.
208 * `readline_internal' reads a line from a stream into a linebuffer
209 * and works regardless of the length of the line.
210 * SIZE is the size of BUFFER, LEN is the length of the string in
211 * BUFFER after readline reads it.
220 /* Many compilers barf on this:
221 Lang_function Ada_funcs;
222 so let's write it this way */
223 void Ada_funcs (FILE *inf);
224 void Asm_labels (FILE *inf);
225 void C_entries (int c_ext, FILE *inf);
226 void default_C_entries (FILE *inf);
227 void plain_C_entries (FILE *inf);
228 void Cjava_entries (FILE *inf);
229 void Cobol_paragraphs (FILE *inf);
230 void Cplusplus_entries (FILE *inf);
231 void Cstar_entries (FILE *inf);
232 void Erlang_functions (FILE *inf);
233 void Fortran_functions (FILE *inf);
234 void Yacc_entries (FILE *inf);
235 void Lisp_functions (FILE *inf);
236 void Pascal_functions (FILE *inf);
237 void Perl_functions (FILE *inf);
238 void Postscript_functions (FILE *inf);
239 void Prolog_functions (FILE *inf);
240 void Python_functions (FILE *inf);
241 void Scheme_functions (FILE *inf);
242 void TeX_functions (FILE *inf);
243 void just_read_file (FILE *inf);
245 compressor *get_compressor_from_suffix (char *file, char **extptr);
246 language *get_language_from_name (char *name);
247 language *get_language_from_interpreter (char *interpreter);
248 language *get_language_from_suffix (char *file);
249 int total_size_of_entries (register node *np);
250 long readline (linebuffer *lbp, FILE *stream);
251 long readline_internal (linebuffer *lbp, register FILE *stream);
252 void get_tag (register char *bp);
255 void analyse_regex (char *regex_arg, bool ignore_case);
256 void add_regex (char *regexp_pattern, bool ignore_case, language *lan);
257 void free_patterns (void);
258 #endif /* ETAGS_REGEXPS */
259 void error (const char *s1, const char *s2);
260 void suggest_asking_for_help (void);
261 void fatal (char *s1, char *s2);
262 void pfatal (char *s1);
263 void add_node (node *np, node **cur_node_p);
266 void initbuffer (linebuffer *lbp);
267 void find_entries (char *file, FILE *inf);
268 void free_tree (register node *np);
269 void pfnote (char *name, bool is_func, char *linestart, int linelen, int lno, long int cno);
270 void new_pfnote (char *name, int namelen, bool is_func, char *linestart, int linelen, int lno, long int cno);
271 void process_file (char *file);
272 void put_entries (register node *np);
273 void takeprec (void);
275 char *concat (char *s1, char *s2, char *s3);
276 char *skip_spaces (char *cp);
277 char *skip_non_spaces (char *cp);
278 char *savenstr (char *cp, int len);
279 char *savestr (char *cp);
280 char *etags_strchr (const char *sp, int c);
281 char *etags_strrchr (const char *sp, int c);
282 char *etags_getcwd (void);
283 char *relative_filename (char *file, char *dir);
284 char *absolute_filename (char *file, char *dir);
285 char *absolute_dirname (char *file, char *dir);
286 bool filename_is_absolute (char *fn);
287 void canonicalize_filename (register char *fn);
288 void grow_linebuffer (linebuffer *lbp, int toksize);
289 long *xmalloc (unsigned int size);
290 long *xrealloc (char *ptr, unsigned int size);
293 char searchar = '/'; /* use /.../ searches */
295 char *tagfile; /* output file */
296 char *progname; /* name this program was invoked with */
297 char *cwd; /* current working directory */
298 char *tagfiledir; /* directory of tagfile */
299 FILE *tagf; /* ioptr for tags file */
301 char *curfile; /* current input file name */
302 language *curlang; /* current language */
304 int lineno; /* line number of current line */
305 long charno; /* current character number */
306 long linecharno; /* charno of start of current line */
307 char *dbp; /* pointer to start of current tag */
309 node *head; /* the head of the binary tree of tags */
311 linebuffer lb; /* the current line */
312 linebuffer token_name; /* used by C_entries as a temporary area */
316 linebuffer lb; /* used by C_entries instead of lb */
319 /* boolean "functions" (see init) */
320 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
323 *white = " \f\t\n\r",
325 *nonam = " \f\t\n\r(=,[;",
326 /* token ending chars */
327 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
328 /* token starting chars */
329 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
330 /* valid in-token chars */
331 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
333 bool append_to_tagfile; /* -a: append to tags */
334 /* The following four default to TRUE for etags, but to FALSE for ctags. */
335 bool typedefs; /* -t: create tags for C and Ada typedefs */
336 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */
337 /* 0 struct/enum/union decls, and C++ */
338 /* member functions. */
339 bool constantypedefs; /* -d: create tags for C #define, enum */
340 /* constants and variables. */
341 /* -D: opposite of -d. Default under ctags. */
342 bool declarations; /* --declarations: tag them and extern in C&Co*/
343 bool globals; /* create tags for global variables */
344 bool members; /* create tags for C member variables */
345 bool update; /* -u: update tags */
346 bool vgrind_style; /* -v: create vgrind style index output */
347 bool no_warnings; /* -w: suppress warnings */
348 bool cxref_style; /* -x: create cxref style output */
349 bool cplusplus; /* .[hc] means C++, not C */
350 bool noindentypedefs; /* -I: ignore indentation in C */
351 bool packages_only; /* --packages-only: in Ada, only tag packages*/
354 struct option longopts[] =
356 { "packages-only", no_argument, &packages_only, TRUE },
357 { "append", no_argument, NULL, 'a' },
358 { "backward-search", no_argument, NULL, 'B' },
359 { "c++", no_argument, NULL, 'C' },
360 { "cxref", no_argument, NULL, 'x' },
361 { "defines", no_argument, NULL, 'd' },
362 { "declarations", no_argument, &declarations, TRUE },
363 { "no-defines", no_argument, NULL, 'D' },
364 { "globals", no_argument, &globals, TRUE },
365 { "no-globals", no_argument, &globals, FALSE },
366 { "help", no_argument, NULL, 'h' },
367 { "help", no_argument, NULL, 'H' },
368 { "ignore-indentation", no_argument, NULL, 'I' },
369 { "include", required_argument, NULL, 'i' },
370 { "language", required_argument, NULL, 'l' },
371 { "members", no_argument, &members, TRUE },
372 { "no-members", no_argument, &members, FALSE },
373 { "no-warn", no_argument, NULL, 'w' },
374 { "output", required_argument, NULL, 'o' },
376 { "regex", required_argument, NULL, 'r' },
377 { "no-regex", no_argument, NULL, 'R' },
378 { "ignore-case-regex", required_argument, NULL, 'c' },
379 #endif /* ETAGS_REGEXPS */
380 { "typedefs", no_argument, NULL, 't' },
381 { "typedefs-and-c++", no_argument, NULL, 'T' },
382 { "update", no_argument, NULL, 'u' },
383 { "version", no_argument, NULL, 'V' },
384 { "vgrind", no_argument, NULL, 'v' },
387 #endif /* LONG_OPTIONS */
390 /* Structure defining a regular expression. Elements are
391 the compiled pattern, and the name string. */
392 typedef struct pattern
394 struct pattern *p_next;
397 struct re_pattern_buffer *pattern;
398 struct re_registers regs;
403 /* List of all regexps. */
404 pattern *p_head = NULL;
406 /* How many characters in the character set. (From regex.c.) */
407 #define CHAR_SET_SIZE 256
408 /* Translation table for case-insensitive matching. */
409 char lc_trans[CHAR_SET_SIZE];
410 #endif /* ETAGS_REGEXPS */
412 compressor compressors[] =
414 { "z", "gzip -d -c"},
415 { "Z", "gzip -d -c"},
416 { "gz", "gzip -d -c"},
417 { "GZ", "gzip -d -c"},
418 { "bz2", "bzip2 -d -c" },
426 /* Non-NULL if language fixed. */
427 language *forced_lang = NULL;
430 char *Ada_suffixes [] =
431 { "ads", "adb", "ada", NULL };
434 char *Asm_suffixes [] = { "a", /* Unix assembler */
435 "asm", /* Microcontroller assembly */
436 "def", /* BSO/Tasking definition includes */
437 "inc", /* Microcontroller include files */
438 "ins", /* Microcontroller include files */
439 "s", "sa", /* Unix assembler */
440 "S", /* cpp-processed Unix assembler */
441 "src", /* BSO/Tasking C compiler output */
445 /* Note that .c and .h can be considered C++, if the --c++ flag was
446 given. That is why default_C_entries is called here. */
447 char *default_C_suffixes [] =
450 char *Cplusplus_suffixes [] =
451 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
452 "M", /* Objective C++ */
453 "pdb", /* Postscript with C syntax */
456 char *Cjava_suffixes [] =
459 char *Cobol_suffixes [] =
460 { "COB", "cob", NULL };
462 char *Cstar_suffixes [] =
463 { "cs", "hs", NULL };
465 char *Erlang_suffixes [] =
466 { "erl", "hrl", NULL };
468 char *Fortran_suffixes [] =
469 { "F", "f", "f90", "for", NULL };
471 char *Lisp_suffixes [] =
472 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
474 char *Pascal_suffixes [] =
475 { "p", "pas", NULL };
477 char *Perl_suffixes [] =
478 { "pl", "pm", NULL };
479 char *Perl_interpreters [] =
480 { "perl", "@PERL@", NULL };
482 char *plain_C_suffixes [] =
483 { "pc", /* Pro*C file */
484 "m", /* Objective C file */
485 "lm", /* Objective lex file */
488 char *Postscript_suffixes [] =
489 { "ps", "psw", NULL }; /* .psw is for PSWrap */
491 char *Prolog_suffixes [] =
494 char *Python_suffixes [] =
497 /* Can't do the `SCM' or `scm' prefix with a version number. */
498 char *Scheme_suffixes [] =
499 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "ss", "t", NULL };
501 char *TeX_suffixes [] =
502 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
504 char *Yacc_suffixes [] =
505 { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */
508 * Table of languages.
510 * It is ok for a given function to be listed under more than one
511 * name. I just didn't.
514 language lang_names [] =
516 { "ada", Ada_funcs, Ada_suffixes, NULL },
517 { "asm", Asm_labels, Asm_suffixes, NULL },
518 { "c", default_C_entries, default_C_suffixes, NULL },
519 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
520 { "c*", Cstar_entries, Cstar_suffixes, NULL },
521 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL },
522 { "erlang", Erlang_functions, Erlang_suffixes, NULL },
523 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
524 { "java", Cjava_entries, Cjava_suffixes, NULL },
525 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
526 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
527 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
528 { "postscript", Postscript_functions, Postscript_suffixes, NULL },
529 { "proc", plain_C_entries, plain_C_suffixes, NULL },
530 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
531 { "python", Python_functions, Python_suffixes, NULL },
532 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
533 { "tex", TeX_functions, TeX_suffixes, NULL },
534 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
535 { "auto", NULL }, /* default guessing scheme */
536 { "none", just_read_file }, /* regexp matching only */
537 { NULL, NULL } /* end of list */
541 print_language_names ()
546 puts ("\nThese are the currently supported languages, along with the\n\
547 default file name suffixes:");
548 for (lang = lang_names; lang->name != NULL; lang++)
550 printf ("\t%s\t", lang->name);
551 if (lang->suffixes != NULL)
552 for (ext = lang->suffixes; *ext != NULL; ext++)
553 printf (" .%s", *ext);
556 puts ("Where `auto' means use default language for files based on file\n\
557 name suffix, and `none' means only do regexp processing on files.\n\
558 If no language is specified and no matching suffix is found,\n\
559 the first line of the file is read for a sharp-bang (#!) sequence\n\
560 followed by the name of an interpreter. If no such sequence is found,\n\
561 Fortran is tried first; if no tags are found, C is tried next.\n\
562 Compressed files are supported using gzip and bzip2.");
566 # define EMACS_NAME "XEmacs"
568 # define EMACS_NAME "GNU Emacs"
572 # define VERSION "20"
577 printf ("%s (" EMACS_NAME " %s)\n", (CTAGS) ? "ctags" : "etags", VERSION);
578 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
579 puts ("This program is distributed under the same terms as Emacs");
587 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
589 These are the options accepted by %s.\n", progname, progname);
591 puts ("You may use unambiguous abbreviations for the long option names.");
593 puts ("Long option names do not work with this executable, as it is not\n\
594 linked with GNU getopt.");
595 #endif /* LONG_OPTIONS */
596 puts ("A - as file name means read names from stdin (one per line).");
598 printf (" Absolute names are stored in the output file as they are.\n\
599 Relative ones are stored relative to the output file's directory.");
602 puts ("-a, --append\n\
603 Append tag entries to existing tags file.");
605 puts ("--packages-only\n\
606 For Ada files, only generate tags for packages .");
609 puts ("-B, --backward-search\n\
610 Write the search commands for the tag entries using '?', the\n\
611 backward-search command instead of '/', the forward-search command.");
614 Treat files whose name suffix defaults to C language as C++ files.");
616 puts ("--declarations\n\
617 In C and derived languages, create tags for function declarations,");
619 puts ("\tand create tags for extern variables if --globals is used.");
622 ("\tand create tags for extern variables unless --no-globals is used.");
625 puts ("-d, --defines\n\
626 Create tag entries for C #define constants and enum constants, too.");
628 puts ("-D, --no-defines\n\
629 Don't create tag entries for C #define constants and enum constants.\n\
630 This makes the tags file smaller.");
634 puts ("-i FILE, --include=FILE\n\
635 Include a note in tag file indicating that, when searching for\n\
636 a tag, one should also consult the tags file FILE after\n\
637 checking the current file.");
638 puts ("-l LANG, --language=LANG\n\
639 Force the following files to be considered as written in the\n\
640 named language up to the next --language=LANG option.");
645 Create tag entries for global variables in some languages.");
647 puts ("--no-globals\n\
648 Do not create tag entries for global variables in some\n\
649 languages. This makes the tags file smaller.");
651 Create tag entries for member variables in C and derived languages.");
654 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
655 Make a tag for each line matching pattern REGEXP in the following\n\
656 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
657 regexfile is a file containing one REGEXP per line.\n\
658 REGEXP is anchored (as if preceded by ^).\n\
659 The form /REGEXP/NAME/ creates a named tag.\n\
660 For example Tcl named tags can be created with:\n\
661 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
662 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
663 Like -r, --regex but ignore case when matching expressions.");
664 puts ("-R, --no-regex\n\
665 Don't create tags from regexps for the following files.");
666 #endif /* ETAGS_REGEXPS */
667 puts ("-o FILE, --output=FILE\n\
668 Write the tags to FILE.");
669 puts ("-I, --ignore-indentation\n\
670 Don't rely on indentation quite as much as normal. Currently,\n\
671 this means not to assume that a closing brace in the first\n\
672 column is the final brace of a function or structure\n\
673 definition in C and C++.");
677 puts ("-t, --typedefs\n\
678 Generate tag entries for C and Ada typedefs.");
679 puts ("-T, --typedefs-and-c++\n\
680 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
681 and C++ member functions.");
682 puts ("-u, --update\n\
683 Update the tag entries for the given files, leaving tag\n\
684 entries for other files in place. Currently, this is\n\
685 implemented by deleting the existing entries for the given\n\
686 files and then rewriting the new entries at the end of the\n\
687 tags file. It is often faster to simply rebuild the entire\n\
688 tag file than to use this.");
689 puts ("-v, --vgrind\n\
690 Generates an index of items intended for human consumption,\n\
691 similar to the output of vgrind. The index is sorted, and\n\
692 gives the page number of each item.");
693 puts ("-w, --no-warn\n\
694 Suppress warning messages about entries defined in multiple\n\
696 puts ("-x, --cxref\n\
697 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
698 The output uses line numbers instead of page numbers, but\n\
699 beyond that the differences are cosmetic; try both to see\n\
703 puts ("-V, --version\n\
704 Print the version of the program.\n\
706 Print this help message.");
708 print_language_names ();
711 puts ("Report bugs to bug-gnu-emacs@gnu.org");
725 /* This structure helps us allow mixing of --lang and file names. */
728 enum argument_type arg_type;
730 language *lang; /* language of the regexp */
733 #ifdef VMS /* VMS specific functions */
737 /* This is a BUG! ANY arbitrary limit is a BUG!
738 Won't someone please fix this? */
739 #define MAX_FILE_SPEC_LEN 255
742 char body[MAX_FILE_SPEC_LEN + 1];
746 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
747 returning in each successive call the next file name matching the input
748 spec. The function expects that each in_spec passed
749 to it will be processed to completion; in particular, up to and
750 including the call following that in which the last matching name
751 is returned, the function ignores the value of in_spec, and will
752 only start processing a new spec with the following call.
753 If an error occurs, on return out_spec contains the value
754 of in_spec when the error occurred.
756 With each successive file name returned in out_spec, the
757 function's return value is one. When there are no more matching
758 names the function returns zero. If on the first call no file
759 matches in_spec, or there is any other error, -1 is returned.
764 #define OUTSIZE MAX_FILE_SPEC_LEN
770 static long context = 0;
771 static struct dsc$descriptor_s o;
772 static struct dsc$descriptor_s i;
773 static bool pass1 = TRUE;
780 o.dsc$a_pointer = (char *) out;
781 o.dsc$w_length = (short)OUTSIZE;
782 i.dsc$a_pointer = in;
783 i.dsc$w_length = (short)strlen(in);
784 i.dsc$b_dtype = DSC$K_DTYPE_T;
785 i.dsc$b_class = DSC$K_CLASS_S;
786 o.dsc$b_dtype = DSC$K_DTYPE_VT;
787 o.dsc$b_class = DSC$K_CLASS_VS;
789 if ((status = lib$find_file(&i, &o, &context, 0, 0)) == RMS$_NORMAL)
791 out->body[out->curlen] = EOS;
794 else if (status == RMS$_NMF)
798 strcpy(out->body, in);
801 lib$find_file_end(&context);
807 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
808 name of each file specified by the provided arg expanding wildcards.
811 gfnames (arg, p_error)
815 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
817 switch (fn_exp (&filename, arg))
821 return filename.body;
827 return filename.body;
831 #ifndef OLD /* Newer versions of VMS do provide `system'. */
835 error ("%s", "system() function not implemented under VMS");
839 #define VERSION_DELIM ';'
840 char *massage_name (s)
846 if (*s == VERSION_DELIM)
864 unsigned int nincluded_files;
865 char **included_files;
868 int current_arg, file_count;
869 linebuffer filename_lb;
875 _fmode = O_BINARY; /* all of files are treated as binary files */
880 included_files = xnew (argc, char *);
884 /* Allocate enough no matter what happens. Overkill, but each one
886 argbuffer = xnew (argc, argument);
889 /* Set syntax for regular expression routines. */
890 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS);
891 /* Translation table for case-insensitive search. */
892 for (i = 0; i < CHAR_SET_SIZE; i++)
893 lc_trans[i] = lowcase (i);
894 #endif /* ETAGS_REGEXPS */
897 * If etags, always find typedefs and structure tags. Why not?
898 * Also default is to find macro constants, enum constants and
903 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
914 optstring = "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
916 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH";
917 #endif /* ETAGS_REGEXPS */
920 optstring = optstring + 1;
921 #endif /* LONG_OPTIONS */
923 opt = getopt_long (argc, argv, optstring, longopts, 0);
930 /* If getopt returns 0, then it has already processed a
931 long-named option. We should do nothing. */
935 /* This means that a file name has been seen. Record it. */
936 argbuffer[current_arg].arg_type = at_filename;
937 argbuffer[current_arg].what = optarg;
942 /* Common options. */
943 case 'a': append_to_tagfile = TRUE; break;
944 case 'C': cplusplus = TRUE; break;
945 case 'd': constantypedefs = TRUE; break;
946 case 'D': constantypedefs = FALSE; break;
947 case 'f': /* for compatibility with old makefiles */
951 error ("-o option may only be given once.", (char *)NULL);
952 suggest_asking_for_help ();
957 case 'S': /* for backward compatibility */
958 noindentypedefs = TRUE;
962 language *lang = get_language_from_name (optarg);
965 argbuffer[current_arg].lang = lang;
966 argbuffer[current_arg].arg_type = at_language;
973 argbuffer[current_arg].arg_type = at_regexp;
974 argbuffer[current_arg].what = optarg;
978 argbuffer[current_arg].arg_type = at_regexp;
979 argbuffer[current_arg].what = NULL;
983 argbuffer[current_arg].arg_type = at_icregexp;
984 argbuffer[current_arg].what = optarg;
987 #endif /* ETAGS_REGEXPS */
999 typedefs = typedefs_and_cplusplus = TRUE;
1004 included_files[nincluded_files++] = optarg;
1007 /* Ctags options. */
1008 case 'B': searchar = '?'; break;
1009 case 'u': update = TRUE; break;
1010 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1011 case 'x': cxref_style = TRUE; break;
1012 case 'w': no_warnings = TRUE; break;
1015 suggest_asking_for_help ();
1019 for (; optind < argc; ++optind)
1021 argbuffer[current_arg].arg_type = at_filename;
1022 argbuffer[current_arg].what = argv[optind];
1027 if (nincluded_files == 0 && file_count == 0)
1029 error ("no input files specified.", (char *)NULL);
1030 suggest_asking_for_help ();
1033 if (tagfile == NULL)
1034 tagfile = CTAGS ? "tags" : "TAGS";
1035 cwd = etags_getcwd (); /* the current working directory */
1036 if (cwd[strlen (cwd) - 1] != '/')
1039 cwd = concat (oldcwd, "/", "");
1042 if (streq (tagfile, "-"))
1045 tagfiledir = absolute_dirname (tagfile, cwd);
1047 init (); /* set up boolean "functions" */
1050 initbuffer (&token_name);
1051 initbuffer (&lbs[0].lb);
1052 initbuffer (&lbs[1].lb);
1053 initbuffer (&filename_lb);
1057 if (streq (tagfile, "-"))
1061 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1062 doesn't take effect until after `stdout' is already open). */
1063 if (!isatty (fileno (stdout)))
1064 setmode (fileno (stdout), O_BINARY);
1068 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1074 * Loop through files finding functions.
1076 for (i = 0; i < current_arg; ++i)
1078 switch (argbuffer[i].arg_type)
1081 forced_lang = argbuffer[i].lang;
1083 #ifdef ETAGS_REGEXPS
1085 analyse_regex (argbuffer[i].what, FALSE);
1088 analyse_regex (argbuffer[i].what, TRUE);
1093 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1097 error ("can't find file %s\n", this_file);
1102 this_file = massage_name (this_file);
1105 this_file = argbuffer[i].what;
1107 /* Input file named "-" means read file names from stdin
1108 (one per line) and use them. */
1109 if (streq (this_file, "-"))
1110 while (readline_internal (&filename_lb, stdin) > 0)
1111 process_file (filename_lb.buffer);
1113 process_file (this_file);
1121 #ifdef ETAGS_REGEXPS
1123 #endif /* ETAGS_REGEXPS */
1127 while (nincluded_files-- > 0)
1128 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1134 /* If CTAGS, we are here. process_file did not write the tags yet,
1135 because we want them ordered. Let's do it now. */
1147 for (i = 0; i < current_arg; ++i)
1149 if (argbuffer[i].arg_type != at_filename)
1152 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1153 tagfile, argbuffer[i].what, tagfile);
1154 if (system (cmd) != GOOD)
1155 fatal ("failed to execute shell command", (char *)NULL);
1157 append_to_tagfile = TRUE;
1160 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1171 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1172 exit (system (cmd));
1180 * Return a compressor given the file name. If EXTPTR is non-zero,
1181 * return a pointer into FILE where the compressor-specific
1182 * extension begins. If no compressor is found, NULL is returned
1183 * and EXTPTR is not significant.
1184 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca>
1187 get_compressor_from_suffix (file, extptr)
1192 char *slash, *suffix;
1194 /* This relies on FN to be after canonicalize_filename,
1195 so we don't need to consider backslashes on DOS_NT. */
1196 slash = etags_strrchr (file, '/');
1197 suffix = etags_strrchr (file, '.');
1198 if (suffix == NULL || suffix < slash)
1203 /* Let those poor souls who live with DOS 8+3 file name limits get
1204 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1205 Only the first do loop is run if not MSDOS */
1209 for (compr = compressors; compr->suffix != NULL; compr++)
1210 if (streq (compr->suffix, suffix))
1214 } while (*suffix != '\0');
1216 for (compr = compressors; compr->suffix != NULL; compr++)
1217 if (streq (compr->suffix, suffix))
1227 * Return a language given the name.
1230 get_language_from_name (name)
1236 error ("empty language name", (char *)NULL);
1239 for (lang = lang_names; lang->name != NULL; lang++)
1240 if (streq (name, lang->name))
1242 error ("unknown language \"%s\"", name);
1250 * Return a language given the interpreter name.
1253 get_language_from_interpreter (interpreter)
1259 if (interpreter == NULL)
1261 for (lang = lang_names; lang->name != NULL; lang++)
1262 if (lang->interpreters != NULL)
1263 for (iname = lang->interpreters; *iname != NULL; iname++)
1264 if (streq (*iname, interpreter))
1273 * Return a language given the file name.
1276 get_language_from_suffix (file)
1280 char **ext, *suffix;
1282 suffix = etags_strrchr (file, '.');
1286 for (lang = lang_names; lang->name != NULL; lang++)
1287 if (lang->suffixes != NULL)
1288 for (ext = lang->suffixes; *ext != NULL; ext++)
1289 if (streq (*ext, suffix))
1297 * This routine is called on each file argument.
1303 struct stat stat_buf;
1306 char *compressed_name, *uncompressed_name;
1307 char *ext, *real_name;
1310 canonicalize_filename (file);
1311 if (streq (file, tagfile) && !streq (tagfile, "-"))
1313 error ("skipping inclusion of %s in self.", file);
1316 if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
1318 compressed_name = NULL;
1319 real_name = uncompressed_name = savestr (file);
1323 real_name = compressed_name = savestr (file);
1324 uncompressed_name = savenstr (file, ext - file);
1327 /* If the canonicalised uncompressed name has already be dealt with,
1328 skip it silently, else add it to the list. */
1330 typedef struct processed_file
1333 struct processed_file *next;
1335 static processed_file *pf_head = NULL;
1336 register processed_file *fnp;
1338 for (fnp = pf_head; fnp != NULL; fnp = fnp->next)
1339 if (streq (uncompressed_name, fnp->filename))
1342 pf_head = xnew (1, struct processed_file);
1343 pf_head->filename = savestr (uncompressed_name);
1344 pf_head->next = fnp;
1347 if (stat (real_name, &stat_buf) != 0)
1349 /* Reset real_name and try with a different name. */
1351 if (compressed_name != NULL) /* try with the given suffix */
1353 if (stat (uncompressed_name, &stat_buf) == 0)
1354 real_name = uncompressed_name;
1356 else /* try all possible suffixes */
1358 for (compr = compressors; compr->suffix != NULL; compr++)
1360 compressed_name = concat (file, ".", compr->suffix);
1361 if (stat (compressed_name, &stat_buf) != 0)
1364 char *suf = compressed_name + strlen (file);
1365 size_t suflen = strlen (compr->suffix) + 1;
1366 for ( ; suf[1]; suf++, suflen--)
1368 memmove (suf, suf + 1, suflen);
1369 if (stat (compressed_name, &stat_buf) == 0)
1371 real_name = compressed_name;
1375 if (real_name != NULL)
1378 free (compressed_name);
1379 compressed_name = NULL;
1383 real_name = compressed_name;
1388 if (real_name == NULL)
1393 } /* try with a different name */
1395 if (!S_ISREG (stat_buf.st_mode))
1397 error ("skipping %s: it is not a regular file.", real_name);
1400 if (real_name == compressed_name)
1402 char *cmd = concat (compr->command, " ", real_name);
1403 inf = popen (cmd, "r");
1407 inf = fopen (real_name, "r");
1414 find_entries (uncompressed_name, inf);
1416 if (real_name == compressed_name)
1425 if (filename_is_absolute (uncompressed_name))
1427 /* file is an absolute file name. Canonicalise it. */
1428 filename = absolute_filename (uncompressed_name, cwd);
1432 /* file is a file name relative to cwd. Make it relative
1433 to the directory of the tags file. */
1434 filename = relative_filename (uncompressed_name, tagfiledir);
1436 fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head));
1444 if (compressed_name) free(compressed_name);
1445 if (uncompressed_name) free(uncompressed_name);
1450 * This routine sets up the boolean pseudo-functions which work
1451 * by setting boolean flags dependent upon the corresponding character.
1452 * Every char which is NOT in that string is not a white char. Therefore,
1453 * all of the array "_wht" is set to FALSE, and then the elements
1454 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1455 * of a char is TRUE if it is the string "white", else FALSE.
1463 for (i = 0; i < CHARS; i++)
1464 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE;
1465 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
1466 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
1467 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
1468 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
1469 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
1470 iswhite('\0') = iswhite('\n');
1471 notinname('\0') = notinname('\n');
1472 begtoken('\0') = begtoken('\n');
1473 intoken('\0') = intoken('\n');
1474 endtoken('\0') = endtoken('\n');
1478 * This routine opens the specified file and calls the function
1479 * which finds the function and type definitions.
1481 node *last_node = NULL;
1484 find_entries (file, inf)
1490 node *old_last_node;
1492 /* Memory leakage here: the string pointed by curfile is
1493 never released, because curfile is copied into np->file
1494 for each node, to be used in CTAGS mode. The amount of
1495 memory leaked here is the sum of the lengths of the
1497 curfile = savestr (file);
1499 /* If user specified a language, use it. */
1501 if (lang != NULL && lang->function != NULL)
1504 lang->function (inf);
1508 /* Try to guess the language given the file name. */
1509 lang = get_language_from_suffix (file);
1510 if (lang != NULL && lang->function != NULL)
1513 lang->function (inf);
1517 /* Look for sharp-bang as the first two characters. */
1518 if (readline_internal (&lb, inf) > 0
1520 && lb.buffer[0] == '#'
1521 && lb.buffer[1] == '!')
1525 /* Set lp to point at the first char after the last slash in the
1526 line or, if no slashes, at the first nonblank. Then set cp to
1527 the first successive blank and terminate the string. */
1528 lp = etags_strrchr (lb.buffer+2, '/');
1532 lp = skip_spaces (lb.buffer + 2);
1533 cp = skip_non_spaces (lp);
1536 if (strlen (lp) > 0)
1538 lang = get_language_from_interpreter (lp);
1539 if (lang != NULL && lang->function != NULL)
1542 lang->function (inf);
1547 /* We rewind here, even if inf may be a pipe. We fail if the
1548 length of the first line is longer than the pipe block size,
1549 which is unlikely. */
1553 old_last_node = last_node;
1554 curlang = get_language_from_name ("fortran");
1555 Fortran_functions (inf);
1557 /* No Fortran entries found. Try C. */
1558 if (old_last_node == last_node)
1560 /* We do not tag if rewind fails.
1561 Only the file name will be recorded in the tags file. */
1563 curlang = get_language_from_name (cplusplus ? "c++" : "c");
1564 default_C_entries (inf);
1571 pfnote (name, is_func, linestart, linelen, lno, cno)
1572 char *name; /* tag name, or NULL if unnamed */
1573 bool is_func; /* tag is a function */
1574 char *linestart; /* start of the line where tag is */
1575 int linelen; /* length of the line where tag is */
1576 int lno; /* line number */
1577 long cno; /* character number */
1581 if (CTAGS && name == NULL)
1584 np = xnew (1, node);
1586 /* If ctags mode, change name "main" to M<thisfilename>. */
1587 if (CTAGS && !cxref_style && streq (name, "main"))
1589 register char *fp = etags_strrchr (curfile, '/');
1590 np->name = concat ("M", fp == NULL ? curfile : fp + 1, "");
1591 fp = etags_strrchr (np->name, '.');
1592 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1597 np->been_warned = FALSE;
1599 np->is_func = is_func;
1601 /* Our char numbers are 0-base, because of C language tradition?
1602 ctags compatibility? old versions compatibility? I don't know.
1603 Anyway, since emacs's are 1-base we expect etags.el to take care
1604 of the difference. If we wanted to have 1-based numbers, we would
1605 uncomment the +1 below. */
1606 np->cno = cno /* + 1 */ ;
1607 np->left = np->right = NULL;
1608 if (CTAGS && !cxref_style)
1610 if (strlen (linestart) < 50)
1611 np->pat = concat (linestart, "$", "");
1613 np->pat = savenstr (linestart, 50);
1616 np->pat = savenstr (linestart, linelen);
1618 add_node (np, &head);
1621 /* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997]
1622 * From: Sam Kendall <kendall@mv.mv.com>
1623 * Subject: Proposal for firming up the TAGS format specification
1624 * To: F.Potorti@cnuce.cnr.it
1626 * pfnote should emit the optimized form [unnamed tag] only if:
1627 * 1. name does not contain any of the characters " \t\r\n(),;";
1628 * 2. linestart contains name as either a rightmost, or rightmost but
1629 * one character, substring;
1630 * 3. the character, if any, immediately before name in linestart must
1631 * be one of the characters " \t(),;";
1632 * 4. the character, if any, immediately after name in linestart must
1633 * also be one of the characters " \t(),;".
1635 * The real implementation uses the notinname() macro, which recognises
1636 * characters slightly different form " \t\r\n(),;". See the variable
1639 #define traditional_tag_style TRUE
1641 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno)
1642 char *name; /* tag name, or NULL if unnamed */
1643 int namelen; /* tag length */
1644 bool is_func; /* tag is a function */
1645 char *linestart; /* start of the line where tag is */
1646 int linelen; /* length of the line where tag is */
1647 int lno; /* line number */
1648 long cno; /* character number */
1656 for (cp = name; !notinname (*cp); cp++)
1658 if (*cp == '\0') /* rule #1 */
1660 cp = linestart + linelen - namelen;
1661 if (notinname (linestart[linelen-1]))
1662 cp -= 1; /* rule #4 */
1663 if (cp >= linestart /* rule #2 */
1665 || notinname (cp[-1])) /* rule #3 */
1666 && strneq (name, cp, namelen)) /* rule #2 */
1667 named = FALSE; /* use unnamed tag */
1672 name = savenstr (name, namelen);
1675 pfnote (name, is_func, linestart, linelen, lno, cno);
1680 * recurse on left children, iterate on right children.
1688 register node *node_right = np->right;
1689 free_tree (np->left);
1690 if (np->name != NULL)
1700 * Adds a node to the tree of nodes. In etags mode, we don't keep
1701 * it sorted; we just keep a linear list. In ctags mode, maintain
1702 * an ordered tree, with no attempt at balancing.
1704 * add_node is the only function allowed to add nodes, so it can
1708 add_node (np, cur_node_p)
1709 node *np, **cur_node_p;
1712 register node *cur_node = *cur_node_p;
1714 if (cur_node == NULL)
1724 if (last_node == NULL)
1725 fatal ("internal error in add_node", (char *)NULL);
1726 last_node->right = np;
1732 dif = strcmp (np->name, cur_node->name);
1735 * If this tag name matches an existing one, then
1736 * do not add the node, but maybe print a warning.
1740 if (streq (np->file, cur_node->file))
1744 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
1745 np->file, lineno, np->name);
1746 fprintf (stderr, "Second entry ignored\n");
1749 else if (!cur_node->been_warned && !no_warnings)
1753 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1754 np->file, cur_node->file, np->name);
1755 cur_node->been_warned = TRUE;
1760 /* Actually add the node */
1761 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1774 /* Output subentries that precede this one */
1775 put_entries (np->left);
1777 /* Output this entry */
1781 if (np->name != NULL)
1782 fprintf (tagf, "%s\177%s\001%d,%ld\n",
1783 np->pat, np->name, np->lno, np->cno);
1785 fprintf (tagf, "%s\177%d,%ld\n",
1786 np->pat, np->lno, np->cno);
1790 if (np->name == NULL)
1791 error ("internal error: NULL name in ctags mode.", (char *)NULL);
1796 fprintf (stdout, "%s %s %d\n",
1797 np->name, np->file, (np->lno + 63) / 64);
1799 fprintf (stdout, "%-16s %3d %-16s %s\n",
1800 np->name, np->lno, np->file, np->pat);
1804 fprintf (tagf, "%s\t%s\t", np->name, np->file);
1808 putc (searchar, tagf);
1811 for (sp = np->pat; *sp; sp++)
1813 if (*sp == '\\' || *sp == searchar)
1817 putc (searchar, tagf);
1820 { /* a typedef; text pattern inadequate */
1821 fprintf (tagf, "%d", np->lno);
1827 /* Output subentries that follow this one */
1828 put_entries (np->right);
1831 /* Length of a number's decimal representation. */
1837 while ((num /= 10) > 0)
1843 * Return total number of characters that put_entries will output for
1844 * the nodes in the subtree of the specified node. Works only if
1845 * we are not ctags, but called only in that case. This count
1846 * is irrelevant with the new tags.el, but is still supplied for
1847 * backward compatibility.
1850 total_size_of_entries (np)
1858 for (total = 0; np != NULL; np = np->right)
1860 /* Count left subentries. */
1861 total += total_size_of_entries (np->left);
1863 /* Count this entry */
1864 total += strlen (np->pat) + 1;
1865 total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1;
1866 if (np->name != NULL)
1867 total += 1 + strlen (np->name); /* \001name */
1874 * The C symbol tables.
1879 st_C_objprot, st_C_objimpl, st_C_objend,
1884 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1887 /* Feed stuff between (but not including) %[ and %] lines to:
1888 gperf -c -k 1,3 -o -p -r -t
1890 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1894 while, 0, st_C_ignore
1895 switch, 0, st_C_ignore
1896 return, 0, st_C_ignore
1897 @interface, 0, st_C_objprot
1898 @protocol, 0, st_C_objprot
1899 @implementation,0, st_C_objimpl
1900 @end, 0, st_C_objend
1901 import, C_JAVA, st_C_ignore
1902 package, C_JAVA, st_C_ignore
1903 friend, C_PLPL, st_C_ignore
1904 extends, C_JAVA, st_C_javastruct
1905 implements, C_JAVA, st_C_javastruct
1906 interface, C_JAVA, st_C_struct
1907 class, C_PLPL, st_C_struct
1908 namespace, C_PLPL, st_C_struct
1909 domain, C_STAR, st_C_struct
1910 union, 0, st_C_struct
1911 struct, 0, st_C_struct
1912 extern, 0, st_C_extern
1914 typedef, 0, st_C_typedef
1915 define, 0, st_C_define
1916 operator, C_PLPL, st_C_operator
1917 bool, C_PLPL, st_C_typespec
1918 long, 0, st_C_typespec
1919 short, 0, st_C_typespec
1920 int, 0, st_C_typespec
1921 char, 0, st_C_typespec
1922 float, 0, st_C_typespec
1923 double, 0, st_C_typespec
1924 signed, 0, st_C_typespec
1925 unsigned, 0, st_C_typespec
1926 auto, 0, st_C_typespec
1927 void, 0, st_C_typespec
1928 static, 0, st_C_typespec
1929 const, 0, st_C_typespec
1930 volatile, 0, st_C_typespec
1931 explicit, C_PLPL, st_C_typespec
1932 mutable, C_PLPL, st_C_typespec
1933 typename, C_PLPL, st_C_typespec
1934 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1935 DEFUN, 0, st_C_gnumacro
1936 SYSCALL, 0, st_C_gnumacro
1937 ENTRY, 0, st_C_gnumacro
1938 PSEUDO, 0, st_C_gnumacro
1939 # These are defined inside C functions, so currently they are not met.
1940 # EXFUN used in glibc, DEFVAR_* in emacs.
1941 #EXFUN, 0, st_C_gnumacro
1942 #DEFVAR_, 0, st_C_gnumacro
1944 and replace lines between %< and %> with its output. */
1946 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
1947 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1948 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1950 #define TOTAL_KEYWORDS 46
1951 #define MIN_WORD_LENGTH 2
1952 #define MAX_WORD_LENGTH 15
1953 #define MIN_HASH_VALUE 13
1954 #define MAX_HASH_VALUE 123
1955 /* maximum key range = 111, duplicates = 0 */
1962 register const char *str;
1963 register unsigned int len;
1965 static unsigned char asso_values[] =
1967 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1968 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1969 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1970 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1971 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1972 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1973 124, 124, 124, 124, 3, 124, 124, 124, 43, 6,
1974 11, 124, 124, 124, 124, 124, 124, 124, 124, 124,
1975 11, 124, 124, 58, 7, 124, 124, 124, 124, 124,
1976 124, 124, 124, 124, 124, 124, 124, 57, 7, 42,
1977 4, 14, 52, 0, 124, 53, 124, 124, 29, 11,
1978 6, 35, 32, 124, 29, 34, 59, 58, 51, 24,
1979 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
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
1994 register int hval = len;
2000 hval += asso_values[(unsigned char)str[2]];
2003 hval += asso_values[(unsigned char)str[0]];
2012 static struct C_stab_entry *
2013 in_word_set (str, len)
2014 register const char *str;
2015 register unsigned int len;
2017 static struct C_stab_entry wordlist[] =
2019 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2020 {""}, {""}, {""}, {""},
2021 {"@end", 0, st_C_objend},
2022 {""}, {""}, {""}, {""},
2023 {"ENTRY", 0, st_C_gnumacro},
2024 {"@interface", 0, st_C_objprot},
2026 {"domain", C_STAR, st_C_struct},
2028 {"PSEUDO", 0, st_C_gnumacro},
2030 {"namespace", C_PLPL, st_C_struct},
2032 {"@implementation",0, st_C_objimpl},
2033 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2034 {"long", 0, st_C_typespec},
2035 {"signed", 0, st_C_typespec},
2036 {"@protocol", 0, st_C_objprot},
2037 {""}, {""}, {""}, {""},
2038 {"bool", C_PLPL, st_C_typespec},
2039 {""}, {""}, {""}, {""}, {""}, {""},
2040 {"const", 0, st_C_typespec},
2041 {"explicit", C_PLPL, st_C_typespec},
2042 {"if", 0, st_C_ignore},
2044 {"operator", C_PLPL, st_C_operator},
2046 {"DEFUN", 0, st_C_gnumacro},
2048 {"define", 0, st_C_define},
2049 {""}, {""}, {""}, {""}, {""},
2050 {"double", 0, st_C_typespec},
2051 {"struct", 0, st_C_struct},
2052 {""}, {""}, {""}, {""},
2053 {"short", 0, st_C_typespec},
2055 {"enum", 0, st_C_enum},
2056 {"mutable", C_PLPL, st_C_typespec},
2058 {"extern", 0, st_C_extern},
2059 {"extends", C_JAVA, st_C_javastruct},
2060 {"package", C_JAVA, st_C_ignore},
2061 {"while", 0, st_C_ignore},
2063 {"for", 0, st_C_ignore},
2065 {"volatile", 0, st_C_typespec},
2067 {"import", C_JAVA, st_C_ignore},
2068 {"float", 0, st_C_typespec},
2069 {"switch", 0, st_C_ignore},
2070 {"return", 0, st_C_ignore},
2071 {"implements", C_JAVA, st_C_javastruct},
2073 {"static", 0, st_C_typespec},
2074 {"typedef", 0, st_C_typedef},
2075 {"typename", C_PLPL, st_C_typespec},
2076 {"unsigned", 0, st_C_typespec},
2078 {"char", 0, st_C_typespec},
2079 {"class", C_PLPL, st_C_struct},
2081 {"void", 0, st_C_typespec},
2083 {"friend", C_PLPL, st_C_ignore},
2085 {"int", 0, st_C_typespec},
2086 {"union", 0, st_C_struct},
2088 {"auto", 0, st_C_typespec},
2089 {"interface", C_JAVA, st_C_struct},
2091 {"SYSCALL", 0, st_C_gnumacro}
2094 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
2096 register int key = hash (str, len);
2098 if (key <= MAX_HASH_VALUE && key >= 0)
2100 register const char *s = wordlist[key].name;
2102 if (*str == *s && !strncmp (str + 1, s + 1, len - 1))
2103 return &wordlist[key];
2110 static enum sym_type
2111 C_symtype (str, len, c_ext)
2116 register struct C_stab_entry *se = in_word_set (str, len);
2118 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
2124 * C functions and variables are recognized using a simple
2125 * finite automaton. fvdef is its state variable.
2129 fvnone, /* nothing seen */
2130 foperator, /* func: operator keyword seen (cplpl) */
2131 fvnameseen, /* function or variable name seen */
2132 fstartlist, /* func: just after open parenthesis */
2133 finlist, /* func: in parameter list */
2134 flistseen, /* func: after parameter list */
2135 fignore, /* func: before open brace */
2136 vignore /* var-like: ignore until ';' */
2139 bool fvextern; /* func or var: extern keyword seen; */
2142 * typedefs are recognized using a simple finite automaton.
2143 * typdef is its state variable.
2147 tnone, /* nothing seen */
2148 tkeyseen, /* typedef keyword seen */
2149 ttypeseen, /* defined type seen */
2150 tinbody, /* inside typedef body */
2151 tend, /* just before typedef tag */
2152 tignore /* junk after typedef tag */
2157 * struct-like structures (enum, struct and union) are recognized
2158 * using another simple finite automaton. `structdef' is its state
2163 snone, /* nothing seen yet */
2164 skeyseen, /* struct-like keyword seen */
2165 stagseen, /* struct-like tag seen */
2166 scolonseen, /* colon seen after struct-like tag */
2167 sinbody /* in struct body: recognize member func defs*/
2171 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
2172 * struct tag, and structtype is the type of the preceding struct-like
2175 char *structtag = "<uninited>";
2176 enum sym_type structtype;
2179 * When objdef is different from onone, objtag is the name of the class.
2181 char *objtag = "<uninited>";
2184 * Yet another little state machine to deal with preprocessor lines.
2188 dnone, /* nothing seen */
2189 dsharpseen, /* '#' seen as first char on line */
2190 ddefineseen, /* '#' and 'define' seen */
2191 dignorerest /* ignore rest of line */
2195 * State machine for Objective C protocols and implementations.
2196 * Tom R.Hageman <tom@basil.icce.rug.nl>
2200 onone, /* nothing seen */
2201 oprotocol, /* @interface or @protocol seen */
2202 oimplementation, /* @implementations seen */
2203 otagseen, /* class name seen */
2204 oparenseen, /* parenthesis before category seen */
2205 ocatseen, /* category name seen */
2206 oinbody, /* in @implementation body */
2207 omethodsign, /* in @implementation body, after +/- */
2208 omethodtag, /* after method name */
2209 omethodcolon, /* after method colon */
2210 omethodparm, /* after method parameter */
2211 oignore /* wait for @end */
2216 * Use this structure to keep info about the token read, and how it
2217 * should be tagged. Used by the make_C_tag function to build a tag.
2230 token tok; /* latest token read */
2233 * Set this to TRUE, and the next token considered is called a function.
2234 * Used only for GNU emacs's function-defining macros.
2236 bool next_token_is_func;
2239 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
2244 * methodlen is the length of the method name stored in token_name.
2250 * checks to see if the current token is at the start of a
2251 * function or variable, or corresponds to a typedef, or
2252 * is a struct/union/enum tag, or #define, or an enum constant.
2254 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2255 * with args. C_EXT is which language we are looking at.
2263 * next_token_is_func IN OUT
2267 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2268 register char *str; /* IN: token pointer */
2269 register int len; /* IN: token length */
2270 register char c; /* IN: first char after the token */
2271 int c_ext; /* IN: C extensions mask */
2272 int cblev; /* IN: curly brace level */
2273 int parlev; /* IN: parenthesis level */
2274 bool *is_func_or_var; /* OUT: function or variable found */
2276 enum sym_type toktype = C_symtype (str, len, c_ext);
2279 * Advance the definedef state machine.
2284 /* We're not on a preprocessor line. */
2287 if (toktype == st_C_define)
2289 definedef = ddefineseen;
2293 definedef = dignorerest;
2298 * Make a tag for any macro, unless it is a constant
2299 * and constantypedefs is FALSE.
2301 definedef = dignorerest;
2302 *is_func_or_var = (c == '(');
2303 if (!*is_func_or_var && !constantypedefs)
2310 error ("internal error: definedef value.", (char *)NULL);
2319 if (toktype == st_C_typedef)
2338 /* Do not return here, so the structdef stuff has a chance. */
2352 * This structdef business is currently only invoked when cblev==0.
2353 * It should be recursively invoked whatever the curly brace level,
2354 * and a stack of states kept, to allow for definitions of structs
2357 * This structdef business is NOT invoked when we are ctags and the
2358 * file is plain C. This is because a struct tag may have the same
2359 * name as another tag, and this loses with ctags.
2363 case st_C_javastruct:
2364 if (structdef == stagseen)
2365 structdef = scolonseen;
2369 if (typdef == tkeyseen
2370 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone))
2372 structdef = skeyseen;
2373 structtype = toktype;
2378 if (structdef == skeyseen)
2380 /* Save the tag for struct/union/class, for functions and variables
2381 that may be defined inside. */
2382 if (structtype == st_C_struct)
2383 structtag = savenstr (str, len);
2385 structtag = "<enum>";
2386 structdef = stagseen;
2390 if (typdef != tnone)
2393 /* Detect GNU macros.
2395 Writers of emacs code are recommended to put the
2396 first two args of a DEFUN on the same line.
2398 The DEFUN macro, used in emacs C source code, has a first arg
2399 that is a string (the lisp function name), and a second arg that
2400 is a C function name. Since etags skips strings, the second arg
2401 is tagged. This is unfortunate, as it would be better to tag the
2402 first arg. The simplest way to deal with this problem would be
2403 to name the tag with a name built from the function name, by
2404 removing the initial 'F' character and substituting '-' for '_'.
2405 Anyway, this assumes that the conventions of naming lisp
2406 functions will never change. Currently, this method is not
2408 if (definedef == dnone && toktype == st_C_gnumacro)
2410 next_token_is_func = TRUE;
2413 if (next_token_is_func)
2415 next_token_is_func = FALSE;
2417 *is_func_or_var = TRUE;
2421 /* Detect Objective C constructs. */
2431 objdef = oimplementation;
2435 case oimplementation:
2436 /* Save the class tag for functions or variables defined inside. */
2437 objtag = savenstr (str, len);
2441 /* Save the class tag for categories. */
2442 objtag = savenstr (str, len);
2444 *is_func_or_var = TRUE;
2448 *is_func_or_var = TRUE;
2455 objdef = omethodtag;
2457 grow_linebuffer (&token_name, methodlen + 1);
2458 strncpy (token_name.buffer, str, len);
2459 token_name.buffer[methodlen] = '\0';
2460 token_name.len = methodlen;
2466 objdef = omethodparm;
2471 objdef = omethodtag;
2473 grow_linebuffer (&token_name, methodlen + 1);
2474 strncat (token_name.buffer, str, len);
2475 token_name.len = methodlen;
2480 if (toktype == st_C_objend)
2482 /* Memory leakage here: the string pointed by objtag is
2483 never released, because many tests would be needed to
2484 avoid breaking on incorrect input code. The amount of
2485 memory leaked here is the sum of the lengths of the
2493 /* A function, variable or enum constant? */
2500 if (fvdef != finlist && fvdef != fignore && fvdef != vignore)
2501 fvdef = fvnone; /* should be useless */
2509 *is_func_or_var = TRUE;
2512 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10))
2515 *is_func_or_var = TRUE;
2518 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2520 if (fvdef == fvnone)
2522 fvdef = fvnameseen; /* function or variable */
2523 *is_func_or_var = TRUE;
2534 * This routine finds functions, variables, typedefs,
2535 * #define's, enum constants and struct/union/enum definitions in
2536 * C syntax and adds them to the list.
2538 #define current_lb_is_new (newndx == curndx)
2539 #define switch_line_buffers() (curndx = 1 - curndx)
2541 #define curlb (lbs[curndx].lb)
2542 #define othlb (lbs[1-curndx].lb)
2543 #define newlb (lbs[newndx].lb)
2544 #define curlinepos (lbs[curndx].linepos)
2545 #define othlinepos (lbs[1-curndx].linepos)
2546 #define newlinepos (lbs[newndx].linepos)
2548 #define CNL_SAVE_DEFINEDEF() \
2550 curlinepos = charno; \
2552 linecharno = charno; \
2553 charno += readline (&curlb, inf); \
2554 lp = curlb.buffer; \
2561 CNL_SAVE_DEFINEDEF(); \
2562 if (savetok.valid) \
2565 savetok.valid = FALSE; \
2567 definedef = dnone; \
2575 /* This function should never be called when tok.valid is FALSE, but
2576 we must protect against invalid input or internal errors. */
2579 if (traditional_tag_style)
2581 /* This was the original code. Now we call new_pfnote instead,
2582 which uses the new method for naming tags (see new_pfnote). */
2585 if (CTAGS || tok.named)
2586 name = savestr (token_name.buffer);
2587 pfnote (name, isfun,
2588 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2591 new_pfnote (token_name.buffer, token_name.len, isfun,
2592 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2601 C_entries (c_ext, inf)
2602 int c_ext; /* extension of C */
2603 FILE *inf; /* input file */
2605 register char c; /* latest char read; '\0' for end of line */
2606 register char *lp; /* pointer one beyond the character `c' */
2607 int curndx, newndx; /* indices for current and new lb */
2608 register int tokoff; /* offset in line of start of current token */
2609 register int toklen; /* length of current token */
2610 char *qualifier; /* string used to qualify names */
2611 int qlen; /* length of qualifier */
2612 int cblev; /* current curly brace level */
2613 int parlev; /* current parenthesis level */
2614 bool incomm, inquote, inchar, quotednl, midtoken;
2615 bool purec, cplpl, cjava;
2616 token savetok; /* token saved during preprocessor handling */
2619 tokoff = toklen = 0; /* keep compiler quiet */
2620 curndx = newndx = 0;
2626 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
2627 structdef = snone; definedef = dnone; objdef = onone;
2628 next_token_is_func = yacc_rules = FALSE;
2629 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2630 tok.valid = savetok.valid = FALSE;
2633 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */
2634 cplpl = (c_ext & C_PLPL) == C_PLPL;
2635 cjava = (c_ext & C_JAVA) == C_JAVA;
2637 { qualifier = "."; qlen = 1; }
2639 { qualifier = "::"; qlen = 2; }
2646 /* If we're at the end of the line, the next character is a
2647 '\0'; don't skip it, because it's the thing that tells us
2648 to read the next line. */
2669 /* Newlines inside comments do not end macro definitions in
2671 CNL_SAVE_DEFINEDEF ();
2684 /* Newlines inside strings do not end macro definitions
2685 in traditional cpp, even though compilers don't
2686 usually accept them. */
2687 CNL_SAVE_DEFINEDEF ();
2697 /* Hmmm, something went wrong. */
2711 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2719 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2732 else if (/* cplpl && */ *lp == '/')
2740 if ((c_ext & YACC) && *lp == '%')
2742 /* entering or exiting rules section in yacc file */
2744 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2745 typdef = tnone; structdef = snone;
2746 next_token_is_func = FALSE;
2747 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2749 yacc_rules = !yacc_rules;
2755 if (definedef == dnone)
2758 bool cpptoken = TRUE;
2760 /* Look back on this line. If all blanks, or nonblanks
2761 followed by an end of comment, this is a preprocessor
2763 for (cp = newlb.buffer; cp < lp-1; cp++)
2766 if (*cp == '*' && *(cp+1) == '/')
2775 definedef = dsharpseen;
2776 } /* if (definedef == dnone) */
2782 /* Consider token only if some complicated conditions are satisfied. */
2783 if ((definedef != dnone
2784 || (cblev == 0 && structdef != scolonseen)
2785 || (cblev == 1 && cplpl && structdef == sinbody)
2786 || (structdef == sinbody && purec))
2787 && typdef != tignore
2788 && definedef != dignorerest
2789 && fvdef != finlist)
2795 bool funorvar = FALSE;
2797 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1]))
2800 * This handles :: in the middle, but not at the
2801 * beginning of an identifier. Also, space-separated
2802 * :: is not recognised.
2812 || consider_token (newlb.buffer + tokoff, toklen, c,
2813 c_ext, cblev, parlev, &funorvar))
2815 if (fvdef == foperator)
2818 lp = skip_spaces (lp-1);
2822 && !isspace (*lp) && *lp != '(')
2825 toklen += lp - oldlp;
2830 && definedef == dnone
2831 && structdef == sinbody)
2832 /* function or var defined in C++ class body */
2834 int len = strlen (structtag) + qlen + toklen;
2835 grow_linebuffer (&token_name, len + 1);
2836 strcpy (token_name.buffer, structtag);
2837 strcat (token_name.buffer, qualifier);
2838 strncat (token_name.buffer,
2839 newlb.buffer + tokoff, toklen);
2840 token_name.len = len;
2843 else if (objdef == ocatseen)
2844 /* Objective C category */
2846 int len = strlen (objtag) + 2 + toklen;
2847 grow_linebuffer (&token_name, len + 1);
2848 strcpy (token_name.buffer, objtag);
2849 strcat (token_name.buffer, "(");
2850 strncat (token_name.buffer,
2851 newlb.buffer + tokoff, toklen);
2852 strcat (token_name.buffer, ")");
2853 token_name.len = len;
2856 else if (objdef == omethodtag
2857 || objdef == omethodparm)
2858 /* Objective C method */
2864 grow_linebuffer (&token_name, toklen + 1);
2865 strncpy (token_name.buffer,
2866 newlb.buffer + tokoff, toklen);
2867 token_name.buffer[toklen] = '\0';
2868 token_name.len = toklen;
2869 /* Name macros and members. */
2870 tok.named = (structdef == stagseen
2871 || typdef == ttypeseen
2874 && definedef == dignorerest)
2876 && definedef == dnone
2877 && structdef == sinbody));
2879 tok.lineno = lineno;
2880 tok.linelen = tokoff + toklen + 1;
2881 tok.buffer = newlb.buffer;
2882 tok.linepos = newlinepos;
2885 if (definedef == dnone
2886 && (fvdef == fvnameseen
2887 || fvdef == foperator
2888 || structdef == stagseen
2890 || objdef != onone))
2892 if (current_lb_is_new)
2893 switch_line_buffers ();
2896 make_C_tag (funorvar);
2900 } /* if (endtoken (c)) */
2901 else if (intoken (c))
2907 } /* if (midtoken) */
2908 else if (begtoken (c))
2919 make_C_tag (TRUE); /* a function */
2926 if (structdef == stagseen && !cjava)
2932 if (!yacc_rules || lp == newlb.buffer + 1)
2934 tokoff = lp - 1 - newlb.buffer;
2939 } /* if (begtoken) */
2940 } /* if must look at token */
2943 /* Detect end of line, colon, comma, semicolon and various braces
2944 after having handled a token.*/
2948 if (definedef != dnone)
2954 make_C_tag (TRUE); /* an Objective C class */
2958 objdef = omethodcolon;
2960 grow_linebuffer (&token_name, methodlen + 1);
2961 strcat (token_name.buffer, ":");
2962 token_name.len = methodlen;
2965 if (structdef == stagseen)
2966 structdef = scolonseen;
2973 make_C_tag (FALSE); /* a yacc function */
2984 if (definedef != dnone)
2990 make_C_tag (FALSE); /* a typedef */
3000 if ((members && cblev == 1)
3001 || (globals && cblev == 0 && (!fvextern || declarations)))
3002 make_C_tag (FALSE); /* a variable */
3008 if (declarations && (cblev == 0 || cblev == 1))
3009 make_C_tag (TRUE); /* a function declaration */
3014 /* The following instruction invalidates the token.
3015 Probably the token should be invalidated in all
3016 other cases where some state machine is reset. */
3019 if (structdef == stagseen)
3023 if (definedef != dnone)
3029 make_C_tag (TRUE); /* an Objective C method */
3041 if ((members && cblev == 1)
3042 || (globals && cblev == 0 && (!fvextern || declarations)))
3043 make_C_tag (FALSE); /* a variable */
3048 if (structdef == stagseen)
3052 if (definedef != dnone)
3054 if (cblev == 0 && typdef == tend)
3057 make_C_tag (FALSE); /* a typedef */
3068 if ((members && cblev == 1)
3069 || (globals && cblev == 0 && (!fvextern || declarations)))
3070 make_C_tag (FALSE); /* a variable */
3075 if (structdef == stagseen)
3079 if (definedef != dnone)
3081 if (objdef == otagseen && parlev == 0)
3082 objdef = oparenseen;
3086 if (typdef == ttypeseen
3089 && structdef != sinbody)
3091 /* This handles constructs like:
3092 typedef void OperatorFun (int fun); */
3107 if (definedef != dnone)
3109 if (objdef == ocatseen && parlev == 1)
3111 make_C_tag (TRUE); /* an Objective C category */
3123 if (cblev == 0 && (typdef == tend))
3126 make_C_tag (FALSE); /* a typedef */
3129 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
3133 if (definedef != dnone)
3135 if (typdef == ttypeseen)
3139 case skeyseen: /* unnamed struct */
3140 structdef = sinbody;
3141 structtag = "_anonymous_";
3144 case scolonseen: /* named struct */
3145 structdef = sinbody;
3146 make_C_tag (FALSE); /* a struct */
3152 make_C_tag (TRUE); /* a function */
3161 make_C_tag (TRUE); /* an Objective C class */
3166 make_C_tag (TRUE); /* an Objective C method */
3170 /* Neutralize `extern "C" {' grot. */
3171 if (cblev == 0 && structdef == snone && typdef == tnone)
3178 if (definedef != dnone)
3180 if (fvdef == fstartlist)
3181 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
3184 if (definedef != dnone)
3186 if (!noindentypedefs && lp == newlb.buffer + 1)
3188 cblev = 0; /* reset curly brace level if first column */
3189 parlev = 0; /* also reset paren level, just in case... */
3195 if (typdef == tinbody)
3197 /* Memory leakage here: the string pointed by structtag is
3198 never released, because I fear to miss something and
3199 break things while freeing the area. The amount of
3200 memory leaked here is the sum of the lengths of the
3202 if (structdef == sinbody)
3203 free (structtag); */
3206 structtag = "<error>";
3210 if (definedef != dnone)
3220 if ((members && cblev == 1)
3221 || (globals && cblev == 0 && (!fvextern || declarations)))
3222 make_C_tag (FALSE); /* a variable */
3230 if (objdef == oinbody && cblev == 0)
3232 objdef = omethodsign;
3236 case '#': case '~': case '&': case '%': case '/': case '|':
3237 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
3238 if (definedef != dnone)
3240 /* These surely cannot follow a function tag in C. */
3253 if (objdef == otagseen)
3255 make_C_tag (TRUE); /* an Objective C class */
3258 /* If a macro spans multiple lines don't reset its state. */
3260 CNL_SAVE_DEFINEDEF ();
3266 } /* while not eof */
3270 * Process either a C++ file or a C file depending on the setting
3274 default_C_entries (inf)
3277 C_entries (cplusplus ? C_PLPL : 0, inf);
3280 /* Always do plain ANSI C. */
3282 plain_C_entries (inf)
3288 /* Always do C++. */
3290 Cplusplus_entries (inf)
3293 C_entries (C_PLPL, inf);
3296 /* Always do Java. */
3301 C_entries (C_JAVA, inf);
3309 C_entries (C_STAR, inf);
3312 /* Always do Yacc. */
3317 C_entries (YACC, inf);
3320 /* A useful macro. */
3321 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3322 for (lineno = charno = 0; /* loop initialization */ \
3323 !feof (file_pointer) /* loop test */ \
3324 && (lineno++, /* instructions at start of loop */ \
3325 linecharno = charno, \
3326 charno += readline (&line_buffer, file_pointer), \
3327 char_pointer = lb.buffer, \
3333 * Read a file, but do no processing. This is used to do regexp
3334 * matching on files that have no language defined.
3337 just_read_file (inf)
3340 register char *dummy;
3342 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3346 /* Fortran parsing */
3352 register int len = 0;
3354 while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len]))
3356 if (*cp == '\0' && !intoken (dbp[len]))
3367 dbp = skip_spaces (dbp);
3371 dbp = skip_spaces (dbp);
3372 if (strneq (dbp, "(*)", 3))
3377 if (!isdigit (*dbp))
3379 --dbp; /* force failure */
3384 while (isdigit (*dbp));
3393 dbp = skip_spaces (dbp);
3397 linecharno = charno;
3398 charno += readline (&lb, inf);
3403 dbp = skip_spaces (dbp);
3405 if (!isalpha (*dbp) && *dbp != '_' && *dbp != '$')
3407 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
3409 pfnote (savenstr (dbp, cp-dbp), TRUE,
3410 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3415 Fortran_functions (inf)
3418 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3421 dbp++; /* Ratfor escape to fortran */
3422 dbp = skip_spaces (dbp);
3425 switch (lowcase (*dbp))
3428 if (tail ("integer"))
3436 if (tail ("logical"))
3440 if (tail ("complex") || tail ("character"))
3444 if (tail ("double"))
3446 dbp = skip_spaces (dbp);
3449 if (tail ("precision"))
3455 dbp = skip_spaces (dbp);
3458 switch (lowcase (*dbp))
3461 if (tail ("function"))
3465 if (tail ("subroutine"))
3473 if (tail ("blockdata") || tail ("block data"))
3475 dbp = skip_spaces (dbp);
3476 if (*dbp == '\0') /* assume un-named */
3477 pfnote (savestr ("blockdata"), TRUE,
3478 lb.buffer, dbp - lb.buffer, lineno, linecharno);
3480 getit (inf); /* look for name */
3488 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24
3491 /* Once we are positioned after an "interesting" keyword, let's get
3492 the real tag value necessary. */
3494 adagetit (inf, name_qualifier)
3496 char *name_qualifier;
3504 dbp = skip_spaces (dbp);
3506 || (dbp[0] == '-' && dbp[1] == '-'))
3509 linecharno = charno;
3510 charno += readline (&lb, inf);
3519 /* Skipping body of procedure body or package body or ....
3520 resetting qualifier to body instead of spec. */
3521 name_qualifier = "/b";
3527 /* Skipping type of task type or protected type ... */
3535 for (cp = dbp; *cp != '\0' && *cp != '"'; cp++)
3540 dbp = skip_spaces (dbp);
3543 && (isalpha (*cp) || isdigit (*cp) || *cp == '_' || *cp == '.'));
3551 name = concat (dbp, name_qualifier, "");
3553 pfnote (name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3564 bool inquote = FALSE;
3566 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3568 while (*dbp != '\0')
3570 /* Skip a string i.e. "abcd". */
3571 if (inquote || (*dbp == '"'))
3573 dbp = etags_strchr ((inquote) ? dbp : dbp+1, '"');
3578 continue; /* advance char */
3583 break; /* advance line */
3587 /* Skip comments. */
3588 if (dbp[0] == '-' && dbp[1] == '-')
3589 break; /* advance line */
3591 /* Skip character enclosed in single quote i.e. 'a'
3592 and skip single quote starting an attribute i.e. 'Image. */
3601 /* Search for beginning of a token. */
3602 if (!begtoken (*dbp))
3605 continue; /* advance char */
3608 /* We are at the beginning of a token. */
3613 if (!packages_only && tail ("function"))
3614 adagetit (inf, "/f");
3616 break; /* from switch */
3617 continue; /* advance char */
3620 if (!packages_only && tail ("procedure"))
3621 adagetit (inf, "/p");
3622 else if (tail ("package"))
3623 adagetit (inf, "/s");
3624 else if (tail ("protected")) /* protected type */
3625 adagetit (inf, "/t");
3627 break; /* from switch */
3628 continue; /* advance char */
3631 if (!packages_only && tail ("task"))
3632 adagetit (inf, "/k");
3633 else if (typedefs && !packages_only && tail ("type"))
3635 adagetit (inf, "/t");
3636 while (*dbp != '\0')
3640 break; /* from switch */
3641 continue; /* advance char */
3644 /* Look for the end of the token. */
3645 while (!endtoken (*dbp))
3648 } /* advance char */
3649 } /* advance line */
3653 * Bob Weiner, Motorola Inc., 4/3/94
3654 * Unix and microcontroller assembly tag handling
3655 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3663 LOOP_ON_INPUT_LINES (inf, lb, cp)
3665 /* If first char is alphabetic or one of [_.$], test for colon
3666 following identifier. */
3667 if (isalpha (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3669 /* Read past label. */
3671 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3673 if (*cp == ':' || isspace (*cp))
3675 /* Found end of label, so copy it and add it to the table. */
3676 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE,
3677 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3684 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3685 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3686 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3687 * Perl variable names: /^(my|local).../
3690 Perl_functions (inf)
3695 LOOP_ON_INPUT_LINES (inf, lb, cp)
3699 && *cp++ == 'b' && isspace (*cp++))
3701 cp = skip_spaces (cp);
3706 && !isspace (*cp) && *cp != '{' && *cp != '(')
3708 pfnote (savenstr (sp, cp-sp), TRUE,
3709 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3712 else if (globals /* only if tagging global vars is enabled */
3713 && ((cp = lb.buffer,
3722 && (*cp == '(' || isspace (*cp)))
3724 /* After "my" or "local", but before any following paren or space. */
3725 char *varname = NULL;
3727 cp = skip_spaces (cp);
3728 if (*cp == '$' || *cp == '@' || *cp == '%')
3730 char* varstart = ++cp;
3731 while (isalnum (*cp) || *cp == '_')
3733 varname = savenstr (varstart, cp-varstart);
3737 /* Should be examining a variable list at this point;
3738 could insist on seeing an open parenthesis. */
3739 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
3743 /* Perhaps I should back cp up one character, so the TAGS table
3744 doesn't mention (and so depend upon) the following char. */
3745 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
3746 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3752 * Python support by Eric S. Raymond <esr@thyrsus.com>
3753 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
3756 Python_functions (inf)
3761 LOOP_ON_INPUT_LINES (inf, lb, cp)
3765 && *cp++ == 'f' && isspace (*cp++))
3767 cp = skip_spaces (cp);
3768 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3771 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3779 && *cp++ == 's' && isspace (*cp++))
3781 cp = skip_spaces (cp);
3782 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3785 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3790 /* Idea by Corny de Souza
3791 * Cobol tag functions
3792 * We could look for anything that could be a paragraph name.
3793 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3796 Cobol_paragraphs (inf)
3799 register char *bp, *ep;
3801 LOOP_ON_INPUT_LINES (inf, lb, bp)
3807 /* If eoln, compiler option or comment ignore whole line. */
3808 if (bp[-1] != ' ' || !isalnum (bp[0]))
3811 for (ep = bp; isalnum (*ep) || *ep == '-'; ep++)
3814 pfnote (savenstr (bp, ep-bp), TRUE,
3815 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3819 /* Added by Mosur Mohan, 4/22/88 */
3820 /* Pascal parsing */
3823 * Locates tags for procedures & functions. Doesn't do any type- or
3824 * var-definitions. It does look for the keyword "extern" or
3825 * "forward" immediately following the procedure statement; if found,
3826 * the tag is skipped.
3829 Pascal_functions (inf)
3832 linebuffer tline; /* mostly copied from C_entries */
3834 int save_lineno, save_len;
3835 char c, *cp, *namebuf;
3837 bool /* each of these flags is TRUE iff: */
3838 incomment, /* point is inside a comment */
3839 inquote, /* point is inside '..' string */
3840 get_tagname, /* point is after PROCEDURE/FUNCTION
3841 keyword, so next item = potential tag */
3842 found_tag, /* point is after a potential tag */
3843 inparms, /* point is within parameter-list */
3844 verify_tag; /* point has passed the parm-list, so the
3845 next token will determine whether this
3846 is a FORWARD/EXTERN to be ignored, or
3847 whether it is a real tag */
3849 save_lcno = save_lineno = save_len = 0; /* keep compiler quiet */
3850 namebuf = NULL; /* keep compiler quiet */
3855 initbuffer (&tline);
3857 incomment = inquote = FALSE;
3858 found_tag = FALSE; /* have a proc name; check if extern */
3859 get_tagname = FALSE; /* have found "procedure" keyword */
3860 inparms = FALSE; /* found '(' after "proc" */
3861 verify_tag = FALSE; /* check if "extern" is ahead */
3864 while (!feof (inf)) /* long main loop to get next char */
3867 if (c == '\0') /* if end of line */
3870 linecharno = charno;
3871 charno += readline (&lb, inf);
3875 if (!((found_tag && verify_tag)
3877 c = *dbp++; /* only if don't need *dbp pointing
3878 to the beginning of the name of
3879 the procedure or function */
3883 if (c == '}') /* within { } comments */
3885 else if (c == '*' && *dbp == ')') /* within (* *) comments */
3902 inquote = TRUE; /* found first quote */
3904 case '{': /* found open { comment */
3908 if (*dbp == '*') /* found open (* comment */
3913 else if (found_tag) /* found '(' after tag, i.e., parm-list */
3916 case ')': /* end of parms list */
3921 if (found_tag && !inparms) /* end of proc or fn stmt */
3928 if (found_tag && verify_tag && (*dbp != ' '))
3930 /* check if this is an "extern" declaration */
3933 if (lowcase (*dbp == 'e'))
3935 if (tail ("extern")) /* superfluous, really! */
3941 else if (lowcase (*dbp) == 'f')
3943 if (tail ("forward")) /* check for forward reference */
3949 if (found_tag && verify_tag) /* not external proc, so make tag */
3953 pfnote (namebuf, TRUE,
3954 tline.buffer, save_len, save_lineno, save_lcno);
3958 if (get_tagname) /* grab name of proc or fn */
3963 /* save all values for later tagging */
3964 grow_linebuffer (&tline, lb.len + 1);
3965 strcpy (tline.buffer, lb.buffer);
3966 save_lineno = lineno;
3967 save_lcno = linecharno;
3969 /* grab block name */
3970 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
3972 namebuf = savenstr (dbp, cp-dbp);
3973 dbp = cp; /* set dbp to e-o-token */
3974 save_len = dbp - lb.buffer + 1;
3975 get_tagname = FALSE;
3979 /* and proceed to check for "extern" */
3981 else if (!incomment && !inquote && !found_tag)
3983 /* check for proc/fn keywords */
3984 switch (lowcase (c))
3987 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3991 if (tail ("unction"))
3996 } /* while not eof */
3998 free (tline.buffer);
4002 * lisp tag functions
4003 * look for (def or (DEF, quote or QUOTE
4007 register char *strp;
4009 return ((strp[1] == 'd' || strp[1] == 'D')
4010 && (strp[2] == 'e' || strp[2] == 'E')
4011 && (strp[3] == 'f' || strp[3] == 'F'));
4016 register char *strp;
4018 return ((*++strp == 'q' || *strp == 'Q')
4019 && (*++strp == 'u' || *strp == 'U')
4020 && (*++strp == 'o' || *strp == 'O')
4021 && (*++strp == 't' || *strp == 'T')
4022 && (*++strp == 'e' || *strp == 'E')
4023 && isspace (*++strp));
4031 if (*dbp == '\'') /* Skip prefix quote */
4033 else if (*dbp == '(')
4035 if (L_isquote (dbp))
4036 dbp += 7; /* Skip "(quote " */
4038 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */
4039 dbp = skip_spaces (dbp);
4042 for (cp = dbp /*+1*/;
4043 *cp != '\0' && *cp != '(' && !isspace(*cp) && *cp != ')';
4049 pfnote (savenstr (dbp, cp-dbp), TRUE,
4050 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4054 Lisp_functions (inf)
4057 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4063 dbp = skip_non_spaces (dbp);
4064 dbp = skip_spaces (dbp);
4069 /* Check for (foo::defmumble name-defined ... */
4072 while (*dbp != '\0' && !isspace (*dbp)
4073 && *dbp != ':' && *dbp != '(' && *dbp != ')');
4078 while (*dbp == ':');
4080 if (L_isdef (dbp - 1))
4082 dbp = skip_non_spaces (dbp);
4083 dbp = skip_spaces (dbp);
4093 * Postscript tag functions
4094 * Just look for lines where the first character is '/'
4095 * Richard Mlynarik <mly@adoc.xerox.com>
4096 * Also look at "defineps" for PSWrap
4097 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp>
4100 Postscript_functions (inf)
4103 register char *bp, *ep;
4105 LOOP_ON_INPUT_LINES (inf, lb, bp)
4110 *ep != '\0' && *ep != ' ' && *ep != '{';
4113 pfnote (savenstr (bp, ep-bp), TRUE,
4114 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4116 else if (strneq (bp, "defineps", 8))
4118 bp = skip_non_spaces (bp);
4119 bp = skip_spaces (bp);
4127 * Scheme tag functions
4128 * look for (def... xyzzy
4129 * look for (def... (xyzzy
4130 * look for (def ... ((...(xyzzy ....
4131 * look for (set! xyzzy
4135 Scheme_functions (inf)
4140 LOOP_ON_INPUT_LINES (inf, lb, bp)
4143 && (bp[1] == 'D' || bp[1] == 'd')
4144 && (bp[2] == 'E' || bp[2] == 'e')
4145 && (bp[3] == 'F' || bp[3] == 'f'))
4147 bp = skip_non_spaces (bp);
4148 /* Skip over open parens and white space */
4149 while (isspace (*bp) || *bp == '(')
4154 && (bp[1] == 'S' || bp[1] == 's')
4155 && (bp[2] == 'E' || bp[2] == 'e')
4156 && (bp[3] == 'T' || bp[3] == 't')
4157 && (bp[4] == '!' || bp[4] == '!')
4158 && (isspace (bp[5])))
4160 bp = skip_non_spaces (bp);
4161 bp = skip_spaces (bp);
4167 /* Find tags in TeX and LaTeX input files. */
4169 /* TEX_toktab is a table of TeX control sequences that define tags.
4170 Each TEX_tabent records one such control sequence.
4171 CONVERT THIS TO USE THE Stab TYPE!! */
4178 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
4180 /* Default set of control sequences to put into TEX_toktab.
4181 The value of environment var TEXTAGS is prepended to this. */
4183 char *TEX_defenv = "\
4184 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4185 :part:appendix:entry:index";
4187 void TEX_mode (FILE *inf);
4188 struct TEX_tabent *TEX_decode_env (char *evarname, char *defenv);
4189 int TEX_Token (char *cp);
4191 char TEX_esc = '\\';
4192 char TEX_opgrp = '{';
4193 char TEX_clgrp = '}';
4196 * TeX/LaTeX scanning loop.
4205 /* Select either \ or ! as escape character. */
4208 /* Initialize token table once from environment. */
4210 TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
4212 LOOP_ON_INPUT_LINES (inf, lb, cp)
4215 /* Look at each esc in line. */
4216 while ((cp = etags_strchr (cp, TEX_esc)) != NULL)
4220 linecharno += cp - lasthit;
4222 i = TEX_Token (lasthit);
4225 /* We seem to include the TeX command in the tag name.
4227 for (p = lasthit + TEX_toktab[i].len;
4228 *p != '\0' && *p != TEX_clgrp;
4231 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL, TRUE,
4232 lb.buffer, lb.len, lineno, linecharno);
4233 break; /* We only tag a line once */
4239 #define TEX_LESC '\\'
4240 #define TEX_SESC '!'
4243 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4244 chars accordingly. */
4251 while ((c = getc (inf)) != EOF)
4253 /* Skip to next line if we hit the TeX comment char. */
4257 else if (c == TEX_LESC || c == TEX_SESC )
4273 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4274 No attempt is made to correct the situation. */
4278 /* Read environment and prepend it to the default string.
4279 Build token table. */
4281 TEX_decode_env (evarname, defenv)
4285 register char *env, *p;
4287 struct TEX_tabent *tab;
4290 /* Append default string to environment. */
4291 env = getenv (evarname);
4297 env = concat (oldenv, defenv, "");
4300 /* Allocate a token table */
4301 for (size = 1, p = env; p;)
4302 if ((p = etags_strchr (p, ':')) && *++p != '\0')
4304 /* Add 1 to leave room for null terminator. */
4305 tab = xnew (size + 1, struct TEX_tabent);
4307 /* Unpack environment string into token table. Be careful about */
4308 /* zero-length strings (leading ':', "::" and trailing ':') */
4311 p = etags_strchr (env, ':');
4312 if (!p) /* End of environment string. */
4313 p = env + strlen (env);
4315 { /* Only non-zero strings. */
4316 tab[i].name = savenstr (env, p - env);
4317 tab[i].len = strlen (tab[i].name);
4324 tab[i].name = NULL; /* Mark end of table. */
4332 /* If the text at CP matches one of the tag-defining TeX command names,
4333 return the pointer to the first occurrence of that command in TEX_toktab.
4334 Otherwise return -1.
4335 Keep the capital `T' in `token' for dumb truncating compilers
4336 (this distinguishes it from `TEX_toktab' */
4343 for (i = 0; TEX_toktab[i].len > 0; i++)
4344 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
4350 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
4352 * Assumes that the predicate starts at column 0.
4353 * Only the first clause of a predicate is added.
4355 int prolog_pred (char *s, char *last);
4356 void prolog_skip_comment (linebuffer *plb, FILE *inf);
4357 int prolog_atom (char *s, int pos);
4360 Prolog_functions (inf)
4371 LOOP_ON_INPUT_LINES (inf, lb, cp)
4373 if (cp[0] == '\0') /* Empty line */
4375 else if (isspace (cp[0])) /* Not a predicate */
4377 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
4378 prolog_skip_comment (&lb, inf);
4379 else if ((len = prolog_pred (cp, last)) > 0)
4381 /* Predicate. Store the function name so that we only
4382 generate a tag for the first clause. */
4384 last = xnew(len + 1, char);
4385 else if (len + 1 > allocated)
4386 last = xrnew (last, len + 1, char);
4387 allocated = len + 1;
4388 strncpy (last, cp, len);
4396 prolog_skip_comment (plb, inf)
4404 for (cp = plb->buffer; *cp != '\0'; cp++)
4405 if (cp[0] == '*' && cp[1] == '/')
4408 linecharno += readline (plb, inf);
4414 * A predicate definition is added if it matches:
4415 * <beginning of line><Prolog Atom><whitespace>(
4417 * It is added to the tags database if it doesn't match the
4418 * name of the previous clause header.
4420 * Return the size of the name of the predicate, or 0 if no header
4424 prolog_pred (s, last)
4426 char *last; /* Name of last clause. */
4431 pos = prolog_atom (s, 0);
4436 pos = skip_spaces (s + pos) - s;
4438 if ((s[pos] == '(') || (s[pos] == '.'))
4443 /* Save only the first clause. */
4445 || len != (int)strlen (last)
4446 || !strneq (s, last, len))
4448 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4456 * Consume a Prolog atom.
4457 * Return the number of bytes consumed, or -1 if there was an error.
4459 * A prolog atom, in this context, could be one of:
4460 * - An alphanumeric sequence, starting with a lower case letter.
4461 * - A quoted arbitrary string. Single quotes can escape themselves.
4462 * Backslash quotes everything.
4465 prolog_atom (s, pos)
4473 if (islower(s[pos]) || (s[pos] == '_'))
4475 /* The atom is unquoted. */
4477 while (isalnum(s[pos]) || (s[pos] == '_'))
4481 return pos - origpos;
4483 else if (s[pos] == '\'')
4494 pos++; /* A double quote */
4496 else if (s[pos] == '\0')
4497 /* Multiline quoted atoms are ignored. */
4499 else if (s[pos] == '\\')
4501 if (s[pos+1] == '\0')
4508 return pos - origpos;
4515 * Support for Erlang -- Anders Lindgren, Feb 1996.
4517 * Generates tags for functions, defines, and records.
4519 * Assumes that Erlang functions start at column 0.
4521 int erlang_func (char *s, char *last);
4522 void erlang_attribute (char *s);
4523 int erlang_atom (char *s, int pos);
4526 Erlang_functions (inf)
4537 LOOP_ON_INPUT_LINES (inf, lb, cp)
4539 if (cp[0] == '\0') /* Empty line */
4541 else if (isspace (cp[0])) /* Not function nor attribute */
4543 else if (cp[0] == '%') /* comment */
4545 else if (cp[0] == '"') /* Sometimes, strings start in column one */
4547 else if (cp[0] == '-') /* attribute, e.g. "-define" */
4549 erlang_attribute (cp);
4552 else if ((len = erlang_func (cp, last)) > 0)
4555 * Function. Store the function name so that we only
4556 * generates a tag for the first clause.
4559 last = xnew (len + 1, char);
4560 else if (len + 1 > allocated)
4561 last = xrnew (last, len + 1, char);
4562 allocated = len + 1;
4563 strncpy (last, cp, len);
4571 * A function definition is added if it matches:
4572 * <beginning of line><Erlang Atom><whitespace>(
4574 * It is added to the tags database if it doesn't match the
4575 * name of the previous clause header.
4577 * Return the size of the name of the function, or 0 if no function
4581 erlang_func (s, last)
4583 char *last; /* Name of last clause. */
4588 pos = erlang_atom (s, 0);
4593 pos = skip_spaces (s + pos) - s;
4595 /* Save only the first clause. */
4598 || len != (int)strlen (last)
4599 || !strneq (s, last, len)))
4601 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno);
4610 * Handle attributes. Currently, tags are generated for defines
4613 * They are on the form:
4614 * -define(foo, bar).
4615 * -define(Foo(M, N), M+N).
4616 * -record(graph, {vtab = notable, cyclic = true}).
4619 erlang_attribute (s)
4625 if (strneq (s, "-define", 7) || strneq (s, "-record", 7))
4627 pos = skip_spaces (s + 7) - s;
4628 if (s[pos++] == '(')
4630 pos = skip_spaces (s + pos) - s;
4631 len = erlang_atom (s, pos);
4633 pfnote (savenstr (& s[pos], len), TRUE,
4634 s, pos + len, lineno, linecharno);
4642 * Consume an Erlang atom (or variable).
4643 * Return the number of bytes consumed, or -1 if there was an error.
4646 erlang_atom (s, pos)
4654 if (isalpha (s[pos]) || s[pos] == '_')
4656 /* The atom is unquoted. */
4658 while (isalnum (s[pos]) || s[pos] == '_')
4660 return pos - origpos;
4662 else if (s[pos] == '\'')
4673 else if (s[pos] == '\0')
4674 /* Multiline quoted atoms are ignored. */
4676 else if (s[pos] == '\\')
4678 if (s[pos+1] == '\0')
4685 return pos - origpos;
4691 #ifdef ETAGS_REGEXPS
4693 /* Take a string like "/blah/" and turn it into "blah", making sure
4694 that the first and last characters are the same, and handling
4695 quoted separator characters. Actually, stops on the occurrence of
4696 an unquoted separator. Also turns "\t" into a Tab character.
4697 Returns pointer to terminating separator. Works in place. Null
4698 terminates name string. */
4700 scan_separators (name)
4704 char *copyto = name;
4705 bool quoted = FALSE;
4707 for (++name; *name != '\0'; ++name)
4713 else if (*name == sep)
4717 /* Something else is quoted, so preserve the quote. */
4723 else if (*name == '\\')
4725 else if (*name == sep)
4731 /* Terminate copied string. */
4736 /* Look at the argument of --regex or --no-regex and do the right
4737 thing. Same for each line of a regexp file. */
4739 analyse_regex (regex_arg, ignore_case)
4743 if (regex_arg == NULL)
4744 free_patterns (); /* --no-regex: remove existing regexps */
4746 /* A real --regexp option or a line in a regexp file. */
4747 switch (regex_arg[0])
4749 /* Comments in regexp file or null arg to --regex. */
4755 /* Read a regex file. This is recursive and may result in a
4756 loop, which will stop when the file descriptors are exhausted. */
4760 linebuffer regexbuf;
4761 char *regexfile = regex_arg + 1;
4763 /* regexfile is a file containing regexps, one per line. */
4764 regexfp = fopen (regexfile, "r");
4765 if (regexfp == NULL)
4770 initbuffer (®exbuf);
4771 while (readline_internal (®exbuf, regexfp) > 0)
4772 analyse_regex (regexbuf.buffer, ignore_case);
4773 free (regexbuf.buffer);
4778 /* Regexp to be used for a specific language only. */
4782 char *lang_name = regex_arg + 1;
4785 for (cp = lang_name; *cp != '}'; cp++)
4788 error ("unterminated language name in regex: %s", regex_arg);
4792 lang = get_language_from_name (lang_name);
4795 add_regex (cp + 1, ignore_case, lang);
4799 /* Regexp to be used for any language. */
4801 add_regex (regex_arg, ignore_case, NULL);
4806 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4807 expression, into a real regular expression by compiling it. */
4809 add_regex (regexp_pattern, ignore_case, lang)
4810 char *regexp_pattern;
4816 struct re_pattern_buffer *patbuf;
4820 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0])
4822 error ("%s: unterminated regexp", regexp_pattern);
4825 name = scan_separators (regexp_pattern);
4826 if (regexp_pattern[0] == '\0')
4828 error ("null regexp", (char *)NULL);
4831 (void) scan_separators (name);
4833 patbuf = xnew (1, struct re_pattern_buffer);
4834 /* Translation table to fold case if appropriate. */
4835 patbuf->translate = (ignore_case) ? lc_trans : NULL;
4836 patbuf->fastmap = NULL;
4837 patbuf->buffer = NULL;
4838 patbuf->allocated = 0;
4840 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4843 error ("%s while compiling pattern", err);
4848 p_head = xnew (1, pattern);
4849 p_head->regex = savestr (regexp_pattern);
4850 p_head->p_next = pp;
4851 p_head->language = lang;
4852 p_head->pattern = patbuf;
4853 p_head->name_pattern = savestr (name);
4854 p_head->error_signaled = FALSE;
4858 * Do the substitutions indicated by the regular expression and
4862 substitute (in, out, regs)
4864 struct re_registers *regs;
4867 int size, dig, diglen;
4870 size = strlen (out);
4872 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4873 if (out[size - 1] == '\\')
4874 fatal ("pattern error in \"%s\"", out);
4875 for (t = etags_strchr (out, '\\');
4877 t = etags_strchr (t + 2, '\\'))
4881 diglen = regs->end[dig] - regs->start[dig];
4887 /* Allocate space and do the substitutions. */
4888 result = xnew (size + 1, char);
4890 for (t = result; *out != '\0'; out++)
4891 if (*out == '\\' && isdigit (*++out))
4893 /* Using "dig2" satisfies my debugger. Bleah. */
4895 diglen = regs->end[dig] - regs->start[dig];
4896 strncpy (t, in + regs->start[dig], diglen);
4903 if (DEBUG && (t > result + size || t - result != (int)strlen (result)))
4909 /* Deallocate all patterns. */
4914 while (p_head != NULL)
4916 pp = p_head->p_next;
4917 free (p_head->regex);
4918 free (p_head->name_pattern);
4933 /* Go till you get to white space or a syntactic break */
4935 *cp != '\0' && *cp != '(' && *cp != ')' && !isspace (*cp);
4938 pfnote (savenstr (bp, cp-bp), TRUE,
4939 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4942 #endif /* ETAGS_REGEXPS */
4943 /* Initialize a linebuffer for use */
4949 lbp->buffer = xnew (200, char);
4953 * Read a line of text from `stream' into `lbp', excluding the
4954 * newline or CR-NL, if any. Return the number of characters read from
4955 * `stream', which is the length of the line including the newline.
4957 * On DOS or Windows we do not count the CR character, if any, before the
4958 * NL, in the returned length; this mirrors the behavior of emacs on those
4959 * platforms (for text files, it translates CR-NL to NL as it reads in the
4963 readline_internal (lbp, stream)
4965 register FILE *stream;
4967 char *buffer = lbp->buffer;
4968 register char *p = lbp->buffer;
4969 register char *pend;
4972 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
4976 register int c = getc (stream);
4979 /* We're at the end of linebuffer: expand it. */
4981 buffer = xrnew (buffer, lbp->size, char);
4982 p += buffer - lbp->buffer;
4983 pend = buffer + lbp->size;
4984 lbp->buffer = buffer;
4994 if (p > buffer && p[-1] == '\r')
4998 /* Assume CRLF->LF translation will be performed by Emacs
4999 when loading this file, so CRs won't appear in the buffer.
5000 It would be cleaner to compensate within Emacs;
5001 however, Emacs does not know how many CRs were deleted
5002 before any given point in the file. */
5017 lbp->len = p - buffer;
5019 return lbp->len + chars_deleted;
5023 * Like readline_internal, above, but in addition try to match the
5024 * input line against relevant regular expressions.
5027 readline (lbp, stream)
5031 /* Read new line. */
5032 long result = readline_internal (lbp, stream);
5033 #ifdef ETAGS_REGEXPS
5037 /* Match against relevant patterns. */
5039 for (pp = p_head; pp != NULL; pp = pp->p_next)
5041 /* Only use generic regexps or those for the current language. */
5042 if (pp->language != NULL && pp->language != curlang)
5045 match = re_match (pp->pattern, lbp->buffer, lbp->len, 0, &pp->regs);
5050 if (!pp->error_signaled)
5052 error ("error while matching \"%s\"", pp->regex);
5053 pp->error_signaled = TRUE;
5060 /* Match occurred. Construct a tag. */
5061 if (pp->name_pattern[0] != '\0')
5063 /* Make a named tag. */
5064 char *name = substitute (lbp->buffer,
5065 pp->name_pattern, &pp->regs);
5067 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
5071 /* Make an unnamed tag. */
5072 pfnote ((char *)NULL, TRUE,
5073 lbp->buffer, match, lineno, linecharno);
5078 #endif /* ETAGS_REGEXPS */
5084 * Return a pointer to a space of size strlen(cp)+1 allocated
5085 * with xnew where the string CP has been copied.
5091 return savenstr (cp, strlen (cp));
5095 * Return a pointer to a space of size LEN+1 allocated with xnew where
5096 * the string CP has been copied for at most the first LEN characters.
5105 dp = xnew (len + 1, char);
5106 strncpy (dp, cp, len);
5112 * Return the ptr in sp at which the character c last
5113 * appears; NULL if not found
5116 etags_strrchr (sp, c)
5120 register const char *r;
5133 * Return the ptr in sp at which the character c first
5134 * appears; NULL if not found
5137 etags_strchr (sp, c)
5149 /* Skip spaces, return new pointer. */
5154 while (isspace (*cp)) /* isspace('\0')==FALSE */
5159 /* Skip non spaces, return new pointer. */
5161 skip_non_spaces (cp)
5164 while (!iswhite (*cp)) /* iswhite('\0')==TRUE */
5169 /* Print error message and exit. */
5187 suggest_asking_for_help ()
5189 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
5200 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5203 const char *s1, *s2;
5205 fprintf (stderr, "%s: ", progname);
5206 fprintf (stderr, s1, s2);
5207 fprintf (stderr, "\n");
5210 /* Return a newly-allocated string whose contents
5211 concatenate those of s1, s2, s3. */
5216 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
5217 char *result = xnew (len1 + len2 + len3 + 1, char);
5219 strcpy (result, s1);
5220 strcpy (result + len1, s2);
5221 strcpy (result + len1 + len2, s3);
5222 result[len1 + len2 + len3] = '\0';
5227 /* Does the same work as the system V getcwd, but does not need to
5228 guess the buffer size in advance. */
5234 char *path = xnew (bufsize, char);
5236 while (getcwd (path, bufsize) == NULL)
5238 if (errno != ERANGE)
5242 path = xnew (bufsize, char);
5245 canonicalize_filename (path);
5248 #else /* not HAVE_GETCWD */
5250 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
5254 for (p = path; *p != '\0'; p++)
5260 return strdup (path);
5261 #else /* not MSDOS */
5266 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
5267 if (pipe == NULL || readline_internal (&path, pipe) == 0)
5272 #endif /* not MSDOS */
5273 #endif /* not HAVE_GETCWD */
5276 /* Return a newly allocated string containing the file name of FILE
5277 relative to the absolute directory DIR (which should end with a slash). */
5279 relative_filename (file, dir)
5282 char *fp, *dp, *afn, *res;
5285 /* Find the common root of file and dir (with a trailing slash). */
5286 afn = absolute_filename (file, cwd);
5289 while (*fp++ == *dp++)
5291 fp--, dp--; /* back to the first differing char */
5293 if (fp == afn && afn[0] != '/') /* cannot build a relative name */
5296 do /* look at the equal chars until '/' */
5300 /* Build a sequence of "../" strings for the resulting relative file name. */
5302 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
5304 res = xnew (3*i + strlen (fp + 1) + 1, char);
5307 strcat (res, "../");
5309 /* Add the file name relative to the common root of file and dir. */
5310 strcat (res, fp + 1);
5316 /* Return a newly allocated string containing the absolute file name
5317 of FILE given DIR (which should end with a slash). */
5319 absolute_filename (file, dir)
5322 char *slashp, *cp, *res;
5324 if (filename_is_absolute (file))
5325 res = savestr (file);
5327 /* We don't support non-absolute file names with a drive
5328 letter, like `d:NAME' (it's too much hassle). */
5329 else if (file[1] == ':')
5330 fatal ("%s: relative file names with drive letters not supported", file);
5333 res = concat (dir, file, "");
5335 /* Delete the "/dirname/.." and "/." substrings. */
5336 slashp = etags_strchr (res, '/');
5337 while (slashp != NULL && slashp[0] != '\0')
5339 if (slashp[1] == '.')
5341 if (slashp[2] == '.'
5342 && (slashp[3] == '/' || slashp[3] == '\0'))
5347 while (cp >= res && !filename_is_absolute (cp));
5349 cp = slashp; /* the absolute name begins with "/.." */
5351 /* Under MSDOS and NT we get `d:/NAME' as absolute
5352 file name, so the luser could say `d:/../NAME'.
5353 We silently treat this as `d:/NAME'. */
5354 else if (cp[0] != '/')
5357 strcpy (cp, slashp + 3);
5361 else if (slashp[2] == '/' || slashp[2] == '\0')
5363 strcpy (slashp, slashp + 2);
5368 slashp = etags_strchr (slashp + 1, '/');
5372 return savestr ("/");
5377 /* Return a newly allocated string containing the absolute
5378 file name of dir where FILE resides given DIR (which should
5379 end with a slash). */
5381 absolute_dirname (file, dir)
5387 canonicalize_filename (file);
5388 slashp = etags_strrchr (file, '/');
5390 return savestr (dir);
5393 res = absolute_filename (file, dir);
5399 /* Whether the argument string is an absolute file name. The argument
5400 string must have been canonicalized with canonicalize_filename. */
5402 filename_is_absolute (fn)
5405 return (fn[0] == '/'
5407 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/')
5412 /* Translate backslashes into slashes. Works in place. */
5414 canonicalize_filename (fn)
5418 /* Canonicalize drive letter case. */
5419 if (islower (fn[0]))
5420 fn[0] = toupper (fn[0]);
5421 /* Convert backslashes to slashes. */
5422 for (; *fn != '\0'; fn++)
5427 fn = NULL; /* shut up the compiler */
5431 /* Increase the size of a linebuffer. */
5433 grow_linebuffer (lbp, toksize)
5437 while (lbp->size < toksize)
5439 lbp->buffer = xrnew (lbp->buffer, lbp->size, char);
5442 /* Like malloc but get fatal error if memory is exhausted. */
5447 long *result = (long *) malloc (size);
5449 fatal ("virtual memory exhausted", (char *)NULL);
5454 xrealloc (ptr, size)
5458 long *result = (long *) realloc (ptr, size);
5460 fatal ("virtual memory exhausted", (char *)NULL);