1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98
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 13.7";
45 # include <sys/param.h>
47 # ifndef HAVE_CONFIG_H
49 # include <sys/config.h>
58 # define MAXPATHLEN _MAX_PATH
64 # endif /* not HAVE_CONFIG_H */
65 #endif /* WINDOWSNT */
69 /* On some systems, Emacs defines static as nothing for the sake
70 of unexec. We don't want that here since we don't use unexec. */
72 # define ETAGS_REGEXPS /* use the regexp features */
73 # define LONG_OPTIONS /* accept long options */
74 #endif /* HAVE_CONFIG_H */
76 #if !defined (WINDOWSNT) && defined (STDC_HEADERS)
85 extern char *getcwd ();
87 #endif /* HAVE_UNISTD_H */
95 #include <sys/types.h>
98 #if !defined (S_ISREG) && defined (S_IFREG)
99 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
105 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
107 extern int optind, opterr;
108 #endif /* LONG_OPTIONS */
112 #endif /* ETAGS_REGEXPS */
114 /* Define CTAGS to make the program "ctags" compatible with the usual one.
115 Leave it undefined to make the program "etags", which makes emacs-style
116 tag tables and tags typedefs, #defines and struct/union/enum by default. */
124 /* Exit codes for success and failure. */
134 #define C_PLPL 0x00001 /* C++ */
135 #define C_STAR 0x00003 /* C* */
136 #define C_JAVA 0x00005 /* JAVA */
137 #define YACC 0x10000 /* yacc file */
139 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
140 && (abort (), 1)) || !strcmp (s, t))
141 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
142 && (abort (), 1)) || !strncmp (s, t, n))
144 #define lowcase(c) tolower ((char)c)
146 #define CHARS 256 /* 2^sizeof(char) */
147 #define CHAR(x) ((unsigned int)x & (CHARS - 1))
148 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
149 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
150 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
151 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
152 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
156 * xnew, xrnew -- allocate, reallocate storage
158 * SYNOPSIS: Type *xnew (int n, Type);
159 * Type *xrnew (OldPointer, int n, Type);
162 # include "chkmalloc.h"
163 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
164 (n) * sizeof (Type)))
165 # define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \
166 (op), (n) * sizeof (Type)))
168 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
169 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type)))
174 typedef void Lang_function ();
180 char *command; /* Takes one arg and decompresses to stdout */
186 Lang_function *function;
191 extern char *getenv ();
193 /* Many compilers barf on this:
194 Lang_function Asm_labels;
195 so let's write it this way */
198 void default_C_entries ();
199 void plain_C_entries ();
200 void Cjava_entries ();
201 void Cobol_paragraphs ();
202 void Cplusplus_entries ();
203 void Cstar_entries ();
204 void Erlang_functions ();
205 void Fortran_functions ();
206 void Yacc_entries ();
207 void Lisp_functions ();
208 void Pascal_functions ();
209 void Perl_functions ();
210 void Postscript_functions ();
211 void Prolog_functions ();
212 void Python_functions ();
213 void Scheme_functions ();
214 void TeX_functions ();
215 void just_read_file ();
217 compressor *get_compressor_from_suffix ();
218 language *get_language_from_name ();
219 language *get_language_from_interpreter ();
220 language *get_language_from_suffix ();
221 int total_size_of_entries ();
222 long readline (), readline_internal ();
224 void analyse_regex ();
226 void free_patterns ();
227 #endif /* ETAGS_REGEXPS */
229 void suggest_asking_for_help ();
230 void fatal (), pfatal ();
235 void find_entries ();
237 void pfnote (), new_pfnote ();
238 void process_file ();
243 char *skip_spaces (), *skip_non_spaces ();
244 char *savenstr (), *savestr ();
245 char *etags_strchr (), *etags_strrchr ();
246 char *etags_getcwd ();
247 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
248 bool filename_is_absolute ();
249 void canonicalize_filename ();
250 void grow_linebuffer ();
251 long *xmalloc (), *xrealloc ();
254 char searchar = '/'; /* use /.../ searches */
256 char *tagfile; /* output file */
257 char *progname; /* name this program was invoked with */
258 char *cwd; /* current working directory */
259 char *tagfiledir; /* directory of tagfile */
260 FILE *tagf; /* ioptr for tags file */
262 char *curfile; /* current input file name */
263 language *curlang; /* current language */
265 int lineno; /* line number of current line */
266 long charno; /* current character number */
267 long linecharno; /* charno of start of current line */
268 char *dbp; /* pointer to start of current tag */
270 typedef struct node_st
271 { /* sorting structure */
272 char *name; /* function or type name */
273 char *file; /* file name */
274 bool is_func; /* use pattern or line no */
275 bool been_warned; /* set if noticed dup */
276 int lno; /* line number tag is on */
277 long cno; /* character number line starts on */
278 char *pat; /* search pattern */
279 struct node_st *left, *right; /* left and right sons */
282 node *head; /* the head of the binary tree of tags */
285 * A `linebuffer' is a structure which holds a line of text.
286 * `readline_internal' reads a line from a stream into a linebuffer
287 * and works regardless of the length of the line.
288 * SIZE is the size of BUFFER, LEN is the length of the string in
289 * BUFFER after readline reads it.
298 linebuffer lb; /* the current line */
299 linebuffer token_name; /* used by C_entries as a temporary area */
303 linebuffer lb; /* used by C_entries instead of lb */
306 /* boolean "functions" (see init) */
307 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
310 *white = " \f\t\n\r",
312 *nonam = " \f\t\n\r(=,[;",
313 /* token ending chars */
314 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
315 /* token starting chars */
316 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
317 /* valid in-token chars */
318 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
320 bool append_to_tagfile; /* -a: append to tags */
321 /* The following four default to TRUE for etags, but to FALSE for ctags. */
322 bool typedefs; /* -t: create tags for C typedefs */
323 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */
324 /* 0 struct/enum/union decls, and C++ */
325 /* member functions. */
326 bool constantypedefs; /* -d: create tags for C #define, enum */
327 /* constants and variables. */
328 /* -D: opposite of -d. Default under ctags. */
329 bool globals; /* create tags for global variables */
330 bool members; /* create tags for C member variables */
331 bool update; /* -u: update tags */
332 bool vgrind_style; /* -v: create vgrind style index output */
333 bool no_warnings; /* -w: suppress warnings */
334 bool cxref_style; /* -x: create cxref style output */
335 bool cplusplus; /* .[hc] means C++, not C */
336 bool noindentypedefs; /* -I: ignore indentation in C */
339 struct option longopts[] =
341 { "append", no_argument, NULL, 'a' },
342 { "backward-search", no_argument, NULL, 'B' },
343 { "c++", no_argument, NULL, 'C' },
344 { "cxref", no_argument, NULL, 'x' },
345 { "defines", no_argument, NULL, 'd' },
346 { "no-defines", no_argument, NULL, 'D' },
347 { "globals", no_argument, &globals, TRUE },
348 { "no-globals", no_argument, &globals, FALSE },
349 { "help", no_argument, NULL, 'h' },
350 { "help", no_argument, NULL, 'H' },
351 { "ignore-indentation", no_argument, NULL, 'I' },
352 { "include", required_argument, NULL, 'i' },
353 { "language", required_argument, NULL, 'l' },
354 { "members", no_argument, &members, TRUE },
355 { "no-members", no_argument, &members, FALSE },
356 { "no-warn", no_argument, NULL, 'w' },
357 { "output", required_argument, NULL, 'o' },
359 { "regex", required_argument, NULL, 'r' },
360 { "no-regex", no_argument, NULL, 'R' },
361 #endif /* ETAGS_REGEXPS */
362 { "typedefs", no_argument, NULL, 't' },
363 { "typedefs-and-c++", no_argument, NULL, 'T' },
364 { "update", no_argument, NULL, 'u' },
365 { "version", no_argument, NULL, 'V' },
366 { "vgrind", no_argument, NULL, 'v' },
369 #endif /* LONG_OPTIONS */
372 /* Structure defining a regular expression. Elements are
373 the compiled pattern, and the name string. */
374 typedef struct pattern
376 struct pattern *p_next;
379 struct re_pattern_buffer *pattern;
380 struct re_registers regs;
385 /* Array of all regexps. */
386 pattern *p_head = NULL;
387 #endif /* ETAGS_REGEXPS */
389 compressor compressors[] =
391 { "z", 1, "gzip -d -c"},
392 { "Z", 1, "gzip -d -c"},
393 { "gz", 2, "gzip -d -c"},
394 { "GZ", 2, "gzip -d -c"},
395 { "bz2", 3, "bzip2 -d -c" },
403 /* Non-NULL if language fixed. */
404 language *forced_lang = NULL;
407 char *Asm_suffixes [] = { "a", /* Unix assembler */
408 "asm", /* Microcontroller assembly */
409 "def", /* BSO/Tasking definition includes */
410 "inc", /* Microcontroller include files */
411 "ins", /* Microcontroller include files */
412 "s", "sa", /* Unix assembler */
413 "S", /* cpp-processed Unix assembler */
414 "src", /* BSO/Tasking C compiler output */
418 /* Note that .c and .h can be considered C++, if the --c++ flag was
419 given. That is why default_C_entries is called here. */
420 char *default_C_suffixes [] =
423 char *Cplusplus_suffixes [] =
424 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
425 "M", /* Objective C++ */
426 "pdb", /* Postscript with C syntax */
429 char *Cjava_suffixes [] =
432 char *Cobol_suffixes [] =
433 { "COB", "cob", NULL };
435 char *Cstar_suffixes [] =
436 { "cs", "hs", NULL };
438 char *Erlang_suffixes [] =
439 { "erl", "hrl", NULL };
441 char *Fortran_suffixes [] =
442 { "F", "f", "f90", "for", NULL };
444 char *Lisp_suffixes [] =
445 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
447 char *Pascal_suffixes [] =
448 { "p", "pas", NULL };
450 char *Perl_suffixes [] =
451 { "pl", "pm", NULL };
452 char *Perl_interpreters [] =
453 { "perl", "@PERL@", NULL };
455 char *plain_C_suffixes [] =
456 { "pc", /* Pro*C file */
457 "m", /* Objective C file */
458 "lm", /* Objective lex file */
461 char *Postscript_suffixes [] =
464 char *Prolog_suffixes [] =
467 char *Python_suffixes [] =
470 /* Can't do the `SCM' or `scm' prefix with a version number. */
471 char *Scheme_suffixes [] =
472 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "ss", "t", NULL };
474 char *TeX_suffixes [] =
475 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
477 char *Yacc_suffixes [] =
478 { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */
481 * Table of languages.
483 * It is ok for a given function to be listed under more than one
484 * name. I just didn't.
487 language lang_names [] =
489 { "asm", Asm_labels, Asm_suffixes, NULL },
490 { "c", default_C_entries, default_C_suffixes, NULL },
491 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
492 { "c*", Cstar_entries, Cstar_suffixes, NULL },
493 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL },
494 { "erlang", Erlang_functions, Erlang_suffixes, NULL },
495 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
496 { "java", Cjava_entries, Cjava_suffixes, NULL },
497 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
498 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
499 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
500 { "postscript", Postscript_functions, Postscript_suffixes, NULL },
501 { "proc", plain_C_entries, plain_C_suffixes, NULL },
502 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
503 { "python", Python_functions, Python_suffixes, NULL },
504 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
505 { "tex", TeX_functions, TeX_suffixes, NULL },
506 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
507 { "auto", NULL }, /* default guessing scheme */
508 { "none", just_read_file }, /* regexp matching only */
509 { NULL, NULL } /* end of list */
513 print_language_names ()
518 puts ("\nThese are the currently supported languages, along with the\n\
519 default file name suffixes:");
520 for (lang = lang_names; lang->name != NULL; lang++)
522 printf ("\t%s\t", lang->name);
523 if (lang->suffixes != NULL)
524 for (ext = lang->suffixes; *ext != NULL; ext++)
525 printf (" .%s", *ext);
528 puts ("Where `auto' means use default language for files based on file\n\
529 name suffix, and `none' means only do regexp processing on files.\n\
530 If no language is specified and no matching suffix is found,\n\
531 the first line of the file is read for a sharp-bang (#!) sequence\n\
532 followed by the name of an interpreter. If no such sequence is found,\n\
533 Fortran is tried first; if no tags are found, C is tried next.\n\
534 Compressed files are supported using gzip and bzip2.");
538 # define VERSION "20"
543 printf ("%s (GNU Emacs %s)\n", (CTAGS) ? "ctags" : "etags", VERSION);
544 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold");
545 puts ("This program is distributed under the same terms as Emacs");
553 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
555 These are the options accepted by %s.\n", progname, progname);
557 puts ("You may use unambiguous abbreviations for the long option names.");
559 puts ("Long option names do not work with this executable, as it is not\n\
560 linked with GNU getopt.");
561 #endif /* LONG_OPTIONS */
562 puts ("A - as file name means read names from stdin (one per line).");
564 printf (" Absolute names are stored in the output file as they are.\n\
565 Relative ones are stored relative to the output file's directory.");
568 puts ("-a, --append\n\
569 Append tag entries to existing tags file.");
572 puts ("-B, --backward-search\n\
573 Write the search commands for the tag entries using '?', the\n\
574 backward-search command instead of '/', the forward-search command.");
577 Treat files whose name suffix defaults to C language as C++ files.");
580 puts ("-d, --defines\n\
581 Create tag entries for C #define constants and enum constants, too.");
583 puts ("-D, --no-defines\n\
584 Don't create tag entries for C #define constants and enum constants.\n\
585 This makes the tags file smaller.");
589 puts ("-i FILE, --include=FILE\n\
590 Include a note in tag file indicating that, when searching for\n\
591 a tag, one should also consult the tags file FILE after\n\
592 checking the current file.");
593 puts ("-l LANG, --language=LANG\n\
594 Force the following files to be considered as written in the\n\
595 named language up to the next --language=LANG option.");
600 Create tag entries for global variables in some languages.");
602 puts ("--no-globals\n\
603 Do not create tag entries for global variables in some\n\
604 languages. This makes the tags file smaller.");
606 Create tag entries for member variables in C and derived languages.");
609 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
610 Make a tag for each line matching pattern REGEXP in the\n\
611 following files. regexfile is a file containing one REGEXP\n\
612 per line. REGEXP is anchored (as if preceded by ^).\n\
613 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
614 named tags can be created with:\n\
615 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
616 puts ("-R, --no-regex\n\
617 Don't create tags from regexps for the following files.");
618 #endif /* ETAGS_REGEXPS */
619 puts ("-o FILE, --output=FILE\n\
620 Write the tags to FILE.");
621 puts ("-I, --ignore-indentation\n\
622 Don't rely on indentation quite as much as normal. Currently,\n\
623 this means not to assume that a closing brace in the first\n\
624 column is the final brace of a function or structure\n\
625 definition in C and C++.");
629 puts ("-t, --typedefs\n\
630 Generate tag entries for C typedefs.");
631 puts ("-T, --typedefs-and-c++\n\
632 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
633 and C++ member functions.");
634 puts ("-u, --update\n\
635 Update the tag entries for the given files, leaving tag\n\
636 entries for other files in place. Currently, this is\n\
637 implemented by deleting the existing entries for the given\n\
638 files and then rewriting the new entries at the end of the\n\
639 tags file. It is often faster to simply rebuild the entire\n\
640 tag file than to use this.");
641 puts ("-v, --vgrind\n\
642 Generates an index of items intended for human consumption,\n\
643 similar to the output of vgrind. The index is sorted, and\n\
644 gives the page number of each item.");
645 puts ("-w, --no-warn\n\
646 Suppress warning messages about entries defined in multiple\n\
648 puts ("-x, --cxref\n\
649 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
650 The output uses line numbers instead of page numbers, but\n\
651 beyond that the differences are cosmetic; try both to see\n\
655 puts ("-V, --version\n\
656 Print the version of the program.\n\
658 Print this help message.");
660 print_language_names ();
663 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu");
676 /* This structure helps us allow mixing of --lang and file names. */
679 enum argument_type arg_type;
681 language *lang; /* language of the regexp */
684 #ifdef VMS /* VMS specific functions */
688 /* This is a BUG! ANY arbitrary limit is a BUG!
689 Won't someone please fix this? */
690 #define MAX_FILE_SPEC_LEN 255
693 char body[MAX_FILE_SPEC_LEN + 1];
697 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
698 returning in each successive call the next file name matching the input
699 spec. The function expects that each in_spec passed
700 to it will be processed to completion; in particular, up to and
701 including the call following that in which the last matching name
702 is returned, the function ignores the value of in_spec, and will
703 only start processing a new spec with the following call.
704 If an error occurs, on return out_spec contains the value
705 of in_spec when the error occurred.
707 With each successive file name returned in out_spec, the
708 function's return value is one. When there are no more matching
709 names the function returns zero. If on the first call no file
710 matches in_spec, or there is any other error, -1 is returned.
715 #define OUTSIZE MAX_FILE_SPEC_LEN
721 static long context = 0;
722 static struct dsc$descriptor_s o;
723 static struct dsc$descriptor_s i;
724 static bool pass1 = TRUE;
731 o.dsc$a_pointer = (char *) out;
732 o.dsc$w_length = (short)OUTSIZE;
733 i.dsc$a_pointer = in;
734 i.dsc$w_length = (short)strlen(in);
735 i.dsc$b_dtype = DSC$K_DTYPE_T;
736 i.dsc$b_class = DSC$K_CLASS_S;
737 o.dsc$b_dtype = DSC$K_DTYPE_VT;
738 o.dsc$b_class = DSC$K_CLASS_VS;
740 if ((status = lib$find_file(&i, &o, &context, 0, 0)) == RMS$_NORMAL)
742 out->body[out->curlen] = EOS;
745 else if (status == RMS$_NMF)
749 strcpy(out->body, in);
752 lib$find_file_end(&context);
758 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
759 name of each file specified by the provided arg expanding wildcards.
762 gfnames (arg, p_error)
766 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
768 switch (fn_exp (&filename, arg))
772 return filename.body;
778 return filename.body;
782 #ifndef OLD /* Newer versions of VMS do provide `system'. */
786 error ("%s", "system() function not implemented under VMS");
790 #define VERSION_DELIM ';'
791 char *massage_name (s)
797 if (*s == VERSION_DELIM)
815 unsigned int nincluded_files;
816 char **included_files;
819 int current_arg, file_count;
820 linebuffer filename_lb;
826 _fmode = O_BINARY; /* all of files are treated as binary files */
831 included_files = xnew (argc, char *);
835 /* Allocate enough no matter what happens. Overkill, but each one
837 argbuffer = xnew (argc, argument);
840 /* Set syntax for regular expression routines. */
841 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS);
842 #endif /* ETAGS_REGEXPS */
845 * If etags, always find typedefs and structure tags. Why not?
846 * Also default is to find macro constants, enum constants and
851 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
862 optstring = "-aCdDf:Il:o:r:RStTi:BuvxwVhH";
864 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH";
865 #endif /* ETAGS_REGEXPS */
868 optstring = optstring + 1;
869 #endif /* LONG_OPTIONS */
871 opt = getopt_long (argc, argv, optstring, longopts, 0);
878 /* If getopt returns 0, then it has already processed a
879 long-named option. We should do nothing. */
883 /* This means that a file name has been seen. Record it. */
884 argbuffer[current_arg].arg_type = at_filename;
885 argbuffer[current_arg].what = optarg;
890 /* Common options. */
891 case 'a': append_to_tagfile = TRUE; break;
892 case 'C': cplusplus = TRUE; break;
893 case 'd': constantypedefs = TRUE; break;
894 case 'D': constantypedefs = FALSE; break;
895 case 'f': /* for compatibility with old makefiles */
899 error ("-%c option may only be given once.", opt);
900 suggest_asking_for_help ();
905 case 'S': /* for backward compatibility */
906 noindentypedefs = TRUE;
910 language *lang = get_language_from_name (optarg);
913 argbuffer[current_arg].lang = lang;
914 argbuffer[current_arg].arg_type = at_language;
921 argbuffer[current_arg].arg_type = at_regexp;
922 argbuffer[current_arg].what = optarg;
926 argbuffer[current_arg].arg_type = at_regexp;
927 argbuffer[current_arg].what = NULL;
930 #endif /* ETAGS_REGEXPS */
942 typedefs = typedefs_and_cplusplus = TRUE;
947 included_files[nincluded_files++] = optarg;
951 case 'B': searchar = '?'; break;
952 case 'u': update = TRUE; break;
953 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
954 case 'x': cxref_style = TRUE; break;
955 case 'w': no_warnings = TRUE; break;
958 suggest_asking_for_help ();
962 for (; optind < argc; ++optind)
964 argbuffer[current_arg].arg_type = at_filename;
965 argbuffer[current_arg].what = argv[optind];
970 if (nincluded_files == 0 && file_count == 0)
972 error ("no input files specified.", 0);
973 suggest_asking_for_help ();
977 tagfile = CTAGS ? "tags" : "TAGS";
978 cwd = etags_getcwd (); /* the current working directory */
979 if (cwd[strlen (cwd) - 1] != '/')
982 cwd = concat (oldcwd, "/", "");
985 if (streq (tagfile, "-"))
988 tagfiledir = absolute_dirname (tagfile, cwd);
990 init (); /* set up boolean "functions" */
993 initbuffer (&token_name);
994 initbuffer (&lbs[0].lb);
995 initbuffer (&lbs[1].lb);
996 initbuffer (&filename_lb);
1000 if (streq (tagfile, "-"))
1004 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1005 doesn't take effect until after `stdout' is already open). */
1006 if (!isatty (fileno (stdout)))
1007 setmode (fileno (stdout), O_BINARY);
1011 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1017 * Loop through files finding functions.
1019 for (i = 0; i < current_arg; ++i)
1021 switch (argbuffer[i].arg_type)
1024 forced_lang = argbuffer[i].lang;
1026 #ifdef ETAGS_REGEXPS
1028 analyse_regex (argbuffer[i].what);
1033 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1037 error ("can't find file %s\n", this_file);
1042 this_file = massage_name (this_file);
1045 this_file = argbuffer[i].what;
1047 /* Input file named "-" means read file names from stdin
1048 (one per line) and use them. */
1049 if (streq (this_file, "-"))
1050 while (readline_internal (&filename_lb, stdin) > 0)
1051 process_file (filename_lb.buffer);
1053 process_file (this_file);
1061 #ifdef ETAGS_REGEXPS
1063 #endif /* ETAGS_REGEXPS */
1067 while (nincluded_files-- > 0)
1068 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1074 /* If CTAGS, we are here. process_file did not write the tags yet,
1075 because we want them ordered. Let's do it now. */
1087 for (i = 0; i < current_arg; ++i)
1089 if (argbuffer[i].arg_type != at_filename)
1092 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1093 tagfile, argbuffer[i].what, tagfile);
1094 if (system (cmd) != GOOD)
1095 fatal ("failed to execute shell command", (char *)NULL);
1097 append_to_tagfile = TRUE;
1100 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1111 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1112 exit (system (cmd));
1120 * Return a compressor given the file name.
1121 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca>
1124 get_compressor_from_suffix (file)
1130 suffix = etags_strrchr (file, '.');
1134 for (compr = compressors; compr->suffix != NULL; compr++)
1135 if (streq (compr->suffix, suffix))
1143 * Return a language given the name.
1146 get_language_from_name (name)
1152 error ("empty language name", (char *)NULL);
1155 for (lang = lang_names; lang->name != NULL; lang++)
1156 if (streq (name, lang->name))
1158 error ("unknown language \"%s\"", name);
1166 * Return a language given the interpreter name.
1169 get_language_from_interpreter (interpreter)
1175 if (interpreter == NULL)
1177 for (lang = lang_names; lang->name != NULL; lang++)
1178 if (lang->interpreters != NULL)
1179 for (iname = lang->interpreters; *iname != NULL; iname++)
1180 if (streq (*iname, interpreter))
1189 * Return a language given the file name.
1192 get_language_from_suffix (file)
1196 char **ext, *suffix;
1198 suffix = etags_strrchr (file, '.');
1202 for (lang = lang_names; lang->name != NULL; lang++)
1203 if (lang->suffixes != NULL)
1204 for (ext = lang->suffixes; *ext != NULL; ext++)
1205 if (streq (*ext, suffix))
1213 * This routine is called on each file argument.
1219 struct stat stat_buf;
1222 char *compressed_name, *uncompressed_name;
1225 canonicalize_filename (file);
1226 if (streq (file, tagfile) && !streq (tagfile, "-"))
1228 error ("skipping inclusion of %s in self.", file);
1231 if ((compr = get_compressor_from_suffix (file)) == NULL)
1233 compressed_name = NULL;
1234 real_name = uncompressed_name = savestr (file);
1238 real_name = compressed_name = savestr (file);
1239 uncompressed_name = savenstr (file, strlen(file) - compr->sufflen - 1);
1241 if (stat (real_name, &stat_buf) != 0)
1243 /* Reset real_name and try with a different name. */
1245 if (compressed_name != NULL) /* try with the given suffix */
1247 if (stat (uncompressed_name, &stat_buf) == 0)
1248 real_name = uncompressed_name;
1250 else /* try all possible suffixes */
1252 for (compr = compressors; compr->suffix != NULL; compr++)
1254 compressed_name = concat (file, ".", compr->suffix);
1255 if (stat (compressed_name, &stat_buf) != 0)
1256 free (compressed_name);
1259 real_name = compressed_name;
1264 if (real_name == NULL)
1269 } /* try with a different name */
1271 if (!S_ISREG (stat_buf.st_mode))
1273 error ("skipping %s: it is not a regular file.", real_name);
1276 if (real_name == compressed_name)
1278 char *cmd = concat (compr->command, " ", real_name);
1279 inf = popen (cmd, "r");
1283 inf = fopen (real_name, "r");
1290 find_entries (uncompressed_name, inf);
1292 if (real_name == compressed_name)
1301 if (filename_is_absolute (uncompressed_name))
1303 /* file is an absolute file name. Canonicalise it. */
1304 filename = absolute_filename (uncompressed_name, cwd);
1308 /* file is a file name relative to cwd. Make it relative
1309 to the directory of the tags file. */
1310 filename = relative_filename (uncompressed_name, tagfiledir);
1312 fprintf (tagf, "\f\n%s,%d\n", filename, total_size_of_entries (head));
1320 if (compressed_name) free(compressed_name);
1321 if (uncompressed_name) free(uncompressed_name);
1326 * This routine sets up the boolean pseudo-functions which work
1327 * by setting boolean flags dependent upon the corresponding character.
1328 * Every char which is NOT in that string is not a white char. Therefore,
1329 * all of the array "_wht" is set to FALSE, and then the elements
1330 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1331 * of a char is TRUE if it is the string "white", else FALSE.
1339 for (i = 0; i < CHARS; i++)
1340 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE;
1341 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
1342 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
1343 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
1344 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
1345 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
1346 iswhite('\0') = iswhite('\n');
1347 notinname('\0') = notinname('\n');
1348 begtoken('\0') = begtoken('\n');
1349 intoken('\0') = intoken('\n');
1350 endtoken('\0') = endtoken('\n');
1354 * This routine opens the specified file and calls the function
1355 * which finds the function and type definitions.
1357 node *last_node = NULL;
1360 find_entries (file, inf)
1366 node *old_last_node;
1368 /* Memory leakage here: the string pointed by curfile is
1369 never released, because curfile is copied into np->file
1370 for each node, to be used in CTAGS mode. The amount of
1371 memory leaked here is the sum of the lengths of the
1373 curfile = savestr (file);
1375 /* If user specified a language, use it. */
1377 if (lang != NULL && lang->function != NULL)
1380 lang->function (inf);
1384 /* Try to guess the language given the file name. */
1385 lang = get_language_from_suffix (file);
1386 if (lang != NULL && lang->function != NULL)
1389 lang->function (inf);
1393 /* Look for sharp-bang as the first two characters. */
1394 if (readline_internal (&lb, inf) > 0
1396 && lb.buffer[0] == '#'
1397 && lb.buffer[1] == '!')
1401 /* Set lp to point at the first char after the last slash in the
1402 line or, if no slashes, at the first nonblank. Then set cp to
1403 the first successive blank and terminate the string. */
1404 lp = etags_strrchr (lb.buffer+2, '/');
1408 lp = skip_spaces (lb.buffer + 2);
1409 cp = skip_non_spaces (lp);
1412 if (strlen (lp) > 0)
1414 lang = get_language_from_interpreter (lp);
1415 if (lang != NULL && lang->function != NULL)
1418 lang->function (inf);
1423 /* We rewind here, even if inf may be a pipe. We fail if the
1424 length of the first line is longer than the pipe block size,
1425 which is unlikely. */
1429 old_last_node = last_node;
1430 curlang = get_language_from_name ("fortran");
1431 Fortran_functions (inf);
1433 /* No Fortran entries found. Try C. */
1434 if (old_last_node == last_node)
1436 /* We do not tag if rewind fails.
1437 Only the file name will be recorded in the tags file. */
1439 curlang = get_language_from_name (cplusplus ? "c++" : "c");
1440 default_C_entries (inf);
1447 pfnote (name, is_func, linestart, linelen, lno, cno)
1448 char *name; /* tag name, or NULL if unnamed */
1449 bool is_func; /* tag is a function */
1450 char *linestart; /* start of the line where tag is */
1451 int linelen; /* length of the line where tag is */
1452 int lno; /* line number */
1453 long cno; /* character number */
1457 if (CTAGS && name == NULL)
1460 np = xnew (1, node);
1462 /* If ctags mode, change name "main" to M<thisfilename>. */
1463 if (CTAGS && !cxref_style && streq (name, "main"))
1465 register char *fp = etags_strrchr (curfile, '/');
1466 np->name = concat ("M", fp == NULL ? curfile : fp + 1, "");
1467 fp = etags_strrchr (np->name, '.');
1468 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
1473 np->been_warned = FALSE;
1475 np->is_func = is_func;
1477 /* Our char numbers are 0-base, because of C language tradition?
1478 ctags compatibility? old versions compatibility? I don't know.
1479 Anyway, since emacs's are 1-base we expect etags.el to take care
1480 of the difference. If we wanted to have 1-based numbers, we would
1481 uncomment the +1 below. */
1482 np->cno = cno /* + 1 */ ;
1483 np->left = np->right = NULL;
1484 if (CTAGS && !cxref_style)
1486 if (strlen (linestart) < 50)
1487 np->pat = concat (linestart, "$", "");
1489 np->pat = savenstr (linestart, 50);
1492 np->pat = savenstr (linestart, linelen);
1494 add_node (np, &head);
1497 /* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997]
1498 * From: Sam Kendall <kendall@mv.mv.com>
1499 * Subject: Proposal for firming up the TAGS format specification
1500 * To: F.Potorti@cnuce.cnr.it
1502 * pfnote should emit the optimized form [unnamed tag] only if:
1503 * 1. name does not contain any of the characters " \t\r\n(),;";
1504 * 2. linestart contains name as either a rightmost, or rightmost but
1505 * one character, substring;
1506 * 3. the character, if any, immediately before name in linestart must
1507 * be one of the characters " \t(),;";
1508 * 4. the character, if any, immediately after name in linestart must
1509 * also be one of the characters " \t(),;".
1511 * The real implementation uses the notinname() macro, which recognises
1512 * characters slightly different form " \t\r\n(),;". See the variable
1515 #define traditional_tag_style TRUE
1517 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno)
1518 char *name; /* tag name, or NULL if unnamed */
1519 int namelen; /* tag length */
1520 bool is_func; /* tag is a function */
1521 char *linestart; /* start of the line where tag is */
1522 int linelen; /* length of the line where tag is */
1523 int lno; /* line number */
1524 long cno; /* character number */
1532 for (cp = name; !notinname (*cp); cp++)
1534 if (*cp == '\0') /* rule #1 */
1536 cp = linestart + linelen - namelen;
1537 if (notinname (linestart[linelen-1]))
1538 cp -= 1; /* rule #4 */
1539 if (cp >= linestart /* rule #2 */
1541 || notinname (cp[-1])) /* rule #3 */
1542 && strneq (name, cp, namelen)) /* rule #2 */
1543 named = FALSE; /* use unnamed tag */
1548 name = savenstr (name, namelen);
1551 pfnote (name, is_func, linestart, linelen, lno, cno);
1556 * recurse on left children, iterate on right children.
1564 register node *node_right = np->right;
1565 free_tree (np->left);
1566 if (np->name != NULL)
1576 * Adds a node to the tree of nodes. In etags mode, we don't keep
1577 * it sorted; we just keep a linear list. In ctags mode, maintain
1578 * an ordered tree, with no attempt at balancing.
1580 * add_node is the only function allowed to add nodes, so it can
1584 add_node (np, cur_node_p)
1585 node *np, **cur_node_p;
1588 register node *cur_node = *cur_node_p;
1590 if (cur_node == NULL)
1600 if (last_node == NULL)
1601 fatal ("internal error in add_node", (char *)NULL);
1602 last_node->right = np;
1608 dif = strcmp (np->name, cur_node->name);
1611 * If this tag name matches an existing one, then
1612 * do not add the node, but maybe print a warning.
1616 if (streq (np->file, cur_node->file))
1620 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
1621 np->file, lineno, np->name);
1622 fprintf (stderr, "Second entry ignored\n");
1625 else if (!cur_node->been_warned && !no_warnings)
1629 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1630 np->file, cur_node->file, np->name);
1631 cur_node->been_warned = TRUE;
1636 /* Actually add the node */
1637 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1650 /* Output subentries that precede this one */
1651 put_entries (np->left);
1653 /* Output this entry */
1657 if (np->name != NULL)
1658 fprintf (tagf, "%s\177%s\001%d,%ld\n",
1659 np->pat, np->name, np->lno, np->cno);
1661 fprintf (tagf, "%s\177%d,%ld\n",
1662 np->pat, np->lno, np->cno);
1666 if (np->name == NULL)
1667 error ("internal error: NULL name in ctags mode.", (char *)NULL);
1672 fprintf (stdout, "%s %s %d\n",
1673 np->name, np->file, (np->lno + 63) / 64);
1675 fprintf (stdout, "%-16s %3d %-16s %s\n",
1676 np->name, np->lno, np->file, np->pat);
1680 fprintf (tagf, "%s\t%s\t", np->name, np->file);
1684 putc (searchar, tagf);
1687 for (sp = np->pat; *sp; sp++)
1689 if (*sp == '\\' || *sp == searchar)
1693 putc (searchar, tagf);
1696 { /* a typedef; text pattern inadequate */
1697 fprintf (tagf, "%d", np->lno);
1703 /* Output subentries that follow this one */
1704 put_entries (np->right);
1707 /* Length of a number's decimal representation. */
1713 while ((num /= 10) > 0)
1719 * Return total number of characters that put_entries will output for
1720 * the nodes in the subtree of the specified node. Works only if
1721 * we are not ctags, but called only in that case. This count
1722 * is irrelevant with the new tags.el, but is still supplied for
1723 * backward compatibility.
1726 total_size_of_entries (np)
1734 for (total = 0; np != NULL; np = np->right)
1736 /* Count left subentries. */
1737 total += total_size_of_entries (np->left);
1739 /* Count this entry */
1740 total += strlen (np->pat) + 1;
1741 total += number_len ((long) np->lno) + 1 + number_len (np->cno) + 1;
1742 if (np->name != NULL)
1743 total += 1 + strlen (np->name); /* \001name */
1750 * The C symbol tables.
1755 st_C_objprot, st_C_objimpl, st_C_objend,
1760 st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1763 /* Feed stuff between (but not including) %[ and %] lines to:
1764 gperf -c -k 1,3 -o -p -r -t
1766 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1768 @interface, 0, st_C_objprot
1769 @protocol, 0, st_C_objprot
1770 @implementation,0, st_C_objimpl
1771 @end, 0, st_C_objend
1772 import, C_JAVA, st_C_ignore
1773 package, C_JAVA, st_C_ignore
1774 friend, C_PLPL, st_C_ignore
1775 extends, C_JAVA, st_C_javastruct
1776 implements, C_JAVA, st_C_javastruct
1777 interface, C_JAVA, st_C_struct
1778 class, C_PLPL, st_C_struct
1779 namespace, C_PLPL, st_C_struct
1780 domain, C_STAR, st_C_struct
1781 union, 0, st_C_struct
1782 struct, 0, st_C_struct
1784 typedef, 0, st_C_typedef
1785 define, 0, st_C_define
1786 operator, C_PLPL, st_C_operator
1787 bool, C_PLPL, st_C_typespec
1788 long, 0, st_C_typespec
1789 short, 0, st_C_typespec
1790 int, 0, st_C_typespec
1791 char, 0, st_C_typespec
1792 float, 0, st_C_typespec
1793 double, 0, st_C_typespec
1794 signed, 0, st_C_typespec
1795 unsigned, 0, st_C_typespec
1796 auto, 0, st_C_typespec
1797 void, 0, st_C_typespec
1798 extern, 0, st_C_typespec
1799 static, 0, st_C_typespec
1800 const, 0, st_C_typespec
1801 volatile, 0, st_C_typespec
1802 explicit, C_PLPL, st_C_typespec
1803 mutable, C_PLPL, st_C_typespec
1804 typename, C_PLPL, st_C_typespec
1805 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1806 DEFUN, 0, st_C_gnumacro
1807 SYSCALL, 0, st_C_gnumacro
1808 ENTRY, 0, st_C_gnumacro
1809 PSEUDO, 0, st_C_gnumacro
1810 # These are defined inside C functions, so currently they are not met.
1811 # EXFUN used in glibc, DEFVAR_* in emacs.
1812 #EXFUN, 0, st_C_gnumacro
1813 #DEFVAR_, 0, st_C_gnumacro
1815 and replace lines between %< and %> with its output. */
1817 /* C code produced by gperf version 2.5 (GNU C++ version) */
1818 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1819 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1821 #define TOTAL_KEYWORDS 41
1822 #define MIN_WORD_LENGTH 3
1823 #define MAX_WORD_LENGTH 15
1824 #define MIN_HASH_VALUE 20
1825 #define MAX_HASH_VALUE 136
1826 /* maximum key range = 117, duplicates = 0 */
1831 register int unsigned len;
1833 static unsigned char asso_values[] =
1835 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1836 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1837 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1838 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1839 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1840 137, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1841 137, 137, 137, 137, 58, 137, 137, 137, 38, 37,
1842 45, 137, 137, 137, 137, 137, 137, 137, 137, 137,
1843 62, 137, 137, 14, 16, 137, 137, 137, 137, 137,
1844 137, 137, 137, 137, 137, 137, 137, 26, 16, 51,
1845 18, 61, 5, 19, 137, 23, 137, 137, 32, 63,
1846 54, 10, 26, 137, 24, 42, 30, 18, 46, 137,
1847 137, 137, 137, 137, 137, 137, 137, 137,
1849 return len + asso_values[str[2]] + asso_values[str[0]];
1852 struct C_stab_entry *
1853 in_word_set (str, len)
1855 register unsigned int len;
1857 static struct C_stab_entry wordlist[] =
1859 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1860 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1862 {"float", 0, st_C_typespec},
1863 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1864 {"define", 0, st_C_define},
1865 {"bool", C_PLPL, st_C_typespec},
1866 {"",}, {"",}, {"",},
1867 {"friend", C_PLPL, st_C_ignore},
1868 {"SYSCALL", 0, st_C_gnumacro},
1869 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1870 {"double", 0, st_C_typespec},
1871 {"",}, {"",}, {"",},
1872 {"union", 0, st_C_struct},
1873 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1874 {"import", C_JAVA, st_C_ignore},
1875 {"int", 0, st_C_typespec},
1876 {"short", 0, st_C_typespec},
1877 {"ENTRY", 0, st_C_gnumacro},
1878 {"implements", C_JAVA, st_C_javastruct},
1879 {"auto", 0, st_C_typespec},
1881 {"interface", C_JAVA, st_C_struct},
1882 {"typedef", 0, st_C_typedef},
1883 {"typename", C_PLPL, st_C_typespec},
1885 {"signed", 0, st_C_typespec},
1886 {"unsigned", 0, st_C_typespec},
1887 {"",}, {"",}, {"",},
1888 {"struct", 0, st_C_struct},
1889 {"void", 0, st_C_typespec},
1890 {"static", 0, st_C_typespec},
1891 {"",}, {"",}, {"",}, {"",},
1892 {"operator", C_PLPL, st_C_operator},
1894 {"char", 0, st_C_typespec},
1895 {"class", C_PLPL, st_C_struct},
1896 {"enum", 0, st_C_enum},
1897 {"package", C_JAVA, st_C_ignore},
1899 {"volatile", 0, st_C_typespec},
1900 {"domain", C_STAR, st_C_struct},
1901 {"DEFUN", 0, st_C_gnumacro},
1903 {"long", 0, st_C_typespec},
1904 {"@protocol", 0, st_C_objprot},
1905 {"",}, {"",}, {"",},
1906 {"explicit", C_PLPL, st_C_typespec},
1908 {"extern", 0, st_C_typespec},
1909 {"extends", C_JAVA, st_C_javastruct},
1911 {"mutable", C_PLPL, st_C_typespec},
1912 {"",}, {"",}, {"",}, {"",},
1913 {"PSEUDO", 0, st_C_gnumacro},
1914 {"",}, {"",}, {"",}, {"",},
1915 {"const", 0, st_C_typespec},
1916 {"",}, {"",}, {"",}, {"",}, {"",},
1917 {"@end", 0, st_C_objend},
1918 {"",}, {"",}, {"",}, {"",}, {"",},
1919 {"@interface", 0, st_C_objprot},
1920 {"",}, {"",}, {"",},
1921 {"namespace", C_PLPL, st_C_struct},
1922 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1923 {"@implementation", 0, st_C_objimpl},
1926 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
1928 register int key = hash (str, len);
1930 if (key <= MAX_HASH_VALUE && key >= 0)
1932 register char *s = wordlist[key].name;
1934 if (*s == *str && !strncmp (str + 1, s + 1, len - 1))
1935 return &wordlist[key];
1943 C_symtype (str, len, c_ext)
1948 register struct C_stab_entry *se = in_word_set (str, len);
1950 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
1956 * C functions and variables are recognized using a simple
1957 * finite automaton. fvdef is its state variable.
1961 fvnone, /* nothing seen */
1962 foperator, /* func: operator keyword seen (cplpl) */
1963 fvnameseen, /* function or variable name seen */
1964 fstartlist, /* func: just after open parenthesis */
1965 finlist, /* func: in parameter list */
1966 flistseen, /* func: after parameter list */
1967 fignore, /* func: before open brace */
1968 vignore /* var-like: ignore until ';' */
1973 * typedefs are recognized using a simple finite automaton.
1974 * typdef is its state variable.
1978 tnone, /* nothing seen */
1979 ttypedseen, /* typedef keyword seen */
1980 tinbody, /* inside typedef body */
1981 tend, /* just before typedef tag */
1982 tignore /* junk after typedef tag */
1987 * struct-like structures (enum, struct and union) are recognized
1988 * using another simple finite automaton. `structdef' is its state
1993 snone, /* nothing seen yet */
1994 skeyseen, /* struct-like keyword seen */
1995 stagseen, /* struct-like tag seen */
1996 scolonseen, /* colon seen after struct-like tag */
1997 sinbody /* in struct body: recognize member func defs*/
2001 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
2002 * struct tag, and structtype is the type of the preceding struct-like
2005 char *structtag = "<uninited>";
2006 enum sym_type structtype;
2009 * When objdef is different from onone, objtag is the name of the class.
2011 char *objtag = "<uninited>";
2014 * Yet another little state machine to deal with preprocessor lines.
2018 dnone, /* nothing seen */
2019 dsharpseen, /* '#' seen as first char on line */
2020 ddefineseen, /* '#' and 'define' seen */
2021 dignorerest /* ignore rest of line */
2025 * State machine for Objective C protocols and implementations.
2026 * Tom R.Hageman <tom@basil.icce.rug.nl>
2030 onone, /* nothing seen */
2031 oprotocol, /* @interface or @protocol seen */
2032 oimplementation, /* @implementations seen */
2033 otagseen, /* class name seen */
2034 oparenseen, /* parenthesis before category seen */
2035 ocatseen, /* category name seen */
2036 oinbody, /* in @implementation body */
2037 omethodsign, /* in @implementation body, after +/- */
2038 omethodtag, /* after method name */
2039 omethodcolon, /* after method colon */
2040 omethodparm, /* after method parameter */
2041 oignore /* wait for @end */
2046 * Use this structure to keep info about the token read, and how it
2047 * should be tagged. Used by the make_C_tag function to build a tag.
2060 token tok; /* latest token read */
2063 * Set this to TRUE, and the next token considered is called a function.
2064 * Used only for GNU emacs's function-defining macros.
2066 bool next_token_is_func;
2069 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
2074 * methodlen is the length of the method name stored in token_name.
2080 * checks to see if the current token is at the start of a
2081 * function or variable, or corresponds to a typedef, or
2082 * is a struct/union/enum tag, or #define, or an enum constant.
2084 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2085 * with args. C_EXT is which language we are looking at.
2093 * next_token_is_func IN OUT
2097 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var)
2098 register char *str; /* IN: token pointer */
2099 register int len; /* IN: token length */
2100 register char c; /* IN: first char after the token */
2101 int c_ext; /* IN: C extensions mask */
2102 int cblev; /* IN: curly brace level */
2103 int parlev; /* IN: parenthesis level */
2104 bool *is_func_or_var; /* OUT: function or variable found */
2106 enum sym_type toktype = C_symtype (str, len, c_ext);
2109 * Advance the definedef state machine.
2114 /* We're not on a preprocessor line. */
2117 if (toktype == st_C_define)
2119 definedef = ddefineseen;
2123 definedef = dignorerest;
2128 * Make a tag for any macro, unless it is a constant
2129 * and constantypedefs is FALSE.
2131 definedef = dignorerest;
2132 *is_func_or_var = (c == '(');
2133 if (!*is_func_or_var && !constantypedefs)
2140 error ("internal error: definedef value.", (char *)NULL);
2149 if (toktype == st_C_typedef)
2152 typdef = ttypedseen;
2168 /* Do not return here, so the structdef stuff has a chance. */
2182 * This structdef business is currently only invoked when cblev==0.
2183 * It should be recursively invoked whatever the curly brace level,
2184 * and a stack of states kept, to allow for definitions of structs
2187 * This structdef business is NOT invoked when we are ctags and the
2188 * file is plain C. This is because a struct tag may have the same
2189 * name as another tag, and this loses with ctags.
2193 case st_C_javastruct:
2194 if (structdef == stagseen)
2195 structdef = scolonseen;
2199 if (typdef == ttypedseen
2200 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone))
2202 structdef = skeyseen;
2203 structtype = toktype;
2208 if (structdef == skeyseen)
2210 /* Save the tag for struct/union/class, for functions and variables
2211 that may be defined inside. */
2212 if (structtype == st_C_struct)
2213 structtag = savenstr (str, len);
2215 structtag = "<enum>";
2216 structdef = stagseen;
2220 /* Avoid entering fvdef stuff if typdef is going on. */
2221 if (typdef != tnone)
2227 /* Detect GNU macros.
2229 DEFUN note for writers of emacs C code:
2230 The DEFUN macro, used in emacs C source code, has a first arg
2231 that is a string (the lisp function name), and a second arg that
2232 is a C function name. Since etags skips strings, the second arg
2233 is tagged. This is unfortunate, as it would be better to tag the
2234 first arg. The simplest way to deal with this problem would be
2235 to name the tag with a name built from the function name, by
2236 removing the initial 'F' character and substituting '-' for '_'.
2237 Anyway, this assumes that the conventions of naming lisp
2238 functions will never change. Currently, this method is not
2239 implemented, so writers of emacs code are recommended to put the
2240 first two args of a DEFUN on the same line. */
2241 if (definedef == dnone && toktype == st_C_gnumacro)
2243 next_token_is_func = TRUE;
2246 if (next_token_is_func)
2248 next_token_is_func = FALSE;
2250 *is_func_or_var = TRUE;
2254 /* Detect Objective C constructs. */
2264 objdef = oimplementation;
2268 case oimplementation:
2269 /* Save the class tag for functions or variables defined inside. */
2270 objtag = savenstr (str, len);
2274 /* Save the class tag for categories. */
2275 objtag = savenstr (str, len);
2277 *is_func_or_var = TRUE;
2281 *is_func_or_var = TRUE;
2288 objdef = omethodtag;
2290 grow_linebuffer (&token_name, methodlen + 1);
2291 strncpy (token_name.buffer, str, len);
2292 token_name.buffer[methodlen] = '\0';
2293 token_name.len = methodlen;
2299 objdef = omethodparm;
2304 objdef = omethodtag;
2306 grow_linebuffer (&token_name, methodlen + 1);
2307 strncat (token_name.buffer, str, len);
2308 token_name.len = methodlen;
2313 if (toktype == st_C_objend)
2315 /* Memory leakage here: the string pointed by objtag is
2316 never released, because many tests would be needed to
2317 avoid breaking on incorrect input code. The amount of
2318 memory leaked here is the sum of the lengths of the
2326 /* A function, variable or enum constant? */
2330 if (fvdef != finlist && fvdef != fignore && fvdef != vignore)
2331 fvdef = fvnone; /* should be useless */
2338 *is_func_or_var = TRUE;
2341 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2343 if (fvdef == fvnone)
2345 fvdef = fvnameseen; /* function or variable */
2346 *is_func_or_var = TRUE;
2356 * This routine finds functions, variables, typedefs,
2357 * #define's, enum constants and struct/union/enum definitions in
2358 * #C syntax and adds them to the list.
2360 #define current_lb_is_new (newndx == curndx)
2361 #define switch_line_buffers() (curndx = 1 - curndx)
2363 #define curlb (lbs[curndx].lb)
2364 #define othlb (lbs[1-curndx].lb)
2365 #define newlb (lbs[newndx].lb)
2366 #define curlinepos (lbs[curndx].linepos)
2367 #define othlinepos (lbs[1-curndx].linepos)
2368 #define newlinepos (lbs[newndx].linepos)
2370 #define CNL_SAVE_DEFINEDEF() \
2372 curlinepos = charno; \
2374 linecharno = charno; \
2375 charno += readline (&curlb, inf); \
2376 lp = curlb.buffer; \
2383 CNL_SAVE_DEFINEDEF(); \
2384 if (savetok.valid) \
2387 savetok.valid = FALSE; \
2389 definedef = dnone; \
2397 /* This function should never be called when tok.valid is FALSE, but
2398 we must protect against invalid input or internal errors. */
2401 if (traditional_tag_style)
2403 /* This was the original code. Now we call new_pfnote instead,
2404 which uses the new method for naming tags (see new_pfnote). */
2407 if (CTAGS || tok.named)
2408 name = savestr (token_name.buffer);
2409 pfnote (name, isfun,
2410 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2413 new_pfnote (token_name.buffer, token_name.len, isfun,
2414 tok.buffer, tok.linelen, tok.lineno, tok.linepos);
2423 C_entries (c_ext, inf)
2424 int c_ext; /* extension of C */
2425 FILE *inf; /* input file */
2427 register char c; /* latest char read; '\0' for end of line */
2428 register char *lp; /* pointer one beyond the character `c' */
2429 int curndx, newndx; /* indices for current and new lb */
2430 register int tokoff; /* offset in line of start of current token */
2431 register int toklen; /* length of current token */
2432 char *qualifier; /* string used to qualify names */
2433 int qlen; /* length of qualifier */
2434 int cblev; /* current curly brace level */
2435 int parlev; /* current parenthesis level */
2436 bool incomm, inquote, inchar, quotednl, midtoken;
2438 token savetok; /* token saved during preprocessor handling */
2441 tokoff = toklen = 0; /* keep compiler quiet */
2442 curndx = newndx = 0;
2448 fvdef = fvnone; typdef = tnone; structdef = snone;
2449 definedef = dnone; objdef = onone;
2450 next_token_is_func = yacc_rules = FALSE;
2451 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2452 tok.valid = savetok.valid = FALSE;
2455 cplpl = (c_ext & C_PLPL) == C_PLPL;
2456 cjava = (c_ext & C_JAVA) == C_JAVA;
2458 { qualifier = "."; qlen = 1; }
2460 { qualifier = "::"; qlen = 2; }
2467 /* If we're at the end of the line, the next character is a
2468 '\0'; don't skip it, because it's the thing that tells us
2469 to read the next line. */
2490 /* Newlines inside comments do not end macro definitions in
2492 CNL_SAVE_DEFINEDEF ();
2505 /* Newlines inside strings do not end macro definitions
2506 in traditional cpp, even though compilers don't
2507 usually accept them. */
2508 CNL_SAVE_DEFINEDEF ();
2518 /* Hmmm, something went wrong. */
2532 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2537 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
2547 else if (/* cplpl && */ *lp == '/')
2555 if ((c_ext & YACC) && *lp == '%')
2557 /* entering or exiting rules section in yacc file */
2559 definedef = dnone; fvdef = fvnone;
2560 typdef = tnone; structdef = snone;
2561 next_token_is_func = FALSE;
2562 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2564 yacc_rules = !yacc_rules;
2570 if (definedef == dnone)
2573 bool cpptoken = TRUE;
2575 /* Look back on this line. If all blanks, or nonblanks
2576 followed by an end of comment, this is a preprocessor
2578 for (cp = newlb.buffer; cp < lp-1; cp++)
2581 if (*cp == '*' && *(cp+1) == '/')
2590 definedef = dsharpseen;
2591 } /* if (definedef == dnone) */
2597 /* Consider token only if some complicated conditions are satisfied. */
2598 if ((definedef != dnone
2599 || (cblev == 0 && structdef != scolonseen)
2600 || (cblev == 1 && cplpl && structdef == sinbody)
2601 || (structdef == sinbody && structtype == st_C_enum))
2602 && typdef != tignore
2603 && definedef != dignorerest
2604 && fvdef != finlist)
2610 if (c == ':' && cplpl && *lp == ':' && begtoken(*(lp + 1)))
2613 * This handles :: in the middle, but not at the
2614 * beginning of an identifier.
2621 bool funorvar = FALSE;
2624 || consider_token (newlb.buffer + tokoff, toklen, c,
2625 c_ext, cblev, parlev, &funorvar))
2628 if (structdef == sinbody
2629 && definedef == dnone
2631 /* function or var defined in C++ class body */
2634 if (fvdef == foperator)
2637 lp = skip_spaces (lp-1);
2639 && !isspace (*lp) && *lp != '(')
2642 toklen += lp - oldlp;
2645 len = strlen (structtag) + qlen + toklen;
2646 grow_linebuffer (&token_name, len + 1);
2647 strcpy (token_name.buffer, structtag);
2648 strcat (token_name.buffer, qualifier);
2649 strncat (token_name.buffer,
2650 newlb.buffer + tokoff, toklen);
2651 token_name.len = len;
2654 else if (objdef == ocatseen)
2655 /* Objective C category */
2657 int len = strlen (objtag) + 2 + toklen;
2658 grow_linebuffer (&token_name, len + 1);
2659 strcpy (token_name.buffer, objtag);
2660 strcat (token_name.buffer, "(");
2661 strncat (token_name.buffer,
2662 newlb.buffer + tokoff, toklen);
2663 strcat (token_name.buffer, ")");
2664 token_name.len = len;
2667 else if (objdef == omethodtag
2668 || objdef == omethodparm)
2669 /* Objective C method */
2675 grow_linebuffer (&token_name, toklen + 1);
2676 strncpy (token_name.buffer,
2677 newlb.buffer + tokoff, toklen);
2678 token_name.buffer[toklen] = '\0';
2679 token_name.len = toklen;
2681 tok.named = (structdef == stagseen
2684 && definedef == dignorerest));
2686 tok.lineno = lineno;
2687 tok.linelen = tokoff + toklen + 1;
2688 tok.buffer = newlb.buffer;
2689 tok.linepos = newlinepos;
2692 if (definedef == dnone
2693 && (fvdef == fvnameseen
2694 || fvdef == foperator
2695 || structdef == stagseen
2697 || objdef != onone))
2699 if (current_lb_is_new)
2700 switch_line_buffers ();
2703 make_C_tag (funorvar);
2707 } /* if (endtoken (c)) */
2708 else if (intoken (c))
2713 } /* if (midtoken) */
2714 else if (begtoken (c))
2725 make_C_tag (TRUE); /* a function */
2732 if (structdef == stagseen && !cjava)
2738 if (!yacc_rules || lp == newlb.buffer + 1)
2740 tokoff = lp - 1 - newlb.buffer;
2745 } /* if (begtoken) */
2746 } /* if must look at token */
2749 /* Detect end of line, colon, comma, semicolon and various braces
2750 after having handled a token.*/
2754 if (definedef != dnone)
2760 make_C_tag (TRUE); /* an Objective C class */
2764 objdef = omethodcolon;
2766 grow_linebuffer (&token_name, methodlen + 1);
2767 strcat (token_name.buffer, ":");
2768 token_name.len = methodlen;
2771 if (structdef == stagseen)
2772 structdef = scolonseen;
2779 make_C_tag (FALSE); /* a yacc function */
2789 if (definedef != dnone)
2795 make_C_tag (FALSE); /* a typedef */
2805 if ((globals && cblev == 0) || (members && cblev == 1))
2806 make_C_tag (FALSE); /* a variable */
2810 /* The following instruction invalidates the token.
2811 Probably the token should be invalidated in all
2812 other cases where some state machine is reset. */
2815 if (structdef == stagseen)
2819 if (definedef != dnone)
2825 make_C_tag (TRUE); /* an Objective C method */
2837 if ((globals && cblev == 0) || (members && cblev == 1))
2838 make_C_tag (FALSE); /* a variable */
2843 if (structdef == stagseen)
2847 if (definedef != dnone)
2849 if (cblev == 0 && typdef == tend)
2852 make_C_tag (FALSE); /* a typedef */
2863 if ((globals && cblev == 0) || (members && cblev == 1))
2864 make_C_tag (FALSE); /* a variable */
2869 if (structdef == stagseen)
2873 if (definedef != dnone)
2875 if (objdef == otagseen && parlev == 0)
2876 objdef = oparenseen;
2884 if (tok.valid && *lp != '*')
2886 /* This handles constructs like:
2887 typedef void OperatorFun (int fun); */
2892 } /* switch (typdef) */
2894 case foperator: /* operator() is not handled */
2905 if (definedef != dnone)
2907 if (objdef == ocatseen && parlev == 1)
2909 make_C_tag (TRUE); /* an Objective C category */
2921 if (cblev == 0 && typdef == tend)
2924 make_C_tag (FALSE); /* a typedef */
2927 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
2931 if (definedef != dnone)
2933 if (typdef == ttypedseen)
2937 case skeyseen: /* unnamed struct */
2938 structdef = sinbody;
2939 structtag = "_anonymous_";
2942 case scolonseen: /* named struct */
2943 structdef = sinbody;
2944 make_C_tag (FALSE); /* a struct */
2950 make_C_tag (TRUE); /* a function */
2959 make_C_tag (TRUE); /* an Objective C class */
2964 make_C_tag (TRUE); /* an Objective C method */
2968 /* Neutralize `extern "C" {' grot. */
2969 if (cblev == 0 && structdef == snone && typdef == tnone)
2976 if (definedef != dnone)
2978 if (fvdef == fstartlist)
2979 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
2982 if (definedef != dnone)
2984 if (!noindentypedefs && lp == newlb.buffer + 1)
2986 cblev = 0; /* reset curly brace level if first column */
2987 parlev = 0; /* also reset paren level, just in case... */
2993 if (typdef == tinbody)
2995 /* Memory leakage here: the string pointed by structtag is
2996 never released, because I fear to miss something and
2997 break things while freeing the area. The amount of
2998 memory leaked here is the sum of the lengths of the
3000 if (structdef == sinbody)
3001 free (structtag); */
3004 structtag = "<error>";
3008 if (definedef != dnone)
3018 if ((globals && cblev == 0) || (members && cblev == 1))
3019 make_C_tag (FALSE); /* a variable */
3027 if (objdef == oinbody && cblev == 0)
3029 objdef = omethodsign;
3033 case '#': case '~': case '&': case '%': case '/': case '|':
3034 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
3035 if (definedef != dnone)
3037 /* These surely cannot follow a function tag in C. */
3050 if (objdef == otagseen)
3052 make_C_tag (TRUE); /* an Objective C class */
3055 /* If a macro spans multiple lines don't reset its state. */
3057 CNL_SAVE_DEFINEDEF ();
3063 } /* while not eof */
3067 * Process either a C++ file or a C file depending on the setting
3071 default_C_entries (inf)
3074 C_entries (cplusplus ? C_PLPL : 0, inf);
3077 /* Always do plain ANSI C. */
3079 plain_C_entries (inf)
3085 /* Always do C++. */
3087 Cplusplus_entries (inf)
3090 C_entries (C_PLPL, inf);
3093 /* Always do Java. */
3098 C_entries (C_JAVA, inf);
3106 C_entries (C_STAR, inf);
3109 /* Always do Yacc. */
3114 C_entries (YACC, inf);
3117 /* A useful macro. */
3118 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3119 for (lineno = charno = 0; /* loop initialization */ \
3120 !feof (file_pointer) /* loop test */ \
3121 && (lineno++, /* instructions at start of loop */ \
3122 linecharno = charno, \
3123 charno += readline (&line_buffer, file_pointer), \
3124 char_pointer = lb.buffer, \
3130 * Read a file, but do no processing. This is used to do regexp
3131 * matching on files that have no language defined.
3134 just_read_file (inf)
3137 register char *dummy;
3139 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3143 /* Fortran parsing */
3149 register int len = 0;
3151 while (*cp && lowcase(*cp) == lowcase(dbp[len]))
3153 if (*cp == '\0' && !intoken(dbp[len]))
3164 dbp = skip_spaces (dbp);
3168 dbp = skip_spaces (dbp);
3169 if (strneq (dbp, "(*)", 3))
3174 if (!isdigit (*dbp))
3176 --dbp; /* force failure */
3181 while (isdigit (*dbp));
3190 dbp = skip_spaces (dbp);
3194 linecharno = charno;
3195 charno += readline (&lb, inf);
3200 dbp = skip_spaces (dbp);
3206 for (cp = dbp + 1; *cp && intoken (*cp); cp++)
3208 pfnote (savenstr (dbp, cp-dbp), TRUE,
3209 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3214 Fortran_functions (inf)
3217 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3220 dbp++; /* Ratfor escape to fortran */
3221 dbp = skip_spaces (dbp);
3224 switch (lowcase (*dbp))
3227 if (tail ("integer"))
3235 if (tail ("logical"))
3239 if (tail ("complex") || tail ("character"))
3243 if (tail ("double"))
3245 dbp = skip_spaces (dbp);
3248 if (tail ("precision"))
3254 dbp = skip_spaces (dbp);
3257 switch (lowcase (*dbp))
3260 if (tail ("function"))
3264 if (tail ("subroutine"))
3272 if (tail ("program") || tail ("procedure"))
3276 if (tail ("blockdata") || tail ("block data"))
3278 dbp = skip_spaces (dbp);
3279 if (*dbp == '\0') /* assume un-named */
3280 pfnote (savestr ("blockdata"), TRUE,
3281 lb.buffer, dbp - lb.buffer, lineno, linecharno);
3283 getit (inf); /* look for name */
3291 * Bob Weiner, Motorola Inc., 4/3/94
3292 * Unix and microcontroller assembly tag handling
3293 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3301 LOOP_ON_INPUT_LINES (inf, lb, cp)
3303 /* If first char is alphabetic or one of [_.$], test for colon
3304 following identifier. */
3305 if (isalpha (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3307 /* Read past label. */
3309 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3311 if (*cp == ':' || isspace (*cp))
3313 /* Found end of label, so copy it and add it to the table. */
3314 pfnote ((CTAGS) ? savenstr(lb.buffer, cp-lb.buffer) : NULL, TRUE,
3315 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3322 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3323 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3324 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3325 * Perl variable names: /^(my|local).../
3328 Perl_functions (inf)
3333 LOOP_ON_INPUT_LINES (inf, lb, cp)
3337 && *cp++ == 'b' && isspace (*cp++))
3339 cp = skip_spaces (cp);
3344 && !isspace (*cp) && *cp != '{' && *cp != '(')
3346 pfnote (savenstr (sp, cp-sp), TRUE,
3347 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3350 else if (globals /* only if tagging global vars is enabled */
3351 && ((cp = lb.buffer,
3360 && (*cp == '(' || isspace (*cp)))
3362 /* After "my" or "local", but before any following paren or space. */
3363 char *varname = NULL;
3365 cp = skip_spaces (cp);
3366 if (*cp == '$' || *cp == '@' || *cp == '%')
3368 char* varstart = ++cp;
3369 while (isalnum (*cp) || *cp == '_')
3371 varname = savenstr (varstart, cp-varstart);
3375 /* Should be examining a variable list at this point;
3376 could insist on seeing an open parenthesis. */
3377 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
3381 /* Perhaps I should back cp up one character, so the TAGS table
3382 doesn't mention (and so depend upon) the following char. */
3383 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
3384 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3390 * Python support by Eric S. Raymond <esr@thyrsus.com>
3391 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
3394 Python_functions (inf)
3399 LOOP_ON_INPUT_LINES (inf, lb, cp)
3403 && *cp++ == 'f' && isspace (*cp++))
3405 cp = skip_spaces (cp);
3406 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3409 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3417 && *cp++ == 's' && isspace (*cp++))
3419 cp = skip_spaces (cp);
3420 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':')
3423 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3428 /* Idea by Corny de Souza
3429 * Cobol tag functions
3430 * We could look for anything that could be a paragraph name.
3431 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3434 Cobol_paragraphs (inf)
3437 register char *bp, *ep;
3439 LOOP_ON_INPUT_LINES (inf, lb, bp)
3445 /* If eoln, compiler option or comment ignore whole line. */
3446 if (bp[-1] != ' ' || !isalnum (bp[0]))
3449 for (ep = bp; isalnum (*ep) || *ep == '-'; ep++)
3452 pfnote (savenstr (bp, ep-bp), TRUE,
3453 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3457 /* Added by Mosur Mohan, 4/22/88 */
3458 /* Pascal parsing */
3461 * Locates tags for procedures & functions. Doesn't do any type- or
3462 * var-definitions. It does look for the keyword "extern" or
3463 * "forward" immediately following the procedure statement; if found,
3464 * the tag is skipped.
3467 Pascal_functions (inf)
3470 linebuffer tline; /* mostly copied from C_entries */
3472 int save_lineno, save_len;
3473 char c, *cp, *namebuf;
3475 bool /* each of these flags is TRUE iff: */
3476 incomment, /* point is inside a comment */
3477 inquote, /* point is inside '..' string */
3478 get_tagname, /* point is after PROCEDURE/FUNCTION
3479 keyword, so next item = potential tag */
3480 found_tag, /* point is after a potential tag */
3481 inparms, /* point is within parameter-list */
3482 verify_tag; /* point has passed the parm-list, so the
3483 next token will determine whether this
3484 is a FORWARD/EXTERN to be ignored, or
3485 whether it is a real tag */
3487 save_lcno = save_lineno = save_len = 0; /* keep compiler quiet */
3488 namebuf = NULL; /* keep compiler quiet */
3493 initbuffer (&tline);
3495 incomment = inquote = FALSE;
3496 found_tag = FALSE; /* have a proc name; check if extern */
3497 get_tagname = FALSE; /* have found "procedure" keyword */
3498 inparms = FALSE; /* found '(' after "proc" */
3499 verify_tag = FALSE; /* check if "extern" is ahead */
3502 while (!feof (inf)) /* long main loop to get next char */
3505 if (c == '\0') /* if end of line */
3508 linecharno = charno;
3509 charno += readline (&lb, inf);
3513 if (!((found_tag && verify_tag)
3515 c = *dbp++; /* only if don't need *dbp pointing
3516 to the beginning of the name of
3517 the procedure or function */
3521 if (c == '}') /* within { } comments */
3523 else if (c == '*' && *dbp == ')') /* within (* *) comments */
3540 inquote = TRUE; /* found first quote */
3542 case '{': /* found open { comment */
3546 if (*dbp == '*') /* found open (* comment */
3551 else if (found_tag) /* found '(' after tag, i.e., parm-list */
3554 case ')': /* end of parms list */
3559 if (found_tag && !inparms) /* end of proc or fn stmt */
3566 if (found_tag && verify_tag && (*dbp != ' '))
3568 /* check if this is an "extern" declaration */
3571 if (lowcase (*dbp == 'e'))
3573 if (tail ("extern")) /* superfluous, really! */
3579 else if (lowcase (*dbp) == 'f')
3581 if (tail ("forward")) /* check for forward reference */
3587 if (found_tag && verify_tag) /* not external proc, so make tag */
3591 pfnote (namebuf, TRUE,
3592 tline.buffer, save_len, save_lineno, save_lcno);
3596 if (get_tagname) /* grab name of proc or fn */
3601 /* save all values for later tagging */
3602 grow_linebuffer (&tline, lb.len + 1);
3603 strcpy (tline.buffer, lb.buffer);
3604 save_lineno = lineno;
3605 save_lcno = linecharno;
3607 /* grab block name */
3608 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
3610 namebuf = savenstr (dbp, cp-dbp);
3611 dbp = cp; /* set dbp to e-o-token */
3612 save_len = dbp - lb.buffer + 1;
3613 get_tagname = FALSE;
3617 /* and proceed to check for "extern" */
3619 else if (!incomment && !inquote && !found_tag)
3621 /* check for proc/fn keywords */
3622 switch (lowcase (c))
3625 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3629 if (tail ("unction"))
3634 } /* while not eof */
3636 free (tline.buffer);
3640 * lisp tag functions
3641 * look for (def or (DEF, quote or QUOTE
3645 register char *strp;
3647 return ((strp[1] == 'd' || strp[1] == 'D')
3648 && (strp[2] == 'e' || strp[2] == 'E')
3649 && (strp[3] == 'f' || strp[3] == 'F'));
3654 register char *strp;
3656 return ((*++strp == 'q' || *strp == 'Q')
3657 && (*++strp == 'u' || *strp == 'U')
3658 && (*++strp == 'o' || *strp == 'O')
3659 && (*++strp == 't' || *strp == 'T')
3660 && (*++strp == 'e' || *strp == 'E')
3661 && isspace (*++strp));
3669 if (*dbp == '\'') /* Skip prefix quote */
3671 else if (*dbp == '(')
3673 if (L_isquote (dbp))
3674 dbp += 7; /* Skip "(quote " */
3676 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */
3677 dbp = skip_spaces (dbp);
3680 for (cp = dbp /*+1*/;
3681 *cp != '\0' && *cp != '(' && *cp != ' ' && *cp != ')';
3687 pfnote (savenstr (dbp, cp-dbp), TRUE,
3688 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3692 Lisp_functions (inf)
3695 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3701 dbp = skip_non_spaces (dbp);
3702 dbp = skip_spaces (dbp);
3707 /* Check for (foo::defmumble name-defined ... */
3710 while (*dbp != '\0' && !isspace (*dbp)
3711 && *dbp != ':' && *dbp != '(' && *dbp != ')');
3716 while (*dbp == ':');
3718 if (L_isdef (dbp - 1))
3720 dbp = skip_non_spaces (dbp);
3721 dbp = skip_spaces (dbp);
3731 * Postscript tag functions
3732 * Just look for lines where the first character is '/'
3733 * Richard Mlynarik <mly@adoc.xerox.com>
3736 Postscript_functions (inf)
3739 register char *bp, *ep;
3741 LOOP_ON_INPUT_LINES (inf, lb, bp)
3746 *ep != '\0' && *ep != ' ' && *ep != '{';
3749 pfnote ((CTAGS) ? savenstr (bp, ep-bp) : NULL, TRUE,
3750 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3757 * Scheme tag functions
3758 * look for (def... xyzzy
3759 * look for (def... (xyzzy
3760 * look for (def ... ((...(xyzzy ....
3761 * look for (set! xyzzy
3767 Scheme_functions (inf)
3770 LOOP_ON_INPUT_LINES (inf, lb, dbp)
3773 && (dbp[1] == 'D' || dbp[1] == 'd')
3774 && (dbp[2] == 'E' || dbp[2] == 'e')
3775 && (dbp[3] == 'F' || dbp[3] == 'f'))
3777 dbp = skip_non_spaces (dbp);
3778 /* Skip over open parens and white space */
3779 while (isspace (*dbp) || *dbp == '(')
3784 && (dbp[1] == 'S' || dbp[1] == 's')
3785 && (dbp[2] == 'E' || dbp[2] == 'e')
3786 && (dbp[3] == 'T' || dbp[3] == 't')
3787 && (dbp[4] == '!' || dbp[4] == '!')
3788 && (isspace (dbp[5])))
3790 dbp = skip_non_spaces (dbp);
3791 dbp = skip_spaces (dbp);
3804 /* Go till you get to white space or a syntactic break */
3806 *cp != '\0' && *cp != '(' && *cp != ')' && !isspace (*cp);
3809 pfnote (savenstr (dbp, cp-dbp), TRUE,
3810 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3813 /* Find tags in TeX and LaTeX input files. */
3815 /* TEX_toktab is a table of TeX control sequences that define tags.
3816 Each TEX_tabent records one such control sequence.
3817 CONVERT THIS TO USE THE Stab TYPE!! */
3824 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
3826 /* Default set of control sequences to put into TEX_toktab.
3827 The value of environment var TEXTAGS is prepended to this. */
3829 char *TEX_defenv = "\
3830 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
3831 :part:appendix:entry:index";
3834 struct TEX_tabent *TEX_decode_env ();
3837 char TEX_esc = '\\';
3838 char TEX_opgrp = '{';
3839 char TEX_clgrp = '}';
3842 * TeX/LaTeX scanning loop.
3851 /* Select either \ or ! as escape character. */
3854 /* Initialize token table once from environment. */
3856 TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
3858 LOOP_ON_INPUT_LINES (inf, lb, cp)
3861 /* Look at each esc in line. */
3862 while ((cp = etags_strchr (cp, TEX_esc)) != NULL)
3866 linecharno += cp - lasthit;
3868 i = TEX_Token (lasthit);
3871 /* We seem to include the TeX command in the tag name.
3873 for (p = lasthit + TEX_toktab[i].len;
3874 *p != '\0' && *p != TEX_clgrp;
3877 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL, TRUE,
3878 lb.buffer, lb.len, lineno, linecharno);
3879 break; /* We only tag a line once */
3885 #define TEX_LESC '\\'
3886 #define TEX_SESC '!'
3889 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3890 chars accordingly. */
3897 while ((c = getc (inf)) != EOF)
3899 /* Skip to next line if we hit the TeX comment char. */
3903 else if (c == TEX_LESC || c == TEX_SESC )
3919 /* If the input file is compressed, inf is a pipe, and rewind may fail.
3920 No attempt is made to correct the situation. */
3924 /* Read environment and prepend it to the default string.
3925 Build token table. */
3927 TEX_decode_env (evarname, defenv)
3931 register char *env, *p;
3933 struct TEX_tabent *tab;
3936 /* Append default string to environment. */
3937 env = getenv (evarname);
3943 env = concat (oldenv, defenv, "");
3946 /* Allocate a token table */
3947 for (size = 1, p = env; p;)
3948 if ((p = etags_strchr (p, ':')) && *++p != '\0')
3950 /* Add 1 to leave room for null terminator. */
3951 tab = xnew (size + 1, struct TEX_tabent);
3953 /* Unpack environment string into token table. Be careful about */
3954 /* zero-length strings (leading ':', "::" and trailing ':') */
3957 p = etags_strchr (env, ':');
3958 if (!p) /* End of environment string. */
3959 p = env + strlen (env);
3961 { /* Only non-zero strings. */
3962 tab[i].name = savenstr (env, p - env);
3963 tab[i].len = strlen (tab[i].name);
3970 tab[i].name = NULL; /* Mark end of table. */
3978 /* If the text at CP matches one of the tag-defining TeX command names,
3979 return the pointer to the first occurrence of that command in TEX_toktab.
3980 Otherwise return -1.
3981 Keep the capital `T' in `token' for dumb truncating compilers
3982 (this distinguishes it from `TEX_toktab' */
3989 for (i = 0; TEX_toktab[i].len > 0; i++)
3990 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
3996 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
3998 * Assumes that the predicate starts at column 0.
3999 * Only the first clause of a predicate is added.
4002 void prolog_skip_comment ();
4006 Prolog_functions (inf)
4017 LOOP_ON_INPUT_LINES (inf, lb, cp)
4019 if (cp[0] == '\0') /* Empty line */
4021 else if (isspace (cp[0])) /* Not a predicate */
4023 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
4024 prolog_skip_comment (&lb, inf);
4025 else if ((len = prolog_pred (cp, last)) > 0)
4027 /* Predicate. Store the function name so that we only
4028 generate a tag for the first clause. */
4030 last = xnew(len + 1, char);
4031 else if (len + 1 > allocated)
4032 last = xrnew (last, len + 1, char);
4033 allocated = len + 1;
4034 strncpy (last, cp, len);
4042 prolog_skip_comment (plb, inf)
4050 for (cp = plb->buffer; *cp != '\0'; cp++)
4051 if (cp[0] == '*' && cp[1] == '/')
4054 linecharno += readline (plb, inf);
4060 * A predicate definition is added if it matches:
4061 * <beginning of line><Prolog Atom><whitespace>(
4063 * It is added to the tags database if it doesn't match the
4064 * name of the previous clause header.
4066 * Return the size of the name of the predicate, or 0 if no header
4070 prolog_pred (s, last)
4072 char *last; /* Name of last clause. */
4077 pos = prolog_atom (s, 0);
4082 pos = skip_spaces (s + pos) - s;
4084 if ((s[pos] == '(') || (s[pos] == '.'))
4089 /* Save only the first clause. */
4091 || len != (int)strlen (last)
4092 || !strneq (s, last, len))
4094 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE,
4095 s, pos, lineno, linecharno);
4103 * Consume a Prolog atom.
4104 * Return the number of bytes consumed, or -1 if there was an error.
4106 * A prolog atom, in this context, could be one of:
4107 * - An alphanumeric sequence, starting with a lower case letter.
4108 * - A quoted arbitrary string. Single quotes can escape themselves.
4109 * Backslash quotes everything.
4112 prolog_atom (s, pos)
4120 if (islower(s[pos]) || (s[pos] == '_'))
4122 /* The atom is unquoted. */
4124 while (isalnum(s[pos]) || (s[pos] == '_'))
4128 return pos - origpos;
4130 else if (s[pos] == '\'')
4141 pos++; /* A double quote */
4143 else if (s[pos] == '\0')
4144 /* Multiline quoted atoms are ignored. */
4146 else if (s[pos] == '\\')
4148 if (s[pos+1] == '\0')
4155 return pos - origpos;
4162 * Support for Erlang -- Anders Lindgren, Feb 1996.
4164 * Generates tags for functions, defines, and records.
4166 * Assumes that Erlang functions start at column 0.
4169 void erlang_attribute ();
4173 Erlang_functions (inf)
4184 LOOP_ON_INPUT_LINES (inf, lb, cp)
4186 if (cp[0] == '\0') /* Empty line */
4188 else if (isspace (cp[0])) /* Not function nor attribute */
4190 else if (cp[0] == '%') /* comment */
4192 else if (cp[0] == '"') /* Sometimes, strings start in column one */
4194 else if (cp[0] == '-') /* attribute, e.g. "-define" */
4196 erlang_attribute (cp);
4199 else if ((len = erlang_func (cp, last)) > 0)
4202 * Function. Store the function name so that we only
4203 * generates a tag for the first clause.
4206 last = xnew (len + 1, char);
4207 else if (len + 1 > allocated)
4208 last = xrnew (last, len + 1, char);
4209 allocated = len + 1;
4210 strncpy (last, cp, len);
4218 * A function definition is added if it matches:
4219 * <beginning of line><Erlang Atom><whitespace>(
4221 * It is added to the tags database if it doesn't match the
4222 * name of the previous clause header.
4224 * Return the size of the name of the function, or 0 if no function
4228 erlang_func (s, last)
4230 char *last; /* Name of last clause. */
4235 pos = erlang_atom (s, 0);
4240 pos = skip_spaces (s + pos) - s;
4242 /* Save only the first clause. */
4245 || len != (int)strlen (last)
4246 || !strneq (s, last, len)))
4248 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE,
4249 s, pos, lineno, linecharno);
4258 * Handle attributes. Currently, tags are generated for defines
4261 * They are on the form:
4262 * -define(foo, bar).
4263 * -define(Foo(M, N), M+N).
4264 * -record(graph, {vtab = notable, cyclic = true}).
4267 erlang_attribute (s)
4273 if (strneq (s, "-define", 7) || strneq (s, "-record", 7))
4275 pos = skip_spaces (s + 7) - s;
4276 if (s[pos++] == '(')
4278 pos = skip_spaces (s + pos) - s;
4279 len = erlang_atom (s, pos);
4281 pfnote ((CTAGS) ? savenstr (& s[pos], len) : NULL, TRUE,
4282 s, pos + len, lineno, linecharno);
4290 * Consume an Erlang atom (or variable).
4291 * Return the number of bytes consumed, or -1 if there was an error.
4294 erlang_atom (s, pos)
4302 if (isalpha (s[pos]) || s[pos] == '_')
4304 /* The atom is unquoted. */
4306 while (isalnum (s[pos]) || s[pos] == '_')
4308 return pos - origpos;
4310 else if (s[pos] == '\'')
4321 else if (s[pos] == '\0')
4322 /* Multiline quoted atoms are ignored. */
4324 else if (s[pos] == '\\')
4326 if (s[pos+1] == '\0')
4333 return pos - origpos;
4339 #ifdef ETAGS_REGEXPS
4341 /* Take a string like "/blah/" and turn it into "blah", making sure
4342 that the first and last characters are the same, and handling
4343 quoted separator characters. Actually, stops on the occurrence of
4344 an unquoted separator. Also turns "\t" into a Tab character.
4345 Returns pointer to terminating separator. Works in place. Null
4346 terminates name string. */
4348 scan_separators (name)
4352 char *copyto = name;
4353 bool quoted = FALSE;
4355 for (++name; *name != '\0'; ++name)
4361 else if (*name == sep)
4365 /* Something else is quoted, so preserve the quote. */
4371 else if (*name == '\\')
4373 else if (*name == sep)
4379 /* Terminate copied string. */
4384 /* Look at the argument of --regex or --no-regex and do the right
4385 thing. Same for each line of a regexp file. */
4387 analyse_regex (regex_arg)
4390 if (regex_arg == NULL)
4391 free_patterns (); /* --no-regex: remove existing regexps */
4393 /* A real --regexp option or a line in a regexp file. */
4394 switch (regex_arg[0])
4396 /* Comments in regexp file or null arg to --regex. */
4402 /* Read a regex file. This is recursive and may result in a
4403 loop, which will stop when the file descriptors are exhausted. */
4407 linebuffer regexbuf;
4408 char *regexfile = regex_arg + 1;
4410 /* regexfile is a file containing regexps, one per line. */
4411 regexfp = fopen (regexfile, "r");
4412 if (regexfp == NULL)
4417 initbuffer (®exbuf);
4418 while (readline_internal (®exbuf, regexfp) > 0)
4419 analyse_regex (regexbuf.buffer);
4420 free (regexbuf.buffer);
4425 /* Regexp to be used for a specific language only. */
4429 char *lang_name = regex_arg + 1;
4432 for (cp = lang_name; *cp != '}'; cp++)
4435 error ("unterminated language name in regex: %s", regex_arg);
4439 lang = get_language_from_name (lang_name);
4442 add_regex (cp + 1, lang);
4446 /* Regexp to be used for any language. */
4448 add_regex (regex_arg, NULL);
4453 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4454 expression, into a real regular expression by compiling it. */
4456 add_regex (regexp_pattern, lang)
4457 char *regexp_pattern;
4462 struct re_pattern_buffer *patbuf;
4466 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0])
4468 error ("%s: unterminated regexp", regexp_pattern);
4471 name = scan_separators (regexp_pattern);
4472 if (regexp_pattern[0] == '\0')
4474 error ("null regexp", (char *)NULL);
4477 (void) scan_separators (name);
4479 patbuf = xnew (1, struct re_pattern_buffer);
4480 patbuf->translate = NULL;
4481 patbuf->fastmap = NULL;
4482 patbuf->buffer = NULL;
4483 patbuf->allocated = 0;
4485 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4488 error ("%s while compiling pattern", err);
4493 p_head = xnew (1, pattern);
4494 p_head->regex = savestr (regexp_pattern);
4495 p_head->p_next = pp;
4496 p_head->language = lang;
4497 p_head->pattern = patbuf;
4498 p_head->name_pattern = savestr (name);
4499 p_head->error_signaled = FALSE;
4503 * Do the substitutions indicated by the regular expression and
4507 substitute (in, out, regs)
4509 struct re_registers *regs;
4512 int size, dig, diglen;
4515 size = strlen (out);
4517 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4518 if (out[size - 1] == '\\')
4519 fatal ("pattern error in \"%s\"", out);
4520 for (t = etags_strchr (out, '\\');
4522 t = etags_strchr (t + 2, '\\'))
4526 diglen = regs->end[dig] - regs->start[dig];
4532 /* Allocate space and do the substitutions. */
4533 result = xnew (size + 1, char);
4535 for (t = result; *out != '\0'; out++)
4536 if (*out == '\\' && isdigit (*++out))
4538 /* Using "dig2" satisfies my debugger. Bleah. */
4540 diglen = regs->end[dig] - regs->start[dig];
4541 strncpy (t, in + regs->start[dig], diglen);
4548 if (DEBUG && (t > result + size || t - result != (int)strlen (result)))
4554 /* Deallocate all patterns. */
4559 while (p_head != NULL)
4561 pp = p_head->p_next;
4562 free (p_head->regex);
4563 free (p_head->name_pattern);
4570 #endif /* ETAGS_REGEXPS */
4571 /* Initialize a linebuffer for use */
4577 lbp->buffer = xnew (200, char);
4581 * Read a line of text from `stream' into `lbp', excluding the
4582 * newline or CR-NL, if any. Return the number of characters read from
4583 * `stream', which is the length of the line including the newline.
4585 * On DOS or Windows we do not count the CR character, if any, before the
4586 * NL, in the returned length; this mirrors the behavior of emacs on those
4587 * platforms (for text files, it translates CR-NL to NL as it reads in the
4591 readline_internal (lbp, stream)
4593 register FILE *stream;
4595 char *buffer = lbp->buffer;
4596 register char *p = lbp->buffer;
4597 register char *pend;
4600 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
4604 register int c = getc (stream);
4607 /* We're at the end of linebuffer: expand it. */
4609 buffer = xrnew (buffer, lbp->size, char);
4610 p += buffer - lbp->buffer;
4611 pend = buffer + lbp->size;
4612 lbp->buffer = buffer;
4622 if (p > buffer && p[-1] == '\r')
4626 /* Assume CRLF->LF translation will be performed by Emacs
4627 when loading this file, so CRs won't appear in the buffer.
4628 It would be cleaner to compensate within Emacs;
4629 however, Emacs does not know how many CRs were deleted
4630 before any given point in the file. */
4645 lbp->len = p - buffer;
4647 return lbp->len + chars_deleted;
4651 * Like readline_internal, above, but in addition try to match the
4652 * input line against relevant regular expressions.
4655 readline (lbp, stream)
4659 /* Read new line. */
4660 long result = readline_internal (lbp, stream);
4661 #ifdef ETAGS_REGEXPS
4665 /* Match against relevant patterns. */
4667 for (pp = p_head; pp != NULL; pp = pp->p_next)
4669 /* Only use generic regexps or those for the current language. */
4670 if (pp->language != NULL && pp->language != curlang)
4673 match = re_match (pp->pattern, lbp->buffer, lbp->len, 0, &pp->regs);
4678 if (!pp->error_signaled)
4680 error ("error while matching \"%s\"", pp->regex);
4681 pp->error_signaled = TRUE;
4688 /* Match occurred. Construct a tag. */
4689 if (pp->name_pattern[0] != '\0')
4691 /* Make a named tag. */
4692 char *name = substitute (lbp->buffer,
4693 pp->name_pattern, &pp->regs);
4695 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
4699 /* Make an unnamed tag. */
4700 pfnote ((char *)NULL, TRUE,
4701 lbp->buffer, match, lineno, linecharno);
4706 #endif /* ETAGS_REGEXPS */
4712 * Return a pointer to a space of size strlen(cp)+1 allocated
4713 * with xnew where the string CP has been copied.
4719 return savenstr (cp, strlen (cp));
4723 * Return a pointer to a space of size LEN+1 allocated with xnew where
4724 * the string CP has been copied for at most the first LEN characters.
4733 dp = xnew (len + 1, char);
4734 strncpy (dp, cp, len);
4740 * Return the ptr in sp at which the character c last
4741 * appears; NULL if not found
4743 * Identical to System V strrchr, included for portability.
4746 etags_strrchr (sp, c)
4747 register char *sp, c;
4762 * Return the ptr in sp at which the character c first
4763 * appears; NULL if not found
4765 * Identical to System V strchr, included for portability.
4768 etags_strchr (sp, c)
4769 register char *sp, c;
4779 /* Skip spaces, return new pointer. */
4784 while (isspace (*cp)) /* isspace('\0')==FALSE */
4789 /* Skip non spaces, return new pointer. */
4791 skip_non_spaces (cp)
4794 while (!iswhite (*cp)) /* iswhite('\0')==TRUE */
4799 /* Print error message and exit. */
4817 suggest_asking_for_help ()
4819 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
4830 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
4835 fprintf (stderr, "%s: ", progname);
4836 fprintf (stderr, s1, s2);
4837 fprintf (stderr, "\n");
4840 /* Return a newly-allocated string whose contents
4841 concatenate those of s1, s2, s3. */
4846 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
4847 char *result = xnew (len1 + len2 + len3 + 1, char);
4849 strcpy (result, s1);
4850 strcpy (result + len1, s2);
4851 strcpy (result + len1 + len2, s3);
4852 result[len1 + len2 + len3] = '\0';
4857 /* Does the same work as the system V getcwd, but does not need to
4858 guess the buffer size in advance. */
4864 char *path = xnew (bufsize, char);
4866 while (getcwd (path, bufsize) == NULL)
4868 if (errno != ERANGE)
4872 path = xnew (bufsize, char);
4875 canonicalize_filename (path);
4878 #else /* not HAVE_GETCWD */
4880 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
4884 for (p = path; *p != '\0'; p++)
4890 return strdup (path);
4891 #else /* not MSDOS */
4896 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
4897 if (pipe == NULL || readline_internal (&path, pipe) == 0)
4902 #endif /* not MSDOS */
4903 #endif /* not HAVE_GETCWD */
4906 /* Return a newly allocated string containing the file name of FILE
4907 relative to the absolute directory DIR (which should end with a slash). */
4909 relative_filename (file, dir)
4912 char *fp, *dp, *afn, *res;
4915 /* Find the common root of file and dir (with a trailing slash). */
4916 afn = absolute_filename (file, cwd);
4919 while (*fp++ == *dp++)
4921 fp--, dp--; /* back to the first differing char */
4922 do /* look at the equal chars until '/' */
4926 /* Build a sequence of "../" strings for the resulting relative file name. */
4928 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
4930 res = xnew (3*i + strlen (fp + 1) + 1, char);
4933 strcat (res, "../");
4935 /* Add the file name relative to the common root of file and dir. */
4936 strcat (res, fp + 1);
4942 /* Return a newly allocated string containing the absolute file name
4943 of FILE given DIR (which should end with a slash). */
4945 absolute_filename (file, dir)
4948 char *slashp, *cp, *res;
4950 if (filename_is_absolute (file))
4951 res = savestr (file);
4953 /* We don't support non-absolute file names with a drive
4954 letter, like `d:NAME' (it's too much hassle). */
4955 else if (file[1] == ':')
4956 fatal ("%s: relative file names with drive letters not supported", file);
4959 res = concat (dir, file, "");
4961 /* Delete the "/dirname/.." and "/." substrings. */
4962 slashp = etags_strchr (res, '/');
4963 while (slashp != NULL && slashp[0] != '\0')
4965 if (slashp[1] == '.')
4967 if (slashp[2] == '.'
4968 && (slashp[3] == '/' || slashp[3] == '\0'))
4973 while (cp >= res && !filename_is_absolute (cp));
4975 cp = slashp; /* the absolute name begins with "/.." */
4977 /* Under MSDOS and NT we get `d:/NAME' as absolute
4978 file name, so the luser could say `d:/../NAME'.
4979 We silently treat this as `d:/NAME'. */
4980 else if (cp[0] != '/')
4983 strcpy (cp, slashp + 3);
4987 else if (slashp[2] == '/' || slashp[2] == '\0')
4989 strcpy (slashp, slashp + 2);
4994 slashp = etags_strchr (slashp + 1, '/');
4998 return savestr ("/");
5003 /* Return a newly allocated string containing the absolute
5004 file name of dir where FILE resides given DIR (which should
5005 end with a slash). */
5007 absolute_dirname (file, dir)
5013 canonicalize_filename (file);
5014 slashp = etags_strrchr (file, '/');
5016 return savestr (dir);
5019 res = absolute_filename (file, dir);
5025 /* Whether the argument string is an absolute file name. The argument
5026 string must have been canonicalized with canonicalize_filename. */
5028 filename_is_absolute (fn)
5031 return (fn[0] == '/'
5033 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/')
5038 /* Translate backslashes into slashes. Works in place. */
5040 canonicalize_filename (fn)
5044 for (; *fn != '\0'; fn++)
5049 fn = NULL; /* shut up the compiler */
5053 /* Increase the size of a linebuffer. */
5055 grow_linebuffer (lbp, toksize)
5059 while (lbp->size < toksize)
5061 lbp->buffer = xrnew (lbp->buffer, lbp->size, char);
5064 /* Like malloc but get fatal error if memory is exhausted. */
5069 long *result = (long *) malloc (size);
5071 fatal ("virtual memory exhausted", (char *)NULL);
5076 xrealloc (ptr, size)
5080 long *result = (long *) realloc (ptr, size);
5082 fatal ("virtual memory exhausted", (char *)NULL);