1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
3 Copyright (C) 1984 The Regents of the University of California
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the
14 3. Neither the name of the University nor the names of its
15 contributors may be used to endorse or promote products derived
16 from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 Copyright (C) 1984, 1987, 1988, 1989, 1993, 1994, 1995, 1998, 1999,
32 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
33 Free Software Foundation, Inc.
35 This file is not considered part of GNU Emacs.
37 This program is free software; you can redistribute it and/or modify
38 it under the terms of the GNU General Public License as published by
39 the Free Software Foundation; either version 2 of the License, or
40 (at your option) any later version.
42 This program is distributed in the hope that it will be useful,
43 but WITHOUT ANY WARRANTY; without even the implied warranty of
44 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 GNU General Public License for more details.
47 You should have received a copy of the GNU General Public License
48 along with this program; if not, write to the Free Software Foundation,
49 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
52 /* NB To comply with the above BSD license, copyright information is
53 reproduced in etc/ETAGS.README. That file should be updated when the
56 To the best of our knowledge, this code was originally based on the
57 ctags.c distributed with BSD4.2, which was copyrighted by the
58 University of California, as described above. */
63 * 1983 Ctags originally by Ken Arnold.
64 * 1984 Fortran added by Jim Kleckner.
65 * 1984 Ed Pelegri-Llopart added C typedefs.
66 * 1985 Emacs TAGS format by Richard Stallman.
67 * 1989 Sam Kendall added C++.
68 * 1992 Joseph B. Wells improved C and C++ parsing.
69 * 1993 Francesco Potortì reorganised C and C++.
70 * 1994 Line-by-line regexp tags by Tom Tromey.
71 * 2001 Nested classes by Francesco Potortì (concept by Mykola Dzyuba).
72 * 2002 #line directives by Francesco Potortì.
74 * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
78 * If you want to add support for a new language, start by looking at the LUA
79 * language, which is the simplest. Alternatively, consider shipping a
80 * configuration file containing regexp definitions for etags.
83 char pot_etags_version[] = "@(#) pot revision number is 17.33";
93 # define NDEBUG /* disable assert */
98 /* On some systems, Emacs defines static as nothing for the sake
99 of unexec. We don't want that here since we don't use unexec. */
101 # ifndef PTR /* for XEmacs */
104 # ifndef __P /* for XEmacs */
105 # define __P(args) args
107 #else /* no config.h */
108 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
109 # define __P(args) args /* use prototypes */
110 # define PTR void * /* for generic pointers */
111 # else /* not standard C */
112 # define __P(args) () /* no prototypes */
113 # define const /* remove const for old compilers' sake */
114 # define PTR long * /* don't use void* */
116 #endif /* !HAVE_CONFIG_H */
119 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
122 /* WIN32_NATIVE is for XEmacs.
123 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
128 #endif /* WIN32_NATIVE */
134 # include <sys/param.h>
136 # ifndef HAVE_CONFIG_H
138 # include <sys/config.h>
150 # define MAXPATHLEN _MAX_PATH
156 # endif /* undef HAVE_GETCWD */
157 #else /* not WINDOWSNT */
161 # else /* no standard C headers */
162 extern char *getenv ();
163 extern char *strcpy ();
164 extern char *strncpy ();
165 extern char *strcat ();
166 extern char *strncat ();
167 extern unsigned long strlen ();
168 extern PTR malloc ();
169 extern PTR realloc ();
171 # define EXIT_SUCCESS 1
172 # define EXIT_FAILURE 0
174 # define EXIT_SUCCESS 0
175 # define EXIT_FAILURE 1
178 #endif /* !WINDOWSNT */
183 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
184 extern char *getcwd (char *buf, size_t size);
186 #endif /* HAVE_UNISTD_H */
194 #include <sys/types.h>
195 #include <sys/stat.h>
199 # undef assert /* some systems have a buggy assert.h */
200 # define assert(x) ((void) 0)
203 #if !defined (S_ISREG) && defined (S_IFREG)
204 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
207 #ifdef NO_LONG_OPTIONS /* define this if you don't have GNU getopt */
208 # define NO_LONG_OPTIONS TRUE
209 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
211 extern int optind, opterr;
213 # define NO_LONG_OPTIONS FALSE
215 #endif /* NO_LONG_OPTIONS */
217 #ifndef HAVE_CONFIG_H /* this is a standalone compilation */
218 # ifdef __CYGWIN__ /* compiling on Cygwin */
220 the regex.h distributed with Cygwin is not compatible with etags, alas!
221 If you want regular expression support, you should delete this notice and
222 arrange to use the GNU regex.h and regex.c.
227 /* Define CTAGS to make the program "ctags" compatible with the usual one.
228 Leave it undefined to make the program "etags", which makes emacs-style
229 tag tables and tags typedefs, #defines and struct/union/enum by default. */
237 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
238 #define strcaseeq(s,t) (assert((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t))
239 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
240 #define strncaseeq(s,t,n) (assert((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n))
242 #define CHARS 256 /* 2^sizeof(char) */
243 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
244 #define iswhite(c) (_wht[CHAR(c)]) /* c is white (see white) */
245 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name (see nonam) */
246 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token (see begtk) */
247 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token (see midtk) */
248 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens (see endtk) */
250 #define ISALNUM(c) isalnum (CHAR(c))
251 #define ISALPHA(c) isalpha (CHAR(c))
252 #define ISDIGIT(c) isdigit (CHAR(c))
253 #define ISLOWER(c) islower (CHAR(c))
255 #define lowcase(c) tolower (CHAR(c))
256 #define upcase(c) toupper (CHAR(c))
260 * xnew, xrnew -- allocate, reallocate storage
262 * SYNOPSIS: Type *xnew (int n, Type);
263 * void xrnew (OldPointer, int n, Type);
266 # include "chkmalloc.h"
267 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
268 (n) * sizeof (Type)))
269 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
270 (char *) (op), (n) * sizeof (Type)))
272 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
273 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
274 (char *) (op), (n) * sizeof (Type)))
279 typedef void Lang_function __P((FILE *));
283 char *suffix; /* file name suffix for this compressor */
284 char *command; /* takes one arg and decompresses to stdout */
289 char *name; /* language name */
290 char *help; /* detailed help for the language */
291 Lang_function *function; /* parse function */
292 char **suffixes; /* name suffixes of this language's files */
293 char **filenames; /* names of this language's files */
294 char **interpreters; /* interpreters for this language */
295 bool metasource; /* source used to generate other sources */
300 struct fdesc *next; /* for the linked list */
301 char *infname; /* uncompressed input file name */
302 char *infabsname; /* absolute uncompressed input file name */
303 char *infabsdir; /* absolute dir of input file */
304 char *taggedfname; /* file name to write in tagfile */
305 language *lang; /* language of file */
306 char *prop; /* file properties to write in tagfile */
307 bool usecharno; /* etags tags shall contain char number */
308 bool written; /* entry written in the tags file */
311 typedef struct node_st
312 { /* sorting structure */
313 struct node_st *left, *right; /* left and right sons */
314 fdesc *fdp; /* description of file to whom tag belongs */
315 char *name; /* tag name */
316 char *regex; /* search regexp */
317 bool valid; /* write this tag on the tag file */
318 bool is_func; /* function tag: use regexp in CTAGS mode */
319 bool been_warned; /* warning already given for duplicated tag */
320 int lno; /* line number tag is on */
321 long cno; /* character number line starts on */
325 * A `linebuffer' is a structure which holds a line of text.
326 * `readline_internal' reads a line from a stream into a linebuffer
327 * and works regardless of the length of the line.
328 * SIZE is the size of BUFFER, LEN is the length of the string in
329 * BUFFER after readline reads it.
338 /* Used to support mixing of --lang and file names. */
342 at_language, /* a language specification */
343 at_regexp, /* a regular expression */
344 at_filename, /* a file name */
345 at_stdin, /* read from stdin here */
346 at_end /* stop parsing the list */
347 } arg_type; /* argument type */
348 language *lang; /* language associated with the argument */
349 char *what; /* the argument itself */
352 /* Structure defining a regular expression. */
353 typedef struct regexp
355 struct regexp *p_next; /* pointer to next in list */
356 language *lang; /* if set, use only for this language */
357 char *pattern; /* the regexp pattern */
358 char *name; /* tag name */
359 struct re_pattern_buffer *pat; /* the compiled pattern */
360 struct re_registers regs; /* re registers */
361 bool error_signaled; /* already signaled for this regexp */
362 bool force_explicit_name; /* do not allow implict tag name */
363 bool ignore_case; /* ignore case when matching */
364 bool multi_line; /* do a multi-line match on the whole file */
368 /* Many compilers barf on this:
369 Lang_function Ada_funcs;
370 so let's write it this way */
371 static void Ada_funcs __P((FILE *));
372 static void Asm_labels __P((FILE *));
373 static void C_entries __P((int c_ext, FILE *));
374 static void default_C_entries __P((FILE *));
375 static void plain_C_entries __P((FILE *));
376 static void Cjava_entries __P((FILE *));
377 static void Cobol_paragraphs __P((FILE *));
378 static void Cplusplus_entries __P((FILE *));
379 static void Cstar_entries __P((FILE *));
380 static void Erlang_functions __P((FILE *));
381 static void Forth_words __P((FILE *));
382 static void Fortran_functions __P((FILE *));
383 static void HTML_labels __P((FILE *));
384 static void Lisp_functions __P((FILE *));
385 static void Lua_functions __P((FILE *));
386 static void Makefile_targets __P((FILE *));
387 static void Pascal_functions __P((FILE *));
388 static void Perl_functions __P((FILE *));
389 static void PHP_functions __P((FILE *));
390 static void PS_functions __P((FILE *));
391 static void Prolog_functions __P((FILE *));
392 static void Python_functions __P((FILE *));
393 static void Scheme_functions __P((FILE *));
394 static void TeX_commands __P((FILE *));
395 static void Texinfo_nodes __P((FILE *));
396 static void Yacc_entries __P((FILE *));
397 static void just_read_file __P((FILE *));
399 static void print_language_names __P((void));
400 static void print_version __P((void));
401 static void print_help __P((argument *));
402 int main __P((int, char **));
404 static compressor *get_compressor_from_suffix __P((char *, char **));
405 static language *get_language_from_langname __P((const char *));
406 static language *get_language_from_interpreter __P((char *));
407 static language *get_language_from_filename __P((char *, bool));
408 static void readline __P((linebuffer *, FILE *));
409 static long readline_internal __P((linebuffer *, FILE *));
410 static bool nocase_tail __P((char *));
411 static void get_tag __P((char *, char **));
413 static void analyse_regex __P((char *));
414 static void free_regexps __P((void));
415 static void regex_tag_multiline __P((void));
416 static void error __P((const char *, const char *));
417 static void suggest_asking_for_help __P((void));
418 void fatal __P((char *, char *));
419 static void pfatal __P((char *));
420 static void add_node __P((node *, node **));
422 static void init __P((void));
423 static void process_file_name __P((char *, language *));
424 static void process_file __P((FILE *, char *, language *));
425 static void find_entries __P((FILE *));
426 static void free_tree __P((node *));
427 static void free_fdesc __P((fdesc *));
428 static void pfnote __P((char *, bool, char *, int, int, long));
429 static void make_tag __P((char *, int, bool, char *, int, int, long));
430 static void invalidate_nodes __P((fdesc *, node **));
431 static void put_entries __P((node *));
433 static char *concat __P((char *, char *, char *));
434 static char *skip_spaces __P((char *));
435 static char *skip_non_spaces __P((char *));
436 static char *savenstr __P((char *, int));
437 static char *savestr __P((char *));
438 static char *etags_strchr __P((const char *, int));
439 static char *etags_strrchr __P((const char *, int));
440 static int etags_strcasecmp __P((const char *, const char *));
441 static int etags_strncasecmp __P((const char *, const char *, int));
442 static char *etags_getcwd __P((void));
443 static char *relative_filename __P((char *, char *));
444 static char *absolute_filename __P((char *, char *));
445 static char *absolute_dirname __P((char *, char *));
446 static bool filename_is_absolute __P((char *f));
447 static void canonicalize_filename __P((char *));
448 static void linebuffer_init __P((linebuffer *));
449 static void linebuffer_setlen __P((linebuffer *, int));
450 static PTR xmalloc __P((unsigned int));
451 static PTR xrealloc __P((char *, unsigned int));
454 static char searchar = '/'; /* use /.../ searches */
456 static char *tagfile; /* output file */
457 static char *progname; /* name this program was invoked with */
458 static char *cwd; /* current working directory */
459 static char *tagfiledir; /* directory of tagfile */
460 static FILE *tagf; /* ioptr for tags file */
462 static fdesc *fdhead; /* head of file description list */
463 static fdesc *curfdp; /* current file description */
464 static int lineno; /* line number of current line */
465 static long charno; /* current character number */
466 static long linecharno; /* charno of start of current line */
467 static char *dbp; /* pointer to start of current tag */
469 static const int invalidcharno = -1;
471 static node *nodehead; /* the head of the binary tree of tags */
472 static node *last_node; /* the last node created */
474 static linebuffer lb; /* the current line */
475 static linebuffer filebuf; /* a buffer containing the whole file */
476 static linebuffer token_name; /* a buffer containing a tag name */
478 /* boolean "functions" (see init) */
479 static bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
482 *white = " \f\t\n\r\v",
484 *nonam = " \f\t\n\r()=,;", /* look at make_tag before modifying! */
485 /* token ending chars */
486 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
487 /* token starting chars */
488 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
489 /* valid in-token chars */
490 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
492 static bool append_to_tagfile; /* -a: append to tags */
493 /* The next five default to TRUE for etags, but to FALSE for ctags. */
494 static bool typedefs; /* -t: create tags for C and Ada typedefs */
495 static bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
496 /* 0 struct/enum/union decls, and C++ */
497 /* member functions. */
498 static bool constantypedefs; /* -d: create tags for C #define, enum */
499 /* constants and variables. */
500 /* -D: opposite of -d. Default under ctags. */
501 static bool globals; /* create tags for global variables */
502 static bool members; /* create tags for C member variables */
503 static bool declarations; /* --declarations: tag them and extern in C&Co*/
504 static bool no_line_directive; /* ignore #line directives (undocumented) */
505 static bool no_duplicates; /* no duplicate tags for ctags (undocumented) */
506 static bool update; /* -u: update tags */
507 static bool vgrind_style; /* -v: create vgrind style index output */
508 static bool no_warnings; /* -w: suppress warnings (undocumented) */
509 static bool cxref_style; /* -x: create cxref style output */
510 static bool cplusplus; /* .[hc] means C++, not C */
511 static bool ignoreindent; /* -I: ignore indentation in C */
512 static bool packages_only; /* --packages-only: in Ada, only tag packages*/
514 /* STDIN is defined in LynxOS system headers */
519 #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
520 static bool parsing_stdin; /* --parse-stdin used */
522 static regexp *p_head; /* list of all regexps */
523 static bool need_filebuf; /* some regexes are multi-line */
525 static struct option longopts[] =
527 { "append", no_argument, NULL, 'a' },
528 { "packages-only", no_argument, &packages_only, TRUE },
529 { "c++", no_argument, NULL, 'C' },
530 { "declarations", no_argument, &declarations, TRUE },
531 { "no-line-directive", no_argument, &no_line_directive, TRUE },
532 { "no-duplicates", no_argument, &no_duplicates, TRUE },
533 { "help", no_argument, NULL, 'h' },
534 { "help", no_argument, NULL, 'H' },
535 { "ignore-indentation", no_argument, NULL, 'I' },
536 { "language", required_argument, NULL, 'l' },
537 { "members", no_argument, &members, TRUE },
538 { "no-members", no_argument, &members, FALSE },
539 { "output", required_argument, NULL, 'o' },
540 { "regex", required_argument, NULL, 'r' },
541 { "no-regex", no_argument, NULL, 'R' },
542 { "ignore-case-regex", required_argument, NULL, 'c' },
543 { "parse-stdin", required_argument, NULL, STDIN },
544 { "version", no_argument, NULL, 'V' },
546 #if CTAGS /* Ctags options */
547 { "backward-search", no_argument, NULL, 'B' },
548 { "cxref", no_argument, NULL, 'x' },
549 { "defines", no_argument, NULL, 'd' },
550 { "globals", no_argument, &globals, TRUE },
551 { "typedefs", no_argument, NULL, 't' },
552 { "typedefs-and-c++", no_argument, NULL, 'T' },
553 { "update", no_argument, NULL, 'u' },
554 { "vgrind", no_argument, NULL, 'v' },
555 { "no-warn", no_argument, NULL, 'w' },
557 #else /* Etags options */
558 { "no-defines", no_argument, NULL, 'D' },
559 { "no-globals", no_argument, &globals, FALSE },
560 { "include", required_argument, NULL, 'i' },
565 static compressor compressors[] =
567 { "z", "gzip -d -c"},
568 { "Z", "gzip -d -c"},
569 { "gz", "gzip -d -c"},
570 { "GZ", "gzip -d -c"},
571 { "bz2", "bzip2 -d -c" },
580 static char *Ada_suffixes [] =
581 { "ads", "adb", "ada", NULL };
582 static char Ada_help [] =
583 "In Ada code, functions, procedures, packages, tasks and types are\n\
584 tags. Use the `--packages-only' option to create tags for\n\
586 Ada tag names have suffixes indicating the type of entity:\n\
587 Entity type: Qualifier:\n\
588 ------------ ----------\n\
595 Thus, `M-x find-tag <RET> bidule/b <RET>' will go directly to the\n\
596 body of the package `bidule', while `M-x find-tag <RET> bidule <RET>'\n\
597 will just search for any tag `bidule'.";
600 static char *Asm_suffixes [] =
601 { "a", /* Unix assembler */
602 "asm", /* Microcontroller assembly */
603 "def", /* BSO/Tasking definition includes */
604 "inc", /* Microcontroller include files */
605 "ins", /* Microcontroller include files */
606 "s", "sa", /* Unix assembler */
607 "S", /* cpp-processed Unix assembler */
608 "src", /* BSO/Tasking C compiler output */
611 static char Asm_help [] =
612 "In assembler code, labels appearing at the beginning of a line,\n\
613 followed by a colon, are tags.";
616 /* Note that .c and .h can be considered C++, if the --c++ flag was
617 given, or if the `class' or `template' keyowrds are met inside the file.
618 That is why default_C_entries is called for these. */
619 static char *default_C_suffixes [] =
621 static char default_C_help [] =
622 "In C code, any C function or typedef is a tag, and so are\n\
623 definitions of `struct', `union' and `enum'. `#define' macro\n\
624 definitions and `enum' constants are tags unless you specify\n\
625 `--no-defines'. Global variables are tags unless you specify\n\
626 `--no-globals' and so are struct members unless you specify\n\
627 `--no-members'. Use of `--no-globals', `--no-defines' and\n\
628 `--no-members' can make the tags table file much smaller.\n\
629 You can tag function declarations and external variables by\n\
630 using `--declarations'.";
632 static char *Cplusplus_suffixes [] =
633 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
634 "M", /* Objective C++ */
635 "pdb", /* Postscript with C syntax */
637 static char Cplusplus_help [] =
638 "In C++ code, all the tag constructs of C code are tagged. (Use\n\
639 --help --lang=c --lang=c++ for full help.)\n\
640 In addition to C tags, member functions are also recognized. Member\n\
641 variables are recognized unless you use the `--no-members' option.\n\
642 Tags for variables and functions in classes are named `CLASS::VARIABLE'\n\
643 and `CLASS::FUNCTION'. `operator' definitions have tag names like\n\
646 static char *Cjava_suffixes [] =
648 static char Cjava_help [] =
649 "In Java code, all the tags constructs of C and C++ code are\n\
650 tagged. (Use --help --lang=c --lang=c++ --lang=java for full help.)";
653 static char *Cobol_suffixes [] =
654 { "COB", "cob", NULL };
655 static char Cobol_help [] =
656 "In Cobol code, tags are paragraph names; that is, any word\n\
657 starting in column 8 and followed by a period.";
659 static char *Cstar_suffixes [] =
660 { "cs", "hs", NULL };
662 static char *Erlang_suffixes [] =
663 { "erl", "hrl", NULL };
664 static char Erlang_help [] =
665 "In Erlang code, the tags are the functions, records and macros\n\
666 defined in the file.";
668 char *Forth_suffixes [] =
669 { "fth", "tok", NULL };
670 static char Forth_help [] =
671 "In Forth code, tags are words defined by `:',\n\
672 constant, code, create, defer, value, variable, buffer:, field.";
674 static char *Fortran_suffixes [] =
675 { "F", "f", "f90", "for", NULL };
676 static char Fortran_help [] =
677 "In Fortran code, functions, subroutines and block data are tags.";
679 static char *HTML_suffixes [] =
680 { "htm", "html", "shtml", NULL };
681 static char HTML_help [] =
682 "In HTML input files, the tags are the `title' and the `h1', `h2',\n\
683 `h3' headers. Also, tags are `name=' in anchors and all\n\
684 occurrences of `id='.";
686 static char *Lisp_suffixes [] =
687 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL };
688 static char Lisp_help [] =
689 "In Lisp code, any function defined with `defun', any variable\n\
690 defined with `defvar' or `defconst', and in general the first\n\
691 argument of any expression that starts with `(def' in column zero\n\
694 static char *Lua_suffixes [] =
695 { "lua", "LUA", NULL };
696 static char Lua_help [] =
697 "In Lua scripts, all functions are tags.";
699 static char *Makefile_filenames [] =
700 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};
701 static char Makefile_help [] =
702 "In makefiles, targets are tags; additionally, variables are tags\n\
703 unless you specify `--no-globals'.";
705 static char *Objc_suffixes [] =
706 { "lm", /* Objective lex file */
707 "m", /* Objective C file */
709 static char Objc_help [] =
710 "In Objective C code, tags include Objective C definitions for classes,\n\
711 class categories, methods and protocols. Tags for variables and\n\
712 functions in classes are named `CLASS::VARIABLE' and `CLASS::FUNCTION'.\n\
713 (Use --help --lang=c --lang=objc --lang=java for full help.)";
715 static char *Pascal_suffixes [] =
716 { "p", "pas", NULL };
717 static char Pascal_help [] =
718 "In Pascal code, the tags are the functions and procedures defined\n\
720 /* " // this is for working around an Emacs highlighting bug... */
722 static char *Perl_suffixes [] =
723 { "pl", "pm", NULL };
724 static char *Perl_interpreters [] =
725 { "perl", "@PERL@", NULL };
726 static char Perl_help [] =
727 "In Perl code, the tags are the packages, subroutines and variables\n\
728 defined by the `package', `sub', `my' and `local' keywords. Use\n\
729 `--globals' if you want to tag global variables. Tags for\n\
730 subroutines are named `PACKAGE::SUB'. The name for subroutines\n\
731 defined in the default package is `main::SUB'.";
733 static char *PHP_suffixes [] =
734 { "php", "php3", "php4", NULL };
735 static char PHP_help [] =
736 "In PHP code, tags are functions, classes and defines. Unless you use\n\
737 the `--no-members' option, vars are tags too.";
739 static char *plain_C_suffixes [] =
740 { "pc", /* Pro*C file */
743 static char *PS_suffixes [] =
744 { "ps", "psw", NULL }; /* .psw is for PSWrap */
745 static char PS_help [] =
746 "In PostScript code, the tags are the functions.";
748 static char *Prolog_suffixes [] =
750 static char Prolog_help [] =
751 "In Prolog code, tags are predicates and rules at the beginning of\n\
754 static char *Python_suffixes [] =
756 static char Python_help [] =
757 "In Python code, `def' or `class' at the beginning of a line\n\
760 /* Can't do the `SCM' or `scm' prefix with a version number. */
761 static char *Scheme_suffixes [] =
762 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL };
763 static char Scheme_help [] =
764 "In Scheme code, tags include anything defined with `def' or with a\n\
765 construct whose name starts with `def'. They also include\n\
766 variables set with `set!' at top level in the file.";
768 static char *TeX_suffixes [] =
769 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL };
770 static char TeX_help [] =
771 "In LaTeX text, the argument of any of the commands `\\chapter',\n\
772 `\\section', `\\subsection', `\\subsubsection', `\\eqno', `\\label',\n\
773 `\\ref', `\\cite', `\\bibitem', `\\part', `\\appendix', `\\entry',\n\
774 `\\index', `\\def', `\\newcommand', `\\renewcommand',\n\
775 `\\newenvironment' or `\\renewenvironment' is a tag.\n\
777 Other commands can be specified by setting the environment variable\n\
778 `TEXTAGS' to a colon-separated list like, for example,\n\
779 TEXTAGS=\"mycommand:myothercommand\".";
782 static char *Texinfo_suffixes [] =
783 { "texi", "texinfo", "txi", NULL };
784 static char Texinfo_help [] =
785 "for texinfo files, lines starting with @node are tagged.";
787 static char *Yacc_suffixes [] =
788 { "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */
789 static char Yacc_help [] =
790 "In Bison or Yacc input files, each rule defines as a tag the\n\
791 nonterminal it constructs. The portions of the file that contain\n\
792 C code are parsed as C code (use --help --lang=c --lang=yacc\n\
795 static char auto_help [] =
796 "`auto' is not a real language, it indicates to use\n\
797 a default language for files base on file name suffix and file contents.";
799 static char none_help [] =
800 "`none' is not a real language, it indicates to only do\n\
801 regexp processing on files.";
803 static char no_lang_help [] =
804 "No detailed help available for this language.";
808 * Table of languages.
810 * It is ok for a given function to be listed under more than one
811 * name. I just didn't.
814 static language lang_names [] =
816 { "ada", Ada_help, Ada_funcs, Ada_suffixes },
817 { "asm", Asm_help, Asm_labels, Asm_suffixes },
818 { "c", default_C_help, default_C_entries, default_C_suffixes },
819 { "c++", Cplusplus_help, Cplusplus_entries, Cplusplus_suffixes },
820 { "c*", no_lang_help, Cstar_entries, Cstar_suffixes },
821 { "cobol", Cobol_help, Cobol_paragraphs, Cobol_suffixes },
822 { "erlang", Erlang_help, Erlang_functions, Erlang_suffixes },
823 { "forth", Forth_help, Forth_words, Forth_suffixes },
824 { "fortran", Fortran_help, Fortran_functions, Fortran_suffixes },
825 { "html", HTML_help, HTML_labels, HTML_suffixes },
826 { "java", Cjava_help, Cjava_entries, Cjava_suffixes },
827 { "lisp", Lisp_help, Lisp_functions, Lisp_suffixes },
828 { "lua", Lua_help, Lua_functions, Lua_suffixes },
829 { "makefile", Makefile_help,Makefile_targets,NULL,Makefile_filenames},
830 { "objc", Objc_help, plain_C_entries, Objc_suffixes },
831 { "pascal", Pascal_help, Pascal_functions, Pascal_suffixes },
832 { "perl",Perl_help,Perl_functions,Perl_suffixes,NULL,Perl_interpreters},
833 { "php", PHP_help, PHP_functions, PHP_suffixes },
834 { "postscript",PS_help, PS_functions, PS_suffixes },
835 { "proc", no_lang_help, plain_C_entries, plain_C_suffixes },
836 { "prolog", Prolog_help, Prolog_functions, Prolog_suffixes },
837 { "python", Python_help, Python_functions, Python_suffixes },
838 { "scheme", Scheme_help, Scheme_functions, Scheme_suffixes },
839 { "tex", TeX_help, TeX_commands, TeX_suffixes },
840 { "texinfo", Texinfo_help, Texinfo_nodes, Texinfo_suffixes },
841 { "yacc", Yacc_help,Yacc_entries,Yacc_suffixes,NULL,NULL,TRUE},
842 { "auto", auto_help }, /* default guessing scheme */
843 { "none", none_help, just_read_file }, /* regexp matching only */
844 { NULL } /* end of list */
849 print_language_names ()
854 puts ("\nThese are the currently supported languages, along with the\n\
855 default file names and dot suffixes:");
856 for (lang = lang_names; lang->name != NULL; lang++)
858 printf (" %-*s", 10, lang->name);
859 if (lang->filenames != NULL)
860 for (name = lang->filenames; *name != NULL; name++)
861 printf (" %s", *name);
862 if (lang->suffixes != NULL)
863 for (ext = lang->suffixes; *ext != NULL; ext++)
864 printf (" .%s", *ext);
867 puts ("where `auto' means use default language for files based on file\n\
868 name suffix, and `none' means only do regexp processing on files.\n\
869 If no language is specified and no matching suffix is found,\n\
870 the first line of the file is read for a sharp-bang (#!) sequence\n\
871 followed by the name of an interpreter. If no such sequence is found,\n\
872 Fortran is tried first; if no tags are found, C is tried next.\n\
873 When parsing any C file, a \"class\" or \"template\" keyword\n\
875 puts ("Compressed files are supported using gzip and bzip2.\n\
877 For detailed help on a given language use, for example,\n\
878 etags --help --lang=ada.");
882 # define EMACS_NAME "standalone"
885 # define VERSION "17.33"
890 printf ("%s (%s %s)\n", (CTAGS) ? "ctags" : "etags", EMACS_NAME, VERSION);
891 puts ("Copyright (C) 2007 Free Software Foundation, Inc.");
892 puts ("This program is distributed under the terms in ETAGS.README");
897 #ifndef PRINT_UNDOCUMENTED_OPTIONS_HELP
898 # define PRINT_UNDOCUMENTED_OPTIONS_HELP FALSE
902 print_help (argbuffer)
905 bool help_for_lang = FALSE;
907 for (; argbuffer->arg_type != at_end; argbuffer++)
908 if (argbuffer->arg_type == at_language)
912 puts (argbuffer->lang->help);
913 help_for_lang = TRUE;
919 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
921 These are the options accepted by %s.\n", progname, progname);
923 puts ("WARNING: long option names do not work with this executable,\n\
924 as it is not linked with GNU getopt.");
926 puts ("You may use unambiguous abbreviations for the long option names.");
927 puts (" A - as file name means read names from stdin (one per line).\n\
928 Absolute names are stored in the output file as they are.\n\
929 Relative ones are stored relative to the output file's directory.\n");
931 puts ("-a, --append\n\
932 Append tag entries to existing tags file.");
934 puts ("--packages-only\n\
935 For Ada files, only generate tags for packages.");
938 puts ("-B, --backward-search\n\
939 Write the search commands for the tag entries using '?', the\n\
940 backward-search command instead of '/', the forward-search command.");
942 /* This option is mostly obsolete, because etags can now automatically
943 detect C++. Retained for backward compatibility and for debugging and
944 experimentation. In principle, we could want to tag as C++ even
945 before any "class" or "template" keyword.
947 Treat files whose name suffix defaults to C language as C++ files.");
950 puts ("--declarations\n\
951 In C and derived languages, create tags for function declarations,");
953 puts ("\tand create tags for extern variables if --globals is used.");
956 ("\tand create tags for extern variables unless --no-globals is used.");
959 puts ("-d, --defines\n\
960 Create tag entries for C #define constants and enum constants, too.");
962 puts ("-D, --no-defines\n\
963 Don't create tag entries for C #define constants and enum constants.\n\
964 This makes the tags file smaller.");
967 puts ("-i FILE, --include=FILE\n\
968 Include a note in tag file indicating that, when searching for\n\
969 a tag, one should also consult the tags file FILE after\n\
970 checking the current file.");
972 puts ("-l LANG, --language=LANG\n\
973 Force the following files to be considered as written in the\n\
974 named language up to the next --language=LANG option.");
978 Create tag entries for global variables in some languages.");
980 puts ("--no-globals\n\
981 Do not create tag entries for global variables in some\n\
982 languages. This makes the tags file smaller.");
984 if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
985 puts ("--no-line-directive\n\
986 Ignore #line preprocessor directives in C and derived languages.");
990 Create tag entries for members of structures in some languages.");
992 puts ("--no-members\n\
993 Do not create tag entries for members of structures\n\
994 in some languages.");
996 puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
997 Make a tag for each line matching a regular expression pattern\n\
998 in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
999 files only. REGEXFILE is a file containing one REGEXP per line.\n\
1000 REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\
1001 optional. The TAGREGEXP pattern is anchored (as if preceded by ^).");
1002 puts (" If TAGNAME/ is present, the tags created are named.\n\
1003 For example Tcl named tags can be created with:\n\
1004 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\".\n\
1005 MODS are optional one-letter modifiers: `i' means to ignore case,\n\
1006 `m' means to allow multi-line matches, `s' implies `m' and\n\
1007 causes dot to match any character, including newline.");
1009 puts ("-R, --no-regex\n\
1010 Don't create tags from regexps for the following files.");
1012 puts ("-I, --ignore-indentation\n\
1013 In C and C++ do not assume that a closing brace in the first\n\
1014 column is the final brace of a function or structure definition.");
1016 puts ("-o FILE, --output=FILE\n\
1017 Write the tags to FILE.");
1019 puts ("--parse-stdin=NAME\n\
1020 Read from standard input and record tags as belonging to file NAME.");
1024 puts ("-t, --typedefs\n\
1025 Generate tag entries for C and Ada typedefs.");
1026 puts ("-T, --typedefs-and-c++\n\
1027 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
1028 and C++ member functions.");
1032 puts ("-u, --update\n\
1033 Update the tag entries for the given files, leaving tag\n\
1034 entries for other files in place. Currently, this is\n\
1035 implemented by deleting the existing entries for the given\n\
1036 files and then rewriting the new entries at the end of the\n\
1037 tags file. It is often faster to simply rebuild the entire\n\
1038 tag file than to use this.");
1042 puts ("-v, --vgrind\n\
1043 Print on the standard output an index of items intended for\n\
1044 human consumption, similar to the output of vgrind. The index\n\
1045 is sorted, and gives the page number of each item.");
1047 if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
1048 puts ("-w, --no-duplicates\n\
1049 Do not create duplicate tag entries, for compatibility with\n\
1050 traditional ctags.");
1052 if (PRINT_UNDOCUMENTED_OPTIONS_HELP)
1053 puts ("-w, --no-warn\n\
1054 Suppress warning messages about duplicate tag entries.");
1056 puts ("-x, --cxref\n\
1057 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
1058 The output uses line numbers instead of page numbers, but\n\
1059 beyond that the differences are cosmetic; try both to see\n\
1063 puts ("-V, --version\n\
1064 Print the version of the program.\n\
1066 Print this help message.\n\
1067 Followed by one or more `--language' options prints detailed\n\
1068 help about tag generation for the specified languages.");
1070 print_language_names ();
1073 puts ("Report bugs to bug-gnu-emacs@gnu.org");
1075 exit (EXIT_SUCCESS);
1079 #ifdef VMS /* VMS specific functions */
1083 /* This is a BUG! ANY arbitrary limit is a BUG!
1084 Won't someone please fix this? */
1085 #define MAX_FILE_SPEC_LEN 255
1088 char body[MAX_FILE_SPEC_LEN + 1];
1092 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
1093 returning in each successive call the next file name matching the input
1094 spec. The function expects that each in_spec passed
1095 to it will be processed to completion; in particular, up to and
1096 including the call following that in which the last matching name
1097 is returned, the function ignores the value of in_spec, and will
1098 only start processing a new spec with the following call.
1099 If an error occurs, on return out_spec contains the value
1100 of in_spec when the error occurred.
1102 With each successive file name returned in out_spec, the
1103 function's return value is one. When there are no more matching
1104 names the function returns zero. If on the first call no file
1105 matches in_spec, or there is any other error, -1 is returned.
1109 #include <descrip.h>
1110 #define OUTSIZE MAX_FILE_SPEC_LEN
1116 static long context = 0;
1117 static struct dsc$descriptor_s o;
1118 static struct dsc$descriptor_s i;
1119 static bool pass1 = TRUE;
1126 o.dsc$a_pointer = (char *) out;
1127 o.dsc$w_length = (short)OUTSIZE;
1128 i.dsc$a_pointer = in;
1129 i.dsc$w_length = (short)strlen(in);
1130 i.dsc$b_dtype = DSC$K_DTYPE_T;
1131 i.dsc$b_class = DSC$K_CLASS_S;
1132 o.dsc$b_dtype = DSC$K_DTYPE_VT;
1133 o.dsc$b_class = DSC$K_CLASS_VS;
1135 if ((status = lib$find_file(&i, &o, &context, 0, 0)) == RMS$_NORMAL)
1137 out->body[out->curlen] = EOS;
1140 else if (status == RMS$_NMF)
1144 strcpy(out->body, in);
1147 lib$find_file_end(&context);
1153 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
1154 name of each file specified by the provided arg expanding wildcards.
1157 gfnames (arg, p_error)
1161 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
1163 switch (fn_exp (&filename, arg))
1167 return filename.body;
1173 return filename.body;
1177 #ifndef OLD /* Newer versions of VMS do provide `system'. */
1181 error ("%s", "system() function not implemented under VMS");
1185 #define VERSION_DELIM ';'
1186 char *massage_name (s)
1192 if (*s == VERSION_DELIM)
1210 unsigned int nincluded_files;
1211 char **included_files;
1212 argument *argbuffer;
1213 int current_arg, file_count;
1214 linebuffer filename_lb;
1215 bool help_asked = FALSE;
1224 _fmode = O_BINARY; /* all of files are treated as binary files */
1228 nincluded_files = 0;
1229 included_files = xnew (argc, char *);
1233 /* Allocate enough no matter what happens. Overkill, but each one
1235 argbuffer = xnew (argc, argument);
1238 * If etags, always find typedefs and structure tags. Why not?
1239 * Also default to find macro constants, enum constants, struct
1240 * members and global variables.
1244 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
1245 globals = members = TRUE;
1248 /* When the optstring begins with a '-' getopt_long does not rearrange the
1249 non-options arguments to be at the end, but leaves them alone. */
1250 optstring = concat (NO_LONG_OPTIONS ? "" : "-",
1251 "ac:Cf:Il:o:r:RSVhH",
1252 (CTAGS) ? "BxdtTuvw" : "Di:");
1254 while ((opt = getopt_long (argc, argv, optstring, longopts, NULL)) != EOF)
1258 /* If getopt returns 0, then it has already processed a
1259 long-named option. We should do nothing. */
1263 /* This means that a file name has been seen. Record it. */
1264 argbuffer[current_arg].arg_type = at_filename;
1265 argbuffer[current_arg].what = optarg;
1271 /* Parse standard input. Idea by Vivek <vivek@etla.org>. */
1272 argbuffer[current_arg].arg_type = at_stdin;
1273 argbuffer[current_arg].what = optarg;
1277 fatal ("cannot parse standard input more than once", (char *)NULL);
1278 parsing_stdin = TRUE;
1281 /* Common options. */
1282 case 'a': append_to_tagfile = TRUE; break;
1283 case 'C': cplusplus = TRUE; break;
1284 case 'f': /* for compatibility with old makefiles */
1288 error ("-o option may only be given once.", (char *)NULL);
1289 suggest_asking_for_help ();
1295 case 'S': /* for backward compatibility */
1296 ignoreindent = TRUE;
1300 language *lang = get_language_from_langname (optarg);
1303 argbuffer[current_arg].lang = lang;
1304 argbuffer[current_arg].arg_type = at_language;
1310 /* Backward compatibility: support obsolete --ignore-case-regexp. */
1311 optarg = concat (optarg, "i", ""); /* memory leak here */
1314 argbuffer[current_arg].arg_type = at_regexp;
1315 argbuffer[current_arg].what = optarg;
1319 argbuffer[current_arg].arg_type = at_regexp;
1320 argbuffer[current_arg].what = NULL;
1332 case 'D': constantypedefs = FALSE; break;
1333 case 'i': included_files[nincluded_files++] = optarg; break;
1335 /* Ctags options. */
1336 case 'B': searchar = '?'; break;
1337 case 'd': constantypedefs = TRUE; break;
1338 case 't': typedefs = TRUE; break;
1339 case 'T': typedefs = typedefs_or_cplusplus = TRUE; break;
1340 case 'u': update = TRUE; break;
1341 case 'v': vgrind_style = TRUE; /*FALLTHRU*/
1342 case 'x': cxref_style = TRUE; break;
1343 case 'w': no_warnings = TRUE; break;
1345 suggest_asking_for_help ();
1349 /* No more options. Store the rest of arguments. */
1350 for (; optind < argc; optind++)
1352 argbuffer[current_arg].arg_type = at_filename;
1353 argbuffer[current_arg].what = argv[optind];
1358 argbuffer[current_arg].arg_type = at_end;
1361 print_help (argbuffer);
1364 if (nincluded_files == 0 && file_count == 0)
1366 error ("no input files specified.", (char *)NULL);
1367 suggest_asking_for_help ();
1371 if (tagfile == NULL)
1372 tagfile = CTAGS ? "tags" : "TAGS";
1373 cwd = etags_getcwd (); /* the current working directory */
1374 if (cwd[strlen (cwd) - 1] != '/')
1377 cwd = concat (oldcwd, "/", "");
1380 /* Relative file names are made relative to the current directory. */
1381 if (streq (tagfile, "-")
1382 || strneq (tagfile, "/dev/", 5))
1385 tagfiledir = absolute_dirname (tagfile, cwd);
1387 init (); /* set up boolean "functions" */
1389 linebuffer_init (&lb);
1390 linebuffer_init (&filename_lb);
1391 linebuffer_init (&filebuf);
1392 linebuffer_init (&token_name);
1396 if (streq (tagfile, "-"))
1400 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1401 doesn't take effect until after `stdout' is already open). */
1402 if (!isatty (fileno (stdout)))
1403 setmode (fileno (stdout), O_BINARY);
1407 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1413 * Loop through files finding functions.
1415 for (i = 0; i < current_arg; i++)
1417 static language *lang; /* non-NULL if language is forced */
1420 switch (argbuffer[i].arg_type)
1423 lang = argbuffer[i].lang;
1426 analyse_regex (argbuffer[i].what);
1430 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL)
1434 error ("can't find file %s\n", this_file);
1439 this_file = massage_name (this_file);
1442 this_file = argbuffer[i].what;
1444 /* Input file named "-" means read file names from stdin
1445 (one per line) and use them. */
1446 if (streq (this_file, "-"))
1449 fatal ("cannot parse standard input AND read file names from it",
1451 while (readline_internal (&filename_lb, stdin) > 0)
1452 process_file_name (filename_lb.buffer, lang);
1455 process_file_name (this_file, lang);
1461 this_file = argbuffer[i].what;
1462 process_file (stdin, this_file, lang);
1469 free (filebuf.buffer);
1470 free (token_name.buffer);
1472 if (!CTAGS || cxref_style)
1474 /* Write the remaining tags to tagf (ETAGS) or stdout (CXREF). */
1475 put_entries (nodehead);
1476 free_tree (nodehead);
1482 /* Output file entries that have no tags. */
1483 for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
1485 fprintf (tagf, "\f\n%s,0\n", fdp->taggedfname);
1487 while (nincluded_files-- > 0)
1488 fprintf (tagf, "\f\n%s,include\n", *included_files++);
1490 if (fclose (tagf) == EOF)
1494 exit (EXIT_SUCCESS);
1500 for (i = 0; i < current_arg; ++i)
1502 switch (argbuffer[i].arg_type)
1508 continue; /* the for loop */
1511 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1512 tagfile, argbuffer[i].what, tagfile);
1513 if (system (cmd) != EXIT_SUCCESS)
1514 fatal ("failed to execute shell command", (char *)NULL);
1516 append_to_tagfile = TRUE;
1519 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1522 put_entries (nodehead); /* write all the tags (CTAGS) */
1523 free_tree (nodehead);
1525 if (fclose (tagf) == EOF)
1529 if (append_to_tagfile || update)
1531 char cmd[2*BUFSIZ+20];
1532 /* Maybe these should be used:
1533 setenv ("LC_COLLATE", "C", 1);
1534 setenv ("LC_ALL", "C", 1); */
1535 sprintf (cmd, "sort -u -o %.*s %.*s", BUFSIZ, tagfile, BUFSIZ, tagfile);
1536 exit (system (cmd));
1538 return EXIT_SUCCESS;
1543 * Return a compressor given the file name. If EXTPTR is non-zero,
1544 * return a pointer into FILE where the compressor-specific
1545 * extension begins. If no compressor is found, NULL is returned
1546 * and EXTPTR is not significant.
1547 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1550 get_compressor_from_suffix (file, extptr)
1555 char *slash, *suffix;
1557 /* This relies on FN to be after canonicalize_filename,
1558 so we don't need to consider backslashes on DOS_NT. */
1559 slash = etags_strrchr (file, '/');
1560 suffix = etags_strrchr (file, '.');
1561 if (suffix == NULL || suffix < slash)
1566 /* Let those poor souls who live with DOS 8+3 file name limits get
1567 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1568 Only the first do loop is run if not MSDOS */
1571 for (compr = compressors; compr->suffix != NULL; compr++)
1572 if (streq (compr->suffix, suffix))
1575 break; /* do it only once: not really a loop */
1578 } while (*suffix != '\0');
1585 * Return a language given the name.
1588 get_language_from_langname (name)
1594 error ("empty language name", (char *)NULL);
1597 for (lang = lang_names; lang->name != NULL; lang++)
1598 if (streq (name, lang->name))
1600 error ("unknown language \"%s\"", name);
1608 * Return a language given the interpreter name.
1611 get_language_from_interpreter (interpreter)
1617 if (interpreter == NULL)
1619 for (lang = lang_names; lang->name != NULL; lang++)
1620 if (lang->interpreters != NULL)
1621 for (iname = lang->interpreters; *iname != NULL; iname++)
1622 if (streq (*iname, interpreter))
1631 * Return a language given the file name.
1634 get_language_from_filename (file, case_sensitive)
1636 bool case_sensitive;
1639 char **name, **ext, *suffix;
1641 /* Try whole file name first. */
1642 for (lang = lang_names; lang->name != NULL; lang++)
1643 if (lang->filenames != NULL)
1644 for (name = lang->filenames; *name != NULL; name++)
1645 if ((case_sensitive)
1646 ? streq (*name, file)
1647 : strcaseeq (*name, file))
1650 /* If not found, try suffix after last dot. */
1651 suffix = etags_strrchr (file, '.');
1655 for (lang = lang_names; lang->name != NULL; lang++)
1656 if (lang->suffixes != NULL)
1657 for (ext = lang->suffixes; *ext != NULL; ext++)
1658 if ((case_sensitive)
1659 ? streq (*ext, suffix)
1660 : strcaseeq (*ext, suffix))
1667 * This routine is called on each file argument.
1670 process_file_name (file, lang)
1674 struct stat stat_buf;
1678 char *compressed_name, *uncompressed_name;
1679 char *ext, *real_name;
1682 canonicalize_filename (file);
1683 if (streq (file, tagfile) && !streq (tagfile, "-"))
1685 error ("skipping inclusion of %s in self.", file);
1688 if ((compr = get_compressor_from_suffix (file, &ext)) == NULL)
1690 compressed_name = NULL;
1691 real_name = uncompressed_name = savestr (file);
1695 real_name = compressed_name = savestr (file);
1696 uncompressed_name = savenstr (file, ext - file);
1699 /* If the canonicalized uncompressed name
1700 has already been dealt with, skip it silently. */
1701 for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
1703 assert (fdp->infname != NULL);
1704 if (streq (uncompressed_name, fdp->infname))
1708 if (stat (real_name, &stat_buf) != 0)
1710 /* Reset real_name and try with a different name. */
1712 if (compressed_name != NULL) /* try with the given suffix */
1714 if (stat (uncompressed_name, &stat_buf) == 0)
1715 real_name = uncompressed_name;
1717 else /* try all possible suffixes */
1719 for (compr = compressors; compr->suffix != NULL; compr++)
1721 compressed_name = concat (file, ".", compr->suffix);
1722 if (stat (compressed_name, &stat_buf) != 0)
1726 char *suf = compressed_name + strlen (file);
1727 size_t suflen = strlen (compr->suffix) + 1;
1728 for ( ; suf[1]; suf++, suflen--)
1730 memmove (suf, suf + 1, suflen);
1731 if (stat (compressed_name, &stat_buf) == 0)
1733 real_name = compressed_name;
1737 if (real_name != NULL)
1740 free (compressed_name);
1741 compressed_name = NULL;
1745 real_name = compressed_name;
1750 if (real_name == NULL)
1755 } /* try with a different name */
1757 if (!S_ISREG (stat_buf.st_mode))
1759 error ("skipping %s: it is not a regular file.", real_name);
1762 if (real_name == compressed_name)
1764 char *cmd = concat (compr->command, " ", real_name);
1765 inf = (FILE *) popen (cmd, "r");
1769 inf = fopen (real_name, "r");
1776 process_file (inf, uncompressed_name, lang);
1778 if (real_name == compressed_name)
1779 retval = pclose (inf);
1781 retval = fclose (inf);
1786 if (compressed_name) free (compressed_name);
1787 if (uncompressed_name) free (uncompressed_name);
1794 process_file (fh, fn, lang)
1799 static const fdesc emptyfdesc;
1802 /* Create a new input file description entry. */
1803 fdp = xnew (1, fdesc);
1806 fdp->infname = savestr (fn);
1808 fdp->infabsname = absolute_filename (fn, cwd);
1809 fdp->infabsdir = absolute_dirname (fn, cwd);
1810 if (filename_is_absolute (fn))
1812 /* An absolute file name. Canonicalize it. */
1813 fdp->taggedfname = absolute_filename (fn, NULL);
1817 /* A file name relative to cwd. Make it relative
1818 to the directory of the tags file. */
1819 fdp->taggedfname = relative_filename (fn, tagfiledir);
1821 fdp->usecharno = TRUE; /* use char position when making tags */
1823 fdp->written = FALSE; /* not written on tags file yet */
1826 curfdp = fdhead; /* the current file description */
1830 /* If not Ctags, and if this is not metasource and if it contained no #line
1831 directives, we can write the tags and free all nodes pointing to
1834 && curfdp->usecharno /* no #line directives in this file */
1835 && !curfdp->lang->metasource)
1839 /* Look for the head of the sublist relative to this file. See add_node
1840 for the structure of the node tree. */
1842 for (np = nodehead; np != NULL; prev = np, np = np->left)
1843 if (np->fdp == curfdp)
1846 /* If we generated tags for this file, write and delete them. */
1849 /* This is the head of the last sublist, if any. The following
1850 instructions depend on this being true. */
1851 assert (np->left == NULL);
1853 assert (fdhead == curfdp);
1854 assert (last_node->fdp == curfdp);
1855 put_entries (np); /* write tags for file curfdp->taggedfname */
1856 free_tree (np); /* remove the written nodes */
1858 nodehead = NULL; /* no nodes left */
1860 prev->left = NULL; /* delete the pointer to the sublist */
1866 * This routine sets up the boolean pseudo-functions which work
1867 * by setting boolean flags dependent upon the corresponding character.
1868 * Every char which is NOT in that string is not a white char. Therefore,
1869 * all of the array "_wht" is set to FALSE, and then the elements
1870 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1871 * of a char is TRUE if it is the string "white", else FALSE.
1879 for (i = 0; i < CHARS; i++)
1880 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE;
1881 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE;
1882 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE;
1883 notinname('\0') = notinname('\n');
1884 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE;
1885 begtoken('\0') = begtoken('\n');
1886 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE;
1887 intoken('\0') = intoken('\n');
1888 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE;
1889 endtoken('\0') = endtoken('\n');
1893 * This routine opens the specified file and calls the function
1894 * which finds the function and type definitions.
1901 language *lang = curfdp->lang;
1902 Lang_function *parser = NULL;
1904 /* If user specified a language, use it. */
1905 if (lang != NULL && lang->function != NULL)
1907 parser = lang->function;
1910 /* Else try to guess the language given the file name. */
1913 lang = get_language_from_filename (curfdp->infname, TRUE);
1914 if (lang != NULL && lang->function != NULL)
1916 curfdp->lang = lang;
1917 parser = lang->function;
1921 /* Else look for sharp-bang as the first two characters. */
1923 && readline_internal (&lb, inf) > 0
1925 && lb.buffer[0] == '#'
1926 && lb.buffer[1] == '!')
1930 /* Set lp to point at the first char after the last slash in the
1931 line or, if no slashes, at the first nonblank. Then set cp to
1932 the first successive blank and terminate the string. */
1933 lp = etags_strrchr (lb.buffer+2, '/');
1937 lp = skip_spaces (lb.buffer + 2);
1938 cp = skip_non_spaces (lp);
1941 if (strlen (lp) > 0)
1943 lang = get_language_from_interpreter (lp);
1944 if (lang != NULL && lang->function != NULL)
1946 curfdp->lang = lang;
1947 parser = lang->function;
1952 /* We rewind here, even if inf may be a pipe. We fail if the
1953 length of the first line is longer than the pipe block size,
1954 which is unlikely. */
1957 /* Else try to guess the language given the case insensitive file name. */
1960 lang = get_language_from_filename (curfdp->infname, FALSE);
1961 if (lang != NULL && lang->function != NULL)
1963 curfdp->lang = lang;
1964 parser = lang->function;
1968 /* Else try Fortran or C. */
1971 node *old_last_node = last_node;
1973 curfdp->lang = get_language_from_langname ("fortran");
1976 if (old_last_node == last_node)
1977 /* No Fortran entries found. Try C. */
1979 /* We do not tag if rewind fails.
1980 Only the file name will be recorded in the tags file. */
1982 curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c");
1988 if (!no_line_directive
1989 && curfdp->lang != NULL && curfdp->lang->metasource)
1990 /* It may be that this is a bingo.y file, and we already parsed a bingo.c
1991 file, or anyway we parsed a file that is automatically generated from
1992 this one. If this is the case, the bingo.c file contained #line
1993 directives that generated tags pointing to this file. Let's delete
1994 them all before parsing this file, which is the real source. */
1996 fdesc **fdpp = &fdhead;
1997 while (*fdpp != NULL)
1999 && streq ((*fdpp)->taggedfname, curfdp->taggedfname))
2000 /* We found one of those! We must delete both the file description
2001 and all tags referring to it. */
2003 fdesc *badfdp = *fdpp;
2005 /* Delete the tags referring to badfdp->taggedfname
2006 that were obtained from badfdp->infname. */
2007 invalidate_nodes (badfdp, &nodehead);
2009 *fdpp = badfdp->next; /* remove the bad description from the list */
2010 free_fdesc (badfdp);
2013 fdpp = &(*fdpp)->next; /* advance the list pointer */
2016 assert (parser != NULL);
2018 /* Generic initialisations before reading from file. */
2019 linebuffer_setlen (&filebuf, 0); /* reset the file buffer */
2021 /* Generic initialisations before parsing file with readline. */
2022 lineno = 0; /* reset global line number */
2023 charno = 0; /* reset global char number */
2024 linecharno = 0; /* reset global char number of line start */
2028 regex_tag_multiline ();
2033 * Check whether an implicitly named tag should be created,
2034 * then call `pfnote'.
2035 * NAME is a string that is internally copied by this function.
2037 * TAGS format specification
2038 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
2039 * The following is explained in some more detail in etc/ETAGS.EBNF.
2041 * make_tag creates tags with "implicit tag names" (unnamed tags)
2042 * if the following are all true, assuming NONAM=" \f\t\n\r()=,;":
2043 * 1. NAME does not contain any of the characters in NONAM;
2044 * 2. LINESTART contains name as either a rightmost, or rightmost but
2045 * one character, substring;
2046 * 3. the character, if any, immediately before NAME in LINESTART must
2047 * be a character in NONAM;
2048 * 4. the character, if any, immediately after NAME in LINESTART must
2049 * also be a character in NONAM.
2051 * The implementation uses the notinname() macro, which recognises the
2052 * characters stored in the string `nonam'.
2053 * etags.el needs to use the same characters that are in NONAM.
2056 make_tag (name, namelen, is_func, linestart, linelen, lno, cno)
2057 char *name; /* tag name, or NULL if unnamed */
2058 int namelen; /* tag length */
2059 bool is_func; /* tag is a function */
2060 char *linestart; /* start of the line where tag is */
2061 int linelen; /* length of the line where tag is */
2062 int lno; /* line number */
2063 long cno; /* character number */
2065 bool named = (name != NULL && namelen > 0);
2067 if (!CTAGS && named) /* maybe set named to false */
2068 /* Let's try to make an implicit tag name, that is, create an unnamed tag
2069 such that etags.el can guess a name from it. */
2072 register char *cp = name;
2074 for (i = 0; i < namelen; i++)
2075 if (notinname (*cp++))
2077 if (i == namelen) /* rule #1 */
2079 cp = linestart + linelen - namelen;
2080 if (notinname (linestart[linelen-1]))
2081 cp -= 1; /* rule #4 */
2082 if (cp >= linestart /* rule #2 */
2084 || notinname (cp[-1])) /* rule #3 */
2085 && strneq (name, cp, namelen)) /* rule #2 */
2086 named = FALSE; /* use implicit tag name */
2091 name = savenstr (name, namelen);
2094 pfnote (name, is_func, linestart, linelen, lno, cno);
2099 pfnote (name, is_func, linestart, linelen, lno, cno)
2100 char *name; /* tag name, or NULL if unnamed */
2101 bool is_func; /* tag is a function */
2102 char *linestart; /* start of the line where tag is */
2103 int linelen; /* length of the line where tag is */
2104 int lno; /* line number */
2105 long cno; /* character number */
2109 assert (name == NULL || name[0] != '\0');
2110 if (CTAGS && name == NULL)
2113 np = xnew (1, node);
2115 /* If ctags mode, change name "main" to M<thisfilename>. */
2116 if (CTAGS && !cxref_style && streq (name, "main"))
2118 register char *fp = etags_strrchr (curfdp->taggedfname, '/');
2119 np->name = concat ("M", fp == NULL ? curfdp->taggedfname : fp + 1, "");
2120 fp = etags_strrchr (np->name, '.');
2121 if (fp != NULL && fp[1] != '\0' && fp[2] == '\0')
2127 np->been_warned = FALSE;
2129 np->is_func = is_func;
2131 if (np->fdp->usecharno)
2132 /* Our char numbers are 0-base, because of C language tradition?
2133 ctags compatibility? old versions compatibility? I don't know.
2134 Anyway, since emacs's are 1-base we expect etags.el to take care
2135 of the difference. If we wanted to have 1-based numbers, we would
2136 uncomment the +1 below. */
2137 np->cno = cno /* + 1 */ ;
2139 np->cno = invalidcharno;
2140 np->left = np->right = NULL;
2141 if (CTAGS && !cxref_style)
2143 if (strlen (linestart) < 50)
2144 np->regex = concat (linestart, "$", "");
2146 np->regex = savenstr (linestart, 50);
2149 np->regex = savenstr (linestart, linelen);
2151 add_node (np, &nodehead);
2156 * recurse on left children, iterate on right children.
2164 register node *node_right = np->right;
2165 free_tree (np->left);
2166 if (np->name != NULL)
2176 * delete a file description
2180 register fdesc *fdp;
2182 if (fdp->infname != NULL) free (fdp->infname);
2183 if (fdp->infabsname != NULL) free (fdp->infabsname);
2184 if (fdp->infabsdir != NULL) free (fdp->infabsdir);
2185 if (fdp->taggedfname != NULL) free (fdp->taggedfname);
2186 if (fdp->prop != NULL) free (fdp->prop);
2192 * Adds a node to the tree of nodes. In etags mode, sort by file
2193 * name. In ctags mode, sort by tag name. Make no attempt at
2196 * add_node is the only function allowed to add nodes, so it can
2200 add_node (np, cur_node_p)
2201 node *np, **cur_node_p;
2204 register node *cur_node = *cur_node_p;
2206 if (cur_node == NULL)
2216 /* For each file name, tags are in a linked sublist on the right
2217 pointer. The first tags of different files are a linked list
2218 on the left pointer. last_node points to the end of the last
2220 if (last_node != NULL && last_node->fdp == np->fdp)
2222 /* Let's use the same sublist as the last added node. */
2223 assert (last_node->right == NULL);
2224 last_node->right = np;
2227 else if (cur_node->fdp == np->fdp)
2229 /* Scanning the list we found the head of a sublist which is
2230 good for us. Let's scan this sublist. */
2231 add_node (np, &cur_node->right);
2234 /* The head of this sublist is not good for us. Let's try the
2236 add_node (np, &cur_node->left);
2237 } /* if ETAGS mode */
2242 dif = strcmp (np->name, cur_node->name);
2245 * If this tag name matches an existing one, then
2246 * do not add the node, but maybe print a warning.
2248 if (no_duplicates && !dif)
2250 if (np->fdp == cur_node->fdp)
2254 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
2255 np->fdp->infname, lineno, np->name);
2256 fprintf (stderr, "Second entry ignored\n");
2259 else if (!cur_node->been_warned && !no_warnings)
2263 "Duplicate entry in files %s and %s: %s (Warning only)\n",
2264 np->fdp->infname, cur_node->fdp->infname, np->name);
2265 cur_node->been_warned = TRUE;
2270 /* Actually add the node */
2271 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
2272 } /* if CTAGS mode */
2276 * invalidate_nodes ()
2277 * Scan the node tree and invalidate all nodes pointing to the
2278 * given file description (CTAGS case) or free them (ETAGS case).
2281 invalidate_nodes (badfdp, npp)
2292 if (np->left != NULL)
2293 invalidate_nodes (badfdp, &np->left);
2294 if (np->fdp == badfdp)
2296 if (np->right != NULL)
2297 invalidate_nodes (badfdp, &np->right);
2301 assert (np->fdp != NULL);
2302 if (np->fdp == badfdp)
2304 *npp = np->left; /* detach the sublist from the list */
2305 np->left = NULL; /* isolate it */
2306 free_tree (np); /* free it */
2307 invalidate_nodes (badfdp, npp);
2310 invalidate_nodes (badfdp, &np->left);
2315 static int total_size_of_entries __P((node *));
2316 static int number_len __P((long));
2318 /* Length of a non-negative number's decimal representation. */
2324 while ((num /= 10) > 0)
2330 * Return total number of characters that put_entries will output for
2331 * the nodes in the linked list at the right of the specified node.
2332 * This count is irrelevant with etags.el since emacs 19.34 at least,
2333 * but is still supplied for backward compatibility.
2336 total_size_of_entries (np)
2339 register int total = 0;
2341 for (; np != NULL; np = np->right)
2344 total += strlen (np->regex) + 1; /* pat\177 */
2345 if (np->name != NULL)
2346 total += strlen (np->name) + 1; /* name\001 */
2347 total += number_len ((long) np->lno) + 1; /* lno, */
2348 if (np->cno != invalidcharno) /* cno */
2349 total += number_len (np->cno);
2350 total += 1; /* newline */
2361 static fdesc *fdp = NULL;
2366 /* Output subentries that precede this one */
2368 put_entries (np->left);
2370 /* Output this entry */
2379 fprintf (tagf, "\f\n%s,%d\n",
2380 fdp->taggedfname, total_size_of_entries (np));
2381 fdp->written = TRUE;
2383 fputs (np->regex, tagf);
2384 fputc ('\177', tagf);
2385 if (np->name != NULL)
2387 fputs (np->name, tagf);
2388 fputc ('\001', tagf);
2390 fprintf (tagf, "%d,", np->lno);
2391 if (np->cno != invalidcharno)
2392 fprintf (tagf, "%ld", np->cno);
2398 if (np->name == NULL)
2399 error ("internal error: NULL name in ctags mode.", (char *)NULL);
2404 fprintf (stdout, "%s %s %d\n",
2405 np->name, np->fdp->taggedfname, (np->lno + 63) / 64);
2407 fprintf (stdout, "%-16s %3d %-16s %s\n",
2408 np->name, np->lno, np->fdp->taggedfname, np->regex);
2412 fprintf (tagf, "%s\t%s\t", np->name, np->fdp->taggedfname);
2415 { /* function or #define macro with args */
2416 putc (searchar, tagf);
2419 for (sp = np->regex; *sp; sp++)
2421 if (*sp == '\\' || *sp == searchar)
2425 putc (searchar, tagf);
2428 { /* anything else; text pattern inadequate */
2429 fprintf (tagf, "%d", np->lno);
2434 } /* if this node contains a valid tag */
2436 /* Output subentries that follow this one */
2437 put_entries (np->right);
2439 put_entries (np->left);
2444 #define C_EXT 0x00fff /* C extensions */
2445 #define C_PLAIN 0x00000 /* C */
2446 #define C_PLPL 0x00001 /* C++ */
2447 #define C_STAR 0x00003 /* C* */
2448 #define C_JAVA 0x00005 /* JAVA */
2449 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
2450 #define YACC 0x10000 /* yacc file */
2453 * The C symbol tables.
2458 st_C_objprot, st_C_objimpl, st_C_objend,
2460 st_C_ignore, st_C_attribute,
2463 st_C_class, st_C_template,
2464 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef
2467 static unsigned int hash __P((const char *, unsigned int));
2468 static struct C_stab_entry * in_word_set __P((const char *, unsigned int));
2469 static enum sym_type C_symtype __P((char *, int, int));
2471 /* Feed stuff between (but not including) %[ and %] lines to:
2477 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2481 while, 0, st_C_ignore
2482 switch, 0, st_C_ignore
2483 return, 0, st_C_ignore
2484 __attribute__, 0, st_C_attribute
2485 @interface, 0, st_C_objprot
2486 @protocol, 0, st_C_objprot
2487 @implementation,0, st_C_objimpl
2488 @end, 0, st_C_objend
2489 import, (C_JAVA & ~C_PLPL), st_C_ignore
2490 package, (C_JAVA & ~C_PLPL), st_C_ignore
2491 friend, C_PLPL, st_C_ignore
2492 extends, (C_JAVA & ~C_PLPL), st_C_javastruct
2493 implements, (C_JAVA & ~C_PLPL), st_C_javastruct
2494 interface, (C_JAVA & ~C_PLPL), st_C_struct
2495 class, 0, st_C_class
2496 namespace, C_PLPL, st_C_struct
2497 domain, C_STAR, st_C_struct
2498 union, 0, st_C_struct
2499 struct, 0, st_C_struct
2500 extern, 0, st_C_extern
2502 typedef, 0, st_C_typedef
2503 define, 0, st_C_define
2504 undef, 0, st_C_define
2505 operator, C_PLPL, st_C_operator
2506 template, 0, st_C_template
2507 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2508 DEFUN, 0, st_C_gnumacro
2509 SYSCALL, 0, st_C_gnumacro
2510 ENTRY, 0, st_C_gnumacro
2511 PSEUDO, 0, st_C_gnumacro
2512 # These are defined inside C functions, so currently they are not met.
2513 # EXFUN used in glibc, DEFVAR_* in emacs.
2514 #EXFUN, 0, st_C_gnumacro
2515 #DEFVAR_, 0, st_C_gnumacro
2517 and replace lines between %< and %> with its output, then:
2518 - remove the #if characterset check
2519 - make in_word_set static and not inline. */
2521 /* C code produced by gperf version 3.0.1 */
2522 /* Command-line: gperf -m 5 */
2523 /* Computed positions: -k'2-3' */
2525 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
2526 /* maximum key range = 33, duplicates = 0 */
2537 register const char *str;
2538 register unsigned int len;
2540 static unsigned char asso_values[] =
2542 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2543 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2544 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2545 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2546 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2547 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2548 35, 35, 35, 35, 35, 35, 35, 35, 35, 15,
2549 14, 35, 35, 35, 35, 35, 35, 35, 14, 35,
2550 35, 35, 35, 12, 13, 35, 35, 35, 35, 12,
2551 35, 35, 35, 35, 35, 1, 35, 16, 35, 6,
2552 23, 0, 0, 35, 22, 0, 35, 35, 5, 0,
2553 0, 15, 1, 35, 6, 35, 8, 19, 35, 16,
2554 4, 5, 35, 35, 35, 35, 35, 35, 35, 35,
2555 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2556 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2557 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2558 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2559 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2560 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2561 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2562 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2563 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2564 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2565 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2566 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
2567 35, 35, 35, 35, 35, 35
2569 register int hval = len;
2574 hval += asso_values[(unsigned char)str[2]];
2577 hval += asso_values[(unsigned char)str[1]];
2583 static struct C_stab_entry *
2584 in_word_set (str, len)
2585 register const char *str;
2586 register unsigned int len;
2590 TOTAL_KEYWORDS = 32,
2591 MIN_WORD_LENGTH = 2,
2592 MAX_WORD_LENGTH = 15,
2597 static struct C_stab_entry wordlist[] =
2600 {"if", 0, st_C_ignore},
2602 {"@end", 0, st_C_objend},
2603 {"union", 0, st_C_struct},
2604 {"define", 0, st_C_define},
2605 {"import", (C_JAVA & ~C_PLPL), st_C_ignore},
2606 {"template", 0, st_C_template},
2607 {"operator", C_PLPL, st_C_operator},
2608 {"@interface", 0, st_C_objprot},
2609 {"implements", (C_JAVA & ~C_PLPL), st_C_javastruct},
2610 {"friend", C_PLPL, st_C_ignore},
2611 {"typedef", 0, st_C_typedef},
2612 {"return", 0, st_C_ignore},
2613 {"@implementation",0, st_C_objimpl},
2614 {"@protocol", 0, st_C_objprot},
2615 {"interface", (C_JAVA & ~C_PLPL), st_C_struct},
2616 {"extern", 0, st_C_extern},
2617 {"extends", (C_JAVA & ~C_PLPL), st_C_javastruct},
2618 {"struct", 0, st_C_struct},
2619 {"domain", C_STAR, st_C_struct},
2620 {"switch", 0, st_C_ignore},
2621 {"enum", 0, st_C_enum},
2622 {"for", 0, st_C_ignore},
2623 {"namespace", C_PLPL, st_C_struct},
2624 {"class", 0, st_C_class},
2625 {"while", 0, st_C_ignore},
2626 {"undef", 0, st_C_define},
2627 {"package", (C_JAVA & ~C_PLPL), st_C_ignore},
2628 {"__attribute__", 0, st_C_attribute},
2629 {"SYSCALL", 0, st_C_gnumacro},
2630 {"ENTRY", 0, st_C_gnumacro},
2631 {"PSEUDO", 0, st_C_gnumacro},
2632 {"DEFUN", 0, st_C_gnumacro}
2635 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
2637 register int key = hash (str, len);
2639 if (key <= MAX_HASH_VALUE && key >= 0)
2641 register const char *s = wordlist[key].name;
2643 if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
2644 return &wordlist[key];
2651 static enum sym_type
2652 C_symtype (str, len, c_ext)
2657 register struct C_stab_entry *se = in_word_set (str, len);
2659 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
2666 * Ignoring __attribute__ ((list))
2668 static bool inattribute; /* looking at an __attribute__ construct */
2671 * C functions and variables are recognized using a simple
2672 * finite automaton. fvdef is its state variable.
2676 fvnone, /* nothing seen */
2677 fdefunkey, /* Emacs DEFUN keyword seen */
2678 fdefunname, /* Emacs DEFUN name seen */
2679 foperator, /* func: operator keyword seen (cplpl) */
2680 fvnameseen, /* function or variable name seen */
2681 fstartlist, /* func: just after open parenthesis */
2682 finlist, /* func: in parameter list */
2683 flistseen, /* func: after parameter list */
2684 fignore, /* func: before open brace */
2685 vignore /* var-like: ignore until ';' */
2688 static bool fvextern; /* func or var: extern keyword seen; */
2691 * typedefs are recognized using a simple finite automaton.
2692 * typdef is its state variable.
2696 tnone, /* nothing seen */
2697 tkeyseen, /* typedef keyword seen */
2698 ttypeseen, /* defined type seen */
2699 tinbody, /* inside typedef body */
2700 tend, /* just before typedef tag */
2701 tignore /* junk after typedef tag */
2705 * struct-like structures (enum, struct and union) are recognized
2706 * using another simple finite automaton. `structdef' is its state
2711 snone, /* nothing seen yet,
2712 or in struct body if bracelev > 0 */
2713 skeyseen, /* struct-like keyword seen */
2714 stagseen, /* struct-like tag seen */
2715 scolonseen /* colon seen after struct-like tag */
2719 * When objdef is different from onone, objtag is the name of the class.
2721 static char *objtag = "<uninited>";
2724 * Yet another little state machine to deal with preprocessor lines.
2728 dnone, /* nothing seen */
2729 dsharpseen, /* '#' seen as first char on line */
2730 ddefineseen, /* '#' and 'define' seen */
2731 dignorerest /* ignore rest of line */
2735 * State machine for Objective C protocols and implementations.
2736 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2740 onone, /* nothing seen */
2741 oprotocol, /* @interface or @protocol seen */
2742 oimplementation, /* @implementations seen */
2743 otagseen, /* class name seen */
2744 oparenseen, /* parenthesis before category seen */
2745 ocatseen, /* category name seen */
2746 oinbody, /* in @implementation body */
2747 omethodsign, /* in @implementation body, after +/- */
2748 omethodtag, /* after method name */
2749 omethodcolon, /* after method colon */
2750 omethodparm, /* after method parameter */
2751 oignore /* wait for @end */
2756 * Use this structure to keep info about the token read, and how it
2757 * should be tagged. Used by the make_C_tag function to build a tag.
2761 char *line; /* string containing the token */
2762 int offset; /* where the token starts in LINE */
2763 int length; /* token length */
2765 The previous members can be used to pass strings around for generic
2766 purposes. The following ones specifically refer to creating tags. In this
2767 case the token contained here is the pattern that will be used to create a
2770 bool valid; /* do not create a tag; the token should be
2771 invalidated whenever a state machine is
2772 reset prematurely */
2773 bool named; /* create a named tag */
2774 int lineno; /* source line number of tag */
2775 long linepos; /* source char number of tag */
2776 } token; /* latest token read */
2779 * Variables and functions for dealing with nested structures.
2780 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2782 static void pushclass_above __P((int, char *, int));
2783 static void popclass_above __P((int));
2784 static void write_classname __P((linebuffer *, char *qualifier));
2787 char **cname; /* nested class names */
2788 int *bracelev; /* nested class brace level */
2789 int nl; /* class nesting level (elements used) */
2790 int size; /* length of the array */
2791 } cstack; /* stack for nested declaration tags */
2792 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2793 #define nestlev (cstack.nl)
2794 /* After struct keyword or in struct body, not inside a nested function. */
2795 #define instruct (structdef == snone && nestlev > 0 \
2796 && bracelev == cstack.bracelev[nestlev-1] + 1)
2799 pushclass_above (bracelev, str, len)
2806 popclass_above (bracelev);
2808 if (nl >= cstack.size)
2810 int size = cstack.size *= 2;
2811 xrnew (cstack.cname, size, char *);
2812 xrnew (cstack.bracelev, size, int);
2814 assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
2815 cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
2816 cstack.bracelev[nl] = bracelev;
2821 popclass_above (bracelev)
2826 for (nl = cstack.nl - 1;
2827 nl >= 0 && cstack.bracelev[nl] >= bracelev;
2830 if (cstack.cname[nl] != NULL)
2831 free (cstack.cname[nl]);
2837 write_classname (cn, qualifier)
2842 int qlen = strlen (qualifier);
2844 if (cstack.nl == 0 || cstack.cname[0] == NULL)
2848 cn->buffer[0] = '\0';
2852 len = strlen (cstack.cname[0]);
2853 linebuffer_setlen (cn, len);
2854 strcpy (cn->buffer, cstack.cname[0]);
2856 for (i = 1; i < cstack.nl; i++)
2861 s = cstack.cname[i];
2866 linebuffer_setlen (cn, len);
2867 strncat (cn->buffer, qualifier, qlen);
2868 strncat (cn->buffer, s, slen);
2873 static bool consider_token __P((char *, int, int, int *, int, int, bool *));
2874 static void make_C_tag __P((bool));
2878 * checks to see if the current token is at the start of a
2879 * function or variable, or corresponds to a typedef, or
2880 * is a struct/union/enum tag, or #define, or an enum constant.
2882 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2883 * with args. C_EXTP points to which language we are looking at.
2894 consider_token (str, len, c, c_extp, bracelev, parlev, is_func_or_var)
2895 register char *str; /* IN: token pointer */
2896 register int len; /* IN: token length */
2897 register int c; /* IN: first char after the token */
2898 int *c_extp; /* IN, OUT: C extensions mask */
2899 int bracelev; /* IN: brace level */
2900 int parlev; /* IN: parenthesis level */
2901 bool *is_func_or_var; /* OUT: function or variable found */
2903 /* When structdef is stagseen, scolonseen, or snone with bracelev > 0,
2904 structtype is the type of the preceding struct-like keyword, and
2905 structbracelev is the brace level where it has been seen. */
2906 static enum sym_type structtype;
2907 static int structbracelev;
2908 static enum sym_type toktype;
2911 toktype = C_symtype (str, len, *c_extp);
2914 * Skip __attribute__
2916 if (toktype == st_C_attribute)
2923 * Advance the definedef state machine.
2928 /* We're not on a preprocessor line. */
2929 if (toktype == st_C_gnumacro)
2936 if (toktype == st_C_define)
2938 definedef = ddefineseen;
2942 definedef = dignorerest;
2947 * Make a tag for any macro, unless it is a constant
2948 * and constantypedefs is FALSE.
2950 definedef = dignorerest;
2951 *is_func_or_var = (c == '(');
2952 if (!*is_func_or_var && !constantypedefs)
2959 error ("internal error: definedef value.", (char *)NULL);
2968 if (toktype == st_C_typedef)
2988 if (structdef == snone && fvdef == fvnone)
3006 * This structdef business is NOT invoked when we are ctags and the
3007 * file is plain C. This is because a struct tag may have the same
3008 * name as another tag, and this loses with ctags.
3012 case st_C_javastruct:
3013 if (structdef == stagseen)
3014 structdef = scolonseen;
3018 if ((*c_extp & C_AUTO) /* automatic detection of C++ language */
3020 && definedef == dnone && structdef == snone
3021 && typdef == tnone && fvdef == fvnone)
3022 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
3023 if (toktype == st_C_template)
3030 && (typdef == tkeyseen
3031 || (typedefs_or_cplusplus && structdef == snone)))
3033 structdef = skeyseen;
3034 structtype = toktype;
3035 structbracelev = bracelev;
3036 if (fvdef == fvnameseen)
3042 if (structdef == skeyseen)
3044 structdef = stagseen;
3048 if (typdef != tnone)
3051 /* Detect Objective C constructs. */
3061 objdef = oimplementation;
3065 case oimplementation:
3066 /* Save the class tag for functions or variables defined inside. */
3067 objtag = savenstr (str, len);
3071 /* Save the class tag for categories. */
3072 objtag = savenstr (str, len);
3074 *is_func_or_var = TRUE;
3078 *is_func_or_var = TRUE;
3086 objdef = omethodtag;
3087 linebuffer_setlen (&token_name, len);
3088 strncpy (token_name.buffer, str, len);
3089 token_name.buffer[len] = '\0';
3095 objdef = omethodparm;
3101 objdef = omethodtag;
3102 linebuffer_setlen (&token_name, token_name.len + len);
3103 strncat (token_name.buffer, str, len);
3108 if (toktype == st_C_objend)
3110 /* Memory leakage here: the string pointed by objtag is
3111 never released, because many tests would be needed to
3112 avoid breaking on incorrect input code. The amount of
3113 memory leaked here is the sum of the lengths of the
3121 /* A function, variable or enum constant? */
3143 *is_func_or_var = TRUE;
3147 && structdef == snone
3148 && structtype == st_C_enum && bracelev > structbracelev)
3149 return TRUE; /* enum constant */
3155 fvdef = fdefunname; /* GNU macro */
3156 *is_func_or_var = TRUE;
3164 if ((strneq (str, "asm", 3) && endtoken (str[3]))
3165 || (strneq (str, "__asm__", 7) && endtoken (str[7])))
3174 if (len >= 10 && strneq (str+len-10, "::operator", 10))
3176 if (*c_extp & C_AUTO) /* automatic detection of C++ */
3177 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
3179 *is_func_or_var = TRUE;
3182 if (bracelev > 0 && !instruct)
3184 fvdef = fvnameseen; /* function or variable */
3185 *is_func_or_var = TRUE;
3196 * C_entries often keeps pointers to tokens or lines which are older than
3197 * the line currently read. By keeping two line buffers, and switching
3198 * them at end of line, it is possible to use those pointers.
3206 #define current_lb_is_new (newndx == curndx)
3207 #define switch_line_buffers() (curndx = 1 - curndx)
3209 #define curlb (lbs[curndx].lb)
3210 #define newlb (lbs[newndx].lb)
3211 #define curlinepos (lbs[curndx].linepos)
3212 #define newlinepos (lbs[newndx].linepos)
3214 #define plainc ((c_ext & C_EXT) == C_PLAIN)
3215 #define cplpl (c_ext & C_PLPL)
3216 #define cjava ((c_ext & C_JAVA) == C_JAVA)
3218 #define CNL_SAVE_DEFINEDEF() \
3220 curlinepos = charno; \
3221 readline (&curlb, inf); \
3222 lp = curlb.buffer; \
3229 CNL_SAVE_DEFINEDEF(); \
3230 if (savetoken.valid) \
3232 token = savetoken; \
3233 savetoken.valid = FALSE; \
3235 definedef = dnone; \
3243 /* This function is never called when token.valid is FALSE, but
3244 we must protect against invalid input or internal errors. */
3245 if (!DEBUG && !token.valid)
3249 make_tag (token_name.buffer, token_name.len, isfun, token.line,
3250 token.offset+token.length+1, token.lineno, token.linepos);
3251 else /* this case is optimised away if !DEBUG */
3252 make_tag (concat ("INVALID TOKEN:-->", token_name.buffer, ""),
3253 token_name.len + 17, isfun, token.line,
3254 token.offset+token.length+1, token.lineno, token.linepos);
3256 token.valid = FALSE;
3262 * This routine finds functions, variables, typedefs,
3263 * #define's, enum constants and struct/union/enum definitions in
3264 * C syntax and adds them to the list.
3267 C_entries (c_ext, inf)
3268 int c_ext; /* extension of C */
3269 FILE *inf; /* input file */
3271 register char c; /* latest char read; '\0' for end of line */
3272 register char *lp; /* pointer one beyond the character `c' */
3273 int curndx, newndx; /* indices for current and new lb */
3274 register int tokoff; /* offset in line of start of current token */
3275 register int toklen; /* length of current token */
3276 char *qualifier; /* string used to qualify names */
3277 int qlen; /* length of qualifier */
3278 int bracelev; /* current brace level */
3279 int bracketlev; /* current bracket level */
3280 int parlev; /* current parenthesis level */
3281 int attrparlev; /* __attribute__ parenthesis level */
3282 int templatelev; /* current template level */
3283 int typdefbracelev; /* bracelev where a typedef struct body begun */
3284 bool incomm, inquote, inchar, quotednl, midtoken;
3285 bool yacc_rules; /* in the rules part of a yacc file */
3286 struct tok savetoken = {0}; /* token saved during preprocessor handling */
3289 linebuffer_init (&lbs[0].lb);
3290 linebuffer_init (&lbs[1].lb);
3291 if (cstack.size == 0)
3293 cstack.size = (DEBUG) ? 1 : 4;
3295 cstack.cname = xnew (cstack.size, char *);
3296 cstack.bracelev = xnew (cstack.size, int);
3299 tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */
3300 curndx = newndx = 0;
3304 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
3305 structdef = snone; definedef = dnone; objdef = onone;
3307 midtoken = inquote = inchar = incomm = quotednl = FALSE;
3308 token.valid = savetoken.valid = FALSE;
3309 bracelev = bracketlev = parlev = attrparlev = templatelev = 0;
3311 { qualifier = "."; qlen = 1; }
3313 { qualifier = "::"; qlen = 2; }
3321 /* If we are at the end of the line, the next character is a
3322 '\0'; do not skip it, because it is what tells us
3323 to read the next line. */
3344 /* Newlines inside comments do not end macro definitions in
3346 CNL_SAVE_DEFINEDEF ();
3359 /* Newlines inside strings do not end macro definitions
3360 in traditional cpp, even though compilers don't
3361 usually accept them. */
3362 CNL_SAVE_DEFINEDEF ();
3372 /* Hmmm, something went wrong. */
3381 else if (bracketlev > 0)
3386 if (--bracketlev > 0)
3390 CNL_SAVE_DEFINEDEF ();
3418 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
3431 else if (/* cplpl && */ *lp == '/')
3437 if ((c_ext & YACC) && *lp == '%')
3439 /* Entering or exiting rules section in yacc file. */
3441 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
3442 typdef = tnone; structdef = snone;
3443 midtoken = inquote = inchar = incomm = quotednl = FALSE;
3445 yacc_rules = !yacc_rules;
3451 if (definedef == dnone)
3454 bool cpptoken = TRUE;
3456 /* Look back on this line. If all blanks, or nonblanks
3457 followed by an end of comment, this is a preprocessor
3459 for (cp = newlb.buffer; cp < lp-1; cp++)
3462 if (*cp == '*' && *(cp+1) == '/')
3471 definedef = dsharpseen;
3472 } /* if (definedef == dnone) */
3480 /* Consider token only if some involved conditions are satisfied. */
3481 if (typdef != tignore
3482 && definedef != dignorerest
3485 && (definedef != dnone
3486 || structdef != scolonseen)
3493 if (c == ':' && *lp == ':' && begtoken (lp[1]))
3494 /* This handles :: in the middle,
3495 but not at the beginning of an identifier.
3496 Also, space-separated :: is not recognised. */
3498 if (c_ext & C_AUTO) /* automatic detection of C++ */
3499 c_ext = (c_ext | C_PLPL) & ~C_AUTO;
3503 goto still_in_token;
3507 bool funorvar = FALSE;
3510 || consider_token (newlb.buffer + tokoff, toklen, c,
3511 &c_ext, bracelev, parlev,
3514 if (fvdef == foperator)
3517 lp = skip_spaces (lp-1);
3521 && !iswhite (*lp) && *lp != '(')
3524 toklen += lp - oldlp;
3526 token.named = FALSE;
3528 && nestlev > 0 && definedef == dnone)
3529 /* in struct body */
3531 write_classname (&token_name, qualifier);
3532 linebuffer_setlen (&token_name,
3533 token_name.len+qlen+toklen);
3534 strcat (token_name.buffer, qualifier);
3535 strncat (token_name.buffer,
3536 newlb.buffer + tokoff, toklen);
3539 else if (objdef == ocatseen)
3540 /* Objective C category */
3542 int len = strlen (objtag) + 2 + toklen;
3543 linebuffer_setlen (&token_name, len);
3544 strcpy (token_name.buffer, objtag);
3545 strcat (token_name.buffer, "(");
3546 strncat (token_name.buffer,
3547 newlb.buffer + tokoff, toklen);
3548 strcat (token_name.buffer, ")");
3551 else if (objdef == omethodtag
3552 || objdef == omethodparm)
3553 /* Objective C method */
3557 else if (fvdef == fdefunname)
3558 /* GNU DEFUN and similar macros */
3560 bool defun = (newlb.buffer[tokoff] == 'F');
3564 /* Rewrite the tag so that emacs lisp DEFUNs
3565 can be found by their elisp name */
3571 linebuffer_setlen (&token_name, len);
3572 strncpy (token_name.buffer,
3573 newlb.buffer + off, len);
3574 token_name.buffer[len] = '\0';
3577 if (token_name.buffer[len] == '_')
3578 token_name.buffer[len] = '-';
3579 token.named = defun;
3583 linebuffer_setlen (&token_name, toklen);
3584 strncpy (token_name.buffer,
3585 newlb.buffer + tokoff, toklen);
3586 token_name.buffer[toklen] = '\0';
3587 /* Name macros and members. */
3588 token.named = (structdef == stagseen
3589 || typdef == ttypeseen
3592 && definedef == dignorerest)
3594 && definedef == dnone
3595 && structdef == snone
3598 token.lineno = lineno;
3599 token.offset = tokoff;
3600 token.length = toklen;
3601 token.line = newlb.buffer;
3602 token.linepos = newlinepos;
3605 if (definedef == dnone
3606 && (fvdef == fvnameseen
3607 || fvdef == foperator
3608 || structdef == stagseen
3610 || typdef == ttypeseen
3611 || objdef != onone))
3613 if (current_lb_is_new)
3614 switch_line_buffers ();
3616 else if (definedef != dnone
3617 || fvdef == fdefunname
3619 make_C_tag (funorvar);
3621 else /* not yacc and consider_token failed */
3623 if (inattribute && fvdef == fignore)
3625 /* We have just met __attribute__ after a
3626 function parameter list: do not tag the
3633 } /* if (endtoken (c)) */
3634 else if (intoken (c))
3640 } /* if (midtoken) */
3641 else if (begtoken (c))
3649 /* This prevents tagging fb in
3650 void (__attribute__((noreturn)) *fb) (void);
3651 Fixing this is not easy and not very important. */
3655 if (plainc || declarations)
3657 make_C_tag (TRUE); /* a function */
3662 if (structdef == stagseen && !cjava)
3664 popclass_above (bracelev);
3672 if (!yacc_rules || lp == newlb.buffer + 1)
3674 tokoff = lp - 1 - newlb.buffer;
3679 } /* if (begtoken) */
3680 } /* if must look at token */
3683 /* Detect end of line, colon, comma, semicolon and various braces
3684 after having handled a token.*/
3690 if (yacc_rules && token.offset == 0 && token.valid)
3692 make_C_tag (FALSE); /* a yacc function */
3695 if (definedef != dnone)
3701 make_C_tag (TRUE); /* an Objective C class */
3705 objdef = omethodcolon;
3706 linebuffer_setlen (&token_name, token_name.len + 1);
3707 strcat (token_name.buffer, ":");
3710 if (structdef == stagseen)
3712 structdef = scolonseen;
3715 /* Should be useless, but may be work as a safety net. */
3716 if (cplpl && fvdef == flistseen)
3718 make_C_tag (TRUE); /* a function */
3724 if (definedef != dnone || inattribute)
3730 make_C_tag (FALSE); /* a typedef */
3740 if (typdef == tignore || cplpl)
3744 if ((globals && bracelev == 0 && (!fvextern || declarations))
3745 || (members && instruct))
3746 make_C_tag (FALSE); /* a variable */
3749 token.valid = FALSE;
3753 && (cplpl || !instruct)
3754 && (typdef == tnone || (typdef != tignore && instruct)))
3756 && plainc && instruct))
3757 make_C_tag (TRUE); /* a function */
3763 && cplpl && structdef == stagseen)
3764 make_C_tag (FALSE); /* forward declaration */
3766 token.valid = FALSE;
3767 } /* switch (fvdef) */
3773 if (structdef == stagseen)
3777 if (definedef != dnone || inattribute)
3783 make_C_tag (TRUE); /* an Objective C method */
3804 && (!fvextern || declarations))
3805 || (members && instruct)))
3806 make_C_tag (FALSE); /* a variable */
3809 if ((declarations && typdef == tnone && !instruct)
3810 || (members && typdef != tignore && instruct))
3812 make_C_tag (TRUE); /* a function */
3815 else if (!declarations)
3817 token.valid = FALSE;
3822 if (structdef == stagseen)
3826 if (definedef != dnone || inattribute)
3828 if (structdef == stagseen)
3835 make_C_tag (FALSE); /* a typedef */
3847 if ((members && bracelev == 1)
3848 || (globals && bracelev == 0
3849 && (!fvextern || declarations)))
3850 make_C_tag (FALSE); /* a variable */
3864 if (definedef != dnone)
3866 if (objdef == otagseen && parlev == 0)
3867 objdef = oparenseen;
3871 if (typdef == ttypeseen
3875 /* This handles constructs like:
3876 typedef void OperatorFun (int fun); */
3895 if (--attrparlev == 0)
3896 inattribute = FALSE;
3899 if (definedef != dnone)
3901 if (objdef == ocatseen && parlev == 1)
3903 make_C_tag (TRUE); /* an Objective C category */
3917 || typdef == ttypeseen))
3920 make_C_tag (FALSE); /* a typedef */
3923 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
3927 if (definedef != dnone)
3929 if (typdef == ttypeseen)
3931 /* Whenever typdef is set to tinbody (currently only
3932 here), typdefbracelev should be set to bracelev. */
3934 typdefbracelev = bracelev;
3939 make_C_tag (TRUE); /* a function */
3948 make_C_tag (TRUE); /* an Objective C class */
3953 make_C_tag (TRUE); /* an Objective C method */
3957 /* Neutralize `extern "C" {' grot. */
3958 if (bracelev == 0 && structdef == snone && nestlev == 0
3966 case skeyseen: /* unnamed struct */
3967 pushclass_above (bracelev, NULL, 0);
3970 case stagseen: /* named struct or enum */
3971 case scolonseen: /* a class */
3972 pushclass_above (bracelev,token.line+token.offset, token.length);
3974 make_C_tag (FALSE); /* a struct or enum */
3980 if (definedef != dnone)
3982 if (fvdef == fstartlist)
3984 fvdef = fvnone; /* avoid tagging `foo' in `foo (*bar()) ()' */
3985 token.valid = FALSE;
3989 if (definedef != dnone)
3991 if (!ignoreindent && lp == newlb.buffer + 1)
3994 token.valid = FALSE;
3995 bracelev = 0; /* reset brace level if first column */
3996 parlev = 0; /* also reset paren level, just in case... */
3998 else if (bracelev > 0)
4001 token.valid = FALSE; /* something gone amiss, token unreliable */
4002 popclass_above (bracelev);
4004 /* Only if typdef == tinbody is typdefbracelev significant. */
4005 if (typdef == tinbody && bracelev <= typdefbracelev)
4007 assert (bracelev == typdefbracelev);
4012 if (definedef != dnone)
4022 if ((members && bracelev == 1)
4023 || (globals && bracelev == 0 && (!fvextern || declarations)))
4024 make_C_tag (FALSE); /* a variable */
4032 && (structdef == stagseen || fvdef == fvnameseen))
4039 if (templatelev > 0)
4047 if (objdef == oinbody && bracelev == 0)
4049 objdef = omethodsign;
4054 case '#': case '~': case '&': case '%': case '/':
4055 case '|': case '^': case '!': case '.': case '?':
4056 if (definedef != dnone)
4058 /* These surely cannot follow a function tag in C. */
4071 if (objdef == otagseen)
4073 make_C_tag (TRUE); /* an Objective C class */
4076 /* If a macro spans multiple lines don't reset its state. */
4078 CNL_SAVE_DEFINEDEF ();
4084 } /* while not eof */
4086 free (lbs[0].lb.buffer);
4087 free (lbs[1].lb.buffer);
4091 * Process either a C++ file or a C file depending on the setting
4095 default_C_entries (inf)
4098 C_entries (cplusplus ? C_PLPL : C_AUTO, inf);
4101 /* Always do plain C. */
4103 plain_C_entries (inf)
4109 /* Always do C++. */
4111 Cplusplus_entries (inf)
4114 C_entries (C_PLPL, inf);
4117 /* Always do Java. */
4122 C_entries (C_JAVA, inf);
4130 C_entries (C_STAR, inf);
4133 /* Always do Yacc. */
4138 C_entries (YACC, inf);
4142 /* Useful macros. */
4143 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
4144 for (; /* loop initialization */ \
4145 !feof (file_pointer) /* loop test */ \
4146 && /* instructions at start of loop */ \
4147 (readline (&line_buffer, file_pointer), \
4148 char_pointer = line_buffer.buffer, \
4152 #define LOOKING_AT(cp, kw) /* kw is the keyword, a literal string */ \
4153 ((assert("" kw), TRUE) /* syntax error if not a literal string */ \
4154 && strneq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
4155 && notinname ((cp)[sizeof(kw)-1]) /* end of kw */ \
4156 && ((cp) = skip_spaces((cp)+sizeof(kw)-1))) /* skip spaces */
4158 /* Similar to LOOKING_AT but does not use notinname, does not skip */
4159 #define LOOKING_AT_NOCASE(cp, kw) /* the keyword is a literal string */ \
4160 ((assert("" kw), TRUE) /* syntax error if not a literal string */ \
4161 && strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
4162 && ((cp) += sizeof(kw)-1)) /* skip spaces */
4165 * Read a file, but do no processing. This is used to do regexp
4166 * matching on files that have no language defined.
4169 just_read_file (inf)
4172 register char *dummy;
4174 LOOP_ON_INPUT_LINES (inf, lb, dummy)
4179 /* Fortran parsing */
4181 static void F_takeprec __P((void));
4182 static void F_getit __P((FILE *));
4187 dbp = skip_spaces (dbp);
4191 dbp = skip_spaces (dbp);
4192 if (strneq (dbp, "(*)", 3))
4197 if (!ISDIGIT (*dbp))
4199 --dbp; /* force failure */
4204 while (ISDIGIT (*dbp));
4213 dbp = skip_spaces (dbp);
4216 readline (&lb, inf);
4221 dbp = skip_spaces (dbp);
4223 if (!ISALPHA (*dbp) && *dbp != '_' && *dbp != '$')
4225 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
4227 make_tag (dbp, cp-dbp, TRUE,
4228 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4233 Fortran_functions (inf)
4236 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4239 dbp++; /* Ratfor escape to fortran */
4240 dbp = skip_spaces (dbp);
4243 switch (lowcase (*dbp))
4246 if (nocase_tail ("integer"))
4250 if (nocase_tail ("real"))
4254 if (nocase_tail ("logical"))
4258 if (nocase_tail ("complex") || nocase_tail ("character"))
4262 if (nocase_tail ("double"))
4264 dbp = skip_spaces (dbp);
4267 if (nocase_tail ("precision"))
4273 dbp = skip_spaces (dbp);
4276 switch (lowcase (*dbp))
4279 if (nocase_tail ("function"))
4283 if (nocase_tail ("subroutine"))
4287 if (nocase_tail ("entry"))
4291 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
4293 dbp = skip_spaces (dbp);
4294 if (*dbp == '\0') /* assume un-named */
4295 make_tag ("blockdata", 9, TRUE,
4296 lb.buffer, dbp - lb.buffer, lineno, linecharno);
4298 F_getit (inf); /* look for name */
4309 * Philippe Waroquiers (1998)
4312 static void Ada_getit __P((FILE *, char *));
4314 /* Once we are positioned after an "interesting" keyword, let's get
4315 the real tag value necessary. */
4317 Ada_getit (inf, name_qualifier)
4319 char *name_qualifier;
4327 dbp = skip_spaces (dbp);
4329 || (dbp[0] == '-' && dbp[1] == '-'))
4331 readline (&lb, inf);
4334 switch (lowcase(*dbp))
4337 if (nocase_tail ("body"))
4339 /* Skipping body of procedure body or package body or ....
4340 resetting qualifier to body instead of spec. */
4341 name_qualifier = "/b";
4346 /* Skipping type of task type or protected type ... */
4347 if (nocase_tail ("type"))
4354 for (cp = dbp; *cp != '\0' && *cp != '"'; cp++)
4359 dbp = skip_spaces (dbp);
4362 && (ISALPHA (*cp) || ISDIGIT (*cp) || *cp == '_' || *cp == '.'));
4370 name = concat (dbp, name_qualifier, "");
4372 make_tag (name, strlen (name), TRUE,
4373 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4385 bool inquote = FALSE;
4386 bool skip_till_semicolumn = FALSE;
4388 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4390 while (*dbp != '\0')
4392 /* Skip a string i.e. "abcd". */
4393 if (inquote || (*dbp == '"'))
4395 dbp = etags_strchr ((inquote) ? dbp : dbp+1, '"');
4400 continue; /* advance char */
4405 break; /* advance line */
4409 /* Skip comments. */
4410 if (dbp[0] == '-' && dbp[1] == '-')
4411 break; /* advance line */
4413 /* Skip character enclosed in single quote i.e. 'a'
4414 and skip single quote starting an attribute i.e. 'Image. */
4423 if (skip_till_semicolumn)
4426 skip_till_semicolumn = FALSE;
4428 continue; /* advance char */
4431 /* Search for beginning of a token. */
4432 if (!begtoken (*dbp))
4435 continue; /* advance char */
4438 /* We are at the beginning of a token. */
4439 switch (lowcase(*dbp))
4442 if (!packages_only && nocase_tail ("function"))
4443 Ada_getit (inf, "/f");
4445 break; /* from switch */
4446 continue; /* advance char */
4448 if (!packages_only && nocase_tail ("procedure"))
4449 Ada_getit (inf, "/p");
4450 else if (nocase_tail ("package"))
4451 Ada_getit (inf, "/s");
4452 else if (nocase_tail ("protected")) /* protected type */
4453 Ada_getit (inf, "/t");
4455 break; /* from switch */
4456 continue; /* advance char */
4459 if (typedefs && !packages_only && nocase_tail ("use"))
4461 /* when tagging types, avoid tagging use type Pack.Typename;
4462 for this, we will skip everything till a ; */
4463 skip_till_semicolumn = TRUE;
4464 continue; /* advance char */
4468 if (!packages_only && nocase_tail ("task"))
4469 Ada_getit (inf, "/k");
4470 else if (typedefs && !packages_only && nocase_tail ("type"))
4472 Ada_getit (inf, "/t");
4473 while (*dbp != '\0')
4477 break; /* from switch */
4478 continue; /* advance char */
4481 /* Look for the end of the token. */
4482 while (!endtoken (*dbp))
4485 } /* advance char */
4486 } /* advance line */
4491 * Unix and microcontroller assembly tag handling
4492 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
4493 * Idea by Bob Weiner, Motorola Inc. (1994)
4501 LOOP_ON_INPUT_LINES (inf, lb, cp)
4503 /* If first char is alphabetic or one of [_.$], test for colon
4504 following identifier. */
4505 if (ISALPHA (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
4507 /* Read past label. */
4509 while (ISALNUM (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
4511 if (*cp == ':' || iswhite (*cp))
4512 /* Found end of label, so copy it and add it to the table. */
4513 make_tag (lb.buffer, cp - lb.buffer, TRUE,
4514 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4522 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
4523 * Perl variable names: /^(my|local).../
4524 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
4525 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
4526 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
4529 Perl_functions (inf)
4532 char *package = savestr ("main"); /* current package name */
4535 LOOP_ON_INPUT_LINES (inf, lb, cp)
4539 if (LOOKING_AT (cp, "package"))
4542 get_tag (cp, &package);
4544 else if (LOOKING_AT (cp, "sub"))
4549 while (!notinname (*cp))
4552 continue; /* nothing found */
4553 if ((pos = etags_strchr (sp, ':')) != NULL
4554 && pos < cp && pos[1] == ':')
4555 /* The name is already qualified. */
4556 make_tag (sp, cp - sp, TRUE,
4557 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4561 char savechar, *name;
4565 name = concat (package, "::", sp);
4567 make_tag (name, strlen(name), TRUE,
4568 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4572 else if (globals) /* only if we are tagging global vars */
4574 /* Skip a qualifier, if any. */
4575 bool qual = LOOKING_AT (cp, "my") || LOOKING_AT (cp, "local");
4576 /* After "my" or "local", but before any following paren or space. */
4577 char *varstart = cp;
4579 if (qual /* should this be removed? If yes, how? */
4580 && (*cp == '$' || *cp == '@' || *cp == '%'))
4585 while (ISALNUM (*cp) || *cp == '_');
4589 /* Should be examining a variable list at this point;
4590 could insist on seeing an open parenthesis. */
4591 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')')
4597 make_tag (varstart, cp - varstart, FALSE,
4598 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4607 * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4608 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4609 * More ideas by seb bacon <seb@jamkit.com> (2002)
4612 Python_functions (inf)
4617 LOOP_ON_INPUT_LINES (inf, lb, cp)
4619 cp = skip_spaces (cp);
4620 if (LOOKING_AT (cp, "def") || LOOKING_AT (cp, "class"))
4623 while (!notinname (*cp) && *cp != ':')
4625 make_tag (name, cp - name, TRUE,
4626 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4635 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4636 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4637 * - /^[ \t]*define\(\"[^\"]+/
4638 * Only with --members:
4639 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4640 * Idea by Diez B. Roggisch (2001)
4646 register char *cp, *name;
4647 bool search_identifier = FALSE;
4649 LOOP_ON_INPUT_LINES (inf, lb, cp)
4651 cp = skip_spaces (cp);
4653 if (search_identifier
4656 while (!notinname (*cp))
4658 make_tag (name, cp - name, TRUE,
4659 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4660 search_identifier = FALSE;
4662 else if (LOOKING_AT (cp, "function"))
4665 cp = skip_spaces (cp+1);
4669 while (!notinname (*cp))
4671 make_tag (name, cp - name, TRUE,
4672 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4675 search_identifier = TRUE;
4677 else if (LOOKING_AT (cp, "class"))
4682 while (*cp != '\0' && !iswhite (*cp))
4684 make_tag (name, cp - name, FALSE,
4685 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4688 search_identifier = TRUE;
4690 else if (strneq (cp, "define", 6)
4691 && (cp = skip_spaces (cp+6))
4693 && (*cp == '"' || *cp == '\''))
4697 while (*cp != quote && *cp != '\0')
4699 make_tag (name, cp - name, FALSE,
4700 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4703 && LOOKING_AT (cp, "var")
4707 while (!notinname(*cp))
4709 make_tag (name, cp - name, FALSE,
4710 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4717 * Cobol tag functions
4718 * We could look for anything that could be a paragraph name.
4719 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4720 * Idea by Corny de Souza (1993)
4723 Cobol_paragraphs (inf)
4726 register char *bp, *ep;
4728 LOOP_ON_INPUT_LINES (inf, lb, bp)
4734 /* If eoln, compiler option or comment ignore whole line. */
4735 if (bp[-1] != ' ' || !ISALNUM (bp[0]))
4738 for (ep = bp; ISALNUM (*ep) || *ep == '-'; ep++)
4741 make_tag (bp, ep - bp, TRUE,
4742 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
4749 * Ideas by Assar Westerlund <assar@sics.se> (2001)
4752 Makefile_targets (inf)
4757 LOOP_ON_INPUT_LINES (inf, lb, bp)
4759 if (*bp == '\t' || *bp == '#')
4761 while (*bp != '\0' && *bp != '=' && *bp != ':')
4763 if (*bp == ':' || (globals && *bp == '='))
4765 /* We should detect if there is more than one tag, but we do not.
4766 We just skip initial and final spaces. */
4767 char * namestart = skip_spaces (lb.buffer);
4768 while (--bp > namestart)
4769 if (!notinname (*bp))
4771 make_tag (namestart, bp - namestart + 1, TRUE,
4772 lb.buffer, bp - lb.buffer + 2, lineno, linecharno);
4780 * Original code by Mosur K. Mohan (1989)
4782 * Locates tags for procedures & functions. Doesn't do any type- or
4783 * var-definitions. It does look for the keyword "extern" or
4784 * "forward" immediately following the procedure statement; if found,
4785 * the tag is skipped.
4788 Pascal_functions (inf)
4791 linebuffer tline; /* mostly copied from C_entries */
4793 int save_lineno, namelen, taglen;
4796 bool /* each of these flags is TRUE iff: */
4797 incomment, /* point is inside a comment */
4798 inquote, /* point is inside '..' string */
4799 get_tagname, /* point is after PROCEDURE/FUNCTION
4800 keyword, so next item = potential tag */
4801 found_tag, /* point is after a potential tag */
4802 inparms, /* point is within parameter-list */
4803 verify_tag; /* point has passed the parm-list, so the
4804 next token will determine whether this
4805 is a FORWARD/EXTERN to be ignored, or
4806 whether it is a real tag */
4808 save_lcno = save_lineno = namelen = taglen = 0; /* keep compiler quiet */
4809 name = NULL; /* keep compiler quiet */
4812 linebuffer_init (&tline);
4814 incomment = inquote = FALSE;
4815 found_tag = FALSE; /* have a proc name; check if extern */
4816 get_tagname = FALSE; /* found "procedure" keyword */
4817 inparms = FALSE; /* found '(' after "proc" */
4818 verify_tag = FALSE; /* check if "extern" is ahead */
4821 while (!feof (inf)) /* long main loop to get next char */
4824 if (c == '\0') /* if end of line */
4826 readline (&lb, inf);
4830 if (!((found_tag && verify_tag)
4832 c = *dbp++; /* only if don't need *dbp pointing
4833 to the beginning of the name of
4834 the procedure or function */
4838 if (c == '}') /* within { } comments */
4840 else if (c == '*' && *dbp == ')') /* within (* *) comments */
4857 inquote = TRUE; /* found first quote */
4859 case '{': /* found open { comment */
4863 if (*dbp == '*') /* found open (* comment */
4868 else if (found_tag) /* found '(' after tag, i.e., parm-list */
4871 case ')': /* end of parms list */
4876 if (found_tag && !inparms) /* end of proc or fn stmt */
4883 if (found_tag && verify_tag && (*dbp != ' '))
4885 /* Check if this is an "extern" declaration. */
4888 if (lowcase (*dbp == 'e'))
4890 if (nocase_tail ("extern")) /* superfluous, really! */
4896 else if (lowcase (*dbp) == 'f')
4898 if (nocase_tail ("forward")) /* check for forward reference */
4904 if (found_tag && verify_tag) /* not external proc, so make tag */
4908 make_tag (name, namelen, TRUE,
4909 tline.buffer, taglen, save_lineno, save_lcno);
4913 if (get_tagname) /* grab name of proc or fn */
4920 /* Find block name. */
4921 for (cp = dbp + 1; *cp != '\0' && !endtoken (*cp); cp++)
4924 /* Save all values for later tagging. */
4925 linebuffer_setlen (&tline, lb.len);
4926 strcpy (tline.buffer, lb.buffer);
4927 save_lineno = lineno;
4928 save_lcno = linecharno;
4929 name = tline.buffer + (dbp - lb.buffer);
4931 taglen = cp - lb.buffer + 1;
4933 dbp = cp; /* set dbp to e-o-token */
4934 get_tagname = FALSE;
4938 /* And proceed to check for "extern". */
4940 else if (!incomment && !inquote && !found_tag)
4942 /* Check for proc/fn keywords. */
4943 switch (lowcase (c))
4946 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4950 if (nocase_tail ("unction"))
4955 } /* while not eof */
4957 free (tline.buffer);
4962 * Lisp tag functions
4963 * look for (def or (DEF, quote or QUOTE
4966 static void L_getit __P((void));
4971 if (*dbp == '\'') /* Skip prefix quote */
4973 else if (*dbp == '(')
4976 /* Try to skip "(quote " */
4977 if (!LOOKING_AT (dbp, "quote") && !LOOKING_AT (dbp, "QUOTE"))
4978 /* Ok, then skip "(" before name in (defstruct (foo)) */
4979 dbp = skip_spaces (dbp);
4981 get_tag (dbp, NULL);
4985 Lisp_functions (inf)
4988 LOOP_ON_INPUT_LINES (inf, lb, dbp)
4993 if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3))
4995 dbp = skip_non_spaces (dbp);
4996 dbp = skip_spaces (dbp);
5001 /* Check for (foo::defmumble name-defined ... */
5004 while (!notinname (*dbp) && *dbp != ':');
5009 while (*dbp == ':');
5011 if (strneq (dbp, "def", 3) || strneq (dbp, "DEF", 3))
5013 dbp = skip_non_spaces (dbp);
5014 dbp = skip_spaces (dbp);
5024 * Lua script language parsing
5025 * Original code by David A. Capello <dacap@users.sourceforge.net> (2004)
5027 * "function" and "local function" are tags if they start at column 1.
5035 LOOP_ON_INPUT_LINES (inf, lb, bp)
5037 if (bp[0] != 'f' && bp[0] != 'l')
5040 (void)LOOKING_AT (bp, "local"); /* skip possible "local" */
5042 if (LOOKING_AT (bp, "function"))
5050 * Just look for lines where the first character is '/'
5051 * Also look at "defineps" for PSWrap
5053 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
5054 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
5060 register char *bp, *ep;
5062 LOOP_ON_INPUT_LINES (inf, lb, bp)
5067 *ep != '\0' && *ep != ' ' && *ep != '{';
5070 make_tag (bp, ep - bp, TRUE,
5071 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
5073 else if (LOOKING_AT (bp, "defineps"))
5081 * Ignore anything after \ followed by space or in ( )
5082 * Look for words defined by :
5083 * Look for constant, code, create, defer, value, and variable
5084 * OBP extensions: Look for buffer:, field,
5085 * Ideas by Eduardo Horvath <eeh@netbsd.org> (2004)
5093 LOOP_ON_INPUT_LINES (inf, lb, bp)
5094 while ((bp = skip_spaces (bp))[0] != '\0')
5095 if (bp[0] == '\\' && iswhite(bp[1]))
5096 break; /* read next line */
5097 else if (bp[0] == '(' && iswhite(bp[1]))
5098 do /* skip to ) or eol */
5100 while (*bp != ')' && *bp != '\0');
5101 else if ((bp[0] == ':' && iswhite(bp[1]) && bp++)
5102 || LOOKING_AT_NOCASE (bp, "constant")
5103 || LOOKING_AT_NOCASE (bp, "code")
5104 || LOOKING_AT_NOCASE (bp, "create")
5105 || LOOKING_AT_NOCASE (bp, "defer")
5106 || LOOKING_AT_NOCASE (bp, "value")
5107 || LOOKING_AT_NOCASE (bp, "variable")
5108 || LOOKING_AT_NOCASE (bp, "buffer:")
5109 || LOOKING_AT_NOCASE (bp, "field"))
5110 get_tag (skip_spaces (bp), NULL); /* Yay! A definition! */
5112 bp = skip_non_spaces (bp);
5117 * Scheme tag functions
5118 * look for (def... xyzzy
5120 * (def ... ((...(xyzzy ....
5122 * Original code by Ken Haase (1985?)
5125 Scheme_functions (inf)
5130 LOOP_ON_INPUT_LINES (inf, lb, bp)
5132 if (strneq (bp, "(def", 4) || strneq (bp, "(DEF", 4))
5134 bp = skip_non_spaces (bp+4);
5135 /* Skip over open parens and white space */
5136 while (notinname (*bp))
5140 if (LOOKING_AT (bp, "(SET!") || LOOKING_AT (bp, "(set!"))
5146 /* Find tags in TeX and LaTeX input files. */
5148 /* TEX_toktab is a table of TeX control sequences that define tags.
5149 * Each entry records one such control sequence.
5151 * Original code from who knows whom.
5153 * Stefan Monnier (2002)
5156 static linebuffer *TEX_toktab = NULL; /* Table with tag tokens */
5158 /* Default set of control sequences to put into TEX_toktab.
5159 The value of environment var TEXTAGS is prepended to this. */
5160 static char *TEX_defenv = "\
5161 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
5162 :part:appendix:entry:index:def\
5163 :newcommand:renewcommand:newenvironment:renewenvironment";
5165 static void TEX_mode __P((FILE *));
5166 static void TEX_decode_env __P((char *, char *));
5168 static char TEX_esc = '\\';
5169 static char TEX_opgrp = '{';
5170 static char TEX_clgrp = '}';
5173 * TeX/LaTeX scanning loop.
5182 /* Select either \ or ! as escape character. */
5185 /* Initialize token table once from environment. */
5186 if (TEX_toktab == NULL)
5187 TEX_decode_env ("TEXTAGS", TEX_defenv);
5189 LOOP_ON_INPUT_LINES (inf, lb, cp)
5191 /* Look at each TEX keyword in line. */
5194 /* Look for a TEX escape. */
5195 while (*cp++ != TEX_esc)
5196 if (cp[-1] == '\0' || cp[-1] == '%')
5199 for (key = TEX_toktab; key->buffer != NULL; key++)
5200 if (strneq (cp, key->buffer, key->len))
5203 int namelen, linelen;
5206 cp = skip_spaces (cp + key->len);
5207 if (*cp == TEX_opgrp)
5213 (!iswhite (*p) && *p != '#' &&
5214 *p != TEX_opgrp && *p != TEX_clgrp);
5219 if (!opgrp || *p == TEX_clgrp)
5221 while (*p != '\0' && *p != TEX_opgrp && *p != TEX_clgrp)
5223 linelen = p - lb.buffer + 1;
5225 make_tag (cp, namelen, TRUE,
5226 lb.buffer, linelen, lineno, linecharno);
5227 goto tex_next_line; /* We only tag a line once */
5235 #define TEX_LESC '\\'
5236 #define TEX_SESC '!'
5238 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
5239 chars accordingly. */
5246 while ((c = getc (inf)) != EOF)
5248 /* Skip to next line if we hit the TeX comment char. */
5250 while (c != '\n' && c != EOF)
5252 else if (c == TEX_LESC || c == TEX_SESC )
5268 /* If the input file is compressed, inf is a pipe, and rewind may fail.
5269 No attempt is made to correct the situation. */
5273 /* Read environment and prepend it to the default string.
5274 Build token table. */
5276 TEX_decode_env (evarname, defenv)
5280 register char *env, *p;
5283 /* Append default string to environment. */
5284 env = getenv (evarname);
5290 env = concat (oldenv, defenv, "");
5293 /* Allocate a token table */
5294 for (len = 1, p = env; p;)
5295 if ((p = etags_strchr (p, ':')) && *++p != '\0')
5297 TEX_toktab = xnew (len, linebuffer);
5299 /* Unpack environment string into token table. Be careful about */
5300 /* zero-length strings (leading ':', "::" and trailing ':') */
5301 for (i = 0; *env != '\0';)
5303 p = etags_strchr (env, ':');
5304 if (!p) /* End of environment string. */
5305 p = env + strlen (env);
5307 { /* Only non-zero strings. */
5308 TEX_toktab[i].buffer = savenstr (env, p - env);
5309 TEX_toktab[i].len = p - env;
5316 TEX_toktab[i].buffer = NULL; /* Mark end of table. */
5317 TEX_toktab[i].len = 0;
5324 /* Texinfo support. Dave Love, Mar. 2000. */
5330 LOOP_ON_INPUT_LINES (inf, lb, cp)
5331 if (LOOKING_AT (cp, "@node"))
5334 while (*cp != '\0' && *cp != ',')
5336 make_tag (start, cp - start, TRUE,
5337 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
5344 * Contents of <title>, <h1>, <h2>, <h3> are tags.
5345 * Contents of <a name=xxx> are tags with name xxx.
5347 * Francesco Potortì, 2002.
5353 bool getnext = FALSE; /* next text outside of HTML tags is a tag */
5354 bool skiptag = FALSE; /* skip to the end of the current HTML tag */
5355 bool intag = FALSE; /* inside an html tag, looking for ID= */
5356 bool inanchor = FALSE; /* when INTAG, is an anchor, look for NAME= */
5360 linebuffer_setlen (&token_name, 0); /* no name in buffer */
5362 LOOP_ON_INPUT_LINES (inf, lb, dbp)
5363 for (;;) /* loop on the same line */
5365 if (skiptag) /* skip HTML tag */
5367 while (*dbp != '\0' && *dbp != '>')
5373 continue; /* look on the same line */
5375 break; /* go to next line */
5378 else if (intag) /* look for "name=" or "id=" */
5380 while (*dbp != '\0' && *dbp != '>'
5381 && lowcase (*dbp) != 'n' && lowcase (*dbp) != 'i')
5384 break; /* go to next line */
5389 continue; /* look on the same line */
5391 if ((inanchor && LOOKING_AT_NOCASE (dbp, "name="))
5392 || LOOKING_AT_NOCASE (dbp, "id="))
5394 bool quoted = (dbp[0] == '"');
5397 for (end = ++dbp; *end != '\0' && *end != '"'; end++)
5400 for (end = dbp; *end != '\0' && intoken (*end); end++)
5402 linebuffer_setlen (&token_name, end - dbp);
5403 strncpy (token_name.buffer, dbp, end - dbp);
5404 token_name.buffer[end - dbp] = '\0';
5407 intag = FALSE; /* we found what we looked for */
5408 skiptag = TRUE; /* skip to the end of the tag */
5409 getnext = TRUE; /* then grab the text */
5410 continue; /* look on the same line */
5415 else if (getnext) /* grab next tokens and tag them */
5417 dbp = skip_spaces (dbp);
5419 break; /* go to next line */
5423 inanchor = (lowcase (dbp[1]) == 'a' && !intoken (dbp[2]));
5424 continue; /* look on the same line */
5427 for (end = dbp + 1; *end != '\0' && *end != '<'; end++)
5429 make_tag (token_name.buffer, token_name.len, TRUE,
5430 dbp, end - dbp, lineno, linecharno);
5431 linebuffer_setlen (&token_name, 0); /* no name in buffer */
5433 break; /* go to next line */
5436 else /* look for an interesting HTML tag */
5438 while (*dbp != '\0' && *dbp != '<')
5441 break; /* go to next line */
5443 if (lowcase (dbp[1]) == 'a' && !intoken (dbp[2]))
5446 continue; /* look on the same line */
5448 else if (LOOKING_AT_NOCASE (dbp, "<title>")
5449 || LOOKING_AT_NOCASE (dbp, "<h1>")
5450 || LOOKING_AT_NOCASE (dbp, "<h2>")
5451 || LOOKING_AT_NOCASE (dbp, "<h3>"))
5455 continue; /* look on the same line */
5466 * Assumes that the predicate or rule starts at column 0.
5467 * Only the first clause of a predicate or rule is added.
5468 * Original code by Sunichirou Sugou (1989)
5469 * Rewritten by Anders Lindgren (1996)
5471 static int prolog_pr __P((char *, char *));
5472 static void prolog_skip_comment __P((linebuffer *, FILE *));
5473 static int prolog_atom __P((char *, int));
5476 Prolog_functions (inf)
5487 LOOP_ON_INPUT_LINES (inf, lb, cp)
5489 if (cp[0] == '\0') /* Empty line */
5491 else if (iswhite (cp[0])) /* Not a predicate */
5493 else if (cp[0] == '/' && cp[1] == '*') /* comment. */
5494 prolog_skip_comment (&lb, inf);
5495 else if ((len = prolog_pr (cp, last)) > 0)
5497 /* Predicate or rule. Store the function name so that we
5498 only generate a tag for the first clause. */
5500 last = xnew(len + 1, char);
5501 else if (len + 1 > allocated)
5502 xrnew (last, len + 1, char);
5503 allocated = len + 1;
5504 strncpy (last, cp, len);
5514 prolog_skip_comment (plb, inf)
5522 for (cp = plb->buffer; *cp != '\0'; cp++)
5523 if (cp[0] == '*' && cp[1] == '/')
5525 readline (plb, inf);
5531 * A predicate or rule definition is added if it matches:
5532 * <beginning of line><Prolog Atom><whitespace>(
5533 * or <beginning of line><Prolog Atom><whitespace>:-
5535 * It is added to the tags database if it doesn't match the
5536 * name of the previous clause header.
5538 * Return the size of the name of the predicate or rule, or 0 if no
5544 char *last; /* Name of last clause. */
5549 pos = prolog_atom (s, 0);
5554 pos = skip_spaces (s + pos) - s;
5557 || (s[pos] == '(' && (pos += 1))
5558 || (s[pos] == ':' && s[pos + 1] == '-' && (pos += 2)))
5559 && (last == NULL /* save only the first clause */
5560 || len != (int)strlen (last)
5561 || !strneq (s, last, len)))
5563 make_tag (s, len, TRUE, s, pos, lineno, linecharno);
5571 * Consume a Prolog atom.
5572 * Return the number of bytes consumed, or -1 if there was an error.
5574 * A prolog atom, in this context, could be one of:
5575 * - An alphanumeric sequence, starting with a lower case letter.
5576 * - A quoted arbitrary string. Single quotes can escape themselves.
5577 * Backslash quotes everything.
5580 prolog_atom (s, pos)
5588 if (ISLOWER(s[pos]) || (s[pos] == '_'))
5590 /* The atom is unquoted. */
5592 while (ISALNUM(s[pos]) || (s[pos] == '_'))
5596 return pos - origpos;
5598 else if (s[pos] == '\'')
5609 pos++; /* A double quote */
5611 else if (s[pos] == '\0')
5612 /* Multiline quoted atoms are ignored. */
5614 else if (s[pos] == '\\')
5616 if (s[pos+1] == '\0')
5623 return pos - origpos;
5631 * Support for Erlang
5633 * Generates tags for functions, defines, and records.
5634 * Assumes that Erlang functions start at column 0.
5635 * Original code by Anders Lindgren (1996)
5637 static int erlang_func __P((char *, char *));
5638 static void erlang_attribute __P((char *));
5639 static int erlang_atom __P((char *));
5642 Erlang_functions (inf)
5653 LOOP_ON_INPUT_LINES (inf, lb, cp)
5655 if (cp[0] == '\0') /* Empty line */
5657 else if (iswhite (cp[0])) /* Not function nor attribute */
5659 else if (cp[0] == '%') /* comment */
5661 else if (cp[0] == '"') /* Sometimes, strings start in column one */
5663 else if (cp[0] == '-') /* attribute, e.g. "-define" */
5665 erlang_attribute (cp);
5672 else if ((len = erlang_func (cp, last)) > 0)
5675 * Function. Store the function name so that we only
5676 * generates a tag for the first clause.
5679 last = xnew (len + 1, char);
5680 else if (len + 1 > allocated)
5681 xrnew (last, len + 1, char);
5682 allocated = len + 1;
5683 strncpy (last, cp, len);
5693 * A function definition is added if it matches:
5694 * <beginning of line><Erlang Atom><whitespace>(
5696 * It is added to the tags database if it doesn't match the
5697 * name of the previous clause header.
5699 * Return the size of the name of the function, or 0 if no function
5703 erlang_func (s, last)
5705 char *last; /* Name of last clause. */
5710 pos = erlang_atom (s);
5715 pos = skip_spaces (s + pos) - s;
5717 /* Save only the first clause. */
5720 || len != (int)strlen (last)
5721 || !strneq (s, last, len)))
5723 make_tag (s, len, TRUE, s, pos, lineno, linecharno);
5732 * Handle attributes. Currently, tags are generated for defines
5735 * They are on the form:
5736 * -define(foo, bar).
5737 * -define(Foo(M, N), M+N).
5738 * -record(graph, {vtab = notable, cyclic = true}).
5741 erlang_attribute (s)
5746 if ((LOOKING_AT (cp, "-define") || LOOKING_AT (cp, "-record"))
5749 int len = erlang_atom (skip_spaces (cp));
5751 make_tag (cp, len, TRUE, s, cp + len - s, lineno, linecharno);
5758 * Consume an Erlang atom (or variable).
5759 * Return the number of bytes consumed, or -1 if there was an error.
5767 if (ISALPHA (s[pos]) || s[pos] == '_')
5769 /* The atom is unquoted. */
5772 while (ISALNUM (s[pos]) || s[pos] == '_');
5774 else if (s[pos] == '\'')
5776 for (pos++; s[pos] != '\''; pos++)
5777 if (s[pos] == '\0' /* multiline quoted atoms are ignored */
5778 || (s[pos] == '\\' && s[++pos] == '\0'))
5787 static char *scan_separators __P((char *));
5788 static void add_regex __P((char *, language *));
5789 static char *substitute __P((char *, char *, struct re_registers *));
5792 * Take a string like "/blah/" and turn it into "blah", verifying
5793 * that the first and last characters are the same, and handling
5794 * quoted separator characters. Actually, stops on the occurrence of
5795 * an unquoted separator. Also process \t, \n, etc. and turn into
5796 * appropriate characters. Works in place. Null terminates name string.
5797 * Returns pointer to terminating separator, or NULL for
5798 * unterminated regexps.
5801 scan_separators (name)
5805 char *copyto = name;
5806 bool quoted = FALSE;
5808 for (++name; *name != '\0'; ++name)
5814 case 'a': *copyto++ = '\007'; break; /* BEL (bell) */
5815 case 'b': *copyto++ = '\b'; break; /* BS (back space) */
5816 case 'd': *copyto++ = 0177; break; /* DEL (delete) */
5817 case 'e': *copyto++ = 033; break; /* ESC (delete) */
5818 case 'f': *copyto++ = '\f'; break; /* FF (form feed) */
5819 case 'n': *copyto++ = '\n'; break; /* NL (new line) */
5820 case 'r': *copyto++ = '\r'; break; /* CR (carriage return) */
5821 case 't': *copyto++ = '\t'; break; /* TAB (horizontal tab) */
5822 case 'v': *copyto++ = '\v'; break; /* VT (vertical tab) */
5828 /* Something else is quoted, so preserve the quote. */
5836 else if (*name == '\\')
5838 else if (*name == sep)
5844 name = NULL; /* signal unterminated regexp */
5846 /* Terminate copied string. */
5851 /* Look at the argument of --regex or --no-regex and do the right
5852 thing. Same for each line of a regexp file. */
5854 analyse_regex (regex_arg)
5857 if (regex_arg == NULL)
5859 free_regexps (); /* --no-regex: remove existing regexps */
5863 /* A real --regexp option or a line in a regexp file. */
5864 switch (regex_arg[0])
5866 /* Comments in regexp file or null arg to --regex. */
5872 /* Read a regex file. This is recursive and may result in a
5873 loop, which will stop when the file descriptors are exhausted. */
5877 linebuffer regexbuf;
5878 char *regexfile = regex_arg + 1;
5880 /* regexfile is a file containing regexps, one per line. */
5881 regexfp = fopen (regexfile, "r");
5882 if (regexfp == NULL)
5887 linebuffer_init (®exbuf);
5888 while (readline_internal (®exbuf, regexfp) > 0)
5889 analyse_regex (regexbuf.buffer);
5890 free (regexbuf.buffer);
5895 /* Regexp to be used for a specific language only. */
5899 char *lang_name = regex_arg + 1;
5902 for (cp = lang_name; *cp != '}'; cp++)
5905 error ("unterminated language name in regex: %s", regex_arg);
5909 lang = get_language_from_langname (lang_name);
5912 add_regex (cp, lang);
5916 /* Regexp to be used for any language. */
5918 add_regex (regex_arg, NULL);
5923 /* Separate the regexp pattern, compile it,
5924 and care for optional name and modifiers. */
5926 add_regex (regexp_pattern, lang)
5927 char *regexp_pattern;
5930 static struct re_pattern_buffer zeropattern;
5931 char sep, *pat, *name, *modifiers;
5933 struct re_pattern_buffer *patbuf;
5936 force_explicit_name = TRUE, /* do not use implicit tag names */
5937 ignore_case = FALSE, /* case is significant */
5938 multi_line = FALSE, /* matches are done one line at a time */
5939 single_line = FALSE; /* dot does not match newline */
5942 if (strlen(regexp_pattern) < 3)
5944 error ("null regexp", (char *)NULL);
5947 sep = regexp_pattern[0];
5948 name = scan_separators (regexp_pattern);
5951 error ("%s: unterminated regexp", regexp_pattern);
5956 error ("null name for regexp \"%s\"", regexp_pattern);
5959 modifiers = scan_separators (name);
5960 if (modifiers == NULL) /* no terminating separator --> no name */
5966 modifiers += 1; /* skip separator */
5968 /* Parse regex modifiers. */
5969 for (; modifiers[0] != '\0'; modifiers++)
5970 switch (modifiers[0])
5973 if (modifiers == name)
5974 error ("forcing explicit tag name but no name, ignoring", NULL);
5975 force_explicit_name = TRUE;
5985 need_filebuf = TRUE;
5990 wrongmod[0] = modifiers[0];
5992 error ("invalid regexp modifier `%s', ignoring", wrongmod);
5997 patbuf = xnew (1, struct re_pattern_buffer);
5998 *patbuf = zeropattern;
6001 static char lc_trans[CHARS];
6003 for (i = 0; i < CHARS; i++)
6004 lc_trans[i] = lowcase (i);
6005 patbuf->translate = lc_trans; /* translation table to fold case */
6009 pat = concat ("^", regexp_pattern, ""); /* anchor to beginning of line */
6011 pat = regexp_pattern;
6014 re_set_syntax (RE_SYNTAX_EMACS | RE_DOT_NEWLINE);
6016 re_set_syntax (RE_SYNTAX_EMACS);
6018 err = re_compile_pattern (pat, strlen (regexp_pattern), patbuf);
6023 error ("%s while compiling pattern", err);
6028 p_head = xnew (1, regexp);
6029 p_head->pattern = savestr (regexp_pattern);
6030 p_head->p_next = rp;
6031 p_head->lang = lang;
6032 p_head->pat = patbuf;
6033 p_head->name = savestr (name);
6034 p_head->error_signaled = FALSE;
6035 p_head->force_explicit_name = force_explicit_name;
6036 p_head->ignore_case = ignore_case;
6037 p_head->multi_line = multi_line;
6041 * Do the substitutions indicated by the regular expression and
6045 substitute (in, out, regs)
6047 struct re_registers *regs;
6050 int size, dig, diglen;
6053 size = strlen (out);
6055 /* Pass 1: figure out how much to allocate by finding all \N strings. */
6056 if (out[size - 1] == '\\')
6057 fatal ("pattern error in \"%s\"", out);
6058 for (t = etags_strchr (out, '\\');
6060 t = etags_strchr (t + 2, '\\'))
6064 diglen = regs->end[dig] - regs->start[dig];
6070 /* Allocate space and do the substitutions. */
6072 result = xnew (size + 1, char);
6074 for (t = result; *out != '\0'; out++)
6075 if (*out == '\\' && ISDIGIT (*++out))
6078 diglen = regs->end[dig] - regs->start[dig];
6079 strncpy (t, in + regs->start[dig], diglen);
6086 assert (t <= result + size);
6087 assert (t - result == (int)strlen (result));
6092 /* Deallocate all regexps. */
6097 while (p_head != NULL)
6099 rp = p_head->p_next;
6100 free (p_head->pattern);
6101 free (p_head->name);
6109 * Reads the whole file as a single string from `filebuf' and looks for
6110 * multi-line regular expressions, creating tags on matches.
6111 * readline already dealt with normal regexps.
6113 * Idea by Ben Wing <ben@666.com> (2002).
6116 regex_tag_multiline ()
6118 char *buffer = filebuf.buffer;
6122 for (rp = p_head; rp != NULL; rp = rp->p_next)
6126 if (!rp->multi_line)
6127 continue; /* skip normal regexps */
6129 /* Generic initialisations before parsing file from memory. */
6130 lineno = 1; /* reset global line number */
6131 charno = 0; /* reset global char number */
6132 linecharno = 0; /* reset global char number of line start */
6134 /* Only use generic regexps or those for the current language. */
6135 if (rp->lang != NULL && rp->lang != curfdp->lang)
6138 while (match >= 0 && match < filebuf.len)
6140 match = re_search (rp->pat, buffer, filebuf.len, charno,
6141 filebuf.len - match, &rp->regs);
6146 if (!rp->error_signaled)
6148 error ("regexp stack overflow while matching \"%s\"",
6150 rp->error_signaled = TRUE;
6157 if (match == rp->regs.end[0])
6159 if (!rp->error_signaled)
6161 error ("regexp matches the empty string: \"%s\"",
6163 rp->error_signaled = TRUE;
6165 match = -3; /* exit from while loop */
6169 /* Match occurred. Construct a tag. */
6170 while (charno < rp->regs.end[0])
6171 if (buffer[charno++] == '\n')
6172 lineno++, linecharno = charno;
6174 if (name[0] == '\0')
6176 else /* make a named tag */
6177 name = substitute (buffer, rp->name, &rp->regs);
6178 if (rp->force_explicit_name)
6179 /* Force explicit tag name, if a name is there. */
6180 pfnote (name, TRUE, buffer + linecharno,
6181 charno - linecharno + 1, lineno, linecharno);
6183 make_tag (name, strlen (name), TRUE, buffer + linecharno,
6184 charno - linecharno + 1, lineno, linecharno);
6196 register int len = 0;
6198 while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len]))
6200 if (*cp == '\0' && !intoken (dbp[len]))
6209 get_tag (bp, namepp)
6213 register char *cp = bp;
6217 /* Go till you get to white space or a syntactic break */
6218 for (cp = bp + 1; !notinname (*cp); cp++)
6220 make_tag (bp, cp - bp, TRUE,
6221 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
6225 *namepp = savenstr (bp, cp - bp);
6229 * Read a line of text from `stream' into `lbp', excluding the
6230 * newline or CR-NL, if any. Return the number of characters read from
6231 * `stream', which is the length of the line including the newline.
6233 * On DOS or Windows we do not count the CR character, if any before the
6234 * NL, in the returned length; this mirrors the behavior of Emacs on those
6235 * platforms (for text files, it translates CR-NL to NL as it reads in the
6238 * If multi-line regular expressions are requested, each line read is
6239 * appended to `filebuf'.
6242 readline_internal (lbp, stream)
6244 register FILE *stream;
6246 char *buffer = lbp->buffer;
6247 register char *p = lbp->buffer;
6248 register char *pend;
6251 pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */
6255 register int c = getc (stream);
6258 /* We're at the end of linebuffer: expand it. */
6260 xrnew (buffer, lbp->size, char);
6261 p += buffer - lbp->buffer;
6262 pend = buffer + lbp->size;
6263 lbp->buffer = buffer;
6273 if (p > buffer && p[-1] == '\r')
6277 /* Assume CRLF->LF translation will be performed by Emacs
6278 when loading this file, so CRs won't appear in the buffer.
6279 It would be cleaner to compensate within Emacs;
6280 however, Emacs does not know how many CRs were deleted
6281 before any given point in the file. */
6296 lbp->len = p - buffer;
6298 if (need_filebuf /* we need filebuf for multi-line regexps */
6299 && chars_deleted > 0) /* not at EOF */
6301 while (filebuf.size <= filebuf.len + lbp->len + 1) /* +1 for \n */
6303 /* Expand filebuf. */
6305 xrnew (filebuf.buffer, filebuf.size, char);
6307 strncpy (filebuf.buffer + filebuf.len, lbp->buffer, lbp->len);
6308 filebuf.len += lbp->len;
6309 filebuf.buffer[filebuf.len++] = '\n';
6310 filebuf.buffer[filebuf.len] = '\0';
6313 return lbp->len + chars_deleted;
6317 * Like readline_internal, above, but in addition try to match the
6318 * input line against relevant regular expressions and manage #line
6322 readline (lbp, stream)
6328 linecharno = charno; /* update global char number of line start */
6329 result = readline_internal (lbp, stream); /* read line */
6330 lineno += 1; /* increment global line number */
6331 charno += result; /* increment global char number */
6333 /* Honour #line directives. */
6334 if (!no_line_directive)
6336 static bool discard_until_line_directive;
6338 /* Check whether this is a #line directive. */
6339 if (result > 12 && strneq (lbp->buffer, "#line ", 6))
6344 if (sscanf (lbp->buffer, "#line %u \"%n", &lno, &start) >= 1
6345 && start > 0) /* double quote character found */
6347 char *endp = lbp->buffer + start;
6349 while ((endp = etags_strchr (endp, '"')) != NULL
6350 && endp[-1] == '\\')
6353 /* Ok, this is a real #line directive. Let's deal with it. */
6355 char *taggedabsname; /* absolute name of original file */
6356 char *taggedfname; /* name of original file as given */
6357 char *name; /* temp var */
6359 discard_until_line_directive = FALSE; /* found it */
6360 name = lbp->buffer + start;
6362 canonicalize_filename (name); /* for DOS */
6363 taggedabsname = absolute_filename (name, tagfiledir);
6364 if (filename_is_absolute (name)
6365 || filename_is_absolute (curfdp->infname))
6366 taggedfname = savestr (taggedabsname);
6368 taggedfname = relative_filename (taggedabsname,tagfiledir);
6370 if (streq (curfdp->taggedfname, taggedfname))
6371 /* The #line directive is only a line number change. We
6372 deal with this afterwards. */
6375 /* The tags following this #line directive should be
6376 attributed to taggedfname. In order to do this, set
6377 curfdp accordingly. */
6379 fdesc *fdp; /* file description pointer */
6381 /* Go look for a file description already set up for the
6382 file indicated in the #line directive. If there is
6383 one, use it from now until the next #line
6385 for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
6386 if (streq (fdp->infname, curfdp->infname)
6387 && streq (fdp->taggedfname, taggedfname))
6388 /* If we remove the second test above (after the &&)
6389 then all entries pertaining to the same file are
6390 coalesced in the tags file. If we use it, then
6391 entries pertaining to the same file but generated
6392 from different files (via #line directives) will
6393 go into separate sections in the tags file. These
6394 alternatives look equivalent. The first one
6395 destroys some apparently useless information. */
6401 /* Else, if we already tagged the real file, skip all
6402 input lines until the next #line directive. */
6403 if (fdp == NULL) /* not found */
6404 for (fdp = fdhead; fdp != NULL; fdp = fdp->next)
6405 if (streq (fdp->infabsname, taggedabsname))
6407 discard_until_line_directive = TRUE;
6411 /* Else create a new file description and use that from
6412 now on, until the next #line directive. */
6413 if (fdp == NULL) /* not found */
6416 fdhead = xnew (1, fdesc);
6417 *fdhead = *curfdp; /* copy curr. file description */
6419 fdhead->infname = savestr (curfdp->infname);
6420 fdhead->infabsname = savestr (curfdp->infabsname);
6421 fdhead->infabsdir = savestr (curfdp->infabsdir);
6422 fdhead->taggedfname = taggedfname;
6423 fdhead->usecharno = FALSE;
6424 fdhead->prop = NULL;
6425 fdhead->written = FALSE;
6429 free (taggedabsname);
6431 readline (lbp, stream);
6433 } /* if a real #line directive */
6434 } /* if #line is followed by a a number */
6435 } /* if line begins with "#line " */
6437 /* If we are here, no #line directive was found. */
6438 if (discard_until_line_directive)
6442 /* Do a tail recursion on ourselves, thus discarding the contents
6443 of the line buffer. */
6444 readline (lbp, stream);
6448 discard_until_line_directive = FALSE;
6451 } /* if #line directives should be considered */
6458 /* Match against relevant regexps. */
6460 for (rp = p_head; rp != NULL; rp = rp->p_next)
6462 /* Only use generic regexps or those for the current language.
6463 Also do not use multiline regexps, which is the job of
6464 regex_tag_multiline. */
6465 if ((rp->lang != NULL && rp->lang != fdhead->lang)
6469 match = re_match (rp->pat, lbp->buffer, lbp->len, 0, &rp->regs);
6474 if (!rp->error_signaled)
6476 error ("regexp stack overflow while matching \"%s\"",
6478 rp->error_signaled = TRUE;
6485 /* Empty string matched. */
6486 if (!rp->error_signaled)
6488 error ("regexp matches the empty string: \"%s\"", rp->pattern);
6489 rp->error_signaled = TRUE;
6493 /* Match occurred. Construct a tag. */
6495 if (name[0] == '\0')
6497 else /* make a named tag */
6498 name = substitute (lbp->buffer, rp->name, &rp->regs);
6499 if (rp->force_explicit_name)
6500 /* Force explicit tag name, if a name is there. */
6501 pfnote (name, TRUE, lbp->buffer, match, lineno, linecharno);
6503 make_tag (name, strlen (name), TRUE,
6504 lbp->buffer, match, lineno, linecharno);
6513 * Return a pointer to a space of size strlen(cp)+1 allocated
6514 * with xnew where the string CP has been copied.
6520 return savenstr (cp, strlen (cp));
6524 * Return a pointer to a space of size LEN+1 allocated with xnew where
6525 * the string CP has been copied for at most the first LEN characters.
6534 dp = xnew (len + 1, char);
6535 strncpy (dp, cp, len);
6541 * Return the ptr in sp at which the character c last
6542 * appears; NULL if not found
6544 * Identical to POSIX strrchr, included for portability.
6547 etags_strrchr (sp, c)
6548 register const char *sp;
6551 register const char *r;
6563 * Return the ptr in sp at which the character c first
6564 * appears; NULL if not found
6566 * Identical to POSIX strchr, included for portability.
6569 etags_strchr (sp, c)
6570 register const char *sp;
6582 * Compare two strings, ignoring case for alphabetic characters.
6584 * Same as BSD's strcasecmp, included for portability.
6587 etags_strcasecmp (s1, s2)
6588 register const char *s1;
6589 register const char *s2;
6592 && (ISALPHA (*s1) && ISALPHA (*s2)
6593 ? lowcase (*s1) == lowcase (*s2)
6597 return (ISALPHA (*s1) && ISALPHA (*s2)
6598 ? lowcase (*s1) - lowcase (*s2)
6603 * Compare two strings, ignoring case for alphabetic characters.
6604 * Stop after a given number of characters
6606 * Same as BSD's strncasecmp, included for portability.
6609 etags_strncasecmp (s1, s2, n)
6610 register const char *s1;
6611 register const char *s2;
6614 while (*s1 != '\0' && n-- > 0
6615 && (ISALPHA (*s1) && ISALPHA (*s2)
6616 ? lowcase (*s1) == lowcase (*s2)
6623 return (ISALPHA (*s1) && ISALPHA (*s2)
6624 ? lowcase (*s1) - lowcase (*s2)
6628 /* Skip spaces (end of string is not space), return new pointer. */
6633 while (iswhite (*cp))
6638 /* Skip non spaces, except end of string, return new pointer. */
6640 skip_non_spaces (cp)
6643 while (*cp != '\0' && !iswhite (*cp))
6648 /* Print error message and exit. */
6654 exit (EXIT_FAILURE);
6662 exit (EXIT_FAILURE);
6666 suggest_asking_for_help ()
6668 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n",
6669 progname, NO_LONG_OPTIONS ? "-h" : "--help");
6670 exit (EXIT_FAILURE);
6673 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
6676 const char *s1, *s2;
6678 fprintf (stderr, "%s: ", progname);
6679 fprintf (stderr, s1, s2);
6680 fprintf (stderr, "\n");
6683 /* Return a newly-allocated string whose contents
6684 concatenate those of s1, s2, s3. */
6689 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
6690 char *result = xnew (len1 + len2 + len3 + 1, char);
6692 strcpy (result, s1);
6693 strcpy (result + len1, s2);
6694 strcpy (result + len1 + len2, s3);
6695 result[len1 + len2 + len3] = '\0';
6701 /* Does the same work as the system V getcwd, but does not need to
6702 guess the buffer size in advance. */
6708 char *path = xnew (bufsize, char);
6710 while (getcwd (path, bufsize) == NULL)
6712 if (errno != ERANGE)
6716 path = xnew (bufsize, char);
6719 canonicalize_filename (path);
6722 #else /* not HAVE_GETCWD */
6725 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
6729 for (p = path; *p != '\0'; p++)
6735 return strdup (path);
6736 #else /* not MSDOS */
6740 linebuffer_init (&path);
6741 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
6742 if (pipe == NULL || readline_internal (&path, pipe) == 0)
6747 #endif /* not MSDOS */
6748 #endif /* not HAVE_GETCWD */
6751 /* Return a newly allocated string containing the file name of FILE
6752 relative to the absolute directory DIR (which should end with a slash). */
6754 relative_filename (file, dir)
6757 char *fp, *dp, *afn, *res;
6760 /* Find the common root of file and dir (with a trailing slash). */
6761 afn = absolute_filename (file, cwd);
6764 while (*fp++ == *dp++)
6766 fp--, dp--; /* back to the first differing char */
6768 if (fp == afn && afn[0] != '/') /* cannot build a relative name */
6771 do /* look at the equal chars until '/' */
6775 /* Build a sequence of "../" strings for the resulting relative file name. */
6777 while ((dp = etags_strchr (dp + 1, '/')) != NULL)
6779 res = xnew (3*i + strlen (fp + 1) + 1, char);
6782 strcat (res, "../");
6784 /* Add the file name relative to the common root of file and dir. */
6785 strcat (res, fp + 1);
6791 /* Return a newly allocated string containing the absolute file name
6792 of FILE given DIR (which should end with a slash). */
6794 absolute_filename (file, dir)
6797 char *slashp, *cp, *res;
6799 if (filename_is_absolute (file))
6800 res = savestr (file);
6802 /* We don't support non-absolute file names with a drive
6803 letter, like `d:NAME' (it's too much hassle). */
6804 else if (file[1] == ':')
6805 fatal ("%s: relative file names with drive letters not supported", file);
6808 res = concat (dir, file, "");
6810 /* Delete the "/dirname/.." and "/." substrings. */
6811 slashp = etags_strchr (res, '/');
6812 while (slashp != NULL && slashp[0] != '\0')
6814 if (slashp[1] == '.')
6816 if (slashp[2] == '.'
6817 && (slashp[3] == '/' || slashp[3] == '\0'))
6822 while (cp >= res && !filename_is_absolute (cp));
6824 cp = slashp; /* the absolute name begins with "/.." */
6826 /* Under MSDOS and NT we get `d:/NAME' as absolute
6827 file name, so the luser could say `d:/../NAME'.
6828 We silently treat this as `d:/NAME'. */
6829 else if (cp[0] != '/')
6832 strcpy (cp, slashp + 3);
6836 else if (slashp[2] == '/' || slashp[2] == '\0')
6838 strcpy (slashp, slashp + 2);
6843 slashp = etags_strchr (slashp + 1, '/');
6846 if (res[0] == '\0') /* just a safety net: should never happen */
6849 return savestr ("/");
6855 /* Return a newly allocated string containing the absolute
6856 file name of dir where FILE resides given DIR (which should
6857 end with a slash). */
6859 absolute_dirname (file, dir)
6865 canonicalize_filename (file);
6866 slashp = etags_strrchr (file, '/');
6868 return savestr (dir);
6871 res = absolute_filename (file, dir);
6877 /* Whether the argument string is an absolute file name. The argument
6878 string must have been canonicalized with canonicalize_filename. */
6880 filename_is_absolute (fn)
6883 return (fn[0] == '/'
6885 || (ISALPHA(fn[0]) && fn[1] == ':' && fn[2] == '/')
6890 /* Translate backslashes into slashes. Works in place. */
6892 canonicalize_filename (fn)
6896 /* Canonicalize drive letter case. */
6897 if (fn[0] != '\0' && fn[1] == ':' && ISLOWER (fn[0]))
6898 fn[0] = upcase (fn[0]);
6899 /* Convert backslashes to slashes. */
6900 for (; *fn != '\0'; fn++)
6905 fn = NULL; /* shut up the compiler */
6910 /* Initialize a linebuffer for use */
6912 linebuffer_init (lbp)
6915 lbp->size = (DEBUG) ? 3 : 200;
6916 lbp->buffer = xnew (lbp->size, char);
6917 lbp->buffer[0] = '\0';
6921 /* Set the minimum size of a string contained in a linebuffer. */
6923 linebuffer_setlen (lbp, toksize)
6927 while (lbp->size <= toksize)
6930 xrnew (lbp->buffer, lbp->size, char);
6935 /* Like malloc but get fatal error if memory is exhausted. */
6940 PTR result = (PTR) malloc (size);
6942 fatal ("virtual memory exhausted", (char *)NULL);
6947 xrealloc (ptr, size)
6951 PTR result = (PTR) realloc (ptr, size);
6953 fatal ("virtual memory exhausted", (char *)NULL);
6959 * indent-tabs-mode: t
6962 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc" "node" "regexp")
6963 * c-file-style: "gnu"
6967 /* arch-tag: 8a9b748d-390c-4922-99db-2eeefa921051
6968 (do not change this comment) */
6970 /* etags.c ends here */