1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 1987, 1988, 1989, 1993 Free Software Foundation, Inc. and Ken Arnold
4 This file is not considered part of GNU Emacs.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 * Ctags originally by Ken Arnold.
23 * Fortran added by Jim Kleckner.
24 * Ed Pelegri-Llopart added C typedefs.
25 * Gnu Emacs TAGS format and modifications by RMS?
26 * Sam Kendall added C++.
28 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer.
31 char pot_etags_version
[] = "@(#) pot revision number is 10.29";
38 #include <../src/config.h>
39 /* On some systems, Emacs defines static as nothing
40 for the sake of unexec. We don't want that here
41 since we don't use unexec. */
47 #include <sys/types.h>
50 #if !defined (S_ISREG) && defined (S_IFREG)
51 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
56 extern char *getenv ();
59 /* Define CTAGS to make the program "ctags" compatible with the usual one.
60 Let it undefined to make the program "etags", which makes emacs-style
61 tag tables and tags typedefs, #defines and struct/union/enum by default. */
69 /* Exit codes for success and failure. */
79 * The FILEPOS abstract type, which represents a position in a file,
80 * plus the following accessor functions:
82 * long GET_CHARNO (pos)
83 * returns absolute char number.
84 * void SET_FILEPOS (pos, fp, charno)
85 * FILE *fp; long charno;
86 * sets `pos' from the current file
87 * position of `fp' and from `charno',
88 * which must be the absolute character
89 * number corresponding to the current
92 * The `pos' parameter is an lvalue expression of type FILEPOS.
93 * Parameters to the accessor functions are evaluated 0 or more times,
94 * and so must have no side effects.
96 * FILEPOS objects can also be assigned and passed to and from
97 * functions in the normal C manner.
99 * Implementation notes: the `+ 0' is to enforce rvalue-ness.
103 /* real implementation */
104 typedef long FILEPOS
;
105 #define GET_CHARNO(pos) ((pos) + 0)
106 #define SET_FILEPOS(pos, fp, cno) ((void) ((pos) = (cno)))
108 /* debugging implementation */
114 #define GET_CHARNO(pos) ((pos).charno + 0)
115 #define SET_FILEPOS(pos, fp, cno) \
116 ((void) ((pos).charno = (cno), \
117 (cno) != ftell (fp) ? (error ("SET_FILEPOS inconsistency"), 0) \
121 #define streq(s, t) (strcmp (s, t) == 0)
122 #define strneq(s, t, n) (strncmp (s, t, n) == 0)
128 #define iswhite(arg) (_wht[arg]) /* T if char is white */
129 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
130 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
131 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
133 #define max(I1,I2) ((I1) > (I2) ? (I1) : (I2))
136 { /* sorting structure */
137 char *name
; /* function or type name */
138 char *file
; /* file name */
139 logical is_func
; /* use pattern or line no */
140 logical named
; /* list name separately */
141 logical been_warned
; /* set if noticed dup */
142 int lno
; /* line number tag is on */
143 long cno
; /* character number line starts on */
144 char *pat
; /* search pattern */
145 struct nd_st
*left
, *right
; /* left and right sons */
148 typedef struct nd_st NODE
;
150 logical header_file
; /* TRUE if .h file, FALSE o.w. */
151 /* boolean "functions" (see init) */
152 logical _wht
[0177], _etk
[0177], _itk
[0177], _btk
[0177];
154 char *cwd
; /* current working directory */
155 char *tagfiledir
; /* directory of tagfile */
158 char *savenstr (), *savestr ();
159 char *etags_strchr (), *etags_strrchr ();
160 char *etags_getcwd ();
161 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
162 char *xmalloc (), *xrealloc ();
163 int total_size_of_entries ();
168 int Fortran_functions ();
169 void Lisp_functions ();
170 void Pascal_functions ();
171 void Prolog_functions ();
172 void Scheme_functions ();
173 void TeX_functions ();
177 logical
find_entries ();
184 void process_file ();
190 * xnew -- allocate storage
193 * Type *xnew (int n, Type);
195 #define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type)))
198 * Symbol table types.
202 st_none
, st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
219 #define C_PLPL 0x00001 /* C++ */
220 #define C_STAR 0x00003 /* C* */
221 #define YACC 0x10000 /* yacc file */
223 char searchar
= '/'; /* use /.../ searches */
225 LINENO lineno
; /* line number of current line */
226 long charno
; /* current character number */
228 long linecharno
; /* charno of start of line; not used by C, but
229 * by every other language.
232 char *curfile
, /* current input file name */
233 *tagfile
, /* output file */
234 *white
= " \f\t\n", /* white chars */
235 *endtk
= " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */
236 /* token starting chars */
237 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~",
238 /* valid in-token chars */
239 *intk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
241 int append_to_tagfile
; /* -a: append to tags */
242 /* The following three default to 1 for etags, but to 0 for ctags. */
243 int typedefs
; /* -t: create tags for typedefs */
244 int typedefs_and_cplusplus
; /* -T: create tags for typedefs, level */
245 /* 0 struct/enum/union decls, and C++ */
246 /* member functions. */
247 int constantypedefs
; /* -d: create tags for C #define and enum */
248 /* constants. Enum consts not implemented. */
249 /* -D: opposite of -d. Default under ctags. */
250 int update
; /* -u: update tags */
251 int vgrind_style
; /* -v: create vgrind style index output */
252 int no_warnings
; /* -w: suppress warnings */
253 int cxref_style
; /* -x: create cxref style output */
254 int cplusplus
; /* .[hc] means C++, not C */
255 int noindentypedefs
; /* -S: ignore indentation in C */
257 /* Name this program was invoked with. */
260 struct option longopts
[] = {
261 { "append", no_argument
, NULL
, 'a' },
262 { "backward-search", no_argument
, NULL
, 'B' },
263 { "c++", no_argument
, NULL
, 'C' },
264 { "cxref", no_argument
, NULL
, 'x' },
265 { "defines", no_argument
, NULL
, 'd' },
266 { "forward-search", no_argument
, NULL
, 'F' },
267 { "help", no_argument
, NULL
, 'H' },
268 { "ignore-indentation", no_argument
, NULL
, 'S' },
269 { "include", required_argument
, NULL
, 'i' },
270 { "no-defines", no_argument
, NULL
, 'D' },
271 { "no-warn", no_argument
, NULL
, 'w' },
272 { "output", required_argument
, NULL
, 'o' },
273 { "typedefs", no_argument
, NULL
, 't' },
274 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
275 { "update", no_argument
, NULL
, 'u' },
276 { "version", no_argument
, NULL
, 'V' },
277 { "vgrind", no_argument
, NULL
, 'v' },
281 FILE *tagf
; /* ioptr for tags file */
282 NODE
*head
; /* the head of the binary tree of tags */
283 logical permit_duplicates
= TRUE
; /* allow duplicate tags */
285 /* A `struct linebuffer' is a structure which holds a line of text.
286 `readline' reads a line from a stream into a linebuffer
287 and works regardless of the length of the line. */
295 struct linebuffer lb
; /* the current line */
296 struct linebuffer filename_lb
; /* used to read in filenames */
300 struct linebuffer lb
; /* used by C_entries instead of lb */
307 printf ("%s for Emacs version %g.\n", (CTAGS
) ? "CTAGS" : "ETAGS", VERSION
);
309 printf ("%s for Emacs version 19.\n", (CTAGS
) ? "CTAGS" : "ETAGS");
318 printf ("These are the options accepted by %s. You may use unambiguous\n\
319 abbreviations for the long option names. A - as file name means read file\n\
320 names from stdin.\n\n", progname
);
322 puts ("-a, --append\n\
323 Append tag entries to existing tags file.");
326 puts ("-B, --backward-search\n\
327 Write the search commands for the tag entries using '?', the\n\
328 backward-search command.");
331 Treat files with `.c' and `.h' extensions as C++ code, not C\n\
332 code. Files with `.C', `.H', `.cxx', `.hxx', or `.cc'\n\
333 extensions are always assumed to be C++ code.");
336 puts ("-d, --defines\n\
337 Create tag entries for C #defines, too.");
339 puts ("-D, --no-defines\n\
340 Don't create tag entries for C #defines. This makes the tags\n\
344 puts ("-F, --forward-search\n\
345 Write the search commands for the tag entries using '/', the\n\
346 forward-search command.");
349 puts ("-i FILE, --include=FILE\n\
350 Include a note in tag file indicating that, when searching for\n\
351 a tag, one should also consult the tags file FILE after\n\
352 checking the current file.");
354 puts ("-o FILE, --output=FILE\n\
355 Write the tags to FILE.");
356 puts ("-S, --ignore-indentation\n\
357 Don't rely on indentation quite as much as normal. Currently,\n\
358 this means not to assume that a closing brace in the first\n\
359 column is the final brace of a function or structure\n\
360 definition in C and C++.");
364 puts ("-t, --typedefs\n\
365 Generate tag entries for C typedefs.");
366 puts ("-T, --typedefs-and-c++\n\
367 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
368 and C++ member functions.");
369 puts ("-u, --update\n\
370 Update the tag entries for the given files, leaving tag\n\
371 entries for other files in place. Currently, this is\n\
372 implemented by deleting the existing entries for the given\n\
373 files and then rewriting the new entries at the end of the\n\
374 tags file. It is often faster to simply rebuild the entire\n\
375 tag file than to use this.");
376 puts ("-v, --vgrind\n\
377 Generates an index of items intended for human consumption,\n\
378 similar to the output of vgrind. The index is sorted, and\n\
379 gives the page number of each item.");
380 puts ("-x, --cxref\n\
381 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
382 The output uses line numbers instead of page numbers, but\n\
383 beyond that the differences are cosmetic; try both to see\n\
385 puts ("-w, --no-warn\n\
386 Suppress warning messages about entries defined in multiple\n\
390 puts ("-V, --version\n\
391 Print the version of the program.\n\
393 Print this help message.");
406 unsigned int nincluded_files
= 0;
407 char **included_files
= xnew (argc
, char *);
412 extern char *gfnames ();
413 extern char *massage_name ();
417 _fmode
= O_BINARY
; /* all of files are treated as binary files */
423 * If etags, always find typedefs and structure tags. Why not?
424 * Also default is to find macro constants.
427 typedefs
= typedefs_and_cplusplus
= constantypedefs
= 1;
432 opt
= getopt_long (argc
, argv
, "aCdDf:o:StTi:BFuvxwVH", longopts
, 0);
440 /* If getopt returns 0, then it has already processed a
441 long-named option. We should do nothing. */
444 /* Common options. */
457 case 'f': /* for compatibility with old makefiles */
462 "%s: -%c flag may only be given once\n", progname
, opt
);
481 included_files
[nincluded_files
++] = optarg
;
498 typedefs_and_cplusplus
++;
520 if (optind
== argc
&& nincluded_files
== 0)
522 fprintf (stderr
, "%s: No input files specified.\n", progname
);
525 fprintf (stderr
, "%s: Try `%s --help' for a complete list of options.\n",
532 tagfile
= CTAGS
? "tags" : "TAGS";
534 cwd
= etags_getcwd (); /* the current working directory */
536 if (streq (tagfile
, "-"))
542 tagfiledir
= absolute_dirname (tagfile
, cwd
);
545 init (); /* set up boolean "functions" */
548 initbuffer (&lbs
[0].lb
);
549 initbuffer (&lbs
[1].lb
);
550 initbuffer (&filename_lb
);
552 * loop through files finding functions
556 if (streq (tagfile
, "-"))
559 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
570 while (gfnames (&argc
, &argv
, &got_err
) != NULL
)
574 error ("Can't find file %s\n", this_file
);
579 this_file
= massage_name (this_file
);
582 } /* solely to balance out the ifdef'd parens above */
585 for (; optind
< argc
; optind
++)
587 this_file
= argv
[optind
];
589 /* Input file named "-" means read file names from stdin and use them. */
590 if (streq (this_file
, "-"))
592 while (!feof (stdin
))
594 (void) readline (&filename_lb
, stdin
);
595 if (strlen (filename_lb
.buffer
) > 0)
596 process_file (filename_lb
.buffer
);
600 process_file (this_file
);
605 while (nincluded_files
-- > 0)
606 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
608 (void) fclose (tagf
);
619 /* update cannot be set under VMS, so we may assume that argc
620 and argv have not been munged. */
621 for (i
= optind
; i
< argc
; i
++)
624 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
625 tagfile
, argv
[i
], tagfile
);
630 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
637 (void) fclose (tagf
);
640 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
648 * This routine is called on each file argument.
654 struct stat stat_buf
;
656 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
658 fprintf (stderr
, "Skipping %s: it is not a regular file.\n", file
);
661 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
663 fprintf (stderr
, "Skipping inclusion of %s in self.\n", file
);
666 if (!find_entries (file
))
676 /* file is an absolute filename. Canonicalise it. */
677 filename
= absolute_filename (file
, cwd
);
681 /* file is a filename relative to cwd. Make it relative
682 to the directory of the tags file. */
683 filename
= relative_filename (file
, tagfiledir
);
685 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
693 * This routine sets up the boolean pseudo-functions which work
694 * by setting boolean flags dependent upon the corresponding character
695 * Every char which is NOT in that string is not a white char. Therefore,
696 * all of the array "_wht" is set to FALSE, and then the elements
697 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
698 * of a char is TRUE if it is the string "white", else FALSE.
706 for (i
= 0; i
< 0177; i
++)
707 _wht
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
708 for (sp
= white
; *sp
; sp
++)
710 for (sp
= endtk
; *sp
; sp
++)
712 for (sp
= intk
; *sp
; sp
++)
714 for (sp
= begtk
; *sp
; sp
++)
716 _wht
[0] = _wht
['\n'];
717 _etk
[0] = _etk
['\n'];
718 _btk
[0] = _btk
['\n'];
719 _itk
[0] = _itk
['\n'];
723 * This routine opens the specified file and calls the function
724 * which finds the function and type definitions.
733 inf
= fopen (file
, "r");
739 curfile
= savestr (file
);
740 cp
= etags_strrchr (file
, '.');
743 header_file
= (cp
&& (streq (cp1
, "h")));
745 /* .tex, .aux or .bbl implies LaTeX source code */
746 if (cp
&& (streq (cp1
, "tex") || streq (cp1
, "aux")
747 || streq (cp1
, "bbl")))
750 goto close_and_return
;
752 /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
753 if (cp
&& (streq (cp1
, "l")
755 || streq (cp1
, "lsp")
756 || streq (cp1
, "lisp")
758 || streq (cp1
, "clisp")))
760 Lisp_functions (inf
);
761 goto close_and_return
;
763 /* .scm or .sm or .scheme or ... implies scheme source code */
764 if (cp
&& (streq (cp1
, "sm")
765 || streq (cp1
, "scm")
766 || streq (cp1
, "scheme")
768 || streq (cp1
, "sch")
771 || streq (cp1
, "SCM")
772 /* The `SCM' or `scm' prefix with a version number */
773 || (cp
[-1] == 'm' && cp
[-2] == 'c' && cp
[-3] == 's'
774 && string_numeric_p (cp1
))
775 || (cp
[-1] == 'M' && cp
[-2] == 'C' && cp
[-3] == 'S'
776 && string_numeric_p (cp1
))))
778 Scheme_functions (inf
);
779 goto close_and_return
;
782 if (cp
&& (streq (cp1
, "s")
783 || streq (cp1
, "a") /* Unix assembler */
784 || streq (cp1
, "sa") /* Unix assembler */
785 || streq (cp1
, "asm") /* Microcontroller assembly */
786 || streq (cp1
, "src") /* BSO/Tasking C compiler output */
787 || streq (cp1
, "def") /* BSO/Tasking definition includes */
788 || streq (cp1
, "ins") /* Microcontroller include files */
789 || streq (cp1
, "inc")))/* Microcontroller include files */
792 goto close_and_return
;
794 /* .C or .H or .cxx or .hxx or .cc: a C++ file */
795 if (cp
&& (streq (cp1
, "C")
797 || streq (cp1
, "cxx")
798 || streq (cp1
, "hxx")
799 || streq (cp1
, "cc")))
801 C_entries (C_PLPL
, inf
); /* C++ */
802 goto close_and_return
;
804 /* .cs or .hs: a C* file */
805 if (cp
&& (streq (cp1
, "cs")
806 || streq (cp1
, "hs")))
808 C_entries (C_STAR
, inf
);
809 goto close_and_return
;
811 /* .y: a yacc file */
812 if (cp
&& (streq (cp1
, "y")))
814 C_entries (YACC
, inf
);
815 goto close_and_return
;
817 /* .pl implies prolog source code */
818 if (cp
&& streq (cp1
, "pl"))
820 Prolog_functions (inf
);
821 goto close_and_return
;
823 /* .p or .pas: a Pascal file */
824 if (cp
&& (streq (cp1
, "p")
825 || streq (cp1
, "pas")))
827 Pascal_functions (inf
);
828 goto close_and_return
;
830 /* If .f or .for, assume it is fortran or nothing. */
831 if (cp
&& (streq (cp1
, "f")
832 || streq (cp1
, "for")))
834 (void) Fortran_functions (inf
);
835 goto close_and_return
;
837 /* if not a .c or .h or .y file, try fortran */
838 if (cp
&& ((cp
[1] != 'c'
841 || (cp
[1] != 0 && cp
[2] != 0)))
843 if (Fortran_functions (inf
) != 0)
844 goto close_and_return
;
845 rewind (inf
); /* no fortran tags found, try C */
847 C_entries (cplusplus
? C_PLPL
: 0, inf
);
854 /* Nonzero if string STR is composed of digits. */
857 string_numeric_p (str
)
862 if (*str
< '0' || *str
> '9')
869 /* Should take a TOKEN* instead!! */
871 pfnote (name
, is_func
, named
, linestart
, linelen
, lno
, cno
)
872 char *name
; /* tag name */
873 logical is_func
; /* function or type name? */
874 logical named
; /* tag different from text of definition? */
890 /* It's okay to output early in etags -- it only disrupts the
891 * character count of the tag entries, which is no longer used
894 error ("too many entries to sort", 0);
901 /* If ctags mode, change name "main" to M<thisfilename>. */
902 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
904 fp
= etags_strrchr (curfile
, '/');
905 name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
906 fp
= etags_strrchr (name
, '.');
907 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
911 np
->name
= savestr (name
);
913 np
->is_func
= is_func
;
916 /* UNCOMMENT THE +1 HERE: */
917 np
->cno
= cno
/* + 1 */ ; /* our char numbers are 0-base; emacs's are 1-base */
918 np
->left
= np
->right
= 0;
921 c
= linestart
[linelen
];
922 linestart
[linelen
] = 0;
924 else if (cxref_style
== 0)
926 sprintf (tem
, strlen (linestart
) < 50 ? "%s$" : "%.50s", linestart
);
929 np
->pat
= savestr (linestart
);
932 linestart
[linelen
] = c
;
935 add_node (np
, &head
);
940 * recurse on left children, iterate on right children.
948 register NODE
*node_right
= node
->right
;
949 free_tree (node
->left
);
952 free ((char *) node
);
959 * Adds a node to the tree of nodes. In etags mode, we don't keep
960 * it sorted; we just keep a linear list. In ctags mode, maintain
961 * an ordered tree, with no attempt at balancing.
963 * add_node is the only function allowed to add nodes, so it can
966 /* Must avoid static vars within functions since some systems
967 #define static as nothing. */
968 NODE
*last_node
= NULL
;
971 add_node (node
, cur_node_p
)
972 NODE
*node
, **cur_node_p
;
975 register NODE
*cur_node
= *cur_node_p
;
977 if (cur_node
== NULL
)
987 if (last_node
== NULL
)
988 fatal ("internal error in add_node", 0);
989 last_node
->right
= node
;
995 dif
= strcmp (node
->name
, cur_node
->name
);
998 * If this tag name matches an existing one, then
999 * do not add the node, but maybe print a warning.
1003 if (node
->file
== cur_node
->file
)
1007 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1008 node
->file
, lineno
, node
->name
);
1009 fprintf (stderr
, "Second entry ignored\n");
1013 if (!cur_node
->been_warned
&& !no_warnings
)
1016 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1017 node
->file
, cur_node
->file
, node
->name
);
1019 cur_node
->been_warned
= TRUE
;
1023 /* Maybe refuse to add duplicate nodes. */
1024 if (!permit_duplicates
)
1026 if (streq (node
->name
, cur_node
->name
)
1027 && streq (node
->file
, cur_node
->file
))
1031 /* Actually add the node */
1032 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1038 register NODE
*node
;
1045 /* Output subentries that precede this one */
1046 put_entries (node
->left
);
1048 /* Output this entry */
1054 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1055 node
->pat
, node
->name
,
1056 node
->lno
, node
->cno
);
1060 fprintf (tagf
, "%s\177%d,%d\n",
1062 node
->lno
, node
->cno
);
1065 else if (!cxref_style
)
1067 fprintf (tagf
, "%s\t%s\t",
1068 node
->name
, node
->file
);
1072 putc (searchar
, tagf
);
1075 for (sp
= node
->pat
; *sp
; sp
++)
1077 if (*sp
== '\\' || *sp
== searchar
)
1081 putc (searchar
, tagf
);
1084 { /* a typedef; text pattern inadequate */
1085 fprintf (tagf
, "%d", node
->lno
);
1089 else if (vgrind_style
)
1090 fprintf (stdout
, "%s %s %d\n",
1091 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1093 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1094 node
->name
, node
->lno
, node
->file
, node
->pat
);
1096 /* Output subentries that follow this one */
1097 put_entries (node
->right
);
1100 /* Length of a number's decimal representation. */
1108 for (; num
; num
/= 10)
1114 * Return total number of characters that put_entries will output for
1115 * the nodes in the subtree of the specified node. Works only if
1116 * we are not ctags, but called only in that case. This count
1117 * is irrelevant with the new tags.el, but is still supplied for
1118 * backward compatibility.
1121 total_size_of_entries (node
)
1122 register NODE
*node
;
1130 for (; node
; node
= node
->right
)
1132 /* Count left subentries. */
1133 total
+= total_size_of_entries (node
->left
);
1135 /* Count this entry */
1136 total
+= strlen (node
->pat
) + 1;
1137 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1139 total
+= 1 + strlen (node
->name
); /* \001name */
1146 * The C symbol tables.
1149 /* Feed stuff between (but not including) %[ and %] lines to:
1150 gperf -c -k1,3 -o -p -r -t
1152 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1154 class, C_PLPL, st_C_struct
1155 domain, C_STAR, st_C_struct
1156 union, 0, st_C_struct
1157 struct, 0, st_C_struct
1159 typedef, 0, st_C_typedef
1160 define, 0, st_C_define
1161 long, 0, st_C_typespec
1162 short, 0, st_C_typespec
1163 int, 0, st_C_typespec
1164 char, 0, st_C_typespec
1165 float, 0, st_C_typespec
1166 double, 0, st_C_typespec
1167 signed, 0, st_C_typespec
1168 unsigned, 0, st_C_typespec
1169 auto, 0, st_C_typespec
1170 void, 0, st_C_typespec
1171 extern, 0, st_C_typespec
1172 static, 0, st_C_typespec
1173 const, 0, st_C_typespec
1174 volatile, 0, st_C_typespec
1176 and replace lines between %< and %> with its output. */
1178 /* C code produced by gperf version 1.8.1 (K&R C version) */
1179 /* Command-line: gperf -c -k1,3 -o -p -r -t */
1182 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1184 #define MIN_WORD_LENGTH 3
1185 #define MAX_WORD_LENGTH 8
1186 #define MIN_HASH_VALUE 10
1187 #define MAX_HASH_VALUE 62
1190 53 is the maximum key range
1198 static unsigned char hash_table
[] =
1200 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1201 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1202 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1203 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1204 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1205 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1206 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1207 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1208 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1209 62, 62, 62, 62, 62, 62, 62, 2, 62, 7,
1210 6, 9, 15, 30, 62, 24, 62, 62, 1, 24,
1211 7, 27, 13, 62, 19, 26, 18, 27, 1, 62,
1212 62, 62, 62, 62, 62, 62, 62, 62,
1214 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1217 struct C_stab_entry
*
1218 in_word_set (str
, len
)
1223 static struct C_stab_entry wordlist
[] =
1225 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1227 {"volatile", 0, st_C_typespec
},
1229 {"long", 0, st_C_typespec
},
1230 {"char", 0, st_C_typespec
},
1231 {"class", C_PLPL
, st_C_struct
},
1232 {"",}, {"",}, {"",}, {"",},
1233 {"const", 0, st_C_typespec
},
1234 {"",}, {"",}, {"",}, {"",},
1235 {"auto", 0, st_C_typespec
},
1237 {"define", 0, st_C_define
},
1239 {"void", 0, st_C_typespec
},
1240 {"",}, {"",}, {"",},
1241 {"extern", 0, st_C_typespec
},
1242 {"static", 0, st_C_typespec
},
1244 {"domain", C_STAR
, st_C_struct
},
1246 {"typedef", 0, st_C_typedef
},
1247 {"double", 0, st_C_typespec
},
1248 {"enum", 0, st_C_enum
},
1249 {"",}, {"",}, {"",}, {"",},
1250 {"int", 0, st_C_typespec
},
1252 {"float", 0, st_C_typespec
},
1253 {"",}, {"",}, {"",},
1254 {"struct", 0, st_C_struct
},
1255 {"",}, {"",}, {"",}, {"",},
1256 {"union", 0, st_C_struct
},
1258 {"short", 0, st_C_typespec
},
1260 {"unsigned", 0, st_C_typespec
},
1261 {"signed", 0, st_C_typespec
},
1264 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1266 register int key
= hash (str
, len
);
1268 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1270 register char *s
= wordlist
[key
].name
;
1272 if (*s
== *str
&& strneq (str
+ 1, s
+ 1, len
- 1))
1273 return &wordlist
[key
];
1281 C_symtype(str
, len
, c_ext
)
1286 register struct C_stab_entry
*se
= in_word_set(str
, len
);
1288 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1294 * C functions are recognized using a simple finite automaton.
1295 * funcdef is its state variable.
1299 fnone
, /* nothing seen */
1300 ftagseen
, /* function-like tag seen */
1301 fstartlist
, /* just after open parenthesis */
1302 finlist
, /* in parameter list */
1303 flistseen
, /* after parameter list */
1304 fignore
/* before open brace */
1310 * typedefs are recognized using a simple finite automaton.
1311 * typeddef is its state variable.
1315 tnone
, /* nothing seen */
1316 ttypedseen
, /* typedef keyword seen */
1317 tinbody
, /* inside typedef body */
1318 tend
, /* just before typedef tag */
1319 tignore
/* junk after typedef tag */
1325 * struct-like structures (enum, struct and union) are recognized
1326 * using another simple finite automaton. `structdef' is its state
1331 snone
, /* nothing seen yet */
1332 skeyseen
, /* struct-like keyword seen */
1333 stagseen
, /* struct-like tag seen */
1334 scolonseen
, /* colon seen after struct-like tag */
1335 sinbody
/* in struct body: recognize member func defs*/
1340 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1341 * struct tag, and structtype is the type of the preceding struct-like
1344 char structtag
[BUFSIZ
];
1345 enum sym_type structtype
;
1348 * Yet another little state machine to deal with preprocessor lines.
1352 dnone
, /* nothing seen */
1353 dsharpseen
, /* '#' seen as first char on line */
1354 ddefineseen
, /* '#' and 'define' seen */
1355 dignorerest
/* ignore rest of line */
1360 * Set this to TRUE, and the next token considered is called a function.
1361 * Used only for GNUmacs's function-defining macros.
1363 logical next_token_is_func
;
1366 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1372 * checks to see if the current token is at the start of a
1373 * function, or corresponds to a typedef, or is a struct/union/enum
1376 * *IS_FUNC gets TRUE iff the token is a function or macro with args.
1377 * C_EXT is which language we are looking at.
1379 * In the future we will need some way to adjust where the end of
1380 * the token is; for instance, implementing the C++ keyword
1381 * `operator' properly will adjust the end of the token to be after
1382 * whatever follows `operator'.
1389 * next_token_is_func IN OUT
1393 consider_token (c
, tokp
, c_ext
, cblev
, is_func
)
1394 register char c
; /* IN: first char after the token */
1395 register TOKEN
*tokp
; /* IN: token pointer */
1396 int c_ext
; /* IN: C extensions mask */
1397 int cblev
; /* IN: curly brace level */
1398 logical
*is_func
; /* OUT */
1400 enum sym_type toktype
= C_symtype(tokp
->p
, tokp
->len
, c_ext
);
1403 * Advance the definedef state machine.
1408 /* We're not on a preprocessor line. */
1411 if (toktype
== st_C_define
)
1413 definedef
= ddefineseen
;
1417 definedef
= dignorerest
;
1422 * Make a tag for any macro.
1424 definedef
= dignorerest
;
1425 *is_func
= (c
== '(');
1426 if (!*is_func
&& !constantypedefs
)
1433 error ("internal error: definedef value.", 0);
1442 if (toktype
== st_C_typedef
)
1445 typdef
= ttypedseen
;
1461 /* Do not return here, so the structdef stuff has a chance. */
1475 * This structdef business is currently only invoked when cblev==0.
1476 * It should be recursively invoked whatever the curly brace level,
1477 * and a stack of states kept, to allow for definitions of structs
1480 * This structdef business is NOT invoked when we are ctags and the
1481 * file is plain C. This is because a struct tag may have the same
1482 * name as another tag, and this loses with ctags.
1484 * This if statement deals with the typdef state machine as
1485 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1486 * return (FALSE). All the other code here is for the structdef
1493 if (typdef
== ttypedseen
1494 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
1496 structdef
= skeyseen
;
1497 structtype
= toktype
;
1501 if (structdef
== skeyseen
)
1503 if (structtype
== st_C_struct
)
1505 strncpy (structtag
, tokp
->p
, tokp
->len
);
1506 structtag
[tokp
->len
] = '\0'; /* for struct/union/class */
1510 structtag
[0] = '\0'; /* for enum (why is it treated differently?) */
1512 structdef
= stagseen
;
1516 /* Avoid entering funcdef stuff if typdef is going on. */
1517 if (typdef
!= tnone
)
1523 /* Detect GNUmacs's function-defining macros. */
1524 if (definedef
== dnone
)
1526 if (strneq (tokp
->p
, "DEF", 3)
1527 || strneq (tokp
->p
, "ENTRY", 5)
1528 || strneq (tokp
->p
, "SYSCALL", 7)
1529 || strneq (tokp
->p
, "PSEUDO", 6))
1531 next_token_is_func
= TRUE
;
1534 if (strneq (tokp
->p
, "EXFUN", 5))
1536 next_token_is_func
= FALSE
;
1540 if (next_token_is_func
)
1542 next_token_is_func
= FALSE
;
1544 *is_func
= TRUE
; /* to force search string in ctags */
1552 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1553 funcdef
= fnone
; /* should be useless */
1556 if (funcdef
== fnone
)
1569 * This routine finds functions, typedefs, #define's and
1570 * struct/union/enum definitions in C syntax and adds them
1574 #define curlb (lbs[curndx].lb)
1575 #define othlb (lbs[1-curndx].lb)
1576 #define newlb (lbs[newndx].lb)
1577 #define curlinepos (lbs[curndx].linepos)
1578 #define othlinepos (lbs[1-curndx].linepos)
1579 #define newlinepos (lbs[newndx].linepos)
1581 /* Save and restore token state. This is used when preprocessor defines
1582 are handled, to avoid disturbing active function/typedef/struct states. */
1583 #define TOKEN_SAVED_P (savetok.lineno > 0)
1584 #define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \
1585 savetok.len = toklen, strcpy(savenameb, nameb))
1586 #define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \
1587 toklen = tok.len, strcpy(nameb, savenameb), \
1590 #define CNL_SAVE_DEFINEDEF \
1592 SET_FILEPOS (curlinepos, inf, charno); \
1594 charno += readline (&curlb, inf); \
1595 lp = curlb.buffer; \
1602 CNL_SAVE_DEFINEDEF; \
1603 if (TOKEN_SAVED_P) \
1605 definedef = dnone; \
1608 #define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \
1609 newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos))
1610 #define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (nameb, isfun, tok.named, \
1611 othlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (othlinepos))
1614 C_entries (c_ext
, inf
)
1615 int c_ext
; /* extension of C? */
1618 register char c
; /* latest char read; '\0' for end of line */
1619 register char *lp
; /* pointer one beyond the character `c' */
1620 int curndx
, newndx
; /* indices for current and new lb */
1621 TOKEN tok
; /* latest token read for funcdef & structdef */
1622 char nameb
[BUFSIZ
]; /* latest token name for funcdef & structdef */
1623 register int tokoff
; /* offset in line of start of latest token */
1624 register int toklen
; /* length of latest token */
1625 int cblev
; /* current curly brace level */
1626 int parlev
; /* current parenthesis level */
1627 logical incomm
, inquote
, inchar
, quotednl
, midtoken
;
1629 TOKEN savetok
; /* saved token during preprocessor handling */
1630 char savenameb
[BUFSIZ
]; /* ouch! */
1633 curndx
= newndx
= 0;
1639 definedef
= dnone
; funcdef
= fnone
; typdef
= tnone
; structdef
= snone
;
1640 next_token_is_func
= yacc_rules
= FALSE
;
1641 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1644 cplpl
= c_ext
& C_PLPL
;
1651 /* If we're at the end of the line, the next character is a
1652 '\0'; don't skip it, because it's the thing that tells us
1653 to read the next line. */
1674 /* Newlines inside comments do not end macro definitions in
1689 /* Newlines inside strings do not end macro definitions
1690 in traditional cpp, even though compilers don't
1691 usually accept them. */
1702 /* Hmmm, something went wrong. */
1716 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1721 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1731 else if (cplpl
&& *lp
== '/')
1739 if ((c_ext
& YACC
) && *lp
== '%')
1741 /* entering or exiting rules section in yacc file */
1743 definedef
= dnone
; funcdef
= fnone
;
1744 typdef
= tnone
; structdef
= snone
;
1745 next_token_is_func
= FALSE
;
1746 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1748 yacc_rules
= !yacc_rules
;
1754 if (lp
== newlb
.buffer
+ 1 && definedef
== dnone
)
1755 definedef
= dsharpseen
;
1760 /* Consider token only if some complicated conditions are satisfied. */
1761 if (((cblev
== 0 && structdef
!= scolonseen
)
1762 || (cblev
== 1 && cplpl
&& structdef
== sinbody
))
1763 && typdef
!= tignore
1764 && definedef
!= dignorerest
1765 && (funcdef
!= finlist
1766 || definedef
!= dnone
))
1772 if (cplpl
&& c
== ':' && *lp
== ':' && begtoken(*(lp
+ 1)))
1775 * This handles :: in the middle, but not at beginning
1783 logical is_func
= FALSE
;
1785 tok
.lineno
= lineno
;
1786 tok
.p
= newlb
.buffer
+ tokoff
;
1790 || consider_token (c
, &tok
, c_ext
, cblev
, &is_func
))
1792 if (structdef
== sinbody
1793 && definedef
== dnone
1795 /* function defined in C++ class body */
1798 sprintf (nameb
, "%s::%.*s",
1799 ((structtag
[0] == '\0')
1800 ? "_anonymous_" : structtag
),
1805 sprintf (nameb
, "%.*s", tok
.len
, tok
.p
);
1808 if (structdef
== stagseen
1812 if (definedef
== dnone
1813 && (funcdef
== ftagseen
1814 || structdef
== stagseen
1817 if (newndx
== curndx
)
1818 curndx
= 1 - curndx
; /* switch line buffers */
1821 MAKE_TAG_FROM_NEW_LB (is_func
);
1825 } /* if (endtoken (c)) */
1826 else if (intoken (c
))
1831 } /* if (midtoken) */
1832 else if (begtoken (c
))
1843 MAKE_TAG_FROM_OTH_LB (TRUE
);
1850 if (structdef
== stagseen
)
1854 /* Take a quick peek ahead for define directive,
1855 so we can avoid saving the token when not absolutely
1856 necessary. [This is a speed hack.] */
1857 if (c
== 'd' && strneq(lp
, "efine", 5)
1858 && iswhite(*(lp
+ 5)))
1861 definedef
= ddefineseen
;
1865 definedef
= dignorerest
;
1868 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
1870 tokoff
= lp
- 1 - newlb
.buffer
;
1876 } /* if must look at token */
1879 /* Detect end of line, colon, comma, semicolon and various braces
1880 after having handled a token.*/
1884 if (definedef
!= dnone
)
1886 if (structdef
== stagseen
)
1887 structdef
= scolonseen
;
1894 MAKE_TAG_FROM_OTH_LB (FALSE
);
1904 if (definedef
!= dnone
)
1910 MAKE_TAG_FROM_OTH_LB (FALSE
);
1915 if (funcdef
!= fignore
)
1917 if (structdef
== stagseen
)
1921 if (definedef
!= dnone
)
1923 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1925 if (structdef
== stagseen
)
1929 if (definedef
!= dnone
)
1931 if (cblev
== 0 && typdef
== tend
)
1934 MAKE_TAG_FROM_OTH_LB (FALSE
);
1937 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1939 if (structdef
== stagseen
)
1943 if (definedef
!= dnone
)
1948 funcdef
= fstartlist
;
1957 if (definedef
!= dnone
)
1965 funcdef
= flistseen
;
1968 if (cblev
== 0 && typdef
== tend
)
1971 MAKE_TAG_FROM_OTH_LB (FALSE
);
1974 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
1978 if (definedef
!= dnone
)
1980 if (typdef
== ttypedseen
)
1984 case skeyseen
: /* unnamed struct */
1985 structtag
[0] = '\0';
1986 structdef
= sinbody
;
1989 case scolonseen
: /* named struct */
1990 structdef
= sinbody
;
1991 MAKE_TAG_FROM_OTH_LB (FALSE
);
1997 MAKE_TAG_FROM_OTH_LB (TRUE
);
2003 /* Neutralize `extern "C" {' grot.
2004 if (cblev == 0 && structdef == snone && typdef == tnone)
2010 if (definedef
!= dnone
)
2012 if (funcdef
== fstartlist
)
2013 funcdef
= fnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2016 if (definedef
!= dnone
)
2018 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2020 cblev
= 0; /* reset curly brace level if first column */
2021 parlev
= 0; /* also reset paren level, just in case... */
2027 if (typdef
== tinbody
)
2030 strcpy (structtag
, "<error 2>");
2034 case '#': case '+': case '-': case '~': case '&': case '%': case '/':
2035 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2036 if (definedef
!= dnone
)
2038 /* These surely cannot follow a function tag. */
2039 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2043 /* If a macro spans multiple lines don't reset its state. */
2051 } /* while not eof */
2054 /* Fortran parsing */
2063 register int len
= 0;
2065 while (*cp
&& (*cp
| ' ') == (dbp
[len
] | ' '))
2078 while (isspace (*dbp
))
2083 while (isspace (*dbp
))
2085 if (!isdigit (*dbp
))
2087 --dbp
; /* force failure */
2092 while (isdigit (*dbp
));
2101 char nambuf
[BUFSIZ
];
2103 while (isspace (*dbp
))
2108 linecharno
= charno
;
2109 charno
+= readline (&lb
, inf
);
2114 while (isspace (*dbp
))
2123 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
2128 strcpy (nambuf
, dbp
);
2130 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
,
2131 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2136 Fortran_functions (inf
)
2146 linecharno
= charno
;
2147 charno
+= readline (&lb
, inf
);
2150 dbp
++; /* Ratfor escape to fortran */
2151 while (isspace (*dbp
))
2158 if (tail ("integer"))
2166 if (tail ("logical"))
2170 if (tail ("complex") || tail ("character"))
2174 if (tail ("double"))
2176 while (isspace (*dbp
))
2180 if (tail ("precision"))
2186 while (isspace (*dbp
))
2193 if (tail ("function"))
2197 if (tail ("subroutine"))
2205 if (tail ("program"))
2210 if (tail ("procedure"))
2219 * Bob Weiner, Motorola Inc., 4/3/94
2220 * Unix and microcontroller assembly tag handling
2221 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
2227 char nambuf
[BUFSIZ
];
2238 linecharno
= charno
;
2239 charno
+= readline (&lb
, inf
);
2242 /* If first char is alphabetic or one of [_.$], test for colon
2243 following identifier. */
2244 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2246 /* Read past label. */
2248 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2250 if (*cp
== ':' || isspace (*cp
))
2252 /* Found end of label, so copy it and add it to the table. */
2255 strcpy (nambuf
, lb
.buffer
);
2257 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
,
2258 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2265 /* Added by Mosur Mohan, 4/22/88 */
2266 /* Pascal parsing */
2268 #define GET_NEW_LINE \
2270 linecharno = charno; lineno++; \
2271 charno += 1 + readline (&lb, inf); \
2275 /* Locates tags for procedures & functions.
2276 * Doesn't do any type- or var-definitions.
2277 * It does look for the keyword "extern" or "forward"
2278 * immediately following the procedure statement;
2279 * if found, the tag is skipped.
2283 Pascal_functions (inf
)
2286 struct linebuffer tline
; /* mostly copied from C_entries */
2290 char nambuf
[BUFSIZ
];
2292 logical
/* each of these flags is TRUE iff: */
2293 incomm1
, /* point is inside {..} comment */
2294 incomm2
, /* point is inside (*..*) comment */
2295 inquote
, /* point is inside '..' string */
2296 get_tagname
, /* point is after PROCEDURE/FUNCTION */
2297 /* keyword, so next item = potential tag */
2298 found_tag
, /* point is after a potential tag */
2299 inparms
, /* point is within parameter-list */
2300 verify_tag
; /* point has passed the parm-list, so the */
2301 /* next token will determine whether */
2302 /* this is a FORWARD/EXTERN to be */
2303 /* ignored, or whether it is a real tag */
2309 initbuffer (&tline
);
2311 incomm1
= incomm2
= inquote
= FALSE
;
2312 found_tag
= FALSE
; /* have a proc name; check if extern */
2313 get_tagname
= FALSE
; /* have found "procedure" keyword */
2314 inparms
= FALSE
; /* found '(' after "proc" */
2315 verify_tag
= FALSE
; /* check if "extern" is ahead */
2317 /* long main loop to get next char */
2321 if (c
== 0) /* if end of line */
2326 if (!((found_tag
&& verify_tag
) ||
2328 c
= *dbp
++; /* only if don't need *dbp pointing */
2329 /* to the beginning of the name of */
2330 /* the procedure or function */
2332 if (incomm1
) /* within { - } comments */
2338 else if (incomm2
) /* within (* - *) comments */
2342 while ((c
= *dbp
++) == '*')
2361 inquote
= TRUE
; /* found first quote */
2363 case '{': /* found open-{-comment */
2367 if (*dbp
== '*') /* found open-(*-comment */
2372 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
2375 case ')': /* end of parms list */
2380 if ((found_tag
) && (!inparms
)) /* end of proc or fn stmt */
2387 if ((found_tag
) && (verify_tag
) && (*dbp
!= ' '))
2389 /* check if this is an "extern" declaration */
2392 if ((*dbp
== 'e') || (*dbp
== 'E'))
2394 if (tail ("extern")) /* superfluous, really! */
2400 else if ((*dbp
== 'f') || (*dbp
== 'F'))
2402 if (tail ("forward")) /* check for forward reference */
2408 if ((found_tag
) && (verify_tag
)) /* not external proc, so make tag */
2412 pfnote (nambuf
, TRUE
, FALSE
,
2413 tline
.buffer
, cp
- tline
.buffer
+ 1,
2414 save_lineno
, save_lcno
);
2418 if (get_tagname
) /* grab name of proc or fn */
2423 /* save all values for later tagging */
2424 tline
.size
= lb
.size
;
2425 strcpy (tline
.buffer
, lb
.buffer
);
2426 save_lineno
= lineno
;
2427 save_lcno
= linecharno
;
2429 /* grab block name */
2430 for (cp
= dbp
+ 1; *cp
&& (!endtoken (*cp
)); cp
++)
2434 strcpy (nambuf
, dbp
);
2436 dbp
= cp
; /* restore dbp to e-o-token */
2437 get_tagname
= FALSE
;
2441 /* and proceed to check for "extern" */
2443 if ((!incomm1
) && (!incomm2
) && (!inquote
) &&
2444 (!found_tag
) && (!get_tagname
))
2446 /* check for proc/fn keywords */
2450 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
2454 if (tail ("unction"))
2459 } /* while not eof */
2463 * lisp tag functions
2464 * just look for (def or (DEF
2471 return ((dbp
[1] == 'd' || dbp
[1] == 'D')
2472 && (dbp
[2] == 'e' || dbp
[2] == 'E')
2473 && (dbp
[3] == 'f' || dbp
[3] == 'F'));
2480 return ((*(++dbp
) == 'q' || *dbp
== 'Q')
2481 && (*(++dbp
) == 'u' || *dbp
== 'U')
2482 && (*(++dbp
) == 'o' || *dbp
== 'O')
2483 && (*(++dbp
) == 't' || *dbp
== 'T')
2484 && (*(++dbp
) == 'e' || *dbp
== 'E')
2485 && isspace(*(++dbp
)));
2493 char nambuf
[BUFSIZ
];
2495 if (*dbp
== '\'') /* Skip prefix quote */
2497 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
2500 while (isspace(*dbp
))
2503 for (cp
= dbp
/*+1*/; *cp
&& *cp
!= '(' && *cp
!= ' ' && *cp
!= ')'; cp
++)
2510 strcpy (nambuf
, dbp
);
2512 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
,
2513 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2518 Lisp_functions (inf
)
2528 linecharno
= charno
;
2529 charno
+= readline (&lb
, inf
);
2535 while (!isspace (*dbp
))
2537 while (isspace (*dbp
))
2543 /* Check for (foo::defmumble name-defined ... */
2546 while (*dbp
&& !isspace (*dbp
)
2547 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
2552 while (*dbp
== ':');
2554 if (L_isdef (dbp
- 1))
2556 while (!isspace (*dbp
))
2558 while (isspace (*dbp
))
2569 * Scheme tag functions
2570 * look for (def... xyzzy
2571 * look for (def... (xyzzy
2572 * look for (def ... ((...(xyzzy ....
2573 * look for (set! xyzzy
2579 Scheme_functions (inf
)
2589 linecharno
= charno
;
2590 charno
+= readline (&lb
, inf
);
2592 if (dbp
[0] == '(' &&
2593 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
2594 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2595 (dbp
[3] == 'F' || dbp
[3] == 'f'))
2597 while (!isspace (*dbp
))
2599 /* Skip over open parens and white space */
2600 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
2604 if (dbp
[0] == '(' &&
2605 (dbp
[1] == 'S' || dbp
[1] == 's') &&
2606 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2607 (dbp
[3] == 'T' || dbp
[3] == 't') &&
2608 (dbp
[4] == '!' || dbp
[4] == '!') &&
2611 while (!isspace (*dbp
))
2613 /* Skip over white space */
2614 while (isspace (*dbp
))
2626 char nambuf
[BUFSIZ
];
2630 /* Go till you get to white space or a syntactic break */
2631 for (cp
= dbp
+ 1; *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
); cp
++)
2633 /* Null terminate the string there. */
2636 /* Copy the string */
2637 strcpy (nambuf
, dbp
);
2638 /* Unterminate the string */
2640 /* Announce the change */
2641 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2645 /* Find tags in TeX and LaTeX input files. */
2647 /* TEX_toktab is a table of TeX control sequences that define tags.
2648 Each TEX_tabent records one such control sequence.
2649 CONVERT THIS TO USE THE Stab TYPE!! */
2657 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
2659 /* Default set of control sequences to put into TEX_toktab.
2660 The value of environment var TEXTAGS is prepended to this. */
2662 char *TEX_defenv
= "\
2663 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
2666 struct TEX_tabent
*TEX_decode_env ();
2670 char TEX_esc
= '\\';
2671 char TEX_opgrp
= '{';
2672 char TEX_clgrp
= '}';
2675 * TeX/LaTeX scanning loop.
2688 /* Select either \ or ! as escape character. */
2691 /* Initialize token table once from environment. */
2693 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
2696 { /* Scan each line in file */
2698 linecharno
= charno
;
2699 charno
+= readline (&lb
, inf
);
2702 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
2708 linecharno
+= dbp
- lasthit
;
2710 i
= TEX_Token (lasthit
);
2713 TEX_getit (lasthit
, TEX_toktab
[i
].len
);
2714 break; /* We only save a line once */
2720 #define TEX_LESC '\\'
2721 #define TEX_SESC '!'
2724 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping */
2725 /* chars accordingly. */
2733 while ((c
= getc (inf
)) != EOF
)
2735 /* Skip to next line if we hit the TeX comment char. */
2739 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
2758 /* Read environment and prepend it to the default string. */
2759 /* Build token table. */
2762 TEX_decode_env (evarname
, defenv
)
2766 register char *env
, *p
;
2768 struct TEX_tabent
*tab
;
2771 /* Append default string to environment. */
2772 env
= getenv (evarname
);
2776 env
= concat (env
, defenv
, "");
2778 /* Allocate a token table */
2779 for (size
= 1, p
= env
; p
;)
2780 if ((p
= etags_strchr (p
, ':')) && *(++p
))
2782 /* Add 1 to leave room for null terminator. */
2783 tab
= xnew (size
+ 1, struct TEX_tabent
);
2785 /* Unpack environment string into token table. Be careful about */
2786 /* zero-length strings (leading ':', "::" and trailing ':') */
2789 p
= etags_strchr (env
, ':');
2790 if (!p
) /* End of environment string. */
2791 p
= env
+ strlen (env
);
2793 { /* Only non-zero strings. */
2794 tab
[i
].name
= savenstr (env
, p
- env
);
2795 tab
[i
].len
= strlen (tab
[i
].name
);
2802 tab
[i
].name
= NULL
; /* Mark end of table. */
2810 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
2811 The name being defined actually starts at (NAME + LEN + 1).
2812 But we seem to include the TeX command in the tag name. */
2815 TEX_getit (name
, len
)
2819 char *p
= name
+ len
;
2820 char nambuf
[BUFSIZ
];
2825 /* Let tag name extend to next group close (or end of line) */
2826 while (*p
&& *p
!= TEX_clgrp
)
2828 strncpy (nambuf
, name
, p
- name
);
2829 nambuf
[p
- name
] = 0;
2831 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
2835 /* If the text at CP matches one of the tag-defining TeX command names,
2836 return the pointer to the first occurrence of that command in TEX_toktab.
2837 Otherwise return -1. */
2839 /* Keep the capital `T' in `Token' for dumb truncating compilers
2840 (this distinguishes it from `TEX_toktab' */
2847 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
2848 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
2853 /* Support for Prolog. */
2855 /* whole head (not only functor, but also arguments)
2856 is gotten in compound term. */
2859 prolog_getit (s
, lineno
, linecharno
)
2864 char nambuf
[BUFSIZ
], *save_s
, tmpc
;
2872 if (*s
== '\0') /* syntax error. */
2874 else if (insquote
&& *s
== '\'' && *(s
+ 1) == '\'')
2876 else if (*s
== '\'')
2878 insquote
= !insquote
;
2881 else if (!insquote
&& *s
== '(')
2886 else if (!insquote
&& *s
== ')')
2892 else if (npar
< 0) /* syntax error. */
2895 else if (!insquote
&& *s
== '.' && (isspace (*(s
+ 1)) || *(s
+ 1) == '\0'))
2897 if (npar
!= 0) /* syntax error. */
2907 strcpy (nambuf
, save_s
);
2909 pfnote (nambuf
, TRUE
, FALSE
, save_s
, strlen (nambuf
), lineno
, linecharno
);
2912 /* It is assumed that prolog predicate starts from column 0. */
2915 Prolog_functions (inf
)
2918 void skip_comment (), prolog_getit ();
2920 lineno
= linecharno
= charno
= 0;
2924 linecharno
+= charno
;
2925 charno
= readline (&lb
, inf
) + 1; /* 1 for newline. */
2927 if (isspace (dbp
[0])) /* not predicate header. */
2929 else if (dbp
[0] == '%') /* comment. */
2931 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
2932 skip_comment (&lb
, inf
, &lineno
, &linecharno
);
2934 prolog_getit (dbp
, lineno
, linecharno
);
2939 skip_comment (plb
, inf
, plineno
, plinecharno
)
2940 struct linebuffer
*plb
;
2942 int *plineno
; /* result */
2943 long *plinecharno
; /* result */
2945 while (!substr ("*/", plb
->buffer
))
2948 *plinecharno
+= readline (plb
, inf
) + 1;
2949 } /* 1 for newline. */
2952 /* Return TRUE if 'sub' exists somewhere in 's'. */
2959 while (*s
&& (s
= etags_strchr (s
, *sub
)))
2960 if (prestr (sub
, s
))
2967 /* Return TRUE if 'pre' is prefix of string 's'. */
2976 else if (*pre
== *s
)
2977 return (prestr (pre
+ 1, s
+ 1));
2982 /* Initialize a linebuffer for use */
2985 initbuffer (linebuffer
)
2986 struct linebuffer
*linebuffer
;
2988 linebuffer
->size
= 200;
2989 linebuffer
->buffer
= xnew (200, char);
2993 * Read a line of text from `stream' into `linebuffer'.
2994 * Return the number of characters read from `stream',
2995 * which is the length of the line including the newline, if any.
2998 readline (linebuffer
, stream
)
2999 struct linebuffer
*linebuffer
;
3000 register FILE *stream
;
3002 char *buffer
= linebuffer
->buffer
;
3003 register char *p
= linebuffer
->buffer
;
3004 register char *pend
;
3005 int newline
; /* 1 if ended with newline, 0 if ended with EOF */
3007 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
3011 register int c
= getc (stream
);
3014 linebuffer
->size
*= 2;
3015 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
3016 p
+= buffer
- linebuffer
->buffer
;
3017 pend
= buffer
+ linebuffer
->size
;
3018 linebuffer
->buffer
= buffer
;
3020 if (c
== EOF
|| c
== '\n')
3023 newline
= (c
== '\n') ? 1 : 0;
3029 return p
- buffer
+ newline
;
3036 return savenstr (cp
, strlen (cp
));
3046 dp
= xnew (len
+ 1, char);
3047 strncpy (dp
, cp
, len
);
3053 * Return the ptr in sp at which the character c last
3054 * appears; NULL if not found
3056 * Identical to System V strrchr, included for portability.
3060 etags_strrchr (sp
, c
)
3061 register char *sp
, c
;
3076 * Return the ptr in sp at which the character c first
3077 * appears; NULL if not found
3079 * Identical to System V strchr, included for portability.
3083 etags_strchr (sp
, c
)
3084 register char *sp
, c
;
3094 /* Print error message and exit. */
3105 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
3112 fprintf (stderr
, "%s: ", progname
);
3113 fprintf (stderr
, s1
, s2
);
3114 fprintf (stderr
, "\n");
3117 /* Return a newly-allocated string whose contents
3118 concatenate those of s1, s2, s3. */
3124 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
3125 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
3127 strcpy (result
, s1
);
3128 strcpy (result
+ len1
, s2
);
3129 strcpy (result
+ len1
+ len2
, s3
);
3130 result
[len1
+ len2
+ len3
] = '\0';
3135 /* Does the same work as the system V getcwd, but does not need to
3136 guess buffer size in advance. Included mostly for compatibility. */
3146 buf
= xnew (bufsize
, char);
3148 pipe
= popen ("pwd 2>/dev/null", "r");
3154 if (fgets (buf
, bufsize
, pipe
) == NULL
)
3163 } while (buf
[strlen (buf
) - 1] != '\n');
3168 /* Return a newly allocated string containing the filename
3169 of FILE relative to the absolute directory DIR (which
3170 should end with a slash). */
3173 relative_filename (file
, dir
)
3176 char *fp
, *dp
, *res
;
3178 /* Find the common root of file and dir. */
3179 fp
= absolute_filename (file
, cwd
);
3181 while (*fp
++ == *dp
++)
3190 /* Build a sequence of "../" strings for the resulting relative filename. */
3191 for (dp
= etags_strchr (dp
+ 1, '/'), res
= "";
3193 dp
= etags_strchr (dp
+ 1, '/'))
3195 res
= concat (res
, "../", "");
3198 /* Add the filename relative to the common root of file and dir. */
3199 res
= concat (res
, fp
+ 1, "");
3201 return res
; /* temporary stub */
3204 /* Return a newly allocated string containing the
3205 absolute filename of FILE given CWD (which should
3206 end with a slash). */
3209 absolute_filename (file
, cwd
)
3212 char *slashp
, *cp
, *res
;
3215 res
= concat (file
, "", "");
3217 res
= concat (cwd
, file
, "");
3219 /* Delete the "/dirname/.." and "/." substrings. */
3220 slashp
= etags_strchr (res
, '/');
3221 while (slashp
!= NULL
&& slashp
[0] != '\0')
3223 if (slashp
[1] == '.')
3225 if (slashp
[2] == '.'
3226 && (slashp
[3] == '/' || slashp
[3] == '\0'))
3231 while (cp
>= res
&& *cp
!= '/');
3234 strcpy (cp
, slashp
+ 3);
3236 else /* else (cp == res) */
3238 if (slashp
[3] != NULL
)
3239 strcpy (cp
, slashp
+ 4);
3245 else if (slashp
[2] == '/' || slashp
[2] == '\0')
3247 strcpy (slashp
, slashp
+ 2);
3252 slashp
= etags_strchr (slashp
+ 1, '/');
3259 /* Return a newly allocated string containing the absolute
3260 filename of dir where FILE resides given CWD (which should
3261 end with a slash). */
3264 absolute_dirname (file
, cwd
)
3270 slashp
= etags_strrchr (file
, '/');
3275 res
= absolute_filename (file
, cwd
);
3281 /* Like malloc but get fatal error if memory is exhausted. */
3287 char *result
= (char *) malloc (size
);
3289 fatal ("virtual memory exhausted", 0);
3294 xrealloc (ptr
, size
)
3298 char *result
= (char *) realloc (ptr
, size
);
3300 fatal ("virtual memory exhausted");