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. 10.7
36 #include <../src/config.h>
41 #include <sys/types.h>
44 #if !defined (S_ISREG) && defined (S_IFREG)
45 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
50 extern char *getenv ();
51 extern char *getcwd ();
53 char *etags_index (), *etags_rindex ();
56 /* Define the symbol ETAGS to make the program "etags",
57 which makes emacs-style tag tables by default.
58 Define CTAGS to make the program "ctags" compatible with the usual one.
59 Define neither one to get behavior that depends
60 on the name with which the program is invoked
61 (but we don't normally compile it that way). */
63 #if !defined(ETAGS) && !defined(CTAGS)
64 /* If neither is defined, program can be run as either. */
69 /* On VMS, CTAGS is not useful, so always do ETAGS. */
76 /* Exit codes for success and failure. */
86 * The FILEPOS abstract type, which represents a position in a file,
87 * plus the following accessor functions:
89 * long GET_CHARNO (pos)
90 * returns absolute char number.
91 * void SET_FILEPOS (pos, fp, charno)
92 * FILE *fp; long charno;
93 * sets `pos' from the current file
94 * position of `fp' and from `charno',
95 * which must be the absolute character
96 * number corresponding to the current
99 * The `pos' parameter is an lvalue expression of type FILEPOS.
100 * Parameters to the accessor functions are evaluated 0 or more times,
101 * and so must have no side effects.
103 * FILEPOS objects can also be assigned and passed to and from
104 * functions in the normal C manner.
106 * Implementation notes: the `+ 0' is to enforce rvalue-ness.
110 /* real implementation */
111 typedef long FILEPOS
;
112 #define GET_CHARNO(pos) ((pos) + 0)
113 #define SET_FILEPOS(pos, fp, cno) ((void) ((pos) = (cno)))
115 /* debugging implementation */
121 #define GET_CHARNO(pos) ((pos).charno + 0)
122 #define SET_FILEPOS(pos, fp, cno) \
123 ((void) ((pos).charno = (cno), \
124 (cno) != ftell (fp) ? (error ("SET_FILEPOS inconsistency"), 0) \
128 #define streq(s, t) (strcmp (s, t) == 0)
129 #define strneq(s, t, n) (strncmp (s, t, n) == 0)
135 #define iswhite(arg) (_wht[arg]) /* T if char is white */
136 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
137 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
138 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
140 #define max(I1,I2) ((I1) > (I2) ? (I1) : (I2))
143 { /* sorting structure */
144 char *name
; /* function or type name */
145 char *file
; /* file name */
146 logical is_func
; /* use pattern or line no */
147 logical named
; /* list name separately */
148 logical been_warned
; /* set if noticed dup */
149 int lno
; /* line number tag is on */
150 long cno
; /* character number line starts on */
151 char *pat
; /* search pattern */
152 struct nd_st
*left
, *right
; /* left and right sons */
156 typedef struct nd_st NODE
;
158 logical header_file
; /* TRUE if .h file, FALSE o.w. */
159 /* boolean "functions" (see init) */
160 logical _wht
[0177], _etk
[0177], _itk
[0177], _btk
[0177];
168 int L_isdef (), L_isquote ();
170 int total_size_of_entries ();
171 logical
consider_token ();
179 void Scheme_funcs ();
184 logical
find_entries ();
191 void process_file ();
197 * xnew -- allocate storage
200 * Type *xnew (int n, Type);
202 #define xnew(n, Type) ((Type *) xmalloc ((n) * sizeof (Type)))
205 * Symbol table types.
209 st_none
, st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
226 #define C_PLPL 0x00001 /* C++ */
227 #define C_STAR 0x00003 /* C* */
228 #define YACC 0x10000 /* yacc file */
230 char searchar
= '/'; /* use /.../ searches */
232 LINENO lineno
; /* line number of current line */
233 long charno
; /* current character number */
235 long linecharno
; /* charno of start of line; not used by C, but
236 * by every other language.
239 char *curfile
, /* current input file name */
240 *outfile
, /* output file */
241 *white
= " \f\t\n", /* white chars */
242 *endtk
= " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */
243 /* token starting chars */
244 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~",
245 /* valid in-token chars */
246 *intk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
248 int append_to_tagfile
; /* -a: append to tags */
249 int absolute_pathnames
; /* -A: use absolute pathnames in tag file */
250 int emacs_tags_format
; /* emacs style output (no -e option any more) */
251 /* The following three default to 1 for etags, but to 0 for ctags. */
252 int typedefs
; /* -t: create tags for typedefs */
253 int typedefs_and_cplusplus
; /* -T: create tags for typedefs, level */
254 /* 0 struct/enum/union decls, and C++ */
255 /* member functions */
256 int constantypedefs
; /* -d: create tags for C #define and enum */
257 /* constants. Default under etags. Enum */
258 /* constants not implemented. */
259 /* -D: opposite of -d. Default under ctags. */
260 int update
; /* -u: update tags */
261 int vgrind_style
; /* -v: create vgrind style index output */
262 int no_warnings
; /* -w: suppress warnings */
263 int cxref_style
; /* -x: create cxref style output */
264 int cplusplus
; /* .[hc] means C++, not C */
265 int noindentypedefs
; /* -S: ignore indentation in C */
267 /* Name this program was invoked with. */
270 /* The current working directory, used if --absolute-pathnames. */
273 struct option longopts
[] = {
274 { "append", no_argument
, NULL
, 'a' },
275 { "absolute-pathnames", no_argument
, NULL
, 'A' },
276 { "backward-search", no_argument
, NULL
, 'B' },
277 { "c++", no_argument
, NULL
, 'C' },
278 { "cxref", no_argument
, NULL
, 'x' },
279 { "defines", no_argument
, NULL
, 'd' },
280 { "forward-search", no_argument
, NULL
, 'F' },
281 { "help", no_argument
, NULL
, 'H' },
282 { "ignore-indentation", no_argument
, NULL
, 'S' },
283 { "include", required_argument
, NULL
, 'i' },
284 { "no-defines", no_argument
, NULL
, 'D' },
285 { "no-warn", no_argument
, NULL
, 'w' },
286 { "output", required_argument
, NULL
, 'o' },
287 { "typedefs", no_argument
, NULL
, 't' },
288 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
289 { "update", no_argument
, NULL
, 'u' },
290 { "version", no_argument
, NULL
, 'V' },
291 { "vgrind", no_argument
, NULL
, 'v' },
295 FILE *inf
, /* ioptr for current input file */
296 *outf
; /* ioptr for tags file */
298 NODE
*head
; /* the head of the binary tree of tags */
300 int permit_duplicates
= 1; /* Nonzero means allow duplicate tags. */
302 /* A `struct linebuffer' is a structure which holds a line of text.
303 `readline' reads a line from a stream into a linebuffer
304 and works regardless of the length of the line. */
312 struct linebuffer lb
; /* the current line */
313 struct linebuffer filename_lb
; /* used to read in filenames */
317 struct linebuffer lb
; /* used by C_entries instead of lb */
332 printf ("for Emacs version 19.\n");
340 printf ("These are the options accepted by %s. You may use unambiguous\n\
341 abbreviations for the long option names. A - as file name means read file\n\
342 names from stdin.\n\n", progname
);
344 puts ("-a, --append\n\
345 Append tag entries to existing tags file.");
346 puts ("-A, --absolute-pathnames\n\
347 Use absolute pathnames for tagged files.");
350 puts ("-B, --backward-search\n\
351 Write the search commands for the tag entries using '?', the\n\
352 backward-search command.");
356 Treat files with `.c' and `.h' extensions as C++ code, not C\n\
357 code. Files with `.C', `.H', `.cxx', `.hxx', or `.cc'\n\
358 extensions are always assumed to be C++ code.");
361 puts ("-d, --defines\n\
362 Create tag entries for #defines, too. This is the default\n\
365 puts ("-d, --defines\n\
366 Create tag entries for #defines, too.");
370 puts ("-D, --no-defines\n\
371 Don't create tag entries for #defines. This is the default\n\
374 puts ("-D, --no-defines\n\
375 Don't create tag entries for #defines.");
379 puts ("-F, --forward-search\n\
380 Write the search commands for the tag entries using '/', the\n\
381 forward-search command.");
386 puts ("-i FILE, --include=FILE\n\
387 Include a note in tag file indicating that, when searching for\n\
388 a tag, one should also consult the tags file FILE after\n\
389 checking the current file.");
392 puts ("-o FILE, --output=FILE\n\
393 Write the tags to FILE.");
394 puts ("-S, --ignore-indentation\n\
395 Don't rely on indentation quite as much as normal. Currently,\n\
396 this means not to assume that a closing brace in the first\n\
397 column is the final brace of a function or structure\n\
399 puts ("-t, --typedefs\n\
400 Generate tag entries for typedefs. This is the default\n\
402 puts ("-T, --typedefs-and-c++\n\
403 Generate tag entries for typedefs, struct/enum/union tags, and\n\
404 C++ member functions.");
407 puts ("-u, --update\n\
408 Update the tag entries for the given files, leaving tag\n\
409 entries for other files in place. Currently, this is\n\
410 implemented by deleting the existing entries for the given\n\
411 files and then rewriting the new entries at the end of the\n\
412 tags file. It is often faster to simply rebuild the entire\n\
413 tag file than to use this.");
414 puts ("-v, --vgrind\n\
415 Generates an index of items intended for human consumption,\n\
416 similar to the output of vgrind. The index is sorted, and\n\
417 gives the page number of each item.");
418 puts ("-x, --cxref\n\
419 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
420 The output uses line numbers instead of page numbers, but\n\
421 beyond that the differences are cosmetic; try both to see\n\
423 puts ("-w, --no-warn\n\
424 Suppress warning messages about entries defined in multiple\n\
428 puts ("-V, --version\n\
429 Print the version of the program.\n\
431 Print this help message.");
444 unsigned int nincluded_files
= 0;
445 char **included_files
= xnew (argc
, char *);
450 extern char *gfnames ();
451 extern char *massage_name ();
455 _fmode
= O_BINARY
; /* all of files are treated as binary files */
461 emacs_tags_format
= 1;
463 emacs_tags_format
= 0;
467 * If etags, always find typedefs and structure tags. Why not?
468 * Also default is to find macro constants.
470 if (emacs_tags_format
)
471 typedefs
= typedefs_and_cplusplus
= constantypedefs
= 1;
476 opt
= getopt_long (argc
, argv
, "aACdDo:f:StTi:BFuvxwVH", longopts
, 0);
484 /* If getopt returns '\0', then it has already processed a
485 long-named option. We should do nothing. */
488 /* Common options. */
493 absolute_pathnames
++;
509 "%s: -%c flag may only be given once\n", progname
, opt
);
522 typedefs_and_cplusplus
++;
533 if (!emacs_tags_format
)
535 included_files
[nincluded_files
++] = optarg
;
541 if (emacs_tags_format
)
546 if (emacs_tags_format
)
551 if (emacs_tags_format
)
559 if (emacs_tags_format
)
564 if (emacs_tags_format
)
573 if (optind
== argc
&& nincluded_files
== 0)
575 fprintf (stderr
, "%s: No input files specified.\n", progname
);
578 fprintf (stderr
, "%s: Try `%s --help' for a complete list of options.\n",
585 outfile
= emacs_tags_format
? "TAGS" : "tags";
588 init (); /* set up boolean "functions" */
591 initbuffer (&lbs
[0].lb
);
592 initbuffer (&lbs
[1].lb
);
593 initbuffer (&filename_lb
);
595 * loop through files finding functions
597 if (emacs_tags_format
)
599 if (streq (outfile
, "-"))
602 outf
= fopen (outfile
, append_to_tagfile
? "a" : "w");
613 while (gfnames (&argc
, &argv
, &got_err
) != NULL
)
617 error ("Can't find file %s\n", this_file
);
622 this_file
= massage_name (this_file
);
625 } /* solely to balance out the ifdef'd parens above */
628 if (absolute_pathnames
)
630 cwd
= getcwd (NULL
, 2*BUFSIZ
);
638 for (; optind
< argc
; optind
++)
640 this_file
= argv
[optind
];
642 /* Input file named "-" means read file names from stdin and use them. */
643 if (streq (this_file
, "-"))
645 while (!feof (stdin
))
647 (void) readline (&filename_lb
, stdin
);
648 if (strlen (filename_lb
.buffer
) > 0)
649 process_file (filename_lb
.buffer
);
653 process_file (this_file
);
656 if (emacs_tags_format
)
658 while (nincluded_files
-- > 0)
659 fprintf (outf
, "\f\n%s,include\n", *included_files
++);
661 (void) fclose (outf
);
672 /* update cannot be set under VMS, so we may assume that argc
673 and argv have not been munged. */
674 for (i
= optind
; i
< argc
; i
++)
677 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
678 outfile
, argv
[i
], outfile
);
683 outf
= fopen (outfile
, append_to_tagfile
? "a" : "w");
690 (void) fclose (outf
);
693 sprintf (cmd
, "sort %s -o %s", outfile
, outfile
);
701 * This routine is called on each file argument.
707 struct stat stat_buf
;
709 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
711 fprintf (stderr
, "Skipping %s: it is not a regular file.\n", file
);
714 if (streq (file
, outfile
) && !streq (outfile
, "-"))
716 fprintf (stderr
, "Skipping inclusion of %s in self.\n", file
);
719 if (!find_entries (file
))
723 if (emacs_tags_format
)
725 fprintf (outf
, "\f\n%s%s,%d\n",
726 ((absolute_pathnames
&& file
[0] != '/') ? cwd
: ""),
727 file
, total_size_of_entries (head
));
735 * This routine sets up the boolean pseudo-functions which work
736 * by setting boolean flags dependent upon the corresponding character
737 * Every char which is NOT in that string is not a white char. Therefore,
738 * all of the array "_wht" is set to FALSE, and then the elements
739 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
740 * of a char is TRUE if it is the string "white", else FALSE.
748 for (i
= 0; i
< 0177; i
++)
749 _wht
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
750 for (sp
= white
; *sp
; sp
++)
752 for (sp
= endtk
; *sp
; sp
++)
754 for (sp
= intk
; *sp
; sp
++)
756 for (sp
= begtk
; *sp
; sp
++)
758 _wht
[0] = _wht
['\n'];
759 _etk
[0] = _etk
['\n'];
760 _btk
[0] = _btk
['\n'];
761 _itk
[0] = _itk
['\n'];
765 * This routine opens the specified file and calls the function
766 * which finds the function and type definitions.
773 void prolog_funcs ();
775 inf
= fopen (file
, "r");
781 curfile
= savestr (file
);
782 cp
= etags_rindex (file
, '.');
784 header_file
= (cp
&& (streq (cp
+ 1, "h")));
786 /* .tex, .aux or .bbl implies LaTeX source code */
787 if (cp
&& (streq (cp
+ 1, "tex") || streq (cp
+ 1, "aux")
788 || streq (cp
+ 1, "bbl")))
791 goto close_and_return
;
793 /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
794 if (cp
&& (streq (cp
+ 1, "l")
795 || streq (cp
+ 1, "el")
796 || streq (cp
+ 1, "lsp")
797 || streq (cp
+ 1, "lisp")
798 || streq (cp
+ 1, "cl")
799 || streq (cp
+ 1, "clisp")))
802 goto close_and_return
;
804 /* .scm or .sm or .scheme or ... implies scheme source code */
805 if (cp
&& (streq (cp
+ 1, "sm")
806 || streq (cp
+ 1, "scm")
807 || streq (cp
+ 1, "scheme")
808 || streq (cp
+ 1, "t")
809 || streq (cp
+ 1, "sch")
810 || streq (cp
+ 1, "SM")
811 || streq (cp
+ 1, "SCM")
812 /* The `SCM' or `scm' prefix with a version number */
813 || (cp
[-1] == 'm' && cp
[-2] == 'c' && cp
[-3] == 's'
814 && string_numeric_p (cp
+ 1))
815 || (cp
[-1] == 'M' && cp
[-2] == 'C' && cp
[-3] == 'S'
816 && string_numeric_p (cp
+ 1))))
819 goto close_and_return
;
821 /* Assume that ".s" or ".a" is assembly code. -wolfgang.
823 if (cp
&& (streq (cp
+ 1, "s")
824 || streq (cp
+ 1, "a")
825 || streq (cp
+ 1, "sa")))
828 goto close_and_return
;
830 /* .C or .H or .cxx or .hxx or .cc: a C++ file */
831 if (cp
&& (streq (cp
+ 1, "C")
832 || streq (cp
+ 1, "H")
833 || streq (cp
+ 1, "cxx")
834 || streq (cp
+ 1, "hxx")
835 || streq (cp
+ 1, "cc")))
837 C_entries (C_PLPL
); /* C++ */
838 goto close_and_return
;
840 /* .cs or .hs: a C* file */
841 if (cp
&& (streq (cp
+ 1, "cs")
842 || streq (cp
+ 1, "hs")))
845 goto close_and_return
;
847 /* .y: a yacc file */
848 if (cp
&& (streq (cp
+ 1, "y")))
851 goto close_and_return
;
853 /* .pl implies prolog source code */
854 if (cp
&& streq (cp
+ 1, "pl"))
857 goto close_and_return
;
859 /* .p or .pas: a Pascal file */
860 if (cp
&& (streq (cp
+ 1, "p")
861 || streq (cp
+ 1, "pas")))
864 goto close_and_return
;
866 /* If .f or .for, assume it is fortran or nothing. */
867 if (cp
&& (streq (cp
+ 1, "f")
868 || streq (cp
+ 1, "for")))
870 (void) PF_funcs (inf
);
871 goto close_and_return
;
873 /* if not a .c or .h or .y file, try fortran */
874 if (cp
&& ((cp
[1] != 'c'
877 || (cp
[1] != 0 && cp
[2] != 0)))
879 if (PF_funcs (inf
) != 0)
880 goto close_and_return
;
881 rewind (inf
); /* no fortran tags found, try C */
883 C_entries (cplusplus
? C_PLPL
: 0);
890 /* Nonzero if string STR is composed of digits. */
893 string_numeric_p (str
)
898 if (*str
< '0' || *str
> '9')
905 /* Should take a TOKEN* instead!! */
907 pfnote (name
, is_func
, named
, linestart
, linelen
, lno
, cno
)
908 char *name
; /* tag name */
909 logical is_func
; /* function or type name? */
910 logical named
; /* tag different from text of definition? */
924 if (!emacs_tags_format
)
926 /* It's okay to output early in etags -- it only disrupts the
927 * character count of the tag entries, which is no longer used
930 error ("too many entries to sort", 0);
937 /* If ctags mode, change name "main" to M<thisfilename>. */
938 if (!emacs_tags_format
&& !cxref_style
&& streq (name
, "main"))
940 fp
= etags_rindex (curfile
, '/');
941 name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
942 fp
= etags_rindex (name
, '.');
943 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
947 np
->name
= savestr (name
);
949 np
->is_func
= is_func
;
952 /* UNCOMMENT THE +1 HERE: */
953 np
->cno
= cno
/* + 1 */ ; /* our char numbers are 0-base; emacs's are 1-base */
954 np
->left
= np
->right
= 0;
955 if (emacs_tags_format
)
957 c
= linestart
[linelen
];
958 linestart
[linelen
] = 0;
960 else if (cxref_style
== 0)
962 sprintf (tem
, strlen (linestart
) < 50 ? "%s$" : "%.50s", linestart
);
965 np
->pat
= savestr (linestart
);
966 if (emacs_tags_format
)
968 linestart
[linelen
] = c
;
971 add_node (np
, &head
);
976 * recurse on left children, iterate on right children.
984 register NODE
*node_right
= node
->right
;
985 free_tree (node
->left
);
988 free ((char *) node
);
995 * Adds a node to the tree of nodes. In etags mode, we don't keep
996 * it sorted; we just keep a linear list. In ctags mode, maintain
997 * an ordered tree, with no attempt at balancing.
999 * add_node is the only function allowed to add nodes, so it can
1002 /* Must avoid static vars within functions since some systems
1003 #define static as nothing. */
1004 static NODE
*last_node
= NULL
;
1007 add_node (node
, cur_node_p
)
1008 NODE
*node
, **cur_node_p
;
1011 register NODE
*cur_node
= *cur_node_p
;
1013 if (cur_node
== NULL
)
1020 if (emacs_tags_format
)
1023 if (last_node
== NULL
)
1024 fatal ("internal error in add_node", 0);
1025 last_node
->right
= node
;
1031 dif
= strcmp (node
->name
, cur_node
->name
);
1034 * If this tag name matches an existing one, then
1035 * do not add the node, but maybe print a warning.
1039 if (node
->file
== cur_node
->file
)
1043 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1044 node
->file
, lineno
, node
->name
);
1045 fprintf (stderr
, "Second entry ignored\n");
1049 if (!cur_node
->been_warned
&& !no_warnings
)
1052 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1053 node
->file
, cur_node
->file
, node
->name
);
1055 cur_node
->been_warned
= TRUE
;
1059 /* Maybe refuse to add duplicate nodes. */
1060 if (!permit_duplicates
)
1062 if (streq (node
->name
, cur_node
->name
)
1063 && streq (node
->file
, cur_node
->file
))
1067 /* Actually add the node */
1068 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1074 register NODE
*node
;
1081 /* Output subentries that precede this one */
1082 put_entries (node
->left
);
1084 /* Output this entry */
1086 if (emacs_tags_format
)
1090 fprintf (outf
, "%s\177%s\001%d,%d\n",
1091 node
->pat
, node
->name
,
1092 node
->lno
, node
->cno
);
1096 fprintf (outf
, "%s\177%d,%d\n",
1098 node
->lno
, node
->cno
);
1101 else if (!cxref_style
)
1103 fprintf (outf
, "%s\t%s\t",
1104 node
->name
, node
->file
);
1108 putc (searchar
, outf
);
1111 for (sp
= node
->pat
; *sp
; sp
++)
1113 if (*sp
== '\\' || *sp
== searchar
)
1117 putc (searchar
, outf
);
1120 { /* a typedef; text pattern inadequate */
1121 fprintf (outf
, "%d", node
->lno
);
1125 else if (vgrind_style
)
1126 fprintf (stdout
, "%s %s %d\n",
1127 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1129 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1130 node
->name
, node
->lno
, node
->file
, node
->pat
);
1132 /* Output subentries that follow this one */
1133 put_entries (node
->right
);
1136 /* Length of a number's decimal representation. */
1144 for (; num
; num
/= 10)
1150 * Return total number of characters that put_entries will output for
1151 * the nodes in the subtree of the specified node. Works only if emacs_tags_format
1152 * is set, but called only in that case. This count is irrelevant with
1153 * the new tags.el, but is still supplied for backward compatibility.
1156 total_size_of_entries (node
)
1157 register NODE
*node
;
1165 for (; node
; node
= node
->right
)
1167 /* Count left subentries. */
1168 total
+= total_size_of_entries (node
->left
);
1170 /* Count this entry */
1171 total
+= strlen (node
->pat
) + 1;
1172 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1174 total
+= 1 + strlen (node
->name
); /* \001name */
1181 * The C symbol tables.
1184 /* Feed stuff between (but not including) %[ and %] lines to:
1185 gperf -c -k1,3 -o -p -r -t
1187 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1189 class, C_PLPL, st_C_struct
1190 domain, C_STAR, st_C_struct
1191 union, 0, st_C_struct
1192 struct, 0, st_C_struct
1194 typedef, 0, st_C_typedef
1195 define, 0, st_C_define
1196 long, 0, st_C_typespec
1197 short, 0, st_C_typespec
1198 int, 0, st_C_typespec
1199 char, 0, st_C_typespec
1200 float, 0, st_C_typespec
1201 double, 0, st_C_typespec
1202 signed, 0, st_C_typespec
1203 unsigned, 0, st_C_typespec
1204 auto, 0, st_C_typespec
1205 void, 0, st_C_typespec
1206 extern, 0, st_C_typespec
1207 static, 0, st_C_typespec
1208 const, 0, st_C_typespec
1209 volatile, 0, st_C_typespec
1211 and replace lines between %< and %> with its output. */
1213 /* C code produced by gperf version 1.8.1 (K&R C version) */
1214 /* Command-line: gperf -c -k1,3 -o -p -r -t */
1217 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1219 #define MIN_WORD_LENGTH 3
1220 #define MAX_WORD_LENGTH 8
1221 #define MIN_HASH_VALUE 10
1222 #define MAX_HASH_VALUE 62
1225 53 is the maximum key range
1233 static unsigned char hash_table
[] =
1235 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1236 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1237 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1238 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1239 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1240 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1241 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1242 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1243 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1244 62, 62, 62, 62, 62, 62, 62, 2, 62, 7,
1245 6, 9, 15, 30, 62, 24, 62, 62, 1, 24,
1246 7, 27, 13, 62, 19, 26, 18, 27, 1, 62,
1247 62, 62, 62, 62, 62, 62, 62, 62,
1249 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1252 struct C_stab_entry
*
1253 in_word_set (str
, len
)
1258 static struct C_stab_entry wordlist
[] =
1260 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1262 {"volatile", 0, st_C_typespec
},
1264 {"long", 0, st_C_typespec
},
1265 {"char", 0, st_C_typespec
},
1266 {"class", C_PLPL
, st_C_struct
},
1267 {"",}, {"",}, {"",}, {"",},
1268 {"const", 0, st_C_typespec
},
1269 {"",}, {"",}, {"",}, {"",},
1270 {"auto", 0, st_C_typespec
},
1272 {"define", 0, st_C_define
},
1274 {"void", 0, st_C_typespec
},
1275 {"",}, {"",}, {"",},
1276 {"extern", 0, st_C_typespec
},
1277 {"static", 0, st_C_typespec
},
1279 {"domain", C_STAR
, st_C_struct
},
1281 {"typedef", 0, st_C_typedef
},
1282 {"double", 0, st_C_typespec
},
1283 {"enum", 0, st_C_enum
},
1284 {"",}, {"",}, {"",}, {"",},
1285 {"int", 0, st_C_typespec
},
1287 {"float", 0, st_C_typespec
},
1288 {"",}, {"",}, {"",},
1289 {"struct", 0, st_C_struct
},
1290 {"",}, {"",}, {"",}, {"",},
1291 {"union", 0, st_C_struct
},
1293 {"short", 0, st_C_typespec
},
1295 {"unsigned", 0, st_C_typespec
},
1296 {"signed", 0, st_C_typespec
},
1299 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1301 register int key
= hash (str
, len
);
1303 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1305 register char *s
= wordlist
[key
].name
;
1307 if (*s
== *str
&& strneq (str
+ 1, s
+ 1, len
- 1))
1308 return &wordlist
[key
];
1316 C_symtype(str
, len
, c_ext
)
1321 register struct C_stab_entry
*se
= in_word_set(str
, len
);
1323 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1329 * C functions are recognized using a simple finite automaton.
1330 * funcdef is its state variable.
1334 fnone
, /* nothing seen */
1335 ftagseen
, /* function-like tag seen */
1336 fstartlist
, /* just after open parenthesis */
1337 finlist
, /* in parameter list */
1338 flistseen
, /* after parameter list */
1339 fignore
/* before open brace */
1344 /* typedefs are recognized using a simple finite automaton.
1345 * typeddef is its state variable.
1349 tnone
, /* nothing seen */
1350 ttypedseen
, /* typedef keyword seen */
1351 tinbody
, /* inside typedef body */
1352 tend
/* just before typedef tag */
1357 /* struct tags for C++ are recognized using another simple
1358 * finite automaton. `structdef' is its state variable.
1359 * This machinery is only invoked for C++; otherwise structdef
1360 * should remain snone. However, this machinery can easily be
1361 * adapted to find structure tags in normal C code.
1365 snone
, /* nothing seen yet */
1366 skeyseen
, /* struct-like keyword seen */
1367 stagseen
, /* struct-like tag seen */
1368 scolonseen
, /* colon seen after struct-like tag */
1369 sinbody
/* in struct body: recognize member func defs*/
1373 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1374 * struct tag, and structtype is the type of the preceding struct-like
1377 char structtag
[BUFSIZ
];
1378 enum sym_type structtype
;
1381 * Yet another little state machine to deal with preprocessor lines.
1385 dnone
, /* nothing seen */
1386 dsharpseen
, /* '#' seen as first char on line */
1387 ddefineseen
, /* '#' and 'define' seen */
1388 dignorerest
/* ignore rest of line */
1393 * Set this to TRUE, and the next token considered is called a function.
1394 * Used only for GNUmacs's function-defining macros.
1396 logical next_token_is_func
;
1399 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1405 * This routine finds functions, typedefs, #define's and
1406 * struct/union/enum definitions in C syntax and adds them
1410 #define curlb (lbs[curndx].lb)
1411 #define othlb (lbs[1-curndx].lb)
1412 #define newlb (lbs[newndx].lb)
1413 #define curlinepos (lbs[curndx].linepos)
1414 #define othlinepos (lbs[1-curndx].linepos)
1415 #define newlinepos (lbs[newndx].linepos)
1417 /* Save and restore token state. This is used when preprocessor defines
1418 are handled, to avoid disturbing active function/typedef/struct states. */
1419 #define TOKEN_SAVED_P (savetok.lineno > 0)
1420 #define SAVE_TOKEN (savetok = tok, savetok.p = (char *) tokoff, \
1421 savetok.len = toklen, strcpy(savenameb, nameb))
1422 #define RESTORE_TOKEN (tok = savetok, tokoff = (int) tok.p, \
1423 toklen = tok.len, strcpy(nameb, savenameb), \
1426 #define CNL_SAVE_DEFINEDEF \
1428 SET_FILEPOS (curlinepos, inf, charno); \
1430 charno += readline (&curlb, inf); \
1431 lp = curlb.buffer; \
1438 CNL_SAVE_DEFINEDEF; \
1439 if (TOKEN_SAVED_P) \
1441 definedef = dnone; \
1444 #define MAKE_TAG_FROM_NEW_LB(isfun) pfnote (nameb, isfun, tok.named, \
1445 newlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (newlinepos))
1446 #define MAKE_TAG_FROM_OTH_LB(isfun) pfnote (nameb, isfun, tok.named, \
1447 othlb.buffer, tokoff + toklen + 1, tok.lineno, GET_CHARNO (othlinepos))
1451 int c_ext
; /* extension of C? */
1453 register char c
; /* latest char read; '\0' for end of line */
1454 register char *lp
; /* pointer one beyond the character `c' */
1455 int curndx
, newndx
; /* indices for current and new lb */
1456 TOKEN tok
; /* latest token read for funcdef & structdef */
1457 char nameb
[BUFSIZ
]; /* latest token name for funcdef & structdef */
1458 register int tokoff
; /* offset in line of start of latest token */
1459 register int toklen
; /* length of latest token */
1460 int cblev
; /* current curly brace level */
1461 int parlev
; /* current parenthesis level */
1462 logical incomm
, inquote
, inchar
, quotednl
, midtoken
;
1464 TOKEN savetok
; /* saved token during preprocessor handling */
1465 char savenameb
[BUFSIZ
]; /* ouch! */
1468 curndx
= newndx
= 0;
1474 definedef
= dnone
; funcdef
= fnone
; typdef
= tnone
; structdef
= snone
;
1475 next_token_is_func
= yacc_rules
= FALSE
;
1476 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1479 cplpl
= c_ext
& C_PLPL
;
1486 /* If we're at the end of the line, the next character is a
1487 '\0'; don't skip it, because it's the thing that tells us
1488 to read the next line. */
1509 /* Newlines inside comments do not end macro definitions in
1524 /* Newlines inside strings do not end macro definitions
1525 in traditional cpp, even though compilers don't
1526 usually accept them. */
1537 /* Hmmm, something went wrong. */
1551 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1556 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1566 else if (cplpl
&& *lp
== '/')
1574 if ((c_ext
& YACC
) && *lp
== '%')
1576 /* entering or exiting rules section in yacc file */
1578 definedef
= dnone
; funcdef
= fnone
;
1579 typdef
= tnone
; structdef
= snone
;
1580 next_token_is_func
= FALSE
;
1581 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1583 yacc_rules
= !yacc_rules
;
1589 if (lp
== newlb
.buffer
+ 1 && definedef
== dnone
)
1590 definedef
= dsharpseen
;
1595 /* Consider token only if some complicated conditions are satisfied. */
1596 if (((cblev
== 0 && structdef
!= scolonseen
)
1597 || (cblev
== 1 && cplpl
&& structdef
== sinbody
))
1598 && definedef
!= dignorerest
1599 && (funcdef
!= finlist
1600 || (definedef
!= dnone
&& definedef
!= dignorerest
)))
1606 if (cplpl
&& c
== ':' && *lp
== ':' && begtoken(*(lp
+ 1)))
1609 * This handles :: in the middle, but not at beginning
1617 logical is_func
= FALSE
;
1619 tok
.lineno
= lineno
;
1620 tok
.p
= newlb
.buffer
+ tokoff
;
1624 || consider_token (c
, &tok
, c_ext
, cblev
, &is_func
))
1626 if (structdef
== sinbody
1627 && definedef
== dnone
1629 /* function defined in C++ class body */
1632 sprintf (nameb
, "%s::%.*s",
1633 ((structtag
[0] == '\0')
1634 ? "_anonymous_" : structtag
),
1639 sprintf (nameb
, "%.*s", tok
.len
, tok
.p
);
1642 if (structdef
== stagseen
1646 if (definedef
== dnone
1647 && (funcdef
== ftagseen
1648 || structdef
== stagseen
1651 if (newndx
== curndx
)
1652 curndx
= 1 - curndx
; /* switch line buffers */
1655 MAKE_TAG_FROM_NEW_LB (is_func
);
1659 } /* if (endtoken (c)) */
1660 else if (intoken (c
))
1665 } /* if (midtoken) */
1666 else if (begtoken (c
))
1677 MAKE_TAG_FROM_OTH_LB (TRUE
);
1684 if (structdef
== stagseen
)
1688 /* Take a quick peek ahead for define directive,
1689 so we can avoid saving the token when not absolutely
1690 necessary. [This is a speed hack.] */
1691 if (c
== 'd' && strneq(lp
, "efine", 5)
1692 && iswhite(*(lp
+ 5)))
1695 definedef
= ddefineseen
;
1699 definedef
= dignorerest
;
1702 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
1704 tokoff
= lp
- 1 - newlb
.buffer
;
1710 } /* if must look at token */
1713 /* Detect end of line, colon, comma, semicolon and various braces
1714 after having handled a token.*/
1718 if (definedef
!= dnone
)
1720 if (structdef
== stagseen
)
1721 structdef
= scolonseen
;
1728 MAKE_TAG_FROM_OTH_LB (FALSE
);
1738 if (definedef
!= dnone
)
1740 if (cblev
== 0 && typdef
== tend
)
1743 MAKE_TAG_FROM_OTH_LB (FALSE
);
1745 if (funcdef
!= fignore
)
1751 if (definedef
!= dnone
)
1753 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1755 if (structdef
== stagseen
)
1759 if (definedef
!= dnone
)
1764 funcdef
= fstartlist
;
1773 if (definedef
!= dnone
)
1781 funcdef
= flistseen
;
1785 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
1789 if (definedef
!= dnone
)
1791 if (typdef
== ttypedseen
)
1795 case skeyseen
: /* unnamed struct */
1796 structtag
[0] = '\0';
1797 structdef
= sinbody
;
1800 case scolonseen
: /* named struct */
1801 structdef
= sinbody
;
1802 MAKE_TAG_FROM_OTH_LB (FALSE
);
1808 MAKE_TAG_FROM_OTH_LB (TRUE
);
1816 if (definedef
!= dnone
)
1818 if (funcdef
== fstartlist
)
1819 funcdef
= fnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
1822 if (definedef
!= dnone
)
1824 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
1826 cblev
= 0; /* reset curly brace level if first column */
1827 parlev
= 0; /* also reset paren level, just in case... */
1833 if (typdef
== tinbody
)
1836 strcpy (structtag
, "<error 2>");
1840 case '#': case '+': case '-': case '~': case '&': case '%': case '/':
1841 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
1842 if (definedef
!= dnone
)
1844 /* These surely cannot follow a function tag. */
1845 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1849 /* If a macro spans multiple lines don't reset its state. */
1857 } /* while not eof */
1862 * checks to see if the current token is at the start of a
1863 * function, or corresponds to a typedef, or is a struct/union/enum
1866 * *IS_FUNC gets TRUE iff the token is a function or macro with args.
1867 * C_EXT is which language we are looking at.
1869 * In the future we will need some way to adjust where the end of
1870 * the token is; for instance, implementing the C++ keyword
1871 * `operator' properly will adjust the end of the token to be after
1872 * whatever follows `operator'.
1879 * next_token_is_func IN OUT
1883 consider_token (c
, tokp
, c_ext
, cblev
, is_func
)
1884 register char c
; /* IN: first char after the token */
1885 register TOKEN
*tokp
; /* IN: token pointer */
1886 int c_ext
; /* IN: C extensions mask */
1887 int cblev
; /* IN: curly brace level */
1888 logical
*is_func
; /* OUT */
1890 enum sym_type toktype
= C_symtype(tokp
->p
, tokp
->len
, c_ext
);
1893 * Advance the definedef state machine.
1898 /* We're not on a preprocessor line. */
1901 if (toktype
== st_C_define
)
1903 definedef
= ddefineseen
;
1907 definedef
= dignorerest
;
1912 * Make a tag for any macro.
1914 definedef
= dignorerest
;
1915 *is_func
= (c
== '(');
1916 if (!*is_func
&& !constantypedefs
)
1923 error ("internal error: definedef value is %d", definedef
);
1932 if (toktype
== st_C_typedef
)
1935 typdef
= ttypedseen
;
1950 /* Do not return here, so the structdef stuff has a chance. */
1964 * This structdef business is currently only invoked when cblev==0.
1965 * It should be recursively invoked whatever the curly brace level,
1966 * and a stack of states kept, to allow for definitions of structs
1969 * This structdef business is NOT invoked when we are ctags and the
1970 * file is plain C. This is because a struct tag may have the same
1971 * name as another tag, and this loses with ctags.
1973 * This if statement deals with the typdef state machine as
1974 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1975 * return (FALSE). All the other code here is for the structdef
1982 if (typdef
== ttypedseen
1983 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
1985 structdef
= skeyseen
;
1986 structtype
= toktype
;
1990 if (structdef
== skeyseen
)
1992 if (structtype
== st_C_struct
)
1994 strncpy (structtag
, tokp
->p
, tokp
->len
);
1995 structtag
[tokp
->len
] = '\0'; /* for struct/union/class */
1999 structtag
[0] = '\0'; /* for enum (why is it treated differently?) */
2001 structdef
= stagseen
;
2005 /* Avoid entering funcdef stuff if typdef is going on. */
2006 if (typdef
!= tnone
)
2012 /* Detect GNUmacs's function-defining macros. */
2013 if (definedef
== dnone
)
2015 if (strneq (tokp
->p
, "DEF", 3)
2016 || strneq (tokp
->p
, "ENTRY", 5)
2017 || strneq (tokp
->p
, "SYSCALL", 7)
2018 || strneq (tokp
->p
, "PSEUDO", 6))
2020 next_token_is_func
= TRUE
;
2023 if (strneq (tokp
->p
, "EXFUN", 5))
2025 next_token_is_func
= FALSE
;
2029 if (next_token_is_func
)
2031 next_token_is_func
= FALSE
;
2033 *is_func
= TRUE
; /* to force search string in ctags */
2041 funcdef
= fnone
; /* should be useless */
2044 if (funcdef
== fnone
)
2055 /* Fortran parsing */
2071 linecharno
= charno
;
2072 charno
+= readline (&lb
, fi
);
2075 dbp
++; /* Ratfor escape to fortran */
2076 while (isspace (*dbp
))
2083 if (tail ("integer"))
2091 if (tail ("logical"))
2095 if (tail ("complex") || tail ("character"))
2099 if (tail ("double"))
2101 while (isspace (*dbp
))
2105 if (tail ("precision"))
2111 while (isspace (*dbp
))
2118 if (tail ("function"))
2122 if (tail ("subroutine"))
2130 if (tail ("program"))
2135 if (tail ("procedure"))
2147 register int len
= 0;
2149 while (*cp
&& (*cp
| ' ') == (dbp
[len
] | ' '))
2162 while (isspace (*dbp
))
2167 while (isspace (*dbp
))
2169 if (!isdigit (*dbp
))
2171 --dbp
; /* force failure */
2176 while (isdigit (*dbp
));
2185 char nambuf
[BUFSIZ
];
2187 while (isspace (*dbp
))
2192 linecharno
= charno
;
2193 charno
+= readline (&lb
, fi
);
2198 while (isspace (*dbp
))
2207 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
2212 strcpy (nambuf
, dbp
);
2214 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
,
2215 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2219 /* Handle a file of assembler code. */
2235 linecharno
= charno
;
2236 charno
+= readline (&lb
, fi
);
2239 for (i
= 0; ((c
= dbp
[i
]) && !isspace (c
)) && (c
!= ':'); i
++)
2242 if ((i
> 0) && (c
== ':'))
2247 /* Added by Mosur Mohan, 4/22/88 */
2248 /* Pascal parsing */
2250 #define GET_NEW_LINE \
2252 linecharno = charno; lineno++; \
2253 charno += 1 + readline (&lb, inf); \
2257 /* Locates tags for procedures & functions.
2258 * Doesn't do any type- or var-definitions.
2259 * It does look for the keyword "extern" or "forward"
2260 * immediately following the procedure statement;
2261 * if found, the tag is skipped.
2268 struct linebuffer tline
; /* mostly copied from C_entries */
2272 char nambuf
[BUFSIZ
];
2274 logical
/* each of these flags is TRUE iff: */
2275 incomm1
, /* point is inside {..} comment */
2276 incomm2
, /* point is inside (*..*) comment */
2277 inquote
, /* point is inside '..' string */
2278 get_tagname
, /* point is after PROCEDURE/FUNCTION */
2279 /* keyword, so next item = potential tag */
2280 found_tag
, /* point is after a potential tag */
2281 inparms
, /* point is within parameter-list */
2282 verify_tag
; /* point has passed the parm-list, so the */
2283 /* next token will determine whether */
2284 /* this is a FORWARD/EXTERN to be */
2285 /* ignored, or whether it is a real tag */
2291 initbuffer (&tline
);
2293 incomm1
= incomm2
= inquote
= FALSE
;
2294 found_tag
= FALSE
; /* have a proc name; check if extern */
2295 get_tagname
= FALSE
; /* have found "procedure" keyword */
2296 inparms
= FALSE
; /* found '(' after "proc" */
2297 verify_tag
= FALSE
; /* check if "extern" is ahead */
2299 /* long main loop to get next char */
2303 if (c
== 0) /* if end of line */
2308 if (!((found_tag
&& verify_tag
) ||
2310 c
= *dbp
++; /* only if don't need *dbp pointing */
2311 /* to the beginning of the name of */
2312 /* the procedure or function */
2314 if (incomm1
) /* within { - } comments */
2320 else if (incomm2
) /* within (* - *) comments */
2324 while ((c
= *dbp
++) == '*')
2343 inquote
= TRUE
; /* found first quote */
2345 case '{': /* found open-{-comment */
2349 if (*dbp
== '*') /* found open-(*-comment */
2354 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
2357 case ')': /* end of parms list */
2362 if ((found_tag
) && (!inparms
)) /* end of proc or fn stmt */
2369 if ((found_tag
) && (verify_tag
) && (*dbp
!= ' '))
2371 /* check if this is an "extern" declaration */
2374 if ((*dbp
== 'e') || (*dbp
== 'E'))
2376 if (tail ("extern")) /* superfluous, really! */
2382 else if ((*dbp
== 'f') || (*dbp
== 'F'))
2384 if (tail ("forward")) /* check for forward reference */
2390 if ((found_tag
) && (verify_tag
)) /* not external proc, so make tag */
2394 pfnote (nambuf
, TRUE
, FALSE
,
2395 tline
.buffer
, cp
- tline
.buffer
+ 1,
2396 save_lineno
, save_lcno
);
2400 if (get_tagname
) /* grab name of proc or fn */
2405 /* save all values for later tagging */
2406 tline
.size
= lb
.size
;
2407 strcpy (tline
.buffer
, lb
.buffer
);
2408 save_lineno
= lineno
;
2409 save_lcno
= linecharno
;
2411 /* grab block name */
2412 for (cp
= dbp
+ 1; *cp
&& (!endtoken (*cp
)); cp
++)
2416 strcpy (nambuf
, dbp
);
2418 dbp
= cp
; /* restore dbp to e-o-token */
2419 get_tagname
= FALSE
;
2423 /* and proceed to check for "extern" */
2425 if ((!incomm1
) && (!incomm2
) && (!inquote
) &&
2426 (!found_tag
) && (!get_tagname
))
2428 /* check for proc/fn keywords */
2432 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
2436 if (tail ("unction"))
2441 } /* while not e-o-f */
2445 * lisp tag functions
2446 * just look for (def or (DEF
2460 linecharno
= charno
;
2461 charno
+= readline (&lb
, fi
);
2467 while (!isspace (*dbp
))
2469 while (isspace (*dbp
))
2475 /* Check for (foo::defmumble name-defined ... */
2478 while (*dbp
&& !isspace (*dbp
)
2479 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
2484 while (*dbp
== ':');
2486 if (L_isdef (dbp
- 1))
2488 while (!isspace (*dbp
))
2490 while (isspace (*dbp
))
2504 return ((dbp
[1] == 'd' || dbp
[1] == 'D')
2505 && (dbp
[2] == 'e' || dbp
[2] == 'E')
2506 && (dbp
[3] == 'f' || dbp
[3] == 'F'));
2513 return ((*(++dbp
) == 'q' || *dbp
== 'Q')
2514 && (*(++dbp
) == 'u' || *dbp
== 'U')
2515 && (*(++dbp
) == 'o' || *dbp
== 'O')
2516 && (*(++dbp
) == 't' || *dbp
== 'T')
2517 && (*(++dbp
) == 'e' || *dbp
== 'E')
2518 && isspace(*(++dbp
)));
2526 char nambuf
[BUFSIZ
];
2528 if (*dbp
== '\'') /* Skip prefix quote */
2530 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
2533 while (isspace(*dbp
))
2536 for (cp
= dbp
/*+1*/; *cp
&& *cp
!= '(' && *cp
!= ' ' && *cp
!= ')'; cp
++)
2543 strcpy (nambuf
, dbp
);
2545 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
,
2546 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2551 * Scheme tag functions
2552 * look for (def... xyzzy
2553 * look for (def... (xyzzy
2554 * look for (def ... ((...(xyzzy ....
2555 * look for (set! xyzzy
2558 static void get_scheme ();
2571 linecharno
= charno
;
2572 charno
+= readline (&lb
, fi
);
2574 if (dbp
[0] == '(' &&
2575 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
2576 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2577 (dbp
[3] == 'F' || dbp
[3] == 'f'))
2579 while (!isspace (*dbp
))
2581 /* Skip over open parens and white space */
2582 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
2586 if (dbp
[0] == '(' &&
2587 (dbp
[1] == 'S' || dbp
[1] == 's') &&
2588 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2589 (dbp
[3] == 'T' || dbp
[3] == 't') &&
2590 (dbp
[4] == '!' || dbp
[4] == '!') &&
2593 while (!isspace (*dbp
))
2595 /* Skip over white space */
2596 while (isspace (*dbp
))
2608 char nambuf
[BUFSIZ
];
2612 /* Go till you get to white space or a syntactic break */
2613 for (cp
= dbp
+ 1; *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
); cp
++)
2615 /* Null terminate the string there. */
2618 /* Copy the string */
2619 strcpy (nambuf
, dbp
);
2620 /* Unterminate the string */
2622 /* Announce the change */
2623 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2627 /* Find tags in TeX and LaTeX input files. */
2629 /* TEX_toktab is a table of TeX control sequences that define tags.
2630 Each TEX_tabent records one such control sequence.
2631 CONVERT THIS TO USE THE Stab TYPE!! */
2639 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
2641 /* Default set of control sequences to put into TEX_toktab.
2642 The value of environment var TEXTAGS is prepended to this. */
2644 static char *TEX_defenv
=
2645 ":chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
2648 struct TEX_tabent
*TEX_decode_env ();
2652 static char TEX_esc
= '\\';
2653 static char TEX_opgrp
= '{';
2654 static char TEX_clgrp
= '}';
2657 * TeX/LaTeX scanning loop.
2670 /* Select either \ or ! as escape character. */
2673 /* Initialize token table once from environment. */
2675 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
2678 { /* Scan each line in file */
2680 linecharno
= charno
;
2681 charno
+= readline (&lb
, fi
);
2684 while (dbp
= etags_index (dbp
, TEX_esc
)) /* Look at each escape in line */
2690 linecharno
+= dbp
- lasthit
;
2692 i
= TEX_Token (lasthit
);
2695 TEX_getit (lasthit
, TEX_toktab
[i
].len
);
2696 break; /* We only save a line once */
2702 #define TEX_LESC '\\'
2703 #define TEX_SESC '!'
2706 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping */
2707 /* chars accordingly. */
2715 while ((c
= getc (f
)) != EOF
)
2717 /* Skip to next line if we hit the TeX comment char. */
2721 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
2740 /* Read environment and prepend it to the default string. */
2741 /* Build token table. */
2744 TEX_decode_env (evarname
, defenv
)
2748 register char *env
, *p
;
2750 struct TEX_tabent
*tab
;
2753 /* Append default string to environment. */
2754 env
= getenv (evarname
);
2758 env
= concat (env
, defenv
, "");
2760 /* Allocate a token table */
2761 for (size
= 1, p
= env
; p
;)
2762 if ((p
= etags_index (p
, ':')) && *(++p
))
2764 /* Add 1 to leave room for null terminator. */
2765 tab
= xnew (size
+ 1, struct TEX_tabent
);
2767 /* Unpack environment string into token table. Be careful about */
2768 /* zero-length strings (leading ':', "::" and trailing ':') */
2771 p
= etags_index (env
, ':');
2772 if (!p
) /* End of environment string. */
2773 p
= env
+ strlen (env
);
2775 { /* Only non-zero strings. */
2776 tab
[i
].name
= savenstr (env
, p
- env
);
2777 tab
[i
].len
= strlen (tab
[i
].name
);
2784 tab
[i
].name
= NULL
; /* Mark end of table. */
2792 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
2793 The name being defined actually starts at (NAME + LEN + 1).
2794 But we seem to include the TeX command in the tag name. */
2797 TEX_getit (name
, len
)
2801 char *p
= name
+ len
;
2802 char nambuf
[BUFSIZ
];
2807 /* Let tag name extend to next group close (or end of line) */
2808 while (*p
&& *p
!= TEX_clgrp
)
2810 strncpy (nambuf
, name
, p
- name
);
2811 nambuf
[p
- name
] = 0;
2813 pfnote (nambuf
, TRUE
, FALSE
, lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
2817 /* If the text at CP matches one of the tag-defining TeX command names,
2818 return the etags_index of that command in TEX_toktab.
2819 Otherwise return -1. */
2821 /* Keep the capital `T' in `Token' for dumb truncating compilers
2822 (this distinguishes it from `TEX_toktab' */
2829 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
2830 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
2835 /* Support for Prolog. */
2837 /* whole head (not only functor, but also arguments)
2838 is gotten in compound term. */
2841 prolog_getit (s
, lineno
, linecharno
)
2846 char nambuf
[BUFSIZ
], *save_s
, tmpc
;
2854 if (*s
== '\0') /* syntax error. */
2856 else if (insquote
&& *s
== '\'' && *(s
+ 1) == '\'')
2858 else if (*s
== '\'')
2860 insquote
= !insquote
;
2863 else if (!insquote
&& *s
== '(')
2868 else if (!insquote
&& *s
== ')')
2874 else if (npar
< 0) /* syntax error. */
2877 else if (!insquote
&& *s
== '.' && (isspace (*(s
+ 1)) || *(s
+ 1) == '\0'))
2879 if (npar
!= 0) /* syntax error. */
2889 strcpy (nambuf
, save_s
);
2891 pfnote (nambuf
, TRUE
, FALSE
, save_s
, strlen (nambuf
), lineno
, linecharno
);
2894 /* It is assumed that prolog predicate starts from column 0. */
2900 void skip_comment (), prolog_getit ();
2902 lineno
= linecharno
= charno
= 0;
2906 linecharno
+= charno
;
2907 charno
= readline (&lb
, fi
) + 1; /* 1 for newline. */
2909 if (isspace (dbp
[0])) /* not predicate header. */
2911 else if (dbp
[0] == '%') /* comment. */
2913 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
2914 skip_comment (&lb
, fi
, &lineno
, &linecharno
);
2916 prolog_getit (dbp
, lineno
, linecharno
);
2921 skip_comment (plb
, fi
, plineno
, plinecharno
)
2922 struct linebuffer
*plb
;
2924 int *plineno
; /* result */
2925 long *plinecharno
; /* result */
2927 while (!substr ("*/", plb
->buffer
))
2930 *plinecharno
+= readline (plb
, fi
) + 1;
2931 } /* 1 for newline. */
2934 /* Return TRUE if 'sub' exists somewhere in 's'. */
2941 while (*s
&& (s
= etags_index (s
, *sub
)))
2942 if (prestr (sub
, s
))
2949 /* Return TRUE if 'pre' is prefix of string 's'. */
2958 else if (*pre
== *s
)
2959 return (prestr (pre
+ 1, s
+ 1));
2964 /* Initialize a linebuffer for use */
2967 initbuffer (linebuffer
)
2968 struct linebuffer
*linebuffer
;
2970 linebuffer
->size
= 200;
2971 linebuffer
->buffer
= xnew (200, char);
2975 * Read a line of text from `stream' into `linebuffer'.
2976 * Return the number of characters read from `stream',
2977 * which is the length of the line including the newline, if any.
2980 readline (linebuffer
, stream
)
2981 struct linebuffer
*linebuffer
;
2982 register FILE *stream
;
2984 char *buffer
= linebuffer
->buffer
;
2985 register char *p
= linebuffer
->buffer
;
2986 register char *pend
;
2987 int newline
; /* 1 if ended with newline, 0 if ended with EOF */
2989 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
2993 register int c
= getc (stream
);
2996 linebuffer
->size
*= 2;
2997 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
2998 p
+= buffer
- linebuffer
->buffer
;
2999 pend
= buffer
+ linebuffer
->size
;
3000 linebuffer
->buffer
= buffer
;
3002 if (c
== EOF
|| c
== '\n')
3005 newline
= (c
== '\n') ? 1 : 0;
3011 return p
- buffer
+ newline
;
3018 return savenstr (cp
, strlen (cp
));
3028 dp
= xnew (len
+ 1, char);
3029 strncpy (dp
, cp
, len
);
3035 * Return the ptr in sp at which the character c last
3036 * appears; NULL if not found
3038 * Identical to v7 rindex, included for portability.
3042 etags_rindex (sp
, c
)
3043 register char *sp
, c
;
3058 * Return the ptr in sp at which the character c first
3059 * appears; NULL if not found
3061 * Identical to v7 index, included for portability.
3066 register char *sp
, c
;
3076 /* Print error message and exit. */
3087 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
3094 fprintf (stderr
, "%s: ", progname
);
3095 fprintf (stderr
, s1
, s2
);
3096 fprintf (stderr
, "\n");
3099 /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */
3105 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
3106 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
3108 strcpy (result
, s1
);
3109 strcpy (result
+ len1
, s2
);
3110 strcpy (result
+ len1
+ len2
, s3
);
3111 *(result
+ len1
+ len2
+ len3
) = 0;
3116 /* Like malloc but get fatal error if memory is exhausted. */
3122 char *result
= (char *) malloc (size
);
3124 fatal ("virtual memory exhausted", 0);
3129 xrealloc (ptr
, size
)
3133 char *result
= (char *) realloc (ptr
, size
);
3135 fatal ("virtual memory exhausted");