1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
2 Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2001, 2002
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * 1989 Sam Kendall added C++.
28 * 1992 Joseph B. Wells improved C and C++ parsing.
29 * 1993 Francesco Potortì reorganised C and C++.
30 * 1994 Line-by-line regexp tags by Tom Tromey.
31 * 2001 Nested classes by Francesco Potortì (concept by Mykola Dzyuba).
32 * 2002 #line directives by Francesco Potortì.
34 * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
38 * If you want to add support for a new language, start by looking at the LUA
39 * language, which is the simplest. Alternatively, consider shipping a
40 * configuration file containing regexp definitions for etags.
43 char pot_etags_version
[] = "@(#) pot revision number is 17.5";
53 # define NDEBUG /* disable assert */
58 /* On some systems, Emacs defines static as nothing for the sake
59 of unexec. We don't want that here since we don't use unexec. */
61 # define ETAGS_REGEXPS /* use the regexp features */
62 # define LONG_OPTIONS /* accept long options */
63 # ifndef PTR /* for Xemacs */
66 # ifndef __P /* for Xemacs */
67 # define __P(args) args
69 #else /* no config.h */
70 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
71 # define __P(args) args /* use prototypes */
72 # define PTR void * /* for generic pointers */
73 # else /* not standard C */
74 # define __P(args) () /* no prototypes */
75 # define const /* remove const for old compilers' sake */
76 # define PTR long * /* don't use void* */
78 #endif /* !HAVE_CONFIG_H */
81 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
86 # define LONG_OPTIONS TRUE
88 # define LONG_OPTIONS FALSE
91 /* WIN32_NATIVE is for Xemacs.
92 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
97 #endif /* WIN32_NATIVE */
103 # include <sys/param.h>
105 # ifndef HAVE_CONFIG_H
107 # include <sys/config.h>
119 # define MAXPATHLEN _MAX_PATH
125 # endif /* undef HAVE_GETCWD */
126 #else /* not WINDOWSNT */
130 # else /* no standard C headers */
131 extern char *getenv ();
133 # define EXIT_SUCCESS 1
134 # define EXIT_FAILURE 0
136 # define EXIT_SUCCESS 0
137 # define EXIT_FAILURE 1
140 #endif /* !WINDOWSNT */
145 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
146 extern char *getcwd (char *buf
, size_t size
);
148 #endif /* HAVE_UNISTD_H */
156 #include <sys/types.h>
157 #include <sys/stat.h>
161 # undef assert /* some systems have a buggy assert.h */
162 # define assert(x) ((void) 0)
165 #if !defined (S_ISREG) && defined (S_IFREG)
166 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
172 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
174 extern int optind
, opterr
;
175 #endif /* LONG_OPTIONS */
178 # ifndef HAVE_CONFIG_H /* this is a standalone compilation */
179 # ifdef __CYGWIN__ /* compiling on Cygwin */
181 the regex
.h distributed with Cygwin is
not compatible with etags
, alas
!
182 If you want regular expression support
, you should
delete this notice
and
183 arrange to use the GNU regex
.h
and regex
.c
.
187 #endif /* ETAGS_REGEXPS */
189 /* Define CTAGS to make the program "ctags" compatible with the usual one.
190 Leave it undefined to make the program "etags", which makes emacs-style
191 tag tables and tags typedefs, #defines and struct/union/enum by default. */
199 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
200 #define strcaseeq(s,t) (assert((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t))
201 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
202 #define strncaseeq(s,t,n) (assert((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n))
204 #define CHARS 256 /* 2^sizeof(char) */
205 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
206 #define iswhite(c) (_wht[CHAR(c)]) /* c is white (see white) */
207 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name (see nonam) */
208 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token (see begtk) */
209 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token (see midtk) */
210 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens (see endtk) */
212 #define ISALNUM(c) isalnum (CHAR(c))
213 #define ISALPHA(c) isalpha (CHAR(c))
214 #define ISDIGIT(c) isdigit (CHAR(c))
215 #define ISLOWER(c) islower (CHAR(c))
217 #define lowcase(c) tolower (CHAR(c))
218 #define upcase(c) toupper (CHAR(c))
222 * xnew, xrnew -- allocate, reallocate storage
224 * SYNOPSIS: Type *xnew (int n, Type);
225 * void xrnew (OldPointer, int n, Type);
228 # include "chkmalloc.h"
229 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
230 (n) * sizeof (Type)))
231 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
232 (char *) (op), (n) * sizeof (Type)))
234 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
235 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
236 (char *) (op), (n) * sizeof (Type)))
241 typedef void Lang_function
__P((FILE *));
245 char *suffix
; /* file name suffix for this compressor */
246 char *command
; /* takes one arg and decompresses to stdout */
251 char *name
; /* language name */
252 char *help
; /* detailed help for the language */
253 Lang_function
*function
; /* parse function */
254 char **suffixes
; /* name suffixes of this language's files */
255 char **filenames
; /* names of this language's files */
256 char **interpreters
; /* interpreters for this language */
257 bool metasource
; /* source used to generate other sources */
262 struct fdesc
*next
; /* for the linked list */
263 char *infname
; /* uncompressed input file name */
264 char *infabsname
; /* absolute uncompressed input file name */
265 char *infabsdir
; /* absolute dir of input file */
266 char *taggedfname
; /* file name to write in tagfile */
267 language
*lang
; /* language of file */
268 char *prop
; /* file properties to write in tagfile */
269 bool usecharno
; /* etags tags shall contain char number */
270 bool written
; /* entry written in the tags file */
273 typedef struct node_st
274 { /* sorting structure */
275 struct node_st
*left
, *right
; /* left and right sons */
276 fdesc
*fdp
; /* description of file to whom tag belongs */
277 char *name
; /* tag name */
278 char *regex
; /* search regexp */
279 bool valid
; /* write this tag on the tag file */
280 bool is_func
; /* function tag: use regexp in CTAGS mode */
281 bool been_warned
; /* warning already given for duplicated tag */
282 int lno
; /* line number tag is on */
283 long cno
; /* character number line starts on */
287 * A `linebuffer' is a structure which holds a line of text.
288 * `readline_internal' reads a line from a stream into a linebuffer
289 * and works regardless of the length of the line.
290 * SIZE is the size of BUFFER, LEN is the length of the string in
291 * BUFFER after readline reads it.
300 /* Used to support mixing of --lang and file names. */
304 at_language
, /* a language specification */
305 at_regexp
, /* a regular expression */
306 at_filename
, /* a file name */
307 at_stdin
, /* read from stdin here */
308 at_end
/* stop parsing the list */
309 } arg_type
; /* argument type */
310 language
*lang
; /* language associated with the argument */
311 char *what
; /* the argument itself */
315 /* Structure defining a regular expression. */
316 typedef struct regexp
318 struct regexp
*p_next
; /* pointer to next in list */
319 language
*lang
; /* if set, use only for this language */
320 char *pattern
; /* the regexp pattern */
321 char *name
; /* tag name */
322 struct re_pattern_buffer
*pat
; /* the compiled pattern */
323 struct re_registers regs
; /* re registers */
324 bool error_signaled
; /* already signaled for this regexp */
325 bool force_explicit_name
; /* do not allow implict tag name */
326 bool ignore_case
; /* ignore case when matching */
327 bool multi_line
; /* do a multi-line match on the whole file */
329 #endif /* ETAGS_REGEXPS */
332 /* Many compilers barf on this:
333 Lang_function Ada_funcs;
334 so let's write it this way */
335 static void Ada_funcs
__P((FILE *));
336 static void Asm_labels
__P((FILE *));
337 static void C_entries
__P((int c_ext
, FILE *));
338 static void default_C_entries
__P((FILE *));
339 static void plain_C_entries
__P((FILE *));
340 static void Cjava_entries
__P((FILE *));
341 static void Cobol_paragraphs
__P((FILE *));
342 static void Cplusplus_entries
__P((FILE *));
343 static void Cstar_entries
__P((FILE *));
344 static void Erlang_functions
__P((FILE *));
345 static void Fortran_functions
__P((FILE *));
346 static void HTML_labels
__P((FILE *));
347 static void Lisp_functions
__P((FILE *));
348 static void Lua_functions
__P((FILE *));
349 static void Makefile_targets
__P((FILE *));
350 static void Pascal_functions
__P((FILE *));
351 static void Perl_functions
__P((FILE *));
352 static void PHP_functions
__P((FILE *));
353 static void PS_functions
__P((FILE *));
354 static void Prolog_functions
__P((FILE *));
355 static void Python_functions
__P((FILE *));
356 static void Scheme_functions
__P((FILE *));
357 static void TeX_commands
__P((FILE *));
358 static void Texinfo_nodes
__P((FILE *));
359 static void Yacc_entries
__P((FILE *));
360 static void just_read_file
__P((FILE *));
362 static void print_language_names
__P((void));
363 static void print_version
__P((void));
364 static void print_help
__P((argument
*));
365 int main
__P((int, char **));
367 static compressor
*get_compressor_from_suffix
__P((char *, char **));
368 static language
*get_language_from_langname
__P((const char *));
369 static language
*get_language_from_interpreter
__P((char *));
370 static language
*get_language_from_filename
__P((char *, bool));
371 static void readline
__P((linebuffer
*, FILE *));
372 static long readline_internal
__P((linebuffer
*, FILE *));
373 static bool nocase_tail
__P((char *));
374 static void get_tag
__P((char *, char **));
377 static void analyse_regex
__P((char *));
378 static void free_regexps
__P((void));
379 static void regex_tag_multiline
__P((void));
380 #endif /* ETAGS_REGEXPS */
381 static void error
__P((const char *, const char *));
382 static void suggest_asking_for_help
__P((void));
383 void fatal
__P((char *, char *));
384 static void pfatal
__P((char *));
385 static void add_node
__P((node
*, node
**));
387 static void init
__P((void));
388 static void process_file_name
__P((char *, language
*));
389 static void process_file
__P((FILE *, char *, language
*));
390 static void find_entries
__P((FILE *));
391 static void free_tree
__P((node
*));
392 static void free_fdesc
__P((fdesc
*));
393 static void pfnote
__P((char *, bool, char *, int, int, long));
394 static void make_tag
__P((char *, int, bool, char *, int, int, long));
395 static void invalidate_nodes
__P((fdesc
*, node
**));
396 static void put_entries
__P((node
*));
398 static char *concat
__P((char *, char *, char *));
399 static char *skip_spaces
__P((char *));
400 static char *skip_non_spaces
__P((char *));
401 static char *savenstr
__P((char *, int));
402 static char *savestr
__P((char *));
403 static char *etags_strchr
__P((const char *, int));
404 static char *etags_strrchr
__P((const char *, int));
405 static int etags_strcasecmp
__P((const char *, const char *));
406 static int etags_strncasecmp
__P((const char *, const char *, int));
407 static char *etags_getcwd
__P((void));
408 static char *relative_filename
__P((char *, char *));
409 static char *absolute_filename
__P((char *, char *));
410 static char *absolute_dirname
__P((char *, char *));
411 static bool filename_is_absolute
__P((char *f
));
412 static void canonicalize_filename
__P((char *));
413 static void linebuffer_init
__P((linebuffer
*));
414 static void linebuffer_setlen
__P((linebuffer
*, int));
415 static PTR xmalloc
__P((unsigned int));
416 static PTR xrealloc
__P((char *, unsigned int));
419 static char searchar
= '/'; /* use /.../ searches */
421 static char *tagfile
; /* output file */
422 static char *progname
; /* name this program was invoked with */
423 static char *cwd
; /* current working directory */
424 static char *tagfiledir
; /* directory of tagfile */
425 static FILE *tagf
; /* ioptr for tags file */
427 static fdesc
*fdhead
; /* head of file description list */
428 static fdesc
*curfdp
; /* current file description */
429 static int lineno
; /* line number of current line */
430 static long charno
; /* current character number */
431 static long linecharno
; /* charno of start of current line */
432 static char *dbp
; /* pointer to start of current tag */
434 static const int invalidcharno
= -1;
436 static node
*nodehead
; /* the head of the binary tree of tags */
437 static node
*last_node
; /* the last node created */
439 static linebuffer lb
; /* the current line */
440 static linebuffer filebuf
; /* a buffer containing the whole file */
441 static linebuffer token_name
; /* a buffer containing a tag name */
443 /* boolean "functions" (see init) */
444 static bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
447 *white
= " \f\t\n\r\v",
449 *nonam
= " \f\t\n\r()=,;", /* look at make_tag before modifying! */
450 /* token ending chars */
451 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
452 /* token starting chars */
453 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
454 /* valid in-token chars */
455 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
457 static bool append_to_tagfile
; /* -a: append to tags */
458 /* The next four default to TRUE for etags, but to FALSE for ctags. */
459 static bool typedefs
; /* -t: create tags for C and Ada typedefs */
460 static bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
461 /* 0 struct/enum/union decls, and C++ */
462 /* member functions. */
463 static bool constantypedefs
; /* -d: create tags for C #define, enum */
464 /* constants and variables. */
465 /* -D: opposite of -d. Default under ctags. */
466 static bool globals
; /* create tags for global variables */
467 static bool declarations
; /* --declarations: tag them and extern in C&Co*/
468 static bool members
; /* create tags for C member variables */
469 static bool no_line_directive
; /* ignore #line directives (undocumented) */
470 static bool update
; /* -u: update tags */
471 static bool vgrind_style
; /* -v: create vgrind style index output */
472 static bool no_warnings
; /* -w: suppress warnings */
473 static bool cxref_style
; /* -x: create cxref style output */
474 static bool cplusplus
; /* .[hc] means C++, not C */
475 static bool ignoreindent
; /* -I: ignore indentation in C */
476 static bool packages_only
; /* --packages-only: in Ada, only tag packages*/
478 #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
479 static bool parsing_stdin
; /* --parse-stdin used */
482 static regexp
*p_head
; /* list of all regexps */
483 static bool need_filebuf
; /* some regexes are multi-line */
485 # define need_filebuf FALSE
486 #endif /* ETAGS_REGEXPS */
489 static struct option longopts
[] =
491 { "packages-only", no_argument
, &packages_only
, TRUE
},
492 { "c++", no_argument
, NULL
, 'C' },
493 { "declarations", no_argument
, &declarations
, TRUE
},
494 { "no-line-directive", no_argument
, &no_line_directive
, TRUE
},
495 { "help", no_argument
, NULL
, 'h' },
496 { "help", no_argument
, NULL
, 'H' },
497 { "ignore-indentation", no_argument
, NULL
, 'I' },
498 { "language", required_argument
, NULL
, 'l' },
499 { "members", no_argument
, &members
, TRUE
},
500 { "no-members", no_argument
, &members
, FALSE
},
501 { "output", required_argument
, NULL
, 'o' },
503 { "regex", required_argument
, NULL
, 'r' },
504 { "no-regex", no_argument
, NULL
, 'R' },
505 { "ignore-case-regex", required_argument
, NULL
, 'c' },
506 #endif /* ETAGS_REGEXPS */
507 { "parse-stdin", required_argument
, NULL
, STDIN
},
508 { "version", no_argument
, NULL
, 'V' },
510 #if CTAGS /* Etags options */
511 { "backward-search", no_argument
, NULL
, 'B' },
512 { "cxref", no_argument
, NULL
, 'x' },
513 { "defines", no_argument
, NULL
, 'd' },
514 { "globals", no_argument
, &globals
, TRUE
},
515 { "typedefs", no_argument
, NULL
, 't' },
516 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
517 { "update", no_argument
, NULL
, 'u' },
518 { "vgrind", no_argument
, NULL
, 'v' },
519 { "no-warn", no_argument
, NULL
, 'w' },
521 #else /* Ctags options */
522 { "append", no_argument
, NULL
, 'a' },
523 { "no-defines", no_argument
, NULL
, 'D' },
524 { "no-globals", no_argument
, &globals
, FALSE
},
525 { "include", required_argument
, NULL
, 'i' },
529 #endif /* LONG_OPTIONS */
531 static compressor compressors
[] =
533 { "z", "gzip -d -c"},
534 { "Z", "gzip -d -c"},
535 { "gz", "gzip -d -c"},
536 { "GZ", "gzip -d -c"},
537 { "bz2", "bzip2 -d -c" },
546 static char *Ada_suffixes
[] =
547 { "ads", "adb", "ada", NULL
};
548 static char Ada_help
[] =
549 "In Ada code, functions, procedures, packages, tasks and types are\n\
550 tags. Use the `--packages-only' option to create tags for\n\
552 Ada tag names have suffixes indicating the type of entity:\n\
553 Entity type: Qualifier:\n\
554 ------------ ----------\n\
561 Thus, `M-x find-tag <RET> bidule/b <RET>' will go directly to the\n\
562 body of the package `bidule', while `M-x find-tag <RET> bidule <RET>'\n\
563 will just search for any tag `bidule'.";
566 static char *Asm_suffixes
[] =
567 { "a", /* Unix assembler */
568 "asm", /* Microcontroller assembly */
569 "def", /* BSO/Tasking definition includes */
570 "inc", /* Microcontroller include files */
571 "ins", /* Microcontroller include files */
572 "s", "sa", /* Unix assembler */
573 "S", /* cpp-processed Unix assembler */
574 "src", /* BSO/Tasking C compiler output */
577 static char Asm_help
[] =
578 "In assembler code, labels appearing at the beginning of a line,\n\
579 followed by a colon, are tags.";
582 /* Note that .c and .h can be considered C++, if the --c++ flag was
583 given, or if the `class' or `template' keyowrds are met inside the file.
584 That is why default_C_entries is called for these. */
585 static char *default_C_suffixes
[] =
587 static char default_C_help
[] =
588 "In C code, any C function or typedef is a tag, and so are\n\
589 definitions of `struct', `union' and `enum'. `#define' macro\n\
590 definitions and `enum' constants are tags unless you specify\n\
591 `--no-defines'. Global variables are tags unless you specify\n\
592 `--no-globals'. Use of `--no-globals' and `--no-defines'\n\
593 can make the tags table file much smaller.\n\
594 You can tag function declarations and external variables by\n\
595 using `--declarations', and struct members by using `--members'.";
597 static char *Cplusplus_suffixes
[] =
598 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
599 "M", /* Objective C++ */
600 "pdb", /* Postscript with C syntax */
602 static char Cplusplus_help
[] =
603 "In C++ code, all the tag constructs of C code are tagged. (Use\n\
604 --help --lang=c --lang=c++ for full help.)\n\
605 In addition to C tags, member functions are also recognized, and\n\
606 optionally member variables if you use the `--members' option.\n\
607 Tags for variables and functions in classes are named `CLASS::VARIABLE'\n\
608 and `CLASS::FUNCTION'. `operator' definitions have tag names like\n\
611 static char *Cjava_suffixes
[] =
613 static char Cjava_help
[] =
614 "In Java code, all the tags constructs of C and C++ code are\n\
615 tagged. (Use --help --lang=c --lang=c++ --lang=java for full help.)";
618 static char *Cobol_suffixes
[] =
619 { "COB", "cob", NULL
};
620 static char Cobol_help
[] =
621 "In Cobol code, tags are paragraph names; that is, any word\n\
622 starting in column 8 and followed by a period.";
624 static char *Cstar_suffixes
[] =
625 { "cs", "hs", NULL
};
627 static char *Erlang_suffixes
[] =
628 { "erl", "hrl", NULL
};
629 static char Erlang_help
[] =
630 "In Erlang code, the tags are the functions, records and macros\n\
631 defined in the file.";
633 static char *Fortran_suffixes
[] =
634 { "F", "f", "f90", "for", NULL
};
635 static char Fortran_help
[] =
636 "In Fortran code, functions, subroutines and block data are tags.";
638 static char *HTML_suffixes
[] =
639 { "htm", "html", "shtml", NULL
};
640 static char HTML_help
[] =
641 "In HTML input files, the tags are the `title' and the `h1', `h2',\n\
642 `h3' headers. Also, tags are `name=' in anchors and all\n\
643 occurrences of `id='.";
645 static char *Lisp_suffixes
[] =
646 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
647 static char Lisp_help
[] =
648 "In Lisp code, any function defined with `defun', any variable\n\
649 defined with `defvar' or `defconst', and in general the first\n\
650 argument of any expression that starts with `(def' in column zero\n\
653 static char *Lua_suffixes
[] =
654 { "lua", "LUA", NULL
};
655 static char Lua_help
[] =
656 "In Lua scripts, all functions are tags.";
658 static char *Makefile_filenames
[] =
659 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
660 static char Makefile_help
[] =
661 "In makefiles, targets are tags; additionally, variables are tags\n\
662 unless you specify `--no-globals'.";
664 static char *Objc_suffixes
[] =
665 { "lm", /* Objective lex file */
666 "m", /* Objective C file */
668 static char Objc_help
[] =
669 "In Objective C code, tags include Objective C definitions for classes,\n\
670 class categories, methods and protocols. Tags for variables and\n\
671 functions in classes are named `CLASS::VARIABLE' and `CLASS::FUNCTION'.";
673 static char *Pascal_suffixes
[] =
674 { "p", "pas", NULL
};
675 static char Pascal_help
[] =
676 "In Pascal code, the tags are the functions and procedures defined\n\
679 static char *Perl_suffixes
[] =
680 { "pl", "pm", NULL
};
681 static char *Perl_interpreters
[] =
682 { "perl", "@PERL@", NULL
};
683 static char Perl_help
[] =
684 "In Perl code, the tags are the packages, subroutines and variables\n\
685 defined by the `package', `sub', `my' and `local' keywords. Use\n\
686 `--globals' if you want to tag global variables. Tags for\n\
687 subroutines are named `PACKAGE::SUB'. The name for subroutines\n\
688 defined in the default package is `main::SUB'.";
690 static char *PHP_suffixes
[] =
691 { "php", "php3", "php4", NULL
};
692 static char PHP_help
[] =
693 "In PHP code, tags are functions, classes and defines. When using\n\
694 the `--members' option, vars are tags too.";
696 static char *plain_C_suffixes
[] =
697 { "pc", /* Pro*C file */
700 static char *PS_suffixes
[] =
701 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
702 static char PS_help
[] =
703 "In PostScript code, the tags are the functions.";
705 static char *Prolog_suffixes
[] =
707 static char Prolog_help
[] =
708 "In Prolog code, tags are predicates and rules at the beginning of\n\
711 static char *Python_suffixes
[] =
713 static char Python_help
[] =
714 "In Python code, `def' or `class' at the beginning of a line\n\
717 /* Can't do the `SCM' or `scm' prefix with a version number. */
718 static char *Scheme_suffixes
[] =
719 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
720 static char Scheme_help
[] =
721 "In Scheme code, tags include anything defined with `def' or with a\n\
722 construct whose name starts with `def'. They also include\n\
723 variables set with `set!' at top level in the file.";
725 static char *TeX_suffixes
[] =
726 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
727 static char TeX_help
[] =
728 "In LaTeX text, the argument of any of the commands `\\chapter',\n\
729 `\\section', `\\subsection', `\\subsubsection', `\\eqno', `\\label',\n\
730 `\\ref', `\\cite', `\\bibitem', `\\part', `\\appendix', `\\entry',\n\
731 `\\index', `\\def', `\\newcommand', `\\renewcommand',\n\
732 `\\newenvironment' or `\\renewenvironment' is a tag.\n\
734 Other commands can be specified by setting the environment variable\n\
735 `TEXTAGS' to a colon-separated list like, for example,\n\
736 TEXTAGS=\"mycommand:myothercommand\".";
739 static char *Texinfo_suffixes
[] =
740 { "texi", "texinfo", "txi", NULL
};
741 static char Texinfo_help
[] =
742 "for texinfo files, lines starting with @node are tagged.";
744 static char *Yacc_suffixes
[] =
745 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
746 static char Yacc_help
[] =
747 "In Bison or Yacc input files, each rule defines as a tag the\n\
748 nonterminal it constructs. The portions of the file that contain\n\
749 C code are parsed as C code (use --help --lang=c --lang=yacc\n\
752 static char auto_help
[] =
753 "`auto' is not a real language, it indicates to use\n\
754 a default language for files base on file name suffix and file contents.";
756 static char none_help
[] =
757 "`none' is not a real language, it indicates to only do\n\
758 regexp processing on files.";
760 static char no_lang_help
[] =
761 "No detailed help available for this language.";
765 * Table of languages.
767 * It is ok for a given function to be listed under more than one
768 * name. I just didn't.
771 static language lang_names
[] =
773 { "ada", Ada_help
, Ada_funcs
, Ada_suffixes
},
774 { "asm", Asm_help
, Asm_labels
, Asm_suffixes
},
775 { "c", default_C_help
, default_C_entries
, default_C_suffixes
},
776 { "c++", Cplusplus_help
, Cplusplus_entries
, Cplusplus_suffixes
},
777 { "c*", no_lang_help
, Cstar_entries
, Cstar_suffixes
},
778 { "cobol", Cobol_help
, Cobol_paragraphs
, Cobol_suffixes
},
779 { "erlang", Erlang_help
, Erlang_functions
, Erlang_suffixes
},
780 { "fortran", Fortran_help
, Fortran_functions
, Fortran_suffixes
},
781 { "html", HTML_help
, HTML_labels
, HTML_suffixes
},
782 { "java", Cjava_help
, Cjava_entries
, Cjava_suffixes
},
783 { "lisp", Lisp_help
, Lisp_functions
, Lisp_suffixes
},
784 { "lua", Lua_help
, Lua_functions
, Lua_suffixes
},
785 { "makefile", Makefile_help
,Makefile_targets
,NULL
,Makefile_filenames
},
786 { "objc", Objc_help
, plain_C_entries
, Objc_suffixes
},
787 { "pascal", Pascal_help
, Pascal_functions
, Pascal_suffixes
},
788 { "perl",Perl_help
,Perl_functions
,Perl_suffixes
,NULL
,Perl_interpreters
},
789 { "php", PHP_help
, PHP_functions
, PHP_suffixes
},
790 { "postscript",PS_help
, PS_functions
, PS_suffixes
},
791 { "proc", no_lang_help
, plain_C_entries
, plain_C_suffixes
},
792 { "prolog", Prolog_help
, Prolog_functions
, Prolog_suffixes
},
793 { "python", Python_help
, Python_functions
, Python_suffixes
},
794 { "scheme", Scheme_help
, Scheme_functions
, Scheme_suffixes
},
795 { "tex", TeX_help
, TeX_commands
, TeX_suffixes
},
796 { "texinfo", Texinfo_help
, Texinfo_nodes
, Texinfo_suffixes
},
797 { "yacc", Yacc_help
,Yacc_entries
,Yacc_suffixes
,NULL
,NULL
,TRUE
},
798 { "auto", auto_help
}, /* default guessing scheme */
799 { "none", none_help
, just_read_file
}, /* regexp matching only */
800 { NULL
} /* end of list */
805 print_language_names ()
810 puts ("\nThese are the currently supported languages, along with the\n\
811 default file names and dot suffixes:");
812 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
814 printf (" %-*s", 10, lang
->name
);
815 if (lang
->filenames
!= NULL
)
816 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
817 printf (" %s", *name
);
818 if (lang
->suffixes
!= NULL
)
819 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
820 printf (" .%s", *ext
);
823 puts ("where `auto' means use default language for files based on file\n\
824 name suffix, and `none' means only do regexp processing on files.\n\
825 If no language is specified and no matching suffix is found,\n\
826 the first line of the file is read for a sharp-bang (#!) sequence\n\
827 followed by the name of an interpreter. If no such sequence is found,\n\
828 Fortran is tried first; if no tags are found, C is tried next.\n\
829 When parsing any C file, a \"class\" or \"template\" keyword\n\
831 puts ("Compressed files are supported using gzip and bzip2.\n\
833 For detailed help on a given language use, for example,\n\
834 etags --help --lang=ada.");
838 # define EMACS_NAME "standalone"
841 # define VERSION "version"
846 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
847 puts ("Copyright (C) 2002 Free Software Foundation, Inc. and Ken Arnold");
848 puts ("This program is distributed under the same terms as Emacs");
854 print_help (argbuffer
)
857 bool help_for_lang
= FALSE
;
859 for (; argbuffer
->arg_type
!= at_end
; argbuffer
++)
860 if (argbuffer
->arg_type
== at_language
)
864 puts (argbuffer
->lang
->help
);
865 help_for_lang
= TRUE
;
871 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
873 These are the options accepted by %s.\n", progname
, progname
);
875 puts ("You may use unambiguous abbreviations for the long option names.");
877 puts ("Long option names do not work with this executable, as it is not\n\
878 linked with GNU getopt.");
879 puts (" A - as file name means read names from stdin (one per line).\n\
880 Absolute names are stored in the output file as they are.\n\
881 Relative ones are stored relative to the output file's directory.\n");
884 puts ("-a, --append\n\
885 Append tag entries to existing tags file.");
887 puts ("--packages-only\n\
888 For Ada files, only generate tags for packages.");
891 puts ("-B, --backward-search\n\
892 Write the search commands for the tag entries using '?', the\n\
893 backward-search command instead of '/', the forward-search command.");
895 /* This option is mostly obsolete, because etags can now automatically
896 detect C++. Retained for backward compatibility and for debugging and
897 experimentation. In principle, we could want to tag as C++ even
898 before any "class" or "template" keyword.
900 Treat files whose name suffix defaults to C language as C++ files.");
903 puts ("--declarations\n\
904 In C and derived languages, create tags for function declarations,");
906 puts ("\tand create tags for extern variables if --globals is used.");
909 ("\tand create tags for extern variables unless --no-globals is used.");
912 puts ("-d, --defines\n\
913 Create tag entries for C #define constants and enum constants, too.");
915 puts ("-D, --no-defines\n\
916 Don't create tag entries for C #define constants and enum constants.\n\
917 This makes the tags file smaller.");
920 puts ("-i FILE, --include=FILE\n\
921 Include a note in tag file indicating that, when searching for\n\
922 a tag, one should also consult the tags file FILE after\n\
923 checking the current file.");
925 puts ("-l LANG, --language=LANG\n\
926 Force the following files to be considered as written in the\n\
927 named language up to the next --language=LANG option.");
931 Create tag entries for global variables in some languages.");
933 puts ("--no-globals\n\
934 Do not create tag entries for global variables in some\n\
935 languages. This makes the tags file smaller.");
937 Create tag entries for members of structures in some languages.");
940 puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
941 Make a tag for each line matching a regular expression pattern\n\
942 in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
943 files only. REGEXFILE is a file containing one REGEXP per line.\n\
944 REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\
945 optional. The TAGREGEXP pattern is anchored (as if preceded by ^).");
946 puts (" If TAGNAME/ is present, the tags created are named.\n\
947 For example Tcl named tags can be created with:\n\
948 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\".\n\
949 MODS are optional one-letter modifiers: `i' means to ignore case,\n\
950 `m' means to allow multi-line matches, `s' implies `m' and\n\
951 causes dot to match any character, including newline.");
952 puts ("-R, --no-regex\n\
953 Don't create tags from regexps for the following files.");
954 #endif /* ETAGS_REGEXPS */
955 puts ("-I, --ignore-indentation\n\
956 In C and C++ do not assume that a closing brace in the first\n\
957 column is the final brace of a function or structure definition.");
958 puts ("-o FILE, --output=FILE\n\
959 Write the tags to FILE.");
960 puts ("--parse-stdin=NAME\n\
961 Read from standard input and record tags as belonging to file NAME.");
965 puts ("-t, --typedefs\n\
966 Generate tag entries for C and Ada typedefs.");
967 puts ("-T, --typedefs-and-c++\n\
968 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
969 and C++ member functions.");
973 puts ("-u, --update\n\
974 Update the tag entries for the given files, leaving tag\n\
975 entries for other files in place. Currently, this is\n\
976 implemented by deleting the existing entries for the given\n\
977 files and then rewriting the new entries at the end of the\n\
978 tags file. It is often faster to simply rebuild the entire\n\
979 tag file than to use this.");
983 puts ("-v, --vgrind\n\
984 Generates an index of items intended for human consumption,\n\
985 similar to the output of vgrind. The index is sorted, and\n\
986 gives the page number of each item.");
987 puts ("-w, --no-warn\n\
988 Suppress warning messages about entries defined in multiple\n\
990 puts ("-x, --cxref\n\
991 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
992 The output uses line numbers instead of page numbers, but\n\
993 beyond that the differences are cosmetic; try both to see\n\
997 puts ("-V, --version\n\
998 Print the version of the program.\n\
1000 Print this help message.\n\
1001 Followed by one or more `--language' options prints detailed\n\
1002 help about tag generation for the specified languages.");
1004 print_language_names ();
1007 puts ("Report bugs to bug-gnu-emacs@gnu.org");
1009 exit (EXIT_SUCCESS
);
1013 #ifdef VMS /* VMS specific functions */
1017 /* This is a BUG! ANY arbitrary limit is a BUG!
1018 Won't someone please fix this? */
1019 #define MAX_FILE_SPEC_LEN 255
1022 char body
[MAX_FILE_SPEC_LEN
+ 1];
1026 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
1027 returning in each successive call the next file name matching the input
1028 spec. The function expects that each in_spec passed
1029 to it will be processed to completion; in particular, up to and
1030 including the call following that in which the last matching name
1031 is returned, the function ignores the value of in_spec, and will
1032 only start processing a new spec with the following call.
1033 If an error occurs, on return out_spec contains the value
1034 of in_spec when the error occurred.
1036 With each successive file name returned in out_spec, the
1037 function's return value is one. When there are no more matching
1038 names the function returns zero. If on the first call no file
1039 matches in_spec, or there is any other error, -1 is returned.
1043 #include <descrip.h>
1044 #define OUTSIZE MAX_FILE_SPEC_LEN
1050 static long context
= 0;
1051 static struct dsc$descriptor_s o
;
1052 static struct dsc$descriptor_s i
;
1053 static bool pass1
= TRUE
;
1060 o
.dsc$a_pointer
= (char *) out
;
1061 o
.dsc$w_length
= (short)OUTSIZE
;
1062 i
.dsc$a_pointer
= in
;
1063 i
.dsc$w_length
= (short)strlen(in
);
1064 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
1065 i
.dsc$b_class
= DSC$K_CLASS_S
;
1066 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
1067 o
.dsc$b_class
= DSC$K_CLASS_VS
;
1069 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
1071 out
->body
[out
->curlen
] = EOS
;
1074 else if (status
== RMS$_NMF
)
1078 strcpy(out
->body
, in
);
1081 lib$
find_file_end(&context
);
1087 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
1088 name of each file specified by the provided arg expanding wildcards.
1091 gfnames (arg
, p_error
)
1095 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
1097 switch (fn_exp (&filename
, arg
))
1101 return filename
.body
;
1107 return filename
.body
;
1111 #ifndef OLD /* Newer versions of VMS do provide `system'. */
1115 error ("%s", "system() function not implemented under VMS");
1119 #define VERSION_DELIM ';'
1120 char *massage_name (s
)
1126 if (*s
== VERSION_DELIM
)
1144 unsigned int nincluded_files
;
1145 char **included_files
;
1146 argument
*argbuffer
;
1147 int current_arg
, file_count
;
1148 linebuffer filename_lb
;
1149 bool help_asked
= FALSE
;
1158 _fmode
= O_BINARY
; /* all of files are treated as binary files */
1162 nincluded_files
= 0;
1163 included_files
= xnew (argc
, char *);
1167 /* Allocate enough no matter what happens. Overkill, but each one
1169 argbuffer
= xnew (argc
, argument
);
1172 * If etags, always find typedefs and structure tags. Why not?
1173 * Also default to find macro constants, enum constants and
1178 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
1183 #ifdef ETAGS_REGEXPS
1184 optstring
= "-r:Rc:";
1185 #endif /* ETAGS_REGEXPS */
1188 optstring
= concat (optstring
,
1190 (CTAGS
) ? "BxdtTuvw" : "aDi:");
1192 while ((opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0)) != EOF
)
1196 /* If getopt returns 0, then it has already processed a
1197 long-named option. We should do nothing. */
1201 /* This means that a file name has been seen. Record it. */
1202 argbuffer
[current_arg
].arg_type
= at_filename
;
1203 argbuffer
[current_arg
].what
= optarg
;
1209 /* Parse standard input. Idea by Vivek <vivek@etla.org>. */
1210 argbuffer
[current_arg
].arg_type
= at_stdin
;
1211 argbuffer
[current_arg
].what
= optarg
;
1215 fatal ("cannot parse standard input more than once", (char *)NULL
);
1216 parsing_stdin
= TRUE
;
1219 /* Common options. */
1220 case 'C': cplusplus
= TRUE
; break;
1221 case 'f': /* for compatibility with old makefiles */
1225 error ("-o option may only be given once.", (char *)NULL
);
1226 suggest_asking_for_help ();
1232 case 'S': /* for backward compatibility */
1233 ignoreindent
= TRUE
;
1237 language
*lang
= get_language_from_langname (optarg
);
1240 argbuffer
[current_arg
].lang
= lang
;
1241 argbuffer
[current_arg
].arg_type
= at_language
;
1247 /* Backward compatibility: support obsolete --ignore-case-regexp. */
1248 optarg
= concat (optarg
, "i", ""); /* memory leak here */
1251 argbuffer
[current_arg
].arg_type
= at_regexp
;
1252 argbuffer
[current_arg
].what
= optarg
;
1256 argbuffer
[current_arg
].arg_type
= at_regexp
;
1257 argbuffer
[current_arg
].what
= NULL
;
1269 case 'a': append_to_tagfile
= TRUE
; break;
1270 case 'D': constantypedefs
= FALSE
; break;
1271 case 'i': included_files
[nincluded_files
++] = optarg
; break;
1273 /* Ctags options. */
1274 case 'B': searchar
= '?'; break;
1275 case 'd': constantypedefs
= TRUE
; break;
1276 case 't': typedefs
= TRUE
; break;
1277 case 'T': typedefs
= typedefs_or_cplusplus
= TRUE
; break;
1278 case 'u': update
= TRUE
; break;
1279 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1280 case 'x': cxref_style
= TRUE
; break;
1281 case 'w': no_warnings
= TRUE
; break;
1283 suggest_asking_for_help ();
1287 for (; optind
< argc
; optind
++)
1289 argbuffer
[current_arg
].arg_type
= at_filename
;
1290 argbuffer
[current_arg
].what
= argv
[optind
];
1295 argbuffer
[current_arg
].arg_type
= at_end
;
1298 print_help (argbuffer
);
1301 if (nincluded_files
== 0 && file_count
== 0)
1303 error ("no input files specified.", (char *)NULL
);
1304 suggest_asking_for_help ();
1308 if (tagfile
== NULL
)
1309 tagfile
= CTAGS
? "tags" : "TAGS";
1310 cwd
= etags_getcwd (); /* the current working directory */
1311 if (cwd
[strlen (cwd
) - 1] != '/')
1314 cwd
= concat (oldcwd
, "/", "");
1317 /* Relative file names are made relative to the current directory. */
1318 if (streq (tagfile
, "-")
1319 || strneq (tagfile
, "/dev/", 5))
1322 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1324 init (); /* set up boolean "functions" */
1326 linebuffer_init (&lb
);
1327 linebuffer_init (&filename_lb
);
1328 linebuffer_init (&filebuf
);
1329 linebuffer_init (&token_name
);
1333 if (streq (tagfile
, "-"))
1337 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1338 doesn't take effect until after `stdout' is already open). */
1339 if (!isatty (fileno (stdout
)))
1340 setmode (fileno (stdout
), O_BINARY
);
1344 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1350 * Loop through files finding functions.
1352 for (i
= 0; i
< current_arg
; i
++)
1354 static language
*lang
; /* non-NULL if language is forced */
1357 switch (argbuffer
[i
].arg_type
)
1360 lang
= argbuffer
[i
].lang
;
1362 #ifdef ETAGS_REGEXPS
1364 analyse_regex (argbuffer
[i
].what
);
1369 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1373 error ("can't find file %s\n", this_file
);
1378 this_file
= massage_name (this_file
);
1381 this_file
= argbuffer
[i
].what
;
1383 /* Input file named "-" means read file names from stdin
1384 (one per line) and use them. */
1385 if (streq (this_file
, "-"))
1388 fatal ("cannot parse standard input AND read file names from it",
1390 while (readline_internal (&filename_lb
, stdin
) > 0)
1391 process_file_name (filename_lb
.buffer
, lang
);
1394 process_file_name (this_file
, lang
);
1400 this_file
= argbuffer
[i
].what
;
1401 process_file (stdin
, this_file
, lang
);
1406 #ifdef ETAGS_REGEXPS
1408 #endif /* ETAGS_REGEXPS */
1410 free (filebuf
.buffer
);
1411 free (token_name
.buffer
);
1413 if (!CTAGS
|| cxref_style
)
1415 put_entries (nodehead
); /* write the remainig tags (ETAGS) */
1416 free_tree (nodehead
);
1422 /* Output file entries that have no tags. */
1423 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
1425 fprintf (tagf
, "\f\n%s,0\n", fdp
->taggedfname
);
1427 while (nincluded_files
-- > 0)
1428 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1431 if (fclose (tagf
) == EOF
)
1433 exit (EXIT_SUCCESS
);
1439 for (i
= 0; i
< current_arg
; ++i
)
1441 switch (argbuffer
[i
].arg_type
)
1447 continue; /* the for loop */
1450 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1451 tagfile
, argbuffer
[i
].what
, tagfile
);
1452 if (system (cmd
) != EXIT_SUCCESS
)
1453 fatal ("failed to execute shell command", (char *)NULL
);
1455 append_to_tagfile
= TRUE
;
1458 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1461 put_entries (nodehead
); /* write all the tags (CTAGS) */
1462 free_tree (nodehead
);
1464 if (fclose (tagf
) == EOF
)
1469 char cmd
[2*BUFSIZ
+10];
1470 sprintf (cmd
, "sort -o %.*s %.*s", BUFSIZ
, tagfile
, BUFSIZ
, tagfile
);
1471 exit (system (cmd
));
1473 return EXIT_SUCCESS
;
1478 * Return a compressor given the file name. If EXTPTR is non-zero,
1479 * return a pointer into FILE where the compressor-specific
1480 * extension begins. If no compressor is found, NULL is returned
1481 * and EXTPTR is not significant.
1482 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1485 get_compressor_from_suffix (file
, extptr
)
1490 char *slash
, *suffix
;
1492 /* This relies on FN to be after canonicalize_filename,
1493 so we don't need to consider backslashes on DOS_NT. */
1494 slash
= etags_strrchr (file
, '/');
1495 suffix
= etags_strrchr (file
, '.');
1496 if (suffix
== NULL
|| suffix
< slash
)
1501 /* Let those poor souls who live with DOS 8+3 file name limits get
1502 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1503 Only the first do loop is run if not MSDOS */
1506 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1507 if (streq (compr
->suffix
, suffix
))
1510 break; /* do it only once: not really a loop */
1513 } while (*suffix
!= '\0');
1520 * Return a language given the name.
1523 get_language_from_langname (name
)
1529 error ("empty language name", (char *)NULL
);
1532 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1533 if (streq (name
, lang
->name
))
1535 error ("unknown language \"%s\"", name
);
1543 * Return a language given the interpreter name.
1546 get_language_from_interpreter (interpreter
)
1552 if (interpreter
== NULL
)
1554 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1555 if (lang
->interpreters
!= NULL
)
1556 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1557 if (streq (*iname
, interpreter
))
1566 * Return a language given the file name.
1569 get_language_from_filename (file
, case_sensitive
)
1571 bool case_sensitive
;
1574 char **name
, **ext
, *suffix
;
1576 /* Try whole file name first. */
1577 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1578 if (lang
->filenames
!= NULL
)
1579 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1580 if ((case_sensitive
)
1581 ? streq (*name
, file
)
1582 : strcaseeq (*name
, file
))
1585 /* If not found, try suffix after last dot. */
1586 suffix
= etags_strrchr (file
, '.');
1590 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1591 if (lang
->suffixes
!= NULL
)
1592 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1593 if ((case_sensitive
)
1594 ? streq (*ext
, suffix
)
1595 : strcaseeq (*ext
, suffix
))
1602 * This routine is called on each file argument.
1605 process_file_name (file
, lang
)
1609 struct stat stat_buf
;
1613 char *compressed_name
, *uncompressed_name
;
1614 char *ext
, *real_name
;
1617 canonicalize_filename (file
);
1618 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1620 error ("skipping inclusion of %s in self.", file
);
1623 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1625 compressed_name
= NULL
;
1626 real_name
= uncompressed_name
= savestr (file
);
1630 real_name
= compressed_name
= savestr (file
);
1631 uncompressed_name
= savenstr (file
, ext
- file
);
1634 /* If the canonicalized uncompressed name
1635 has already been dealt with, skip it silently. */
1636 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
1638 assert (fdp
->infname
!= NULL
);
1639 if (streq (uncompressed_name
, fdp
->infname
))
1643 if (stat (real_name
, &stat_buf
) != 0)
1645 /* Reset real_name and try with a different name. */
1647 if (compressed_name
!= NULL
) /* try with the given suffix */
1649 if (stat (uncompressed_name
, &stat_buf
) == 0)
1650 real_name
= uncompressed_name
;
1652 else /* try all possible suffixes */
1654 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1656 compressed_name
= concat (file
, ".", compr
->suffix
);
1657 if (stat (compressed_name
, &stat_buf
) != 0)
1661 char *suf
= compressed_name
+ strlen (file
);
1662 size_t suflen
= strlen (compr
->suffix
) + 1;
1663 for ( ; suf
[1]; suf
++, suflen
--)
1665 memmove (suf
, suf
+ 1, suflen
);
1666 if (stat (compressed_name
, &stat_buf
) == 0)
1668 real_name
= compressed_name
;
1672 if (real_name
!= NULL
)
1675 free (compressed_name
);
1676 compressed_name
= NULL
;
1680 real_name
= compressed_name
;
1685 if (real_name
== NULL
)
1690 } /* try with a different name */
1692 if (!S_ISREG (stat_buf
.st_mode
))
1694 error ("skipping %s: it is not a regular file.", real_name
);
1697 if (real_name
== compressed_name
)
1699 char *cmd
= concat (compr
->command
, " ", real_name
);
1700 inf
= (FILE *) popen (cmd
, "r");
1704 inf
= fopen (real_name
, "r");
1711 process_file (inf
, uncompressed_name
, lang
);
1713 if (real_name
== compressed_name
)
1714 retval
= pclose (inf
);
1716 retval
= fclose (inf
);
1721 if (compressed_name
) free (compressed_name
);
1722 if (uncompressed_name
) free (uncompressed_name
);
1729 process_file (fh
, fn
, lang
)
1734 static const fdesc emptyfdesc
;
1737 /* Create a new input file description entry. */
1738 fdp
= xnew (1, fdesc
);
1741 fdp
->infname
= savestr (fn
);
1743 fdp
->infabsname
= absolute_filename (fn
, cwd
);
1744 fdp
->infabsdir
= absolute_dirname (fn
, cwd
);
1745 if (filename_is_absolute (fn
))
1747 /* An absolute file name. Canonicalize it. */
1748 fdp
->taggedfname
= absolute_filename (fn
, NULL
);
1752 /* A file name relative to cwd. Make it relative
1753 to the directory of the tags file. */
1754 fdp
->taggedfname
= relative_filename (fn
, tagfiledir
);
1756 fdp
->usecharno
= TRUE
; /* use char position when making tags */
1758 fdp
->written
= FALSE
; /* not written on tags file yet */
1761 curfdp
= fdhead
; /* the current file description */
1765 /* If not Ctags, and if this is not metasource and if it contained no #line
1766 directives, we can write the tags and free all nodes pointing to
1769 && curfdp
->usecharno
/* no #line directives in this file */
1770 && !curfdp
->lang
->metasource
)
1774 /* Look for the head of the sublist relative to this file. See add_node
1775 for the structure of the node tree. */
1777 for (np
= nodehead
; np
!= NULL
; prev
= np
, np
= np
->left
)
1778 if (np
->fdp
== curfdp
)
1781 /* If we generated tags for this file, write and delete them. */
1784 /* This is the head of the last sublist, if any. The following
1785 instructions depend on this being true. */
1786 assert (np
->left
== NULL
);
1788 assert (fdhead
== curfdp
);
1789 assert (last_node
->fdp
== curfdp
);
1790 put_entries (np
); /* write tags for file curfdp->taggedfname */
1791 free_tree (np
); /* remove the written nodes */
1793 nodehead
= NULL
; /* no nodes left */
1795 prev
->left
= NULL
; /* delete the pointer to the sublist */
1801 * This routine sets up the boolean pseudo-functions which work
1802 * by setting boolean flags dependent upon the corresponding character.
1803 * Every char which is NOT in that string is not a white char. Therefore,
1804 * all of the array "_wht" is set to FALSE, and then the elements
1805 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1806 * of a char is TRUE if it is the string "white", else FALSE.
1814 for (i
= 0; i
< CHARS
; i
++)
1815 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1816 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1817 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1818 notinname('\0') = notinname('\n');
1819 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1820 begtoken('\0') = begtoken('\n');
1821 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1822 intoken('\0') = intoken('\n');
1823 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1824 endtoken('\0') = endtoken('\n');
1828 * This routine opens the specified file and calls the function
1829 * which finds the function and type definitions.
1836 language
*lang
= curfdp
->lang
;
1837 Lang_function
*parser
= NULL
;
1839 /* If user specified a language, use it. */
1840 if (lang
!= NULL
&& lang
->function
!= NULL
)
1842 parser
= lang
->function
;
1845 /* Else try to guess the language given the file name. */
1848 lang
= get_language_from_filename (curfdp
->infname
, TRUE
);
1849 if (lang
!= NULL
&& lang
->function
!= NULL
)
1851 curfdp
->lang
= lang
;
1852 parser
= lang
->function
;
1856 /* Else look for sharp-bang as the first two characters. */
1858 && readline_internal (&lb
, inf
) > 0
1860 && lb
.buffer
[0] == '#'
1861 && lb
.buffer
[1] == '!')
1865 /* Set lp to point at the first char after the last slash in the
1866 line or, if no slashes, at the first nonblank. Then set cp to
1867 the first successive blank and terminate the string. */
1868 lp
= etags_strrchr (lb
.buffer
+2, '/');
1872 lp
= skip_spaces (lb
.buffer
+ 2);
1873 cp
= skip_non_spaces (lp
);
1876 if (strlen (lp
) > 0)
1878 lang
= get_language_from_interpreter (lp
);
1879 if (lang
!= NULL
&& lang
->function
!= NULL
)
1881 curfdp
->lang
= lang
;
1882 parser
= lang
->function
;
1887 /* We rewind here, even if inf may be a pipe. We fail if the
1888 length of the first line is longer than the pipe block size,
1889 which is unlikely. */
1892 /* Else try to guess the language given the case insensitive file name. */
1895 lang
= get_language_from_filename (curfdp
->infname
, FALSE
);
1896 if (lang
!= NULL
&& lang
->function
!= NULL
)
1898 curfdp
->lang
= lang
;
1899 parser
= lang
->function
;
1903 /* Else try Fortran or C. */
1906 node
*old_last_node
= last_node
;
1908 curfdp
->lang
= get_language_from_langname ("fortran");
1911 if (old_last_node
== last_node
)
1912 /* No Fortran entries found. Try C. */
1914 /* We do not tag if rewind fails.
1915 Only the file name will be recorded in the tags file. */
1917 curfdp
->lang
= get_language_from_langname (cplusplus
? "c++" : "c");
1923 if (!no_line_directive
1924 && curfdp
->lang
!= NULL
&& curfdp
->lang
->metasource
)
1925 /* It may be that this is a bingo.y file, and we already parsed a bingo.c
1926 file, or anyway we parsed a file that is automatically generated from
1927 this one. If this is the case, the bingo.c file contained #line
1928 directives that generated tags pointing to this file. Let's delete
1929 them all before parsing this file, which is the real source. */
1931 fdesc
**fdpp
= &fdhead
;
1932 while (*fdpp
!= NULL
)
1934 && streq ((*fdpp
)->taggedfname
, curfdp
->taggedfname
))
1935 /* We found one of those! We must delete both the file description
1936 and all tags referring to it. */
1938 fdesc
*badfdp
= *fdpp
;
1940 /* Delete the tags referring to badfdp->taggedfname
1941 that were obtained from badfdp->infname. */
1942 invalidate_nodes (badfdp
, &nodehead
);
1944 *fdpp
= badfdp
->next
; /* remove the bad description from the list */
1945 free_fdesc (badfdp
);
1948 fdpp
= &(*fdpp
)->next
; /* advance the list pointer */
1951 assert (parser
!= NULL
);
1953 /* Generic initialisations before reading from file. */
1954 linebuffer_setlen (&filebuf
, 0); /* reset the file buffer */
1956 /* Generic initialisations before parsing file with readline. */
1957 lineno
= 0; /* reset global line number */
1958 charno
= 0; /* reset global char number */
1959 linecharno
= 0; /* reset global char number of line start */
1963 #ifdef ETAGS_REGEXPS
1964 regex_tag_multiline ();
1965 #endif /* ETAGS_REGEXPS */
1970 * Check whether an implicitly named tag should be created,
1971 * then call `pfnote'.
1972 * NAME is a string that is internally copied by this function.
1974 * TAGS format specification
1975 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1976 * The following is explained in some more detail in etc/ETAGS.EBNF.
1978 * make_tag creates tags with "implicit tag names" (unnamed tags)
1979 * if the following are all true, assuming NONAM=" \f\t\n\r()=,;":
1980 * 1. NAME does not contain any of the characters in NONAM;
1981 * 2. LINESTART contains name as either a rightmost, or rightmost but
1982 * one character, substring;
1983 * 3. the character, if any, immediately before NAME in LINESTART must
1984 * be a character in NONAM;
1985 * 4. the character, if any, immediately after NAME in LINESTART must
1986 * also be a character in NONAM.
1988 * The implementation uses the notinname() macro, which recognises the
1989 * characters stored in the string `nonam'.
1990 * etags.el needs to use the same characters that are in NONAM.
1993 make_tag (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1994 char *name
; /* tag name, or NULL if unnamed */
1995 int namelen
; /* tag length */
1996 bool is_func
; /* tag is a function */
1997 char *linestart
; /* start of the line where tag is */
1998 int linelen
; /* length of the line where tag is */
1999 int lno
; /* line number */
2000 long cno
; /* character number */
2002 bool named
= (name
!= NULL
&& namelen
> 0);
2004 if (!CTAGS
&& named
) /* maybe set named to false */
2005 /* Let's try to make an implicit tag name, that is, create an unnamed tag
2006 such that etags.el can guess a name from it. */
2009 register char *cp
= name
;
2011 for (i
= 0; i
< namelen
; i
++)
2012 if (notinname (*cp
++))
2014 if (i
== namelen
) /* rule #1 */
2016 cp
= linestart
+ linelen
- namelen
;
2017 if (notinname (linestart
[linelen
-1]))
2018 cp
-= 1; /* rule #4 */
2019 if (cp
>= linestart
/* rule #2 */
2021 || notinname (cp
[-1])) /* rule #3 */
2022 && strneq (name
, cp
, namelen
)) /* rule #2 */
2023 named
= FALSE
; /* use implicit tag name */
2028 name
= savenstr (name
, namelen
);
2031 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
2036 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
2037 char *name
; /* tag name, or NULL if unnamed */
2038 bool is_func
; /* tag is a function */
2039 char *linestart
; /* start of the line where tag is */
2040 int linelen
; /* length of the line where tag is */
2041 int lno
; /* line number */
2042 long cno
; /* character number */
2046 assert (name
== NULL
|| name
[0] != '\0');
2047 if (CTAGS
&& name
== NULL
)
2050 np
= xnew (1, node
);
2052 /* If ctags mode, change name "main" to M<thisfilename>. */
2053 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
2055 register char *fp
= etags_strrchr (curfdp
->taggedfname
, '/');
2056 np
->name
= concat ("M", fp
== NULL
? curfdp
->taggedfname
: fp
+ 1, "");
2057 fp
= etags_strrchr (np
->name
, '.');
2058 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
2064 np
->been_warned
= FALSE
;
2066 np
->is_func
= is_func
;
2068 if (np
->fdp
->usecharno
)
2069 /* Our char numbers are 0-base, because of C language tradition?
2070 ctags compatibility? old versions compatibility? I don't know.
2071 Anyway, since emacs's are 1-base we expect etags.el to take care
2072 of the difference. If we wanted to have 1-based numbers, we would
2073 uncomment the +1 below. */
2074 np
->cno
= cno
/* + 1 */ ;
2076 np
->cno
= invalidcharno
;
2077 np
->left
= np
->right
= NULL
;
2078 if (CTAGS
&& !cxref_style
)
2080 if (strlen (linestart
) < 50)
2081 np
->regex
= concat (linestart
, "$", "");
2083 np
->regex
= savenstr (linestart
, 50);
2086 np
->regex
= savenstr (linestart
, linelen
);
2088 add_node (np
, &nodehead
);
2093 * recurse on left children, iterate on right children.
2101 register node
*node_right
= np
->right
;
2102 free_tree (np
->left
);
2103 if (np
->name
!= NULL
)
2113 * delete a file description
2117 register fdesc
*fdp
;
2119 if (fdp
->infname
!= NULL
) free (fdp
->infname
);
2120 if (fdp
->infabsname
!= NULL
) free (fdp
->infabsname
);
2121 if (fdp
->infabsdir
!= NULL
) free (fdp
->infabsdir
);
2122 if (fdp
->taggedfname
!= NULL
) free (fdp
->taggedfname
);
2123 if (fdp
->prop
!= NULL
) free (fdp
->prop
);
2129 * Adds a node to the tree of nodes. In etags mode, sort by file
2130 * name. In ctags mode, sort by tag name. Make no attempt at
2133 * add_node is the only function allowed to add nodes, so it can
2137 add_node (np
, cur_node_p
)
2138 node
*np
, **cur_node_p
;
2141 register node
*cur_node
= *cur_node_p
;
2143 if (cur_node
== NULL
)
2153 /* For each file name, tags are in a linked sublist on the right
2154 pointer. The first tags of different files are a linked list
2155 on the left pointer. last_node points to the end of the last
2157 if (last_node
!= NULL
&& last_node
->fdp
== np
->fdp
)
2159 /* Let's use the same sublist as the last added node. */
2160 assert (last_node
->right
== NULL
);
2161 last_node
->right
= np
;
2164 else if (cur_node
->fdp
== np
->fdp
)
2166 /* Scanning the list we found the head of a sublist which is
2167 good for us. Let's scan this sublist. */
2168 add_node (np
, &cur_node
->right
);
2171 /* The head of this sublist is not good for us. Let's try the
2173 add_node (np
, &cur_node
->left
);
2174 } /* if ETAGS mode */
2179 dif
= strcmp (np
->name
, cur_node
->name
);
2182 * If this tag name matches an existing one, then
2183 * do not add the node, but maybe print a warning.
2187 if (np
->fdp
== cur_node
->fdp
)
2191 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
2192 np
->fdp
->infname
, lineno
, np
->name
);
2193 fprintf (stderr
, "Second entry ignored\n");
2196 else if (!cur_node
->been_warned
&& !no_warnings
)
2200 "Duplicate entry in files %s and %s: %s (Warning only)\n",
2201 np
->fdp
->infname
, cur_node
->fdp
->infname
, np
->name
);
2202 cur_node
->been_warned
= TRUE
;
2207 /* Actually add the node */
2208 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
2209 } /* if CTAGS mode */
2213 * invalidate_nodes ()
2214 * Scan the node tree and invalidate all nodes pointing to the
2215 * given file description (CTAGS case) or free them (ETAGS case).
2218 invalidate_nodes (badfdp
, npp
)
2229 if (np
->left
!= NULL
)
2230 invalidate_nodes (badfdp
, &np
->left
);
2231 if (np
->fdp
== badfdp
)
2233 if (np
->right
!= NULL
)
2234 invalidate_nodes (badfdp
, &np
->right
);
2238 assert (np
->fdp
!= NULL
);
2239 if (np
->fdp
== badfdp
)
2241 *npp
= np
->left
; /* detach the sublist from the list */
2242 np
->left
= NULL
; /* isolate it */
2243 free_tree (np
); /* free it */
2244 invalidate_nodes (badfdp
, npp
);
2247 invalidate_nodes (badfdp
, &np
->left
);
2252 static int total_size_of_entries
__P((node
*));
2253 static int number_len
__P((long));
2255 /* Length of a non-negative number's decimal representation. */
2261 while ((num
/= 10) > 0)
2267 * Return total number of characters that put_entries will output for
2268 * the nodes in the linked list at the right of the specified node.
2269 * This count is irrelevant with etags.el since emacs 19.34 at least,
2270 * but is still supplied for backward compatibility.
2273 total_size_of_entries (np
)
2276 register int total
= 0;
2278 for (; np
!= NULL
; np
= np
->right
)
2281 total
+= strlen (np
->regex
) + 1; /* pat\177 */
2282 if (np
->name
!= NULL
)
2283 total
+= strlen (np
->name
) + 1; /* name\001 */
2284 total
+= number_len ((long) np
->lno
) + 1; /* lno, */
2285 if (np
->cno
!= invalidcharno
) /* cno */
2286 total
+= number_len (np
->cno
);
2287 total
+= 1; /* newline */
2298 static fdesc
*fdp
= NULL
;
2303 /* Output subentries that precede this one */
2305 put_entries (np
->left
);
2307 /* Output this entry */
2316 fprintf (tagf
, "\f\n%s,%d\n",
2317 fdp
->taggedfname
, total_size_of_entries (np
));
2318 fdp
->written
= TRUE
;
2320 fputs (np
->regex
, tagf
);
2321 fputc ('\177', tagf
);
2322 if (np
->name
!= NULL
)
2324 fputs (np
->name
, tagf
);
2325 fputc ('\001', tagf
);
2327 fprintf (tagf
, "%d,", np
->lno
);
2328 if (np
->cno
!= invalidcharno
)
2329 fprintf (tagf
, "%ld", np
->cno
);
2335 if (np
->name
== NULL
)
2336 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
2341 fprintf (stdout
, "%s %s %d\n",
2342 np
->name
, np
->fdp
->taggedfname
, (np
->lno
+ 63) / 64);
2344 fprintf (stdout
, "%-16s %3d %-16s %s\n",
2345 np
->name
, np
->lno
, np
->fdp
->taggedfname
, np
->regex
);
2349 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->fdp
->taggedfname
);
2352 { /* function or #define macro with args */
2353 putc (searchar
, tagf
);
2356 for (sp
= np
->regex
; *sp
; sp
++)
2358 if (*sp
== '\\' || *sp
== searchar
)
2362 putc (searchar
, tagf
);
2365 { /* anything else; text pattern inadequate */
2366 fprintf (tagf
, "%d", np
->lno
);
2371 } /* if this node contains a valid tag */
2373 /* Output subentries that follow this one */
2374 put_entries (np
->right
);
2376 put_entries (np
->left
);
2381 #define C_EXT 0x00fff /* C extensions */
2382 #define C_PLAIN 0x00000 /* C */
2383 #define C_PLPL 0x00001 /* C++ */
2384 #define C_STAR 0x00003 /* C* */
2385 #define C_JAVA 0x00005 /* JAVA */
2386 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
2387 #define YACC 0x10000 /* yacc file */
2390 * The C symbol tables.
2395 st_C_objprot
, st_C_objimpl
, st_C_objend
,
2397 st_C_ignore
, st_C_attribute
,
2400 st_C_class
, st_C_template
,
2401 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
2404 static unsigned int hash
__P((const char *, unsigned int));
2405 static struct C_stab_entry
* in_word_set
__P((const char *, unsigned int));
2406 static enum sym_type C_symtype
__P((char *, int, int));
2408 /* Feed stuff between (but not including) %[ and %] lines to:
2414 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2418 while, 0, st_C_ignore
2419 switch, 0, st_C_ignore
2420 return, 0, st_C_ignore
2421 __attribute__, 0, st_C_attribute
2422 @interface, 0, st_C_objprot
2423 @protocol, 0, st_C_objprot
2424 @implementation,0, st_C_objimpl
2425 @end, 0, st_C_objend
2426 import, (C_JAVA & !C_PLPL), st_C_ignore
2427 package, (C_JAVA & !C_PLPL), st_C_ignore
2428 friend, C_PLPL, st_C_ignore
2429 extends, (C_JAVA & !C_PLPL), st_C_javastruct
2430 implements, (C_JAVA & !C_PLPL), st_C_javastruct
2431 interface, (C_JAVA & !C_PLPL), st_C_struct
2432 class, 0, st_C_class
2433 namespace, C_PLPL, st_C_struct
2434 domain, C_STAR, st_C_struct
2435 union, 0, st_C_struct
2436 struct, 0, st_C_struct
2437 extern, 0, st_C_extern
2439 typedef, 0, st_C_typedef
2440 define, 0, st_C_define
2441 operator, C_PLPL, st_C_operator
2442 template, 0, st_C_template
2443 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2444 DEFUN, 0, st_C_gnumacro
2445 SYSCALL, 0, st_C_gnumacro
2446 ENTRY, 0, st_C_gnumacro
2447 PSEUDO, 0, st_C_gnumacro
2448 # These are defined inside C functions, so currently they are not met.
2449 # EXFUN used in glibc, DEFVAR_* in emacs.
2450 #EXFUN, 0, st_C_gnumacro
2451 #DEFVAR_, 0, st_C_gnumacro
2453 and replace lines between %< and %> with its output, then:
2454 - remove the #if characterset check
2455 - make in_word_set static and not inline. */
2457 /* C code produced by gperf version 3.0.1 */
2458 /* Command-line: gperf -m 5 */
2459 /* Computed positions: -k'1-2' */
2461 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2462 /* maximum key range = 31, duplicates = 0 */
2473 register const char *str
;
2474 register unsigned int len
;
2476 static unsigned char asso_values
[] =
2478 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2479 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2480 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2481 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2482 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2483 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2484 34, 34, 34, 34, 1, 34, 34, 34, 14, 14,
2485 34, 34, 34, 34, 34, 34, 34, 34, 13, 34,
2486 13, 34, 34, 12, 34, 34, 34, 34, 34, 11,
2487 34, 34, 34, 34, 34, 8, 34, 11, 34, 12,
2488 11, 0, 1, 34, 7, 0, 34, 34, 11, 9,
2489 0, 4, 0, 34, 7, 4, 14, 21, 34, 15,
2490 0, 2, 34, 34, 34, 34, 34, 34, 34, 34,
2491 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2492 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2493 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2494 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2495 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2496 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2497 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2498 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2499 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2500 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2501 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2502 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
2503 34, 34, 34, 34, 34, 34
2505 return len
+ asso_values
[(unsigned char)str
[1]] + asso_values
[(unsigned char)str
[0]];
2508 static struct C_stab_entry
*
2509 in_word_set (str
, len
)
2510 register const char *str
;
2511 register unsigned int len
;
2515 TOTAL_KEYWORDS
= 31,
2516 MIN_WORD_LENGTH
= 2,
2517 MAX_WORD_LENGTH
= 15,
2522 static struct C_stab_entry wordlist
[] =
2525 {"if", 0, st_C_ignore
},
2526 {"enum", 0, st_C_enum
},
2527 {"@end", 0, st_C_objend
},
2528 {"extern", 0, st_C_extern
},
2529 {"extends", (C_JAVA
& !C_PLPL
), st_C_javastruct
},
2530 {"for", 0, st_C_ignore
},
2531 {"interface", (C_JAVA
& !C_PLPL
), st_C_struct
},
2532 {"@protocol", 0, st_C_objprot
},
2533 {"@interface", 0, st_C_objprot
},
2534 {"operator", C_PLPL
, st_C_operator
},
2535 {"return", 0, st_C_ignore
},
2536 {"friend", C_PLPL
, st_C_ignore
},
2537 {"import", (C_JAVA
& !C_PLPL
), st_C_ignore
},
2538 {"@implementation",0, st_C_objimpl
},
2539 {"define", 0, st_C_define
},
2540 {"package", (C_JAVA
& !C_PLPL
), st_C_ignore
},
2541 {"implements", (C_JAVA
& !C_PLPL
), st_C_javastruct
},
2542 {"namespace", C_PLPL
, st_C_struct
},
2543 {"domain", C_STAR
, st_C_struct
},
2544 {"template", 0, st_C_template
},
2545 {"typedef", 0, st_C_typedef
},
2546 {"struct", 0, st_C_struct
},
2547 {"switch", 0, st_C_ignore
},
2548 {"union", 0, st_C_struct
},
2549 {"while", 0, st_C_ignore
},
2550 {"class", 0, st_C_class
},
2551 {"__attribute__", 0, st_C_attribute
},
2552 {"SYSCALL", 0, st_C_gnumacro
},
2553 {"PSEUDO", 0, st_C_gnumacro
},
2554 {"ENTRY", 0, st_C_gnumacro
},
2555 {"DEFUN", 0, st_C_gnumacro
}
2558 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2560 register int key
= hash (str
, len
);
2562 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2564 register const char *s
= wordlist
[key
].name
;
2566 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1) && s
[len
] == '\0')
2567 return &wordlist
[key
];
2574 static enum sym_type
2575 C_symtype (str
, len
, c_ext
)
2580 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2582 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2589 * Ignoring __attribute__ ((list))
2591 static bool inattribute
; /* looking at an __attribute__ construct */
2594 * C functions and variables are recognized using a simple
2595 * finite automaton. fvdef is its state variable.
2599 fvnone
, /* nothing seen */
2600 fdefunkey
, /* Emacs DEFUN keyword seen */
2601 fdefunname
, /* Emacs DEFUN name seen */
2602 foperator
, /* func: operator keyword seen (cplpl) */
2603 fvnameseen
, /* function or variable name seen */
2604 fstartlist
, /* func: just after open parenthesis */
2605 finlist
, /* func: in parameter list */
2606 flistseen
, /* func: after parameter list */
2607 fignore
, /* func: before open brace */
2608 vignore
/* var-like: ignore until ';' */
2611 static bool fvextern
; /* func or var: extern keyword seen; */
2614 * typedefs are recognized using a simple finite automaton.
2615 * typdef is its state variable.
2619 tnone
, /* nothing seen */
2620 tkeyseen
, /* typedef keyword seen */
2621 ttypeseen
, /* defined type seen */
2622 tinbody
, /* inside typedef body */
2623 tend
, /* just before typedef tag */
2624 tignore
/* junk after typedef tag */
2628 * struct-like structures (enum, struct and union) are recognized
2629 * using another simple finite automaton. `structdef' is its state
2634 snone
, /* nothing seen yet,
2635 or in struct body if bracelev > 0 */
2636 skeyseen
, /* struct-like keyword seen */
2637 stagseen
, /* struct-like tag seen */
2638 scolonseen
/* colon seen after struct-like tag */
2642 * When objdef is different from onone, objtag is the name of the class.
2644 static char *objtag
= "<uninited>";
2647 * Yet another little state machine to deal with preprocessor lines.
2651 dnone
, /* nothing seen */
2652 dsharpseen
, /* '#' seen as first char on line */
2653 ddefineseen
, /* '#' and 'define' seen */
2654 dignorerest
/* ignore rest of line */
2658 * State machine for Objective C protocols and implementations.
2659 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2663 onone
, /* nothing seen */
2664 oprotocol
, /* @interface or @protocol seen */
2665 oimplementation
, /* @implementations seen */
2666 otagseen
, /* class name seen */
2667 oparenseen
, /* parenthesis before category seen */
2668 ocatseen
, /* category name seen */
2669 oinbody
, /* in @implementation body */
2670 omethodsign
, /* in @implementation body, after +/- */
2671 omethodtag
, /* after method name */
2672 omethodcolon
, /* after method colon */
2673 omethodparm
, /* after method parameter */
2674 oignore
/* wait for @end */
2679 * Use this structure to keep info about the token read, and how it
2680 * should be tagged. Used by the make_C_tag function to build a tag.
2684 char *line
; /* string containing the token */
2685 int offset
; /* where the token starts in LINE */
2686 int length
; /* token length */
2688 The previous members can be used to pass strings around for generic
2689 purposes. The following ones specifically refer to creating tags. In this
2690 case the token contained here is the pattern that will be used to create a
2693 bool valid
; /* do not create a tag; the token should be
2694 invalidated whenever a state machine is
2695 reset prematurely */
2696 bool named
; /* create a named tag */
2697 int lineno
; /* source line number of tag */
2698 long linepos
; /* source char number of tag */
2699 } token
; /* latest token read */
2702 * Variables and functions for dealing with nested structures.
2703 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2705 static void pushclass_above
__P((int, char *, int));
2706 static void popclass_above
__P((int));
2707 static void write_classname
__P((linebuffer
*, char *qualifier
));
2710 char **cname
; /* nested class names */
2711 int *bracelev
; /* nested class brace level */
2712 int nl
; /* class nesting level (elements used) */
2713 int size
; /* length of the array */
2714 } cstack
; /* stack for nested declaration tags */
2715 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2716 #define nestlev (cstack.nl)
2717 /* After struct keyword or in struct body, not inside a nested function. */
2718 #define instruct (structdef == snone && nestlev > 0 \
2719 && bracelev == cstack.bracelev[nestlev-1] + 1)
2722 pushclass_above (bracelev
, str
, len
)
2729 popclass_above (bracelev
);
2731 if (nl
>= cstack
.size
)
2733 int size
= cstack
.size
*= 2;
2734 xrnew (cstack
.cname
, size
, char *);
2735 xrnew (cstack
.bracelev
, size
, int);
2737 assert (nl
== 0 || cstack
.bracelev
[nl
-1] < bracelev
);
2738 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2739 cstack
.bracelev
[nl
] = bracelev
;
2744 popclass_above (bracelev
)
2749 for (nl
= cstack
.nl
- 1;
2750 nl
>= 0 && cstack
.bracelev
[nl
] >= bracelev
;
2753 if (cstack
.cname
[nl
] != NULL
)
2754 free (cstack
.cname
[nl
]);
2760 write_classname (cn
, qualifier
)
2765 int qlen
= strlen (qualifier
);
2767 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2771 cn
->buffer
[0] = '\0';
2775 len
= strlen (cstack
.cname
[0]);
2776 linebuffer_setlen (cn
, len
);
2777 strcpy (cn
->buffer
, cstack
.cname
[0]);
2779 for (i
= 1; i
< cstack
.nl
; i
++)
2784 s
= cstack
.cname
[i
];
2789 linebuffer_setlen (cn
, len
);
2790 strncat (cn
->buffer
, qualifier
, qlen
);
2791 strncat (cn
->buffer
, s
, slen
);
2796 static bool consider_token
__P((char *, int, int, int *, int, int, bool *));
2797 static void make_C_tag
__P((bool));
2801 * checks to see if the current token is at the start of a
2802 * function or variable, or corresponds to a typedef, or
2803 * is a struct/union/enum tag, or #define, or an enum constant.
2805 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2806 * with args. C_EXTP points to which language we are looking at.
2817 consider_token (str
, len
, c
, c_extp
, bracelev
, parlev
, is_func_or_var
)
2818 register char *str
; /* IN: token pointer */
2819 register int len
; /* IN: token length */
2820 register int c
; /* IN: first char after the token */
2821 int *c_extp
; /* IN, OUT: C extensions mask */
2822 int bracelev
; /* IN: brace level */
2823 int parlev
; /* IN: parenthesis level */
2824 bool *is_func_or_var
; /* OUT: function or variable found */
2826 /* When structdef is stagseen, scolonseen, or snone with bracelev > 0,
2827 structtype is the type of the preceding struct-like keyword, and
2828 structbracelev is the brace level where it has been seen. */
2829 static enum sym_type structtype
;
2830 static int structbracelev
;
2831 static enum sym_type toktype
;
2834 toktype
= C_symtype (str
, len
, *c_extp
);
2837 * Skip __attribute__
2839 if (toktype
== st_C_attribute
)
2846 * Advance the definedef state machine.
2851 /* We're not on a preprocessor line. */
2852 if (toktype
== st_C_gnumacro
)
2859 if (toktype
== st_C_define
)
2861 definedef
= ddefineseen
;
2865 definedef
= dignorerest
;
2870 * Make a tag for any macro, unless it is a constant
2871 * and constantypedefs is FALSE.
2873 definedef
= dignorerest
;
2874 *is_func_or_var
= (c
== '(');
2875 if (!*is_func_or_var
&& !constantypedefs
)
2882 error ("internal error: definedef value.", (char *)NULL
);
2891 if (toktype
== st_C_typedef
)
2911 if (structdef
== snone
&& fvdef
== fvnone
)
2929 * This structdef business is NOT invoked when we are ctags and the
2930 * file is plain C. This is because a struct tag may have the same
2931 * name as another tag, and this loses with ctags.
2935 case st_C_javastruct
:
2936 if (structdef
== stagseen
)
2937 structdef
= scolonseen
;
2941 if ((*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2943 && definedef
== dnone
&& structdef
== snone
2944 && typdef
== tnone
&& fvdef
== fvnone
)
2945 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2946 if (toktype
== st_C_template
)
2953 && (typdef
== tkeyseen
2954 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2956 structdef
= skeyseen
;
2957 structtype
= toktype
;
2958 structbracelev
= bracelev
;
2959 if (fvdef
== fvnameseen
)
2965 if (structdef
== skeyseen
)
2967 structdef
= stagseen
;
2971 if (typdef
!= tnone
)
2974 /* Detect Objective C constructs. */
2984 objdef
= oimplementation
;
2988 case oimplementation
:
2989 /* Save the class tag for functions or variables defined inside. */
2990 objtag
= savenstr (str
, len
);
2994 /* Save the class tag for categories. */
2995 objtag
= savenstr (str
, len
);
2997 *is_func_or_var
= TRUE
;
3001 *is_func_or_var
= TRUE
;
3009 objdef
= omethodtag
;
3010 linebuffer_setlen (&token_name
, len
);
3011 strncpy (token_name
.buffer
, str
, len
);
3012 token_name
.buffer
[len
] = '\0';
3018 objdef
= omethodparm
;
3024 objdef
= omethodtag
;
3025 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
3026 strncat (token_name
.buffer
, str
, len
);
3031 if (toktype
== st_C_objend
)
3033 /* Memory leakage here: the string pointed by objtag is
3034 never released, because many tests would be needed to
3035 avoid breaking on incorrect input code. The amount of
3036 memory leaked here is the sum of the lengths of the
3044 /* A function, variable or enum constant? */
3066 *is_func_or_var
= TRUE
;
3070 && structdef
== snone
3071 && structtype
== st_C_enum
&& bracelev
> structbracelev
)
3072 return TRUE
; /* enum constant */
3078 fvdef
= fdefunname
; /* GNU macro */
3079 *is_func_or_var
= TRUE
;
3087 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
3088 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
3097 if (len
>= 10 && strneq (str
+len
-10, "::operator", 10))
3099 if (*c_extp
& C_AUTO
) /* automatic detection of C++ */
3100 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
3102 *is_func_or_var
= TRUE
;
3105 if (bracelev
> 0 && !instruct
)
3107 fvdef
= fvnameseen
; /* function or variable */
3108 *is_func_or_var
= TRUE
;
3119 * C_entries often keeps pointers to tokens or lines which are older than
3120 * the line currently read. By keeping two line buffers, and switching
3121 * them at end of line, it is possible to use those pointers.
3129 #define current_lb_is_new (newndx == curndx)
3130 #define switch_line_buffers() (curndx = 1 - curndx)
3132 #define curlb (lbs[curndx].lb)
3133 #define newlb (lbs[newndx].lb)
3134 #define curlinepos (lbs[curndx].linepos)
3135 #define newlinepos (lbs[newndx].linepos)
3137 #define plainc ((c_ext & C_EXT) == C_PLAIN)
3138 #define cplpl (c_ext & C_PLPL)
3139 #define cjava ((c_ext & C_JAVA) == C_JAVA)
3141 #define CNL_SAVE_DEFINEDEF() \
3143 curlinepos = charno; \
3144 readline (&curlb, inf); \
3145 lp = curlb.buffer; \
3152 CNL_SAVE_DEFINEDEF(); \
3153 if (savetoken.valid) \
3155 token = savetoken; \
3156 savetoken.valid = FALSE; \
3158 definedef = dnone; \
3166 /* This function should never be called when token.valid is FALSE, but
3167 we must protect against invalid input or internal errors. */
3168 if (!DEBUG
&& !token
.valid
)
3172 make_tag (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
3173 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
3174 else /* this case is optimised away if !DEBUG */
3175 make_tag (concat ("INVALID TOKEN:-->", token_name
.buffer
, ""),
3176 token_name
.len
+ 17, isfun
, token
.line
,
3177 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
3179 token
.valid
= FALSE
;
3185 * This routine finds functions, variables, typedefs,
3186 * #define's, enum constants and struct/union/enum definitions in
3187 * C syntax and adds them to the list.
3190 C_entries (c_ext
, inf
)
3191 int c_ext
; /* extension of C */
3192 FILE *inf
; /* input file */
3194 register char c
; /* latest char read; '\0' for end of line */
3195 register char *lp
; /* pointer one beyond the character `c' */
3196 int curndx
, newndx
; /* indices for current and new lb */
3197 register int tokoff
; /* offset in line of start of current token */
3198 register int toklen
; /* length of current token */
3199 char *qualifier
; /* string used to qualify names */
3200 int qlen
; /* length of qualifier */
3201 int bracelev
; /* current brace level */
3202 int bracketlev
; /* current bracket level */
3203 int parlev
; /* current parenthesis level */
3204 int attrparlev
; /* __attribute__ parenthesis level */
3205 int templatelev
; /* current template level */
3206 int typdefbracelev
; /* bracelev where a typedef struct body begun */
3207 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
3208 bool yacc_rules
; /* in the rules part of a yacc file */
3209 struct tok savetoken
; /* token saved during preprocessor handling */
3212 linebuffer_init (&lbs
[0].lb
);
3213 linebuffer_init (&lbs
[1].lb
);
3214 if (cstack
.size
== 0)
3216 cstack
.size
= (DEBUG
) ? 1 : 4;
3218 cstack
.cname
= xnew (cstack
.size
, char *);
3219 cstack
.bracelev
= xnew (cstack
.size
, int);
3222 tokoff
= toklen
= typdefbracelev
= 0; /* keep compiler quiet */
3223 curndx
= newndx
= 0;
3227 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
3228 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
3230 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
3231 token
.valid
= savetoken
.valid
= FALSE
;
3232 bracelev
= bracketlev
= parlev
= attrparlev
= templatelev
= 0;
3234 { qualifier
= "."; qlen
= 1; }
3236 { qualifier
= "::"; qlen
= 2; }
3244 /* If we are at the end of the line, the next character is a
3245 '\0'; do not skip it, because it is what tells us
3246 to read the next line. */
3267 /* Newlines inside comments do not end macro definitions in
3269 CNL_SAVE_DEFINEDEF ();
3282 /* Newlines inside strings do not end macro definitions
3283 in traditional cpp, even though compilers don't
3284 usually accept them. */
3285 CNL_SAVE_DEFINEDEF ();
3295 /* Hmmm, something went wrong. */
3304 else if (bracketlev
> 0)
3309 if (--bracketlev
> 0)
3313 CNL_SAVE_DEFINEDEF ();
3341 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
3354 else if (/* cplpl && */ *lp
== '/')
3362 if ((c_ext
& YACC
) && *lp
== '%')
3364 /* Entering or exiting rules section in yacc file. */
3366 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
3367 typdef
= tnone
; structdef
= snone
;
3368 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
3370 yacc_rules
= !yacc_rules
;
3376 if (definedef
== dnone
)
3379 bool cpptoken
= TRUE
;
3381 /* Look back on this line. If all blanks, or nonblanks
3382 followed by an end of comment, this is a preprocessor
3384 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
3387 if (*cp
== '*' && *(cp
+1) == '/')
3396 definedef
= dsharpseen
;
3397 } /* if (definedef == dnone) */
3405 /* Consider token only if some involved conditions are satisfied. */
3406 if (typdef
!= tignore
3407 && definedef
!= dignorerest
3410 && (definedef
!= dnone
3411 || structdef
!= scolonseen
)
3418 if (c
== ':' && *lp
== ':' && begtoken (lp
[1]))
3419 /* This handles :: in the middle,
3420 but not at the beginning of an identifier.
3421 Also, space-separated :: is not recognised. */
3423 if (c_ext
& C_AUTO
) /* automatic detection of C++ */
3424 c_ext
= (c_ext
| C_PLPL
) & ~C_AUTO
;
3428 goto still_in_token
;
3432 bool funorvar
= FALSE
;
3435 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
3436 &c_ext
, bracelev
, parlev
,
3439 if (fvdef
== foperator
)
3442 lp
= skip_spaces (lp
-1);
3446 && !iswhite (*lp
) && *lp
!= '(')
3449 toklen
+= lp
- oldlp
;
3451 token
.named
= FALSE
;
3453 && nestlev
> 0 && definedef
== dnone
)
3454 /* in struct body */
3456 write_classname (&token_name
, qualifier
);
3457 linebuffer_setlen (&token_name
,
3458 token_name
.len
+qlen
+toklen
);
3459 strcat (token_name
.buffer
, qualifier
);
3460 strncat (token_name
.buffer
,
3461 newlb
.buffer
+ tokoff
, toklen
);
3464 else if (objdef
== ocatseen
)
3465 /* Objective C category */
3467 int len
= strlen (objtag
) + 2 + toklen
;
3468 linebuffer_setlen (&token_name
, len
);
3469 strcpy (token_name
.buffer
, objtag
);
3470 strcat (token_name
.buffer
, "(");
3471 strncat (token_name
.buffer
,
3472 newlb
.buffer
+ tokoff
, toklen
);
3473 strcat (token_name
.buffer
, ")");
3476 else if (objdef
== omethodtag
3477 || objdef
== omethodparm
)
3478 /* Objective C method */
3482 else if (fvdef
== fdefunname
)
3483 /* GNU DEFUN and similar macros */
3485 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3489 /* Rewrite the tag so that emacs lisp DEFUNs
3490 can be found by their elisp name */
3497 linebuffer_setlen (&token_name
, len
);
3498 strncpy (token_name
.buffer
,
3499 newlb
.buffer
+ off
, len
);
3500 token_name
.buffer
[len
] = '\0';
3503 if (token_name
.buffer
[len
] == '_')
3504 token_name
.buffer
[len
] = '-';
3505 token
.named
= defun
;
3509 linebuffer_setlen (&token_name
, toklen
);
3510 strncpy (token_name
.buffer
,
3511 newlb
.buffer
+ tokoff
, toklen
);
3512 token_name
.buffer
[toklen
] = '\0';
3513 /* Name macros and members. */
3514 token
.named
= (structdef
== stagseen
3515 || typdef
== ttypeseen
3518 && definedef
== dignorerest
)
3520 && definedef
== dnone
3521 && structdef
== snone
3524 token
.lineno
= lineno
;
3525 token
.offset
= tokoff
;
3526 token
.length
= toklen
;
3527 token
.line
= newlb
.buffer
;
3528 token
.linepos
= newlinepos
;
3531 if (definedef
== dnone
3532 && (fvdef
== fvnameseen
3533 || fvdef
== foperator
3534 || structdef
== stagseen
3536 || typdef
== ttypeseen
3537 || objdef
!= onone
))
3539 if (current_lb_is_new
)
3540 switch_line_buffers ();
3542 else if (definedef
!= dnone
3543 || fvdef
== fdefunname
3545 make_C_tag (funorvar
);
3547 else /* not yacc and consider_token failed */
3549 if (inattribute
&& fvdef
== fignore
)
3551 /* We have just met __attribute__ after a
3552 function parameter list: do not tag the
3559 } /* if (endtoken (c)) */
3560 else if (intoken (c
))
3566 } /* if (midtoken) */
3567 else if (begtoken (c
))
3575 /* This prevents tagging fb in
3576 void (__attribute__((noreturn)) *fb) (void);
3577 Fixing this is not easy and not very important. */
3581 if (plainc
|| declarations
)
3583 make_C_tag (TRUE
); /* a function */
3588 if (structdef
== stagseen
&& !cjava
)
3590 popclass_above (bracelev
);
3598 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3600 tokoff
= lp
- 1 - newlb
.buffer
;
3605 } /* if (begtoken) */
3606 } /* if must look at token */
3609 /* Detect end of line, colon, comma, semicolon and various braces
3610 after having handled a token.*/
3616 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3618 make_C_tag (FALSE
); /* a yacc function */
3621 if (definedef
!= dnone
)
3627 make_C_tag (TRUE
); /* an Objective C class */
3631 objdef
= omethodcolon
;
3632 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3633 strcat (token_name
.buffer
, ":");
3636 if (structdef
== stagseen
)
3638 structdef
= scolonseen
;
3641 /* Should be useless, but may be work as a safety net. */
3642 if (cplpl
&& fvdef
== flistseen
)
3644 make_C_tag (TRUE
); /* a function */
3650 if (definedef
!= dnone
|| inattribute
)
3656 make_C_tag (FALSE
); /* a typedef */
3666 if (typdef
== tignore
|| cplpl
)
3670 if ((globals
&& bracelev
== 0 && (!fvextern
|| declarations
))
3671 || (members
&& instruct
))
3672 make_C_tag (FALSE
); /* a variable */
3675 token
.valid
= FALSE
;
3679 && (cplpl
|| !instruct
)
3680 && (typdef
== tnone
|| (typdef
!= tignore
&& instruct
)))
3682 && plainc
&& instruct
))
3683 make_C_tag (TRUE
); /* a function */
3689 && cplpl
&& structdef
== stagseen
)
3690 make_C_tag (FALSE
); /* forward declaration */
3692 token
.valid
= FALSE
;
3693 } /* switch (fvdef) */
3699 if (structdef
== stagseen
)
3703 if (definedef
!= dnone
|| inattribute
)
3709 make_C_tag (TRUE
); /* an Objective C method */
3730 && (!fvextern
|| declarations
))
3731 || (members
&& instruct
)))
3732 make_C_tag (FALSE
); /* a variable */
3735 if ((declarations
&& typdef
== tnone
&& !instruct
)
3736 || (members
&& typdef
!= tignore
&& instruct
))
3738 make_C_tag (TRUE
); /* a function */
3741 else if (!declarations
)
3743 token
.valid
= FALSE
;
3748 if (structdef
== stagseen
)
3752 if (definedef
!= dnone
|| inattribute
)
3754 if (structdef
== stagseen
)
3761 make_C_tag (FALSE
); /* a typedef */
3773 if ((members
&& bracelev
== 1)
3774 || (globals
&& bracelev
== 0
3775 && (!fvextern
|| declarations
)))
3776 make_C_tag (FALSE
); /* a variable */
3790 if (definedef
!= dnone
)
3792 if (objdef
== otagseen
&& parlev
== 0)
3793 objdef
= oparenseen
;
3797 if (typdef
== ttypeseen
3801 /* This handles constructs like:
3802 typedef void OperatorFun (int fun); */
3821 if (--attrparlev
== 0)
3822 inattribute
= FALSE
;
3825 if (definedef
!= dnone
)
3827 if (objdef
== ocatseen
&& parlev
== 1)
3829 make_C_tag (TRUE
); /* an Objective C category */
3843 || typdef
== ttypeseen
))
3846 make_C_tag (FALSE
); /* a typedef */
3849 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3853 if (definedef
!= dnone
)
3855 if (typdef
== ttypeseen
)
3857 /* Whenever typdef is set to tinbody (currently only
3858 here), typdefbracelev should be set to bracelev. */
3860 typdefbracelev
= bracelev
;
3865 make_C_tag (TRUE
); /* a function */
3874 make_C_tag (TRUE
); /* an Objective C class */
3879 make_C_tag (TRUE
); /* an Objective C method */
3883 /* Neutralize `extern "C" {' grot. */
3884 if (bracelev
== 0 && structdef
== snone
&& nestlev
== 0
3892 case skeyseen
: /* unnamed struct */
3893 pushclass_above (bracelev
, NULL
, 0);
3896 case stagseen
: /* named struct or enum */
3897 case scolonseen
: /* a class */
3898 pushclass_above (bracelev
,token
.line
+token
.offset
, token
.length
);
3900 make_C_tag (FALSE
); /* a struct or enum */
3906 if (definedef
!= dnone
)
3908 if (fvdef
== fstartlist
)
3910 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3911 token
.valid
= FALSE
;
3915 if (definedef
!= dnone
)
3917 if (!ignoreindent
&& lp
== newlb
.buffer
+ 1)
3920 token
.valid
= FALSE
;
3921 bracelev
= 0; /* reset brace level if first column */
3922 parlev
= 0; /* also reset paren level, just in case... */
3924 else if (bracelev
> 0)
3927 token
.valid
= FALSE
; /* something gone amiss, token unreliable */
3928 popclass_above (bracelev
);
3930 /* Only if typdef == tinbody is typdefbracelev significant. */
3931 if (typdef
== tinbody
&& bracelev
<= typdefbracelev
)
3933 assert (bracelev
== typdefbracelev
);
3938 if (definedef
!= dnone
)
3948 if ((members
&& bracelev
== 1)
3949 || (globals
&& bracelev
== 0 && (!fvextern
|| declarations
)))
3950 make_C_tag (FALSE
); /* a variable */
3958 && (structdef
== stagseen
|| fvdef
== fvnameseen
))
3965 if (templatelev
> 0)
3973 if (objdef
== oinbody
&& bracelev
== 0)
3975 objdef
= omethodsign
;
3980 case '#': case '~': case '&': case '%': case '/':
3981 case '|': case '^': case '!': case '.': case '?':
3982 if (definedef
!= dnone
)
3984 /* These surely cannot follow a function tag in C. */
3997 if (objdef
== otagseen
)
3999 make_C_tag (TRUE
); /* an Objective C class */
4002 /* If a macro spans multiple lines don't reset its state. */
4004 CNL_SAVE_DEFINEDEF ();
4010 } /* while not eof */
4012 free (lbs
[0].lb
.buffer
);
4013 free (lbs
[1].lb
.buffer
);
4017 * Process either a C++ file or a C file depending on the setting
4021 default_C_entries (inf
)
4024 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
4027 /* Always do plain C. */
4029 plain_C_entries (inf
)
4035 /* Always do C++. */
4037 Cplusplus_entries (inf
)
4040 C_entries (C_PLPL
, inf
);
4043 /* Always do Java. */
4048 C_entries (C_JAVA
, inf
);
4056 C_entries (C_STAR
, inf
);
4059 /* Always do Yacc. */
4064 C_entries (YACC
, inf
);
4068 /* Useful macros. */
4069 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
4070 for (; /* loop initialization */ \
4071 !feof (file_pointer) /* loop test */ \
4072 && /* instructions at start of loop */ \
4073 (readline (&line_buffer, file_pointer), \
4074 char_pointer = line_buffer.buffer, \
4077 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
4078 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \
4079 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \
4080 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */
4083 * Read a file, but do no processing. This is used to do regexp
4084 * matching on files that have no language defined.
4087 just_read_file (inf
)
4090 register char *dummy
;
4092 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
4097 /* Fortran parsing */
4099 static void F_takeprec
__P((void));
4100 static void F_getit
__P((FILE *));
4105 dbp
= skip_spaces (dbp
);
4109 dbp
= skip_spaces (dbp
);
4110 if (strneq (dbp
, "(*)", 3))
4115 if (!ISDIGIT (*dbp
))
4117 --dbp
; /* force failure */
4122 while (ISDIGIT (*dbp
));
4131 dbp
= skip_spaces (dbp
);
4134 readline (&lb
, inf
);
4139 dbp
= skip_spaces (dbp
);
4141 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
4143 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
4145 make_tag (dbp
, cp
-dbp
, TRUE
,
4146 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4151 Fortran_functions (inf
)
4154 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4157 dbp
++; /* Ratfor escape to fortran */
4158 dbp
= skip_spaces (dbp
);
4161 switch (lowcase (*dbp
))
4164 if (nocase_tail ("integer"))
4168 if (nocase_tail ("real"))
4172 if (nocase_tail ("logical"))
4176 if (nocase_tail ("complex") || nocase_tail ("character"))
4180 if (nocase_tail ("double"))
4182 dbp
= skip_spaces (dbp
);
4185 if (nocase_tail ("precision"))
4191 dbp
= skip_spaces (dbp
);
4194 switch (lowcase (*dbp
))
4197 if (nocase_tail ("function"))
4201 if (nocase_tail ("subroutine"))
4205 if (nocase_tail ("entry"))
4209 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
4211 dbp
= skip_spaces (dbp
);
4212 if (*dbp
== '\0') /* assume un-named */
4213 make_tag ("blockdata", 9, TRUE
,
4214 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
4216 F_getit (inf
); /* look for name */
4227 * Philippe Waroquiers (1998)
4230 static void Ada_getit
__P((FILE *, char *));
4232 /* Once we are positioned after an "interesting" keyword, let's get
4233 the real tag value necessary. */
4235 Ada_getit (inf
, name_qualifier
)
4237 char *name_qualifier
;
4245 dbp
= skip_spaces (dbp
);
4247 || (dbp
[0] == '-' && dbp
[1] == '-'))
4249 readline (&lb
, inf
);
4252 switch (lowcase(*dbp
))
4255 if (nocase_tail ("body"))
4257 /* Skipping body of procedure body or package body or ....
4258 resetting qualifier to body instead of spec. */
4259 name_qualifier
= "/b";
4264 /* Skipping type of task type or protected type ... */
4265 if (nocase_tail ("type"))
4272 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
4277 dbp
= skip_spaces (dbp
);
4280 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
4288 name
= concat (dbp
, name_qualifier
, "");
4290 make_tag (name
, strlen (name
), TRUE
,
4291 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4303 bool inquote
= FALSE
;
4304 bool skip_till_semicolumn
= FALSE
;
4306 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4308 while (*dbp
!= '\0')
4310 /* Skip a string i.e. "abcd". */
4311 if (inquote
|| (*dbp
== '"'))
4313 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
4318 continue; /* advance char */
4323 break; /* advance line */
4327 /* Skip comments. */
4328 if (dbp
[0] == '-' && dbp
[1] == '-')
4329 break; /* advance line */
4331 /* Skip character enclosed in single quote i.e. 'a'
4332 and skip single quote starting an attribute i.e. 'Image. */
4341 if (skip_till_semicolumn
)
4344 skip_till_semicolumn
= FALSE
;
4346 continue; /* advance char */
4349 /* Search for beginning of a token. */
4350 if (!begtoken (*dbp
))
4353 continue; /* advance char */
4356 /* We are at the beginning of a token. */
4357 switch (lowcase(*dbp
))
4360 if (!packages_only
&& nocase_tail ("function"))
4361 Ada_getit (inf
, "/f");
4363 break; /* from switch */
4364 continue; /* advance char */
4366 if (!packages_only
&& nocase_tail ("procedure"))
4367 Ada_getit (inf
, "/p");
4368 else if (nocase_tail ("package"))
4369 Ada_getit (inf
, "/s");
4370 else if (nocase_tail ("protected")) /* protected type */
4371 Ada_getit (inf
, "/t");
4373 break; /* from switch */
4374 continue; /* advance char */
4377 if (typedefs
&& !packages_only
&& nocase_tail ("use"))
4379 /* when tagging types, avoid tagging use type Pack.Typename;
4380 for this, we will skip everything till a ; */
4381 skip_till_semicolumn
= TRUE
;
4382 continue; /* advance char */
4386 if (!packages_only
&& nocase_tail ("task"))
4387 Ada_getit (inf
, "/k");
4388 else if (typedefs
&& !packages_only
&& nocase_tail ("type"))
4390 Ada_getit (inf
, "/t");
4391 while (*dbp
!= '\0')
4395 break; /* from switch */
4396 continue; /* advance char */
4399 /* Look for the end of the token. */
4400 while (!endtoken (*dbp
))
4403 } /* advance char */
4404 } /* advance line */
4409 * Unix and microcontroller assembly tag handling
4410 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
4411 * Idea by Bob Weiner, Motorola Inc. (1994)
4419 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4421 /* If first char is alphabetic or one of [_.$], test for colon
4422 following identifier. */
4423 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4425 /* Read past label. */
4427 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4429 if (*cp
== ':' || iswhite (*cp
))
4430 /* Found end of label, so copy it and add it to the table. */
4431 make_tag (lb
.buffer
, cp
- lb
.buffer
, TRUE
,
4432 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4440 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
4441 * Perl variable names: /^(my|local).../
4442 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
4443 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
4444 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
4447 Perl_functions (inf
)
4450 char *package
= savestr ("main"); /* current package name */
4453 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4457 if (LOOKING_AT (cp
, "package"))
4460 get_tag (cp
, &package
);
4462 else if (LOOKING_AT (cp
, "sub"))
4467 while (!notinname (*cp
))
4470 continue; /* nothing found */
4471 if ((pos
= etags_strchr (sp
, ':')) != NULL
4472 && pos
< cp
&& pos
[1] == ':')
4473 /* The name is already qualified. */
4474 make_tag (sp
, cp
- sp
, TRUE
,
4475 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4479 char savechar
, *name
;
4483 name
= concat (package
, "::", sp
);
4485 make_tag (name
, strlen(name
), TRUE
,
4486 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4490 else if (globals
) /* only if we are tagging global vars */
4492 /* Skip a qualifier, if any. */
4493 bool qual
= LOOKING_AT (cp
, "my") || LOOKING_AT (cp
, "local");
4494 /* After "my" or "local", but before any following paren or space. */
4495 char *varstart
= cp
;
4497 if (qual
/* should this be removed? If yes, how? */
4498 && (*cp
== '$' || *cp
== '@' || *cp
== '%'))
4503 while (ISALNUM (*cp
) || *cp
== '_');
4507 /* Should be examining a variable list at this point;
4508 could insist on seeing an open parenthesis. */
4509 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4515 make_tag (varstart
, cp
- varstart
, FALSE
,
4516 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4524 * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4525 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4526 * More ideas by seb bacon <seb@jamkit.com> (2002)
4529 Python_functions (inf
)
4534 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4536 cp
= skip_spaces (cp
);
4537 if (LOOKING_AT (cp
, "def") || LOOKING_AT (cp
, "class"))
4540 while (!notinname (*cp
) && *cp
!= ':')
4542 make_tag (name
, cp
- name
, TRUE
,
4543 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4552 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4553 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4554 * - /^[ \t]*define\(\"[^\"]+/
4555 * Only with --members:
4556 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4557 * Idea by Diez B. Roggisch (2001)
4563 register char *cp
, *name
;
4564 bool search_identifier
= FALSE
;
4566 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4568 cp
= skip_spaces (cp
);
4570 if (search_identifier
4573 while (!notinname (*cp
))
4575 make_tag (name
, cp
- name
, TRUE
,
4576 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4577 search_identifier
= FALSE
;
4579 else if (LOOKING_AT (cp
, "function"))
4582 cp
= skip_spaces (cp
+1);
4586 while (!notinname (*cp
))
4588 make_tag (name
, cp
- name
, TRUE
,
4589 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4592 search_identifier
= TRUE
;
4594 else if (LOOKING_AT (cp
, "class"))
4599 while (*cp
!= '\0' && !iswhite (*cp
))
4601 make_tag (name
, cp
- name
, FALSE
,
4602 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4605 search_identifier
= TRUE
;
4607 else if (strneq (cp
, "define", 6)
4608 && (cp
= skip_spaces (cp
+6))
4610 && (*cp
== '"' || *cp
== '\''))
4614 while (*cp
!= quote
&& *cp
!= '\0')
4616 make_tag (name
, cp
- name
, FALSE
,
4617 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4620 && LOOKING_AT (cp
, "var")
4624 while (!notinname(*cp
))
4626 make_tag (name
, cp
- name
, FALSE
,
4627 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4634 * Cobol tag functions
4635 * We could look for anything that could be a paragraph name.
4636 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4637 * Idea by Corny de Souza (1993)
4640 Cobol_paragraphs (inf
)
4643 register char *bp
, *ep
;
4645 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4651 /* If eoln, compiler option or comment ignore whole line. */
4652 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4655 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4658 make_tag (bp
, ep
- bp
, TRUE
,
4659 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4666 * Ideas by Assar Westerlund <assar@sics.se> (2001)
4669 Makefile_targets (inf
)
4674 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4676 if (*bp
== '\t' || *bp
== '#')
4678 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4680 if (*bp
== ':' || (globals
&& *bp
== '='))
4681 make_tag (lb
.buffer
, bp
- lb
.buffer
, TRUE
,
4682 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4689 * Original code by Mosur K. Mohan (1989)
4691 * Locates tags for procedures & functions. Doesn't do any type- or
4692 * var-definitions. It does look for the keyword "extern" or
4693 * "forward" immediately following the procedure statement; if found,
4694 * the tag is skipped.
4697 Pascal_functions (inf
)
4700 linebuffer tline
; /* mostly copied from C_entries */
4702 int save_lineno
, namelen
, taglen
;
4705 bool /* each of these flags is TRUE iff: */
4706 incomment
, /* point is inside a comment */
4707 inquote
, /* point is inside '..' string */
4708 get_tagname
, /* point is after PROCEDURE/FUNCTION
4709 keyword, so next item = potential tag */
4710 found_tag
, /* point is after a potential tag */
4711 inparms
, /* point is within parameter-list */
4712 verify_tag
; /* point has passed the parm-list, so the
4713 next token will determine whether this
4714 is a FORWARD/EXTERN to be ignored, or
4715 whether it is a real tag */
4717 save_lcno
= save_lineno
= namelen
= taglen
= 0; /* keep compiler quiet */
4718 name
= NULL
; /* keep compiler quiet */
4721 linebuffer_init (&tline
);
4723 incomment
= inquote
= FALSE
;
4724 found_tag
= FALSE
; /* have a proc name; check if extern */
4725 get_tagname
= FALSE
; /* found "procedure" keyword */
4726 inparms
= FALSE
; /* found '(' after "proc" */
4727 verify_tag
= FALSE
; /* check if "extern" is ahead */
4730 while (!feof (inf
)) /* long main loop to get next char */
4733 if (c
== '\0') /* if end of line */
4735 readline (&lb
, inf
);
4739 if (!((found_tag
&& verify_tag
)
4741 c
= *dbp
++; /* only if don't need *dbp pointing
4742 to the beginning of the name of
4743 the procedure or function */
4747 if (c
== '}') /* within { } comments */
4749 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4766 inquote
= TRUE
; /* found first quote */
4768 case '{': /* found open { comment */
4772 if (*dbp
== '*') /* found open (* comment */
4777 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4780 case ')': /* end of parms list */
4785 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4792 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4794 /* Check if this is an "extern" declaration. */
4797 if (lowcase (*dbp
== 'e'))
4799 if (nocase_tail ("extern")) /* superfluous, really! */
4805 else if (lowcase (*dbp
) == 'f')
4807 if (nocase_tail ("forward")) /* check for forward reference */
4813 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4817 make_tag (name
, namelen
, TRUE
,
4818 tline
.buffer
, taglen
, save_lineno
, save_lcno
);
4822 if (get_tagname
) /* grab name of proc or fn */
4829 /* Find block name. */
4830 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4833 /* Save all values for later tagging. */
4834 linebuffer_setlen (&tline
, lb
.len
);
4835 strcpy (tline
.buffer
, lb
.buffer
);
4836 save_lineno
= lineno
;
4837 save_lcno
= linecharno
;
4838 name
= tline
.buffer
+ (dbp
- lb
.buffer
);
4840 taglen
= cp
- lb
.buffer
+ 1;
4842 dbp
= cp
; /* set dbp to e-o-token */
4843 get_tagname
= FALSE
;
4847 /* And proceed to check for "extern". */
4849 else if (!incomment
&& !inquote
&& !found_tag
)
4851 /* Check for proc/fn keywords. */
4852 switch (lowcase (c
))
4855 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4859 if (nocase_tail ("unction"))
4864 } /* while not eof */
4866 free (tline
.buffer
);
4871 * Lisp tag functions
4872 * look for (def or (DEF, quote or QUOTE
4875 static void L_getit
__P((void));
4880 if (*dbp
== '\'') /* Skip prefix quote */
4882 else if (*dbp
== '(')
4885 /* Try to skip "(quote " */
4886 if (!LOOKING_AT (dbp
, "quote") && !LOOKING_AT (dbp
, "QUOTE"))
4887 /* Ok, then skip "(" before name in (defstruct (foo)) */
4888 dbp
= skip_spaces (dbp
);
4890 get_tag (dbp
, NULL
);
4894 Lisp_functions (inf
)
4897 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4902 if (strneq (dbp
+1, "def", 3) || strneq (dbp
+1, "DEF", 3))
4904 dbp
= skip_non_spaces (dbp
);
4905 dbp
= skip_spaces (dbp
);
4910 /* Check for (foo::defmumble name-defined ... */
4913 while (!notinname (*dbp
) && *dbp
!= ':');
4918 while (*dbp
== ':');
4920 if (strneq (dbp
, "def", 3) || strneq (dbp
, "DEF", 3))
4922 dbp
= skip_non_spaces (dbp
);
4923 dbp
= skip_spaces (dbp
);
4933 * Lua script language parsing
4934 * Original code by David A. Capello <dacap@users.sourceforge.net> (2004)
4936 * "function" and "local function" are tags if they start at column 1.
4944 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4946 if (bp
[0] != 'f' && bp
[0] != 'l')
4949 LOOKING_AT (bp
, "local"); /* skip possible "local" */
4951 if (LOOKING_AT (bp
, "function"))
4958 * Postscript tag functions
4959 * Just look for lines where the first character is '/'
4960 * Also look at "defineps" for PSWrap
4962 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4963 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4969 register char *bp
, *ep
;
4971 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4976 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4979 make_tag (bp
, ep
- bp
, TRUE
,
4980 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4982 else if (LOOKING_AT (bp
, "defineps"))
4989 * Scheme tag functions
4990 * look for (def... xyzzy
4992 * (def ... ((...(xyzzy ....
4994 * Original code by Ken Haase (1985?)
4998 Scheme_functions (inf
)
5003 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
5005 if (strneq (bp
, "(def", 4) || strneq (bp
, "(DEF", 4))
5007 bp
= skip_non_spaces (bp
+4);
5008 /* Skip over open parens and white space */
5009 while (notinname (*bp
))
5013 if (LOOKING_AT (bp
, "(SET!") || LOOKING_AT (bp
, "(set!"))
5019 /* Find tags in TeX and LaTeX input files. */
5021 /* TEX_toktab is a table of TeX control sequences that define tags.
5022 * Each entry records one such control sequence.
5024 * Original code from who knows whom.
5026 * Stefan Monnier (2002)
5029 static linebuffer
*TEX_toktab
= NULL
; /* Table with tag tokens */
5031 /* Default set of control sequences to put into TEX_toktab.
5032 The value of environment var TEXTAGS is prepended to this. */
5033 static char *TEX_defenv
= "\
5034 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
5035 :part:appendix:entry:index:def\
5036 :newcommand:renewcommand:newenvironment:renewenvironment";
5038 static void TEX_mode
__P((FILE *));
5039 static void TEX_decode_env
__P((char *, char *));
5041 static char TEX_esc
= '\\';
5042 static char TEX_opgrp
= '{';
5043 static char TEX_clgrp
= '}';
5046 * TeX/LaTeX scanning loop.
5055 /* Select either \ or ! as escape character. */
5058 /* Initialize token table once from environment. */
5059 if (TEX_toktab
== NULL
)
5060 TEX_decode_env ("TEXTAGS", TEX_defenv
);
5062 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5064 /* Look at each TEX keyword in line. */
5067 /* Look for a TEX escape. */
5068 while (*cp
++ != TEX_esc
)
5069 if (cp
[-1] == '\0' || cp
[-1] == '%')
5072 for (key
= TEX_toktab
; key
->buffer
!= NULL
; key
++)
5073 if (strneq (cp
, key
->buffer
, key
->len
))
5076 int namelen
, linelen
;
5079 cp
= skip_spaces (cp
+ key
->len
);
5080 if (*cp
== TEX_opgrp
)
5086 (!iswhite (*p
) && *p
!= '#' &&
5087 *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
);
5092 if (!opgrp
|| *p
== TEX_clgrp
)
5094 while (*p
!= '\0' && *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
)
5096 linelen
= p
- lb
.buffer
+ 1;
5098 make_tag (cp
, namelen
, TRUE
,
5099 lb
.buffer
, linelen
, lineno
, linecharno
);
5100 goto tex_next_line
; /* We only tag a line once */
5108 #define TEX_LESC '\\'
5109 #define TEX_SESC '!'
5111 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
5112 chars accordingly. */
5119 while ((c
= getc (inf
)) != EOF
)
5121 /* Skip to next line if we hit the TeX comment char. */
5125 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
5141 /* If the input file is compressed, inf is a pipe, and rewind may fail.
5142 No attempt is made to correct the situation. */
5146 /* Read environment and prepend it to the default string.
5147 Build token table. */
5149 TEX_decode_env (evarname
, defenv
)
5153 register char *env
, *p
;
5156 /* Append default string to environment. */
5157 env
= getenv (evarname
);
5163 env
= concat (oldenv
, defenv
, "");
5166 /* Allocate a token table */
5167 for (len
= 1, p
= env
; p
;)
5168 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
5170 TEX_toktab
= xnew (len
, linebuffer
);
5172 /* Unpack environment string into token table. Be careful about */
5173 /* zero-length strings (leading ':', "::" and trailing ':') */
5174 for (i
= 0; *env
!= '\0';)
5176 p
= etags_strchr (env
, ':');
5177 if (!p
) /* End of environment string. */
5178 p
= env
+ strlen (env
);
5180 { /* Only non-zero strings. */
5181 TEX_toktab
[i
].buffer
= savenstr (env
, p
- env
);
5182 TEX_toktab
[i
].len
= p
- env
;
5189 TEX_toktab
[i
].buffer
= NULL
; /* Mark end of table. */
5190 TEX_toktab
[i
].len
= 0;
5197 /* Texinfo support. Dave Love, Mar. 2000. */
5203 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5204 if (LOOKING_AT (cp
, "@node"))
5207 while (*cp
!= '\0' && *cp
!= ',')
5209 make_tag (start
, cp
- start
, TRUE
,
5210 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5215 /* Similar to LOOKING_AT but does not use notinname, does not skip */
5216 #define LOOKING_AT_NOCASE(cp, kw) /* kw is a constant string */ \
5217 (strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
5218 && ((cp) += sizeof(kw)-1)) /* skip spaces */
5222 * Contents of <title>, <h1>, <h2>, <h3> are tags.
5223 * Contents of <a name=xxx> are tags with name xxx.
5225 * Francesco Potortì, 2002.
5231 bool getnext
= FALSE
; /* next text outside of HTML tags is a tag */
5232 bool skiptag
= FALSE
; /* skip to the end of the current HTML tag */
5233 bool intag
= FALSE
; /* inside an html tag, looking for ID= */
5234 bool inanchor
= FALSE
; /* when INTAG, is an anchor, look for NAME= */
5238 linebuffer_setlen (&token_name
, 0); /* no name in buffer */
5240 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
5241 for (;;) /* loop on the same line */
5243 if (skiptag
) /* skip HTML tag */
5245 while (*dbp
!= '\0' && *dbp
!= '>')
5251 continue; /* look on the same line */
5253 break; /* go to next line */
5256 else if (intag
) /* look for "name=" or "id=" */
5258 while (*dbp
!= '\0' && *dbp
!= '>'
5259 && lowcase (*dbp
) != 'n' && lowcase (*dbp
) != 'i')
5262 break; /* go to next line */
5267 continue; /* look on the same line */
5269 if ((inanchor
&& LOOKING_AT_NOCASE (dbp
, "name="))
5270 || LOOKING_AT_NOCASE (dbp
, "id="))
5272 bool quoted
= (dbp
[0] == '"');
5275 for (end
= ++dbp
; *end
!= '\0' && *end
!= '"'; end
++)
5278 for (end
= dbp
; *end
!= '\0' && intoken (*end
); end
++)
5280 linebuffer_setlen (&token_name
, end
- dbp
);
5281 strncpy (token_name
.buffer
, dbp
, end
- dbp
);
5282 token_name
.buffer
[end
- dbp
] = '\0';
5285 intag
= FALSE
; /* we found what we looked for */
5286 skiptag
= TRUE
; /* skip to the end of the tag */
5287 getnext
= TRUE
; /* then grab the text */
5288 continue; /* look on the same line */
5293 else if (getnext
) /* grab next tokens and tag them */
5295 dbp
= skip_spaces (dbp
);
5297 break; /* go to next line */
5301 inanchor
= (lowcase (dbp
[1]) == 'a' && !intoken (dbp
[2]));
5302 continue; /* look on the same line */
5305 for (end
= dbp
+ 1; *end
!= '\0' && *end
!= '<'; end
++)
5307 make_tag (token_name
.buffer
, token_name
.len
, TRUE
,
5308 dbp
, end
- dbp
, lineno
, linecharno
);
5309 linebuffer_setlen (&token_name
, 0); /* no name in buffer */
5311 break; /* go to next line */
5314 else /* look for an interesting HTML tag */
5316 while (*dbp
!= '\0' && *dbp
!= '<')
5319 break; /* go to next line */
5321 if (lowcase (dbp
[1]) == 'a' && !intoken (dbp
[2]))
5324 continue; /* look on the same line */
5326 else if (LOOKING_AT_NOCASE (dbp
, "<title>")
5327 || LOOKING_AT_NOCASE (dbp
, "<h1>")
5328 || LOOKING_AT_NOCASE (dbp
, "<h2>")
5329 || LOOKING_AT_NOCASE (dbp
, "<h3>"))
5333 continue; /* look on the same line */
5344 * Assumes that the predicate or rule starts at column 0.
5345 * Only the first clause of a predicate or rule is added.
5346 * Original code by Sunichirou Sugou (1989)
5347 * Rewritten by Anders Lindgren (1996)
5349 static int prolog_pr
__P((char *, char *));
5350 static void prolog_skip_comment
__P((linebuffer
*, FILE *));
5351 static int prolog_atom
__P((char *, int));
5354 Prolog_functions (inf
)
5365 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5367 if (cp
[0] == '\0') /* Empty line */
5369 else if (iswhite (cp
[0])) /* Not a predicate */
5371 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
5372 prolog_skip_comment (&lb
, inf
);
5373 else if ((len
= prolog_pr (cp
, last
)) > 0)
5375 /* Predicate or rule. Store the function name so that we
5376 only generate a tag for the first clause. */
5378 last
= xnew(len
+ 1, char);
5379 else if (len
+ 1 > allocated
)
5380 xrnew (last
, len
+ 1, char);
5381 allocated
= len
+ 1;
5382 strncpy (last
, cp
, len
);
5390 prolog_skip_comment (plb
, inf
)
5398 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
5399 if (cp
[0] == '*' && cp
[1] == '/')
5401 readline (plb
, inf
);
5407 * A predicate or rule definition is added if it matches:
5408 * <beginning of line><Prolog Atom><whitespace>(
5409 * or <beginning of line><Prolog Atom><whitespace>:-
5411 * It is added to the tags database if it doesn't match the
5412 * name of the previous clause header.
5414 * Return the size of the name of the predicate or rule, or 0 if no
5420 char *last
; /* Name of last clause. */
5425 pos
= prolog_atom (s
, 0);
5430 pos
= skip_spaces (s
+ pos
) - s
;
5433 || (s
[pos
] == '(' && (pos
+= 1))
5434 || (s
[pos
] == ':' && s
[pos
+ 1] == '-' && (pos
+= 2)))
5435 && (last
== NULL
/* save only the first clause */
5436 || len
!= strlen (last
)
5437 || !strneq (s
, last
, len
)))
5439 make_tag (s
, len
, TRUE
, s
, pos
, lineno
, linecharno
);
5447 * Consume a Prolog atom.
5448 * Return the number of bytes consumed, or -1 if there was an error.
5450 * A prolog atom, in this context, could be one of:
5451 * - An alphanumeric sequence, starting with a lower case letter.
5452 * - A quoted arbitrary string. Single quotes can escape themselves.
5453 * Backslash quotes everything.
5456 prolog_atom (s
, pos
)
5464 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
5466 /* The atom is unquoted. */
5468 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
5472 return pos
- origpos
;
5474 else if (s
[pos
] == '\'')
5485 pos
++; /* A double quote */
5487 else if (s
[pos
] == '\0')
5488 /* Multiline quoted atoms are ignored. */
5490 else if (s
[pos
] == '\\')
5492 if (s
[pos
+1] == '\0')
5499 return pos
- origpos
;
5507 * Support for Erlang
5509 * Generates tags for functions, defines, and records.
5510 * Assumes that Erlang functions start at column 0.
5511 * Original code by Anders Lindgren (1996)
5513 static int erlang_func
__P((char *, char *));
5514 static void erlang_attribute
__P((char *));
5515 static int erlang_atom
__P((char *));
5518 Erlang_functions (inf
)
5529 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5531 if (cp
[0] == '\0') /* Empty line */
5533 else if (iswhite (cp
[0])) /* Not function nor attribute */
5535 else if (cp
[0] == '%') /* comment */
5537 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
5539 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
5541 erlang_attribute (cp
);
5544 else if ((len
= erlang_func (cp
, last
)) > 0)
5547 * Function. Store the function name so that we only
5548 * generates a tag for the first clause.
5551 last
= xnew (len
+ 1, char);
5552 else if (len
+ 1 > allocated
)
5553 xrnew (last
, len
+ 1, char);
5554 allocated
= len
+ 1;
5555 strncpy (last
, cp
, len
);
5563 * A function definition is added if it matches:
5564 * <beginning of line><Erlang Atom><whitespace>(
5566 * It is added to the tags database if it doesn't match the
5567 * name of the previous clause header.
5569 * Return the size of the name of the function, or 0 if no function
5573 erlang_func (s
, last
)
5575 char *last
; /* Name of last clause. */
5580 pos
= erlang_atom (s
);
5585 pos
= skip_spaces (s
+ pos
) - s
;
5587 /* Save only the first clause. */
5590 || len
!= (int)strlen (last
)
5591 || !strneq (s
, last
, len
)))
5593 make_tag (s
, len
, TRUE
, s
, pos
, lineno
, linecharno
);
5602 * Handle attributes. Currently, tags are generated for defines
5605 * They are on the form:
5606 * -define(foo, bar).
5607 * -define(Foo(M, N), M+N).
5608 * -record(graph, {vtab = notable, cyclic = true}).
5611 erlang_attribute (s
)
5616 if ((LOOKING_AT (cp
, "-define") || LOOKING_AT (cp
, "-record"))
5619 int len
= erlang_atom (skip_spaces (cp
));
5621 make_tag (cp
, len
, TRUE
, s
, cp
+ len
- s
, lineno
, linecharno
);
5628 * Consume an Erlang atom (or variable).
5629 * Return the number of bytes consumed, or -1 if there was an error.
5637 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
5639 /* The atom is unquoted. */
5642 while (ISALNUM (s
[pos
]) || s
[pos
] == '_');
5644 else if (s
[pos
] == '\'')
5646 for (pos
++; s
[pos
] != '\''; pos
++)
5647 if (s
[pos
] == '\0' /* multiline quoted atoms are ignored */
5648 || (s
[pos
] == '\\' && s
[++pos
] == '\0'))
5657 #ifdef ETAGS_REGEXPS
5659 static char *scan_separators
__P((char *));
5660 static void add_regex
__P((char *, language
*));
5661 static char *substitute
__P((char *, char *, struct re_registers
*));
5664 * Take a string like "/blah/" and turn it into "blah", verifying
5665 * that the first and last characters are the same, and handling
5666 * quoted separator characters. Actually, stops on the occurrence of
5667 * an unquoted separator. Also process \t, \n, etc. and turn into
5668 * appropriate characters. Works in place. Null terminates name string.
5669 * Returns pointer to terminating separator, or NULL for
5670 * unterminated regexps.
5673 scan_separators (name
)
5677 char *copyto
= name
;
5678 bool quoted
= FALSE
;
5680 for (++name
; *name
!= '\0'; ++name
)
5686 case 'a': *copyto
++ = '\007'; break; /* BEL (bell) */
5687 case 'b': *copyto
++ = '\b'; break; /* BS (back space) */
5688 case 'd': *copyto
++ = 0177; break; /* DEL (delete) */
5689 case 'e': *copyto
++ = 033; break; /* ESC (delete) */
5690 case 'f': *copyto
++ = '\f'; break; /* FF (form feed) */
5691 case 'n': *copyto
++ = '\n'; break; /* NL (new line) */
5692 case 'r': *copyto
++ = '\r'; break; /* CR (carriage return) */
5693 case 't': *copyto
++ = '\t'; break; /* TAB (horizontal tab) */
5694 case 'v': *copyto
++ = '\v'; break; /* VT (vertical tab) */
5700 /* Something else is quoted, so preserve the quote. */
5708 else if (*name
== '\\')
5710 else if (*name
== sep
)
5716 name
= NULL
; /* signal unterminated regexp */
5718 /* Terminate copied string. */
5723 /* Look at the argument of --regex or --no-regex and do the right
5724 thing. Same for each line of a regexp file. */
5726 analyse_regex (regex_arg
)
5729 if (regex_arg
== NULL
)
5731 free_regexps (); /* --no-regex: remove existing regexps */
5735 /* A real --regexp option or a line in a regexp file. */
5736 switch (regex_arg
[0])
5738 /* Comments in regexp file or null arg to --regex. */
5744 /* Read a regex file. This is recursive and may result in a
5745 loop, which will stop when the file descriptors are exhausted. */
5749 linebuffer regexbuf
;
5750 char *regexfile
= regex_arg
+ 1;
5752 /* regexfile is a file containing regexps, one per line. */
5753 regexfp
= fopen (regexfile
, "r");
5754 if (regexfp
== NULL
)
5759 linebuffer_init (®exbuf
);
5760 while (readline_internal (®exbuf
, regexfp
) > 0)
5761 analyse_regex (regexbuf
.buffer
);
5762 free (regexbuf
.buffer
);
5767 /* Regexp to be used for a specific language only. */
5771 char *lang_name
= regex_arg
+ 1;
5774 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5777 error ("unterminated language name in regex: %s", regex_arg
);
5781 lang
= get_language_from_langname (lang_name
);
5784 add_regex (cp
, lang
);
5788 /* Regexp to be used for any language. */
5790 add_regex (regex_arg
, NULL
);
5795 /* Separate the regexp pattern, compile it,
5796 and care for optional name and modifiers. */
5798 add_regex (regexp_pattern
, lang
)
5799 char *regexp_pattern
;
5802 static struct re_pattern_buffer zeropattern
;
5803 char sep
, *pat
, *name
, *modifiers
;
5805 struct re_pattern_buffer
*patbuf
;
5808 force_explicit_name
= TRUE
, /* do not use implicit tag names */
5809 ignore_case
= FALSE
, /* case is significant */
5810 multi_line
= FALSE
, /* matches are done one line at a time */
5811 single_line
= FALSE
; /* dot does not match newline */
5814 if (strlen(regexp_pattern
) < 3)
5816 error ("null regexp", (char *)NULL
);
5819 sep
= regexp_pattern
[0];
5820 name
= scan_separators (regexp_pattern
);
5823 error ("%s: unterminated regexp", regexp_pattern
);
5828 error ("null name for regexp \"%s\"", regexp_pattern
);
5831 modifiers
= scan_separators (name
);
5832 if (modifiers
== NULL
) /* no terminating separator --> no name */
5838 modifiers
+= 1; /* skip separator */
5840 /* Parse regex modifiers. */
5841 for (; modifiers
[0] != '\0'; modifiers
++)
5842 switch (modifiers
[0])
5845 if (modifiers
== name
)
5846 error ("forcing explicit tag name but no name, ignoring", NULL
);
5847 force_explicit_name
= TRUE
;
5857 need_filebuf
= TRUE
;
5862 wrongmod
[0] = modifiers
[0];
5864 error ("invalid regexp modifier `%s', ignoring", wrongmod
);
5869 patbuf
= xnew (1, struct re_pattern_buffer
);
5870 *patbuf
= zeropattern
;
5873 static char lc_trans
[CHARS
];
5875 for (i
= 0; i
< CHARS
; i
++)
5876 lc_trans
[i
] = lowcase (i
);
5877 patbuf
->translate
= lc_trans
; /* translation table to fold case */
5881 pat
= concat ("^", regexp_pattern
, ""); /* anchor to beginning of line */
5883 pat
= regexp_pattern
;
5886 re_set_syntax (RE_SYNTAX_EMACS
| RE_DOT_NEWLINE
);
5888 re_set_syntax (RE_SYNTAX_EMACS
);
5890 err
= re_compile_pattern (pat
, strlen (regexp_pattern
), patbuf
);
5895 error ("%s while compiling pattern", err
);
5900 p_head
= xnew (1, regexp
);
5901 p_head
->pattern
= savestr (regexp_pattern
);
5902 p_head
->p_next
= rp
;
5903 p_head
->lang
= lang
;
5904 p_head
->pat
= patbuf
;
5905 p_head
->name
= savestr (name
);
5906 p_head
->error_signaled
= FALSE
;
5907 p_head
->force_explicit_name
= force_explicit_name
;
5908 p_head
->ignore_case
= ignore_case
;
5909 p_head
->multi_line
= multi_line
;
5913 * Do the substitutions indicated by the regular expression and
5917 substitute (in
, out
, regs
)
5919 struct re_registers
*regs
;
5922 int size
, dig
, diglen
;
5925 size
= strlen (out
);
5927 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5928 if (out
[size
- 1] == '\\')
5929 fatal ("pattern error in \"%s\"", out
);
5930 for (t
= etags_strchr (out
, '\\');
5932 t
= etags_strchr (t
+ 2, '\\'))
5936 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5942 /* Allocate space and do the substitutions. */
5944 result
= xnew (size
+ 1, char);
5946 for (t
= result
; *out
!= '\0'; out
++)
5947 if (*out
== '\\' && ISDIGIT (*++out
))
5950 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5951 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5958 assert (t
<= result
+ size
);
5959 assert (t
- result
== (int)strlen (result
));
5964 /* Deallocate all regexps. */
5969 while (p_head
!= NULL
)
5971 rp
= p_head
->p_next
;
5972 free (p_head
->pattern
);
5973 free (p_head
->name
);
5981 * Reads the whole file as a single string from `filebuf' and looks for
5982 * multi-line regular expressions, creating tags on matches.
5983 * readline already dealt with normal regexps.
5985 * Idea by Ben Wing <ben@666.com> (2002).
5988 regex_tag_multiline ()
5990 char *buffer
= filebuf
.buffer
;
5994 for (rp
= p_head
; rp
!= NULL
; rp
= rp
->p_next
)
5998 if (!rp
->multi_line
)
5999 continue; /* skip normal regexps */
6001 /* Generic initialisations before parsing file from memory. */
6002 lineno
= 1; /* reset global line number */
6003 charno
= 0; /* reset global char number */
6004 linecharno
= 0; /* reset global char number of line start */
6006 /* Only use generic regexps or those for the current language. */
6007 if (rp
->lang
!= NULL
&& rp
->lang
!= curfdp
->lang
)
6010 while (match
>= 0 && match
< filebuf
.len
)
6012 match
= re_search (rp
->pat
, buffer
, filebuf
.len
, charno
,
6013 filebuf
.len
- match
, &rp
->regs
);
6018 if (!rp
->error_signaled
)
6020 error ("regexp stack overflow while matching \"%s\"",
6022 rp
->error_signaled
= TRUE
;
6029 if (match
== rp
->regs
.end
[0])
6031 if (!rp
->error_signaled
)
6033 error ("regexp matches the empty string: \"%s\"",
6035 rp
->error_signaled
= TRUE
;
6037 match
= -3; /* exit from while loop */
6041 /* Match occurred. Construct a tag. */
6042 while (charno
< rp
->regs
.end
[0])
6043 if (buffer
[charno
++] == '\n')
6044 lineno
++, linecharno
= charno
;
6046 if (name
[0] == '\0')
6048 else /* make a named tag */
6049 name
= substitute (buffer
, rp
->name
, &rp
->regs
);
6050 if (rp
->force_explicit_name
)
6051 /* Force explicit tag name, if a name is there. */
6052 pfnote (name
, TRUE
, buffer
+ linecharno
,
6053 charno
- linecharno
+ 1, lineno
, linecharno
);
6055 make_tag (name
, strlen (name
), TRUE
, buffer
+ linecharno
,
6056 charno
- linecharno
+ 1, lineno
, linecharno
);
6063 #endif /* ETAGS_REGEXPS */
6070 register int len
= 0;
6072 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
6074 if (*cp
== '\0' && !intoken (dbp
[len
]))
6083 get_tag (bp
, namepp
)
6087 register char *cp
= bp
;
6091 /* Go till you get to white space or a syntactic break */
6092 for (cp
= bp
+ 1; !notinname (*cp
); cp
++)
6094 make_tag (bp
, cp
- bp
, TRUE
,
6095 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
6099 *namepp
= savenstr (bp
, cp
- bp
);
6103 * Read a line of text from `stream' into `lbp', excluding the
6104 * newline or CR-NL, if any. Return the number of characters read from
6105 * `stream', which is the length of the line including the newline.
6107 * On DOS or Windows we do not count the CR character, if any before the
6108 * NL, in the returned length; this mirrors the behavior of Emacs on those
6109 * platforms (for text files, it translates CR-NL to NL as it reads in the
6112 * If multi-line regular expressions are requested, each line read is
6113 * appended to `filebuf'.
6116 readline_internal (lbp
, stream
)
6118 register FILE *stream
;
6120 char *buffer
= lbp
->buffer
;
6121 register char *p
= lbp
->buffer
;
6122 register char *pend
;
6125 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
6129 register int c
= getc (stream
);
6132 /* We're at the end of linebuffer: expand it. */
6134 xrnew (buffer
, lbp
->size
, char);
6135 p
+= buffer
- lbp
->buffer
;
6136 pend
= buffer
+ lbp
->size
;
6137 lbp
->buffer
= buffer
;
6147 if (p
> buffer
&& p
[-1] == '\r')
6151 /* Assume CRLF->LF translation will be performed by Emacs
6152 when loading this file, so CRs won't appear in the buffer.
6153 It would be cleaner to compensate within Emacs;
6154 however, Emacs does not know how many CRs were deleted
6155 before any given point in the file. */
6170 lbp
->len
= p
- buffer
;
6172 if (need_filebuf
/* we need filebuf for multi-line regexps */
6173 && chars_deleted
> 0) /* not at EOF */
6175 while (filebuf
.size
<= filebuf
.len
+ lbp
->len
+ 1) /* +1 for \n */
6177 /* Expand filebuf. */
6179 xrnew (filebuf
.buffer
, filebuf
.size
, char);
6181 strncpy (filebuf
.buffer
+ filebuf
.len
, lbp
->buffer
, lbp
->len
);
6182 filebuf
.len
+= lbp
->len
;
6183 filebuf
.buffer
[filebuf
.len
++] = '\n';
6184 filebuf
.buffer
[filebuf
.len
] = '\0';
6187 return lbp
->len
+ chars_deleted
;
6191 * Like readline_internal, above, but in addition try to match the
6192 * input line against relevant regular expressions and manage #line
6196 readline (lbp
, stream
)
6202 linecharno
= charno
; /* update global char number of line start */
6203 result
= readline_internal (lbp
, stream
); /* read line */
6204 lineno
+= 1; /* increment global line number */
6205 charno
+= result
; /* increment global char number */
6207 /* Honour #line directives. */
6208 if (!no_line_directive
)
6210 static bool discard_until_line_directive
;
6212 /* Check whether this is a #line directive. */
6213 if (result
> 12 && strneq (lbp
->buffer
, "#line ", 6))
6217 if (DEBUG
) start
= 0; /* shut up the compiler */
6218 if (sscanf (lbp
->buffer
, "#line %d \"%n", &lno
, &start
) == 1)
6220 char *endp
= lbp
->buffer
+ start
;
6223 while ((endp
= etags_strchr (endp
, '"')) != NULL
6224 && endp
[-1] == '\\')
6227 /* Ok, this is a real #line directive. Let's deal with it. */
6229 char *taggedabsname
; /* absolute name of original file */
6230 char *taggedfname
; /* name of original file as given */
6231 char *name
; /* temp var */
6233 discard_until_line_directive
= FALSE
; /* found it */
6234 name
= lbp
->buffer
+ start
;
6236 canonicalize_filename (name
); /* for DOS */
6237 taggedabsname
= absolute_filename (name
, curfdp
->infabsdir
);
6238 if (filename_is_absolute (name
)
6239 || filename_is_absolute (curfdp
->infname
))
6240 taggedfname
= savestr (taggedabsname
);
6242 taggedfname
= relative_filename (taggedabsname
,tagfiledir
);
6244 if (streq (curfdp
->taggedfname
, taggedfname
))
6245 /* The #line directive is only a line number change. We
6246 deal with this afterwards. */
6249 /* The tags following this #line directive should be
6250 attributed to taggedfname. In order to do this, set
6251 curfdp accordingly. */
6253 fdesc
*fdp
; /* file description pointer */
6255 /* Go look for a file description already set up for the
6256 file indicated in the #line directive. If there is
6257 one, use it from now until the next #line
6259 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
6260 if (streq (fdp
->infname
, curfdp
->infname
)
6261 && streq (fdp
->taggedfname
, taggedfname
))
6262 /* If we remove the second test above (after the &&)
6263 then all entries pertaining to the same file are
6264 coalesced in the tags file. If we use it, then
6265 entries pertaining to the same file but generated
6266 from different files (via #line directives) will
6267 go into separate sections in the tags file. These
6268 alternatives look equivalent. The first one
6269 destroys some apparently useless information. */
6275 /* Else, if we already tagged the real file, skip all
6276 input lines until the next #line directive. */
6277 if (fdp
== NULL
) /* not found */
6278 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
6279 if (streq (fdp
->infabsname
, taggedabsname
))
6281 discard_until_line_directive
= TRUE
;
6285 /* Else create a new file description and use that from
6286 now on, until the next #line directive. */
6287 if (fdp
== NULL
) /* not found */
6290 fdhead
= xnew (1, fdesc
);
6291 *fdhead
= *curfdp
; /* copy curr. file description */
6293 fdhead
->infname
= savestr (curfdp
->infname
);
6294 fdhead
->infabsname
= savestr (curfdp
->infabsname
);
6295 fdhead
->infabsdir
= savestr (curfdp
->infabsdir
);
6296 fdhead
->taggedfname
= taggedfname
;
6297 fdhead
->usecharno
= FALSE
;
6298 fdhead
->prop
= NULL
;
6299 fdhead
->written
= FALSE
;
6303 free (taggedabsname
);
6305 readline (lbp
, stream
);
6307 } /* if a real #line directive */
6308 } /* if #line is followed by a a number */
6309 } /* if line begins with "#line " */
6311 /* If we are here, no #line directive was found. */
6312 if (discard_until_line_directive
)
6316 /* Do a tail recursion on ourselves, thus discarding the contents
6317 of the line buffer. */
6318 readline (lbp
, stream
);
6322 discard_until_line_directive
= FALSE
;
6325 } /* if #line directives should be considered */
6327 #ifdef ETAGS_REGEXPS
6333 /* Match against relevant regexps. */
6335 for (rp
= p_head
; rp
!= NULL
; rp
= rp
->p_next
)
6337 /* Only use generic regexps or those for the current language.
6338 Also do not use multiline regexps, which is the job of
6339 regex_tag_multiline. */
6340 if ((rp
->lang
!= NULL
&& rp
->lang
!= fdhead
->lang
)
6344 match
= re_match (rp
->pat
, lbp
->buffer
, lbp
->len
, 0, &rp
->regs
);
6349 if (!rp
->error_signaled
)
6351 error ("regexp stack overflow while matching \"%s\"",
6353 rp
->error_signaled
= TRUE
;
6360 /* Empty string matched. */
6361 if (!rp
->error_signaled
)
6363 error ("regexp matches the empty string: \"%s\"", rp
->pattern
);
6364 rp
->error_signaled
= TRUE
;
6368 /* Match occurred. Construct a tag. */
6370 if (name
[0] == '\0')
6372 else /* make a named tag */
6373 name
= substitute (lbp
->buffer
, rp
->name
, &rp
->regs
);
6374 if (rp
->force_explicit_name
)
6375 /* Force explicit tag name, if a name is there. */
6376 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
6378 make_tag (name
, strlen (name
), TRUE
,
6379 lbp
->buffer
, match
, lineno
, linecharno
);
6384 #endif /* ETAGS_REGEXPS */
6389 * Return a pointer to a space of size strlen(cp)+1 allocated
6390 * with xnew where the string CP has been copied.
6396 return savenstr (cp
, strlen (cp
));
6400 * Return a pointer to a space of size LEN+1 allocated with xnew where
6401 * the string CP has been copied for at most the first LEN characters.
6410 dp
= xnew (len
+ 1, char);
6411 strncpy (dp
, cp
, len
);
6417 * Return the ptr in sp at which the character c last
6418 * appears; NULL if not found
6420 * Identical to POSIX strrchr, included for portability.
6423 etags_strrchr (sp
, c
)
6424 register const char *sp
;
6427 register const char *r
;
6439 * Return the ptr in sp at which the character c first
6440 * appears; NULL if not found
6442 * Identical to POSIX strchr, included for portability.
6445 etags_strchr (sp
, c
)
6446 register const char *sp
;
6458 * Compare two strings, ignoring case for alphabetic characters.
6460 * Same as BSD's strcasecmp, included for portability.
6463 etags_strcasecmp (s1
, s2
)
6464 register const char *s1
;
6465 register const char *s2
;
6468 && (ISALPHA (*s1
) && ISALPHA (*s2
)
6469 ? lowcase (*s1
) == lowcase (*s2
)
6473 return (ISALPHA (*s1
) && ISALPHA (*s2
)
6474 ? lowcase (*s1
) - lowcase (*s2
)
6479 * Compare two strings, ignoring case for alphabetic characters.
6480 * Stop after a given number of characters
6482 * Same as BSD's strncasecmp, included for portability.
6485 etags_strncasecmp (s1
, s2
, n
)
6486 register const char *s1
;
6487 register const char *s2
;
6490 while (*s1
!= '\0' && n
-- > 0
6491 && (ISALPHA (*s1
) && ISALPHA (*s2
)
6492 ? lowcase (*s1
) == lowcase (*s2
)
6499 return (ISALPHA (*s1
) && ISALPHA (*s2
)
6500 ? lowcase (*s1
) - lowcase (*s2
)
6504 /* Skip spaces, return new pointer. */
6509 while (iswhite (*cp
))
6514 /* Skip non spaces, return new pointer. */
6516 skip_non_spaces (cp
)
6519 while (*cp
!= '\0' && !iswhite (*cp
))
6524 /* Print error message and exit. */
6530 exit (EXIT_FAILURE
);
6538 exit (EXIT_FAILURE
);
6542 suggest_asking_for_help ()
6544 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
6545 progname
, LONG_OPTIONS
? "--help" : "-h");
6546 exit (EXIT_FAILURE
);
6549 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
6552 const char *s1
, *s2
;
6554 fprintf (stderr
, "%s: ", progname
);
6555 fprintf (stderr
, s1
, s2
);
6556 fprintf (stderr
, "\n");
6559 /* Return a newly-allocated string whose contents
6560 concatenate those of s1, s2, s3. */
6565 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
6566 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
6568 strcpy (result
, s1
);
6569 strcpy (result
+ len1
, s2
);
6570 strcpy (result
+ len1
+ len2
, s3
);
6571 result
[len1
+ len2
+ len3
] = '\0';
6577 /* Does the same work as the system V getcwd, but does not need to
6578 guess the buffer size in advance. */
6584 char *path
= xnew (bufsize
, char);
6586 while (getcwd (path
, bufsize
) == NULL
)
6588 if (errno
!= ERANGE
)
6592 path
= xnew (bufsize
, char);
6595 canonicalize_filename (path
);
6598 #else /* not HAVE_GETCWD */
6601 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
6605 for (p
= path
; *p
!= '\0'; p
++)
6611 return strdup (path
);
6612 #else /* not MSDOS */
6616 linebuffer_init (&path
);
6617 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
6618 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
6623 #endif /* not MSDOS */
6624 #endif /* not HAVE_GETCWD */
6627 /* Return a newly allocated string containing the file name of FILE
6628 relative to the absolute directory DIR (which should end with a slash). */
6630 relative_filename (file
, dir
)
6633 char *fp
, *dp
, *afn
, *res
;
6636 /* Find the common root of file and dir (with a trailing slash). */
6637 afn
= absolute_filename (file
, cwd
);
6640 while (*fp
++ == *dp
++)
6642 fp
--, dp
--; /* back to the first differing char */
6644 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
6647 do /* look at the equal chars until '/' */
6651 /* Build a sequence of "../" strings for the resulting relative file name. */
6653 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
6655 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
6658 strcat (res
, "../");
6660 /* Add the file name relative to the common root of file and dir. */
6661 strcat (res
, fp
+ 1);
6667 /* Return a newly allocated string containing the absolute file name
6668 of FILE given DIR (which should end with a slash). */
6670 absolute_filename (file
, dir
)
6673 char *slashp
, *cp
, *res
;
6675 if (filename_is_absolute (file
))
6676 res
= savestr (file
);
6678 /* We don't support non-absolute file names with a drive
6679 letter, like `d:NAME' (it's too much hassle). */
6680 else if (file
[1] == ':')
6681 fatal ("%s: relative file names with drive letters not supported", file
);
6684 res
= concat (dir
, file
, "");
6686 /* Delete the "/dirname/.." and "/." substrings. */
6687 slashp
= etags_strchr (res
, '/');
6688 while (slashp
!= NULL
&& slashp
[0] != '\0')
6690 if (slashp
[1] == '.')
6692 if (slashp
[2] == '.'
6693 && (slashp
[3] == '/' || slashp
[3] == '\0'))
6698 while (cp
>= res
&& !filename_is_absolute (cp
));
6700 cp
= slashp
; /* the absolute name begins with "/.." */
6702 /* Under MSDOS and NT we get `d:/NAME' as absolute
6703 file name, so the luser could say `d:/../NAME'.
6704 We silently treat this as `d:/NAME'. */
6705 else if (cp
[0] != '/')
6708 strcpy (cp
, slashp
+ 3);
6712 else if (slashp
[2] == '/' || slashp
[2] == '\0')
6714 strcpy (slashp
, slashp
+ 2);
6719 slashp
= etags_strchr (slashp
+ 1, '/');
6723 return savestr ("/");
6728 /* Return a newly allocated string containing the absolute
6729 file name of dir where FILE resides given DIR (which should
6730 end with a slash). */
6732 absolute_dirname (file
, dir
)
6738 canonicalize_filename (file
);
6739 slashp
= etags_strrchr (file
, '/');
6741 return savestr (dir
);
6744 res
= absolute_filename (file
, dir
);
6750 /* Whether the argument string is an absolute file name. The argument
6751 string must have been canonicalized with canonicalize_filename. */
6753 filename_is_absolute (fn
)
6756 return (fn
[0] == '/'
6758 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
6763 /* Translate backslashes into slashes. Works in place. */
6765 canonicalize_filename (fn
)
6769 /* Canonicalize drive letter case. */
6770 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
6771 fn
[0] = upcase (fn
[0]);
6772 /* Convert backslashes to slashes. */
6773 for (; *fn
!= '\0'; fn
++)
6778 fn
= NULL
; /* shut up the compiler */
6783 /* Initialize a linebuffer for use */
6785 linebuffer_init (lbp
)
6788 lbp
->size
= (DEBUG
) ? 3 : 200;
6789 lbp
->buffer
= xnew (lbp
->size
, char);
6790 lbp
->buffer
[0] = '\0';
6794 /* Set the minimum size of a string contained in a linebuffer. */
6796 linebuffer_setlen (lbp
, toksize
)
6800 while (lbp
->size
<= toksize
)
6803 xrnew (lbp
->buffer
, lbp
->size
, char);
6808 /* Like malloc but get fatal error if memory is exhausted. */
6813 PTR result
= (PTR
) malloc (size
);
6815 fatal ("virtual memory exhausted", (char *)NULL
);
6820 xrealloc (ptr
, size
)
6824 PTR result
= (PTR
) realloc (ptr
, size
);
6826 fatal ("virtual memory exhausted", (char *)NULL
);
6832 * c-indentation-style: gnu
6833 * indent-tabs-mode: t
6836 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc" "node" "regexp")
6840 /* arch-tag: 8a9b748d-390c-4922-99db-2eeefa921051
6841 (do not change this comment) */
6843 /* etags.c ends here */