1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey.
31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer.
34 char pot_etags_version
[] = "@(#) pot revision number is 11.71";
46 # include <sys/param.h>
54 # define MAXPATHLEN _MAX_PATH
59 /* On some systems, Emacs defines static as nothing for the sake
60 of unexec. We don't want that here since we don't use unexec. */
70 #include <sys/types.h>
73 #if !defined (S_ISREG) && defined (S_IFREG)
74 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
81 #endif /* ETAGS_REGEXPS */
83 /* Define CTAGS to make the program "ctags" compatible with the usual one.
84 Let it undefined to make the program "etags", which makes emacs-style
85 tag tables and tags typedefs, #defines and struct/union/enum by default. */
93 /* Exit codes for success and failure. */
103 #define C_PLPL 0x00001 /* C++ */
104 #define C_STAR 0x00003 /* C* */
105 #define YACC 0x10000 /* yacc file */
107 #define streq(s,t) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strcmp(s,t))
108 #define strneq(s,t,n) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strncmp(s,t,n))
110 #define lowcase(c) tolower ((unsigned char)c)
112 #define iswhite(arg) (_wht[arg]) /* T if char is white */
113 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
114 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
115 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
118 # define absolutefn(fn) (fn[0] == '/' \
119 || (fn[1] == ':' && fn[2] == '/'))
121 # define absolutefn(fn) (fn[0] == '/')
126 * xnew -- allocate storage
128 * SYNOPSIS: Type *xnew (int n, Type);
130 #define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
135 { /* sorting structure */
136 char *name
; /* function or type name */
137 char *file
; /* file name */
138 logical is_func
; /* use pattern or line no */
139 logical been_warned
; /* set if noticed dup */
140 int lno
; /* line number tag is on */
141 long cno
; /* character number line starts on */
142 char *pat
; /* search pattern */
143 struct nd_st
*left
, *right
; /* left and right sons */
146 extern char *getenv ();
149 char *savenstr (), *savestr ();
150 char *etags_strchr (), *etags_strrchr ();
151 char *etags_getcwd ();
152 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
153 long *xmalloc (), *xrealloc ();
155 typedef void Lang_function ();
156 #if FALSE /* many compilers barf on this */
157 Lang_function Asm_labels
;
158 Lang_function default_C_entries
;
159 Lang_function C_entries
;
160 Lang_function Cplusplus_entries
;
161 Lang_function Cstar_entries
;
162 Lang_function Erlang_functions
;
163 Lang_function Fortran_functions
;
164 Lang_function Yacc_entries
;
165 Lang_function Lisp_functions
;
166 Lang_function Pascal_functions
;
167 Lang_function Perl_functions
;
168 Lang_function Prolog_functions
;
169 Lang_function Scheme_functions
;
170 Lang_function TeX_functions
;
171 Lang_function just_read_file
;
172 #else /* so let's write it this way */
175 void default_C_entries ();
176 void plain_C_entries ();
177 void Cplusplus_entries ();
178 void Cstar_entries ();
179 void Erlang_functions ();
180 void Fortran_functions ();
181 void Yacc_entries ();
182 void Lisp_functions ();
183 void Pascal_functions ();
184 void Perl_functions ();
185 void Prolog_functions ();
186 void Scheme_functions ();
187 void TeX_functions ();
188 void just_read_file ();
191 Lang_function
*get_language_from_name ();
192 Lang_function
*get_language_from_interpreter ();
193 Lang_function
*get_language_from_suffix ();
194 int total_size_of_entries ();
196 long readline_internal ();
202 void suggest_asking_for_help ();
203 void fatal (), pfatal ();
204 void find_entries ();
210 void process_file ();
215 char searchar
= '/'; /* use /.../ searches */
217 int lineno
; /* line number of current line */
218 long charno
; /* current character number */
219 long linecharno
; /* charno of start of line */
221 char *curfile
; /* current input file name */
222 char *tagfile
; /* output file */
223 char *progname
; /* name this program was invoked with */
224 char *cwd
; /* current working directory */
225 char *tagfiledir
; /* directory of tagfile */
227 FILE *tagf
; /* ioptr for tags file */
228 NODE
*head
; /* the head of the binary tree of tags */
231 * A `struct linebuffer' is a structure which holds a line of text.
232 * `readline' reads a line from a stream into a linebuffer and works
233 * regardless of the length of the line.
235 #define GROW_LINEBUFFER(buf,toksize) \
236 while (buf.size < toksize) \
237 buf.buffer = (char *) xrealloc (buf.buffer, buf.size *= 2)
244 struct linebuffer lb
; /* the current line */
245 struct linebuffer token_name
; /* used by C_entries as a temporary area */
249 struct linebuffer lb
; /* used by C_entries instead of lb */
252 /* boolean "functions" (see init) */
253 logical _wht
[0177], _etk
[0177], _itk
[0177], _btk
[0177];
256 *white
= " \f\t\n\013",
257 /* token ending chars */
258 *endtk
= " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?",
259 /* token starting chars */
260 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
261 /* valid in-token chars */
262 *intk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
264 logical append_to_tagfile
; /* -a: append to tags */
265 /* The following three default to TRUE for etags, but to FALSE for ctags. */
266 logical typedefs
; /* -t: create tags for typedefs */
267 logical typedefs_and_cplusplus
; /* -T: create tags for typedefs, level */
268 /* 0 struct/enum/union decls, and C++ */
269 /* member functions. */
270 logical constantypedefs
; /* -d: create tags for C #define and enum */
271 /* constants. Enum consts not implemented. */
272 /* -D: opposite of -d. Default under ctags. */
273 logical update
; /* -u: update tags */
274 logical vgrind_style
; /* -v: create vgrind style index output */
275 logical no_warnings
; /* -w: suppress warnings */
276 logical cxref_style
; /* -x: create cxref style output */
277 logical cplusplus
; /* .[hc] means C++, not C */
278 logical noindentypedefs
; /* -I: ignore indentation in C */
280 struct option longopts
[] =
282 { "append", no_argument
, NULL
, 'a' },
283 { "backward-search", no_argument
, NULL
, 'B' },
284 { "c++", no_argument
, NULL
, 'C' },
285 { "cxref", no_argument
, NULL
, 'x' },
286 { "defines", no_argument
, NULL
, 'd' },
287 { "help", no_argument
, NULL
, 'h' },
288 { "help", no_argument
, NULL
, 'H' },
289 { "ignore-indentation", no_argument
, NULL
, 'I' },
290 { "include", required_argument
, NULL
, 'i' },
291 { "language", required_argument
, NULL
, 'l' },
292 { "no-defines", no_argument
, NULL
, 'D' },
293 { "no-regex", no_argument
, NULL
, 'R' },
294 { "no-warn", no_argument
, NULL
, 'w' },
295 { "output", required_argument
, NULL
, 'o' },
296 { "regex", required_argument
, NULL
, 'r' },
297 { "typedefs", no_argument
, NULL
, 't' },
298 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
299 { "update", no_argument
, NULL
, 'u' },
300 { "version", no_argument
, NULL
, 'V' },
301 { "vgrind", no_argument
, NULL
, 'v' },
306 /* Structure defining a regular expression. Elements are
307 the compiled pattern, and the name string. */
310 struct re_pattern_buffer
*pattern
;
311 struct re_registers regs
;
313 logical error_signaled
;
316 /* Number of regexps found. */
317 int num_patterns
= 0;
319 /* Array of all regexps. */
320 struct pattern
*patterns
= NULL
;
321 #endif /* ETAGS_REGEXPS */
327 /* Non-NULL if language fixed. */
328 Lang_function
*lang_func
= NULL
;
331 char *Asm_suffixes
[] = { "a", /* Unix assembler */
332 "asm", /* Microcontroller assembly */
333 "def", /* BSO/Tasking definition includes */
334 "inc", /* Microcontroller include files */
335 "ins", /* Microcontroller include files */
336 "s", "sa", /* Unix assembler */
337 "src", /* BSO/Tasking C compiler output */
341 /* Note that .c and .h can be considered C++, if the --c++ flag was
342 given. That is why default_C_entries is called here. */
343 char *default_C_suffixes
[] =
346 /* .M is for Objective C++ files. */
347 char *Cplusplus_suffixes
[] =
348 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", "M", NULL
};
350 char *Cstar_suffixes
[] =
351 { "cs", "hs", NULL
};
353 char *Erlang_suffixes
[] =
354 { "erl", "hrl", NULL
};
356 char *Fortran_suffixes
[] =
357 { "F", "f", "f90", "for", NULL
};
359 char *Lisp_suffixes
[] =
360 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL
};
362 char *Pascal_suffixes
[] =
363 { "p", "pas", NULL
};
365 char *Perl_suffixes
[] =
366 { "pl", "pm", NULL
};
367 char *Perl_interpreters
[] =
368 { "perl", "@PERL@", NULL
};
370 char *plain_C_suffixes
[] =
371 { "pc", /* Pro*C file */
372 "m", /* Objective C file */
373 "lm", /* Objective lex file */
376 char *Prolog_suffixes
[] =
379 /* Can't do the `SCM' or `scm' prefix with a version number. */
380 char *Scheme_suffixes
[] =
381 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL
};
383 char *TeX_suffixes
[] =
384 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL
};
386 char *Yacc_suffixes
[] =
387 { "y", "ym", NULL
}; /* .ym is Objective yacc file */
389 /* Table of language names and corresponding functions, file suffixes
390 and interpreter names.
391 It is ok for a given function to be listed under more than one
392 name. I just didn't. */
396 Lang_function
*function
;
401 struct lang_entry lang_names
[] =
403 { "asm", Asm_labels
, Asm_suffixes
, NULL
},
404 { "c", default_C_entries
, default_C_suffixes
, NULL
},
405 { "c++", Cplusplus_entries
, Cplusplus_suffixes
, NULL
},
406 { "c*", Cstar_entries
, Cstar_suffixes
, NULL
},
407 { "erlang", Erlang_functions
, Erlang_suffixes
, NULL
},
408 { "fortran", Fortran_functions
, Fortran_suffixes
, NULL
},
409 { "lisp", Lisp_functions
, Lisp_suffixes
, NULL
},
410 { "pascal", Pascal_functions
, Pascal_suffixes
, NULL
},
411 { "perl", Perl_functions
, Perl_suffixes
, Perl_interpreters
},
412 { "proc", plain_C_entries
, plain_C_suffixes
, NULL
},
413 { "prolog", Prolog_functions
, Prolog_suffixes
, NULL
},
414 { "scheme", Scheme_functions
, Scheme_suffixes
, NULL
},
415 { "tex", TeX_functions
, TeX_suffixes
, NULL
},
416 { "yacc", Yacc_entries
, Yacc_suffixes
, NULL
},
417 { "auto", NULL
}, /* default guessing scheme */
418 { "none", just_read_file
}, /* regexp matching only */
419 { NULL
, NULL
} /* end of list */
424 print_language_names ()
426 struct lang_entry
*lang
;
429 puts ("\nThese are the currently supported languages, along with the\n\
430 default file name suffixes:");
431 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
433 printf ("\t%s\t", lang
->name
);
434 if (lang
->suffixes
!= NULL
)
435 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
436 printf (" .%s", *ext
);
439 puts ("Where `auto' means use default language for files based on file\n\
440 name suffix, and `none' means only do regexp processing on files.\n\
441 If no language is specified and no matching suffix is found,\n\
442 the first line of the file is read for a sharp-bang (#!) sequence\n\
443 followed by the name of an interpreter. If no such sequence is found,\n\
444 Fortran is tried first; if no tags are found, C is tried next.");
448 # define VERSION "19"
453 printf ("%s (GNU Emacs %s)\n", (CTAGS
) ? "ctags" : "etags", VERSION
);
454 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold");
455 puts ("This program is distributed under the same terms as Emacs");
463 printf ("These are the options accepted by %s. You may use unambiguous\n\
464 abbreviations for the long option names. A - as file name means read\n\
465 names from stdin.", progname
);
467 printf (" Absolute names are stored in the output file as they\n\
468 are. Relative ones are stored relative to the output file's directory.");
471 puts ("-a, --append\n\
472 Append tag entries to existing tags file.");
475 puts ("-B, --backward-search\n\
476 Write the search commands for the tag entries using '?', the\n\
477 backward-search command instead of '/', the forward-search command.");
480 Treat files whose name suffix defaults to C language as C++ files.");
483 puts ("-d, --defines\n\
484 Create tag entries for constant C #defines, too.");
486 puts ("-D, --no-defines\n\
487 Don't create tag entries for constant C #defines. This makes\n\
488 the tags file smaller.");
492 puts ("-i FILE, --include=FILE\n\
493 Include a note in tag file indicating that, when searching for\n\
494 a tag, one should also consult the tags file FILE after\n\
495 checking the current file.");
496 puts ("-l LANG, --language=LANG\n\
497 Force the following files to be considered as written in the\n\
498 named language up to the next --language=LANG option.");
502 puts ("-r /REGEXP/, --regex=/REGEXP/\n\
503 Make a tag for each line matching pattern REGEXP in the\n\
504 following files. REGEXP is anchored (as if preceded by ^).\n\
505 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
506 named tags can be created with:\n\
507 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
508 puts ("-R, --no-regex\n\
509 Don't create tags from regexps for the following files.");
510 #endif /* ETAGS_REGEXPS */
511 puts ("-o FILE, --output=FILE\n\
512 Write the tags to FILE.");
513 puts ("-I, --ignore-indentation\n\
514 Don't rely on indentation quite as much as normal. Currently,\n\
515 this means not to assume that a closing brace in the first\n\
516 column is the final brace of a function or structure\n\
517 definition in C and C++.");
521 puts ("-t, --typedefs\n\
522 Generate tag entries for C typedefs.");
523 puts ("-T, --typedefs-and-c++\n\
524 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
525 and C++ member functions.");
526 puts ("-u, --update\n\
527 Update the tag entries for the given files, leaving tag\n\
528 entries for other files in place. Currently, this is\n\
529 implemented by deleting the existing entries for the given\n\
530 files and then rewriting the new entries at the end of the\n\
531 tags file. It is often faster to simply rebuild the entire\n\
532 tag file than to use this.");
533 puts ("-v, --vgrind\n\
534 Generates an index of items intended for human consumption,\n\
535 similar to the output of vgrind. The index is sorted, and\n\
536 gives the page number of each item.");
537 puts ("-w, --no-warn\n\
538 Suppress warning messages about entries defined in multiple\n\
540 puts ("-x, --cxref\n\
541 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
542 The output uses line numbers instead of page numbers, but\n\
543 beyond that the differences are cosmetic; try both to see\n\
547 puts ("-V, --version\n\
548 Print the version of the program.\n\
550 Print this help message.");
552 print_language_names ();
555 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu");
568 /* This structure helps us allow mixing of --lang and filenames. */
571 enum argument_type arg_type
;
573 Lang_function
*function
;
576 #ifdef VMS /* VMS specific functions */
580 /* This is a BUG! ANY arbitrary limit is a BUG!
581 Won't someone please fix this? */
582 #define MAX_FILE_SPEC_LEN 255
585 char body
[MAX_FILE_SPEC_LEN
+ 1];
589 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
590 returning in each successive call the next filename matching the input
591 spec. The function expects that each in_spec passed
592 to it will be processed to completion; in particular, up to and
593 including the call following that in which the last matching name
594 is returned, the function ignores the value of in_spec, and will
595 only start processing a new spec with the following call.
596 If an error occurs, on return out_spec contains the value
597 of in_spec when the error occurred.
599 With each successive filename returned in out_spec, the
600 function's return value is one. When there are no more matching
601 names the function returns zero. If on the first call no file
602 matches in_spec, or there is any other error, -1 is returned.
607 #define OUTSIZE MAX_FILE_SPEC_LEN
613 static long context
= 0;
614 static struct dsc$descriptor_s o
;
615 static struct dsc$descriptor_s i
;
616 static logical pass1
= TRUE
;
623 o
.dsc$a_pointer
= (char *) out
;
624 o
.dsc$w_length
= (short)OUTSIZE
;
625 i
.dsc$a_pointer
= in
;
626 i
.dsc$w_length
= (short)strlen(in
);
627 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
628 i
.dsc$b_class
= DSC$K_CLASS_S
;
629 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
630 o
.dsc$b_class
= DSC$K_CLASS_VS
;
632 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
634 out
->body
[out
->curlen
] = EOS
;
637 else if (status
== RMS$_NMF
)
641 strcpy(out
->body
, in
);
644 lib$
find_file_end(&context
);
650 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
651 name of each file specified by the provided arg expanding wildcards.
654 gfnames (arg
, p_error
)
658 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
660 switch (fn_exp (&filename
, arg
))
664 return filename
.body
;
670 return filename
.body
;
674 #ifndef OLD /* Newer versions of VMS do provide `system'. */
678 fprintf (stderr
, "system() function not implemented under VMS\n");
682 #define VERSION_DELIM ';'
683 char *massage_name (s
)
689 if (*s
== VERSION_DELIM
)
707 unsigned int nincluded_files
= 0;
708 char **included_files
= xnew (argc
, char *);
711 int current_arg
= 0, file_count
= 0;
712 struct linebuffer filename_lb
;
718 _fmode
= O_BINARY
; /* all of files are treated as binary files */
723 /* Allocate enough no matter what happens. Overkill, but each one
725 argbuffer
= xnew (argc
, argument
);
728 /* Set syntax for regular expression routines. */
729 re_set_syntax (RE_SYNTAX_EMACS
);
730 #endif /* ETAGS_REGEXPS */
733 * If etags, always find typedefs and structure tags. Why not?
734 * Also default is to find macro constants.
737 typedefs
= typedefs_and_cplusplus
= constantypedefs
= TRUE
;
741 int opt
= getopt_long (argc
, argv
,
742 "-aCdDf:Il:o:r:RStTi:BuvxwVhH", longopts
, 0);
750 /* If getopt returns 0, then it has already processed a
751 long-named option. We should do nothing. */
755 /* This means that a filename has been seen. Record it. */
756 argbuffer
[current_arg
].arg_type
= at_filename
;
757 argbuffer
[current_arg
].what
= optarg
;
762 /* Common options. */
764 append_to_tagfile
= TRUE
;
770 constantypedefs
= TRUE
;
773 constantypedefs
= FALSE
;
775 case 'f': /* for compatibility with old makefiles */
779 fprintf (stderr
, "%s: -%c option may only be given once.\n",
781 suggest_asking_for_help ();
786 case 'S': /* for backward compatibility */
787 noindentypedefs
= TRUE
;
790 argbuffer
[current_arg
].function
= get_language_from_name (optarg
);
791 argbuffer
[current_arg
].arg_type
= at_language
;
796 argbuffer
[current_arg
].arg_type
= at_regexp
;
797 argbuffer
[current_arg
].what
= optarg
;
801 argbuffer
[current_arg
].arg_type
= at_regexp
;
802 argbuffer
[current_arg
].what
= NULL
;
805 #endif /* ETAGS_REGEXPS */
817 typedefs
= typedefs_and_cplusplus
= TRUE
;
822 included_files
[nincluded_files
++] = optarg
;
843 suggest_asking_for_help ();
847 for (; optind
< argc
; ++optind
)
849 argbuffer
[current_arg
].arg_type
= at_filename
;
850 argbuffer
[current_arg
].what
= argv
[optind
];
855 if (nincluded_files
== 0 && file_count
== 0)
857 fprintf (stderr
, "%s: No input files specified.\n", progname
);
858 suggest_asking_for_help ();
862 tagfile
= CTAGS
? "tags" : "TAGS";
863 cwd
= etags_getcwd (); /* the current working directory */
864 if (cwd
[strlen (cwd
) - 1] != '/')
865 cwd
= concat (cwd
, "/", "");
866 if (streq (tagfile
, "-"))
869 tagfiledir
= absolute_dirname (tagfile
, cwd
);
871 init (); /* set up boolean "functions" */
874 initbuffer (&token_name
);
875 initbuffer (&lbs
[0].lb
);
876 initbuffer (&lbs
[1].lb
);
877 initbuffer (&filename_lb
);
881 if (streq (tagfile
, "-"))
885 /* Switch redirected `stdout' to binary mode (setting `_fmode'
886 doesn't take effect until after `stdout' is already open). */
887 if (!isatty (fileno (stdout
)))
888 setmode (fileno (stdout
), O_BINARY
);
892 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
898 * Loop through files finding functions.
900 for (i
= 0; i
< current_arg
; ++i
)
902 switch (argbuffer
[i
].arg_type
)
905 lang_func
= argbuffer
[i
].function
;
909 add_regex (argbuffer
[i
].what
);
914 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
918 error ("Can't find file %s\n", this_file
);
923 this_file
= massage_name (this_file
);
926 this_file
= argbuffer
[i
].what
;
928 /* Input file named "-" means read file names from stdin
930 if (streq (this_file
, "-"))
931 while (readline_internal (&filename_lb
, stdin
) > 0)
932 process_file (filename_lb
.buffer
);
934 process_file (this_file
);
944 while (nincluded_files
-- > 0)
945 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
951 /* If CTAGS, we are here. process_file did not write the tags yet,
952 because we want them ordered. Let's do it now. */
962 for (i
= 0; i
< current_arg
; ++i
)
964 if (argbuffer
[i
].arg_type
!= at_filename
)
967 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
968 tagfile
, argbuffer
[i
].what
, tagfile
);
969 if (system (cmd
) != GOOD
)
970 fatal ("failed to execute shell command");
972 append_to_tagfile
= TRUE
;
975 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
984 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
992 * Return a Lang_function given the name.
995 get_language_from_name (name
)
998 struct lang_entry
*lang
;
1001 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1003 if (streq (name
, lang
->name
))
1004 return lang
->function
;
1007 fprintf (stderr
, "%s: language \"%s\" not recognized.\n",
1009 suggest_asking_for_help ();
1011 /* This point should never be reached. The function should either
1012 return a function pointer or never return. Note that a NULL
1013 pointer cannot be considered as an error, as it means that the
1014 language has not been explicitely imposed by the user ("auto"). */
1015 return NULL
; /* avoid warnings from compiler */
1020 * Return a Lang_function given the interpreter name.
1023 get_language_from_interpreter (interpreter
)
1026 struct lang_entry
*lang
;
1029 if (interpreter
== NULL
)
1031 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1032 if (lang
->interpreters
!= NULL
)
1033 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1034 if (streq (*iname
, interpreter
))
1035 return lang
->function
;
1043 * Return a Lang_function given the file suffix.
1046 get_language_from_suffix (suffix
)
1049 struct lang_entry
*lang
;
1054 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1055 if (lang
->suffixes
!= NULL
)
1056 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1057 if (streq (*ext
, suffix
))
1058 return lang
->function
;
1065 * This routine is called on each file argument.
1071 struct stat stat_buf
;
1076 for (p
= file
; *p
!= '\0'; p
++)
1081 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
1083 fprintf (stderr
, "Skipping %s: it is not a regular file.\n", file
);
1086 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1088 fprintf (stderr
, "Skipping inclusion of %s in self.\n", file
);
1091 inf
= fopen (file
, "r");
1098 find_entries (file
, inf
);
1104 if (absolutefn (file
))
1106 /* file is an absolute filename. Canonicalise it. */
1107 filename
= absolute_filename (file
, cwd
);
1111 /* file is a filename relative to cwd. Make it relative
1112 to the directory of the tags file. */
1113 filename
= relative_filename (file
, tagfiledir
);
1115 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1124 * This routine sets up the boolean pseudo-functions which work
1125 * by setting boolean flags dependent upon the corresponding character
1126 * Every char which is NOT in that string is not a white char. Therefore,
1127 * all of the array "_wht" is set to FALSE, and then the elements
1128 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1129 * of a char is TRUE if it is the string "white", else FALSE.
1137 for (i
= 0; i
< 0177; i
++)
1138 _wht
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
1139 for (sp
= white
; *sp
; sp
++)
1141 for (sp
= endtk
; *sp
; sp
++)
1143 for (sp
= intk
; *sp
; sp
++)
1145 for (sp
= begtk
; *sp
; sp
++)
1147 _wht
[0] = _wht
['\n'];
1148 _etk
[0] = _etk
['\n'];
1149 _btk
[0] = _btk
['\n'];
1150 _itk
[0] = _itk
['\n'];
1154 * This routine opens the specified file and calls the function
1155 * which finds the function and type definitions.
1158 find_entries (file
, inf
)
1163 Lang_function
*function
;
1164 NODE
*old_last_node
;
1165 extern NODE
*last_node
;
1168 /* Memory leakage here: the memory block pointed by curfile is never
1169 released. The amount of memory leaked here is the sum of the
1170 lengths of the input file names. */
1171 curfile
= savestr (file
);
1173 /* If user specified a language, use it. */
1174 function
= lang_func
;
1175 if (function
!= NULL
)
1182 cp
= etags_strrchr (file
, '.');
1186 function
= get_language_from_suffix (cp
);
1187 if (function
!= NULL
)
1195 /* Look for sharp-bang as the first two characters. */
1196 if (readline_internal (&lb
, inf
) > 2
1197 && lb
.buffer
[0] == '#'
1198 && lb
.buffer
[1] == '!')
1202 /* Set lp to point at the first char after the last slash in the
1203 line or, if no slashes, at the first nonblank. Then set cp to
1204 the first successive blank and terminate the string. */
1205 lp
= etags_strrchr (lb
.buffer
+2, '/');
1209 for (lp
= lb
.buffer
+2; *lp
!= '\0' && isspace (*lp
); lp
++)
1211 for (cp
= lp
; *cp
!= '\0' && !isspace (*cp
); cp
++)
1215 if (strlen (lp
) > 0)
1217 function
= get_language_from_interpreter (lp
);
1218 if (function
!= NULL
)
1229 old_last_node
= last_node
;
1230 Fortran_functions (inf
);
1232 /* No Fortran entries found. Try C. */
1233 if (old_last_node
== last_node
)
1236 default_C_entries (inf
);
1244 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1245 char *name
; /* tag name, or NULL if unnamed */
1246 logical is_func
; /* tag is a function */
1247 char *linestart
; /* start of the line where tag is */
1248 int linelen
; /* length of the line where tag is */
1249 int lno
; /* line number */
1250 long cno
; /* character number */
1254 if (CTAGS
&& name
== NULL
)
1257 np
= xnew (1, NODE
);
1259 /* If ctags mode, change name "main" to M<thisfilename>. */
1260 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1262 register char *fp
= etags_strrchr (curfile
, '/');
1263 np
->name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
1264 fp
= etags_strrchr (np
->name
, '.');
1265 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
1270 np
->been_warned
= FALSE
;
1272 np
->is_func
= is_func
;
1274 /* Our char numbers are 0-base, because of C language tradition?
1275 ctags compatibility? old versions compatibility? I don't know.
1276 Anyway, since emacs's are 1-base we expect etags.el to take care
1277 of the difference. If we wanted to have 1-based numbers, we would
1278 uncomment the +1 below. */
1279 np
->cno
= cno
/* + 1 */ ;
1280 np
->left
= np
->right
= NULL
;
1281 if (CTAGS
&& !cxref_style
)
1283 if (strlen (linestart
) < 50)
1284 np
->pat
= concat (linestart
, "$", "");
1286 np
->pat
= savenstr (linestart
, 50);
1289 np
->pat
= savenstr (linestart
, linelen
);
1291 add_node (np
, &head
);
1296 * recurse on left children, iterate on right children.
1300 register NODE
*node
;
1304 register NODE
*node_right
= node
->right
;
1305 free_tree (node
->left
);
1306 if (node
->name
!= NULL
)
1309 free ((char *) node
);
1316 * Adds a node to the tree of nodes. In etags mode, we don't keep
1317 * it sorted; we just keep a linear list. In ctags mode, maintain
1318 * an ordered tree, with no attempt at balancing.
1320 * add_node is the only function allowed to add nodes, so it can
1323 NODE
*last_node
= NULL
;
1325 add_node (node
, cur_node_p
)
1326 NODE
*node
, **cur_node_p
;
1329 register NODE
*cur_node
= *cur_node_p
;
1331 if (cur_node
== NULL
)
1341 if (last_node
== NULL
)
1342 fatal ("internal error in add_node", 0);
1343 last_node
->right
= node
;
1349 dif
= strcmp (node
->name
, cur_node
->name
);
1352 * If this tag name matches an existing one, then
1353 * do not add the node, but maybe print a warning.
1357 if (streq (node
->file
, cur_node
->file
))
1361 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1362 node
->file
, lineno
, node
->name
);
1363 fprintf (stderr
, "Second entry ignored\n");
1366 else if (!cur_node
->been_warned
&& !no_warnings
)
1370 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1371 node
->file
, cur_node
->file
, node
->name
);
1372 cur_node
->been_warned
= TRUE
;
1377 /* Actually add the node */
1378 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1384 register NODE
*node
;
1391 /* Output subentries that precede this one */
1392 put_entries (node
->left
);
1394 /* Output this entry */
1398 if (node
->name
!= NULL
)
1399 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1400 node
->pat
, node
->name
, node
->lno
, node
->cno
);
1402 fprintf (tagf
, "%s\177%d,%d\n",
1403 node
->pat
, node
->lno
, node
->cno
);
1407 if (node
->name
== NULL
)
1408 error ("internal error: NULL name in ctags mode.", 0);
1413 fprintf (stdout
, "%s %s %d\n",
1414 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1416 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1417 node
->name
, node
->lno
, node
->file
, node
->pat
);
1421 fprintf (tagf
, "%s\t%s\t", node
->name
, node
->file
);
1425 putc (searchar
, tagf
);
1428 for (sp
= node
->pat
; *sp
; sp
++)
1430 if (*sp
== '\\' || *sp
== searchar
)
1434 putc (searchar
, tagf
);
1437 { /* a typedef; text pattern inadequate */
1438 fprintf (tagf
, "%d", node
->lno
);
1444 /* Output subentries that follow this one */
1445 put_entries (node
->right
);
1448 /* Length of a number's decimal representation. */
1456 for (; num
; num
/= 10)
1462 * Return total number of characters that put_entries will output for
1463 * the nodes in the subtree of the specified node. Works only if
1464 * we are not ctags, but called only in that case. This count
1465 * is irrelevant with the new tags.el, but is still supplied for
1466 * backward compatibility.
1469 total_size_of_entries (node
)
1470 register NODE
*node
;
1478 for (; node
; node
= node
->right
)
1480 /* Count left subentries. */
1481 total
+= total_size_of_entries (node
->left
);
1483 /* Count this entry */
1484 total
+= strlen (node
->pat
) + 1;
1485 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1486 if (node
->name
!= NULL
)
1487 total
+= 1 + strlen (node
->name
); /* \001name */
1494 * The C symbol tables.
1498 st_none
, st_C_objprot
, st_C_objimpl
, st_C_objend
, st_C_gnumacro
,
1499 st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1502 /* Feed stuff between (but not including) %[ and %] lines to:
1503 gperf -c -k 1,3 -o -p -r -t
1505 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1507 @interface, 0, st_C_objprot
1508 @protocol, 0, st_C_objprot
1509 @implementation,0, st_C_objimpl
1510 @end, 0, st_C_objend
1511 class, C_PLPL, st_C_struct
1512 namespace, C_PLPL, st_C_struct
1513 domain, C_STAR, st_C_struct
1514 union, 0, st_C_struct
1515 struct, 0, st_C_struct
1517 typedef, 0, st_C_typedef
1518 define, 0, st_C_define
1519 bool, C_PLPL, st_C_typespec
1520 long, 0, st_C_typespec
1521 short, 0, st_C_typespec
1522 int, 0, st_C_typespec
1523 char, 0, st_C_typespec
1524 float, 0, st_C_typespec
1525 double, 0, st_C_typespec
1526 signed, 0, st_C_typespec
1527 unsigned, 0, st_C_typespec
1528 auto, 0, st_C_typespec
1529 void, 0, st_C_typespec
1530 extern, 0, st_C_typespec
1531 static, 0, st_C_typespec
1532 const, 0, st_C_typespec
1533 volatile, 0, st_C_typespec
1534 explicit, C_PLPL, st_C_typespec
1535 mutable, C_PLPL, st_C_typespec
1536 typename, C_PLPL, st_C_typespec
1537 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1538 DEFUN, 0, st_C_gnumacro
1539 SYSCALL, 0, st_C_gnumacro
1540 ENTRY, 0, st_C_gnumacro
1541 PSEUDO, 0, st_C_gnumacro
1542 # These are defined inside C functions, so currently they are not met.
1543 # EXFUN used in glibc, DEFVAR_* in emacs.
1544 #EXFUN, 0, st_C_gnumacro
1545 #DEFVAR_, 0, st_C_gnumacro
1547 and replace lines between %< and %> with its output. */
1549 /* C code produced by gperf version 2.1 (K&R C version) */
1550 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1553 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1555 #define MIN_WORD_LENGTH 3
1556 #define MAX_WORD_LENGTH 15
1557 #define MIN_HASH_VALUE 34
1558 #define MAX_HASH_VALUE 121
1561 88 is the maximum key range
1567 register unsigned int len
;
1569 static unsigned char hash_table
[] =
1571 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1572 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1573 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1574 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1575 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1576 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1577 121, 121, 121, 121, 45, 121, 121, 121, 16, 19,
1578 61, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1579 10, 121, 121, 20, 53, 121, 121, 121, 121, 121,
1580 121, 121, 121, 121, 121, 121, 121, 41, 45, 22,
1581 60, 47, 37, 28, 121, 55, 121, 121, 20, 14,
1582 29, 30, 5, 121, 50, 59, 30, 54, 6, 121,
1583 121, 121, 121, 121, 121, 121, 121, 121,
1585 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1588 struct C_stab_entry
*
1589 in_word_set (str
, len
)
1591 register unsigned int len
;
1594 static struct C_stab_entry wordlist
[] =
1596 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1597 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1598 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1599 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1600 {"volatile", 0, st_C_typespec
},
1601 {"PSEUDO", 0, st_C_gnumacro
},
1602 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1603 {"typedef", 0, st_C_typedef
},
1604 {"typename", C_PLPL
, st_C_typespec
},
1605 {"",}, {"",}, {"",},
1606 {"SYSCALL", 0, st_C_gnumacro
},
1607 {"",}, {"",}, {"",},
1608 {"mutable", C_PLPL
, st_C_typespec
},
1609 {"namespace", C_PLPL
, st_C_struct
},
1610 {"long", 0, st_C_typespec
},
1612 {"const", 0, st_C_typespec
},
1613 {"",}, {"",}, {"",},
1614 {"explicit", C_PLPL
, st_C_typespec
},
1615 {"",}, {"",}, {"",}, {"",},
1616 {"void", 0, st_C_typespec
},
1618 {"char", 0, st_C_typespec
},
1619 {"class", C_PLPL
, st_C_struct
},
1620 {"",}, {"",}, {"",},
1621 {"float", 0, st_C_typespec
},
1623 {"@implementation", 0, st_C_objimpl
},
1624 {"auto", 0, st_C_typespec
},
1626 {"ENTRY", 0, st_C_gnumacro
},
1627 {"@end", 0, st_C_objend
},
1628 {"bool", C_PLPL
, st_C_typespec
},
1629 {"domain", C_STAR
, st_C_struct
},
1631 {"DEFUN", 0, st_C_gnumacro
},
1632 {"extern", 0, st_C_typespec
},
1633 {"@interface", 0, st_C_objprot
},
1634 {"",}, {"",}, {"",},
1635 {"int", 0, st_C_typespec
},
1636 {"",}, {"",}, {"",}, {"",},
1637 {"signed", 0, st_C_typespec
},
1638 {"short", 0, st_C_typespec
},
1639 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1640 {"define", 0, st_C_define
},
1641 {"@protocol", 0, st_C_objprot
},
1642 {"enum", 0, st_C_enum
},
1643 {"static", 0, st_C_typespec
},
1644 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1645 {"union", 0, st_C_struct
},
1646 {"struct", 0, st_C_struct
},
1647 {"",}, {"",}, {"",}, {"",},
1648 {"double", 0, st_C_typespec
},
1649 {"unsigned", 0, st_C_typespec
},
1652 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1654 register int key
= hash (str
, len
);
1656 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1658 register char *s
= wordlist
[key
].name
;
1660 if (*s
== *str
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
1661 return &wordlist
[key
];
1669 C_symtype(str
, len
, c_ext
)
1674 register struct C_stab_entry
*se
= in_word_set(str
, len
);
1676 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1682 * C functions are recognized using a simple finite automaton.
1683 * funcdef is its state variable.
1687 fnone
, /* nothing seen */
1688 ftagseen
, /* function-like tag seen */
1689 fstartlist
, /* just after open parenthesis */
1690 finlist
, /* in parameter list */
1691 flistseen
, /* after parameter list */
1692 fignore
/* before open brace */
1697 * typedefs are recognized using a simple finite automaton.
1698 * typdef is its state variable.
1702 tnone
, /* nothing seen */
1703 ttypedseen
, /* typedef keyword seen */
1704 tinbody
, /* inside typedef body */
1705 tend
, /* just before typedef tag */
1706 tignore
/* junk after typedef tag */
1711 * struct-like structures (enum, struct and union) are recognized
1712 * using another simple finite automaton. `structdef' is its state
1717 snone
, /* nothing seen yet */
1718 skeyseen
, /* struct-like keyword seen */
1719 stagseen
, /* struct-like tag seen */
1720 scolonseen
, /* colon seen after struct-like tag */
1721 sinbody
/* in struct body: recognize member func defs*/
1725 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1726 * struct tag, and structtype is the type of the preceding struct-like
1729 char *structtag
= "<uninited>";
1730 enum sym_type structtype
;
1733 * When objdef is different from onone, objtag is the name of the class.
1735 char *objtag
= "<uninited>";
1738 * Yet another little state machine to deal with preprocessor lines.
1742 dnone
, /* nothing seen */
1743 dsharpseen
, /* '#' seen as first char on line */
1744 ddefineseen
, /* '#' and 'define' seen */
1745 dignorerest
/* ignore rest of line */
1749 * State machine for Objective C protocols and implementations.
1753 onone
, /* nothing seen */
1754 oprotocol
, /* @interface or @protocol seen */
1755 oimplementation
, /* @implementations seen */
1756 otagseen
, /* class name seen */
1757 oparenseen
, /* parenthesis before category seen */
1758 ocatseen
, /* category name seen */
1759 oinbody
, /* in @implementation body */
1760 omethodsign
, /* in @implementation body, after +/- */
1761 omethodtag
, /* after method name */
1762 omethodcolon
, /* after method colon */
1763 omethodparm
, /* after method parameter */
1764 oignore
/* wait for @end */
1768 * Set this to TRUE, and the next token considered is called a function.
1769 * Used only for GNU emacs's function-defining macros.
1771 logical next_token_is_func
;
1774 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1779 * methodlen is the length of the method name stored in token_name.
1785 * checks to see if the current token is at the start of a
1786 * function, or corresponds to a typedef, or is a struct/union/enum
1789 * *IS_FUNC gets TRUE iff the token is a function or macro with args.
1790 * C_EXT is which language we are looking at.
1792 * In the future we will need some way to adjust where the end of
1793 * the token is; for instance, implementing the C++ keyword
1794 * `operator' properly will adjust the end of the token to be after
1795 * whatever follows `operator'.
1803 * next_token_is_func IN OUT
1807 consider_token (str
, len
, c
, c_ext
, cblev
, parlev
, is_func
)
1808 register char *str
; /* IN: token pointer */
1809 register int len
; /* IN: token length */
1810 register char c
; /* IN: first char after the token */
1811 int c_ext
; /* IN: C extensions mask */
1812 int cblev
; /* IN: curly brace level */
1813 int parlev
; /* IN: parenthesis level */
1814 logical
*is_func
; /* OUT: function found */
1816 enum sym_type toktype
= C_symtype (str
, len
, c_ext
);
1819 * Advance the definedef state machine.
1824 /* We're not on a preprocessor line. */
1827 if (toktype
== st_C_define
)
1829 definedef
= ddefineseen
;
1833 definedef
= dignorerest
;
1838 * Make a tag for any macro, unless it is a constant
1839 * and constantypedefs is FALSE.
1841 definedef
= dignorerest
;
1842 *is_func
= (c
== '(');
1843 if (!*is_func
&& !constantypedefs
)
1850 error ("internal error: definedef value.", 0);
1859 if (toktype
== st_C_typedef
)
1862 typdef
= ttypedseen
;
1878 /* Do not return here, so the structdef stuff has a chance. */
1892 * This structdef business is currently only invoked when cblev==0.
1893 * It should be recursively invoked whatever the curly brace level,
1894 * and a stack of states kept, to allow for definitions of structs
1897 * This structdef business is NOT invoked when we are ctags and the
1898 * file is plain C. This is because a struct tag may have the same
1899 * name as another tag, and this loses with ctags.
1901 * This if statement deals with the typdef state machine as
1902 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1903 * return FALSE. All the other code here is for the structdef
1910 if (typdef
== ttypedseen
1911 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
1913 structdef
= skeyseen
;
1914 structtype
= toktype
;
1918 if (structdef
== skeyseen
)
1920 /* Save the tag for struct/union/class, for functions that may be
1922 if (structtype
== st_C_struct
)
1923 structtag
= savenstr (str
, len
);
1925 structtag
= "<enum>";
1926 structdef
= stagseen
;
1930 /* Avoid entering funcdef stuff if typdef is going on. */
1931 if (typdef
!= tnone
)
1937 /* Detect GNU macros. */
1938 if (definedef
== dnone
&& toktype
== st_C_gnumacro
)
1940 next_token_is_func
= TRUE
;
1943 if (next_token_is_func
)
1945 next_token_is_func
= FALSE
;
1952 * Detecting Objective C constructs.
1963 objdef
= oimplementation
;
1967 case oimplementation
:
1968 /* Save the class tag for functions that may be defined inside. */
1969 objtag
= savenstr (str
, len
);
1973 /* Save the class tag for categories. */
1974 objtag
= savenstr (str
, len
);
1987 objdef
= omethodtag
;
1989 GROW_LINEBUFFER (token_name
, methodlen
+1);
1990 strncpy (token_name
.buffer
, str
, len
);
1991 token_name
.buffer
[methodlen
] = '\0';
1997 objdef
= omethodparm
;
2002 objdef
= omethodtag
;
2004 GROW_LINEBUFFER (token_name
, methodlen
+1);
2005 strncat (token_name
.buffer
, str
, len
);
2010 if (toktype
== st_C_objend
)
2012 /* Memory leakage here: the string pointed by objtag is
2013 never released, because many tests would be needed to
2014 avoid breaking on incorrect input code. The amount of
2015 memory leaked here is the sum of the lengths of the
2027 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2028 funcdef
= fnone
; /* should be useless */
2031 if (funcdef
== fnone
)
2044 * This routine finds functions, typedefs, #define's and
2045 * struct/union/enum definitions in C syntax and adds them
2059 #define current_lb_is_new (newndx == curndx)
2060 #define switch_line_buffers() (curndx = 1 - curndx)
2062 #define curlb (lbs[curndx].lb)
2063 #define othlb (lbs[1-curndx].lb)
2064 #define newlb (lbs[newndx].lb)
2065 #define curlinepos (lbs[curndx].linepos)
2066 #define othlinepos (lbs[1-curndx].linepos)
2067 #define newlinepos (lbs[newndx].linepos)
2069 #define CNL_SAVE_DEFINEDEF \
2071 curlinepos = charno; \
2073 linecharno = charno; \
2074 charno += readline (&curlb, inf); \
2075 lp = curlb.buffer; \
2082 CNL_SAVE_DEFINEDEF; \
2083 if (savetok.valid) \
2086 savetok.valid = FALSE; \
2088 definedef = dnone; \
2091 /* Ideally this macro should never be called wihen tok.valid is FALSE,
2092 but this would mean that the state machines always guess right. */
2093 #define make_tag(isfun) do \
2095 char *name = NULL; \
2096 if (CTAGS || tok.named) \
2097 name = savestr (token_name.buffer); \
2098 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
2099 tok.valid = FALSE; \
2103 C_entries (c_ext
, inf
)
2104 int c_ext
; /* extension of C */
2105 FILE *inf
; /* input file */
2107 register char c
; /* latest char read; '\0' for end of line */
2108 register char *lp
; /* pointer one beyond the character `c' */
2109 int curndx
, newndx
; /* indices for current and new lb */
2110 TOKEN tok
; /* latest token read */
2111 register int tokoff
; /* offset in line of start of current token */
2112 register int toklen
; /* length of current token */
2113 int cblev
; /* current curly brace level */
2114 int parlev
; /* current parenthesis level */
2115 logical incomm
, inquote
, inchar
, quotednl
, midtoken
;
2117 TOKEN savetok
; /* token saved during preprocessor handling */
2120 curndx
= newndx
= 0;
2126 funcdef
= fnone
; typdef
= tnone
; structdef
= snone
;
2127 definedef
= dnone
; objdef
= onone
;
2128 next_token_is_func
= yacc_rules
= FALSE
;
2129 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2130 tok
.valid
= savetok
.valid
= FALSE
;
2133 cplpl
= c_ext
& C_PLPL
;
2140 /* If we're at the end of the line, the next character is a
2141 '\0'; don't skip it, because it's the thing that tells us
2142 to read the next line. */
2163 /* Newlines inside comments do not end macro definitions in
2178 /* Newlines inside strings do not end macro definitions
2179 in traditional cpp, even though compilers don't
2180 usually accept them. */
2191 /* Hmmm, something went wrong. */
2205 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2210 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2220 else if (/* cplpl && */ *lp
== '/')
2228 if ((c_ext
& YACC
) && *lp
== '%')
2230 /* entering or exiting rules section in yacc file */
2232 definedef
= dnone
; funcdef
= fnone
;
2233 typdef
= tnone
; structdef
= snone
;
2234 next_token_is_func
= FALSE
;
2235 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2237 yacc_rules
= !yacc_rules
;
2243 if (definedef
== dnone
)
2246 logical cpptoken
= TRUE
;
2248 /* Look back on this line. If all blanks, or nonblanks
2249 followed by an end of comment, this is a preprocessor
2251 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2254 if (*cp
== '*' && *(cp
+1) == '/')
2263 definedef
= dsharpseen
;
2264 } /* if (definedef == dnone) */
2270 /* Consider token only if some complicated conditions are satisfied. */
2271 if ((definedef
!= dnone
2272 || (cblev
== 0 && structdef
!= scolonseen
)
2273 || (cblev
== 1 && cplpl
&& structdef
== sinbody
))
2274 && typdef
!= tignore
2275 && definedef
!= dignorerest
2276 && funcdef
!= finlist
)
2282 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken(*(lp
+ 1)))
2285 * This handles :: in the middle, but not at the
2286 * beginning of an identifier.
2293 logical is_func
= FALSE
;
2296 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
2297 c_ext
, cblev
, parlev
, &is_func
))
2299 if (structdef
== sinbody
2300 && definedef
== dnone
2302 /* function defined in C++ class body */
2304 GROW_LINEBUFFER (token_name
,
2305 strlen(structtag
)+2+toklen
+1);
2306 strcpy (token_name
.buffer
, structtag
);
2307 strcat (token_name
.buffer
, "::");
2308 strncat (token_name
.buffer
,
2309 newlb
.buffer
+tokoff
, toklen
);
2312 else if (objdef
== ocatseen
)
2313 /* Objective C category */
2315 GROW_LINEBUFFER (token_name
,
2316 strlen(objtag
)+2+toklen
+1);
2317 strcpy (token_name
.buffer
, objtag
);
2318 strcat (token_name
.buffer
, "(");
2319 strncat (token_name
.buffer
,
2320 newlb
.buffer
+tokoff
, toklen
);
2321 strcat (token_name
.buffer
, ")");
2324 else if (objdef
== omethodtag
2325 || objdef
== omethodparm
)
2326 /* Objective C method */
2332 GROW_LINEBUFFER (token_name
, toklen
+1);
2333 strncpy (token_name
.buffer
,
2334 newlb
.buffer
+tokoff
, toklen
);
2335 token_name
.buffer
[toklen
] = '\0';
2336 if (structdef
== stagseen
2339 && definedef
== dignorerest
)) /* macro */
2344 tok
.lineno
= lineno
;
2345 tok
.linelen
= tokoff
+ toklen
+ 1;
2346 tok
.buffer
= newlb
.buffer
;
2347 tok
.linepos
= newlinepos
;
2350 if (definedef
== dnone
2351 && (funcdef
== ftagseen
2352 || structdef
== stagseen
2354 || objdef
!= onone
))
2356 if (current_lb_is_new
)
2357 switch_line_buffers ();
2364 } /* if (endtoken (c)) */
2365 else if (intoken (c
))
2370 } /* if (midtoken) */
2371 else if (begtoken (c
))
2389 if (structdef
== stagseen
)
2395 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
2397 tokoff
= lp
- 1 - newlb
.buffer
;
2402 } /* if (begtoken) */
2403 } /* if must look at token */
2406 /* Detect end of line, colon, comma, semicolon and various braces
2407 after having handled a token.*/
2411 if (definedef
!= dnone
)
2421 objdef
= omethodcolon
;
2423 GROW_LINEBUFFER (token_name
, methodlen
+1);
2424 strcat (token_name
.buffer
, ":");
2427 if (structdef
== stagseen
)
2428 structdef
= scolonseen
;
2445 if (definedef
!= dnone
)
2456 if (funcdef
!= fignore
)
2459 /* The following instruction invalidates the token.
2460 Probably the token should be invalidated in all
2461 other cases where some state machine is reset. */
2464 if (structdef
== stagseen
)
2468 if (definedef
!= dnone
)
2478 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2480 if (structdef
== stagseen
)
2484 if (definedef
!= dnone
)
2486 if (cblev
== 0 && typdef
== tend
)
2492 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2494 if (structdef
== stagseen
)
2498 if (definedef
!= dnone
)
2500 if (objdef
== otagseen
&& parlev
== 0)
2501 objdef
= oparenseen
;
2509 /* Make sure that the next char is not a '*'.
2510 This handles constructs like:
2511 typedef void OperatorFun (int fun); */
2518 } /* switch (typdef) */
2521 funcdef
= fstartlist
;
2530 if (definedef
!= dnone
)
2532 if (objdef
== ocatseen
&& parlev
== 1)
2543 funcdef
= flistseen
;
2546 if (cblev
== 0 && typdef
== tend
)
2552 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
2556 if (definedef
!= dnone
)
2558 if (typdef
== ttypedseen
)
2562 case skeyseen
: /* unnamed struct */
2563 structtag
= "_anonymous_";
2564 structdef
= sinbody
;
2567 case scolonseen
: /* named struct */
2568 structdef
= sinbody
;
2593 /* Neutralize `extern "C" {' grot and look inside structs. */
2594 if (cblev
== 0 && structdef
== snone
&& typdef
== tnone
)
2601 if (definedef
!= dnone
)
2603 if (funcdef
== fstartlist
)
2604 funcdef
= fnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2607 if (definedef
!= dnone
)
2609 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2611 cblev
= 0; /* reset curly brace level if first column */
2612 parlev
= 0; /* also reset paren level, just in case... */
2618 if (typdef
== tinbody
)
2620 /* Memory leakage here: the string pointed by structtag is
2621 never released, because I fear to miss something and
2622 break things while freeing the area. The amount of
2623 memory leaked here is the sum of the lengths of the
2625 if (structdef == sinbody)
2626 free (structtag); */
2629 structtag
= "<error>";
2634 if (objdef
== oinbody
&& cblev
== 0)
2636 objdef
= omethodsign
;
2640 case '=': case '#': case '~': case '&': case '%': case '/':
2641 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2642 if (definedef
!= dnone
)
2644 /* These surely cannot follow a function tag. */
2645 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2649 if (objdef
== otagseen
)
2654 /* If a macro spans multiple lines don't reset its state. */
2662 } /* while not eof */
2666 * Process either a C++ file or a C file depending on the setting
2670 default_C_entries (inf
)
2673 C_entries (cplusplus
? C_PLPL
: 0, inf
);
2676 /* Always do plain ANSI C. */
2678 plain_C_entries (inf
)
2684 /* Always do C++. */
2686 Cplusplus_entries (inf
)
2689 C_entries (C_PLPL
, inf
);
2697 C_entries (C_STAR
, inf
);
2700 /* Always do Yacc. */
2705 C_entries (YACC
, inf
);
2708 /* Fortran parsing */
2716 register int len
= 0;
2718 while (*cp
&& lowcase(*cp
) == lowcase(dbp
[len
]))
2720 if (*cp
== '\0' && !intoken(dbp
[len
]))
2731 while (isspace (*dbp
))
2736 while (isspace (*dbp
))
2738 if (strneq (dbp
, "(*)", 3))
2743 if (!isdigit (*dbp
))
2745 --dbp
; /* force failure */
2750 while (isdigit (*dbp
));
2759 while (isspace (*dbp
))
2764 linecharno
= charno
;
2765 charno
+= readline (&lb
, inf
);
2770 while (isspace (*dbp
))
2779 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
2782 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
2783 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2787 Fortran_functions (inf
)
2796 linecharno
= charno
;
2797 charno
+= readline (&lb
, inf
);
2800 dbp
++; /* Ratfor escape to fortran */
2801 while (isspace (*dbp
))
2805 switch (lowcase (*dbp
))
2808 if (tail ("integer"))
2816 if (tail ("logical"))
2820 if (tail ("complex") || tail ("character"))
2824 if (tail ("double"))
2826 while (isspace (*dbp
))
2830 if (tail ("precision"))
2836 while (isspace (*dbp
))
2840 switch (lowcase (*dbp
))
2843 if (tail ("function"))
2847 if (tail ("subroutine"))
2855 if (tail ("program"))
2860 if (tail ("procedure"))
2868 * Bob Weiner, Motorola Inc., 4/3/94
2869 * Unix and microcontroller assembly tag handling
2870 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
2884 linecharno
= charno
;
2885 charno
+= readline (&lb
, inf
);
2888 /* If first char is alphabetic or one of [_.$], test for colon
2889 following identifier. */
2890 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2892 /* Read past label. */
2894 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2896 if (*cp
== ':' || isspace (*cp
))
2898 /* Found end of label, so copy it and add it to the table. */
2899 pfnote ((CTAGS
) ? savenstr(lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
2900 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2907 * Perl support by Bart Robinson <lomew@cs.utah.edu>
2908 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
2911 Perl_functions (inf
)
2922 linecharno
= charno
;
2923 charno
+= readline (&lb
, inf
);
2926 if (*cp
++ == 's' && *cp
++ == 'u' && *cp
++ == 'b' && isspace(*cp
++))
2928 while (*cp
&& isspace(*cp
))
2930 while (*cp
&& ! isspace(*cp
) && *cp
!= '{')
2932 pfnote ((CTAGS
) ? savenstr (lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
2933 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2938 /* Added by Mosur Mohan, 4/22/88 */
2939 /* Pascal parsing */
2942 * Locates tags for procedures & functions. Doesn't do any type- or
2943 * var-definitions. It does look for the keyword "extern" or
2944 * "forward" immediately following the procedure statement; if found,
2945 * the tag is skipped.
2948 Pascal_functions (inf
)
2951 struct linebuffer tline
; /* mostly copied from C_entries */
2953 int save_lineno
, save_len
;
2954 char c
, *cp
, *namebuf
;
2956 logical
/* each of these flags is TRUE iff: */
2957 incomment
, /* point is inside a comment */
2958 inquote
, /* point is inside '..' string */
2959 get_tagname
, /* point is after PROCEDURE/FUNCTION
2960 keyword, so next item = potential tag */
2961 found_tag
, /* point is after a potential tag */
2962 inparms
, /* point is within parameter-list */
2963 verify_tag
; /* point has passed the parm-list, so the
2964 next token will determine whether this
2965 is a FORWARD/EXTERN to be ignored, or
2966 whether it is a real tag */
2973 initbuffer (&tline
);
2975 incomment
= inquote
= FALSE
;
2976 found_tag
= FALSE
; /* have a proc name; check if extern */
2977 get_tagname
= FALSE
; /* have found "procedure" keyword */
2978 inparms
= FALSE
; /* found '(' after "proc" */
2979 verify_tag
= FALSE
; /* check if "extern" is ahead */
2981 /* long main loop to get next char */
2985 if (c
== '\0') /* if end of line */
2988 linecharno
= charno
;
2989 charno
+= readline (&lb
, inf
);
2993 if (!((found_tag
&& verify_tag
) ||
2995 c
= *dbp
++; /* only if don't need *dbp pointing
2996 to the beginning of the name of
2997 the procedure or function */
3001 if (c
== '}') /* within { } comments */
3003 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
3020 inquote
= TRUE
; /* found first quote */
3022 case '{': /* found open { comment */
3026 if (*dbp
== '*') /* found open (* comment */
3031 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
3034 case ')': /* end of parms list */
3039 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
3046 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
3048 /* check if this is an "extern" declaration */
3051 if (lowcase (*dbp
== 'e'))
3053 if (tail ("extern")) /* superfluous, really! */
3059 else if (lowcase (*dbp
) == 'f')
3061 if (tail ("forward")) /* check for forward reference */
3067 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
3071 pfnote (namebuf
, TRUE
,
3072 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
3076 if (get_tagname
) /* grab name of proc or fn */
3081 /* save all values for later tagging */
3082 GROW_LINEBUFFER (tline
, strlen (lb
.buffer
) + 1);
3083 strcpy (tline
.buffer
, lb
.buffer
);
3084 save_lineno
= lineno
;
3085 save_lcno
= linecharno
;
3087 /* grab block name */
3088 for (cp
= dbp
+ 1; *cp
&& (!endtoken (*cp
)); cp
++)
3090 namebuf
= (CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
;
3091 dbp
= cp
; /* set dbp to e-o-token */
3092 save_len
= dbp
- lb
.buffer
+ 1;
3093 get_tagname
= FALSE
;
3097 /* and proceed to check for "extern" */
3099 else if (!incomment
&& !inquote
&& !found_tag
)
3101 /* check for proc/fn keywords */
3102 switch (lowcase (c
))
3105 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3109 if (tail ("unction"))
3114 } /* while not eof */
3116 free (tline
.buffer
);
3120 * lisp tag functions
3121 * look for (def or (DEF, quote or QUOTE
3125 register char *strp
;
3127 return ((strp
[1] == 'd' || strp
[1] == 'D')
3128 && (strp
[2] == 'e' || strp
[2] == 'E')
3129 && (strp
[3] == 'f' || strp
[3] == 'F'));
3134 register char *strp
;
3136 return ((*(++strp
) == 'q' || *strp
== 'Q')
3137 && (*(++strp
) == 'u' || *strp
== 'U')
3138 && (*(++strp
) == 'o' || *strp
== 'O')
3139 && (*(++strp
) == 't' || *strp
== 'T')
3140 && (*(++strp
) == 'e' || *strp
== 'E')
3141 && isspace(*(++strp
)));
3149 if (*dbp
== '\'') /* Skip prefix quote */
3151 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
3154 while (isspace(*dbp
))
3157 for (cp
= dbp
/*+1*/;
3158 *cp
&& *cp
!= '(' && *cp
!= ' ' && *cp
!= ')';
3164 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3165 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3169 Lisp_functions (inf
)
3178 linecharno
= charno
;
3179 charno
+= readline (&lb
, inf
);
3185 while (!isspace (*dbp
))
3187 while (isspace (*dbp
))
3193 /* Check for (foo::defmumble name-defined ... */
3196 while (*dbp
&& !isspace (*dbp
)
3197 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
3202 while (*dbp
== ':');
3204 if (L_isdef (dbp
- 1))
3206 while (!isspace (*dbp
))
3208 while (isspace (*dbp
))
3219 * Scheme tag functions
3220 * look for (def... xyzzy
3221 * look for (def... (xyzzy
3222 * look for (def ... ((...(xyzzy ....
3223 * look for (set! xyzzy
3229 Scheme_functions (inf
)
3238 linecharno
= charno
;
3239 charno
+= readline (&lb
, inf
);
3241 if (dbp
[0] == '(' &&
3242 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
3243 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3244 (dbp
[3] == 'F' || dbp
[3] == 'f'))
3246 while (!isspace (*dbp
))
3248 /* Skip over open parens and white space */
3249 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
3253 if (dbp
[0] == '(' &&
3254 (dbp
[1] == 'S' || dbp
[1] == 's') &&
3255 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3256 (dbp
[3] == 'T' || dbp
[3] == 't') &&
3257 (dbp
[4] == '!' || dbp
[4] == '!') &&
3260 while (!isspace (*dbp
))
3262 /* Skip over white space */
3263 while (isspace (*dbp
))
3277 /* Go till you get to white space or a syntactic break */
3279 *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
);
3282 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3283 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3286 /* Find tags in TeX and LaTeX input files. */
3288 /* TEX_toktab is a table of TeX control sequences that define tags.
3289 Each TEX_tabent records one such control sequence.
3290 CONVERT THIS TO USE THE Stab TYPE!! */
3297 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
3299 /* Default set of control sequences to put into TEX_toktab.
3300 The value of environment var TEXTAGS is prepended to this. */
3302 char *TEX_defenv
= "\
3303 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
3304 :part:appendix:entry:index";
3307 struct TEX_tabent
*TEX_decode_env ();
3309 #if TeX_named_tokens
3313 char TEX_esc
= '\\';
3314 char TEX_opgrp
= '{';
3315 char TEX_clgrp
= '}';
3318 * TeX/LaTeX scanning loop.
3329 /* Select either \ or ! as escape character. */
3332 /* Initialize token table once from environment. */
3334 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
3337 { /* Scan each line in file */
3339 linecharno
= charno
;
3340 charno
+= readline (&lb
, inf
);
3343 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
3349 linecharno
+= dbp
- lasthit
;
3351 i
= TEX_Token (lasthit
);
3355 lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
3356 #if TeX_named_tokens
3357 TEX_getit (lasthit
, TEX_toktab
[i
].len
);
3359 break; /* We only save a line once */
3365 #define TEX_LESC '\\'
3366 #define TEX_SESC '!'
3369 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3370 chars accordingly. */
3377 while ((c
= getc (inf
)) != EOF
)
3379 /* Skip to next line if we hit the TeX comment char. */
3383 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
3402 /* Read environment and prepend it to the default string.
3403 Build token table. */
3405 TEX_decode_env (evarname
, defenv
)
3409 register char *env
, *p
;
3411 struct TEX_tabent
*tab
;
3414 /* Append default string to environment. */
3415 env
= getenv (evarname
);
3419 env
= concat (env
, defenv
, "");
3421 /* Allocate a token table */
3422 for (size
= 1, p
= env
; p
;)
3423 if ((p
= etags_strchr (p
, ':')) && *(++p
))
3425 /* Add 1 to leave room for null terminator. */
3426 tab
= xnew (size
+ 1, struct TEX_tabent
);
3428 /* Unpack environment string into token table. Be careful about */
3429 /* zero-length strings (leading ':', "::" and trailing ':') */
3432 p
= etags_strchr (env
, ':');
3433 if (!p
) /* End of environment string. */
3434 p
= env
+ strlen (env
);
3436 { /* Only non-zero strings. */
3437 tab
[i
].name
= savenstr (env
, p
- env
);
3438 tab
[i
].len
= strlen (tab
[i
].name
);
3445 tab
[i
].name
= NULL
; /* Mark end of table. */
3453 #if TeX_named_tokens
3454 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
3455 The name being defined actually starts at (NAME + LEN + 1).
3456 But we seem to include the TeX command in the tag name. */
3458 TEX_getit (name
, len
)
3462 char *p
= name
+ len
;
3467 /* Let tag name extend to next group close (or end of line) */
3468 while (*p
&& *p
!= TEX_clgrp
)
3470 pfnote (savenstr (name
, p
-name
), TRUE
,
3471 lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
3475 /* If the text at CP matches one of the tag-defining TeX command names,
3476 return the pointer to the first occurrence of that command in TEX_toktab.
3477 Otherwise return -1.
3478 Keep the capital `T' in `Token' for dumb truncating compilers
3479 (this distinguishes it from `TEX_toktab' */
3486 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
3487 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
3493 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
3495 * Assumes that the predicate starts at column 0.
3496 * Only the first clause of a predicate is added.
3499 Prolog_functions (inf
)
3503 void prolog_skip_comment ();
3520 linecharno
+= charno
;
3521 charno
= readline (&lb
, inf
);
3523 if (dbp
[0] == '\0') /* Empty line */
3525 else if (isspace (dbp
[0])) /* Not a predicate */
3527 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
3528 prolog_skip_comment (&lb
, inf
, &lineno
, &linecharno
);
3529 else if (len
= prolog_pred (dbp
, last
))
3531 /* Predicate. Store the function name so that we only
3532 * generates a tag for the first clause. */
3534 last
= xnew(len
+ 1, char);
3535 else if (len
+ 1 > allocated
)
3536 last
= (char *) xrealloc(last
, len
+ 1);
3537 allocated
= len
+ 1;
3538 strncpy (last
, dbp
, len
);
3546 prolog_skip_comment (plb
, inf
)
3547 struct linebuffer
*plb
;
3554 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
3555 if (cp
[0] == '*' && cp
[1] == '/')
3558 linecharno
+= readline (plb
, inf
);
3564 * A predicate definition is added if it matches:
3565 * <beginning of line><Prolog Atom><whitespace>(
3567 * It is added to the tags database if it doesn't match the
3568 * name of the previous clause header.
3570 * Return the size of the name of the predicate, or 0 if no header
3574 prolog_pred (s
, last
)
3576 char *last
; /* Name of last clause. */
3584 pos
= prolog_atom(s
, 0);
3589 pos
+= prolog_white(s
, pos
);
3591 if ((s
[pos
] == '(') || (s
[pos
] == '.'))
3596 /* Save only the first clause. */
3597 if ((last
== NULL
) ||
3598 (len
!= strlen(last
)) ||
3599 (strncmp(s
, last
, len
) != 0))
3601 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
3602 s
, pos
, lineno
, linecharno
);
3610 * Consume a Prolog atom.
3611 * Return the number of bytes consumed, or -1 if there was an error.
3613 * A prolog atom, in this context, could be one of:
3614 * - An alphanumeric sequence, starting with a lower case letter.
3615 * - A quoted arbitrary string. Single quotes can escape themselves.
3616 * Backslash quotes everything.
3619 prolog_atom (s
, pos
)
3627 if (islower(s
[pos
]) || (s
[pos
] == '_'))
3629 /* The atom is unquoted. */
3631 while (isalnum(s
[pos
]) || (s
[pos
] == '_'))
3635 return pos
- origpos
;
3637 else if (s
[pos
] == '\'')
3648 pos
++; /* A double quote */
3650 else if (s
[pos
] == '\0')
3651 /* Multiline quoted atoms are ignored. */
3653 else if (s
[pos
] == '\\')
3655 if (s
[pos
+1] == '\0')
3662 return pos
- origpos
;
3668 /* Consume whitespace. Return the number of bytes eaten. */
3670 prolog_white (s
, pos
)
3678 while (isspace(s
[pos
]))
3681 return pos
- origpos
;
3685 * Support for Erlang -- Anders Lindgren, Feb 1996.
3687 * Generates tags for functions, defines, and records.
3689 * Assumes that Erlang functions start at column 0.
3692 Erlang_functions (inf
)
3696 void erlang_attribute ();
3713 linecharno
+= charno
;
3714 charno
= readline (&lb
, inf
);
3716 if (dbp
[0] == '\0') /* Empty line */
3718 else if (isspace (dbp
[0])) /* Not function nor attribute */
3720 else if (dbp
[0] == '%') /* comment */
3722 else if (dbp
[0] == '"') /* Sometimes, strings start in column one */
3724 else if (dbp
[0] == '-') /* attribute, e.g. "-define" */
3726 erlang_attribute(dbp
);
3729 else if (len
= erlang_func (dbp
, last
))
3732 * Function. Store the function name so that we only
3733 * generates a tag for the first clause.
3736 last
= xnew(len
+ 1, char);
3737 else if (len
+ 1 > allocated
)
3738 last
= (char *) xrealloc(last
, len
+ 1);
3739 allocated
= len
+ 1;
3740 strncpy (last
, dbp
, len
);
3748 * A function definition is added if it matches:
3749 * <beginning of line><Erlang Atom><whitespace>(
3751 * It is added to the tags database if it doesn't match the
3752 * name of the previous clause header.
3754 * Return the size of the name of the function, or 0 if no function
3758 erlang_func (s
, last
)
3760 char *last
; /* Name of last clause. */
3763 int erlang_white ();
3768 pos
= erlang_atom(s
, 0);
3773 pos
+= erlang_white(s
, pos
);
3775 if (s
[pos
++] == '(')
3777 /* Save only the first clause. */
3778 if ((last
== NULL
) ||
3779 (len
!= strlen(last
)) ||
3780 (strncmp(s
, last
, len
) != 0))
3782 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
3783 s
, pos
, lineno
, linecharno
);
3792 * Handle attributes. Currently, tags are generated for defines
3795 * They are on the form:
3796 * -define(foo, bar).
3797 * -define(Foo(M, N), M+N).
3798 * -record(graph, {vtab = notable, cyclic = true}).
3801 erlang_attribute (s
)
3805 int erlang_white ();
3810 if ((strncmp(s
, "-define", 7) == 0) ||
3811 (strncmp(s
, "-record", 7) == 0))
3814 pos
+= erlang_white(s
, pos
);
3816 if (s
[pos
++] == '(')
3818 pos
+= erlang_white(s
, pos
);
3820 if (len
= erlang_atom(s
, pos
))
3822 pfnote ((CTAGS
) ? savenstr (& s
[pos
], len
) : NULL
, TRUE
,
3823 s
, pos
+ len
, lineno
, linecharno
);
3832 * Consume an Erlang atom (or variable).
3833 * Return the number of bytes consumed, or -1 if there was an error.
3836 erlang_atom (s
, pos
)
3844 if (isalpha (s
[pos
]) || s
[pos
] == '_')
3846 /* The atom is unquoted. */
3848 while (isalnum (s
[pos
]) || s
[pos
] == '_')
3850 return pos
- origpos
;
3852 else if (s
[pos
] == '\'')
3863 else if (s
[pos
] == '\0')
3864 /* Multiline quoted atoms are ignored. */
3866 else if (s
[pos
] == '\\')
3868 if (s
[pos
+1] == '\0')
3875 return pos
- origpos
;
3881 /* Consume whitespace. Return the number of bytes eaten */
3883 erlang_white (s
, pos
)
3891 while (isspace (s
[pos
]))
3894 return pos
- origpos
;
3897 #ifdef ETAGS_REGEXPS
3898 /* Take a string like "/blah/" and turn it into "blah", making sure
3899 that the first and last characters are the same, and handling
3900 quoted separator characters. Actually, stops on the occurrence of
3901 an unquoted separator. Also turns "\t" into a Tab character.
3902 Returns pointer to terminating separator. Works in place. Null
3903 terminates name string. */
3905 scan_separators (name
)
3909 char *copyto
= name
;
3910 logical quoted
= FALSE
;
3912 for (++name
; *name
!= '\0'; ++name
)
3918 else if (*name
== sep
)
3922 /* Something else is quoted, so preserve the quote. */
3928 else if (*name
== '\\')
3930 else if (*name
== sep
)
3936 /* Terminate copied string. */
3941 /* Turn a name, which is an ed-style (but Emacs syntax) regular
3942 expression, into a real regular expression by compiling it. */
3944 add_regex (regexp_pattern
)
3945 char *regexp_pattern
;
3949 struct re_pattern_buffer
*patbuf
;
3951 if (regexp_pattern
== NULL
)
3953 /* Remove existing regexps. */
3959 if (regexp_pattern
[0] == '\0')
3961 error ("missing regexp", 0);
3964 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
3966 error ("%s: unterminated regexp", regexp_pattern
);
3969 name
= scan_separators (regexp_pattern
);
3970 if (regexp_pattern
[0] == '\0')
3972 error ("null regexp", 0);
3975 (void) scan_separators (name
);
3977 patbuf
= xnew (1, struct re_pattern_buffer
);
3978 patbuf
->translate
= NULL
;
3979 patbuf
->fastmap
= NULL
;
3980 patbuf
->buffer
= NULL
;
3981 patbuf
->allocated
= 0;
3983 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
3986 error ("%s while compiling pattern", err
);
3991 if (num_patterns
== 1)
3992 patterns
= xnew (1, struct pattern
);
3994 patterns
= ((struct pattern
*)
3996 (num_patterns
* sizeof (struct pattern
))));
3997 patterns
[num_patterns
- 1].pattern
= patbuf
;
3998 patterns
[num_patterns
- 1].name_pattern
= savestr (name
);
3999 patterns
[num_patterns
- 1].error_signaled
= FALSE
;
4003 * Do the substitutions indicated by the regular expression and
4007 substitute (in
, out
, regs
)
4009 struct re_registers
*regs
;
4011 char *result
= NULL
, *t
;
4014 /* Pass 1: figure out how much size to allocate. */
4015 for (t
= out
; *t
; ++t
)
4022 fprintf (stderr
, "%s: pattern substitution ends prematurely\n",
4029 size
+= regs
->end
[dig
] - regs
->start
[dig
];
4034 /* Allocate space and do the substitutions. */
4035 result
= xnew (size
+ 1, char);
4044 /* Using "dig2" satisfies my debugger. Bleah. */
4045 int dig2
= *out
- '0';
4046 strncpy (result
+ size
, in
+ regs
->start
[dig2
],
4047 regs
->end
[dig2
] - regs
->start
[dig2
]);
4048 size
+= regs
->end
[dig2
] - regs
->start
[dig2
];
4051 result
[size
++] = *out
;
4054 result
[size
++] = *out
;
4056 result
[size
] = '\0';
4061 #endif /* ETAGS_REGEXPS */
4062 /* Initialize a linebuffer for use */
4064 initbuffer (linebuffer
)
4065 struct linebuffer
*linebuffer
;
4067 linebuffer
->size
= 200;
4068 linebuffer
->buffer
= xnew (200, char);
4072 * Read a line of text from `stream' into `linebuffer'.
4073 * Return the number of characters read from `stream',
4074 * which is the length of the line including the newline, if any.
4077 readline_internal (linebuffer
, stream
)
4078 struct linebuffer
*linebuffer
;
4079 register FILE *stream
;
4081 char *buffer
= linebuffer
->buffer
;
4082 register char *p
= linebuffer
->buffer
;
4083 register char *pend
;
4086 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
4090 register int c
= getc (stream
);
4093 linebuffer
->size
*= 2;
4094 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
4095 p
+= buffer
- linebuffer
->buffer
;
4096 pend
= buffer
+ linebuffer
->size
;
4097 linebuffer
->buffer
= buffer
;
4107 if (p
> buffer
&& p
[-1] == '\r')
4111 /* Assume CRLF->LF translation will be performed by Emacs
4112 when loading this file, so CRs won't appear in the buffer.
4113 It would be cleaner to compensate within Emacs;
4114 however, Emacs does not know how many CRs were deleted
4115 before any given point in the file. */
4131 return p
- buffer
+ chars_deleted
;
4135 * Like readline_internal, above, but try to match the input
4136 * line against any existing regular expressions.
4139 readline (linebuffer
, stream
)
4140 struct linebuffer
*linebuffer
;
4143 /* Read new line. */
4144 long result
= readline_internal (linebuffer
, stream
);
4145 #ifdef ETAGS_REGEXPS
4148 /* Match against all listed patterns. */
4149 for (i
= 0; i
< num_patterns
; ++i
)
4151 int match
= re_match (patterns
[i
].pattern
, linebuffer
->buffer
,
4152 (int)result
, 0, &patterns
[i
].regs
);
4157 if (!patterns
[i
].error_signaled
)
4159 error ("error while matching pattern %d", i
);
4160 patterns
[i
].error_signaled
= TRUE
;
4167 /* Match occurred. Construct a tag. */
4168 if (patterns
[i
].name_pattern
[0] != '\0')
4170 /* Make a named tag. */
4171 char *name
= substitute (linebuffer
->buffer
,
4172 patterns
[i
].name_pattern
,
4176 linebuffer
->buffer
, match
, lineno
, linecharno
);
4180 /* Make an unnamed tag. */
4182 linebuffer
->buffer
, match
, lineno
, linecharno
);
4187 #endif /* ETAGS_REGEXPS */
4193 * Read a file, but do no processing. This is used to do regexp
4194 * matching on files that have no language defined.
4197 just_read_file (inf
)
4206 linecharno
= charno
;
4207 charno
+= readline (&lb
, inf
) + 1;
4213 * Return a pointer to a space of size strlen(cp)+1 allocated
4214 * with xnew where the string CP has been copied.
4220 return savenstr (cp
, strlen (cp
));
4224 * Return a pointer to a space of size LEN+1 allocated with xnew where
4225 * the string CP has been copied for at most the first LEN characters.
4234 dp
= xnew (len
+ 1, char);
4235 strncpy (dp
, cp
, len
);
4241 * Return the ptr in sp at which the character c last
4242 * appears; NULL if not found
4244 * Identical to System V strrchr, included for portability.
4247 etags_strrchr (sp
, c
)
4248 register char *sp
, c
;
4263 * Return the ptr in sp at which the character c first
4264 * appears; NULL if not found
4266 * Identical to System V strchr, included for portability.
4269 etags_strchr (sp
, c
)
4270 register char *sp
, c
;
4280 /* Print error message and exit. */
4298 suggest_asking_for_help ()
4300 fprintf (stderr
, "\tTry `%s --help' for a complete list of options.\n",
4305 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
4310 fprintf (stderr
, "%s: ", progname
);
4311 fprintf (stderr
, s1
, s2
);
4312 fprintf (stderr
, "\n");
4315 /* Return a newly-allocated string whose contents
4316 concatenate those of s1, s2, s3. */
4321 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
4322 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
4324 strcpy (result
, s1
);
4325 strcpy (result
+ len1
, s2
);
4326 strcpy (result
+ len1
+ len2
, s3
);
4327 result
[len1
+ len2
+ len3
] = '\0';
4332 /* Does the same work as the system V getcwd, but does not need to
4333 guess the buffer size in advance. */
4339 char *path
= xnew (bufsize
, char);
4342 while (getcwd (path
, bufsize
) == NULL
)
4344 if (errno
!= ERANGE
)
4347 path
= xnew (bufsize
, char);
4350 /* Convert backslashes to slashes. */
4352 for (p
= path
; *p
!= '\0'; p
++)
4359 #else /* not HAVE_GETCWD */
4361 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
4365 for (p
= path
; *p
!= '\0'; p
++)
4371 return strdup (path
);
4372 #else /* not MSDOS */
4373 struct linebuffer path
;
4377 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
4378 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
4383 #endif /* not MSDOS */
4384 #endif /* not HAVE_GETCWD */
4387 /* Return a newly allocated string containing the filename
4388 of FILE relative to the absolute directory DIR (which
4389 should end with a slash). */
4391 relative_filename (file
, dir
)
4394 char *fp
, *dp
, *abs
, *res
;
4396 /* Find the common root of file and dir. */
4397 abs
= absolute_filename (file
, cwd
);
4400 while (*fp
++ == *dp
++)
4409 /* Build a sequence of "../" strings for the resulting relative filename. */
4410 for (dp
= etags_strchr (dp
+ 1, '/'), res
= "";
4412 dp
= etags_strchr (dp
+ 1, '/'))
4414 res
= concat (res
, "../", "");
4417 /* Add the filename relative to the common root of file and dir. */
4418 res
= concat (res
, fp
+ 1, "");
4424 /* Return a newly allocated string containing the
4425 absolute filename of FILE given CWD (which should
4426 end with a slash). */
4428 absolute_filename (file
, cwd
)
4431 char *slashp
, *cp
, *res
;
4433 if (absolutefn (file
))
4434 res
= concat (file
, "", "");
4436 /* We don't support non-absolute filenames with a drive
4437 letter, like `d:NAME' (it's too much hassle). */
4438 else if (file
[1] == ':')
4439 fatal ("%s: relative filenames with drive letters not supported", file
);
4442 res
= concat (cwd
, file
, "");
4444 /* Delete the "/dirname/.." and "/." substrings. */
4445 slashp
= etags_strchr (res
, '/');
4446 while (slashp
!= NULL
&& slashp
[0] != '\0')
4448 if (slashp
[1] == '.')
4450 if (slashp
[2] == '.'
4451 && (slashp
[3] == '/' || slashp
[3] == '\0'))
4456 while (cp
>= res
&& !absolutefn (cp
));
4459 strcpy (cp
, slashp
+ 3);
4462 /* Under MSDOS and NT we get `d:/NAME' as absolute
4463 filename, so the luser could say `d:/../NAME'.
4464 We silently treat this as `d:/NAME'. */
4465 else if (cp
[1] == ':')
4466 strcpy (cp
+ 3, slashp
+ 4);
4468 else /* else (cp == res) */
4470 if (slashp
[3] != '\0')
4471 strcpy (cp
, slashp
+ 4);
4478 else if (slashp
[2] == '/' || slashp
[2] == '\0')
4480 strcpy (slashp
, slashp
+ 2);
4485 slashp
= etags_strchr (slashp
+ 1, '/');
4491 /* Return a newly allocated string containing the absolute
4492 filename of dir where FILE resides given CWD (which should
4493 end with a slash). */
4495 absolute_dirname (file
, cwd
)
4503 for (p
= file
; *p
!= '\0'; p
++)
4508 slashp
= etags_strrchr (file
, '/');
4513 res
= absolute_filename (file
, cwd
);
4519 /* Like malloc but get fatal error if memory is exhausted. */
4524 long *result
= (long *) malloc (size
);
4526 fatal ("virtual memory exhausted", 0);
4531 xrealloc (ptr
, size
)
4535 long *result
= (long *) realloc (ptr
, size
);
4537 fatal ("virtual memory exhausted");