1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey.
31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer.
34 char pot_etags_version
[] = "@(#) pot revision number is 12.11";
46 # include <sys/param.h>
54 # define MAXPATHLEN _MAX_PATH
59 /* On some systems, Emacs defines static as nothing for the sake
60 of unexec. We don't want that here since we don't use unexec. */
62 # define ETAGS_REGEXPS
66 #if !defined (MSDOS) && !defined (WINDOWSNT) && defined (STDC_HEADERS)
77 #include <sys/types.h>
80 #if !defined (S_ISREG) && defined (S_IFREG)
81 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
87 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
89 extern int optind
, opterr
;
90 #endif /* LONG_OPTIONS */
94 #endif /* ETAGS_REGEXPS */
96 /* Define CTAGS to make the program "ctags" compatible with the usual one.
97 Leave it undefined to make the program "etags", which makes emacs-style
98 tag tables and tags typedefs, #defines and struct/union/enum by default. */
106 /* Exit codes for success and failure. */
116 #define C_PLPL 0x00001 /* C++ */
117 #define C_STAR 0x00003 /* C* */
118 #define C_JAVA 0x00005 /* JAVA */
119 #define YACC 0x10000 /* yacc file */
121 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
122 && (abort (), 1)) || !strcmp (s, t))
123 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
124 && (abort (), 1)) || !strncmp (s, t, n))
126 #define lowcase(c) tolower ((char)c)
128 #define CHARS 256 /* 2^sizeof(char) */
129 #define CHAR(x) ((int)x & (CHARS - 1))
130 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
131 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
132 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
133 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
134 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
137 # define absolutefn(fn) (fn[0] == '/' \
138 || (fn[1] == ':' && fn[2] == '/'))
140 # define absolutefn(fn) (fn[0] == '/')
145 * xnew -- allocate storage
147 * SYNOPSIS: Type *xnew (int n, Type);
150 # include "chkmalloc.h"
151 # define xnew(n,Type) ((Type *) trace_xmalloc (__FILE__, __LINE__, \
152 (n) * sizeof (Type)))
154 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
160 { /* sorting structure */
161 char *name
; /* function or type name */
162 char *file
; /* file name */
163 bool is_func
; /* use pattern or line no */
164 bool been_warned
; /* set if noticed dup */
165 int lno
; /* line number tag is on */
166 long cno
; /* character number line starts on */
167 char *pat
; /* search pattern */
168 struct nd_st
*left
, *right
; /* left and right sons */
171 extern char *getenv ();
174 char *savenstr (), *savestr ();
175 char *etags_strchr (), *etags_strrchr ();
176 char *etags_getcwd ();
177 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
178 void grow_linebuffer ();
179 long *xmalloc (), *xrealloc ();
181 typedef void Lang_function ();
182 /* Many compilers barf on this:
183 Lang_function Asm_labels;
184 so let's write it this way */
187 void default_C_entries ();
188 void plain_C_entries ();
189 void Cjava_entries ();
190 void Cobol_paragraphs ();
191 void Cplusplus_entries ();
192 void Cstar_entries ();
193 void Erlang_functions ();
194 void Fortran_functions ();
195 void Yacc_entries ();
196 void Lisp_functions ();
197 void Pascal_functions ();
198 void Perl_functions ();
199 void Postscript_functions ();
200 void Prolog_functions ();
201 void Scheme_functions ();
202 void TeX_functions ();
203 void just_read_file ();
205 Lang_function
*get_language_from_name ();
206 Lang_function
*get_language_from_interpreter ();
207 Lang_function
*get_language_from_suffix ();
208 int total_size_of_entries ();
210 long readline_internal ();
212 void analyse_regex ();
214 #endif /* ETAGS_REGEXPS */
217 void suggest_asking_for_help ();
218 void fatal (), pfatal ();
219 void find_entries ();
224 void pfnote (), new_pfnote ();
225 void process_file ();
230 char searchar
= '/'; /* use /.../ searches */
232 int lineno
; /* line number of current line */
233 long charno
; /* current character number */
234 long linecharno
; /* charno of start of line */
236 char *curfile
; /* current input file name */
237 char *tagfile
; /* output file */
238 char *progname
; /* name this program was invoked with */
239 char *cwd
; /* current working directory */
240 char *tagfiledir
; /* directory of tagfile */
242 FILE *tagf
; /* ioptr for tags file */
243 NODE
*head
; /* the head of the binary tree of tags */
246 * A `struct linebuffer' is a structure which holds a line of text.
247 * `readline' reads a line from a stream into a linebuffer and works
248 * regardless of the length of the line.
249 * SIZE is the size of BUFFER, LEN is the length of the string in
250 * BUFFER after readline reads it.
259 struct linebuffer lb
; /* the current line */
260 struct linebuffer token_name
; /* used by C_entries as a temporary area */
264 struct linebuffer lb
; /* used by C_entries instead of lb */
267 /* boolean "functions" (see init) */
268 bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
271 *white
= " \f\t\n\013",
273 *nonam
=" \f\t\n\013(=,[;",
274 /* token ending chars */
275 *endtk
= " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?",
276 /* token starting chars */
277 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
278 /* valid in-token chars */
279 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
281 bool append_to_tagfile
; /* -a: append to tags */
282 /* The following four default to TRUE for etags, but to FALSE for ctags. */
283 bool typedefs
; /* -t: create tags for C typedefs */
284 bool typedefs_and_cplusplus
; /* -T: create tags for C typedefs, level */
285 /* 0 struct/enum/union decls, and C++ */
286 /* member functions. */
287 bool constantypedefs
; /* -d: create tags for C #define, enum */
288 /* constants and variables. */
289 /* -D: opposite of -d. Default under ctags. */
290 bool globals
; /* create tags for C global variables */
291 bool members
; /* create tags for C member variables */
292 bool update
; /* -u: update tags */
293 bool vgrind_style
; /* -v: create vgrind style index output */
294 bool no_warnings
; /* -w: suppress warnings */
295 bool cxref_style
; /* -x: create cxref style output */
296 bool cplusplus
; /* .[hc] means C++, not C */
297 bool noindentypedefs
; /* -I: ignore indentation in C */
300 struct option longopts
[] =
302 { "append", no_argument
, NULL
, 'a' },
303 { "backward-search", no_argument
, NULL
, 'B' },
304 { "c++", no_argument
, NULL
, 'C' },
305 { "cxref", no_argument
, NULL
, 'x' },
306 { "defines", no_argument
, NULL
, 'd' },
307 { "no-defines", no_argument
, NULL
, 'D' },
308 { "globals", no_argument
, &globals
, TRUE
},
309 { "no-globals", no_argument
, &globals
, FALSE
},
310 { "help", no_argument
, NULL
, 'h' },
311 { "help", no_argument
, NULL
, 'H' },
312 { "ignore-indentation", no_argument
, NULL
, 'I' },
313 { "include", required_argument
, NULL
, 'i' },
314 { "language", required_argument
, NULL
, 'l' },
315 { "members", no_argument
, &members
, TRUE
},
316 { "no-members", no_argument
, &members
, FALSE
},
317 { "no-warn", no_argument
, NULL
, 'w' },
318 { "output", required_argument
, NULL
, 'o' },
320 { "regex", required_argument
, NULL
, 'r' },
321 { "no-regex", no_argument
, NULL
, 'R' },
322 #endif /* ETAGS_REGEXPS */
323 { "typedefs", no_argument
, NULL
, 't' },
324 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
325 { "update", no_argument
, NULL
, 'u' },
326 { "version", no_argument
, NULL
, 'V' },
327 { "vgrind", no_argument
, NULL
, 'v' },
330 #endif /* LONG_OPTIONS */
333 /* Structure defining a regular expression. Elements are
334 the compiled pattern, and the name string. */
337 struct re_pattern_buffer
*pattern
;
338 struct re_registers regs
;
343 /* Number of regexps found. */
344 int num_patterns
= 0;
346 /* Array of all regexps. */
347 struct pattern
*patterns
= NULL
;
348 #endif /* ETAGS_REGEXPS */
354 /* Non-NULL if language fixed. */
355 Lang_function
*lang_func
= NULL
;
358 char *Asm_suffixes
[] = { "a", /* Unix assembler */
359 "asm", /* Microcontroller assembly */
360 "def", /* BSO/Tasking definition includes */
361 "inc", /* Microcontroller include files */
362 "ins", /* Microcontroller include files */
363 "s", "sa", /* Unix assembler */
364 "src", /* BSO/Tasking C compiler output */
368 /* Note that .c and .h can be considered C++, if the --c++ flag was
369 given. That is why default_C_entries is called here. */
370 char *default_C_suffixes
[] =
373 char *Cplusplus_suffixes
[] =
374 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
375 "M", /* Objective C++ */
376 "pdb", /* Postscript with C syntax */
379 char *Cjava_suffixes
[] =
382 char *Cobol_suffixes
[] =
383 { "COB", "cob", NULL
};
385 char *Cstar_suffixes
[] =
386 { "cs", "hs", NULL
};
388 char *Erlang_suffixes
[] =
389 { "erl", "hrl", NULL
};
391 char *Fortran_suffixes
[] =
392 { "F", "f", "f90", "for", NULL
};
394 char *Lisp_suffixes
[] =
395 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL
};
397 char *Pascal_suffixes
[] =
398 { "p", "pas", NULL
};
400 char *Perl_suffixes
[] =
401 { "pl", "pm", NULL
};
402 char *Perl_interpreters
[] =
403 { "perl", "@PERL@", NULL
};
405 char *plain_C_suffixes
[] =
406 { "pc", /* Pro*C file */
407 "m", /* Objective C file */
408 "lm", /* Objective lex file */
411 char *Postscript_suffixes
[] =
414 char *Prolog_suffixes
[] =
417 /* Can't do the `SCM' or `scm' prefix with a version number. */
418 char *Scheme_suffixes
[] =
419 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL
};
421 char *TeX_suffixes
[] =
422 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL
};
424 char *Yacc_suffixes
[] =
425 { "y", "ym", NULL
}; /* .ym is Objective yacc file */
427 /* Table of language names and corresponding functions, file suffixes
428 and interpreter names.
429 It is ok for a given function to be listed under more than one
430 name. I just didn't. */
434 Lang_function
*function
;
439 struct lang_entry lang_names
[] =
441 { "asm", Asm_labels
, Asm_suffixes
, NULL
},
442 { "c", default_C_entries
, default_C_suffixes
, NULL
},
443 { "c++", Cplusplus_entries
, Cplusplus_suffixes
, NULL
},
444 { "c*", Cstar_entries
, Cstar_suffixes
, NULL
},
445 { "cobol", Cobol_paragraphs
, Cobol_suffixes
, NULL
},
446 { "erlang", Erlang_functions
, Erlang_suffixes
, NULL
},
447 { "fortran", Fortran_functions
, Fortran_suffixes
, NULL
},
448 { "java", Cjava_entries
, Cjava_suffixes
, NULL
},
449 { "lisp", Lisp_functions
, Lisp_suffixes
, NULL
},
450 { "pascal", Pascal_functions
, Pascal_suffixes
, NULL
},
451 { "perl", Perl_functions
, Perl_suffixes
, Perl_interpreters
},
452 { "postscript", Postscript_functions
, Postscript_suffixes
, NULL
},
453 { "proc", plain_C_entries
, plain_C_suffixes
, NULL
},
454 { "prolog", Prolog_functions
, Prolog_suffixes
, NULL
},
455 { "scheme", Scheme_functions
, Scheme_suffixes
, NULL
},
456 { "tex", TeX_functions
, TeX_suffixes
, NULL
},
457 { "yacc", Yacc_entries
, Yacc_suffixes
, NULL
},
458 { "auto", NULL
}, /* default guessing scheme */
459 { "none", just_read_file
}, /* regexp matching only */
460 { NULL
, NULL
} /* end of list */
465 print_language_names ()
467 struct lang_entry
*lang
;
470 puts ("\nThese are the currently supported languages, along with the\n\
471 default file name suffixes:");
472 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
474 printf ("\t%s\t", lang
->name
);
475 if (lang
->suffixes
!= NULL
)
476 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
477 printf (" .%s", *ext
);
480 puts ("Where `auto' means use default language for files based on file\n\
481 name suffix, and `none' means only do regexp processing on files.\n\
482 If no language is specified and no matching suffix is found,\n\
483 the first line of the file is read for a sharp-bang (#!) sequence\n\
484 followed by the name of an interpreter. If no such sequence is found,\n\
485 Fortran is tried first; if no tags are found, C is tried next.");
489 # define VERSION "19"
494 printf ("%s (GNU Emacs %s)\n", (CTAGS
) ? "ctags" : "etags", VERSION
);
495 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold");
496 puts ("This program is distributed under the same terms as Emacs");
504 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
506 These are the options accepted by %s.\n", progname
, progname
);
508 puts ("You may use unambiguous abbreviations for the long option names.");
510 puts ("Long option names do not work with this executable, as it is not\n\
511 linked with GNU getopt.");
512 #endif /* LONG_OPTIONS */
513 puts ("A - as file name means read names from stdin.");
515 printf (" Absolute names are stored in the output file as they\n\
516 are. Relative ones are stored relative to the output file's directory.");
519 puts ("-a, --append\n\
520 Append tag entries to existing tags file.");
523 puts ("-B, --backward-search\n\
524 Write the search commands for the tag entries using '?', the\n\
525 backward-search command instead of '/', the forward-search command.");
528 Treat files whose name suffix defaults to C language as C++ files.");
531 puts ("-d, --defines\n\
532 Create tag entries for C #define constants and enum constants, too.");
534 puts ("-D, --no-defines\n\
535 Don't create tag entries for C #define constants and enum constants.\n\
536 This makes the tags file smaller.");
540 puts ("-i FILE, --include=FILE\n\
541 Include a note in tag file indicating that, when searching for\n\
542 a tag, one should also consult the tags file FILE after\n\
543 checking the current file.");
544 puts ("-l LANG, --language=LANG\n\
545 Force the following files to be considered as written in the\n\
546 named language up to the next --language=LANG option.");
551 Create tag entries for global variables in C and derived languages.");
553 puts ("--no-globals\n\
554 Do not create tag entries for global variables in C and\n\
555 derived languages. This makes the tags file smaller.");
557 Create tag entries for member variables in C and derived languages.");
560 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
561 Make a tag for each line matching pattern REGEXP in the\n\
562 following files. regexfile is a file containing one REGEXP\n\
563 per line. REGEXP is anchored (as if preceded by ^).\n\
564 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
565 named tags can be created with:\n\
566 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
567 puts ("-R, --no-regex\n\
568 Don't create tags from regexps for the following files.");
569 #endif /* ETAGS_REGEXPS */
570 puts ("-o FILE, --output=FILE\n\
571 Write the tags to FILE.");
572 puts ("-I, --ignore-indentation\n\
573 Don't rely on indentation quite as much as normal. Currently,\n\
574 this means not to assume that a closing brace in the first\n\
575 column is the final brace of a function or structure\n\
576 definition in C and C++.");
580 puts ("-t, --typedefs\n\
581 Generate tag entries for C typedefs.");
582 puts ("-T, --typedefs-and-c++\n\
583 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
584 and C++ member functions.");
585 puts ("-u, --update\n\
586 Update the tag entries for the given files, leaving tag\n\
587 entries for other files in place. Currently, this is\n\
588 implemented by deleting the existing entries for the given\n\
589 files and then rewriting the new entries at the end of the\n\
590 tags file. It is often faster to simply rebuild the entire\n\
591 tag file than to use this.");
592 puts ("-v, --vgrind\n\
593 Generates an index of items intended for human consumption,\n\
594 similar to the output of vgrind. The index is sorted, and\n\
595 gives the page number of each item.");
596 puts ("-w, --no-warn\n\
597 Suppress warning messages about entries defined in multiple\n\
599 puts ("-x, --cxref\n\
600 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
601 The output uses line numbers instead of page numbers, but\n\
602 beyond that the differences are cosmetic; try both to see\n\
606 puts ("-V, --version\n\
607 Print the version of the program.\n\
609 Print this help message.");
611 print_language_names ();
614 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu");
627 /* This structure helps us allow mixing of --lang and file names. */
630 enum argument_type arg_type
;
632 Lang_function
*function
;
635 #ifdef VMS /* VMS specific functions */
639 /* This is a BUG! ANY arbitrary limit is a BUG!
640 Won't someone please fix this? */
641 #define MAX_FILE_SPEC_LEN 255
644 char body
[MAX_FILE_SPEC_LEN
+ 1];
648 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
649 returning in each successive call the next file name matching the input
650 spec. The function expects that each in_spec passed
651 to it will be processed to completion; in particular, up to and
652 including the call following that in which the last matching name
653 is returned, the function ignores the value of in_spec, and will
654 only start processing a new spec with the following call.
655 If an error occurs, on return out_spec contains the value
656 of in_spec when the error occurred.
658 With each successive file name returned in out_spec, the
659 function's return value is one. When there are no more matching
660 names the function returns zero. If on the first call no file
661 matches in_spec, or there is any other error, -1 is returned.
666 #define OUTSIZE MAX_FILE_SPEC_LEN
672 static long context
= 0;
673 static struct dsc$descriptor_s o
;
674 static struct dsc$descriptor_s i
;
675 static bool pass1
= TRUE
;
682 o
.dsc$a_pointer
= (char *) out
;
683 o
.dsc$w_length
= (short)OUTSIZE
;
684 i
.dsc$a_pointer
= in
;
685 i
.dsc$w_length
= (short)strlen(in
);
686 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
687 i
.dsc$b_class
= DSC$K_CLASS_S
;
688 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
689 o
.dsc$b_class
= DSC$K_CLASS_VS
;
691 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
693 out
->body
[out
->curlen
] = EOS
;
696 else if (status
== RMS$_NMF
)
700 strcpy(out
->body
, in
);
703 lib$
find_file_end(&context
);
709 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
710 name of each file specified by the provided arg expanding wildcards.
713 gfnames (arg
, p_error
)
717 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
719 switch (fn_exp (&filename
, arg
))
723 return filename
.body
;
729 return filename
.body
;
733 #ifndef OLD /* Newer versions of VMS do provide `system'. */
737 error ("%s", "system() function not implemented under VMS");
741 #define VERSION_DELIM ';'
742 char *massage_name (s
)
748 if (*s
== VERSION_DELIM
)
766 unsigned int nincluded_files
;
767 char **included_files
;
770 int current_arg
, file_count
;
771 struct linebuffer filename_lb
;
777 _fmode
= O_BINARY
; /* all of files are treated as binary files */
782 included_files
= xnew (argc
, char *);
786 /* Allocate enough no matter what happens. Overkill, but each one
788 argbuffer
= xnew (argc
, argument
);
791 /* Set syntax for regular expression routines. */
792 re_set_syntax (RE_SYNTAX_EMACS
);
793 #endif /* ETAGS_REGEXPS */
796 * If etags, always find typedefs and structure tags. Why not?
797 * Also default is to find macro constants, enum constants and
802 typedefs
= typedefs_and_cplusplus
= constantypedefs
= TRUE
;
813 optstring
= "-aCdDf:Il:o:r:RStTi:BuvxwVhH";
815 optstring
= "-aCdDf:Il:o:StTi:BuvxwVhH";
816 #endif /* ETAGS_REGEXPS */
819 optstring
= optstring
+ 1;
820 #endif /* LONG_OPTIONS */
822 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
829 /* If getopt returns 0, then it has already processed a
830 long-named option. We should do nothing. */
834 /* This means that a file name has been seen. Record it. */
835 argbuffer
[current_arg
].arg_type
= at_filename
;
836 argbuffer
[current_arg
].what
= optarg
;
841 /* Common options. */
842 case 'a': append_to_tagfile
= TRUE
; break;
843 case 'C': cplusplus
= TRUE
; break;
844 case 'd': constantypedefs
= TRUE
; break;
845 case 'D': constantypedefs
= FALSE
; break;
846 case 'f': /* for compatibility with old makefiles */
850 error ("-%c option may only be given once.", opt
);
851 suggest_asking_for_help ();
856 case 'S': /* for backward compatibility */
857 noindentypedefs
= TRUE
;
860 argbuffer
[current_arg
].function
= get_language_from_name (optarg
);
861 argbuffer
[current_arg
].arg_type
= at_language
;
866 argbuffer
[current_arg
].arg_type
= at_regexp
;
867 argbuffer
[current_arg
].what
= optarg
;
871 argbuffer
[current_arg
].arg_type
= at_regexp
;
872 argbuffer
[current_arg
].what
= NULL
;
875 #endif /* ETAGS_REGEXPS */
887 typedefs
= typedefs_and_cplusplus
= TRUE
;
892 included_files
[nincluded_files
++] = optarg
;
896 case 'B': searchar
= '?'; break;
897 case 'u': update
= TRUE
; break;
898 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
899 case 'x': cxref_style
= TRUE
; break;
900 case 'w': no_warnings
= TRUE
; break;
903 suggest_asking_for_help ();
907 for (; optind
< argc
; ++optind
)
909 argbuffer
[current_arg
].arg_type
= at_filename
;
910 argbuffer
[current_arg
].what
= argv
[optind
];
915 if (nincluded_files
== 0 && file_count
== 0)
917 error ("no input files specified.", 0);
918 suggest_asking_for_help ();
922 tagfile
= CTAGS
? "tags" : "TAGS";
923 cwd
= etags_getcwd (); /* the current working directory */
924 if (cwd
[strlen (cwd
) - 1] != '/')
927 cwd
= concat (oldcwd
, "/", "");
930 if (streq (tagfile
, "-"))
933 tagfiledir
= absolute_dirname (tagfile
, cwd
);
935 init (); /* set up boolean "functions" */
938 initbuffer (&token_name
);
939 initbuffer (&lbs
[0].lb
);
940 initbuffer (&lbs
[1].lb
);
941 initbuffer (&filename_lb
);
945 if (streq (tagfile
, "-"))
949 /* Switch redirected `stdout' to binary mode (setting `_fmode'
950 doesn't take effect until after `stdout' is already open). */
951 if (!isatty (fileno (stdout
)))
952 setmode (fileno (stdout
), O_BINARY
);
956 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
962 * Loop through files finding functions.
964 for (i
= 0; i
< current_arg
; ++i
)
966 switch (argbuffer
[i
].arg_type
)
969 lang_func
= argbuffer
[i
].function
;
973 analyse_regex (argbuffer
[i
].what
);
978 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
982 error ("can't find file %s\n", this_file
);
987 this_file
= massage_name (this_file
);
990 this_file
= argbuffer
[i
].what
;
992 /* Input file named "-" means read file names from stdin
994 if (streq (this_file
, "-"))
995 while (readline_internal (&filename_lb
, stdin
) > 0)
996 process_file (filename_lb
.buffer
);
998 process_file (this_file
);
1008 while (nincluded_files
-- > 0)
1009 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1015 /* If CTAGS, we are here. process_file did not write the tags yet,
1016 because we want them ordered. Let's do it now. */
1026 for (i
= 0; i
< current_arg
; ++i
)
1028 if (argbuffer
[i
].arg_type
!= at_filename
)
1031 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1032 tagfile
, argbuffer
[i
].what
, tagfile
);
1033 if (system (cmd
) != GOOD
)
1034 fatal ("failed to execute shell command", (char *)NULL
);
1036 append_to_tagfile
= TRUE
;
1039 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1048 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
1049 exit (system (cmd
));
1056 * Return a Lang_function given the name.
1059 get_language_from_name (name
)
1062 struct lang_entry
*lang
;
1065 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1067 if (streq (name
, lang
->name
))
1068 return lang
->function
;
1071 error ("language \"%s\" not recognized.", optarg
);
1072 suggest_asking_for_help ();
1074 /* This point should never be reached. The function should either
1075 return a function pointer or never return. Note that a NULL
1076 pointer cannot be considered as an error, as it means that the
1077 language has not been explicitely imposed by the user ("auto"). */
1078 return NULL
; /* avoid warnings from compiler */
1083 * Return a Lang_function given the interpreter name.
1086 get_language_from_interpreter (interpreter
)
1089 struct lang_entry
*lang
;
1092 if (interpreter
== NULL
)
1094 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1095 if (lang
->interpreters
!= NULL
)
1096 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1097 if (streq (*iname
, interpreter
))
1098 return lang
->function
;
1106 * Return a Lang_function given the file suffix.
1109 get_language_from_suffix (suffix
)
1112 struct lang_entry
*lang
;
1117 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1118 if (lang
->suffixes
!= NULL
)
1119 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1120 if (streq (*ext
, suffix
))
1121 return lang
->function
;
1128 * This routine is called on each file argument.
1134 struct stat stat_buf
;
1139 for (p
= file
; *p
!= '\0'; p
++)
1144 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
1146 error ("skipping %s: it is not a regular file.", file
);
1149 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1151 error ("skipping inclusion of %s in self.", file
);
1154 inf
= fopen (file
, "r");
1161 find_entries (file
, inf
);
1167 if (absolutefn (file
))
1169 /* file is an absolute file name. Canonicalise it. */
1170 filename
= absolute_filename (file
, cwd
);
1174 /* file is a file name relative to cwd. Make it relative
1175 to the directory of the tags file. */
1176 filename
= relative_filename (file
, tagfiledir
);
1178 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1187 * This routine sets up the boolean pseudo-functions which work
1188 * by setting boolean flags dependent upon the corresponding character
1189 * Every char which is NOT in that string is not a white char. Therefore,
1190 * all of the array "_wht" is set to FALSE, and then the elements
1191 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1192 * of a char is TRUE if it is the string "white", else FALSE.
1200 for (i
= 0; i
< CHARS
; i
++)
1201 _wht
[i
] = _nin
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
1202 for (sp
= white
; *sp
; sp
++) _wht
[*sp
] = TRUE
; _wht
[0] = _wht
['\n'];
1203 for (sp
= nonam
; *sp
; sp
++) _nin
[*sp
] = TRUE
; _nin
[0] = _nin
['\n'];
1204 for (sp
= endtk
; *sp
; sp
++) _etk
[*sp
] = TRUE
; _etk
[0] = _etk
['\n'];
1205 for (sp
= midtk
; *sp
; sp
++) _itk
[*sp
] = TRUE
; _btk
[0] = _btk
['\n'];
1206 for (sp
= begtk
; *sp
; sp
++) _btk
[*sp
] = TRUE
; _itk
[0] = _itk
['\n'];
1210 * This routine opens the specified file and calls the function
1211 * which finds the function and type definitions.
1214 find_entries (file
, inf
)
1219 Lang_function
*function
;
1220 NODE
*old_last_node
;
1221 extern NODE
*last_node
;
1224 /* Memory leakage here: the memory block pointed by curfile is never
1225 released. The amount of memory leaked here is the sum of the
1226 lengths of the input file names. */
1227 curfile
= savestr (file
);
1229 /* If user specified a language, use it. */
1230 function
= lang_func
;
1231 if (function
!= NULL
)
1238 cp
= etags_strrchr (file
, '.');
1242 function
= get_language_from_suffix (cp
);
1243 if (function
!= NULL
)
1251 /* Look for sharp-bang as the first two characters. */
1252 if (readline_internal (&lb
, inf
)
1254 && lb
.buffer
[0] == '#'
1255 && lb
.buffer
[1] == '!')
1259 /* Set lp to point at the first char after the last slash in the
1260 line or, if no slashes, at the first nonblank. Then set cp to
1261 the first successive blank and terminate the string. */
1262 lp
= etags_strrchr (lb
.buffer
+2, '/');
1266 for (lp
= lb
.buffer
+2; *lp
!= '\0' && isspace (*lp
); lp
++)
1268 for (cp
= lp
; *cp
!= '\0' && !isspace (*cp
); cp
++)
1272 if (strlen (lp
) > 0)
1274 function
= get_language_from_interpreter (lp
);
1275 if (function
!= NULL
)
1286 old_last_node
= last_node
;
1287 Fortran_functions (inf
);
1289 /* No Fortran entries found. Try C. */
1290 if (old_last_node
== last_node
)
1293 default_C_entries (inf
);
1301 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1302 char *name
; /* tag name, or NULL if unnamed */
1303 bool is_func
; /* tag is a function */
1304 char *linestart
; /* start of the line where tag is */
1305 int linelen
; /* length of the line where tag is */
1306 int lno
; /* line number */
1307 long cno
; /* character number */
1311 if (CTAGS
&& name
== NULL
)
1314 np
= xnew (1, NODE
);
1316 /* If ctags mode, change name "main" to M<thisfilename>. */
1317 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1319 register char *fp
= etags_strrchr (curfile
, '/');
1320 np
->name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
1321 fp
= etags_strrchr (np
->name
, '.');
1322 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
1327 np
->been_warned
= FALSE
;
1329 np
->is_func
= is_func
;
1331 /* Our char numbers are 0-base, because of C language tradition?
1332 ctags compatibility? old versions compatibility? I don't know.
1333 Anyway, since emacs's are 1-base we expect etags.el to take care
1334 of the difference. If we wanted to have 1-based numbers, we would
1335 uncomment the +1 below. */
1336 np
->cno
= cno
/* + 1 */ ;
1337 np
->left
= np
->right
= NULL
;
1338 if (CTAGS
&& !cxref_style
)
1340 if (strlen (linestart
) < 50)
1341 np
->pat
= concat (linestart
, "$", "");
1343 np
->pat
= savenstr (linestart
, 50);
1346 np
->pat
= savenstr (linestart
, linelen
);
1348 add_node (np
, &head
);
1351 /* Date: Wed, 22 Jan 1997 02:56:31 -0500
1352 * From: Sam Kendall <kendall@cybercom.net>
1353 * Subject: Proposal for firming up the TAGS format specification
1354 * To: F.Potorti@cnuce.cnr.it
1356 * pfnote should emit the optimized form [unnamed tag] only if:
1357 * 1. name does not contain any of the characters " \t\r\n()";
1358 * 2. linestart contains name as either a rightmost, or rightmost but
1359 * one character, substring;
1360 * 3. the character, if any, immediately before name in linestart must
1361 * be one of the characters " \t()";
1362 * 4. the character, if any, immediately after name in linestart must
1363 * also be one of the characters " \t()".
1365 #define traditional_tag_style TRUE
1367 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1368 char *name
; /* tag name, or NULL if unnamed */
1369 int namelen
; /* tag length */
1370 bool is_func
; /* tag is a function */
1371 char *linestart
; /* start of the line where tag is */
1372 int linelen
; /* length of the line where tag is */
1373 int lno
; /* line number */
1374 long cno
; /* character number */
1382 for (cp
= name
; !notinname (*cp
); cp
++)
1384 if (*cp
== '\0') /* rule #1 */
1386 cp
= linestart
+ linelen
- namelen
;
1387 if (notinname (linestart
[linelen
-1]))
1388 cp
-= 1; /* rule #4 */
1389 if (cp
>= linestart
/* rule #2 */
1391 || notinname (cp
[-1])) /* rule #3 */
1392 && strneq (name
, cp
, namelen
)) /* rule #2 */
1393 named
= FALSE
; /* use unnamed tag */
1398 name
= savenstr (name
, namelen
);
1401 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1406 * recurse on left children, iterate on right children.
1410 register NODE
*node
;
1414 register NODE
*node_right
= node
->right
;
1415 free_tree (node
->left
);
1416 if (node
->name
!= NULL
)
1419 free ((char *) node
);
1426 * Adds a node to the tree of nodes. In etags mode, we don't keep
1427 * it sorted; we just keep a linear list. In ctags mode, maintain
1428 * an ordered tree, with no attempt at balancing.
1430 * add_node is the only function allowed to add nodes, so it can
1433 NODE
*last_node
= NULL
;
1435 add_node (node
, cur_node_p
)
1436 NODE
*node
, **cur_node_p
;
1439 register NODE
*cur_node
= *cur_node_p
;
1441 if (cur_node
== NULL
)
1451 if (last_node
== NULL
)
1452 fatal ("internal error in add_node", (char *)NULL
);
1453 last_node
->right
= node
;
1459 dif
= strcmp (node
->name
, cur_node
->name
);
1462 * If this tag name matches an existing one, then
1463 * do not add the node, but maybe print a warning.
1467 if (streq (node
->file
, cur_node
->file
))
1471 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1472 node
->file
, lineno
, node
->name
);
1473 fprintf (stderr
, "Second entry ignored\n");
1476 else if (!cur_node
->been_warned
&& !no_warnings
)
1480 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1481 node
->file
, cur_node
->file
, node
->name
);
1482 cur_node
->been_warned
= TRUE
;
1487 /* Actually add the node */
1488 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1494 register NODE
*node
;
1501 /* Output subentries that precede this one */
1502 put_entries (node
->left
);
1504 /* Output this entry */
1508 if (node
->name
!= NULL
)
1509 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1510 node
->pat
, node
->name
, node
->lno
, node
->cno
);
1512 fprintf (tagf
, "%s\177%d,%d\n",
1513 node
->pat
, node
->lno
, node
->cno
);
1517 if (node
->name
== NULL
)
1518 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
1523 fprintf (stdout
, "%s %s %d\n",
1524 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1526 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1527 node
->name
, node
->lno
, node
->file
, node
->pat
);
1531 fprintf (tagf
, "%s\t%s\t", node
->name
, node
->file
);
1535 putc (searchar
, tagf
);
1538 for (sp
= node
->pat
; *sp
; sp
++)
1540 if (*sp
== '\\' || *sp
== searchar
)
1544 putc (searchar
, tagf
);
1547 { /* a typedef; text pattern inadequate */
1548 fprintf (tagf
, "%d", node
->lno
);
1554 /* Output subentries that follow this one */
1555 put_entries (node
->right
);
1558 /* Length of a number's decimal representation. */
1566 for (; num
; num
/= 10)
1572 * Return total number of characters that put_entries will output for
1573 * the nodes in the subtree of the specified node. Works only if
1574 * we are not ctags, but called only in that case. This count
1575 * is irrelevant with the new tags.el, but is still supplied for
1576 * backward compatibility.
1579 total_size_of_entries (node
)
1580 register NODE
*node
;
1588 for (; node
; node
= node
->right
)
1590 /* Count left subentries. */
1591 total
+= total_size_of_entries (node
->left
);
1593 /* Count this entry */
1594 total
+= strlen (node
->pat
) + 1;
1595 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1596 if (node
->name
!= NULL
)
1597 total
+= 1 + strlen (node
->name
); /* \001name */
1604 * The C symbol tables.
1609 st_C_objprot
, st_C_objimpl
, st_C_objend
,
1613 st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1616 /* Feed stuff between (but not including) %[ and %] lines to:
1617 gperf -c -k 1,3 -o -p -r -t
1619 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1621 @interface, 0, st_C_objprot
1622 @protocol, 0, st_C_objprot
1623 @implementation,0, st_C_objimpl
1624 @end, 0, st_C_objend
1625 import, C_JAVA, st_C_ignore
1626 package, C_JAVA, st_C_ignore
1627 friend, C_PLPL, st_C_ignore
1628 extends, C_JAVA, st_C_javastruct
1629 implements, C_JAVA, st_C_javastruct
1630 class, C_PLPL, st_C_struct
1631 namespace, C_PLPL, st_C_struct
1632 domain, C_STAR, st_C_struct
1633 union, 0, st_C_struct
1634 struct, 0, st_C_struct
1636 typedef, 0, st_C_typedef
1637 define, 0, st_C_define
1638 bool, C_PLPL, st_C_typespec
1639 long, 0, st_C_typespec
1640 short, 0, st_C_typespec
1641 int, 0, st_C_typespec
1642 char, 0, st_C_typespec
1643 float, 0, st_C_typespec
1644 double, 0, st_C_typespec
1645 signed, 0, st_C_typespec
1646 unsigned, 0, st_C_typespec
1647 auto, 0, st_C_typespec
1648 void, 0, st_C_typespec
1649 extern, 0, st_C_typespec
1650 static, 0, st_C_typespec
1651 const, 0, st_C_typespec
1652 volatile, 0, st_C_typespec
1653 explicit, C_PLPL, st_C_typespec
1654 mutable, C_PLPL, st_C_typespec
1655 typename, C_PLPL, st_C_typespec
1656 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1657 DEFUN, 0, st_C_gnumacro
1658 SYSCALL, 0, st_C_gnumacro
1659 ENTRY, 0, st_C_gnumacro
1660 PSEUDO, 0, st_C_gnumacro
1661 # These are defined inside C functions, so currently they are not met.
1662 # EXFUN used in glibc, DEFVAR_* in emacs.
1663 #EXFUN, 0, st_C_gnumacro
1664 #DEFVAR_, 0, st_C_gnumacro
1666 and replace lines between %< and %> with its output. */
1668 /* starting time is 10:31:16 */
1669 /* C code produced by gperf version 2.1 (K&R C version) */
1670 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1673 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1675 #define MIN_WORD_LENGTH 3
1676 #define MAX_WORD_LENGTH 15
1677 #define MIN_HASH_VALUE 15
1678 #define MAX_HASH_VALUE 128
1681 114 is the maximum key range
1687 register unsigned int len
;
1689 static unsigned char hash_table
[] =
1691 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1692 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1693 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1694 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1695 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1696 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1697 128, 128, 128, 128, 39, 128, 128, 128, 54, 48,
1698 46, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1699 28, 128, 128, 40, 32, 128, 128, 128, 128, 128,
1700 128, 128, 128, 128, 128, 128, 128, 24, 30, 47,
1701 62, 7, 60, 27, 128, 60, 128, 128, 59, 16,
1702 31, 23, 45, 128, 4, 14, 2, 55, 5, 128,
1703 128, 128, 128, 128, 128, 128, 128, 128,
1705 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1708 struct C_stab_entry
*
1709 in_word_set (str
, len
)
1711 register unsigned int len
;
1714 static struct C_stab_entry wordlist
[] =
1716 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1717 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1718 {"extern", 0, st_C_typespec
},
1719 {"extends", C_JAVA
, st_C_javastruct
},
1720 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1721 {"struct", 0, st_C_struct
},
1722 {"mutable", C_PLPL
, st_C_typespec
},
1723 {"",}, {"",}, {"",}, {"",},
1724 {"auto", 0, st_C_typespec
},
1725 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1727 {"short", 0, st_C_typespec
},
1729 {"static", 0, st_C_typespec
},
1731 {"signed", 0, st_C_typespec
},
1732 {"",}, {"",}, {"",}, {"",},
1733 {"@protocol", 0, st_C_objprot
},
1735 {"typedef", 0, st_C_typedef
},
1736 {"typename", C_PLPL
, st_C_typespec
},
1737 {"namespace", C_PLPL
, st_C_struct
},
1738 {"bool", C_PLPL
, st_C_typespec
},
1740 {"explicit", C_PLPL
, st_C_typespec
},
1741 {"",}, {"",}, {"",}, {"",},
1742 {"int", 0, st_C_typespec
},
1743 {"enum", 0, st_C_enum
},
1745 {"void", 0, st_C_typespec
},
1746 {"@implementation", 0, st_C_objimpl
},
1748 {"volatile", 0, st_C_typespec
},
1750 {"@end", 0, st_C_objend
},
1751 {"char", 0, st_C_typespec
},
1752 {"class", C_PLPL
, st_C_struct
},
1753 {"unsigned", 0, st_C_typespec
},
1755 {"@interface", 0, st_C_objprot
},
1757 {"PSEUDO", 0, st_C_gnumacro
},
1758 {"const", 0, st_C_typespec
},
1759 {"domain", C_STAR
, st_C_struct
},
1760 {"ENTRY", 0, st_C_gnumacro
},
1762 {"SYSCALL", 0, st_C_gnumacro
},
1763 {"float", 0, st_C_typespec
},
1764 {"",}, {"",}, {"",}, {"",}, {"",},
1765 {"long", 0, st_C_typespec
},
1766 {"",}, {"",}, {"",}, {"",},
1767 {"package", C_JAVA
, st_C_ignore
},
1768 {"",}, {"",}, {"",}, {"",}, {"",},
1769 {"DEFUN", 0, st_C_gnumacro
},
1770 {"",}, {"",}, {"",}, {"",}, {"",},
1771 {"import", C_JAVA
, st_C_ignore
},
1772 {"",}, {"",}, {"",},
1773 {"implements", C_JAVA
, st_C_javastruct
},
1774 {"",}, {"",}, {"",}, {"",},
1775 {"union", 0, st_C_struct
},
1777 {"double", 0, st_C_typespec
},
1779 {"friend", C_PLPL
, st_C_ignore
},
1781 {"define", 0, st_C_define
},
1784 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1786 register int key
= hash (str
, len
);
1788 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1790 register char *s
= wordlist
[key
].name
;
1792 if (*s
== *str
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
1793 return &wordlist
[key
];
1798 /* ending time is 10:31:16 */
1802 C_symtype (str
, len
, c_ext
)
1807 register struct C_stab_entry
*se
= in_word_set (str
, len
);
1809 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1815 * C functions and variables are recognized using a simple
1816 * finite automaton. fvdef is its state variable.
1820 fvnone
, /* nothing seen */
1821 fvnameseen
, /* function or variable name seen */
1822 fstartlist
, /* func: just after open parenthesis */
1823 finlist
, /* func: in parameter list */
1824 flistseen
, /* func: after parameter list */
1825 fignore
, /* func: before open brace */
1826 vignore
/* var-like: ignore until ';' */
1831 * typedefs are recognized using a simple finite automaton.
1832 * typdef is its state variable.
1836 tnone
, /* nothing seen */
1837 ttypedseen
, /* typedef keyword seen */
1838 tinbody
, /* inside typedef body */
1839 tend
, /* just before typedef tag */
1840 tignore
/* junk after typedef tag */
1845 * struct-like structures (enum, struct and union) are recognized
1846 * using another simple finite automaton. `structdef' is its state
1851 snone
, /* nothing seen yet */
1852 skeyseen
, /* struct-like keyword seen */
1853 stagseen
, /* struct-like tag seen */
1854 scolonseen
, /* colon seen after struct-like tag */
1855 sinbody
/* in struct body: recognize member func defs*/
1859 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1860 * struct tag, and structtype is the type of the preceding struct-like
1863 char *structtag
= "<uninited>";
1864 enum sym_type structtype
;
1867 * When objdef is different from onone, objtag is the name of the class.
1869 char *objtag
= "<uninited>";
1872 * Yet another little state machine to deal with preprocessor lines.
1876 dnone
, /* nothing seen */
1877 dsharpseen
, /* '#' seen as first char on line */
1878 ddefineseen
, /* '#' and 'define' seen */
1879 dignorerest
/* ignore rest of line */
1883 * State machine for Objective C protocols and implementations.
1884 * Tom R.Hageman <tom@basil.icce.rug.nl>
1888 onone
, /* nothing seen */
1889 oprotocol
, /* @interface or @protocol seen */
1890 oimplementation
, /* @implementations seen */
1891 otagseen
, /* class name seen */
1892 oparenseen
, /* parenthesis before category seen */
1893 ocatseen
, /* category name seen */
1894 oinbody
, /* in @implementation body */
1895 omethodsign
, /* in @implementation body, after +/- */
1896 omethodtag
, /* after method name */
1897 omethodcolon
, /* after method colon */
1898 omethodparm
, /* after method parameter */
1899 oignore
/* wait for @end */
1904 * Use this structure to keep info about the token read, and how it
1905 * should be tagged. Used by the make_C_tag function to build a tag.
1917 TOKEN tok
; /* latest token read */
1921 * Set this to TRUE, and the next token considered is called a function.
1922 * Used only for GNU emacs's function-defining macros.
1924 bool next_token_is_func
;
1927 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1932 * methodlen is the length of the method name stored in token_name.
1938 * checks to see if the current token is at the start of a
1939 * function or variable, or corresponds to a typedef, or
1940 * is a struct/union/enum tag, or #define, or an enum constant.
1942 * *IS_FUNC gets TRUE iff the token is a function or #define macro
1943 * with args. C_EXT is which language we are looking at.
1945 * In the future we will need some way to adjust where the end of
1946 * the token is; for instance, implementing the C++ keyword
1947 * `operator' properly will adjust the end of the token to be after
1948 * whatever follows `operator'.
1956 * next_token_is_func IN OUT
1960 consider_token (str
, len
, c
, c_ext
, cblev
, parlev
, is_func_or_var
)
1961 register char *str
; /* IN: token pointer */
1962 register int len
; /* IN: token length */
1963 register char c
; /* IN: first char after the token */
1964 int c_ext
; /* IN: C extensions mask */
1965 int cblev
; /* IN: curly brace level */
1966 int parlev
; /* IN: parenthesis level */
1967 bool *is_func_or_var
; /* OUT: function or variable found */
1969 enum sym_type toktype
= C_symtype (str
, len
, c_ext
);
1972 * Advance the definedef state machine.
1977 /* We're not on a preprocessor line. */
1980 if (toktype
== st_C_define
)
1982 definedef
= ddefineseen
;
1986 definedef
= dignorerest
;
1991 * Make a tag for any macro, unless it is a constant
1992 * and constantypedefs is FALSE.
1994 definedef
= dignorerest
;
1995 *is_func_or_var
= (c
== '(');
1996 if (!*is_func_or_var
&& !constantypedefs
)
2003 error ("internal error: definedef value.", (char *)NULL
);
2012 if (toktype
== st_C_typedef
)
2015 typdef
= ttypedseen
;
2031 /* Do not return here, so the structdef stuff has a chance. */
2045 * This structdef business is currently only invoked when cblev==0.
2046 * It should be recursively invoked whatever the curly brace level,
2047 * and a stack of states kept, to allow for definitions of structs
2050 * This structdef business is NOT invoked when we are ctags and the
2051 * file is plain C. This is because a struct tag may have the same
2052 * name as another tag, and this loses with ctags.
2056 case st_C_javastruct
:
2057 if (structdef
== stagseen
)
2058 structdef
= scolonseen
;
2063 if (typdef
== ttypedseen
2064 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
2066 structdef
= skeyseen
;
2067 structtype
= toktype
;
2072 if (structdef
== skeyseen
)
2074 /* Save the tag for struct/union/class, for functions and variables
2075 that may be defined inside. */
2076 if (structtype
== st_C_struct
)
2077 structtag
= savenstr (str
, len
);
2079 structtag
= "<enum>";
2080 structdef
= stagseen
;
2084 /* Avoid entering fvdef stuff if typdef is going on. */
2085 if (typdef
!= tnone
)
2091 /* Detect GNU macros.
2093 DEFUN note for writers of emacs C code:
2094 The DEFUN macro, used in emacs C source code, has a first arg
2095 that is a string (the lisp function name), and a second arg that
2096 is a C function name. Since etags skips strings, the second arg
2097 is tagged. This is unfortunate, as it would be better to tag the
2098 first arg. The simplest way to deal with this problem would be
2099 to name the tag with a name built from the function name, by
2100 removing the initial 'F' character and substituting '-' for '_'.
2101 Anyway, this assumes that the conventions of naming lisp
2102 functions will never change. Currently, this method is not
2103 implemented, so writers of emacs code are recommended to put the
2104 first two args of a DEFUN on the same line. */
2105 if (definedef
== dnone
&& toktype
== st_C_gnumacro
)
2107 next_token_is_func
= TRUE
;
2110 if (next_token_is_func
)
2112 next_token_is_func
= FALSE
;
2114 *is_func_or_var
= TRUE
;
2118 /* Detect Objective C constructs. */
2128 objdef
= oimplementation
;
2132 case oimplementation
:
2133 /* Save the class tag for functions or variables defined inside. */
2134 objtag
= savenstr (str
, len
);
2138 /* Save the class tag for categories. */
2139 objtag
= savenstr (str
, len
);
2141 *is_func_or_var
= TRUE
;
2145 *is_func_or_var
= TRUE
;
2152 objdef
= omethodtag
;
2154 grow_linebuffer (&token_name
, methodlen
+ 1);
2155 strncpy (token_name
.buffer
, str
, len
);
2156 token_name
.buffer
[methodlen
] = '\0';
2157 token_name
.len
= methodlen
;
2163 objdef
= omethodparm
;
2168 objdef
= omethodtag
;
2170 grow_linebuffer (&token_name
, methodlen
+ 1);
2171 strncat (token_name
.buffer
, str
, len
);
2172 token_name
.len
= methodlen
;
2177 if (toktype
== st_C_objend
)
2179 /* Memory leakage here: the string pointed by objtag is
2180 never released, because many tests would be needed to
2181 avoid breaking on incorrect input code. The amount of
2182 memory leaked here is the sum of the lengths of the
2190 /* A function, variable or enum constant? */
2194 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2195 fvdef
= fvnone
; /* should be useless */
2201 if (constantypedefs
&& structdef
== sinbody
&& structtype
== st_C_enum
)
2203 if (fvdef
== fvnone
)
2205 fvdef
= fvnameseen
; /* function or variable */
2206 *is_func_or_var
= TRUE
;
2216 * This routine finds functions, variables, typedefs,
2217 * #define's, enum constants and struct/union/enum definitions in
2218 * #C syntax and adds them to the list.
2220 #define current_lb_is_new (newndx == curndx)
2221 #define switch_line_buffers() (curndx = 1 - curndx)
2223 #define curlb (lbs[curndx].lb)
2224 #define othlb (lbs[1-curndx].lb)
2225 #define newlb (lbs[newndx].lb)
2226 #define curlinepos (lbs[curndx].linepos)
2227 #define othlinepos (lbs[1-curndx].linepos)
2228 #define newlinepos (lbs[newndx].linepos)
2230 #define CNL_SAVE_DEFINEDEF \
2232 curlinepos = charno; \
2234 linecharno = charno; \
2235 charno += readline (&curlb, inf); \
2236 lp = curlb.buffer; \
2243 CNL_SAVE_DEFINEDEF; \
2244 if (savetok.valid) \
2247 savetok.valid = FALSE; \
2249 definedef = dnone; \
2257 /* This function should never be called when tok.valid is FALSE, but
2258 we must protect against invalid input or internal errors. */
2261 if (traditional_tag_style
)
2263 /* This was the original code. Now we call new_pfnote instead,
2264 which uses the new method for naming tags (see new_pfnote). */
2267 if (CTAGS
|| tok
.named
)
2268 name
= savestr (token_name
.buffer
);
2269 pfnote (name
, isfun
,
2270 tok
.buffer
, tok
.linelen
, tok
.lineno
, tok
.linepos
);
2273 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
,
2274 tok
.buffer
, tok
.linelen
, tok
.lineno
, tok
.linepos
);
2283 C_entries (c_ext
, inf
)
2284 int c_ext
; /* extension of C */
2285 FILE *inf
; /* input file */
2287 register char c
; /* latest char read; '\0' for end of line */
2288 register char *lp
; /* pointer one beyond the character `c' */
2289 int curndx
, newndx
; /* indices for current and new lb */
2290 register int tokoff
; /* offset in line of start of current token */
2291 register int toklen
; /* length of current token */
2292 char *qualifier
; /* string used to qualify names */
2293 int qlen
; /* length of qualifier */
2294 int cblev
; /* current curly brace level */
2295 int parlev
; /* current parenthesis level */
2296 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2298 TOKEN savetok
; /* token saved during preprocessor handling */
2301 curndx
= newndx
= 0;
2307 fvdef
= fvnone
; typdef
= tnone
; structdef
= snone
;
2308 definedef
= dnone
; objdef
= onone
;
2309 next_token_is_func
= yacc_rules
= FALSE
;
2310 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2311 tok
.valid
= savetok
.valid
= FALSE
;
2314 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2315 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2317 { qualifier
= "."; qlen
= 1; }
2319 { qualifier
= "::"; qlen
= 2; }
2326 /* If we're at the end of the line, the next character is a
2327 '\0'; don't skip it, because it's the thing that tells us
2328 to read the next line. */
2349 /* Newlines inside comments do not end macro definitions in
2364 /* Newlines inside strings do not end macro definitions
2365 in traditional cpp, even though compilers don't
2366 usually accept them. */
2377 /* Hmmm, something went wrong. */
2391 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2396 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2406 else if (/* cplpl && */ *lp
== '/')
2414 if ((c_ext
& YACC
) && *lp
== '%')
2416 /* entering or exiting rules section in yacc file */
2418 definedef
= dnone
; fvdef
= fvnone
;
2419 typdef
= tnone
; structdef
= snone
;
2420 next_token_is_func
= FALSE
;
2421 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2423 yacc_rules
= !yacc_rules
;
2429 if (definedef
== dnone
)
2432 bool cpptoken
= TRUE
;
2434 /* Look back on this line. If all blanks, or nonblanks
2435 followed by an end of comment, this is a preprocessor
2437 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2440 if (*cp
== '*' && *(cp
+1) == '/')
2449 definedef
= dsharpseen
;
2450 } /* if (definedef == dnone) */
2456 /* Consider token only if some complicated conditions are satisfied. */
2457 if ((definedef
!= dnone
2458 || (cblev
== 0 && structdef
!= scolonseen
)
2459 || (cblev
== 1 && cplpl
&& structdef
== sinbody
)
2460 || (structdef
== sinbody
&& structtype
== st_C_enum
))
2461 && typdef
!= tignore
2462 && definedef
!= dignorerest
2463 && fvdef
!= finlist
)
2469 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken(*(lp
+ 1)))
2472 * This handles :: in the middle, but not at the
2473 * beginning of an identifier.
2480 bool funorvar
= FALSE
;
2483 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
2484 c_ext
, cblev
, parlev
, &funorvar
))
2487 if (structdef
== sinbody
2488 && definedef
== dnone
2490 /* function or var defined in C++ class body */
2492 int len
= strlen (structtag
) + qlen
+ toklen
;
2493 grow_linebuffer (&token_name
, len
+ 1);
2494 strcpy (token_name
.buffer
, structtag
);
2495 strcat (token_name
.buffer
, qualifier
);
2496 strncat (token_name
.buffer
,
2497 newlb
.buffer
+ tokoff
, toklen
);
2498 token_name
.len
= len
;
2501 else if (objdef
== ocatseen
)
2502 /* Objective C category */
2504 int len
= strlen (objtag
) + 2 + toklen
;
2505 grow_linebuffer (&token_name
, len
+ 1);
2506 strcpy (token_name
.buffer
, objtag
);
2507 strcat (token_name
.buffer
, "(");
2508 strncat (token_name
.buffer
,
2509 newlb
.buffer
+ tokoff
, toklen
);
2510 strcat (token_name
.buffer
, ")");
2511 token_name
.len
= len
;
2514 else if (objdef
== omethodtag
2515 || objdef
== omethodparm
)
2516 /* Objective C method */
2522 grow_linebuffer (&token_name
, toklen
+ 1);
2523 strncpy (token_name
.buffer
,
2524 newlb
.buffer
+ tokoff
, toklen
);
2525 token_name
.buffer
[toklen
] = '\0';
2526 token_name
.len
= toklen
;
2528 tok
.named
= (structdef
== stagseen
2531 && definedef
== dignorerest
));
2533 tok
.lineno
= lineno
;
2534 tok
.linelen
= tokoff
+ toklen
+ 1;
2535 tok
.buffer
= newlb
.buffer
;
2536 tok
.linepos
= newlinepos
;
2539 if (definedef
== dnone
2540 && (fvdef
== fvnameseen
2541 || structdef
== stagseen
2543 || objdef
!= onone
))
2545 if (current_lb_is_new
)
2546 switch_line_buffers ();
2549 make_C_tag (funorvar
);
2553 } /* if (endtoken (c)) */
2554 else if (intoken (c
))
2559 } /* if (midtoken) */
2560 else if (begtoken (c
))
2571 make_C_tag (TRUE
); /* a function */
2578 if (structdef
== stagseen
&& !cjava
)
2584 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
2586 tokoff
= lp
- 1 - newlb
.buffer
;
2591 } /* if (begtoken) */
2592 } /* if must look at token */
2595 /* Detect end of line, colon, comma, semicolon and various braces
2596 after having handled a token.*/
2600 if (definedef
!= dnone
)
2606 make_C_tag (TRUE
); /* an Objective C class */
2610 objdef
= omethodcolon
;
2612 grow_linebuffer (&token_name
, methodlen
+ 1);
2613 strcat (token_name
.buffer
, ":");
2614 token_name
.len
= methodlen
;
2617 if (structdef
== stagseen
)
2618 structdef
= scolonseen
;
2625 make_C_tag (FALSE
); /* a yacc function */
2635 if (definedef
!= dnone
)
2641 make_C_tag (FALSE
); /* a typedef */
2651 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2652 make_C_tag (FALSE
); /* a variable */
2656 /* The following instruction invalidates the token.
2657 Probably the token should be invalidated in all
2658 other cases where some state machine is reset. */
2661 if (structdef
== stagseen
)
2665 if (definedef
!= dnone
)
2671 make_C_tag (TRUE
); /* an Objective C method */
2682 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2683 make_C_tag (FALSE
); /* a variable */
2688 if (structdef
== stagseen
)
2692 if (definedef
!= dnone
)
2694 if (cblev
== 0 && typdef
== tend
)
2697 make_C_tag (FALSE
); /* a typedef */
2707 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2708 make_C_tag (FALSE
); /* a variable */
2713 if (structdef
== stagseen
)
2717 if (definedef
!= dnone
)
2719 if (objdef
== otagseen
&& parlev
== 0)
2720 objdef
= oparenseen
;
2728 if (tok
.valid
&& *lp
!= '*')
2730 /* This handles constructs like:
2731 typedef void OperatorFun (int fun); */
2736 } /* switch (typdef) */
2748 if (definedef
!= dnone
)
2750 if (objdef
== ocatseen
&& parlev
== 1)
2752 make_C_tag (TRUE
); /* an Objective C category */
2764 if (cblev
== 0 && typdef
== tend
)
2767 make_C_tag (FALSE
); /* a typedef */
2770 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
2774 if (definedef
!= dnone
)
2776 if (typdef
== ttypedseen
)
2780 case skeyseen
: /* unnamed struct */
2781 structdef
= sinbody
;
2782 structtag
= "_anonymous_";
2785 case scolonseen
: /* named struct */
2786 structdef
= sinbody
;
2787 make_C_tag (FALSE
); /* a struct */
2793 make_C_tag (TRUE
); /* a function */
2802 make_C_tag (TRUE
); /* an Objective C class */
2807 make_C_tag (TRUE
); /* an Objective C method */
2811 /* Neutralize `extern "C" {' grot. */
2812 if (cblev
== 0 && structdef
== snone
&& typdef
== tnone
)
2819 if (definedef
!= dnone
)
2821 if (fvdef
== fstartlist
)
2822 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2825 if (definedef
!= dnone
)
2827 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2829 cblev
= 0; /* reset curly brace level if first column */
2830 parlev
= 0; /* also reset paren level, just in case... */
2836 if (typdef
== tinbody
)
2838 /* Memory leakage here: the string pointed by structtag is
2839 never released, because I fear to miss something and
2840 break things while freeing the area. The amount of
2841 memory leaked here is the sum of the lengths of the
2843 if (structdef == sinbody)
2844 free (structtag); */
2847 structtag
= "<error>";
2851 if (definedef
!= dnone
)
2860 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2861 make_C_tag (FALSE
); /* a variable */
2869 if (objdef
== oinbody
&& cblev
== 0)
2871 objdef
= omethodsign
;
2875 case '#': case '~': case '&': case '%': case '/': case '|':
2876 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
2877 if (definedef
!= dnone
)
2879 /* These surely cannot follow a function tag. */
2880 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2884 if (objdef
== otagseen
)
2886 make_C_tag (TRUE
); /* an Objective C class */
2889 /* If a macro spans multiple lines don't reset its state. */
2897 } /* while not eof */
2901 * Process either a C++ file or a C file depending on the setting
2905 default_C_entries (inf
)
2908 C_entries (cplusplus
? C_PLPL
: 0, inf
);
2911 /* Always do plain ANSI C. */
2913 plain_C_entries (inf
)
2919 /* Always do C++. */
2921 Cplusplus_entries (inf
)
2924 C_entries (C_PLPL
, inf
);
2927 /* Always do Java. */
2932 C_entries (C_JAVA
, inf
);
2940 C_entries (C_STAR
, inf
);
2943 /* Always do Yacc. */
2948 C_entries (YACC
, inf
);
2951 /* Fortran parsing */
2959 register int len
= 0;
2961 while (*cp
&& lowcase(*cp
) == lowcase(dbp
[len
]))
2963 if (*cp
== '\0' && !intoken(dbp
[len
]))
2974 while (isspace (*dbp
))
2979 while (isspace (*dbp
))
2981 if (strneq (dbp
, "(*)", 3))
2986 if (!isdigit (*dbp
))
2988 --dbp
; /* force failure */
2993 while (isdigit (*dbp
));
3002 while (isspace (*dbp
))
3007 linecharno
= charno
;
3008 charno
+= readline (&lb
, inf
);
3013 while (isspace (*dbp
))
3022 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
3025 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3026 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3030 Fortran_functions (inf
)
3039 linecharno
= charno
;
3040 charno
+= readline (&lb
, inf
);
3043 dbp
++; /* Ratfor escape to fortran */
3044 while (isspace (*dbp
))
3048 switch (lowcase (*dbp
))
3051 if (tail ("integer"))
3059 if (tail ("logical"))
3063 if (tail ("complex") || tail ("character"))
3067 if (tail ("double"))
3069 while (isspace (*dbp
))
3073 if (tail ("precision"))
3079 while (isspace (*dbp
))
3083 switch (lowcase (*dbp
))
3086 if (tail ("function"))
3090 if (tail ("subroutine"))
3098 if (tail ("program"))
3103 if (tail ("procedure"))
3111 * Bob Weiner, Motorola Inc., 4/3/94
3112 * Unix and microcontroller assembly tag handling
3113 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3127 linecharno
= charno
;
3128 charno
+= readline (&lb
, inf
);
3131 /* If first char is alphabetic or one of [_.$], test for colon
3132 following identifier. */
3133 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3135 /* Read past label. */
3137 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3139 if (*cp
== ':' || isspace (*cp
))
3141 /* Found end of label, so copy it and add it to the table. */
3142 pfnote ((CTAGS
) ? savenstr(lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
3143 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3150 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3151 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3154 Perl_functions (inf
)
3165 linecharno
= charno
;
3166 charno
+= readline (&lb
, inf
);
3169 if (*cp
++ == 's' && *cp
++ == 'u' && *cp
++ == 'b' && isspace (*cp
++))
3171 while (*cp
&& isspace (*cp
))
3173 while (*cp
&& ! isspace (*cp
) && *cp
!= '{')
3175 pfnote ((CTAGS
) ? savenstr (lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
3176 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3181 /* Idea by Corny de Souza
3182 * Cobol tag functions
3183 * We could look for anything that could be a paragraph name.
3184 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3187 Cobol_paragraphs (inf
)
3198 linecharno
= charno
;
3199 charno
+= readline (&lb
, inf
);
3203 dbp
= lb
.buffer
+ 8;
3205 /* If eoln, compiler option or comment ignore whole line. */
3206 if (dbp
[-1] != ' ' || !isalnum (dbp
[0]))
3209 for (cp
= dbp
; isalnum (*cp
) || *cp
== '-'; cp
++)
3212 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3213 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3217 /* Added by Mosur Mohan, 4/22/88 */
3218 /* Pascal parsing */
3221 * Locates tags for procedures & functions. Doesn't do any type- or
3222 * var-definitions. It does look for the keyword "extern" or
3223 * "forward" immediately following the procedure statement; if found,
3224 * the tag is skipped.
3227 Pascal_functions (inf
)
3230 struct linebuffer tline
; /* mostly copied from C_entries */
3232 int save_lineno
, save_len
;
3233 char c
, *cp
, *namebuf
;
3235 bool /* each of these flags is TRUE iff: */
3236 incomment
, /* point is inside a comment */
3237 inquote
, /* point is inside '..' string */
3238 get_tagname
, /* point is after PROCEDURE/FUNCTION
3239 keyword, so next item = potential tag */
3240 found_tag
, /* point is after a potential tag */
3241 inparms
, /* point is within parameter-list */
3242 verify_tag
; /* point has passed the parm-list, so the
3243 next token will determine whether this
3244 is a FORWARD/EXTERN to be ignored, or
3245 whether it is a real tag */
3252 initbuffer (&tline
);
3254 incomment
= inquote
= FALSE
;
3255 found_tag
= FALSE
; /* have a proc name; check if extern */
3256 get_tagname
= FALSE
; /* have found "procedure" keyword */
3257 inparms
= FALSE
; /* found '(' after "proc" */
3258 verify_tag
= FALSE
; /* check if "extern" is ahead */
3260 /* long main loop to get next char */
3264 if (c
== '\0') /* if end of line */
3267 linecharno
= charno
;
3268 charno
+= readline (&lb
, inf
);
3272 if (!((found_tag
&& verify_tag
) ||
3274 c
= *dbp
++; /* only if don't need *dbp pointing
3275 to the beginning of the name of
3276 the procedure or function */
3280 if (c
== '}') /* within { } comments */
3282 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
3299 inquote
= TRUE
; /* found first quote */
3301 case '{': /* found open { comment */
3305 if (*dbp
== '*') /* found open (* comment */
3310 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
3313 case ')': /* end of parms list */
3318 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
3325 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
3327 /* check if this is an "extern" declaration */
3330 if (lowcase (*dbp
== 'e'))
3332 if (tail ("extern")) /* superfluous, really! */
3338 else if (lowcase (*dbp
) == 'f')
3340 if (tail ("forward")) /* check for forward reference */
3346 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
3350 pfnote (namebuf
, TRUE
,
3351 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
3355 if (get_tagname
) /* grab name of proc or fn */
3360 /* save all values for later tagging */
3361 grow_linebuffer (&tline
, lb
.len
+ 1);
3362 strcpy (tline
.buffer
, lb
.buffer
);
3363 save_lineno
= lineno
;
3364 save_lcno
= linecharno
;
3366 /* grab block name */
3367 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
3369 namebuf
= (CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
;
3370 dbp
= cp
; /* set dbp to e-o-token */
3371 save_len
= dbp
- lb
.buffer
+ 1;
3372 get_tagname
= FALSE
;
3376 /* and proceed to check for "extern" */
3378 else if (!incomment
&& !inquote
&& !found_tag
)
3380 /* check for proc/fn keywords */
3381 switch (lowcase (c
))
3384 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3388 if (tail ("unction"))
3393 } /* while not eof */
3395 free (tline
.buffer
);
3399 * lisp tag functions
3400 * look for (def or (DEF, quote or QUOTE
3404 register char *strp
;
3406 return ((strp
[1] == 'd' || strp
[1] == 'D')
3407 && (strp
[2] == 'e' || strp
[2] == 'E')
3408 && (strp
[3] == 'f' || strp
[3] == 'F'));
3413 register char *strp
;
3415 return ((*(++strp
) == 'q' || *strp
== 'Q')
3416 && (*(++strp
) == 'u' || *strp
== 'U')
3417 && (*(++strp
) == 'o' || *strp
== 'O')
3418 && (*(++strp
) == 't' || *strp
== 'T')
3419 && (*(++strp
) == 'e' || *strp
== 'E')
3420 && isspace (*(++strp
)));
3428 if (*dbp
== '\'') /* Skip prefix quote */
3430 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
3433 while (isspace (*dbp
))
3436 for (cp
= dbp
/*+1*/;
3437 *cp
!= '\0' && *cp
!= '(' && *cp
!= ' ' && *cp
!= ')';
3443 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3444 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3448 Lisp_functions (inf
)
3457 linecharno
= charno
;
3458 charno
+= readline (&lb
, inf
);
3464 while (!isspace (*dbp
))
3466 while (isspace (*dbp
))
3472 /* Check for (foo::defmumble name-defined ... */
3475 while (*dbp
&& !isspace (*dbp
)
3476 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
3481 while (*dbp
== ':');
3483 if (L_isdef (dbp
- 1))
3485 while (!isspace (*dbp
))
3487 while (isspace (*dbp
))
3498 * Postscript tag functions
3499 * Just look for lines where the first character is '/'
3500 * Richard Mlynarik <mly@adoc.xerox.com>
3503 Postscript_functions (inf
)
3512 linecharno
= charno
;
3513 charno
+= readline (&lb
, inf
);
3519 *cp
!= '\0' && *cp
!= ' ' && *cp
!= '{';
3522 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3523 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3530 * Scheme tag functions
3531 * look for (def... xyzzy
3532 * look for (def... (xyzzy
3533 * look for (def ... ((...(xyzzy ....
3534 * look for (set! xyzzy
3540 Scheme_functions (inf
)
3549 linecharno
= charno
;
3550 charno
+= readline (&lb
, inf
);
3552 if (dbp
[0] == '(' &&
3553 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
3554 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3555 (dbp
[3] == 'F' || dbp
[3] == 'f'))
3557 while (!isspace (*dbp
))
3559 /* Skip over open parens and white space */
3560 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
3564 if (dbp
[0] == '(' &&
3565 (dbp
[1] == 'S' || dbp
[1] == 's') &&
3566 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3567 (dbp
[3] == 'T' || dbp
[3] == 't') &&
3568 (dbp
[4] == '!' || dbp
[4] == '!') &&
3571 while (!isspace (*dbp
))
3573 /* Skip over white space */
3574 while (isspace (*dbp
))
3588 /* Go till you get to white space or a syntactic break */
3590 *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
);
3593 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3594 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3597 /* Find tags in TeX and LaTeX input files. */
3599 /* TEX_toktab is a table of TeX control sequences that define tags.
3600 Each TEX_tabent records one such control sequence.
3601 CONVERT THIS TO USE THE Stab TYPE!! */
3608 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
3610 /* Default set of control sequences to put into TEX_toktab.
3611 The value of environment var TEXTAGS is prepended to this. */
3613 char *TEX_defenv
= "\
3614 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
3615 :part:appendix:entry:index";
3618 struct TEX_tabent
*TEX_decode_env ();
3621 char TEX_esc
= '\\';
3622 char TEX_opgrp
= '{';
3623 char TEX_clgrp
= '}';
3626 * TeX/LaTeX scanning loop.
3638 /* Select either \ or ! as escape character. */
3641 /* Initialize token table once from environment. */
3643 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
3646 { /* Scan each line in file */
3648 linecharno
= charno
;
3649 charno
+= readline (&lb
, inf
);
3652 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
3656 linecharno
+= dbp
- lasthit
;
3658 i
= TEX_Token (lasthit
);
3661 /* We seem to include the TeX command in the tag name.
3663 for (p = lasthit + TEX_toktab[i].len;
3664 *p != '\0' && *p != TEX_clgrp;
3667 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL
, TRUE
,
3668 lb
.buffer
, lb
.len
, lineno
, linecharno
);
3669 break; /* We only tag a line once */
3675 #define TEX_LESC '\\'
3676 #define TEX_SESC '!'
3679 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3680 chars accordingly. */
3687 while ((c
= getc (inf
)) != EOF
)
3689 /* Skip to next line if we hit the TeX comment char. */
3693 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
3712 /* Read environment and prepend it to the default string.
3713 Build token table. */
3715 TEX_decode_env (evarname
, defenv
)
3719 register char *env
, *p
;
3721 struct TEX_tabent
*tab
;
3724 /* Append default string to environment. */
3725 env
= getenv (evarname
);
3731 env
= concat (oldenv
, defenv
, "");
3735 /* Allocate a token table */
3736 for (size
= 1, p
= env
; p
;)
3737 if ((p
= etags_strchr (p
, ':')) && *(++p
))
3739 /* Add 1 to leave room for null terminator. */
3740 tab
= xnew (size
+ 1, struct TEX_tabent
);
3742 /* Unpack environment string into token table. Be careful about */
3743 /* zero-length strings (leading ':', "::" and trailing ':') */
3746 p
= etags_strchr (env
, ':');
3747 if (!p
) /* End of environment string. */
3748 p
= env
+ strlen (env
);
3750 { /* Only non-zero strings. */
3751 tab
[i
].name
= savenstr (env
, p
- env
);
3752 tab
[i
].len
= strlen (tab
[i
].name
);
3759 tab
[i
].name
= NULL
; /* Mark end of table. */
3767 /* If the text at CP matches one of the tag-defining TeX command names,
3768 return the pointer to the first occurrence of that command in TEX_toktab.
3769 Otherwise return -1.
3770 Keep the capital `T' in `Token' for dumb truncating compilers
3771 (this distinguishes it from `TEX_toktab' */
3778 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
3779 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
3785 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
3787 * Assumes that the predicate starts at column 0.
3788 * Only the first clause of a predicate is added.
3791 void prolog_skip_comment ();
3796 Prolog_functions (inf
)
3814 linecharno
+= charno
;
3815 charno
= readline (&lb
, inf
);
3817 if (dbp
[0] == '\0') /* Empty line */
3819 else if (isspace (dbp
[0])) /* Not a predicate */
3821 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
3822 prolog_skip_comment (&lb
, inf
);
3823 else if (len
= prolog_pred (dbp
, last
))
3825 /* Predicate. Store the function name so that we only
3826 generate a tag for the first clause. */
3828 last
= xnew(len
+ 1, char);
3829 else if (len
+ 1 > allocated
)
3830 last
= (char *) xrealloc(last
, len
+ 1);
3831 allocated
= len
+ 1;
3832 strncpy (last
, dbp
, len
);
3840 prolog_skip_comment (plb
, inf
)
3841 struct linebuffer
*plb
;
3848 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
3849 if (cp
[0] == '*' && cp
[1] == '/')
3852 linecharno
+= readline (plb
, inf
);
3858 * A predicate definition is added if it matches:
3859 * <beginning of line><Prolog Atom><whitespace>(
3861 * It is added to the tags database if it doesn't match the
3862 * name of the previous clause header.
3864 * Return the size of the name of the predicate, or 0 if no header
3868 prolog_pred (s
, last
)
3870 char *last
; /* Name of last clause. */
3875 pos
= prolog_atom (s
, 0);
3880 pos
+= eat_white (s
, pos
);
3882 if ((s
[pos
] == '(') || (s
[pos
] == '.'))
3887 /* Save only the first clause. */
3889 || len
!= strlen (last
)
3890 || !strneq (s
, last
, len
))
3892 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
3893 s
, pos
, lineno
, linecharno
);
3901 * Consume a Prolog atom.
3902 * Return the number of bytes consumed, or -1 if there was an error.
3904 * A prolog atom, in this context, could be one of:
3905 * - An alphanumeric sequence, starting with a lower case letter.
3906 * - A quoted arbitrary string. Single quotes can escape themselves.
3907 * Backslash quotes everything.
3910 prolog_atom (s
, pos
)
3918 if (islower(s
[pos
]) || (s
[pos
] == '_'))
3920 /* The atom is unquoted. */
3922 while (isalnum(s
[pos
]) || (s
[pos
] == '_'))
3926 return pos
- origpos
;
3928 else if (s
[pos
] == '\'')
3939 pos
++; /* A double quote */
3941 else if (s
[pos
] == '\0')
3942 /* Multiline quoted atoms are ignored. */
3944 else if (s
[pos
] == '\\')
3946 if (s
[pos
+1] == '\0')
3953 return pos
- origpos
;
3959 /* Consume whitespace. Return the number of bytes eaten. */
3969 while (isspace (s
[pos
]))
3972 return pos
- origpos
;
3976 * Support for Erlang -- Anders Lindgren, Feb 1996.
3978 * Generates tags for functions, defines, and records.
3980 * Assumes that Erlang functions start at column 0.
3983 void erlang_attribute ();
3987 Erlang_functions (inf
)
4005 linecharno
+= charno
;
4006 charno
= readline (&lb
, inf
);
4008 if (dbp
[0] == '\0') /* Empty line */
4010 else if (isspace (dbp
[0])) /* Not function nor attribute */
4012 else if (dbp
[0] == '%') /* comment */
4014 else if (dbp
[0] == '"') /* Sometimes, strings start in column one */
4016 else if (dbp
[0] == '-') /* attribute, e.g. "-define" */
4018 erlang_attribute (dbp
);
4021 else if (len
= erlang_func (dbp
, last
))
4024 * Function. Store the function name so that we only
4025 * generates a tag for the first clause.
4028 last
= xnew (len
+ 1, char);
4029 else if (len
+ 1 > allocated
)
4030 last
= (char *) xrealloc (last
, len
+ 1);
4031 allocated
= len
+ 1;
4032 strncpy (last
, dbp
, len
);
4040 * A function definition is added if it matches:
4041 * <beginning of line><Erlang Atom><whitespace>(
4043 * It is added to the tags database if it doesn't match the
4044 * name of the previous clause header.
4046 * Return the size of the name of the function, or 0 if no function
4050 erlang_func (s
, last
)
4052 char *last
; /* Name of last clause. */
4057 pos
= erlang_atom (s
, 0);
4062 pos
+= eat_white (s
, pos
);
4064 /* Save only the first clause. */
4067 || len
!= strlen (last
)
4068 || !strneq (s
, last
, len
)))
4070 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
4071 s
, pos
, lineno
, linecharno
);
4080 * Handle attributes. Currently, tags are generated for defines
4083 * They are on the form:
4084 * -define(foo, bar).
4085 * -define(Foo(M, N), M+N).
4086 * -record(graph, {vtab = notable, cyclic = true}).
4089 erlang_attribute (s
)
4095 if (strneq (s
, "-define", 7) || strneq (s
, "-record", 7))
4097 pos
= 7 + eat_white (s
, pos
);
4098 if (s
[pos
++] == '(')
4100 pos
+= eat_white (s
, pos
);
4101 if (len
= erlang_atom (s
, pos
))
4102 pfnote ((CTAGS
) ? savenstr (& s
[pos
], len
) : NULL
, TRUE
,
4103 s
, pos
+ len
, lineno
, linecharno
);
4111 * Consume an Erlang atom (or variable).
4112 * Return the number of bytes consumed, or -1 if there was an error.
4115 erlang_atom (s
, pos
)
4123 if (isalpha (s
[pos
]) || s
[pos
] == '_')
4125 /* The atom is unquoted. */
4127 while (isalnum (s
[pos
]) || s
[pos
] == '_')
4129 return pos
- origpos
;
4131 else if (s
[pos
] == '\'')
4142 else if (s
[pos
] == '\0')
4143 /* Multiline quoted atoms are ignored. */
4145 else if (s
[pos
] == '\\')
4147 if (s
[pos
+1] == '\0')
4154 return pos
- origpos
;
4160 #ifdef ETAGS_REGEXPS
4161 /* Take a string like "/blah/" and turn it into "blah", making sure
4162 that the first and last characters are the same, and handling
4163 quoted separator characters. Actually, stops on the occurrence of
4164 an unquoted separator. Also turns "\t" into a Tab character.
4165 Returns pointer to terminating separator. Works in place. Null
4166 terminates name string. */
4168 scan_separators (name
)
4172 char *copyto
= name
;
4173 bool quoted
= FALSE
;
4175 for (++name
; *name
!= '\0'; ++name
)
4181 else if (*name
== sep
)
4185 /* Something else is quoted, so preserve the quote. */
4191 else if (*name
== '\\')
4193 else if (*name
== sep
)
4199 /* Terminate copied string. */
4204 /* Look at the argument of --regex or --no-regex and do the right
4207 analyse_regex (regex_arg
)
4210 struct stat stat_buf
;
4212 if (regex_arg
== NULL
)
4214 /* Remove existing regexps. */
4219 if (regex_arg
[0] == '\0')
4221 error ("missing regexp", (char *)NULL
);
4224 if (regex_arg
[0] == '@'
4225 && stat (regex_arg
+ 1, &stat_buf
) == 0)
4228 struct linebuffer regexbuf
;
4229 char *regexfile
= regex_arg
+ 1;
4231 /* regexfile is a file containing regexps, one per line. */
4232 regexfp
= fopen (regexfile
, "r");
4233 if (regexfp
== NULL
)
4238 initbuffer (®exbuf
);
4239 while (readline_internal (®exbuf
, regexfp
))
4240 add_regex (regexbuf
.buffer
);
4241 free (regexbuf
.buffer
);
4246 add_regex (regex_arg
);
4250 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4251 expression, into a real regular expression by compiling it. */
4253 add_regex (regexp_pattern
)
4254 char *regexp_pattern
;
4258 struct re_pattern_buffer
*patbuf
;
4261 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
4263 error ("%s: unterminated regexp", regexp_pattern
);
4266 name
= scan_separators (regexp_pattern
);
4267 if (regexp_pattern
[0] == '\0')
4269 error ("null regexp", (char *)NULL
);
4272 (void) scan_separators (name
);
4274 patbuf
= xnew (1, struct re_pattern_buffer
);
4275 patbuf
->translate
= NULL
;
4276 patbuf
->fastmap
= NULL
;
4277 patbuf
->buffer
= NULL
;
4278 patbuf
->allocated
= 0;
4280 re_syntax_options
= RE_INTERVALS
;
4281 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
4284 error ("%s while compiling pattern", err
);
4289 if (num_patterns
== 1)
4290 patterns
= xnew (1, struct pattern
);
4292 patterns
= ((struct pattern
*)
4294 (num_patterns
* sizeof (struct pattern
))));
4295 patterns
[num_patterns
- 1].pattern
= patbuf
;
4296 patterns
[num_patterns
- 1].name_pattern
= savestr (name
);
4297 patterns
[num_patterns
- 1].error_signaled
= FALSE
;
4301 * Do the substitutions indicated by the regular expression and
4305 substitute (in
, out
, regs
)
4307 struct re_registers
*regs
;
4310 int size
, dig
, diglen
;
4313 size
= strlen (out
);
4315 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4316 if (out
[size
- 1] == '\\')
4317 fatal ("pattern error in \"%s\"", out
);
4318 for (t
= etags_strchr (out
, '\\');
4320 t
= etags_strchr (t
+ 2, '\\'))
4324 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
4330 /* Allocate space and do the substitutions. */
4331 result
= xnew (size
+ 1, char);
4333 for (t
= result
; *out
!= '\0'; out
++)
4334 if (*out
== '\\' && isdigit (*++out
))
4336 /* Using "dig2" satisfies my debugger. Bleah. */
4338 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
4339 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
4346 if (DEBUG
&& (t
> result
+ size
|| t
- result
!= strlen (result
)))
4352 #endif /* ETAGS_REGEXPS */
4353 /* Initialize a linebuffer for use */
4355 initbuffer (linebuffer
)
4356 struct linebuffer
*linebuffer
;
4358 linebuffer
->size
= 200;
4359 linebuffer
->buffer
= xnew (200, char);
4363 * Read a line of text from `stream' into `linebuffer'.
4364 * Return the number of characters read from `stream',
4365 * which is the length of the line including the newline, if any.
4368 readline_internal (linebuffer
, stream
)
4369 struct linebuffer
*linebuffer
;
4370 register FILE *stream
;
4372 char *buffer
= linebuffer
->buffer
;
4373 register char *p
= linebuffer
->buffer
;
4374 register char *pend
;
4377 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
4381 register int c
= getc (stream
);
4384 linebuffer
->size
*= 2;
4385 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
4386 p
+= buffer
- linebuffer
->buffer
;
4387 pend
= buffer
+ linebuffer
->size
;
4388 linebuffer
->buffer
= buffer
;
4398 if (p
> buffer
&& p
[-1] == '\r')
4402 /* Assume CRLF->LF translation will be performed by Emacs
4403 when loading this file, so CRs won't appear in the buffer.
4404 It would be cleaner to compensate within Emacs;
4405 however, Emacs does not know how many CRs were deleted
4406 before any given point in the file. */
4421 linebuffer
->len
= p
- buffer
;
4423 return linebuffer
->len
+ chars_deleted
;
4427 * Like readline_internal, above, but in addition try to match the
4428 * input line against any existing regular expressions.
4431 readline (linebuffer
, stream
)
4432 struct linebuffer
*linebuffer
;
4435 /* Read new line. */
4436 long result
= readline_internal (linebuffer
, stream
);
4437 #ifdef ETAGS_REGEXPS
4440 /* Match against all listed patterns. */
4441 if (linebuffer
->len
> 0)
4442 for (i
= 0; i
< num_patterns
; ++i
)
4444 int match
= re_match (patterns
[i
].pattern
, linebuffer
->buffer
,
4445 linebuffer
->len
, 0, &patterns
[i
].regs
);
4450 if (!patterns
[i
].error_signaled
)
4452 error ("error while matching pattern %d", i
);
4453 patterns
[i
].error_signaled
= TRUE
;
4460 /* Match occurred. Construct a tag. */
4461 if (patterns
[i
].name_pattern
[0] != '\0')
4463 /* Make a named tag. */
4464 char *name
= substitute (linebuffer
->buffer
,
4465 patterns
[i
].name_pattern
,
4469 linebuffer
->buffer
, match
, lineno
, linecharno
);
4473 /* Make an unnamed tag. */
4474 pfnote ((char *)NULL
, TRUE
,
4475 linebuffer
->buffer
, match
, lineno
, linecharno
);
4480 #endif /* ETAGS_REGEXPS */
4486 * Read a file, but do no processing. This is used to do regexp
4487 * matching on files that have no language defined.
4490 just_read_file (inf
)
4499 linecharno
= charno
;
4500 charno
+= readline (&lb
, inf
);
4506 * Return a pointer to a space of size strlen(cp)+1 allocated
4507 * with xnew where the string CP has been copied.
4513 return savenstr (cp
, strlen (cp
));
4517 * Return a pointer to a space of size LEN+1 allocated with xnew where
4518 * the string CP has been copied for at most the first LEN characters.
4527 dp
= xnew (len
+ 1, char);
4528 strncpy (dp
, cp
, len
);
4534 * Return the ptr in sp at which the character c last
4535 * appears; NULL if not found
4537 * Identical to System V strrchr, included for portability.
4540 etags_strrchr (sp
, c
)
4541 register char *sp
, c
;
4556 * Return the ptr in sp at which the character c first
4557 * appears; NULL if not found
4559 * Identical to System V strchr, included for portability.
4562 etags_strchr (sp
, c
)
4563 register char *sp
, c
;
4573 /* Print error message and exit. */
4591 suggest_asking_for_help ()
4593 fprintf (stderr
, "\tTry `%s --help' for a complete list of options.\n",
4598 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
4603 fprintf (stderr
, "%s: ", progname
);
4604 fprintf (stderr
, s1
, s2
);
4605 fprintf (stderr
, "\n");
4608 /* Return a newly-allocated string whose contents
4609 concatenate those of s1, s2, s3. */
4614 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
4615 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
4617 strcpy (result
, s1
);
4618 strcpy (result
+ len1
, s2
);
4619 strcpy (result
+ len1
+ len2
, s3
);
4620 result
[len1
+ len2
+ len3
] = '\0';
4625 /* Does the same work as the system V getcwd, but does not need to
4626 guess the buffer size in advance. */
4632 char *path
= xnew (bufsize
, char);
4634 while (getcwd (path
, bufsize
) == NULL
)
4636 if (errno
!= ERANGE
)
4640 path
= xnew (bufsize
, char);
4645 /* Convert backslashes to slashes. */
4647 for (p
= path
; *p
!= '\0'; p
++)
4655 #else /* not HAVE_GETCWD */
4657 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
4661 for (p
= path
; *p
!= '\0'; p
++)
4667 return strdup (path
);
4668 #else /* not MSDOS */
4669 struct linebuffer path
;
4673 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
4674 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
4679 #endif /* not MSDOS */
4680 #endif /* not HAVE_GETCWD */
4683 /* Return a newly allocated string containing the file name
4684 of FILE relative to the absolute directory DIR (which
4685 should end with a slash). */
4687 relative_filename (file
, dir
)
4690 char *fp
, *dp
, *abs
, *res
;
4693 /* Find the common root of file and dir (with a trailing slash). */
4694 abs
= absolute_filename (file
, cwd
);
4697 while (*fp
++ == *dp
++)
4699 fp
--, dp
--; /* back to the first differing char */
4700 do /* look at the equal chars until '/' */
4704 /* Build a sequence of "../" strings for the resulting relative file name. */
4706 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
4708 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
4711 strcat (res
, "../");
4713 /* Add the file name relative to the common root of file and dir. */
4714 strcat (res
, fp
+ 1);
4720 /* Return a newly allocated string containing the
4721 absolute file name of FILE given CWD (which should
4722 end with a slash). */
4724 absolute_filename (file
, cwd
)
4727 char *slashp
, *cp
, *res
;
4729 if (absolutefn (file
))
4730 res
= savestr (file
);
4732 /* We don't support non-absolute file names with a drive
4733 letter, like `d:NAME' (it's too much hassle). */
4734 else if (file
[1] == ':')
4735 fatal ("%s: relative file names with drive letters not supported", file
);
4738 res
= concat (cwd
, file
, "");
4740 /* Delete the "/dirname/.." and "/." substrings. */
4741 slashp
= etags_strchr (res
, '/');
4742 while (slashp
!= NULL
&& slashp
[0] != '\0')
4744 if (slashp
[1] == '.')
4746 if (slashp
[2] == '.'
4747 && (slashp
[3] == '/' || slashp
[3] == '\0'))
4752 while (cp
>= res
&& !absolutefn (cp
));
4754 cp
= slashp
; /* the absolute name begins with "/.." */
4756 /* Under MSDOS and NT we get `d:/NAME' as absolute
4757 file name, so the luser could say `d:/../NAME'.
4758 We silently treat this as `d:/NAME'. */
4759 else if (cp
[0] != '/')
4762 strcpy (cp
, slashp
+ 3);
4766 else if (slashp
[2] == '/' || slashp
[2] == '\0')
4768 strcpy (slashp
, slashp
+ 2);
4773 slashp
= etags_strchr (slashp
+ 1, '/');
4777 return savestr ("/");
4782 /* Return a newly allocated string containing the absolute
4783 file name of dir where FILE resides given CWD (which should
4784 end with a slash). */
4786 absolute_dirname (file
, cwd
)
4794 for (p
= file
; *p
!= '\0'; p
++)
4799 slashp
= etags_strrchr (file
, '/');
4801 return savestr (cwd
);
4804 res
= absolute_filename (file
, cwd
);
4810 /* Increase the size of a linebuffer. */
4812 grow_linebuffer (bufp
, toksize
)
4813 struct linebuffer
*bufp
;
4816 while (bufp
->size
< toksize
)
4818 bufp
->buffer
= (char *) xrealloc (bufp
->buffer
, bufp
->size
);
4821 /* Like malloc but get fatal error if memory is exhausted. */
4826 long *result
= (long *) malloc (size
);
4828 fatal ("virtual memory exhausted", (char *)NULL
);
4833 xrealloc (ptr
, size
)
4837 long *result
= (long *) realloc (ptr
, size
);
4839 fatal ("virtual memory exhausted", (char *)NULL
);