1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
2 Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2001
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 Regexp tags by Tom Tromey.
31 * 2001 Nested classes by Francesco Potortì (ideas by Mykola Dzyuba).
33 * Francesco Potortì <pot@gnu.org> has maintained it since 1993.
36 char pot_etags_version
[] = "@(#) pot revision number is 15.2";
46 # define NDEBUG /* disable assert */
51 /* On some systems, Emacs defines static as nothing for the sake
52 of unexec. We don't want that here since we don't use unexec. */
54 # define ETAGS_REGEXPS /* use the regexp features */
55 # define LONG_OPTIONS /* accept long options */
56 # ifndef PTR /* for Xemacs */
59 # ifndef __P /* for Xemacs */
60 # define __P(args) args
63 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
64 # define __P(args) args /* use prototypes */
65 # define PTR void * /* for generic pointers */
67 # define __P(args) () /* no prototypes */
68 # define const /* remove const for old compilers' sake */
69 # define PTR long * /* don't use void* */
71 #endif /* !HAVE_CONFIG_H */
74 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
77 /* WIN32_NATIVE is for Xemacs.
78 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
83 #endif /* WIN32_NATIVE */
89 # include <sys/param.h>
91 # ifndef HAVE_CONFIG_H
93 # include <sys/config.h>
105 # define MAXPATHLEN _MAX_PATH
111 # endif /* undef HAVE_GETCWD */
112 #else /* !WINDOWSNT */
117 extern char *getenv ();
119 #endif /* !WINDOWSNT */
124 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
125 extern char *getcwd (char *buf
, size_t size
);
127 #endif /* HAVE_UNISTD_H */
135 #include <sys/types.h>
136 #include <sys/stat.h>
140 # undef assert /* some systems have a buggy assert.h */
141 # define assert(x) ((void) 0)
144 #if !defined (S_ISREG) && defined (S_IFREG)
145 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
151 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
153 extern int optind
, opterr
;
154 #endif /* LONG_OPTIONS */
157 # ifndef HAVE_CONFIG_H /* this is a standalone compilation */
158 # ifdef __CYGWIN__ /* compiling on Cygwin */
160 the regex
.h distributed with Cygwin is
not compatible with etags
, alas
!
161 If you want regular expression support
, you should
delete this notice
and
162 arrange to use the GNU regex
.h
and regex
.c
.
166 #endif /* ETAGS_REGEXPS */
168 /* Define CTAGS to make the program "ctags" compatible with the usual one.
169 Leave it undefined to make the program "etags", which makes emacs-style
170 tag tables and tags typedefs, #defines and struct/union/enum by default. */
178 /* Exit codes for success and failure. */
187 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
188 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
190 #define CHARS 256 /* 2^sizeof(char) */
191 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
192 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
193 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
194 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
195 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
196 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
198 #define ISALNUM(c) isalnum (CHAR(c))
199 #define ISALPHA(c) isalpha (CHAR(c))
200 #define ISDIGIT(c) isdigit (CHAR(c))
201 #define ISLOWER(c) islower (CHAR(c))
203 #define lowcase(c) tolower (CHAR(c))
204 #define upcase(c) toupper (CHAR(c))
208 * xnew, xrnew -- allocate, reallocate storage
210 * SYNOPSIS: Type *xnew (int n, Type);
211 * void xrnew (OldPointer, int n, Type);
214 # include "chkmalloc.h"
215 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
216 (n) * sizeof (Type)))
217 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
218 (char *) (op), (n) * sizeof (Type)))
220 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
221 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
222 (char *) (op), (n) * sizeof (Type)))
227 typedef void Lang_function
__P((FILE *));
232 char *command
; /* Takes one arg and decompresses to stdout */
238 Lang_function
*function
;
244 typedef struct node_st
245 { /* sorting structure */
246 char *name
; /* function or type name */
247 char *file
; /* file name */
248 bool is_func
; /* use pattern or line no */
249 bool been_warned
; /* set if noticed dup */
250 int lno
; /* line number tag is on */
251 long cno
; /* character number line starts on */
252 char *pat
; /* search pattern */
253 struct node_st
*left
, *right
; /* left and right sons */
257 * A `linebuffer' is a structure which holds a line of text.
258 * `readline_internal' reads a line from a stream into a linebuffer
259 * and works regardless of the length of the line.
260 * SIZE is the size of BUFFER, LEN is the length of the string in
261 * BUFFER after readline reads it.
270 /* Many compilers barf on this:
271 Lang_function Ada_funcs;
272 so let's write it this way */
273 static void Ada_funcs
__P((FILE *));
274 static void Asm_labels
__P((FILE *));
275 static void C_entries
__P((int c_ext
, FILE *));
276 static void default_C_entries
__P((FILE *));
277 static void plain_C_entries
__P((FILE *));
278 static void Cjava_entries
__P((FILE *));
279 static void Cobol_paragraphs
__P((FILE *));
280 static void Cplusplus_entries
__P((FILE *));
281 static void Cstar_entries
__P((FILE *));
282 static void Erlang_functions
__P((FILE *));
283 static void Fortran_functions
__P((FILE *));
284 static void Yacc_entries
__P((FILE *));
285 static void Lisp_functions
__P((FILE *));
286 static void Makefile_targets
__P((FILE *));
287 static void Pascal_functions
__P((FILE *));
288 static void Perl_functions
__P((FILE *));
289 static void PHP_functions
__P((FILE *));
290 static void Postscript_functions
__P((FILE *));
291 static void Prolog_functions
__P((FILE *));
292 static void Python_functions
__P((FILE *));
293 static void Scheme_functions
__P((FILE *));
294 static void TeX_commands
__P((FILE *));
295 static void Texinfo_nodes
__P((FILE *));
296 static void just_read_file
__P((FILE *));
298 static void print_language_names
__P((void));
299 static void print_version
__P((void));
300 static void print_help
__P((void));
301 int main
__P((int, char **));
303 static compressor
*get_compressor_from_suffix
__P((char *, char **));
304 static language
*get_language_from_langname
__P((const char *));
305 static language
*get_language_from_interpreter
__P((char *));
306 static language
*get_language_from_filename
__P((char *));
307 static long readline
__P((linebuffer
*, FILE *));
308 static long readline_internal
__P((linebuffer
*, FILE *));
309 static bool nocase_tail
__P((char *));
310 static char *get_tag
__P((char *));
313 static void analyse_regex
__P((char *, bool));
314 static void add_regex
__P((char *, bool, language
*));
315 static void free_patterns
__P((void));
316 #endif /* ETAGS_REGEXPS */
317 static void error
__P((const char *, const char *));
318 static void suggest_asking_for_help
__P((void));
319 void fatal
__P((char *, char *));
320 static void pfatal
__P((char *));
321 static void add_node
__P((node
*, node
**));
323 static void init
__P((void));
324 static void initbuffer
__P((linebuffer
*));
325 static void find_entries
__P((char *, FILE *));
326 static void free_tree
__P((node
*));
327 static void pfnote
__P((char *, bool, char *, int, int, long));
328 static void new_pfnote
__P((char *, int, bool, char *, int, int, long));
329 static void process_file
__P((char *));
330 static void put_entries
__P((node
*));
332 static char *concat
__P((char *, char *, char *));
333 static char *skip_spaces
__P((char *));
334 static char *skip_non_spaces
__P((char *));
335 static char *savenstr
__P((char *, int));
336 static char *savestr
__P((char *));
337 static char *etags_strchr
__P((const char *, int));
338 static char *etags_strrchr
__P((const char *, int));
339 static char *etags_getcwd
__P((void));
340 static char *relative_filename
__P((char *, char *));
341 static char *absolute_filename
__P((char *, char *));
342 static char *absolute_dirname
__P((char *, char *));
343 static bool filename_is_absolute
__P((char *f
));
344 static void canonicalize_filename
__P((char *));
345 static void linebuffer_setlen
__P((linebuffer
*, int));
346 static PTR xmalloc
__P((unsigned int));
347 static PTR xrealloc
__P((char *, unsigned int));
350 static char searchar
= '/'; /* use /.../ searches */
352 static char *tagfile
; /* output file */
353 static char *progname
; /* name this program was invoked with */
354 static char *cwd
; /* current working directory */
355 static char *tagfiledir
; /* directory of tagfile */
356 static FILE *tagf
; /* ioptr for tags file */
358 static char *curfile
; /* current input uncompressed file name */
359 static char *curfiledir
; /* absolute dir of curfile */
360 static char *curtagfname
; /* current file name to write in tagfile */
361 static language
*curlang
; /* current language */
363 static int lineno
; /* line number of current line */
364 static long charno
; /* current character number */
365 static long linecharno
; /* charno of start of current line */
366 static char *dbp
; /* pointer to start of current tag */
367 static bool nocharno
; /* only use line number when making tag */
368 static const int invalidcharno
= -1;
370 static node
*head
; /* the head of the binary tree of tags */
372 static linebuffer lb
; /* the current line */
374 /* boolean "functions" (see init) */
375 static bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
378 *white
= " \f\t\n\r\v",
380 *nonam
= " \f\t\n\r()=,;",
381 /* token ending chars */
382 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
383 /* token starting chars */
384 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
385 /* valid in-token chars */
386 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
388 static bool append_to_tagfile
; /* -a: append to tags */
389 /* The following four default to TRUE for etags, but to FALSE for ctags. */
390 static bool typedefs
; /* -t: create tags for C and Ada typedefs */
391 static bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
392 /* 0 struct/enum/union decls, and C++ */
393 /* member functions. */
394 static bool constantypedefs
; /* -d: create tags for C #define, enum */
395 /* constants and variables. */
396 /* -D: opposite of -d. Default under ctags. */
397 static bool declarations
; /* --declarations: tag them and extern in C&Co*/
398 static bool globals
; /* create tags for global variables */
399 static bool no_line_directive
; /* ignore #line directives */
400 static bool members
; /* create tags for C member variables */
401 static bool update
; /* -u: update tags */
402 static bool vgrind_style
; /* -v: create vgrind style index output */
403 static bool no_warnings
; /* -w: suppress warnings */
404 static bool cxref_style
; /* -x: create cxref style output */
405 static bool cplusplus
; /* .[hc] means C++, not C */
406 static bool noindentypedefs
; /* -I: ignore indentation in C */
407 static bool packages_only
; /* --packages-only: in Ada, only tag packages*/
410 static struct option longopts
[] =
412 { "packages-only", no_argument
, &packages_only
, TRUE
},
413 { "append", no_argument
, NULL
, 'a' },
414 { "backward-search", no_argument
, NULL
, 'B' },
415 { "c++", no_argument
, NULL
, 'C' },
416 { "cxref", no_argument
, NULL
, 'x' },
417 { "defines", no_argument
, NULL
, 'd' },
418 { "declarations", no_argument
, &declarations
, TRUE
},
419 { "no-defines", no_argument
, NULL
, 'D' },
420 { "globals", no_argument
, &globals
, TRUE
},
421 { "no-globals", no_argument
, &globals
, FALSE
},
422 { "no-line-directive", no_argument
, &no_line_directive
, TRUE
},
423 { "help", no_argument
, NULL
, 'h' },
424 { "help", no_argument
, NULL
, 'H' },
425 { "ignore-indentation", no_argument
, NULL
, 'I' },
426 { "include", required_argument
, NULL
, 'i' },
427 { "language", required_argument
, NULL
, 'l' },
428 { "members", no_argument
, &members
, TRUE
},
429 { "no-members", no_argument
, &members
, FALSE
},
430 { "no-warn", no_argument
, NULL
, 'w' },
431 { "output", required_argument
, NULL
, 'o' },
433 { "regex", required_argument
, NULL
, 'r' },
434 { "no-regex", no_argument
, NULL
, 'R' },
435 { "ignore-case-regex", required_argument
, NULL
, 'c' },
436 #endif /* ETAGS_REGEXPS */
437 { "typedefs", no_argument
, NULL
, 't' },
438 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
439 { "update", no_argument
, NULL
, 'u' },
440 { "version", no_argument
, NULL
, 'V' },
441 { "vgrind", no_argument
, NULL
, 'v' },
444 #endif /* LONG_OPTIONS */
447 /* Structure defining a regular expression. Elements are
448 the compiled pattern, and the name string. */
449 typedef struct pattern
451 struct pattern
*p_next
;
454 struct re_pattern_buffer
*pat
;
455 struct re_registers regs
;
460 /* List of all regexps. */
461 static pattern
*p_head
= NULL
;
463 /* How many characters in the character set. (From regex.c.) */
464 #define CHAR_SET_SIZE 256
465 /* Translation table for case-insensitive matching. */
466 static char lc_trans
[CHAR_SET_SIZE
];
467 #endif /* ETAGS_REGEXPS */
469 static compressor compressors
[] =
471 { "z", "gzip -d -c"},
472 { "Z", "gzip -d -c"},
473 { "gz", "gzip -d -c"},
474 { "GZ", "gzip -d -c"},
475 { "bz2", "bzip2 -d -c" },
483 /* Non-NULL if language fixed. */
484 static language
*forced_lang
= NULL
;
487 static char *Ada_suffixes
[] =
488 { "ads", "adb", "ada", NULL
};
491 static char *Asm_suffixes
[] =
492 { "a", /* Unix assembler */
493 "asm", /* Microcontroller assembly */
494 "def", /* BSO/Tasking definition includes */
495 "inc", /* Microcontroller include files */
496 "ins", /* Microcontroller include files */
497 "s", "sa", /* Unix assembler */
498 "S", /* cpp-processed Unix assembler */
499 "src", /* BSO/Tasking C compiler output */
503 /* Note that .c and .h can be considered C++, if the --c++ flag was
504 given, or if the `class' keyowrd is met inside the file.
505 That is why default_C_entries is called for these. */
506 static char *default_C_suffixes
[] =
509 static char *Cplusplus_suffixes
[] =
510 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
511 "M", /* Objective C++ */
512 "pdb", /* Postscript with C syntax */
515 static char *Cjava_suffixes
[] =
518 static char *Cobol_suffixes
[] =
519 { "COB", "cob", NULL
};
521 static char *Cstar_suffixes
[] =
522 { "cs", "hs", NULL
};
524 static char *Erlang_suffixes
[] =
525 { "erl", "hrl", NULL
};
527 static char *Fortran_suffixes
[] =
528 { "F", "f", "f90", "for", NULL
};
530 static char *Lisp_suffixes
[] =
531 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
533 static char *Makefile_filenames
[] =
534 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
536 static char *Pascal_suffixes
[] =
537 { "p", "pas", NULL
};
539 static char *Perl_suffixes
[] =
540 { "pl", "pm", NULL
};
542 static char *Perl_interpreters
[] =
543 { "perl", "@PERL@", NULL
};
545 static char *PHP_suffixes
[] =
546 { "php", "php3", "php4", NULL
};
548 static char *plain_C_suffixes
[] =
549 { "lm", /* Objective lex file */
550 "m", /* Objective C file */
551 "pc", /* Pro*C file */
554 static char *Postscript_suffixes
[] =
555 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
557 static char *Prolog_suffixes
[] =
560 static char *Python_suffixes
[] =
563 /* Can't do the `SCM' or `scm' prefix with a version number. */
564 static char *Scheme_suffixes
[] =
565 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
567 static char *TeX_suffixes
[] =
568 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
570 static char *Texinfo_suffixes
[] =
571 { "texi", "texinfo", "txi", NULL
};
573 static char *Yacc_suffixes
[] =
574 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
577 * Table of languages.
579 * It is ok for a given function to be listed under more than one
580 * name. I just didn't.
583 static language lang_names
[] =
585 { "ada", Ada_funcs
, NULL
, Ada_suffixes
, NULL
},
586 { "asm", Asm_labels
, NULL
, Asm_suffixes
, NULL
},
587 { "c", default_C_entries
, NULL
, default_C_suffixes
, NULL
},
588 { "c++", Cplusplus_entries
, NULL
, Cplusplus_suffixes
, NULL
},
589 { "c*", Cstar_entries
, NULL
, Cstar_suffixes
, NULL
},
590 { "cobol", Cobol_paragraphs
, NULL
, Cobol_suffixes
, NULL
},
591 { "erlang", Erlang_functions
, NULL
, Erlang_suffixes
, NULL
},
592 { "fortran", Fortran_functions
, NULL
, Fortran_suffixes
, NULL
},
593 { "java", Cjava_entries
, NULL
, Cjava_suffixes
, NULL
},
594 { "lisp", Lisp_functions
, NULL
, Lisp_suffixes
, NULL
},
595 { "makefile", Makefile_targets
, Makefile_filenames
, NULL
, NULL
},
596 { "pascal", Pascal_functions
, NULL
, Pascal_suffixes
, NULL
},
597 { "perl", Perl_functions
, NULL
, Perl_suffixes
, Perl_interpreters
},
598 { "php", PHP_functions
, NULL
, PHP_suffixes
, NULL
},
599 { "postscript", Postscript_functions
, NULL
, Postscript_suffixes
, NULL
},
600 { "proc", plain_C_entries
, NULL
, plain_C_suffixes
, NULL
},
601 { "prolog", Prolog_functions
, NULL
, Prolog_suffixes
, NULL
},
602 { "python", Python_functions
, NULL
, Python_suffixes
, NULL
},
603 { "scheme", Scheme_functions
, NULL
, Scheme_suffixes
, NULL
},
604 { "tex", TeX_commands
, NULL
, TeX_suffixes
, NULL
},
605 { "texinfo", Texinfo_nodes
, NULL
, Texinfo_suffixes
, NULL
},
606 { "yacc", Yacc_entries
, NULL
, Yacc_suffixes
, NULL
},
607 { "auto", NULL
}, /* default guessing scheme */
608 { "none", just_read_file
}, /* regexp matching only */
609 { NULL
, NULL
} /* end of list */
614 print_language_names ()
619 puts ("\nThese are the currently supported languages, along with the\n\
620 default file names and dot suffixes:");
621 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
623 printf (" %-*s", 10, lang
->name
);
624 if (lang
->filenames
!= NULL
)
625 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
626 printf (" %s", *name
);
627 if (lang
->suffixes
!= NULL
)
628 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
629 printf (" .%s", *ext
);
632 puts ("Where `auto' means use default language for files based on file\n\
633 name suffix, and `none' means only do regexp processing on files.\n\
634 If no language is specified and no matching suffix is found,\n\
635 the first line of the file is read for a sharp-bang (#!) sequence\n\
636 followed by the name of an interpreter. If no such sequence is found,\n\
637 Fortran is tried first; if no tags are found, C is tried next.\n\
638 When parsing any C file, a \"class\" keyword switches to C++.\n\
639 Compressed files are supported using gzip and bzip2.");
643 # define EMACS_NAME "GNU Emacs"
646 # define VERSION "21"
651 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
652 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
653 puts ("This program is distributed under the same terms as Emacs");
661 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
663 These are the options accepted by %s.\n", progname
, progname
);
665 puts ("You may use unambiguous abbreviations for the long option names.");
667 puts ("Long option names do not work with this executable, as it is not\n\
668 linked with GNU getopt.");
669 #endif /* LONG_OPTIONS */
670 puts ("A - as file name means read names from stdin (one per line).");
672 printf (" Absolute names are stored in the output file as they are.\n\
673 Relative ones are stored relative to the output file's directory.");
676 puts ("-a, --append\n\
677 Append tag entries to existing tags file.");
679 puts ("--packages-only\n\
680 For Ada files, only generate tags for packages .");
683 puts ("-B, --backward-search\n\
684 Write the search commands for the tag entries using '?', the\n\
685 backward-search command instead of '/', the forward-search command.");
687 /* This option is mostly obsolete, because etags can now automatically
688 detect C++. Retained for backward compatibility and for debugging and
689 experimentation. In principle, we could want to tag as C++ even
690 before any "class" keyword.
692 Treat files whose name suffix defaults to C language as C++ files.");
695 puts ("--declarations\n\
696 In C and derived languages, create tags for function declarations,");
698 puts ("\tand create tags for extern variables if --globals is used.");
701 ("\tand create tags for extern variables unless --no-globals is used.");
704 puts ("-d, --defines\n\
705 Create tag entries for C #define constants and enum constants, too.");
707 puts ("-D, --no-defines\n\
708 Don't create tag entries for C #define constants and enum constants.\n\
709 This makes the tags file smaller.");
713 puts ("-i FILE, --include=FILE\n\
714 Include a note in tag file indicating that, when searching for\n\
715 a tag, one should also consult the tags file FILE after\n\
716 checking the current file.");
717 puts ("-l LANG, --language=LANG\n\
718 Force the following files to be considered as written in the\n\
719 named language up to the next --language=LANG option.");
724 Create tag entries for global variables in some languages.");
726 puts ("--no-globals\n\
727 Do not create tag entries for global variables in some\n\
728 languages. This makes the tags file smaller.");
730 Create tag entries for member variables in C and derived languages.");
733 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
734 Make a tag for each line matching pattern REGEXP in the following\n\
735 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
736 regexfile is a file containing one REGEXP per line.\n\
737 REGEXP is anchored (as if preceded by ^).\n\
738 The form /REGEXP/NAME/ creates a named tag.\n\
739 For example Tcl named tags can be created with:\n\
740 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\"");
741 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
742 Like -r, --regex but ignore case when matching expressions.");
743 puts ("-R, --no-regex\n\
744 Don't create tags from regexps for the following files.");
745 #endif /* ETAGS_REGEXPS */
746 puts ("-o FILE, --output=FILE\n\
747 Write the tags to FILE.");
748 puts ("-I, --ignore-indentation\n\
749 Don't rely on indentation quite as much as normal. Currently,\n\
750 this means not to assume that a closing brace in the first\n\
751 column is the final brace of a function or structure\n\
752 definition in C and C++.");
756 puts ("-t, --typedefs\n\
757 Generate tag entries for C and Ada typedefs.");
758 puts ("-T, --typedefs-and-c++\n\
759 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
760 and C++ member functions.");
761 puts ("-u, --update\n\
762 Update the tag entries for the given files, leaving tag\n\
763 entries for other files in place. Currently, this is\n\
764 implemented by deleting the existing entries for the given\n\
765 files and then rewriting the new entries at the end of the\n\
766 tags file. It is often faster to simply rebuild the entire\n\
767 tag file than to use this.");
768 puts ("-v, --vgrind\n\
769 Generates an index of items intended for human consumption,\n\
770 similar to the output of vgrind. The index is sorted, and\n\
771 gives the page number of each item.");
772 puts ("-w, --no-warn\n\
773 Suppress warning messages about entries defined in multiple\n\
775 puts ("-x, --cxref\n\
776 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
777 The output uses line numbers instead of page numbers, but\n\
778 beyond that the differences are cosmetic; try both to see\n\
782 puts ("-V, --version\n\
783 Print the version of the program.\n\
785 Print this help message.");
787 print_language_names ();
790 puts ("Report bugs to bug-gnu-emacs@gnu.org");
804 /* This structure helps us allow mixing of --lang and file names. */
807 enum argument_type arg_type
;
809 language
*lang
; /* language of the regexp */
812 #ifdef VMS /* VMS specific functions */
816 /* This is a BUG! ANY arbitrary limit is a BUG!
817 Won't someone please fix this? */
818 #define MAX_FILE_SPEC_LEN 255
821 char body
[MAX_FILE_SPEC_LEN
+ 1];
825 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
826 returning in each successive call the next file name matching the input
827 spec. The function expects that each in_spec passed
828 to it will be processed to completion; in particular, up to and
829 including the call following that in which the last matching name
830 is returned, the function ignores the value of in_spec, and will
831 only start processing a new spec with the following call.
832 If an error occurs, on return out_spec contains the value
833 of in_spec when the error occurred.
835 With each successive file name returned in out_spec, the
836 function's return value is one. When there are no more matching
837 names the function returns zero. If on the first call no file
838 matches in_spec, or there is any other error, -1 is returned.
843 #define OUTSIZE MAX_FILE_SPEC_LEN
849 static long context
= 0;
850 static struct dsc$descriptor_s o
;
851 static struct dsc$descriptor_s i
;
852 static bool pass1
= TRUE
;
859 o
.dsc$a_pointer
= (char *) out
;
860 o
.dsc$w_length
= (short)OUTSIZE
;
861 i
.dsc$a_pointer
= in
;
862 i
.dsc$w_length
= (short)strlen(in
);
863 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
864 i
.dsc$b_class
= DSC$K_CLASS_S
;
865 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
866 o
.dsc$b_class
= DSC$K_CLASS_VS
;
868 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
870 out
->body
[out
->curlen
] = EOS
;
873 else if (status
== RMS$_NMF
)
877 strcpy(out
->body
, in
);
880 lib$
find_file_end(&context
);
886 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
887 name of each file specified by the provided arg expanding wildcards.
890 gfnames (arg
, p_error
)
894 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
896 switch (fn_exp (&filename
, arg
))
900 return filename
.body
;
906 return filename
.body
;
910 #ifndef OLD /* Newer versions of VMS do provide `system'. */
914 error ("%s", "system() function not implemented under VMS");
918 #define VERSION_DELIM ';'
919 char *massage_name (s
)
925 if (*s
== VERSION_DELIM
)
943 unsigned int nincluded_files
;
944 char **included_files
;
947 int current_arg
, file_count
;
948 linebuffer filename_lb
;
954 _fmode
= O_BINARY
; /* all of files are treated as binary files */
959 included_files
= xnew (argc
, char *);
963 /* Allocate enough no matter what happens. Overkill, but each one
965 argbuffer
= xnew (argc
, argument
);
968 /* Set syntax for regular expression routines. */
969 re_set_syntax (RE_SYNTAX_EMACS
| RE_INTERVALS
);
970 /* Translation table for case-insensitive search. */
971 for (i
= 0; i
< CHAR_SET_SIZE
; i
++)
972 lc_trans
[i
] = lowcase (i
);
973 #endif /* ETAGS_REGEXPS */
976 * If etags, always find typedefs and structure tags. Why not?
977 * Also default to find macro constants, enum constants and
982 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
984 declarations
= FALSE
;
994 optstring
= "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
996 optstring
= "-aCdDf:Il:o:StTi:BuvxwVhH";
997 #endif /* ETAGS_REGEXPS */
1000 optstring
= optstring
+ 1;
1001 #endif /* LONG_OPTIONS */
1003 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
1010 /* If getopt returns 0, then it has already processed a
1011 long-named option. We should do nothing. */
1015 /* This means that a file name has been seen. Record it. */
1016 argbuffer
[current_arg
].arg_type
= at_filename
;
1017 argbuffer
[current_arg
].what
= optarg
;
1022 /* Common options. */
1023 case 'a': append_to_tagfile
= TRUE
; break;
1024 case 'C': cplusplus
= TRUE
; break;
1025 case 'd': constantypedefs
= TRUE
; break;
1026 case 'D': constantypedefs
= FALSE
; break;
1027 case 'f': /* for compatibility with old makefiles */
1031 error ("-o option may only be given once.", (char *)NULL
);
1032 suggest_asking_for_help ();
1037 case 'S': /* for backward compatibility */
1038 noindentypedefs
= TRUE
;
1042 language
*lang
= get_language_from_langname (optarg
);
1045 argbuffer
[current_arg
].lang
= lang
;
1046 argbuffer
[current_arg
].arg_type
= at_language
;
1052 argbuffer
[current_arg
].arg_type
= at_regexp
;
1053 argbuffer
[current_arg
].what
= optarg
;
1057 argbuffer
[current_arg
].arg_type
= at_regexp
;
1058 argbuffer
[current_arg
].what
= NULL
;
1062 argbuffer
[current_arg
].arg_type
= at_icregexp
;
1063 argbuffer
[current_arg
].what
= optarg
;
1077 typedefs
= typedefs_or_cplusplus
= TRUE
;
1081 included_files
[nincluded_files
++] = optarg
;
1083 /* Ctags options. */
1084 case 'B': searchar
= '?'; break;
1085 case 'u': update
= TRUE
; break;
1086 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1087 case 'x': cxref_style
= TRUE
; break;
1088 case 'w': no_warnings
= TRUE
; break;
1090 suggest_asking_for_help ();
1094 for (; optind
< argc
; ++optind
)
1096 argbuffer
[current_arg
].arg_type
= at_filename
;
1097 argbuffer
[current_arg
].what
= argv
[optind
];
1102 if (nincluded_files
== 0 && file_count
== 0)
1104 error ("no input files specified.", (char *)NULL
);
1105 suggest_asking_for_help ();
1108 if (tagfile
== NULL
)
1109 tagfile
= CTAGS
? "tags" : "TAGS";
1110 cwd
= etags_getcwd (); /* the current working directory */
1111 if (cwd
[strlen (cwd
) - 1] != '/')
1114 cwd
= concat (oldcwd
, "/", "");
1117 if (streq (tagfile
, "-"))
1120 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1122 init (); /* set up boolean "functions" */
1125 initbuffer (&filename_lb
);
1129 if (streq (tagfile
, "-"))
1133 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1134 doesn't take effect until after `stdout' is already open). */
1135 if (!isatty (fileno (stdout
)))
1136 setmode (fileno (stdout
), O_BINARY
);
1140 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1146 * Loop through files finding functions.
1148 for (i
= 0; i
< current_arg
; ++i
)
1150 switch (argbuffer
[i
].arg_type
)
1153 forced_lang
= argbuffer
[i
].lang
;
1155 #ifdef ETAGS_REGEXPS
1157 analyse_regex (argbuffer
[i
].what
, FALSE
);
1160 analyse_regex (argbuffer
[i
].what
, TRUE
);
1165 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1169 error ("can't find file %s\n", this_file
);
1174 this_file
= massage_name (this_file
);
1177 this_file
= argbuffer
[i
].what
;
1179 /* Input file named "-" means read file names from stdin
1180 (one per line) and use them. */
1181 if (streq (this_file
, "-"))
1182 while (readline_internal (&filename_lb
, stdin
) > 0)
1183 process_file (filename_lb
.buffer
);
1185 process_file (this_file
);
1193 #ifdef ETAGS_REGEXPS
1195 #endif /* ETAGS_REGEXPS */
1197 if (!CTAGS
|| cxref_style
)
1203 while (nincluded_files
-- > 0)
1204 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1206 if (fclose (tagf
) == EOF
)
1214 for (i
= 0; i
< current_arg
; ++i
)
1216 if (argbuffer
[i
].arg_type
!= at_filename
)
1219 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1220 tagfile
, argbuffer
[i
].what
, tagfile
);
1221 if (system (cmd
) != GOOD
)
1222 fatal ("failed to execute shell command", (char *)NULL
);
1224 append_to_tagfile
= TRUE
;
1227 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1233 if (fclose (tagf
) == EOF
)
1239 sprintf (cmd
, "sort -o %s %s", tagfile
, tagfile
);
1240 exit (system (cmd
));
1248 * Return a compressor given the file name. If EXTPTR is non-zero,
1249 * return a pointer into FILE where the compressor-specific
1250 * extension begins. If no compressor is found, NULL is returned
1251 * and EXTPTR is not significant.
1252 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1255 get_compressor_from_suffix (file
, extptr
)
1260 char *slash
, *suffix
;
1262 /* This relies on FN to be after canonicalize_filename,
1263 so we don't need to consider backslashes on DOS_NT. */
1264 slash
= etags_strrchr (file
, '/');
1265 suffix
= etags_strrchr (file
, '.');
1266 if (suffix
== NULL
|| suffix
< slash
)
1271 /* Let those poor souls who live with DOS 8+3 file name limits get
1272 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1273 Only the first do loop is run if not MSDOS */
1276 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1277 if (streq (compr
->suffix
, suffix
))
1280 break; /* do it only once: not really a loop */
1283 } while (*suffix
!= '\0');
1290 * Return a language given the name.
1293 get_language_from_langname (name
)
1299 error ("empty language name", (char *)NULL
);
1302 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1303 if (streq (name
, lang
->name
))
1305 error ("unknown language \"%s\"", name
);
1313 * Return a language given the interpreter name.
1316 get_language_from_interpreter (interpreter
)
1322 if (interpreter
== NULL
)
1324 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1325 if (lang
->interpreters
!= NULL
)
1326 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1327 if (streq (*iname
, interpreter
))
1336 * Return a language given the file name.
1339 get_language_from_filename (file
)
1343 char **name
, **ext
, *suffix
;
1345 /* Try whole file name first. */
1346 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1347 if (lang
->filenames
!= NULL
)
1348 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1349 if (streq (*name
, file
))
1352 /* If not found, try suffix after last dot. */
1353 suffix
= etags_strrchr (file
, '.');
1357 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1358 if (lang
->suffixes
!= NULL
)
1359 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1360 if (streq (*ext
, suffix
))
1368 * This routine is called on each file argument.
1374 struct stat stat_buf
;
1377 char *compressed_name
, *uncompressed_name
;
1378 char *ext
, *real_name
;
1382 canonicalize_filename (file
);
1383 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1385 error ("skipping inclusion of %s in self.", file
);
1388 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1390 compressed_name
= NULL
;
1391 real_name
= uncompressed_name
= savestr (file
);
1395 real_name
= compressed_name
= savestr (file
);
1396 uncompressed_name
= savenstr (file
, ext
- file
);
1399 /* If the canonicalized uncompressed name has already be dealt with,
1400 skip it silently, else add it to the list. */
1402 typedef struct processed_file
1405 struct processed_file
*next
;
1407 static processed_file
*pf_head
= NULL
;
1408 register processed_file
*fnp
;
1410 for (fnp
= pf_head
; fnp
!= NULL
; fnp
= fnp
->next
)
1411 if (streq (uncompressed_name
, fnp
->filename
))
1414 pf_head
= xnew (1, struct processed_file
);
1415 pf_head
->filename
= savestr (uncompressed_name
);
1416 pf_head
->next
= fnp
;
1419 if (stat (real_name
, &stat_buf
) != 0)
1421 /* Reset real_name and try with a different name. */
1423 if (compressed_name
!= NULL
) /* try with the given suffix */
1425 if (stat (uncompressed_name
, &stat_buf
) == 0)
1426 real_name
= uncompressed_name
;
1428 else /* try all possible suffixes */
1430 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1432 compressed_name
= concat (file
, ".", compr
->suffix
);
1433 if (stat (compressed_name
, &stat_buf
) != 0)
1437 char *suf
= compressed_name
+ strlen (file
);
1438 size_t suflen
= strlen (compr
->suffix
) + 1;
1439 for ( ; suf
[1]; suf
++, suflen
--)
1441 memmove (suf
, suf
+ 1, suflen
);
1442 if (stat (compressed_name
, &stat_buf
) == 0)
1444 real_name
= compressed_name
;
1448 if (real_name
!= NULL
)
1451 free (compressed_name
);
1452 compressed_name
= NULL
;
1456 real_name
= compressed_name
;
1461 if (real_name
== NULL
)
1466 } /* try with a different name */
1468 if (!S_ISREG (stat_buf
.st_mode
))
1470 error ("skipping %s: it is not a regular file.", real_name
);
1473 if (real_name
== compressed_name
)
1475 char *cmd
= concat (compr
->command
, " ", real_name
);
1476 inf
= (FILE *) popen (cmd
, "r");
1480 inf
= fopen (real_name
, "r");
1487 curfile
= uncompressed_name
;
1488 curfiledir
= absolute_dirname (curfile
, cwd
);
1489 if (filename_is_absolute (curfile
))
1491 /* file is an absolute file name. Canonicalize it. */
1492 curtagfname
= absolute_filename (curfile
, NULL
);
1496 /* file is a file name relative to cwd. Make it relative
1497 to the directory of the tags file. */
1498 curtagfname
= relative_filename (curfile
, tagfiledir
);
1500 nocharno
= FALSE
; /* use char position when making tags */
1501 find_entries (curfile
, inf
);
1504 if (real_name
== compressed_name
)
1505 retval
= pclose (inf
);
1507 retval
= fclose (inf
);
1512 if (compressed_name
) free(compressed_name
);
1513 if (uncompressed_name
) free(uncompressed_name
);
1518 * This routine sets up the boolean pseudo-functions which work
1519 * by setting boolean flags dependent upon the corresponding character.
1520 * Every char which is NOT in that string is not a white char. Therefore,
1521 * all of the array "_wht" is set to FALSE, and then the elements
1522 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1523 * of a char is TRUE if it is the string "white", else FALSE.
1531 for (i
= 0; i
< CHARS
; i
++)
1532 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1533 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1534 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1535 notinname('\0') = notinname('\n');
1536 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1537 begtoken('\0') = begtoken('\n');
1538 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1539 intoken('\0') = intoken('\n');
1540 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1541 endtoken('\0') = endtoken('\n');
1545 * This routine opens the specified file and calls the function
1546 * which finds the function and type definitions.
1548 static node
*last_node
= NULL
;
1551 find_entries (file
, inf
)
1557 node
*old_last_node
;
1559 /* If user specified a language, use it. */
1561 if (lang
!= NULL
&& lang
->function
!= NULL
)
1564 lang
->function (inf
);
1568 /* Try to guess the language given the file name. */
1569 lang
= get_language_from_filename (file
);
1570 if (lang
!= NULL
&& lang
->function
!= NULL
)
1573 lang
->function (inf
);
1577 /* Look for sharp-bang as the first two characters. */
1578 if (readline_internal (&lb
, inf
) > 0
1580 && lb
.buffer
[0] == '#'
1581 && lb
.buffer
[1] == '!')
1585 /* Set lp to point at the first char after the last slash in the
1586 line or, if no slashes, at the first nonblank. Then set cp to
1587 the first successive blank and terminate the string. */
1588 lp
= etags_strrchr (lb
.buffer
+2, '/');
1592 lp
= skip_spaces (lb
.buffer
+ 2);
1593 cp
= skip_non_spaces (lp
);
1596 if (strlen (lp
) > 0)
1598 lang
= get_language_from_interpreter (lp
);
1599 if (lang
!= NULL
&& lang
->function
!= NULL
)
1602 lang
->function (inf
);
1607 /* We rewind here, even if inf may be a pipe. We fail if the
1608 length of the first line is longer than the pipe block size,
1609 which is unlikely. */
1613 old_last_node
= last_node
;
1614 curlang
= get_language_from_langname ("fortran");
1615 Fortran_functions (inf
);
1617 /* No Fortran entries found. Try C. */
1618 if (old_last_node
== last_node
)
1620 /* We do not tag if rewind fails.
1621 Only the file name will be recorded in the tags file. */
1623 curlang
= get_language_from_langname (cplusplus
? "c++" : "c");
1624 default_C_entries (inf
);
1632 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1633 char *name
; /* tag name, or NULL if unnamed */
1634 bool is_func
; /* tag is a function */
1635 char *linestart
; /* start of the line where tag is */
1636 int linelen
; /* length of the line where tag is */
1637 int lno
; /* line number */
1638 long cno
; /* character number */
1642 if (CTAGS
&& name
== NULL
)
1645 np
= xnew (1, node
);
1647 /* If ctags mode, change name "main" to M<thisfilename>. */
1648 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1650 register char *fp
= etags_strrchr (curtagfname
, '/');
1651 np
->name
= concat ("M", fp
== NULL
? curtagfname
: fp
+ 1, "");
1652 fp
= etags_strrchr (np
->name
, '.');
1653 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
1658 np
->been_warned
= FALSE
;
1659 np
->file
= curtagfname
;
1660 np
->is_func
= is_func
;
1663 np
->cno
= invalidcharno
;
1665 /* Our char numbers are 0-base, because of C language tradition?
1666 ctags compatibility? old versions compatibility? I don't know.
1667 Anyway, since emacs's are 1-base we expect etags.el to take care
1668 of the difference. If we wanted to have 1-based numbers, we would
1669 uncomment the +1 below. */
1670 np
->cno
= cno
/* + 1 */ ;
1671 np
->left
= np
->right
= NULL
;
1672 if (CTAGS
&& !cxref_style
)
1674 if (strlen (linestart
) < 50)
1675 np
->pat
= concat (linestart
, "$", "");
1677 np
->pat
= savenstr (linestart
, 50);
1680 np
->pat
= savenstr (linestart
, linelen
);
1682 add_node (np
, &head
);
1686 * TAGS format specification
1687 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1689 * pfnote should emit the optimized form [unnamed tag] only if:
1690 * 1. name does not contain any of the characters " \t\r\n(),;";
1691 * 2. linestart contains name as either a rightmost, or rightmost but
1692 * one character, substring;
1693 * 3. the character, if any, immediately before name in linestart must
1694 * be one of the characters " \t(),;";
1695 * 4. the character, if any, immediately after name in linestart must
1696 * also be one of the characters " \t(),;".
1698 * The real implementation uses the notinname() macro, which recognises
1699 * characters slightly different from " \t\r\n(),;". See the variable
1702 #define traditional_tag_style TRUE
1704 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1705 char *name
; /* tag name, or NULL if unnamed */
1706 int namelen
; /* tag length */
1707 bool is_func
; /* tag is a function */
1708 char *linestart
; /* start of the line where tag is */
1709 int linelen
; /* length of the line where tag is */
1710 int lno
; /* line number */
1711 long cno
; /* character number */
1719 for (cp
= name
; !notinname (*cp
); cp
++)
1721 if (*cp
== '\0') /* rule #1 */
1723 cp
= linestart
+ linelen
- namelen
;
1724 if (notinname (linestart
[linelen
-1]))
1725 cp
-= 1; /* rule #4 */
1726 if (cp
>= linestart
/* rule #2 */
1728 || notinname (cp
[-1])) /* rule #3 */
1729 && strneq (name
, cp
, namelen
)) /* rule #2 */
1730 named
= FALSE
; /* use unnamed tag */
1735 name
= savenstr (name
, namelen
);
1738 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1743 * recurse on left children, iterate on right children.
1751 register node
*node_right
= np
->right
;
1752 free_tree (np
->left
);
1753 if (np
->name
!= NULL
)
1763 * Adds a node to the tree of nodes. In etags mode, sort by file
1764 * name. In ctags mode, sort by tag name. Make no attempt at
1767 * add_node is the only function allowed to add nodes, so it can
1771 add_node (np
, cur_node_p
)
1772 node
*np
, **cur_node_p
;
1775 register node
*cur_node
= *cur_node_p
;
1777 if (cur_node
== NULL
)
1787 assert (last_node
!= NULL
);
1788 /* For each file name, tags are in a linked sublist on the right
1789 pointer. The first tags of different files are a linked list
1790 on the left pointer. last_node points to the end of the last
1792 if (last_node
->file
== np
->file
)
1794 /* Let's use the same sublist as the last added node. */
1795 last_node
->right
= np
;
1798 else if (streq (cur_node
->file
, np
->file
))
1800 /* Scanning the list we found the head of a sublist which is
1801 good for us. Let's scan this sublist. */
1802 add_node (np
, &cur_node
->right
);
1805 /* The head of this sublist is not good for us. Let's try the
1807 add_node (np
, &cur_node
->left
);
1812 dif
= strcmp (np
->name
, cur_node
->name
);
1815 * If this tag name matches an existing one, then
1816 * do not add the node, but maybe print a warning.
1820 if (streq (np
->file
, cur_node
->file
))
1824 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1825 np
->file
, lineno
, np
->name
);
1826 fprintf (stderr
, "Second entry ignored\n");
1829 else if (!cur_node
->been_warned
&& !no_warnings
)
1833 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1834 np
->file
, cur_node
->file
, np
->name
);
1835 cur_node
->been_warned
= TRUE
;
1840 /* Actually add the node */
1841 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1846 static int total_size_of_entries
__P((node
*));
1847 static int number_len
__P((long));
1849 /* Length of a number's decimal representation. */
1855 while ((num
/= 10) > 0)
1861 * Return total number of characters that put_entries will output for
1862 * the nodes in the linked list at the right of the specified node.
1863 * This count is irrelevant with etags.el since emacs 19.34 at least,
1864 * but is still supplied for backward compatibility.
1867 total_size_of_entries (np
)
1870 register int total
= 0;
1872 for (; np
!= NULL
; np
= np
->right
)
1874 total
+= strlen (np
->pat
) + 1; /* pat\177 */
1875 if (np
->name
!= NULL
)
1876 total
+= strlen (np
->name
) + 1; /* name\001 */
1877 total
+= number_len ((long) np
->lno
) + 1; /* lno, */
1878 if (np
->cno
!= invalidcharno
) /* cno */
1879 total
+= number_len (np
->cno
);
1880 total
+= 1; /* newline */
1891 static char *file
= NULL
;
1896 /* Output subentries that precede this one */
1898 put_entries (np
->left
);
1900 /* Output this entry */
1904 if (file
!= np
->file
1905 && (file
== NULL
|| !streq (file
, np
->file
)))
1908 fprintf (tagf
, "\f\n%s,%d\n",
1909 file
, total_size_of_entries (np
));
1911 fputs (np
->pat
, tagf
);
1912 fputc ('\177', tagf
);
1913 if (np
->name
!= NULL
)
1915 fputs (np
->name
, tagf
);
1916 fputc ('\001', tagf
);
1918 fprintf (tagf
, "%d,", np
->lno
);
1919 if (np
->cno
== invalidcharno
)
1922 fprintf (tagf
, "%ld\n", np
->cno
);
1927 if (np
->name
== NULL
)
1928 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
1933 fprintf (stdout
, "%s %s %d\n",
1934 np
->name
, np
->file
, (np
->lno
+ 63) / 64);
1936 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1937 np
->name
, np
->lno
, np
->file
, np
->pat
);
1941 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->file
);
1945 putc (searchar
, tagf
);
1948 for (sp
= np
->pat
; *sp
; sp
++)
1950 if (*sp
== '\\' || *sp
== searchar
)
1954 putc (searchar
, tagf
);
1957 { /* a typedef; text pattern inadequate */
1958 fprintf (tagf
, "%d", np
->lno
);
1965 /* Output subentries that follow this one */
1966 put_entries (np
->right
);
1968 put_entries (np
->left
);
1973 #define C_EXT 0x00fff /* C extensions */
1974 #define C_PLAIN 0x00000 /* C */
1975 #define C_PLPL 0x00001 /* C++ */
1976 #define C_STAR 0x00003 /* C* */
1977 #define C_JAVA 0x00005 /* JAVA */
1978 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
1979 #define YACC 0x10000 /* yacc file */
1982 * The C symbol tables.
1987 st_C_objprot
, st_C_objimpl
, st_C_objend
,
1992 st_C_class
, st_C_template
,
1993 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1996 static unsigned int hash
__P((const char *, unsigned int));
1997 static struct C_stab_entry
* in_word_set
__P((const char *, unsigned int));
1998 static enum sym_type C_symtype
__P((char *, int, int));
2000 /* Feed stuff between (but not including) %[ and %] lines to:
2001 gperf -c -k 1,3 -o -p -r -t
2003 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2007 while, 0, st_C_ignore
2008 switch, 0, st_C_ignore
2009 return, 0, st_C_ignore
2010 @interface, 0, st_C_objprot
2011 @protocol, 0, st_C_objprot
2012 @implementation,0, st_C_objimpl
2013 @end, 0, st_C_objend
2014 import, C_JAVA, st_C_ignore
2015 package, C_JAVA, st_C_ignore
2016 friend, C_PLPL, st_C_ignore
2017 extends, C_JAVA, st_C_javastruct
2018 implements, C_JAVA, st_C_javastruct
2019 interface, C_JAVA, st_C_struct
2020 class, 0, st_C_class
2021 namespace, C_PLPL, st_C_struct
2022 domain, C_STAR, st_C_struct
2023 union, 0, st_C_struct
2024 struct, 0, st_C_struct
2025 extern, 0, st_C_extern
2027 typedef, 0, st_C_typedef
2028 define, 0, st_C_define
2029 operator, C_PLPL, st_C_operator
2030 template, 0, st_C_template
2031 bool, C_PLPL, st_C_typespec
2032 long, 0, st_C_typespec
2033 short, 0, st_C_typespec
2034 int, 0, st_C_typespec
2035 char, 0, st_C_typespec
2036 float, 0, st_C_typespec
2037 double, 0, st_C_typespec
2038 signed, 0, st_C_typespec
2039 unsigned, 0, st_C_typespec
2040 auto, 0, st_C_typespec
2041 void, 0, st_C_typespec
2042 static, 0, st_C_typespec
2043 const, 0, st_C_typespec
2044 volatile, 0, st_C_typespec
2045 explicit, C_PLPL, st_C_typespec
2046 mutable, C_PLPL, st_C_typespec
2047 typename, C_PLPL, st_C_typespec
2048 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2049 DEFUN, 0, st_C_gnumacro
2050 SYSCALL, 0, st_C_gnumacro
2051 ENTRY, 0, st_C_gnumacro
2052 PSEUDO, 0, st_C_gnumacro
2053 # These are defined inside C functions, so currently they are not met.
2054 # EXFUN used in glibc, DEFVAR_* in emacs.
2055 #EXFUN, 0, st_C_gnumacro
2056 #DEFVAR_, 0, st_C_gnumacro
2058 and replace lines between %< and %> with its output,
2059 then make in_word_set and C_stab_entry static. */
2061 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
2062 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
2063 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2065 #define TOTAL_KEYWORDS 47
2066 #define MIN_WORD_LENGTH 2
2067 #define MAX_WORD_LENGTH 15
2068 #define MIN_HASH_VALUE 18
2069 #define MAX_HASH_VALUE 138
2070 /* maximum key range = 121, duplicates = 0 */
2077 register const char *str
;
2078 register unsigned int len
;
2080 static unsigned char asso_values
[] =
2082 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2083 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2084 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2085 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2086 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2087 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2088 139, 139, 139, 139, 63, 139, 139, 139, 33, 44,
2089 62, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2090 42, 139, 139, 12, 32, 139, 139, 139, 139, 139,
2091 139, 139, 139, 139, 139, 139, 139, 34, 59, 37,
2092 24, 58, 33, 3, 139, 16, 139, 139, 42, 60,
2093 18, 11, 39, 139, 23, 57, 4, 63, 6, 20,
2094 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2095 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2096 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2097 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2098 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2099 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2100 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2101 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2102 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2103 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2104 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2105 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2106 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2107 139, 139, 139, 139, 139, 139
2109 register int hval
= len
;
2115 hval
+= asso_values
[(unsigned char)str
[2]];
2118 hval
+= asso_values
[(unsigned char)str
[0]];
2127 static struct C_stab_entry
*
2128 in_word_set (str
, len
)
2129 register const char *str
;
2130 register unsigned int len
;
2132 static struct C_stab_entry wordlist
[] =
2134 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2135 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2136 {"if", 0, st_C_ignore
},
2137 {""}, {""}, {""}, {""},
2138 {"int", 0, st_C_typespec
},
2140 {"void", 0, st_C_typespec
},
2142 {"interface", C_JAVA
, st_C_struct
},
2144 {"SYSCALL", 0, st_C_gnumacro
},
2146 {"return", 0, st_C_ignore
},
2147 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2148 {"while", 0, st_C_ignore
},
2149 {"auto", 0, st_C_typespec
},
2150 {""}, {""}, {""}, {""}, {""}, {""},
2151 {"float", 0, st_C_typespec
},
2152 {"typedef", 0, st_C_typedef
},
2153 {"typename", C_PLPL
, st_C_typespec
},
2155 {"friend", C_PLPL
, st_C_ignore
},
2156 {"volatile", 0, st_C_typespec
},
2158 {"for", 0, st_C_ignore
},
2159 {"const", 0, st_C_typespec
},
2160 {"import", C_JAVA
, st_C_ignore
},
2162 {"define", 0, st_C_define
},
2163 {"long", 0, st_C_typespec
},
2164 {"implements", C_JAVA
, st_C_javastruct
},
2165 {"signed", 0, st_C_typespec
},
2167 {"extern", 0, st_C_extern
},
2168 {"extends", C_JAVA
, st_C_javastruct
},
2170 {"mutable", C_PLPL
, st_C_typespec
},
2171 {"template", 0, st_C_template
},
2172 {"short", 0, st_C_typespec
},
2173 {"bool", C_PLPL
, st_C_typespec
},
2174 {"char", 0, st_C_typespec
},
2175 {"class", 0, st_C_class
},
2176 {"operator", C_PLPL
, st_C_operator
},
2178 {"switch", 0, st_C_ignore
},
2180 {"ENTRY", 0, st_C_gnumacro
},
2182 {"package", C_JAVA
, st_C_ignore
},
2183 {"union", 0, st_C_struct
},
2184 {"@end", 0, st_C_objend
},
2185 {"struct", 0, st_C_struct
},
2186 {"namespace", C_PLPL
, st_C_struct
},
2188 {"domain", C_STAR
, st_C_struct
},
2189 {"@interface", 0, st_C_objprot
},
2190 {"PSEUDO", 0, st_C_gnumacro
},
2191 {"double", 0, st_C_typespec
},
2193 {"@protocol", 0, st_C_objprot
},
2195 {"static", 0, st_C_typespec
},
2197 {"DEFUN", 0, st_C_gnumacro
},
2198 {""}, {""}, {""}, {""},
2199 {"explicit", C_PLPL
, st_C_typespec
},
2200 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2201 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2203 {"enum", 0, st_C_enum
},
2205 {"unsigned", 0, st_C_typespec
},
2206 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2207 {"@implementation",0, st_C_objimpl
}
2210 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2212 register int key
= hash (str
, len
);
2214 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2216 register const char *s
= wordlist
[key
].name
;
2218 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
2219 return &wordlist
[key
];
2226 static enum sym_type
2227 C_symtype (str
, len
, c_ext
)
2232 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2234 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2241 * C functions and variables are recognized using a simple
2242 * finite automaton. fvdef is its state variable.
2246 fvnone
, /* nothing seen */
2247 fdefunkey
, /* Emacs DEFUN keyword seen */
2248 fdefunname
, /* Emacs DEFUN name seen */
2249 foperator
, /* func: operator keyword seen (cplpl) */
2250 fvnameseen
, /* function or variable name seen */
2251 fstartlist
, /* func: just after open parenthesis */
2252 finlist
, /* func: in parameter list */
2253 flistseen
, /* func: after parameter list */
2254 fignore
, /* func: before open brace */
2255 vignore
/* var-like: ignore until ';' */
2258 static bool fvextern
; /* func or var: extern keyword seen; */
2261 * typedefs are recognized using a simple finite automaton.
2262 * typdef is its state variable.
2266 tnone
, /* nothing seen */
2267 tkeyseen
, /* typedef keyword seen */
2268 ttypeseen
, /* defined type seen */
2269 tinbody
, /* inside typedef body */
2270 tend
, /* just before typedef tag */
2271 tignore
/* junk after typedef tag */
2275 * struct-like structures (enum, struct and union) are recognized
2276 * using another simple finite automaton. `structdef' is its state
2281 snone
, /* nothing seen yet,
2282 or in struct body if cblev > 0 */
2283 skeyseen
, /* struct-like keyword seen */
2284 stagseen
, /* struct-like tag seen */
2285 sintemplate
, /* inside template (ignore) */
2286 scolonseen
/* colon seen after struct-like tag */
2290 * When objdef is different from onone, objtag is the name of the class.
2292 static char *objtag
= "<uninited>";
2295 * Yet another little state machine to deal with preprocessor lines.
2299 dnone
, /* nothing seen */
2300 dsharpseen
, /* '#' seen as first char on line */
2301 ddefineseen
, /* '#' and 'define' seen */
2302 dignorerest
/* ignore rest of line */
2306 * State machine for Objective C protocols and implementations.
2307 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2311 onone
, /* nothing seen */
2312 oprotocol
, /* @interface or @protocol seen */
2313 oimplementation
, /* @implementations seen */
2314 otagseen
, /* class name seen */
2315 oparenseen
, /* parenthesis before category seen */
2316 ocatseen
, /* category name seen */
2317 oinbody
, /* in @implementation body */
2318 omethodsign
, /* in @implementation body, after +/- */
2319 omethodtag
, /* after method name */
2320 omethodcolon
, /* after method colon */
2321 omethodparm
, /* after method parameter */
2322 oignore
/* wait for @end */
2327 * Use this structure to keep info about the token read, and how it
2328 * should be tagged. Used by the make_C_tag function to build a tag.
2339 } token
; /* latest token read */
2340 static linebuffer token_name
; /* its name */
2343 * Variables and functions for dealing with nested structures.
2344 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2346 static void pushclass_above
__P((int, char *, int));
2347 static void popclass_above
__P((int));
2348 static void write_classname
__P((linebuffer
*, char *qualifier
));
2351 char **cname
; /* nested class names */
2352 int *cblev
; /* nested class curly brace level */
2353 int nl
; /* class nesting level (elements used) */
2354 int size
; /* length of the array */
2355 } cstack
; /* stack for nested declaration tags */
2356 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2357 #define nestlev (cstack.nl)
2358 /* After struct keyword or in struct body, not inside an nested function. */
2359 #define instruct (structdef == snone && nestlev > 0 \
2360 && cblev == cstack.cblev[nestlev-1] + 1)
2363 pushclass_above (cblev
, str
, len
)
2370 popclass_above (cblev
);
2372 if (nl
>= cstack
.size
)
2374 int size
= cstack
.size
*= 2;
2375 xrnew (cstack
.cname
, size
, char *);
2376 xrnew (cstack
.cblev
, size
, int);
2378 assert (nl
== 0 || cstack
.cblev
[nl
-1] < cblev
);
2379 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2380 cstack
.cblev
[nl
] = cblev
;
2385 popclass_above (cblev
)
2390 for (nl
= cstack
.nl
- 1;
2391 nl
>= 0 && cstack
.cblev
[nl
] >= cblev
;
2394 if (cstack
.cname
[nl
] != NULL
)
2395 free (cstack
.cname
[nl
]);
2401 write_classname (cn
, qualifier
)
2406 int qlen
= strlen (qualifier
);
2408 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2412 cn
->buffer
[0] = '\0';
2416 len
= strlen (cstack
.cname
[0]);
2417 linebuffer_setlen (cn
, len
);
2418 strcpy (cn
->buffer
, cstack
.cname
[0]);
2420 for (i
= 1; i
< cstack
.nl
; i
++)
2425 s
= cstack
.cname
[i
];
2430 linebuffer_setlen (cn
, len
);
2431 strncat (cn
->buffer
, qualifier
, qlen
);
2432 strncat (cn
->buffer
, s
, slen
);
2437 static bool consider_token
__P((char *, int, int, int *, int, int, bool *));
2438 static void make_C_tag
__P((bool));
2442 * checks to see if the current token is at the start of a
2443 * function or variable, or corresponds to a typedef, or
2444 * is a struct/union/enum tag, or #define, or an enum constant.
2446 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2447 * with args. C_EXTP points to which language we are looking at.
2458 consider_token (str
, len
, c
, c_extp
, cblev
, parlev
, is_func_or_var
)
2459 register char *str
; /* IN: token pointer */
2460 register int len
; /* IN: token length */
2461 register int c
; /* IN: first char after the token */
2462 int *c_extp
; /* IN, OUT: C extensions mask */
2463 int cblev
; /* IN: curly brace level */
2464 int parlev
; /* IN: parenthesis level */
2465 bool *is_func_or_var
; /* OUT: function or variable found */
2467 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2468 structtype is the type of the preceding struct-like keyword, and
2469 structcblev is the curly brace level where it has been seen. */
2470 static enum sym_type structtype
;
2471 static int structcblev
;
2472 static enum sym_type toktype
;
2475 toktype
= C_symtype (str
, len
, *c_extp
);
2478 * Advance the definedef state machine.
2483 /* We're not on a preprocessor line. */
2484 if (toktype
== st_C_gnumacro
)
2491 if (toktype
== st_C_define
)
2493 definedef
= ddefineseen
;
2497 definedef
= dignorerest
;
2502 * Make a tag for any macro, unless it is a constant
2503 * and constantypedefs is FALSE.
2505 definedef
= dignorerest
;
2506 *is_func_or_var
= (c
== '(');
2507 if (!*is_func_or_var
&& !constantypedefs
)
2514 error ("internal error: definedef value.", (char *)NULL
);
2523 if (toktype
== st_C_typedef
)
2545 if (structdef
== snone
&& fvdef
== fvnone
)
2564 * This structdef business is NOT invoked when we are ctags and the
2565 * file is plain C. This is because a struct tag may have the same
2566 * name as another tag, and this loses with ctags.
2570 case st_C_javastruct
:
2571 if (structdef
== stagseen
)
2572 structdef
= scolonseen
;
2577 && (*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2578 && definedef
== dnone
&& structdef
== snone
2579 && typdef
== tnone
&& fvdef
== fvnone
)
2580 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2581 if (toktype
== st_C_template
)
2588 && (typdef
== tkeyseen
2589 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2591 structdef
= skeyseen
;
2592 structtype
= toktype
;
2593 structcblev
= cblev
;
2598 if (structdef
== skeyseen
)
2600 structdef
= stagseen
;
2604 if (typdef
!= tnone
)
2607 /* Detect Objective C constructs. */
2617 objdef
= oimplementation
;
2621 case oimplementation
:
2622 /* Save the class tag for functions or variables defined inside. */
2623 objtag
= savenstr (str
, len
);
2627 /* Save the class tag for categories. */
2628 objtag
= savenstr (str
, len
);
2630 *is_func_or_var
= TRUE
;
2634 *is_func_or_var
= TRUE
;
2641 objdef
= omethodtag
;
2642 linebuffer_setlen (&token_name
, len
);
2643 strncpy (token_name
.buffer
, str
, len
);
2644 token_name
.buffer
[len
] = '\0';
2650 objdef
= omethodparm
;
2655 objdef
= omethodtag
;
2656 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
2657 strncat (token_name
.buffer
, str
, len
);
2662 if (toktype
== st_C_objend
)
2664 /* Memory leakage here: the string pointed by objtag is
2665 never released, because many tests would be needed to
2666 avoid breaking on incorrect input code. The amount of
2667 memory leaked here is the sum of the lengths of the
2675 /* A function, variable or enum constant? */
2682 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2683 fvdef
= fvnone
; /* should be useless */
2691 *is_func_or_var
= TRUE
;
2695 && structdef
== snone
2696 && structtype
== st_C_enum
&& cblev
> structcblev
)
2697 return TRUE
; /* enum constant */
2703 fvdef
= fdefunname
; /* GNU macro */
2704 *is_func_or_var
= TRUE
;
2707 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
2708 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
2713 if ((*c_extp
& C_PLPL
) && strneq (str
+len
-10, "::operator", 10))
2716 *is_func_or_var
= TRUE
;
2719 if (cblev
> 0 && !instruct
)
2721 fvdef
= fvnameseen
; /* function or variable */
2722 *is_func_or_var
= TRUE
;
2733 * C_entries often keeps pointers to tokens or lines which are older than
2734 * the line currently read. By keeping two line buffers, and switching
2735 * them at end of line, it is possible to use those pointers.
2743 #define current_lb_is_new (newndx == curndx)
2744 #define switch_line_buffers() (curndx = 1 - curndx)
2746 #define curlb (lbs[curndx].lb)
2747 #define newlb (lbs[newndx].lb)
2748 #define curlinepos (lbs[curndx].linepos)
2749 #define newlinepos (lbs[newndx].linepos)
2751 #define CNL_SAVE_DEFINEDEF() \
2753 curlinepos = charno; \
2755 linecharno = charno; \
2756 charno += readline (&curlb, inf); \
2757 lp = curlb.buffer; \
2764 CNL_SAVE_DEFINEDEF(); \
2765 if (savetoken.valid) \
2767 token = savetoken; \
2768 savetoken.valid = FALSE; \
2770 definedef = dnone; \
2778 /* This function should never be called when token.valid is FALSE, but
2779 we must protect against invalid input or internal errors. */
2780 if (DEBUG
|| token
.valid
)
2782 if (traditional_tag_style
)
2784 /* This was the original code. Now we call new_pfnote instead,
2785 which uses the new method for naming tags (see new_pfnote). */
2788 if (CTAGS
|| token
.named
)
2789 name
= savestr (token_name
.buffer
);
2790 if (DEBUG
&& !token
.valid
)
2793 name
= concat (name
, "##invalid##", "");
2795 name
= savestr ("##invalid##");
2797 pfnote (name
, isfun
, token
.line
,
2798 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2801 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
2802 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2803 token
.valid
= FALSE
;
2810 * This routine finds functions, variables, typedefs,
2811 * #define's, enum constants and struct/union/enum definitions in
2812 * C syntax and adds them to the list.
2815 C_entries (c_ext
, inf
)
2816 int c_ext
; /* extension of C */
2817 FILE *inf
; /* input file */
2819 register char c
; /* latest char read; '\0' for end of line */
2820 register char *lp
; /* pointer one beyond the character `c' */
2821 int curndx
, newndx
; /* indices for current and new lb */
2822 register int tokoff
; /* offset in line of start of current token */
2823 register int toklen
; /* length of current token */
2824 char *qualifier
; /* string used to qualify names */
2825 int qlen
; /* length of qualifier */
2826 int cblev
; /* current curly brace level */
2827 int parlev
; /* current parenthesis level */
2828 int typdefcblev
; /* cblev where a typedef struct body begun */
2829 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2831 bool yacc_rules
; /* in the rules part of a yacc file */
2832 struct tok savetoken
; /* token saved during preprocessor handling */
2835 initbuffer (&token_name
);
2836 initbuffer (&lbs
[0].lb
);
2837 initbuffer (&lbs
[1].lb
);
2838 if (cstack
.size
== 0)
2840 cstack
.size
= (DEBUG
) ? 1 : 4;
2842 cstack
.cname
= xnew (cstack
.size
, char *);
2843 cstack
.cblev
= xnew (cstack
.size
, int);
2846 tokoff
= toklen
= typdefcblev
= 0; /* keep compiler quiet */
2847 curndx
= newndx
= 0;
2853 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
2854 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
2856 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2857 token
.valid
= savetoken
.valid
= FALSE
;
2860 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2861 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2863 { qualifier
= "."; qlen
= 1; }
2865 { qualifier
= "::"; qlen
= 2; }
2873 /* If we're at the end of the line, the next character is a
2874 '\0'; don't skip it, because it's the thing that tells us
2875 to read the next line. */
2896 /* Newlines inside comments do not end macro definitions in
2898 CNL_SAVE_DEFINEDEF ();
2911 /* Newlines inside strings do not end macro definitions
2912 in traditional cpp, even though compilers don't
2913 usually accept them. */
2914 CNL_SAVE_DEFINEDEF ();
2924 /* Hmmm, something went wrong. */
2953 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2966 else if (/* cplpl && */ *lp
== '/')
2974 if ((c_ext
& YACC
) && *lp
== '%')
2976 /* Entering or exiting rules section in yacc file. */
2978 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
2979 typdef
= tnone
; structdef
= snone
;
2980 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2982 yacc_rules
= !yacc_rules
;
2988 if (definedef
== dnone
)
2991 bool cpptoken
= TRUE
;
2993 /* Look back on this line. If all blanks, or nonblanks
2994 followed by an end of comment, this is a preprocessor
2996 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2999 if (*cp
== '*' && *(cp
+1) == '/')
3008 definedef
= dsharpseen
;
3009 } /* if (definedef == dnone) */
3015 /* Consider token only if some involved conditions are satisfied. */
3016 if (typdef
!= tignore
3017 && definedef
!= dignorerest
3019 && structdef
!= sintemplate
3020 && (definedef
!= dnone
3021 || structdef
!= scolonseen
))
3027 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken (lp
[1]))
3030 * This handles :: in the middle, but not at the
3031 * beginning of an identifier. Also, space-separated
3032 * :: is not recognised.
3037 goto still_in_token
;
3041 bool funorvar
= FALSE
;
3044 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
3045 &c_ext
, cblev
, parlev
, &funorvar
))
3047 if (fvdef
== foperator
)
3050 lp
= skip_spaces (lp
-1);
3054 && !iswhite (*lp
) && *lp
!= '(')
3057 toklen
+= lp
- oldlp
;
3059 token
.named
= FALSE
;
3060 if ((c_ext
& C_EXT
) /* not pure C */
3061 && nestlev
> 0 && definedef
== dnone
)
3062 /* in struct body */
3064 write_classname (&token_name
, qualifier
);
3065 linebuffer_setlen (&token_name
,
3066 token_name
.len
+qlen
+toklen
);
3067 strcat (token_name
.buffer
, qualifier
);
3068 strncat (token_name
.buffer
,
3069 newlb
.buffer
+ tokoff
, toklen
);
3072 else if (objdef
== ocatseen
)
3073 /* Objective C category */
3075 int len
= strlen (objtag
) + 2 + toklen
;
3076 linebuffer_setlen (&token_name
, len
);
3077 strcpy (token_name
.buffer
, objtag
);
3078 strcat (token_name
.buffer
, "(");
3079 strncat (token_name
.buffer
,
3080 newlb
.buffer
+ tokoff
, toklen
);
3081 strcat (token_name
.buffer
, ")");
3084 else if (objdef
== omethodtag
3085 || objdef
== omethodparm
)
3086 /* Objective C method */
3090 else if (fvdef
== fdefunname
)
3091 /* GNU DEFUN and similar macros */
3093 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3097 /* Rewrite the tag so that emacs lisp DEFUNs
3098 can be found by their elisp name */
3105 linebuffer_setlen (&token_name
, len
);
3106 strncpy (token_name
.buffer
,
3107 newlb
.buffer
+ off
, len
);
3108 token_name
.buffer
[len
] = '\0';
3111 if (token_name
.buffer
[len
] == '_')
3112 token_name
.buffer
[len
] = '-';
3113 token
.named
= defun
;
3117 linebuffer_setlen (&token_name
, toklen
);
3118 strncpy (token_name
.buffer
,
3119 newlb
.buffer
+ tokoff
, toklen
);
3120 token_name
.buffer
[toklen
] = '\0';
3121 /* Name macros and members. */
3122 token
.named
= (structdef
== stagseen
3123 || typdef
== ttypeseen
3126 && definedef
== dignorerest
)
3128 && definedef
== dnone
3129 && structdef
== snone
3132 token
.lineno
= lineno
;
3133 token
.offset
= tokoff
;
3134 token
.length
= toklen
;
3135 token
.line
= newlb
.buffer
;
3136 token
.linepos
= newlinepos
;
3139 if (definedef
== dnone
3140 && (fvdef
== fvnameseen
3141 || fvdef
== foperator
3142 || structdef
== stagseen
3144 || typdef
== ttypeseen
3145 || objdef
!= onone
))
3147 if (current_lb_is_new
)
3148 switch_line_buffers ();
3150 else if (definedef
!= dnone
3151 || fvdef
== fdefunname
3153 make_C_tag (funorvar
);
3157 } /* if (endtoken (c)) */
3158 else if (intoken (c
))
3164 } /* if (midtoken) */
3165 else if (begtoken (c
))
3176 make_C_tag (TRUE
); /* a function */
3183 if (structdef
== stagseen
&& !cjava
)
3185 popclass_above (cblev
);
3192 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3194 tokoff
= lp
- 1 - newlb
.buffer
;
3199 } /* if (begtoken) */
3200 } /* if must look at token */
3203 /* Detect end of line, colon, comma, semicolon and various braces
3204 after having handled a token.*/
3208 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3210 make_C_tag (FALSE
); /* a yacc function */
3213 if (definedef
!= dnone
)
3219 make_C_tag (TRUE
); /* an Objective C class */
3223 objdef
= omethodcolon
;
3224 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3225 strcat (token_name
.buffer
, ":");
3228 if (structdef
== stagseen
)
3229 structdef
= scolonseen
;
3232 if (definedef
!= dnone
)
3238 make_C_tag (FALSE
); /* a typedef */
3248 if (typdef
== tignore
)
3252 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3253 || (members
&& instruct
))
3254 make_C_tag (FALSE
); /* a variable */
3257 token
.valid
= FALSE
;
3260 if ((declarations
&& typdef
== tnone
&& !instruct
)
3261 || (members
&& typdef
!= tignore
&& instruct
))
3262 make_C_tag (TRUE
); /* a function declaration */
3268 && structdef
== stagseen
&& (c_ext
& C_PLPL
))
3269 make_C_tag (FALSE
); /* forward declaration */
3271 /* The following instruction invalidates the token.
3272 Probably the token should be invalidated in all other
3273 cases where some state machine is reset prematurely. */
3274 token
.valid
= FALSE
;
3275 } /* switch (fvdef) */
3281 if (structdef
== stagseen
)
3285 if (definedef
!= dnone
)
3291 make_C_tag (TRUE
); /* an Objective C method */
3307 case fvnameseen
: /* a variable */
3308 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3309 || (members
&& instruct
))
3312 case flistseen
: /* a function */
3313 if ((declarations
&& typdef
== tnone
&& !instruct
)
3314 || (members
&& typdef
!= tignore
&& instruct
))
3316 make_C_tag (TRUE
); /* a function declaration */
3319 else if (!declarations
)
3321 token
.valid
= FALSE
;
3326 if (structdef
== stagseen
)
3330 if (definedef
!= dnone
)
3332 if (structdef
== stagseen
)
3339 make_C_tag (FALSE
); /* a typedef */
3351 if ((members
&& cblev
== 1)
3352 || (globals
&& cblev
== 0
3353 && (!fvextern
|| declarations
)))
3354 make_C_tag (FALSE
); /* a variable */
3363 if (definedef
!= dnone
)
3365 if (objdef
== otagseen
&& parlev
== 0)
3366 objdef
= oparenseen
;
3370 if (typdef
== ttypeseen
3374 /* This handles constructs like:
3375 typedef void OperatorFun (int fun); */
3392 if (definedef
!= dnone
)
3394 if (objdef
== ocatseen
&& parlev
== 1)
3396 make_C_tag (TRUE
); /* an Objective C category */
3410 || typdef
== ttypeseen
))
3413 make_C_tag (FALSE
); /* a typedef */
3416 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3420 if (definedef
!= dnone
)
3422 if (typdef
== ttypeseen
)
3424 /* Whenever typdef is set to tinbody (currently only
3425 here), typdefcblev should be set to cblev. */
3427 typdefcblev
= cblev
;
3432 make_C_tag (TRUE
); /* a function */
3441 make_C_tag (TRUE
); /* an Objective C class */
3446 make_C_tag (TRUE
); /* an Objective C method */
3450 /* Neutralize `extern "C" {' grot. */
3451 if (cblev
== 0 && structdef
== snone
&& nestlev
== 0
3458 case skeyseen
: /* unnamed struct */
3459 pushclass_above (cblev
, NULL
, 0);
3462 case stagseen
: /* named struct or enum */
3463 case scolonseen
: /* a class */
3464 pushclass_above (cblev
, token
.line
+token
.offset
, token
.length
);
3466 make_C_tag (FALSE
); /* a struct or enum */
3472 if (definedef
!= dnone
)
3474 if (fvdef
== fstartlist
)
3475 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3478 if (definedef
!= dnone
)
3480 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
3482 cblev
= 0; /* reset curly brace level if first column */
3483 parlev
= 0; /* also reset paren level, just in case... */
3487 popclass_above (cblev
);
3489 /* Only if typdef == tinbody is typdefcblev significant. */
3490 if (typdef
== tinbody
&& cblev
<= typdefcblev
)
3492 assert (cblev
== typdefcblev
);
3497 if (definedef
!= dnone
)
3507 if ((members
&& cblev
== 1)
3508 || (globals
&& cblev
== 0 && (!fvextern
|| declarations
)))
3509 make_C_tag (FALSE
); /* a variable */
3516 if (cplpl
&& structdef
== stagseen
)
3518 structdef
= sintemplate
;
3523 if (structdef
== sintemplate
)
3525 structdef
= stagseen
;
3531 if (objdef
== oinbody
&& cblev
== 0)
3533 objdef
= omethodsign
;
3538 case '#': case '~': case '&': case '%': case '/': case '|':
3539 case '^': case '!': case '.': case '?': case ']':
3540 if (definedef
!= dnone
)
3542 /* These surely cannot follow a function tag in C. */
3555 if (objdef
== otagseen
)
3557 make_C_tag (TRUE
); /* an Objective C class */
3560 /* If a macro spans multiple lines don't reset its state. */
3562 CNL_SAVE_DEFINEDEF ();
3568 } /* while not eof */
3570 free (token_name
.buffer
);
3571 free (lbs
[0].lb
.buffer
);
3572 free (lbs
[1].lb
.buffer
);
3576 * Process either a C++ file or a C file depending on the setting
3580 default_C_entries (inf
)
3583 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
3586 /* Always do plain C. */
3588 plain_C_entries (inf
)
3594 /* Always do C++. */
3596 Cplusplus_entries (inf
)
3599 C_entries (C_PLPL
, inf
);
3602 /* Always do Java. */
3607 C_entries (C_JAVA
, inf
);
3615 C_entries (C_STAR
, inf
);
3618 /* Always do Yacc. */
3623 C_entries (YACC
, inf
);
3627 /* Useful macros. */
3628 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3629 for (lineno = charno = 0; /* loop initialization */ \
3630 !feof (file_pointer) /* loop test */ \
3631 && (lineno++, /* instructions at start of loop */ \
3632 linecharno = charno, \
3633 charno += readline (&line_buffer, file_pointer), \
3634 char_pointer = lb.buffer, \
3637 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
3638 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \
3639 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \
3640 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */
3643 * Read a file, but do no processing. This is used to do regexp
3644 * matching on files that have no language defined.
3647 just_read_file (inf
)
3650 register char *dummy
;
3652 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
3657 /* Fortran parsing */
3659 static void F_takeprec
__P((void));
3660 static void F_getit
__P((FILE *));
3665 dbp
= skip_spaces (dbp
);
3669 dbp
= skip_spaces (dbp
);
3670 if (strneq (dbp
, "(*)", 3))
3675 if (!ISDIGIT (*dbp
))
3677 --dbp
; /* force failure */
3682 while (ISDIGIT (*dbp
));
3691 dbp
= skip_spaces (dbp
);
3695 linecharno
= charno
;
3696 charno
+= readline (&lb
, inf
);
3701 dbp
= skip_spaces (dbp
);
3703 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
3705 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
3707 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3708 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3713 Fortran_functions (inf
)
3716 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3719 dbp
++; /* Ratfor escape to fortran */
3720 dbp
= skip_spaces (dbp
);
3723 switch (lowcase (*dbp
))
3726 if (nocase_tail ("integer"))
3730 if (nocase_tail ("real"))
3734 if (nocase_tail ("logical"))
3738 if (nocase_tail ("complex") || nocase_tail ("character"))
3742 if (nocase_tail ("double"))
3744 dbp
= skip_spaces (dbp
);
3747 if (nocase_tail ("precision"))
3753 dbp
= skip_spaces (dbp
);
3756 switch (lowcase (*dbp
))
3759 if (nocase_tail ("function"))
3763 if (nocase_tail ("subroutine"))
3767 if (nocase_tail ("entry"))
3771 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
3773 dbp
= skip_spaces (dbp
);
3774 if (*dbp
== '\0') /* assume un-named */
3775 pfnote (savestr ("blockdata"), TRUE
,
3776 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
3778 F_getit (inf
); /* look for name */
3789 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3792 static void Ada_getit
__P((FILE *, char *));
3794 /* Once we are positioned after an "interesting" keyword, let's get
3795 the real tag value necessary. */
3797 Ada_getit (inf
, name_qualifier
)
3799 char *name_qualifier
;
3807 dbp
= skip_spaces (dbp
);
3809 || (dbp
[0] == '-' && dbp
[1] == '-'))
3812 linecharno
= charno
;
3813 charno
+= readline (&lb
, inf
);
3816 switch (lowcase(*dbp
))
3819 if (nocase_tail ("body"))
3821 /* Skipping body of procedure body or package body or ....
3822 resetting qualifier to body instead of spec. */
3823 name_qualifier
= "/b";
3828 /* Skipping type of task type or protected type ... */
3829 if (nocase_tail ("type"))
3836 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
3841 dbp
= skip_spaces (dbp
);
3844 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
3852 name
= concat (dbp
, name_qualifier
, "");
3854 pfnote (name
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3865 bool inquote
= FALSE
;
3867 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3869 while (*dbp
!= '\0')
3871 /* Skip a string i.e. "abcd". */
3872 if (inquote
|| (*dbp
== '"'))
3874 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
3879 continue; /* advance char */
3884 break; /* advance line */
3888 /* Skip comments. */
3889 if (dbp
[0] == '-' && dbp
[1] == '-')
3890 break; /* advance line */
3892 /* Skip character enclosed in single quote i.e. 'a'
3893 and skip single quote starting an attribute i.e. 'Image. */
3902 /* Search for beginning of a token. */
3903 if (!begtoken (*dbp
))
3906 continue; /* advance char */
3909 /* We are at the beginning of a token. */
3910 switch (lowcase(*dbp
))
3913 if (!packages_only
&& nocase_tail ("function"))
3914 Ada_getit (inf
, "/f");
3916 break; /* from switch */
3917 continue; /* advance char */
3919 if (!packages_only
&& nocase_tail ("procedure"))
3920 Ada_getit (inf
, "/p");
3921 else if (nocase_tail ("package"))
3922 Ada_getit (inf
, "/s");
3923 else if (nocase_tail ("protected")) /* protected type */
3924 Ada_getit (inf
, "/t");
3926 break; /* from switch */
3927 continue; /* advance char */
3929 if (!packages_only
&& nocase_tail ("task"))
3930 Ada_getit (inf
, "/k");
3931 else if (typedefs
&& !packages_only
&& nocase_tail ("type"))
3933 Ada_getit (inf
, "/t");
3934 while (*dbp
!= '\0')
3938 break; /* from switch */
3939 continue; /* advance char */
3942 /* Look for the end of the token. */
3943 while (!endtoken (*dbp
))
3946 } /* advance char */
3947 } /* advance line */
3952 * Unix and microcontroller assembly tag handling
3953 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
3954 * Idea by Bob Weiner, Motorola Inc. (1994)
3962 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
3964 /* If first char is alphabetic or one of [_.$], test for colon
3965 following identifier. */
3966 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3968 /* Read past label. */
3970 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3972 if (*cp
== ':' || iswhite (*cp
))
3974 /* Found end of label, so copy it and add it to the table. */
3975 pfnote (savenstr(lb
.buffer
, cp
-lb
.buffer
), TRUE
,
3976 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3985 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
3986 * Perl variable names: /^(my|local).../
3987 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
3988 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
3989 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
3992 Perl_functions (inf
)
3995 char *package
= savestr ("main"); /* current package name */
3998 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4002 if (LOOKING_AT (cp
, "package"))
4005 package
= get_tag (cp
);
4006 if (package
== NULL
) /* can't parse package name */
4007 package
= savestr ("");
4009 package
= savestr(package
); /* make a copy */
4011 else if (LOOKING_AT (cp
, "sub"))
4013 char *name
, *fullname
, *pos
;
4016 while (!notinname (*cp
))
4020 name
= savenstr (sp
, cp
-sp
);
4021 if ((pos
= etags_strchr (name
, ':')) != NULL
&& pos
[1] == ':')
4024 fullname
= concat (package
, "::", name
);
4025 pfnote (fullname
, TRUE
,
4026 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4027 if (name
!= fullname
)
4030 else if (globals
/* only if tagging global vars is enabled */
4031 && (LOOKING_AT (cp
, "my") || LOOKING_AT (cp
, "local")))
4033 /* After "my" or "local", but before any following paren or space. */
4034 char *varname
= NULL
;
4036 if (*cp
== '$' || *cp
== '@' || *cp
== '%')
4038 char* varstart
= ++cp
;
4039 while (ISALNUM (*cp
) || *cp
== '_')
4041 varname
= savenstr (varstart
, cp
-varstart
);
4045 /* Should be examining a variable list at this point;
4046 could insist on seeing an open parenthesis. */
4047 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4051 /* Perhaps I should back cp up one character, so the TAGS table
4052 doesn't mention (and so depend upon) the following char. */
4053 pfnote (varname
, FALSE
,
4054 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4062 * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4063 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4064 * More ideas by seb bacon <seb@jamkit.com> (2002)
4067 Python_functions (inf
)
4072 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4074 cp
= skip_spaces (cp
);
4075 if (LOOKING_AT (cp
, "def") || LOOKING_AT (cp
, "class"))
4078 while (!notinname (*cp
) && *cp
!= ':')
4080 pfnote (savenstr (name
, cp
-name
), TRUE
,
4081 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4090 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4091 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4092 * - /^[ \t]*define\(\"[^\"]+/
4093 * Only with --members:
4094 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4095 * Idea by Diez B. Roggisch (2001)
4101 register char *cp
, *name
;
4102 bool search_identifier
= FALSE
;
4104 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4106 cp
= skip_spaces (cp
);
4108 if (search_identifier
4111 while (!notinname (*cp
))
4113 pfnote (savenstr (name
, cp
-name
), TRUE
,
4114 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4115 search_identifier
= FALSE
;
4117 else if (LOOKING_AT (cp
, "function"))
4120 cp
= skip_spaces (cp
+1);
4124 while (!notinname (*cp
))
4126 pfnote (savenstr (name
, cp
-name
), TRUE
,
4127 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4130 search_identifier
= TRUE
;
4132 else if (LOOKING_AT (cp
, "class"))
4137 while (*cp
!= '\0' && !iswhite (*cp
))
4139 pfnote (savenstr (name
, cp
-name
), FALSE
,
4140 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4143 search_identifier
= TRUE
;
4145 else if (strneq (cp
, "define", 6)
4146 && (cp
= skip_spaces (cp
+6))
4148 && (*cp
== '"' || *cp
== '\''))
4152 while (*cp
!= quote
&& *cp
!= '\0')
4154 pfnote (savenstr (name
, cp
-name
), FALSE
,
4155 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4158 && LOOKING_AT (cp
, "var")
4162 while (!notinname(*cp
))
4164 pfnote (savenstr (name
, cp
-name
), FALSE
,
4165 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4172 * Cobol tag functions
4173 * We could look for anything that could be a paragraph name.
4174 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4175 * Idea by Corny de Souza (1993)
4178 Cobol_paragraphs (inf
)
4181 register char *bp
, *ep
;
4183 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4189 /* If eoln, compiler option or comment ignore whole line. */
4190 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4193 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4196 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4197 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4204 * Idea by Assar Westerlund <assar@sics.se> (2001)
4207 Makefile_targets (inf
)
4212 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4214 if (*bp
== '\t' || *bp
== '#')
4216 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4219 pfnote (savenstr (lb
.buffer
, bp
- lb
.buffer
), TRUE
,
4220 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4227 * Original code by Mosur K. Mohan (1989)
4229 * Locates tags for procedures & functions. Doesn't do any type- or
4230 * var-definitions. It does look for the keyword "extern" or
4231 * "forward" immediately following the procedure statement; if found,
4232 * the tag is skipped.
4235 Pascal_functions (inf
)
4238 linebuffer tline
; /* mostly copied from C_entries */
4240 int save_lineno
, save_len
;
4241 char c
, *cp
, *namebuf
;
4243 bool /* each of these flags is TRUE iff: */
4244 incomment
, /* point is inside a comment */
4245 inquote
, /* point is inside '..' string */
4246 get_tagname
, /* point is after PROCEDURE/FUNCTION
4247 keyword, so next item = potential tag */
4248 found_tag
, /* point is after a potential tag */
4249 inparms
, /* point is within parameter-list */
4250 verify_tag
; /* point has passed the parm-list, so the
4251 next token will determine whether this
4252 is a FORWARD/EXTERN to be ignored, or
4253 whether it is a real tag */
4255 save_lcno
= save_lineno
= save_len
= 0; /* keep compiler quiet */
4256 namebuf
= NULL
; /* keep compiler quiet */
4261 initbuffer (&tline
);
4263 incomment
= inquote
= FALSE
;
4264 found_tag
= FALSE
; /* have a proc name; check if extern */
4265 get_tagname
= FALSE
; /* have found "procedure" keyword */
4266 inparms
= FALSE
; /* found '(' after "proc" */
4267 verify_tag
= FALSE
; /* check if "extern" is ahead */
4270 while (!feof (inf
)) /* long main loop to get next char */
4273 if (c
== '\0') /* if end of line */
4276 linecharno
= charno
;
4277 charno
+= readline (&lb
, inf
);
4281 if (!((found_tag
&& verify_tag
)
4283 c
= *dbp
++; /* only if don't need *dbp pointing
4284 to the beginning of the name of
4285 the procedure or function */
4289 if (c
== '}') /* within { } comments */
4291 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4308 inquote
= TRUE
; /* found first quote */
4310 case '{': /* found open { comment */
4314 if (*dbp
== '*') /* found open (* comment */
4319 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4322 case ')': /* end of parms list */
4327 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4334 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4336 /* check if this is an "extern" declaration */
4339 if (lowcase (*dbp
== 'e'))
4341 if (nocase_tail ("extern")) /* superfluous, really! */
4347 else if (lowcase (*dbp
) == 'f')
4349 if (nocase_tail ("forward")) /* check for forward reference */
4355 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4359 pfnote (namebuf
, TRUE
,
4360 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
4364 if (get_tagname
) /* grab name of proc or fn */
4369 /* save all values for later tagging */
4370 linebuffer_setlen (&tline
, lb
.len
);
4371 strcpy (tline
.buffer
, lb
.buffer
);
4372 save_lineno
= lineno
;
4373 save_lcno
= linecharno
;
4375 /* grab block name */
4376 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4378 namebuf
= savenstr (dbp
, cp
-dbp
);
4379 dbp
= cp
; /* set dbp to e-o-token */
4380 save_len
= dbp
- lb
.buffer
+ 1;
4381 get_tagname
= FALSE
;
4385 /* and proceed to check for "extern" */
4387 else if (!incomment
&& !inquote
&& !found_tag
)
4389 /* check for proc/fn keywords */
4390 switch (lowcase (c
))
4393 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4397 if (nocase_tail ("unction"))
4402 } /* while not eof */
4404 free (tline
.buffer
);
4409 * Lisp tag functions
4410 * look for (def or (DEF, quote or QUOTE
4413 static void L_getit
__P((void));
4418 if (*dbp
== '\'') /* Skip prefix quote */
4420 else if (*dbp
== '(')
4423 /* Try to skip "(quote " */
4424 if (!LOOKING_AT (dbp
, "quote") && !LOOKING_AT (dbp
, "QUOTE"))
4425 /* Ok, then skip "(" before name in (defstruct (foo)) */
4426 dbp
= skip_spaces (dbp
);
4432 Lisp_functions (inf
)
4435 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4440 if (strneq (dbp
+1, "def", 3) || strneq (dbp
+1, "DEF", 3))
4442 dbp
= skip_non_spaces (dbp
);
4443 dbp
= skip_spaces (dbp
);
4448 /* Check for (foo::defmumble name-defined ... */
4451 while (!notinname (*dbp
) && *dbp
!= ':');
4456 while (*dbp
== ':');
4458 if (strneq (dbp
, "def", 3) || strneq (dbp
, "DEF", 3))
4460 dbp
= skip_non_spaces (dbp
);
4461 dbp
= skip_spaces (dbp
);
4471 * Postscript tag functions
4472 * Just look for lines where the first character is '/'
4473 * Also look at "defineps" for PSWrap
4475 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4476 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4479 Postscript_functions (inf
)
4482 register char *bp
, *ep
;
4484 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4489 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4492 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4493 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4495 else if (LOOKING_AT (bp
, "defineps"))
4502 * Scheme tag functions
4503 * look for (def... xyzzy
4505 * (def ... ((...(xyzzy ....
4507 * Original code by Ken Haase (1985?)
4511 Scheme_functions (inf
)
4516 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4518 if (strneq (bp
, "(def", 4) || strneq (bp
, "(DEF", 4))
4520 bp
= skip_non_spaces (bp
+4);
4521 /* Skip over open parens and white space */
4522 while (notinname (*bp
))
4526 if (LOOKING_AT (bp
, "(SET!") || LOOKING_AT (bp
, "(set!"))
4532 /* Find tags in TeX and LaTeX input files. */
4534 /* TEX_toktab is a table of TeX control sequences that define tags.
4535 Each TEX_tabent records one such control sequence.
4536 CONVERT THIS TO USE THE Stab TYPE!! */
4543 static struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
4545 /* Default set of control sequences to put into TEX_toktab.
4546 The value of environment var TEXTAGS is prepended to this. */
4548 static char *TEX_defenv
= "\
4549 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4550 :part:appendix:entry:index";
4552 static void TEX_mode
__P((FILE *));
4553 static struct TEX_tabent
*TEX_decode_env
__P((char *, char *));
4554 static int TEX_Token
__P((char *));
4556 static char TEX_esc
= '\\';
4557 static char TEX_opgrp
= '{';
4558 static char TEX_clgrp
= '}';
4561 * TeX/LaTeX scanning loop.
4570 /* Select either \ or ! as escape character. */
4573 /* Initialize token table once from environment. */
4575 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
4577 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4580 /* Look at each esc in line. */
4581 while ((cp
= etags_strchr (cp
, TEX_esc
)) != NULL
)
4585 linecharno
+= cp
- lasthit
;
4587 i
= TEX_Token (lasthit
);
4591 for (lasthit
+= TEX_toktab
[i
].len
;
4592 *lasthit
== TEX_esc
|| *lasthit
== TEX_opgrp
;
4596 !iswhite (*p
) && *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
;
4599 pfnote (savenstr (lasthit
, p
-lasthit
), TRUE
,
4600 lb
.buffer
, lb
.len
, lineno
, linecharno
);
4601 break; /* We only tag a line once */
4607 #define TEX_LESC '\\'
4608 #define TEX_SESC '!'
4611 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4612 chars accordingly. */
4619 while ((c
= getc (inf
)) != EOF
)
4621 /* Skip to next line if we hit the TeX comment char. */
4625 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
4641 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4642 No attempt is made to correct the situation. */
4646 /* Read environment and prepend it to the default string.
4647 Build token table. */
4648 static struct TEX_tabent
*
4649 TEX_decode_env (evarname
, defenv
)
4653 register char *env
, *p
;
4655 struct TEX_tabent
*tab
;
4658 /* Append default string to environment. */
4659 env
= getenv (evarname
);
4665 env
= concat (oldenv
, defenv
, "");
4668 /* Allocate a token table */
4669 for (size
= 1, p
= env
; p
;)
4670 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
4672 /* Add 1 to leave room for null terminator. */
4673 tab
= xnew (size
+ 1, struct TEX_tabent
);
4675 /* Unpack environment string into token table. Be careful about */
4676 /* zero-length strings (leading ':', "::" and trailing ':') */
4679 p
= etags_strchr (env
, ':');
4680 if (!p
) /* End of environment string. */
4681 p
= env
+ strlen (env
);
4683 { /* Only non-zero strings. */
4684 tab
[i
].name
= savenstr (env
, p
- env
);
4685 tab
[i
].len
= strlen (tab
[i
].name
);
4692 tab
[i
].name
= NULL
; /* Mark end of table. */
4700 /* If the text at CP matches one of the tag-defining TeX command names,
4701 return the pointer to the first occurrence of that command in TEX_toktab.
4702 Otherwise return -1.
4703 Keep the capital `T' in `token' for dumb truncating compilers
4704 (this distinguishes it from `TEX_toktab' */
4711 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
4712 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
4718 /* Texinfo support. Dave Love, Mar. 2000. */
4724 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4725 if (LOOKING_AT (cp
, "@node"))
4728 while (*cp
!= '\0' && *cp
!= ',')
4730 pfnote (savenstr (start
, cp
- start
), TRUE
,
4731 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4739 * Assumes that the predicate or rule starts at column 0.
4740 * Only the first clause of a predicate or rule is added.
4741 * Original code by Sunichirou Sugou (1989)
4742 * Rewritten by Anders Lindgren (1996)
4744 static int prolog_pr
__P((char *, char *));
4745 static void prolog_skip_comment
__P((linebuffer
*, FILE *));
4746 static int prolog_atom
__P((char *, int));
4749 Prolog_functions (inf
)
4760 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4762 if (cp
[0] == '\0') /* Empty line */
4764 else if (iswhite (cp
[0])) /* Not a predicate */
4766 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
4767 prolog_skip_comment (&lb
, inf
);
4768 else if ((len
= prolog_pr (cp
, last
)) > 0)
4770 /* Predicate or rule. Store the function name so that we
4771 only generate a tag for the first clause. */
4773 last
= xnew(len
+ 1, char);
4774 else if (len
+ 1 > allocated
)
4775 xrnew (last
, len
+ 1, char);
4776 allocated
= len
+ 1;
4777 strncpy (last
, cp
, len
);
4785 prolog_skip_comment (plb
, inf
)
4793 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
4794 if (cp
[0] == '*' && cp
[1] == '/')
4797 linecharno
+= readline (plb
, inf
);
4803 * A predicate or rule definition is added if it matches:
4804 * <beginning of line><Prolog Atom><whitespace>(
4805 * or <beginning of line><Prolog Atom><whitespace>:-
4807 * It is added to the tags database if it doesn't match the
4808 * name of the previous clause header.
4810 * Return the size of the name of the predicate or rule, or 0 if no
4816 char *last
; /* Name of last clause. */
4821 pos
= prolog_atom (s
, 0);
4826 pos
= skip_spaces (s
+ pos
) - s
;
4829 || (s
[pos
] == '(' && (pos
+= 1))
4830 || (s
[pos
] == ':' && s
[pos
+ 1] == '-' && (pos
+= 2)))
4831 && (last
== NULL
/* save only the first clause */
4832 || len
!= strlen (last
)
4833 || !strneq (s
, last
, len
)))
4835 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4843 * Consume a Prolog atom.
4844 * Return the number of bytes consumed, or -1 if there was an error.
4846 * A prolog atom, in this context, could be one of:
4847 * - An alphanumeric sequence, starting with a lower case letter.
4848 * - A quoted arbitrary string. Single quotes can escape themselves.
4849 * Backslash quotes everything.
4852 prolog_atom (s
, pos
)
4860 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
4862 /* The atom is unquoted. */
4864 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
4868 return pos
- origpos
;
4870 else if (s
[pos
] == '\'')
4881 pos
++; /* A double quote */
4883 else if (s
[pos
] == '\0')
4884 /* Multiline quoted atoms are ignored. */
4886 else if (s
[pos
] == '\\')
4888 if (s
[pos
+1] == '\0')
4895 return pos
- origpos
;
4903 * Support for Erlang
4905 * Generates tags for functions, defines, and records.
4906 * Assumes that Erlang functions start at column 0.
4907 * Original code by Anders Lindgren (1996)
4909 static int erlang_func
__P((char *, char *));
4910 static void erlang_attribute
__P((char *));
4911 static int erlang_atom
__P((char *, int));
4914 Erlang_functions (inf
)
4925 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4927 if (cp
[0] == '\0') /* Empty line */
4929 else if (iswhite (cp
[0])) /* Not function nor attribute */
4931 else if (cp
[0] == '%') /* comment */
4933 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
4935 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
4937 erlang_attribute (cp
);
4940 else if ((len
= erlang_func (cp
, last
)) > 0)
4943 * Function. Store the function name so that we only
4944 * generates a tag for the first clause.
4947 last
= xnew (len
+ 1, char);
4948 else if (len
+ 1 > allocated
)
4949 xrnew (last
, len
+ 1, char);
4950 allocated
= len
+ 1;
4951 strncpy (last
, cp
, len
);
4959 * A function definition is added if it matches:
4960 * <beginning of line><Erlang Atom><whitespace>(
4962 * It is added to the tags database if it doesn't match the
4963 * name of the previous clause header.
4965 * Return the size of the name of the function, or 0 if no function
4969 erlang_func (s
, last
)
4971 char *last
; /* Name of last clause. */
4976 pos
= erlang_atom (s
, 0);
4981 pos
= skip_spaces (s
+ pos
) - s
;
4983 /* Save only the first clause. */
4986 || len
!= (int)strlen (last
)
4987 || !strneq (s
, last
, len
)))
4989 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4998 * Handle attributes. Currently, tags are generated for defines
5001 * They are on the form:
5002 * -define(foo, bar).
5003 * -define(Foo(M, N), M+N).
5004 * -record(graph, {vtab = notable, cyclic = true}).
5007 erlang_attribute (s
)
5013 if (LOOKING_AT (s
, "-define") || LOOKING_AT (s
, "-record"))
5015 if (s
[pos
++] == '(')
5017 pos
= skip_spaces (s
+ pos
) - s
;
5018 len
= erlang_atom (s
, pos
);
5020 pfnote (savenstr (& s
[pos
], len
), TRUE
,
5021 s
, pos
+ len
, lineno
, linecharno
);
5029 * Consume an Erlang atom (or variable).
5030 * Return the number of bytes consumed, or -1 if there was an error.
5033 erlang_atom (s
, pos
)
5041 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
5043 /* The atom is unquoted. */
5045 while (ISALNUM (s
[pos
]) || s
[pos
] == '_')
5047 return pos
- origpos
;
5049 else if (s
[pos
] == '\'')
5060 else if (s
[pos
] == '\0')
5061 /* Multiline quoted atoms are ignored. */
5063 else if (s
[pos
] == '\\')
5065 if (s
[pos
+1] == '\0')
5072 return pos
- origpos
;
5079 #ifdef ETAGS_REGEXPS
5081 static char *scan_separators
__P((char *));
5082 static void analyse_regex
__P((char *, bool));
5083 static void add_regex
__P((char *, bool, language
*));
5084 static char *substitute
__P((char *, char *, struct re_registers
*));
5086 /* Take a string like "/blah/" and turn it into "blah", making sure
5087 that the first and last characters are the same, and handling
5088 quoted separator characters. Actually, stops on the occurrence of
5089 an unquoted separator. Also turns "\t" into a Tab character.
5090 Returns pointer to terminating separator. Works in place. Null
5091 terminates name string. */
5093 scan_separators (name
)
5097 char *copyto
= name
;
5098 bool quoted
= FALSE
;
5100 for (++name
; *name
!= '\0'; ++name
)
5106 else if (*name
== sep
)
5110 /* Something else is quoted, so preserve the quote. */
5116 else if (*name
== '\\')
5118 else if (*name
== sep
)
5124 /* Terminate copied string. */
5129 /* Look at the argument of --regex or --no-regex and do the right
5130 thing. Same for each line of a regexp file. */
5132 analyse_regex (regex_arg
, ignore_case
)
5136 if (regex_arg
== NULL
)
5138 free_patterns (); /* --no-regex: remove existing regexps */
5142 /* A real --regexp option or a line in a regexp file. */
5143 switch (regex_arg
[0])
5145 /* Comments in regexp file or null arg to --regex. */
5151 /* Read a regex file. This is recursive and may result in a
5152 loop, which will stop when the file descriptors are exhausted. */
5156 linebuffer regexbuf
;
5157 char *regexfile
= regex_arg
+ 1;
5159 /* regexfile is a file containing regexps, one per line. */
5160 regexfp
= fopen (regexfile
, "r");
5161 if (regexfp
== NULL
)
5166 initbuffer (®exbuf
);
5167 while (readline_internal (®exbuf
, regexfp
) > 0)
5168 analyse_regex (regexbuf
.buffer
, ignore_case
);
5169 free (regexbuf
.buffer
);
5174 /* Regexp to be used for a specific language only. */
5178 char *lang_name
= regex_arg
+ 1;
5181 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5184 error ("unterminated language name in regex: %s", regex_arg
);
5188 lang
= get_language_from_langname (lang_name
);
5191 add_regex (cp
+ 1, ignore_case
, lang
);
5195 /* Regexp to be used for any language. */
5197 add_regex (regex_arg
, ignore_case
, NULL
);
5202 /* Turn a name, which is an ed-style (but Emacs syntax) regular
5203 expression, into a real regular expression by compiling it. */
5205 add_regex (regexp_pattern
, ignore_case
, lang
)
5206 char *regexp_pattern
;
5210 static struct re_pattern_buffer zeropattern
;
5213 struct re_pattern_buffer
*patbuf
;
5217 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
5219 error ("%s: unterminated regexp", regexp_pattern
);
5222 name
= scan_separators (regexp_pattern
);
5223 if (regexp_pattern
[0] == '\0')
5225 error ("null regexp", (char *)NULL
);
5228 (void) scan_separators (name
);
5230 patbuf
= xnew (1, struct re_pattern_buffer
);
5231 *patbuf
= zeropattern
;
5233 patbuf
->translate
= lc_trans
; /* translation table to fold case */
5235 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
5238 error ("%s while compiling pattern", err
);
5243 p_head
= xnew (1, pattern
);
5244 p_head
->regex
= savestr (regexp_pattern
);
5245 p_head
->p_next
= pp
;
5246 p_head
->lang
= lang
;
5247 p_head
->pat
= patbuf
;
5248 p_head
->name_pattern
= savestr (name
);
5249 p_head
->error_signaled
= FALSE
;
5253 * Do the substitutions indicated by the regular expression and
5257 substitute (in
, out
, regs
)
5259 struct re_registers
*regs
;
5262 int size
, dig
, diglen
;
5265 size
= strlen (out
);
5267 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5268 if (out
[size
- 1] == '\\')
5269 fatal ("pattern error in \"%s\"", out
);
5270 for (t
= etags_strchr (out
, '\\');
5272 t
= etags_strchr (t
+ 2, '\\'))
5276 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5282 /* Allocate space and do the substitutions. */
5283 result
= xnew (size
+ 1, char);
5285 for (t
= result
; *out
!= '\0'; out
++)
5286 if (*out
== '\\' && ISDIGIT (*++out
))
5289 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5290 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5297 assert (t
<= result
+ size
&& t
- result
== (int)strlen (result
));
5302 /* Deallocate all patterns. */
5307 while (p_head
!= NULL
)
5309 pp
= p_head
->p_next
;
5310 free (p_head
->regex
);
5311 free (p_head
->name_pattern
);
5317 #endif /* ETAGS_REGEXPS */
5324 register int len
= 0;
5326 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
5328 if (*cp
== '\0' && !intoken (dbp
[len
]))
5340 register char *cp
, *name
;
5344 /* Go till you get to white space or a syntactic break */
5345 for (cp
= bp
+ 1; !notinname (*cp
); cp
++)
5347 name
= savenstr (bp
, cp
-bp
);
5349 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5353 /* Initialize a linebuffer for use */
5358 lbp
->size
= (DEBUG
) ? 3 : 200;
5359 lbp
->buffer
= xnew (lbp
->size
, char);
5360 lbp
->buffer
[0] = '\0';
5365 * Read a line of text from `stream' into `lbp', excluding the
5366 * newline or CR-NL, if any. Return the number of characters read from
5367 * `stream', which is the length of the line including the newline.
5369 * On DOS or Windows we do not count the CR character, if any, before the
5370 * NL, in the returned length; this mirrors the behavior of emacs on those
5371 * platforms (for text files, it translates CR-NL to NL as it reads in the
5375 readline_internal (lbp
, stream
)
5377 register FILE *stream
;
5379 char *buffer
= lbp
->buffer
;
5380 register char *p
= lbp
->buffer
;
5381 register char *pend
;
5384 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
5388 register int c
= getc (stream
);
5391 /* We're at the end of linebuffer: expand it. */
5393 xrnew (buffer
, lbp
->size
, char);
5394 p
+= buffer
- lbp
->buffer
;
5395 pend
= buffer
+ lbp
->size
;
5396 lbp
->buffer
= buffer
;
5406 if (p
> buffer
&& p
[-1] == '\r')
5410 /* Assume CRLF->LF translation will be performed by Emacs
5411 when loading this file, so CRs won't appear in the buffer.
5412 It would be cleaner to compensate within Emacs;
5413 however, Emacs does not know how many CRs were deleted
5414 before any given point in the file. */
5429 lbp
->len
= p
- buffer
;
5431 return lbp
->len
+ chars_deleted
;
5435 * Like readline_internal, above, but in addition try to match the
5436 * input line against relevant regular expressions.
5439 readline (lbp
, stream
)
5443 /* Read new line. */
5444 long result
= readline_internal (lbp
, stream
);
5446 /* Honour #line directives. */
5447 if (!no_line_directive
5448 && result
> 12 && strneq (lbp
->buffer
, "#line ", 6))
5452 if (sscanf (lbp
->buffer
, "#line %d \"%n", &lno
, &start
) == 1)
5454 char *endp
= lbp
->buffer
+ start
;
5456 while ((endp
= etags_strchr (endp
, '"')) != NULL
5457 && endp
[-1] == '\\')
5461 char *absname
, *name
= lbp
->buffer
+ start
;
5464 canonicalize_filename(name
); /* for DOS */
5465 absname
= absolute_filename (name
, curfiledir
);
5466 if (filename_is_absolute (name
)
5467 || filename_is_absolute (curfile
))
5471 name
= relative_filename (absname
, tagfiledir
);
5475 if (streq (curtagfname
, name
))
5480 nocharno
= TRUE
; /* do not use char position for tags */
5481 return readline (lbp
, stream
);
5486 #ifdef ETAGS_REGEXPS
5491 /* Match against relevant patterns. */
5493 for (pp
= p_head
; pp
!= NULL
; pp
= pp
->p_next
)
5495 /* Only use generic regexps or those for the current language. */
5496 if (pp
->lang
!= NULL
&& pp
->lang
!= curlang
)
5499 match
= re_match (pp
->pat
, lbp
->buffer
, lbp
->len
, 0, &pp
->regs
);
5504 if (!pp
->error_signaled
)
5506 error ("error while matching \"%s\"", pp
->regex
);
5507 pp
->error_signaled
= TRUE
;
5514 /* Match occurred. Construct a tag. */
5515 if (pp
->name_pattern
[0] != '\0')
5517 /* Make a named tag. */
5518 char *name
= substitute (lbp
->buffer
,
5519 pp
->name_pattern
, &pp
->regs
);
5521 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
5525 /* Make an unnamed tag. */
5526 pfnote ((char *)NULL
, TRUE
,
5527 lbp
->buffer
, match
, lineno
, linecharno
);
5533 #endif /* ETAGS_REGEXPS */
5540 * Return a pointer to a space of size strlen(cp)+1 allocated
5541 * with xnew where the string CP has been copied.
5547 return savenstr (cp
, strlen (cp
));
5551 * Return a pointer to a space of size LEN+1 allocated with xnew where
5552 * the string CP has been copied for at most the first LEN characters.
5561 dp
= xnew (len
+ 1, char);
5562 strncpy (dp
, cp
, len
);
5568 * Return the ptr in sp at which the character c last
5569 * appears; NULL if not found
5571 * Identical to POSIX strrchr, included for portability.
5574 etags_strrchr (sp
, c
)
5575 register const char *sp
;
5578 register const char *r
;
5591 * Return the ptr in sp at which the character c first
5592 * appears; NULL if not found
5594 * Identical to POSIX strchr, included for portability.
5597 etags_strchr (sp
, c
)
5598 register const char *sp
;
5609 /* Skip spaces, return new pointer. */
5614 while (iswhite (*cp
))
5619 /* Skip non spaces, return new pointer. */
5621 skip_non_spaces (cp
)
5624 while (*cp
!= '\0' && !iswhite (*cp
))
5629 /* Print error message and exit. */
5647 suggest_asking_for_help ()
5649 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
5660 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5663 const char *s1
, *s2
;
5665 fprintf (stderr
, "%s: ", progname
);
5666 fprintf (stderr
, s1
, s2
);
5667 fprintf (stderr
, "\n");
5670 /* Return a newly-allocated string whose contents
5671 concatenate those of s1, s2, s3. */
5676 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
5677 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
5679 strcpy (result
, s1
);
5680 strcpy (result
+ len1
, s2
);
5681 strcpy (result
+ len1
+ len2
, s3
);
5682 result
[len1
+ len2
+ len3
] = '\0';
5688 /* Does the same work as the system V getcwd, but does not need to
5689 guess the buffer size in advance. */
5695 char *path
= xnew (bufsize
, char);
5697 while (getcwd (path
, bufsize
) == NULL
)
5699 if (errno
!= ERANGE
)
5703 path
= xnew (bufsize
, char);
5706 canonicalize_filename (path
);
5709 #else /* not HAVE_GETCWD */
5712 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
5716 for (p
= path
; *p
!= '\0'; p
++)
5722 return strdup (path
);
5723 #else /* not MSDOS */
5728 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
5729 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
5734 #endif /* not MSDOS */
5735 #endif /* not HAVE_GETCWD */
5738 /* Return a newly allocated string containing the file name of FILE
5739 relative to the absolute directory DIR (which should end with a slash). */
5741 relative_filename (file
, dir
)
5744 char *fp
, *dp
, *afn
, *res
;
5747 /* Find the common root of file and dir (with a trailing slash). */
5748 afn
= absolute_filename (file
, cwd
);
5751 while (*fp
++ == *dp
++)
5753 fp
--, dp
--; /* back to the first differing char */
5755 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
5758 do /* look at the equal chars until '/' */
5762 /* Build a sequence of "../" strings for the resulting relative file name. */
5764 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
5766 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
5769 strcat (res
, "../");
5771 /* Add the file name relative to the common root of file and dir. */
5772 strcat (res
, fp
+ 1);
5778 /* Return a newly allocated string containing the absolute file name
5779 of FILE given DIR (which should end with a slash). */
5781 absolute_filename (file
, dir
)
5784 char *slashp
, *cp
, *res
;
5786 if (filename_is_absolute (file
))
5787 res
= savestr (file
);
5789 /* We don't support non-absolute file names with a drive
5790 letter, like `d:NAME' (it's too much hassle). */
5791 else if (file
[1] == ':')
5792 fatal ("%s: relative file names with drive letters not supported", file
);
5795 res
= concat (dir
, file
, "");
5797 /* Delete the "/dirname/.." and "/." substrings. */
5798 slashp
= etags_strchr (res
, '/');
5799 while (slashp
!= NULL
&& slashp
[0] != '\0')
5801 if (slashp
[1] == '.')
5803 if (slashp
[2] == '.'
5804 && (slashp
[3] == '/' || slashp
[3] == '\0'))
5809 while (cp
>= res
&& !filename_is_absolute (cp
));
5811 cp
= slashp
; /* the absolute name begins with "/.." */
5813 /* Under MSDOS and NT we get `d:/NAME' as absolute
5814 file name, so the luser could say `d:/../NAME'.
5815 We silently treat this as `d:/NAME'. */
5816 else if (cp
[0] != '/')
5819 strcpy (cp
, slashp
+ 3);
5823 else if (slashp
[2] == '/' || slashp
[2] == '\0')
5825 strcpy (slashp
, slashp
+ 2);
5830 slashp
= etags_strchr (slashp
+ 1, '/');
5834 return savestr ("/");
5839 /* Return a newly allocated string containing the absolute
5840 file name of dir where FILE resides given DIR (which should
5841 end with a slash). */
5843 absolute_dirname (file
, dir
)
5849 canonicalize_filename (file
);
5850 slashp
= etags_strrchr (file
, '/');
5852 return savestr (dir
);
5855 res
= absolute_filename (file
, dir
);
5861 /* Whether the argument string is an absolute file name. The argument
5862 string must have been canonicalized with canonicalize_filename. */
5864 filename_is_absolute (fn
)
5867 return (fn
[0] == '/'
5869 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
5874 /* Translate backslashes into slashes. Works in place. */
5876 canonicalize_filename (fn
)
5880 /* Canonicalize drive letter case. */
5881 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
5882 fn
[0] = upcase (fn
[0]);
5883 /* Convert backslashes to slashes. */
5884 for (; *fn
!= '\0'; fn
++)
5889 fn
= NULL
; /* shut up the compiler */
5893 /* Set the minimum size of a string contained in a linebuffer. */
5895 linebuffer_setlen (lbp
, toksize
)
5899 while (lbp
->size
<= toksize
)
5902 xrnew (lbp
->buffer
, lbp
->size
, char);
5907 /* Like malloc but get fatal error if memory is exhausted. */
5912 PTR result
= (PTR
) malloc (size
);
5914 fatal ("virtual memory exhausted", (char *)NULL
);
5919 xrealloc (ptr
, size
)
5923 PTR result
= (PTR
) realloc (ptr
, size
);
5925 fatal ("virtual memory exhausted", (char *)NULL
);
5931 * c-indentation-style: gnu
5932 * indent-tabs-mode: t
5934 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer")