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 14.35";
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 **));
302 static int number_len
__P((long));
304 static compressor
*get_compressor_from_suffix
__P((char *, char **));
305 static language
*get_language_from_langname
__P((const char *));
306 static language
*get_language_from_interpreter
__P((char *));
307 static language
*get_language_from_filename
__P((char *));
308 static int total_size_of_entries
__P((node
*));
309 static long readline
__P((linebuffer
*, FILE *));
310 static long readline_internal
__P((linebuffer
*, FILE *));
311 static bool nocase_tail
__P((char *));
312 static char *get_tag
__P((char *));
315 static void analyse_regex
__P((char *, bool));
316 static void add_regex
__P((char *, bool, language
*));
317 static void free_patterns
__P((void));
318 #endif /* ETAGS_REGEXPS */
319 static void error
__P((const char *, const char *));
320 static void suggest_asking_for_help
__P((void));
321 void fatal
__P((char *, char *));
322 static void pfatal
__P((char *));
323 static void add_node
__P((node
*, node
**));
325 static void init
__P((void));
326 static void initbuffer
__P((linebuffer
*));
327 static void find_entries
__P((char *, FILE *));
328 static void free_tree
__P((node
*));
329 static void pfnote
__P((char *, bool, char *, int, int, long));
330 static void new_pfnote
__P((char *, int, bool, char *, int, int, long));
331 static void process_file
__P((char *));
332 static void put_entries
__P((node
*));
334 static char *concat
__P((char *, char *, char *));
335 static char *skip_spaces
__P((char *));
336 static char *skip_non_spaces
__P((char *));
337 static char *savenstr
__P((char *, int));
338 static char *savestr
__P((char *));
339 static char *etags_strchr
__P((const char *, int));
340 static char *etags_strrchr
__P((const char *, int));
341 static char *etags_getcwd
__P((void));
342 static char *relative_filename
__P((char *, char *));
343 static char *absolute_filename
__P((char *, char *));
344 static char *absolute_dirname
__P((char *, char *));
345 static bool filename_is_absolute
__P((char *f
));
346 static void canonicalize_filename
__P((char *));
347 static void linebuffer_setlen
__P((linebuffer
*, int));
348 PTR xmalloc
__P((unsigned int));
349 PTR xrealloc
__P((char *, unsigned int));
352 char searchar
= '/'; /* use /.../ searches */
354 char *tagfile
; /* output file */
355 char *progname
; /* name this program was invoked with */
356 char *cwd
; /* current working directory */
357 char *tagfiledir
; /* directory of tagfile */
358 FILE *tagf
; /* ioptr for tags file */
360 char *curfile
; /* current input file name */
361 language
*curlang
; /* current language */
363 int lineno
; /* line number of current line */
364 long charno
; /* current character number */
365 long linecharno
; /* charno of start of current line */
366 char *dbp
; /* pointer to start of current tag */
368 node
*head
; /* the head of the binary tree of tags */
370 linebuffer lb
; /* the current line */
372 /* boolean "functions" (see init) */
373 bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
376 *white
= " \f\t\n\r\v",
378 *nonam
= " \f\t\n\r()=,;",
379 /* token ending chars */
380 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
381 /* token starting chars */
382 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
383 /* valid in-token chars */
384 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
386 bool append_to_tagfile
; /* -a: append to tags */
387 /* The following four default to TRUE for etags, but to FALSE for ctags. */
388 bool typedefs
; /* -t: create tags for C and Ada typedefs */
389 bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
390 /* 0 struct/enum/union decls, and C++ */
391 /* member functions. */
392 bool constantypedefs
; /* -d: create tags for C #define, enum */
393 /* constants and variables. */
394 /* -D: opposite of -d. Default under ctags. */
395 bool declarations
; /* --declarations: tag them and extern in C&Co*/
396 bool globals
; /* create tags for global variables */
397 bool members
; /* create tags for C member variables */
398 bool update
; /* -u: update tags */
399 bool vgrind_style
; /* -v: create vgrind style index output */
400 bool no_warnings
; /* -w: suppress warnings */
401 bool cxref_style
; /* -x: create cxref style output */
402 bool cplusplus
; /* .[hc] means C++, not C */
403 bool noindentypedefs
; /* -I: ignore indentation in C */
404 bool packages_only
; /* --packages-only: in Ada, only tag packages*/
407 struct option longopts
[] =
409 { "packages-only", no_argument
, &packages_only
, TRUE
},
410 { "append", no_argument
, NULL
, 'a' },
411 { "backward-search", no_argument
, NULL
, 'B' },
412 { "c++", no_argument
, NULL
, 'C' },
413 { "cxref", no_argument
, NULL
, 'x' },
414 { "defines", no_argument
, NULL
, 'd' },
415 { "declarations", no_argument
, &declarations
, TRUE
},
416 { "no-defines", no_argument
, NULL
, 'D' },
417 { "globals", no_argument
, &globals
, TRUE
},
418 { "no-globals", no_argument
, &globals
, FALSE
},
419 { "help", no_argument
, NULL
, 'h' },
420 { "help", no_argument
, NULL
, 'H' },
421 { "ignore-indentation", no_argument
, NULL
, 'I' },
422 { "include", required_argument
, NULL
, 'i' },
423 { "language", required_argument
, NULL
, 'l' },
424 { "members", no_argument
, &members
, TRUE
},
425 { "no-members", no_argument
, &members
, FALSE
},
426 { "no-warn", no_argument
, NULL
, 'w' },
427 { "output", required_argument
, NULL
, 'o' },
429 { "regex", required_argument
, NULL
, 'r' },
430 { "no-regex", no_argument
, NULL
, 'R' },
431 { "ignore-case-regex", required_argument
, NULL
, 'c' },
432 #endif /* ETAGS_REGEXPS */
433 { "typedefs", no_argument
, NULL
, 't' },
434 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
435 { "update", no_argument
, NULL
, 'u' },
436 { "version", no_argument
, NULL
, 'V' },
437 { "vgrind", no_argument
, NULL
, 'v' },
440 #endif /* LONG_OPTIONS */
443 /* Structure defining a regular expression. Elements are
444 the compiled pattern, and the name string. */
445 typedef struct pattern
447 struct pattern
*p_next
;
450 struct re_pattern_buffer
*pat
;
451 struct re_registers regs
;
456 /* List of all regexps. */
457 pattern
*p_head
= NULL
;
459 /* How many characters in the character set. (From regex.c.) */
460 #define CHAR_SET_SIZE 256
461 /* Translation table for case-insensitive matching. */
462 char lc_trans
[CHAR_SET_SIZE
];
463 #endif /* ETAGS_REGEXPS */
465 compressor compressors
[] =
467 { "z", "gzip -d -c"},
468 { "Z", "gzip -d -c"},
469 { "gz", "gzip -d -c"},
470 { "GZ", "gzip -d -c"},
471 { "bz2", "bzip2 -d -c" },
479 /* Non-NULL if language fixed. */
480 language
*forced_lang
= NULL
;
483 char *Ada_suffixes
[] =
484 { "ads", "adb", "ada", NULL
};
487 char *Asm_suffixes
[] = { "a", /* Unix assembler */
488 "asm", /* Microcontroller assembly */
489 "def", /* BSO/Tasking definition includes */
490 "inc", /* Microcontroller include files */
491 "ins", /* Microcontroller include files */
492 "s", "sa", /* Unix assembler */
493 "S", /* cpp-processed Unix assembler */
494 "src", /* BSO/Tasking C compiler output */
498 /* Note that .c and .h can be considered C++, if the --c++ flag was
499 given, or if the `class' keyowrd is met inside the file.
500 That is why default_C_entries is called for these. */
501 char *default_C_suffixes
[] =
504 char *Cplusplus_suffixes
[] =
505 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
506 "M", /* Objective C++ */
507 "pdb", /* Postscript with C syntax */
510 char *Cjava_suffixes
[] =
513 char *Cobol_suffixes
[] =
514 { "COB", "cob", NULL
};
516 char *Cstar_suffixes
[] =
517 { "cs", "hs", NULL
};
519 char *Erlang_suffixes
[] =
520 { "erl", "hrl", NULL
};
522 char *Fortran_suffixes
[] =
523 { "F", "f", "f90", "for", NULL
};
525 char *Lisp_suffixes
[] =
526 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
528 char *Makefile_filenames
[] =
529 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
531 char *Pascal_suffixes
[] =
532 { "p", "pas", NULL
};
534 char *Perl_suffixes
[] =
535 { "pl", "pm", NULL
};
536 char *Perl_interpreters
[] =
537 { "perl", "@PERL@", NULL
};
539 char *PHP_suffixes
[] =
540 { "php", "php3", "php4", NULL
};
542 char *plain_C_suffixes
[] =
543 { "lm", /* Objective lex file */
544 "m", /* Objective C file */
545 "pc", /* Pro*C file */
548 char *Postscript_suffixes
[] =
549 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
551 char *Prolog_suffixes
[] =
554 char *Python_suffixes
[] =
557 /* Can't do the `SCM' or `scm' prefix with a version number. */
558 char *Scheme_suffixes
[] =
559 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
561 char *TeX_suffixes
[] =
562 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
564 char *Texinfo_suffixes
[] =
565 { "texi", "texinfo", "txi", NULL
};
567 char *Yacc_suffixes
[] =
568 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
571 * Table of languages.
573 * It is ok for a given function to be listed under more than one
574 * name. I just didn't.
577 language lang_names
[] =
579 { "ada", Ada_funcs
, NULL
, Ada_suffixes
, NULL
},
580 { "asm", Asm_labels
, NULL
, Asm_suffixes
, NULL
},
581 { "c", default_C_entries
, NULL
, default_C_suffixes
, NULL
},
582 { "c++", Cplusplus_entries
, NULL
, Cplusplus_suffixes
, NULL
},
583 { "c*", Cstar_entries
, NULL
, Cstar_suffixes
, NULL
},
584 { "cobol", Cobol_paragraphs
, NULL
, Cobol_suffixes
, NULL
},
585 { "erlang", Erlang_functions
, NULL
, Erlang_suffixes
, NULL
},
586 { "fortran", Fortran_functions
, NULL
, Fortran_suffixes
, NULL
},
587 { "java", Cjava_entries
, NULL
, Cjava_suffixes
, NULL
},
588 { "lisp", Lisp_functions
, NULL
, Lisp_suffixes
, NULL
},
589 { "makefile", Makefile_targets
, Makefile_filenames
, NULL
, NULL
},
590 { "pascal", Pascal_functions
, NULL
, Pascal_suffixes
, NULL
},
591 { "perl", Perl_functions
, NULL
, Perl_suffixes
, Perl_interpreters
},
592 { "php", PHP_functions
, NULL
, PHP_suffixes
, NULL
},
593 { "postscript", Postscript_functions
, NULL
, Postscript_suffixes
, NULL
},
594 { "proc", plain_C_entries
, NULL
, plain_C_suffixes
, NULL
},
595 { "prolog", Prolog_functions
, NULL
, Prolog_suffixes
, NULL
},
596 { "python", Python_functions
, NULL
, Python_suffixes
, NULL
},
597 { "scheme", Scheme_functions
, NULL
, Scheme_suffixes
, NULL
},
598 { "tex", TeX_commands
, NULL
, TeX_suffixes
, NULL
},
599 { "texinfo", Texinfo_nodes
, NULL
, Texinfo_suffixes
, NULL
},
600 { "yacc", Yacc_entries
, NULL
, Yacc_suffixes
, NULL
},
601 { "auto", NULL
}, /* default guessing scheme */
602 { "none", just_read_file
}, /* regexp matching only */
603 { NULL
, NULL
} /* end of list */
608 print_language_names ()
613 puts ("\nThese are the currently supported languages, along with the\n\
614 default file names and dot suffixes:");
615 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
617 printf (" %-*s", 10, lang
->name
);
618 if (lang
->filenames
!= NULL
)
619 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
620 printf (" %s", *name
);
621 if (lang
->suffixes
!= NULL
)
622 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
623 printf (" .%s", *ext
);
626 puts ("Where `auto' means use default language for files based on file\n\
627 name suffix, and `none' means only do regexp processing on files.\n\
628 If no language is specified and no matching suffix is found,\n\
629 the first line of the file is read for a sharp-bang (#!) sequence\n\
630 followed by the name of an interpreter. If no such sequence is found,\n\
631 Fortran is tried first; if no tags are found, C is tried next.\n\
632 When parsing any C file, a \"class\" keyword switches to C++.\n\
633 Compressed files are supported using gzip and bzip2.");
637 # define EMACS_NAME "GNU Emacs"
640 # define VERSION "21"
645 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
646 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
647 puts ("This program is distributed under the same terms as Emacs");
655 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
657 These are the options accepted by %s.\n", progname
, progname
);
659 puts ("You may use unambiguous abbreviations for the long option names.");
661 puts ("Long option names do not work with this executable, as it is not\n\
662 linked with GNU getopt.");
663 #endif /* LONG_OPTIONS */
664 puts ("A - as file name means read names from stdin (one per line).");
666 printf (" Absolute names are stored in the output file as they are.\n\
667 Relative ones are stored relative to the output file's directory.");
670 puts ("-a, --append\n\
671 Append tag entries to existing tags file.");
673 puts ("--packages-only\n\
674 For Ada files, only generate tags for packages .");
677 puts ("-B, --backward-search\n\
678 Write the search commands for the tag entries using '?', the\n\
679 backward-search command instead of '/', the forward-search command.");
681 /* This option is mostly obsolete, because etags can now automatically
682 detect C++. Retained for backward compatibility and for debugging and
683 experimentation. In principle, we could want to tag as C++ even
684 before any "class" keyword.
686 Treat files whose name suffix defaults to C language as C++ files.");
689 puts ("--declarations\n\
690 In C and derived languages, create tags for function declarations,");
692 puts ("\tand create tags for extern variables if --globals is used.");
695 ("\tand create tags for extern variables unless --no-globals is used.");
698 puts ("-d, --defines\n\
699 Create tag entries for C #define constants and enum constants, too.");
701 puts ("-D, --no-defines\n\
702 Don't create tag entries for C #define constants and enum constants.\n\
703 This makes the tags file smaller.");
707 puts ("-i FILE, --include=FILE\n\
708 Include a note in tag file indicating that, when searching for\n\
709 a tag, one should also consult the tags file FILE after\n\
710 checking the current file.");
711 puts ("-l LANG, --language=LANG\n\
712 Force the following files to be considered as written in the\n\
713 named language up to the next --language=LANG option.");
718 Create tag entries for global variables in some languages.");
720 puts ("--no-globals\n\
721 Do not create tag entries for global variables in some\n\
722 languages. This makes the tags file smaller.");
724 Create tag entries for member variables in C and derived languages.");
727 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
728 Make a tag for each line matching pattern REGEXP in the following\n\
729 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
730 regexfile is a file containing one REGEXP per line.\n\
731 REGEXP is anchored (as if preceded by ^).\n\
732 The form /REGEXP/NAME/ creates a named tag.\n\
733 For example Tcl named tags can be created with:\n\
734 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\"");
735 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
736 Like -r, --regex but ignore case when matching expressions.");
737 puts ("-R, --no-regex\n\
738 Don't create tags from regexps for the following files.");
739 #endif /* ETAGS_REGEXPS */
740 puts ("-o FILE, --output=FILE\n\
741 Write the tags to FILE.");
742 puts ("-I, --ignore-indentation\n\
743 Don't rely on indentation quite as much as normal. Currently,\n\
744 this means not to assume that a closing brace in the first\n\
745 column is the final brace of a function or structure\n\
746 definition in C and C++.");
750 puts ("-t, --typedefs\n\
751 Generate tag entries for C and Ada typedefs.");
752 puts ("-T, --typedefs-and-c++\n\
753 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
754 and C++ member functions.");
755 puts ("-u, --update\n\
756 Update the tag entries for the given files, leaving tag\n\
757 entries for other files in place. Currently, this is\n\
758 implemented by deleting the existing entries for the given\n\
759 files and then rewriting the new entries at the end of the\n\
760 tags file. It is often faster to simply rebuild the entire\n\
761 tag file than to use this.");
762 puts ("-v, --vgrind\n\
763 Generates an index of items intended for human consumption,\n\
764 similar to the output of vgrind. The index is sorted, and\n\
765 gives the page number of each item.");
766 puts ("-w, --no-warn\n\
767 Suppress warning messages about entries defined in multiple\n\
769 puts ("-x, --cxref\n\
770 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
771 The output uses line numbers instead of page numbers, but\n\
772 beyond that the differences are cosmetic; try both to see\n\
776 puts ("-V, --version\n\
777 Print the version of the program.\n\
779 Print this help message.");
781 print_language_names ();
784 puts ("Report bugs to bug-gnu-emacs@gnu.org");
798 /* This structure helps us allow mixing of --lang and file names. */
801 enum argument_type arg_type
;
803 language
*lang
; /* language of the regexp */
806 #ifdef VMS /* VMS specific functions */
810 /* This is a BUG! ANY arbitrary limit is a BUG!
811 Won't someone please fix this? */
812 #define MAX_FILE_SPEC_LEN 255
815 char body
[MAX_FILE_SPEC_LEN
+ 1];
819 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
820 returning in each successive call the next file name matching the input
821 spec. The function expects that each in_spec passed
822 to it will be processed to completion; in particular, up to and
823 including the call following that in which the last matching name
824 is returned, the function ignores the value of in_spec, and will
825 only start processing a new spec with the following call.
826 If an error occurs, on return out_spec contains the value
827 of in_spec when the error occurred.
829 With each successive file name returned in out_spec, the
830 function's return value is one. When there are no more matching
831 names the function returns zero. If on the first call no file
832 matches in_spec, or there is any other error, -1 is returned.
837 #define OUTSIZE MAX_FILE_SPEC_LEN
843 static long context
= 0;
844 static struct dsc$descriptor_s o
;
845 static struct dsc$descriptor_s i
;
846 static bool pass1
= TRUE
;
853 o
.dsc$a_pointer
= (char *) out
;
854 o
.dsc$w_length
= (short)OUTSIZE
;
855 i
.dsc$a_pointer
= in
;
856 i
.dsc$w_length
= (short)strlen(in
);
857 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
858 i
.dsc$b_class
= DSC$K_CLASS_S
;
859 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
860 o
.dsc$b_class
= DSC$K_CLASS_VS
;
862 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
864 out
->body
[out
->curlen
] = EOS
;
867 else if (status
== RMS$_NMF
)
871 strcpy(out
->body
, in
);
874 lib$
find_file_end(&context
);
880 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
881 name of each file specified by the provided arg expanding wildcards.
884 gfnames (arg
, p_error
)
888 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
890 switch (fn_exp (&filename
, arg
))
894 return filename
.body
;
900 return filename
.body
;
904 #ifndef OLD /* Newer versions of VMS do provide `system'. */
908 error ("%s", "system() function not implemented under VMS");
912 #define VERSION_DELIM ';'
913 char *massage_name (s
)
919 if (*s
== VERSION_DELIM
)
937 unsigned int nincluded_files
;
938 char **included_files
;
941 int current_arg
, file_count
;
942 linebuffer filename_lb
;
948 _fmode
= O_BINARY
; /* all of files are treated as binary files */
953 included_files
= xnew (argc
, char *);
957 /* Allocate enough no matter what happens. Overkill, but each one
959 argbuffer
= xnew (argc
, argument
);
962 /* Set syntax for regular expression routines. */
963 re_set_syntax (RE_SYNTAX_EMACS
| RE_INTERVALS
);
964 /* Translation table for case-insensitive search. */
965 for (i
= 0; i
< CHAR_SET_SIZE
; i
++)
966 lc_trans
[i
] = lowcase (i
);
967 #endif /* ETAGS_REGEXPS */
970 * If etags, always find typedefs and structure tags. Why not?
971 * Also default to find macro constants, enum constants and
976 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
978 declarations
= FALSE
;
988 optstring
= "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
990 optstring
= "-aCdDf:Il:o:StTi:BuvxwVhH";
991 #endif /* ETAGS_REGEXPS */
994 optstring
= optstring
+ 1;
995 #endif /* LONG_OPTIONS */
997 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
1004 /* If getopt returns 0, then it has already processed a
1005 long-named option. We should do nothing. */
1009 /* This means that a file name has been seen. Record it. */
1010 argbuffer
[current_arg
].arg_type
= at_filename
;
1011 argbuffer
[current_arg
].what
= optarg
;
1016 /* Common options. */
1017 case 'a': append_to_tagfile
= TRUE
; break;
1018 case 'C': cplusplus
= TRUE
; break;
1019 case 'd': constantypedefs
= TRUE
; break;
1020 case 'D': constantypedefs
= FALSE
; break;
1021 case 'f': /* for compatibility with old makefiles */
1025 error ("-o option may only be given once.", (char *)NULL
);
1026 suggest_asking_for_help ();
1031 case 'S': /* for backward compatibility */
1032 noindentypedefs
= TRUE
;
1036 language
*lang
= get_language_from_langname (optarg
);
1039 argbuffer
[current_arg
].lang
= lang
;
1040 argbuffer
[current_arg
].arg_type
= at_language
;
1045 #ifdef ETAGS_REGEXPS
1047 argbuffer
[current_arg
].arg_type
= at_regexp
;
1048 argbuffer
[current_arg
].what
= optarg
;
1052 argbuffer
[current_arg
].arg_type
= at_regexp
;
1053 argbuffer
[current_arg
].what
= NULL
;
1057 argbuffer
[current_arg
].arg_type
= at_icregexp
;
1058 argbuffer
[current_arg
].what
= optarg
;
1061 #endif /* ETAGS_REGEXPS */
1073 typedefs
= typedefs_or_cplusplus
= TRUE
;
1078 included_files
[nincluded_files
++] = optarg
;
1081 /* Ctags options. */
1082 case 'B': searchar
= '?'; break;
1083 case 'u': update
= TRUE
; break;
1084 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1085 case 'x': cxref_style
= TRUE
; break;
1086 case 'w': no_warnings
= TRUE
; break;
1089 suggest_asking_for_help ();
1093 for (; optind
< argc
; ++optind
)
1095 argbuffer
[current_arg
].arg_type
= at_filename
;
1096 argbuffer
[current_arg
].what
= argv
[optind
];
1101 if (nincluded_files
== 0 && file_count
== 0)
1103 error ("no input files specified.", (char *)NULL
);
1104 suggest_asking_for_help ();
1107 if (tagfile
== NULL
)
1108 tagfile
= CTAGS
? "tags" : "TAGS";
1109 cwd
= etags_getcwd (); /* the current working directory */
1110 if (cwd
[strlen (cwd
) - 1] != '/')
1113 cwd
= concat (oldcwd
, "/", "");
1116 if (streq (tagfile
, "-"))
1119 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1121 init (); /* set up boolean "functions" */
1124 initbuffer (&filename_lb
);
1128 if (streq (tagfile
, "-"))
1132 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1133 doesn't take effect until after `stdout' is already open). */
1134 if (!isatty (fileno (stdout
)))
1135 setmode (fileno (stdout
), O_BINARY
);
1139 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1145 * Loop through files finding functions.
1147 for (i
= 0; i
< current_arg
; ++i
)
1149 switch (argbuffer
[i
].arg_type
)
1152 forced_lang
= argbuffer
[i
].lang
;
1154 #ifdef ETAGS_REGEXPS
1156 analyse_regex (argbuffer
[i
].what
, FALSE
);
1159 analyse_regex (argbuffer
[i
].what
, TRUE
);
1164 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1168 error ("can't find file %s\n", this_file
);
1173 this_file
= massage_name (this_file
);
1176 this_file
= argbuffer
[i
].what
;
1178 /* Input file named "-" means read file names from stdin
1179 (one per line) and use them. */
1180 if (streq (this_file
, "-"))
1181 while (readline_internal (&filename_lb
, stdin
) > 0)
1182 process_file (filename_lb
.buffer
);
1184 process_file (this_file
);
1192 #ifdef ETAGS_REGEXPS
1194 #endif /* ETAGS_REGEXPS */
1198 while (nincluded_files
-- > 0)
1199 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1205 /* If CTAGS, we are here. process_file did not write the tags yet,
1206 because we want them ordered. Let's do it now. */
1218 for (i
= 0; i
< current_arg
; ++i
)
1220 if (argbuffer
[i
].arg_type
!= at_filename
)
1223 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1224 tagfile
, argbuffer
[i
].what
, tagfile
);
1225 if (system (cmd
) != GOOD
)
1226 fatal ("failed to execute shell command", (char *)NULL
);
1228 append_to_tagfile
= TRUE
;
1231 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1242 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
1243 exit (system (cmd
));
1251 * Return a compressor given the file name. If EXTPTR is non-zero,
1252 * return a pointer into FILE where the compressor-specific
1253 * extension begins. If no compressor is found, NULL is returned
1254 * and EXTPTR is not significant.
1255 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1258 get_compressor_from_suffix (file
, extptr
)
1263 char *slash
, *suffix
;
1265 /* This relies on FN to be after canonicalize_filename,
1266 so we don't need to consider backslashes on DOS_NT. */
1267 slash
= etags_strrchr (file
, '/');
1268 suffix
= etags_strrchr (file
, '.');
1269 if (suffix
== NULL
|| suffix
< slash
)
1274 /* Let those poor souls who live with DOS 8+3 file name limits get
1275 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1276 Only the first do loop is run if not MSDOS */
1279 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1280 if (streq (compr
->suffix
, suffix
))
1283 break; /* do it only once: not really a loop */
1286 } while (*suffix
!= '\0');
1293 * Return a language given the name.
1296 get_language_from_langname (name
)
1302 error ("empty language name", (char *)NULL
);
1305 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1306 if (streq (name
, lang
->name
))
1308 error ("unknown language \"%s\"", name
);
1316 * Return a language given the interpreter name.
1319 get_language_from_interpreter (interpreter
)
1325 if (interpreter
== NULL
)
1327 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1328 if (lang
->interpreters
!= NULL
)
1329 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1330 if (streq (*iname
, interpreter
))
1339 * Return a language given the file name.
1342 get_language_from_filename (file
)
1346 char **name
, **ext
, *suffix
;
1348 /* Try whole file name first. */
1349 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1350 if (lang
->filenames
!= NULL
)
1351 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1352 if (streq (*name
, file
))
1355 /* If not found, try suffix after last dot. */
1356 suffix
= etags_strrchr (file
, '.');
1360 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1361 if (lang
->suffixes
!= NULL
)
1362 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1363 if (streq (*ext
, suffix
))
1371 * This routine is called on each file argument.
1377 struct stat stat_buf
;
1380 char *compressed_name
, *uncompressed_name
;
1381 char *ext
, *real_name
;
1384 canonicalize_filename (file
);
1385 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1387 error ("skipping inclusion of %s in self.", file
);
1390 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1392 compressed_name
= NULL
;
1393 real_name
= uncompressed_name
= savestr (file
);
1397 real_name
= compressed_name
= savestr (file
);
1398 uncompressed_name
= savenstr (file
, ext
- file
);
1401 /* If the canonicalised uncompressed name has already be dealt with,
1402 skip it silently, else add it to the list. */
1404 typedef struct processed_file
1407 struct processed_file
*next
;
1409 static processed_file
*pf_head
= NULL
;
1410 register processed_file
*fnp
;
1412 for (fnp
= pf_head
; fnp
!= NULL
; fnp
= fnp
->next
)
1413 if (streq (uncompressed_name
, fnp
->filename
))
1416 pf_head
= xnew (1, struct processed_file
);
1417 pf_head
->filename
= savestr (uncompressed_name
);
1418 pf_head
->next
= fnp
;
1421 if (stat (real_name
, &stat_buf
) != 0)
1423 /* Reset real_name and try with a different name. */
1425 if (compressed_name
!= NULL
) /* try with the given suffix */
1427 if (stat (uncompressed_name
, &stat_buf
) == 0)
1428 real_name
= uncompressed_name
;
1430 else /* try all possible suffixes */
1432 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1434 compressed_name
= concat (file
, ".", compr
->suffix
);
1435 if (stat (compressed_name
, &stat_buf
) != 0)
1439 char *suf
= compressed_name
+ strlen (file
);
1440 size_t suflen
= strlen (compr
->suffix
) + 1;
1441 for ( ; suf
[1]; suf
++, suflen
--)
1443 memmove (suf
, suf
+ 1, suflen
);
1444 if (stat (compressed_name
, &stat_buf
) == 0)
1446 real_name
= compressed_name
;
1450 if (real_name
!= NULL
)
1453 free (compressed_name
);
1454 compressed_name
= NULL
;
1458 real_name
= compressed_name
;
1463 if (real_name
== NULL
)
1468 } /* try with a different name */
1470 if (!S_ISREG (stat_buf
.st_mode
))
1472 error ("skipping %s: it is not a regular file.", real_name
);
1475 if (real_name
== compressed_name
)
1477 char *cmd
= concat (compr
->command
, " ", real_name
);
1478 inf
= (FILE *) popen (cmd
, "r");
1482 inf
= fopen (real_name
, "r");
1489 find_entries (uncompressed_name
, inf
);
1491 if (real_name
== compressed_name
)
1500 if (filename_is_absolute (uncompressed_name
))
1502 /* file is an absolute file name. Canonicalise it. */
1503 filename
= absolute_filename (uncompressed_name
, cwd
);
1507 /* file is a file name relative to cwd. Make it relative
1508 to the directory of the tags file. */
1509 filename
= relative_filename (uncompressed_name
, tagfiledir
);
1511 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1519 if (compressed_name
) free(compressed_name
);
1520 if (uncompressed_name
) free(uncompressed_name
);
1525 * This routine sets up the boolean pseudo-functions which work
1526 * by setting boolean flags dependent upon the corresponding character.
1527 * Every char which is NOT in that string is not a white char. Therefore,
1528 * all of the array "_wht" is set to FALSE, and then the elements
1529 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1530 * of a char is TRUE if it is the string "white", else FALSE.
1538 for (i
= 0; i
< CHARS
; i
++)
1539 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1540 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1541 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1542 notinname('\0') = notinname('\n');
1543 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1544 begtoken('\0') = begtoken('\n');
1545 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1546 intoken('\0') = intoken('\n');
1547 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1548 endtoken('\0') = endtoken('\n');
1552 * This routine opens the specified file and calls the function
1553 * which finds the function and type definitions.
1555 node
*last_node
= NULL
;
1558 find_entries (file
, inf
)
1564 node
*old_last_node
;
1566 /* Memory leakage here: the string pointed by curfile is
1567 never released, because curfile is copied into np->file
1568 for each node, to be used in CTAGS mode. The amount of
1569 memory leaked here is the sum of the lengths of the
1571 curfile
= savestr (file
);
1573 /* If user specified a language, use it. */
1575 if (lang
!= NULL
&& lang
->function
!= NULL
)
1578 lang
->function (inf
);
1582 /* Try to guess the language given the file name. */
1583 lang
= get_language_from_filename (file
);
1584 if (lang
!= NULL
&& lang
->function
!= NULL
)
1587 lang
->function (inf
);
1591 /* Look for sharp-bang as the first two characters. */
1592 if (readline_internal (&lb
, inf
) > 0
1594 && lb
.buffer
[0] == '#'
1595 && lb
.buffer
[1] == '!')
1599 /* Set lp to point at the first char after the last slash in the
1600 line or, if no slashes, at the first nonblank. Then set cp to
1601 the first successive blank and terminate the string. */
1602 lp
= etags_strrchr (lb
.buffer
+2, '/');
1606 lp
= skip_spaces (lb
.buffer
+ 2);
1607 cp
= skip_non_spaces (lp
);
1610 if (strlen (lp
) > 0)
1612 lang
= get_language_from_interpreter (lp
);
1613 if (lang
!= NULL
&& lang
->function
!= NULL
)
1616 lang
->function (inf
);
1621 /* We rewind here, even if inf may be a pipe. We fail if the
1622 length of the first line is longer than the pipe block size,
1623 which is unlikely. */
1627 old_last_node
= last_node
;
1628 curlang
= get_language_from_langname ("fortran");
1629 Fortran_functions (inf
);
1631 /* No Fortran entries found. Try C. */
1632 if (old_last_node
== last_node
)
1634 /* We do not tag if rewind fails.
1635 Only the file name will be recorded in the tags file. */
1637 curlang
= get_language_from_langname (cplusplus
? "c++" : "c");
1638 default_C_entries (inf
);
1646 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1647 char *name
; /* tag name, or NULL if unnamed */
1648 bool is_func
; /* tag is a function */
1649 char *linestart
; /* start of the line where tag is */
1650 int linelen
; /* length of the line where tag is */
1651 int lno
; /* line number */
1652 long cno
; /* character number */
1656 if (CTAGS
&& name
== NULL
)
1659 np
= xnew (1, node
);
1661 /* If ctags mode, change name "main" to M<thisfilename>. */
1662 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1664 register char *fp
= etags_strrchr (curfile
, '/');
1665 np
->name
= concat ("M", fp
== NULL
? curfile
: fp
+ 1, "");
1666 fp
= etags_strrchr (np
->name
, '.');
1667 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
1672 np
->been_warned
= FALSE
;
1674 np
->is_func
= is_func
;
1676 /* Our char numbers are 0-base, because of C language tradition?
1677 ctags compatibility? old versions compatibility? I don't know.
1678 Anyway, since emacs's are 1-base we expect etags.el to take care
1679 of the difference. If we wanted to have 1-based numbers, we would
1680 uncomment the +1 below. */
1681 np
->cno
= cno
/* + 1 */ ;
1682 np
->left
= np
->right
= NULL
;
1683 if (CTAGS
&& !cxref_style
)
1685 if (strlen (linestart
) < 50)
1686 np
->pat
= concat (linestart
, "$", "");
1688 np
->pat
= savenstr (linestart
, 50);
1691 np
->pat
= savenstr (linestart
, linelen
);
1693 add_node (np
, &head
);
1697 * TAGS format specification
1698 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1700 * pfnote should emit the optimized form [unnamed tag] only if:
1701 * 1. name does not contain any of the characters " \t\r\n(),;";
1702 * 2. linestart contains name as either a rightmost, or rightmost but
1703 * one character, substring;
1704 * 3. the character, if any, immediately before name in linestart must
1705 * be one of the characters " \t(),;";
1706 * 4. the character, if any, immediately after name in linestart must
1707 * also be one of the characters " \t(),;".
1709 * The real implementation uses the notinname() macro, which recognises
1710 * characters slightly different from " \t\r\n(),;". See the variable
1713 #define traditional_tag_style TRUE
1715 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1716 char *name
; /* tag name, or NULL if unnamed */
1717 int namelen
; /* tag length */
1718 bool is_func
; /* tag is a function */
1719 char *linestart
; /* start of the line where tag is */
1720 int linelen
; /* length of the line where tag is */
1721 int lno
; /* line number */
1722 long cno
; /* character number */
1730 for (cp
= name
; !notinname (*cp
); cp
++)
1732 if (*cp
== '\0') /* rule #1 */
1734 cp
= linestart
+ linelen
- namelen
;
1735 if (notinname (linestart
[linelen
-1]))
1736 cp
-= 1; /* rule #4 */
1737 if (cp
>= linestart
/* rule #2 */
1739 || notinname (cp
[-1])) /* rule #3 */
1740 && strneq (name
, cp
, namelen
)) /* rule #2 */
1741 named
= FALSE
; /* use unnamed tag */
1746 name
= savenstr (name
, namelen
);
1749 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1754 * recurse on left children, iterate on right children.
1762 register node
*node_right
= np
->right
;
1763 free_tree (np
->left
);
1764 if (np
->name
!= NULL
)
1774 * Adds a node to the tree of nodes. In etags mode, we don't keep
1775 * it sorted; we just keep a linear list. In ctags mode, maintain
1776 * an ordered tree, with no attempt at balancing.
1778 * add_node is the only function allowed to add nodes, so it can
1782 add_node (np
, cur_node_p
)
1783 node
*np
, **cur_node_p
;
1786 register node
*cur_node
= *cur_node_p
;
1788 if (cur_node
== NULL
)
1798 if (last_node
== NULL
)
1799 fatal ("internal error in add_node", (char *)NULL
);
1800 last_node
->right
= np
;
1806 dif
= strcmp (np
->name
, cur_node
->name
);
1809 * If this tag name matches an existing one, then
1810 * do not add the node, but maybe print a warning.
1814 if (streq (np
->file
, cur_node
->file
))
1818 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1819 np
->file
, lineno
, np
->name
);
1820 fprintf (stderr
, "Second entry ignored\n");
1823 else if (!cur_node
->been_warned
&& !no_warnings
)
1827 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1828 np
->file
, cur_node
->file
, np
->name
);
1829 cur_node
->been_warned
= TRUE
;
1834 /* Actually add the node */
1835 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1849 /* Output subentries that precede this one */
1850 put_entries (np
->left
);
1852 /* Output this entry */
1856 if (np
->name
!= NULL
)
1857 fprintf (tagf
, "%s\177%s\001%d,%ld\n",
1858 np
->pat
, np
->name
, np
->lno
, np
->cno
);
1860 fprintf (tagf
, "%s\177%d,%ld\n",
1861 np
->pat
, np
->lno
, np
->cno
);
1865 if (np
->name
== NULL
)
1866 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
1871 fprintf (stdout
, "%s %s %d\n",
1872 np
->name
, np
->file
, (np
->lno
+ 63) / 64);
1874 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1875 np
->name
, np
->lno
, np
->file
, np
->pat
);
1879 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->file
);
1883 putc (searchar
, tagf
);
1886 for (sp
= np
->pat
; *sp
; sp
++)
1888 if (*sp
== '\\' || *sp
== searchar
)
1892 putc (searchar
, tagf
);
1895 { /* a typedef; text pattern inadequate */
1896 fprintf (tagf
, "%d", np
->lno
);
1902 /* Output subentries that follow this one */
1903 put_entries (np
->right
);
1906 /* Length of a number's decimal representation. */
1912 while ((num
/= 10) > 0)
1918 * Return total number of characters that put_entries will output for
1919 * the nodes in the subtree of the specified node. Works only if
1920 * we are not ctags, but called only in that case. This count
1921 * is irrelevant with the new tags.el, but is still supplied for
1922 * backward compatibility.
1925 total_size_of_entries (np
)
1933 for (total
= 0; np
!= NULL
; np
= np
->right
)
1935 /* Count left subentries. */
1936 total
+= total_size_of_entries (np
->left
);
1938 /* Count this entry */
1939 total
+= strlen (np
->pat
) + 1;
1940 total
+= number_len ((long) np
->lno
) + 1 + number_len (np
->cno
) + 1;
1941 if (np
->name
!= NULL
)
1942 total
+= 1 + strlen (np
->name
); /* \001name */
1950 #define C_EXT 0x00fff /* C extensions */
1951 #define C_PLAIN 0x00000 /* C */
1952 #define C_PLPL 0x00001 /* C++ */
1953 #define C_STAR 0x00003 /* C* */
1954 #define C_JAVA 0x00005 /* JAVA */
1955 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
1956 #define YACC 0x10000 /* yacc file */
1959 * The C symbol tables.
1964 st_C_objprot
, st_C_objimpl
, st_C_objend
,
1969 st_C_class
, st_C_template
,
1970 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1973 static unsigned int hash
__P((const char *, unsigned int));
1974 static struct C_stab_entry
* in_word_set
__P((const char *, unsigned int));
1975 static enum sym_type C_symtype
__P((char *, int, int));
1977 /* Feed stuff between (but not including) %[ and %] lines to:
1978 gperf -c -k 1,3 -o -p -r -t
1980 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1984 while, 0, st_C_ignore
1985 switch, 0, st_C_ignore
1986 return, 0, st_C_ignore
1987 @interface, 0, st_C_objprot
1988 @protocol, 0, st_C_objprot
1989 @implementation,0, st_C_objimpl
1990 @end, 0, st_C_objend
1991 import, C_JAVA, st_C_ignore
1992 package, C_JAVA, st_C_ignore
1993 friend, C_PLPL, st_C_ignore
1994 extends, C_JAVA, st_C_javastruct
1995 implements, C_JAVA, st_C_javastruct
1996 interface, C_JAVA, st_C_struct
1997 class, 0, st_C_class
1998 namespace, C_PLPL, st_C_struct
1999 domain, C_STAR, st_C_struct
2000 union, 0, st_C_struct
2001 struct, 0, st_C_struct
2002 extern, 0, st_C_extern
2004 typedef, 0, st_C_typedef
2005 define, 0, st_C_define
2006 operator, C_PLPL, st_C_operator
2007 template, 0, st_C_template
2008 bool, C_PLPL, st_C_typespec
2009 long, 0, st_C_typespec
2010 short, 0, st_C_typespec
2011 int, 0, st_C_typespec
2012 char, 0, st_C_typespec
2013 float, 0, st_C_typespec
2014 double, 0, st_C_typespec
2015 signed, 0, st_C_typespec
2016 unsigned, 0, st_C_typespec
2017 auto, 0, st_C_typespec
2018 void, 0, st_C_typespec
2019 static, 0, st_C_typespec
2020 const, 0, st_C_typespec
2021 volatile, 0, st_C_typespec
2022 explicit, C_PLPL, st_C_typespec
2023 mutable, C_PLPL, st_C_typespec
2024 typename, C_PLPL, st_C_typespec
2025 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2026 DEFUN, 0, st_C_gnumacro
2027 SYSCALL, 0, st_C_gnumacro
2028 ENTRY, 0, st_C_gnumacro
2029 PSEUDO, 0, st_C_gnumacro
2030 # These are defined inside C functions, so currently they are not met.
2031 # EXFUN used in glibc, DEFVAR_* in emacs.
2032 #EXFUN, 0, st_C_gnumacro
2033 #DEFVAR_, 0, st_C_gnumacro
2035 and replace lines between %< and %> with its output,
2036 then make in_word_set static. */
2038 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
2039 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
2040 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2042 #define TOTAL_KEYWORDS 47
2043 #define MIN_WORD_LENGTH 2
2044 #define MAX_WORD_LENGTH 15
2045 #define MIN_HASH_VALUE 18
2046 #define MAX_HASH_VALUE 138
2047 /* maximum key range = 121, duplicates = 0 */
2054 register const char *str
;
2055 register unsigned int len
;
2057 static unsigned char asso_values
[] =
2059 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2060 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2061 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2062 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2063 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2064 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2065 139, 139, 139, 139, 63, 139, 139, 139, 33, 44,
2066 62, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2067 42, 139, 139, 12, 32, 139, 139, 139, 139, 139,
2068 139, 139, 139, 139, 139, 139, 139, 34, 59, 37,
2069 24, 58, 33, 3, 139, 16, 139, 139, 42, 60,
2070 18, 11, 39, 139, 23, 57, 4, 63, 6, 20,
2071 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2072 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2073 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2074 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2075 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2076 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2077 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2078 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2079 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2080 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2081 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
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
2086 register int hval
= len
;
2092 hval
+= asso_values
[(unsigned char)str
[2]];
2095 hval
+= asso_values
[(unsigned char)str
[0]];
2104 static struct C_stab_entry
*
2105 in_word_set (str
, len
)
2106 register const char *str
;
2107 register unsigned int len
;
2109 static struct C_stab_entry wordlist
[] =
2111 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2112 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2113 {"if", 0, st_C_ignore
},
2114 {""}, {""}, {""}, {""},
2115 {"int", 0, st_C_typespec
},
2117 {"void", 0, st_C_typespec
},
2119 {"interface", C_JAVA
, st_C_struct
},
2121 {"SYSCALL", 0, st_C_gnumacro
},
2123 {"return", 0, st_C_ignore
},
2124 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2125 {"while", 0, st_C_ignore
},
2126 {"auto", 0, st_C_typespec
},
2127 {""}, {""}, {""}, {""}, {""}, {""},
2128 {"float", 0, st_C_typespec
},
2129 {"typedef", 0, st_C_typedef
},
2130 {"typename", C_PLPL
, st_C_typespec
},
2132 {"friend", C_PLPL
, st_C_ignore
},
2133 {"volatile", 0, st_C_typespec
},
2135 {"for", 0, st_C_ignore
},
2136 {"const", 0, st_C_typespec
},
2137 {"import", C_JAVA
, st_C_ignore
},
2139 {"define", 0, st_C_define
},
2140 {"long", 0, st_C_typespec
},
2141 {"implements", C_JAVA
, st_C_javastruct
},
2142 {"signed", 0, st_C_typespec
},
2144 {"extern", 0, st_C_extern
},
2145 {"extends", C_JAVA
, st_C_javastruct
},
2147 {"mutable", C_PLPL
, st_C_typespec
},
2148 {"template", 0, st_C_template
},
2149 {"short", 0, st_C_typespec
},
2150 {"bool", C_PLPL
, st_C_typespec
},
2151 {"char", 0, st_C_typespec
},
2152 {"class", 0, st_C_class
},
2153 {"operator", C_PLPL
, st_C_operator
},
2155 {"switch", 0, st_C_ignore
},
2157 {"ENTRY", 0, st_C_gnumacro
},
2159 {"package", C_JAVA
, st_C_ignore
},
2160 {"union", 0, st_C_struct
},
2161 {"@end", 0, st_C_objend
},
2162 {"struct", 0, st_C_struct
},
2163 {"namespace", C_PLPL
, st_C_struct
},
2165 {"domain", C_STAR
, st_C_struct
},
2166 {"@interface", 0, st_C_objprot
},
2167 {"PSEUDO", 0, st_C_gnumacro
},
2168 {"double", 0, st_C_typespec
},
2170 {"@protocol", 0, st_C_objprot
},
2172 {"static", 0, st_C_typespec
},
2174 {"DEFUN", 0, st_C_gnumacro
},
2175 {""}, {""}, {""}, {""},
2176 {"explicit", C_PLPL
, st_C_typespec
},
2177 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2178 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2180 {"enum", 0, st_C_enum
},
2182 {"unsigned", 0, st_C_typespec
},
2183 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2184 {"@implementation",0, st_C_objimpl
}
2187 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2189 register int key
= hash (str
, len
);
2191 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2193 register const char *s
= wordlist
[key
].name
;
2195 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
2196 return &wordlist
[key
];
2203 static enum sym_type
2204 C_symtype (str
, len
, c_ext
)
2209 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2211 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2218 * C functions and variables are recognized using a simple
2219 * finite automaton. fvdef is its state variable.
2223 fvnone
, /* nothing seen */
2224 fdefunkey
, /* Emacs DEFUN keyword seen */
2225 fdefunname
, /* Emacs DEFUN name seen */
2226 foperator
, /* func: operator keyword seen (cplpl) */
2227 fvnameseen
, /* function or variable name seen */
2228 fstartlist
, /* func: just after open parenthesis */
2229 finlist
, /* func: in parameter list */
2230 flistseen
, /* func: after parameter list */
2231 fignore
, /* func: before open brace */
2232 vignore
/* var-like: ignore until ';' */
2235 bool fvextern
; /* func or var: extern keyword seen; */
2238 * typedefs are recognized using a simple finite automaton.
2239 * typdef is its state variable.
2243 tnone
, /* nothing seen */
2244 tkeyseen
, /* typedef keyword seen */
2245 ttypeseen
, /* defined type seen */
2246 tinbody
, /* inside typedef body */
2247 tend
, /* just before typedef tag */
2248 tignore
/* junk after typedef tag */
2252 * struct-like structures (enum, struct and union) are recognized
2253 * using another simple finite automaton. `structdef' is its state
2258 snone
, /* nothing seen yet,
2259 or in struct body if cblev > 0 */
2260 skeyseen
, /* struct-like keyword seen */
2261 stagseen
, /* struct-like tag seen */
2262 sintemplate
, /* inside template (ignore) */
2263 scolonseen
/* colon seen after struct-like tag */
2267 * When objdef is different from onone, objtag is the name of the class.
2269 char *objtag
= "<uninited>";
2272 * Yet another little state machine to deal with preprocessor lines.
2276 dnone
, /* nothing seen */
2277 dsharpseen
, /* '#' seen as first char on line */
2278 ddefineseen
, /* '#' and 'define' seen */
2279 dignorerest
/* ignore rest of line */
2283 * State machine for Objective C protocols and implementations.
2284 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2288 onone
, /* nothing seen */
2289 oprotocol
, /* @interface or @protocol seen */
2290 oimplementation
, /* @implementations seen */
2291 otagseen
, /* class name seen */
2292 oparenseen
, /* parenthesis before category seen */
2293 ocatseen
, /* category name seen */
2294 oinbody
, /* in @implementation body */
2295 omethodsign
, /* in @implementation body, after +/- */
2296 omethodtag
, /* after method name */
2297 omethodcolon
, /* after method colon */
2298 omethodparm
, /* after method parameter */
2299 oignore
/* wait for @end */
2304 * Use this structure to keep info about the token read, and how it
2305 * should be tagged. Used by the make_C_tag function to build a tag.
2316 } token
; /* latest token read */
2317 linebuffer token_name
; /* its name */
2320 * Variables and functions for dealing with nested structures.
2321 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2323 static void pushclass_above
__P((int, char *, int));
2324 static void popclass_above
__P((int));
2325 static void write_classname
__P((linebuffer
*, char *qualifier
));
2328 char **cname
; /* nested class names */
2329 int *cblev
; /* nested class curly brace level */
2330 int nl
; /* class nesting level (elements used) */
2331 int size
; /* length of the array */
2332 } cstack
; /* stack for nested declaration tags */
2333 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2334 #define nestlev (cstack.nl)
2335 /* After struct keyword or in struct body, not inside an nested function. */
2336 #define instruct (structdef == snone && nestlev > 0 \
2337 && cblev == cstack.cblev[nestlev-1] + 1)
2340 pushclass_above (cblev
, str
, len
)
2347 popclass_above (cblev
);
2349 if (nl
>= cstack
.size
)
2351 int size
= cstack
.size
*= 2;
2352 xrnew (cstack
.cname
, size
, char *);
2353 xrnew (cstack
.cblev
, size
, int);
2355 assert (nl
== 0 || cstack
.cblev
[nl
-1] < cblev
);
2356 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2357 cstack
.cblev
[nl
] = cblev
;
2362 popclass_above (cblev
)
2367 for (nl
= cstack
.nl
- 1;
2368 nl
>= 0 && cstack
.cblev
[nl
] >= cblev
;
2371 if (cstack
.cname
[nl
] != NULL
)
2372 free (cstack
.cname
[nl
]);
2378 write_classname (cn
, qualifier
)
2383 int qlen
= strlen (qualifier
);
2385 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2389 cn
->buffer
[0] = '\0';
2393 len
= strlen (cstack
.cname
[0]);
2394 linebuffer_setlen (cn
, len
);
2395 strcpy (cn
->buffer
, cstack
.cname
[0]);
2397 for (i
= 1; i
< cstack
.nl
; i
++)
2402 s
= cstack
.cname
[i
];
2407 linebuffer_setlen (cn
, len
);
2408 strncat (cn
->buffer
, qualifier
, qlen
);
2409 strncat (cn
->buffer
, s
, slen
);
2414 static bool consider_token
__P((char *, int, int, int *, int, int, bool *));
2415 static void make_C_tag
__P((bool));
2419 * checks to see if the current token is at the start of a
2420 * function or variable, or corresponds to a typedef, or
2421 * is a struct/union/enum tag, or #define, or an enum constant.
2423 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2424 * with args. C_EXTP points to which language we are looking at.
2435 consider_token (str
, len
, c
, c_extp
, cblev
, parlev
, is_func_or_var
)
2436 register char *str
; /* IN: token pointer */
2437 register int len
; /* IN: token length */
2438 register int c
; /* IN: first char after the token */
2439 int *c_extp
; /* IN, OUT: C extensions mask */
2440 int cblev
; /* IN: curly brace level */
2441 int parlev
; /* IN: parenthesis level */
2442 bool *is_func_or_var
; /* OUT: function or variable found */
2444 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2445 structtype is the type of the preceding struct-like keyword, and
2446 structcblev is the curly brace level where it has been seen. */
2447 static enum sym_type structtype
;
2448 static int structcblev
;
2449 static enum sym_type toktype
;
2452 toktype
= C_symtype (str
, len
, *c_extp
);
2455 * Advance the definedef state machine.
2460 /* We're not on a preprocessor line. */
2461 if (toktype
== st_C_gnumacro
)
2468 if (toktype
== st_C_define
)
2470 definedef
= ddefineseen
;
2474 definedef
= dignorerest
;
2479 * Make a tag for any macro, unless it is a constant
2480 * and constantypedefs is FALSE.
2482 definedef
= dignorerest
;
2483 *is_func_or_var
= (c
== '(');
2484 if (!*is_func_or_var
&& !constantypedefs
)
2491 error ("internal error: definedef value.", (char *)NULL
);
2500 if (toktype
== st_C_typedef
)
2522 if (structdef
== snone
&& fvdef
== fvnone
)
2541 * This structdef business is NOT invoked when we are ctags and the
2542 * file is plain C. This is because a struct tag may have the same
2543 * name as another tag, and this loses with ctags.
2547 case st_C_javastruct
:
2548 if (structdef
== stagseen
)
2549 structdef
= scolonseen
;
2554 && (*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2555 && definedef
== dnone
&& structdef
== snone
2556 && typdef
== tnone
&& fvdef
== fvnone
)
2557 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2558 if (toktype
== st_C_template
)
2565 && (typdef
== tkeyseen
2566 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2568 structdef
= skeyseen
;
2569 structtype
= toktype
;
2570 structcblev
= cblev
;
2575 if (structdef
== skeyseen
)
2577 structdef
= stagseen
;
2581 if (typdef
!= tnone
)
2584 /* Detect Objective C constructs. */
2594 objdef
= oimplementation
;
2598 case oimplementation
:
2599 /* Save the class tag for functions or variables defined inside. */
2600 objtag
= savenstr (str
, len
);
2604 /* Save the class tag for categories. */
2605 objtag
= savenstr (str
, len
);
2607 *is_func_or_var
= TRUE
;
2611 *is_func_or_var
= TRUE
;
2618 objdef
= omethodtag
;
2619 linebuffer_setlen (&token_name
, len
);
2620 strncpy (token_name
.buffer
, str
, len
);
2621 token_name
.buffer
[len
] = '\0';
2627 objdef
= omethodparm
;
2632 objdef
= omethodtag
;
2633 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
2634 strncat (token_name
.buffer
, str
, len
);
2639 if (toktype
== st_C_objend
)
2641 /* Memory leakage here: the string pointed by objtag is
2642 never released, because many tests would be needed to
2643 avoid breaking on incorrect input code. The amount of
2644 memory leaked here is the sum of the lengths of the
2652 /* A function, variable or enum constant? */
2659 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2660 fvdef
= fvnone
; /* should be useless */
2668 *is_func_or_var
= TRUE
;
2672 && structdef
== snone
2673 && structtype
== st_C_enum
&& cblev
> structcblev
)
2674 return TRUE
; /* enum constant */
2680 fvdef
= fdefunname
; /* GNU macro */
2681 *is_func_or_var
= TRUE
;
2684 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
2685 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
2690 if ((*c_extp
& C_PLPL
) && strneq (str
+len
-10, "::operator", 10))
2693 *is_func_or_var
= TRUE
;
2696 if (cblev
> 0 && !instruct
)
2698 fvdef
= fvnameseen
; /* function or variable */
2699 *is_func_or_var
= TRUE
;
2710 * C_entries often keeps pointers to tokens or lines which are older than
2711 * the line currently read. By keeping two line buffers, and switching
2712 * them at end of line, it is possible to use those pointers.
2720 #define current_lb_is_new (newndx == curndx)
2721 #define switch_line_buffers() (curndx = 1 - curndx)
2723 #define curlb (lbs[curndx].lb)
2724 #define newlb (lbs[newndx].lb)
2725 #define curlinepos (lbs[curndx].linepos)
2726 #define newlinepos (lbs[newndx].linepos)
2728 #define CNL_SAVE_DEFINEDEF() \
2730 curlinepos = charno; \
2732 linecharno = charno; \
2733 charno += readline (&curlb, inf); \
2734 lp = curlb.buffer; \
2741 CNL_SAVE_DEFINEDEF(); \
2742 if (savetoken.valid) \
2744 token = savetoken; \
2745 savetoken.valid = FALSE; \
2747 definedef = dnone; \
2755 /* This function should never be called when token.valid is FALSE, but
2756 we must protect against invalid input or internal errors. */
2757 if (DEBUG
|| token
.valid
)
2759 if (traditional_tag_style
)
2761 /* This was the original code. Now we call new_pfnote instead,
2762 which uses the new method for naming tags (see new_pfnote). */
2765 if (CTAGS
|| token
.named
)
2766 name
= savestr (token_name
.buffer
);
2767 if (DEBUG
&& !token
.valid
)
2770 name
= concat (name
, "##invalid##", "");
2772 name
= savestr ("##invalid##");
2774 pfnote (name
, isfun
, token
.line
,
2775 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2778 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
2779 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2780 token
.valid
= FALSE
;
2787 * This routine finds functions, variables, typedefs,
2788 * #define's, enum constants and struct/union/enum definitions in
2789 * C syntax and adds them to the list.
2792 C_entries (c_ext
, inf
)
2793 int c_ext
; /* extension of C */
2794 FILE *inf
; /* input file */
2796 register char c
; /* latest char read; '\0' for end of line */
2797 register char *lp
; /* pointer one beyond the character `c' */
2798 int curndx
, newndx
; /* indices for current and new lb */
2799 register int tokoff
; /* offset in line of start of current token */
2800 register int toklen
; /* length of current token */
2801 char *qualifier
; /* string used to qualify names */
2802 int qlen
; /* length of qualifier */
2803 int cblev
; /* current curly brace level */
2804 int parlev
; /* current parenthesis level */
2805 int typdefcblev
; /* cblev where a typedef struct body begun */
2806 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2808 bool yacc_rules
; /* in the rules part of a yacc file */
2809 struct tok savetoken
; /* token saved during preprocessor handling */
2812 initbuffer (&token_name
);
2813 initbuffer (&lbs
[0].lb
);
2814 initbuffer (&lbs
[1].lb
);
2815 if (cstack
.size
== 0)
2817 cstack
.size
= (DEBUG
) ? 1 : 4;
2819 cstack
.cname
= xnew (cstack
.size
, char *);
2820 cstack
.cblev
= xnew (cstack
.size
, int);
2823 tokoff
= toklen
= typdefcblev
= 0; /* keep compiler quiet */
2824 curndx
= newndx
= 0;
2830 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
2831 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
2833 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2834 token
.valid
= savetoken
.valid
= FALSE
;
2837 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2838 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2840 { qualifier
= "."; qlen
= 1; }
2842 { qualifier
= "::"; qlen
= 2; }
2850 /* If we're at the end of the line, the next character is a
2851 '\0'; don't skip it, because it's the thing that tells us
2852 to read the next line. */
2873 /* Newlines inside comments do not end macro definitions in
2875 CNL_SAVE_DEFINEDEF ();
2888 /* Newlines inside strings do not end macro definitions
2889 in traditional cpp, even though compilers don't
2890 usually accept them. */
2891 CNL_SAVE_DEFINEDEF ();
2901 /* Hmmm, something went wrong. */
2930 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2943 else if (/* cplpl && */ *lp
== '/')
2951 if ((c_ext
& YACC
) && *lp
== '%')
2953 /* Entering or exiting rules section in yacc file. */
2955 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
2956 typdef
= tnone
; structdef
= snone
;
2957 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2959 yacc_rules
= !yacc_rules
;
2965 if (definedef
== dnone
)
2968 bool cpptoken
= TRUE
;
2970 /* Look back on this line. If all blanks, or nonblanks
2971 followed by an end of comment, this is a preprocessor
2973 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2976 if (*cp
== '*' && *(cp
+1) == '/')
2985 definedef
= dsharpseen
;
2986 } /* if (definedef == dnone) */
2992 /* Consider token only if some involved conditions are satisfied. */
2993 if (typdef
!= tignore
2994 && definedef
!= dignorerest
2996 && structdef
!= sintemplate
2997 && (definedef
!= dnone
2998 || structdef
!= scolonseen
))
3004 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken (lp
[1]))
3007 * This handles :: in the middle, but not at the
3008 * beginning of an identifier. Also, space-separated
3009 * :: is not recognised.
3014 goto still_in_token
;
3018 bool funorvar
= FALSE
;
3021 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
3022 &c_ext
, cblev
, parlev
, &funorvar
))
3024 if (fvdef
== foperator
)
3027 lp
= skip_spaces (lp
-1);
3031 && !iswhite (*lp
) && *lp
!= '(')
3034 toklen
+= lp
- oldlp
;
3036 token
.named
= FALSE
;
3037 if ((c_ext
& C_EXT
) /* not pure C */
3038 && nestlev
> 0 && definedef
== dnone
)
3039 /* in struct body */
3041 write_classname (&token_name
, qualifier
);
3042 linebuffer_setlen (&token_name
,
3043 token_name
.len
+qlen
+toklen
);
3044 strcat (token_name
.buffer
, qualifier
);
3045 strncat (token_name
.buffer
,
3046 newlb
.buffer
+ tokoff
, toklen
);
3049 else if (objdef
== ocatseen
)
3050 /* Objective C category */
3052 int len
= strlen (objtag
) + 2 + toklen
;
3053 linebuffer_setlen (&token_name
, len
);
3054 strcpy (token_name
.buffer
, objtag
);
3055 strcat (token_name
.buffer
, "(");
3056 strncat (token_name
.buffer
,
3057 newlb
.buffer
+ tokoff
, toklen
);
3058 strcat (token_name
.buffer
, ")");
3061 else if (objdef
== omethodtag
3062 || objdef
== omethodparm
)
3063 /* Objective C method */
3067 else if (fvdef
== fdefunname
)
3068 /* GNU DEFUN and similar macros */
3070 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3074 /* Rewrite the tag so that emacs lisp DEFUNs
3075 can be found by their elisp name */
3082 linebuffer_setlen (&token_name
, len
);
3083 strncpy (token_name
.buffer
,
3084 newlb
.buffer
+ off
, len
);
3085 token_name
.buffer
[len
] = '\0';
3088 if (token_name
.buffer
[len
] == '_')
3089 token_name
.buffer
[len
] = '-';
3090 token
.named
= defun
;
3094 linebuffer_setlen (&token_name
, toklen
);
3095 strncpy (token_name
.buffer
,
3096 newlb
.buffer
+ tokoff
, toklen
);
3097 token_name
.buffer
[toklen
] = '\0';
3098 /* Name macros and members. */
3099 token
.named
= (structdef
== stagseen
3100 || typdef
== ttypeseen
3103 && definedef
== dignorerest
)
3105 && definedef
== dnone
3106 && structdef
== snone
3109 token
.lineno
= lineno
;
3110 token
.offset
= tokoff
;
3111 token
.length
= toklen
;
3112 token
.line
= newlb
.buffer
;
3113 token
.linepos
= newlinepos
;
3116 if (definedef
== dnone
3117 && (fvdef
== fvnameseen
3118 || fvdef
== foperator
3119 || structdef
== stagseen
3121 || typdef
== ttypeseen
3122 || objdef
!= onone
))
3124 if (current_lb_is_new
)
3125 switch_line_buffers ();
3127 else if (definedef
!= dnone
3128 || fvdef
== fdefunname
3130 make_C_tag (funorvar
);
3134 } /* if (endtoken (c)) */
3135 else if (intoken (c
))
3141 } /* if (midtoken) */
3142 else if (begtoken (c
))
3153 make_C_tag (TRUE
); /* a function */
3160 if (structdef
== stagseen
&& !cjava
)
3162 popclass_above (cblev
);
3169 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3171 tokoff
= lp
- 1 - newlb
.buffer
;
3176 } /* if (begtoken) */
3177 } /* if must look at token */
3180 /* Detect end of line, colon, comma, semicolon and various braces
3181 after having handled a token.*/
3185 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3187 make_C_tag (FALSE
); /* a yacc function */
3190 if (definedef
!= dnone
)
3196 make_C_tag (TRUE
); /* an Objective C class */
3200 objdef
= omethodcolon
;
3201 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3202 strcat (token_name
.buffer
, ":");
3205 if (structdef
== stagseen
)
3206 structdef
= scolonseen
;
3209 if (definedef
!= dnone
)
3215 make_C_tag (FALSE
); /* a typedef */
3225 if (typdef
== tignore
)
3229 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3230 || (members
&& instruct
))
3231 make_C_tag (FALSE
); /* a variable */
3234 token
.valid
= FALSE
;
3237 if ((declarations
&& typdef
== tnone
&& !instruct
)
3238 || (members
&& typdef
!= tignore
&& instruct
))
3239 make_C_tag (TRUE
); /* a function declaration */
3245 && structdef
== stagseen
&& (c_ext
& C_PLPL
))
3246 make_C_tag (FALSE
); /* forward declaration */
3248 /* The following instruction invalidates the token.
3249 Probably the token should be invalidated in all other
3250 cases where some state machine is reset prematurely. */
3251 token
.valid
= FALSE
;
3252 } /* switch (fvdef) */
3258 if (structdef
== stagseen
)
3262 if (definedef
!= dnone
)
3268 make_C_tag (TRUE
); /* an Objective C method */
3284 case fvnameseen
: /* a variable */
3285 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3286 || (members
&& instruct
))
3289 case flistseen
: /* a function */
3290 if ((declarations
&& typdef
== tnone
&& !instruct
)
3291 || (members
&& typdef
!= tignore
&& instruct
))
3293 make_C_tag (TRUE
); /* a function declaration */
3296 else if (!declarations
)
3298 token
.valid
= FALSE
;
3303 if (structdef
== stagseen
)
3307 if (definedef
!= dnone
)
3309 if (structdef
== stagseen
)
3316 make_C_tag (FALSE
); /* a typedef */
3328 if ((members
&& cblev
== 1)
3329 || (globals
&& cblev
== 0
3330 && (!fvextern
|| declarations
)))
3331 make_C_tag (FALSE
); /* a variable */
3340 if (definedef
!= dnone
)
3342 if (objdef
== otagseen
&& parlev
== 0)
3343 objdef
= oparenseen
;
3347 if (typdef
== ttypeseen
3351 /* This handles constructs like:
3352 typedef void OperatorFun (int fun); */
3369 if (definedef
!= dnone
)
3371 if (objdef
== ocatseen
&& parlev
== 1)
3373 make_C_tag (TRUE
); /* an Objective C category */
3387 || typdef
== ttypeseen
))
3390 make_C_tag (FALSE
); /* a typedef */
3393 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3397 if (definedef
!= dnone
)
3399 if (typdef
== ttypeseen
)
3401 /* Whenever typdef is set to tinbody (currently only
3402 here), typdefcblev should be set to cblev. */
3404 typdefcblev
= cblev
;
3409 make_C_tag (TRUE
); /* a function */
3418 make_C_tag (TRUE
); /* an Objective C class */
3423 make_C_tag (TRUE
); /* an Objective C method */
3427 /* Neutralize `extern "C" {' grot. */
3428 if (cblev
== 0 && structdef
== snone
&& nestlev
== 0
3435 case skeyseen
: /* unnamed struct */
3436 pushclass_above (cblev
, NULL
, 0);
3439 case stagseen
: /* named struct or enum */
3440 case scolonseen
: /* a class */
3441 pushclass_above (cblev
, token
.line
+token
.offset
, token
.length
);
3443 make_C_tag (FALSE
); /* a struct or enum */
3449 if (definedef
!= dnone
)
3451 if (fvdef
== fstartlist
)
3452 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3455 if (definedef
!= dnone
)
3457 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
3459 cblev
= 0; /* reset curly brace level if first column */
3460 parlev
= 0; /* also reset paren level, just in case... */
3464 popclass_above (cblev
);
3466 /* Only if typdef == tinbody is typdefcblev significant. */
3467 if (typdef
== tinbody
&& cblev
<= typdefcblev
)
3469 assert (cblev
== typdefcblev
);
3474 if (definedef
!= dnone
)
3484 if ((members
&& cblev
== 1)
3485 || (globals
&& cblev
== 0 && (!fvextern
|| declarations
)))
3486 make_C_tag (FALSE
); /* a variable */
3493 if (cplpl
&& structdef
== stagseen
)
3495 structdef
= sintemplate
;
3500 if (structdef
== sintemplate
)
3502 structdef
= stagseen
;
3508 if (objdef
== oinbody
&& cblev
== 0)
3510 objdef
= omethodsign
;
3515 case '#': case '~': case '&': case '%': case '/': case '|':
3516 case '^': case '!': case '.': case '?': case ']':
3517 if (definedef
!= dnone
)
3519 /* These surely cannot follow a function tag in C. */
3532 if (objdef
== otagseen
)
3534 make_C_tag (TRUE
); /* an Objective C class */
3537 /* If a macro spans multiple lines don't reset its state. */
3539 CNL_SAVE_DEFINEDEF ();
3545 } /* while not eof */
3547 free (token_name
.buffer
);
3548 free (lbs
[0].lb
.buffer
);
3549 free (lbs
[1].lb
.buffer
);
3553 * Process either a C++ file or a C file depending on the setting
3557 default_C_entries (inf
)
3560 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
3563 /* Always do plain C. */
3565 plain_C_entries (inf
)
3571 /* Always do C++. */
3573 Cplusplus_entries (inf
)
3576 C_entries (C_PLPL
, inf
);
3579 /* Always do Java. */
3584 C_entries (C_JAVA
, inf
);
3592 C_entries (C_STAR
, inf
);
3595 /* Always do Yacc. */
3600 C_entries (YACC
, inf
);
3604 /* Useful macros. */
3605 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3606 for (lineno = charno = 0; /* loop initialization */ \
3607 !feof (file_pointer) /* loop test */ \
3608 && (lineno++, /* instructions at start of loop */ \
3609 linecharno = charno, \
3610 charno += readline (&line_buffer, file_pointer), \
3611 char_pointer = lb.buffer, \
3614 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
3615 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \
3616 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \
3617 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */
3620 * Read a file, but do no processing. This is used to do regexp
3621 * matching on files that have no language defined.
3624 just_read_file (inf
)
3627 register char *dummy
;
3629 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
3634 /* Fortran parsing */
3636 static void F_takeprec
__P((void));
3637 static void F_getit
__P((FILE *));
3642 dbp
= skip_spaces (dbp
);
3646 dbp
= skip_spaces (dbp
);
3647 if (strneq (dbp
, "(*)", 3))
3652 if (!ISDIGIT (*dbp
))
3654 --dbp
; /* force failure */
3659 while (ISDIGIT (*dbp
));
3668 dbp
= skip_spaces (dbp
);
3672 linecharno
= charno
;
3673 charno
+= readline (&lb
, inf
);
3678 dbp
= skip_spaces (dbp
);
3680 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
3682 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
3684 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3685 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3690 Fortran_functions (inf
)
3693 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3696 dbp
++; /* Ratfor escape to fortran */
3697 dbp
= skip_spaces (dbp
);
3700 switch (lowcase (*dbp
))
3703 if (nocase_tail ("integer"))
3707 if (nocase_tail ("real"))
3711 if (nocase_tail ("logical"))
3715 if (nocase_tail ("complex") || nocase_tail ("character"))
3719 if (nocase_tail ("double"))
3721 dbp
= skip_spaces (dbp
);
3724 if (nocase_tail ("precision"))
3730 dbp
= skip_spaces (dbp
);
3733 switch (lowcase (*dbp
))
3736 if (nocase_tail ("function"))
3740 if (nocase_tail ("subroutine"))
3744 if (nocase_tail ("entry"))
3748 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
3750 dbp
= skip_spaces (dbp
);
3751 if (*dbp
== '\0') /* assume un-named */
3752 pfnote (savestr ("blockdata"), TRUE
,
3753 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
3755 F_getit (inf
); /* look for name */
3766 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3769 static void Ada_getit
__P((FILE *, char *));
3771 /* Once we are positioned after an "interesting" keyword, let's get
3772 the real tag value necessary. */
3774 Ada_getit (inf
, name_qualifier
)
3776 char *name_qualifier
;
3784 dbp
= skip_spaces (dbp
);
3786 || (dbp
[0] == '-' && dbp
[1] == '-'))
3789 linecharno
= charno
;
3790 charno
+= readline (&lb
, inf
);
3793 switch (lowcase(*dbp
))
3796 if (nocase_tail ("body"))
3798 /* Skipping body of procedure body or package body or ....
3799 resetting qualifier to body instead of spec. */
3800 name_qualifier
= "/b";
3805 /* Skipping type of task type or protected type ... */
3806 if (nocase_tail ("type"))
3813 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
3818 dbp
= skip_spaces (dbp
);
3821 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
3829 name
= concat (dbp
, name_qualifier
, "");
3831 pfnote (name
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3842 bool inquote
= FALSE
;
3844 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3846 while (*dbp
!= '\0')
3848 /* Skip a string i.e. "abcd". */
3849 if (inquote
|| (*dbp
== '"'))
3851 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
3856 continue; /* advance char */
3861 break; /* advance line */
3865 /* Skip comments. */
3866 if (dbp
[0] == '-' && dbp
[1] == '-')
3867 break; /* advance line */
3869 /* Skip character enclosed in single quote i.e. 'a'
3870 and skip single quote starting an attribute i.e. 'Image. */
3879 /* Search for beginning of a token. */
3880 if (!begtoken (*dbp
))
3883 continue; /* advance char */
3886 /* We are at the beginning of a token. */
3887 switch (lowcase(*dbp
))
3890 if (!packages_only
&& nocase_tail ("function"))
3891 Ada_getit (inf
, "/f");
3893 break; /* from switch */
3894 continue; /* advance char */
3896 if (!packages_only
&& nocase_tail ("procedure"))
3897 Ada_getit (inf
, "/p");
3898 else if (nocase_tail ("package"))
3899 Ada_getit (inf
, "/s");
3900 else if (nocase_tail ("protected")) /* protected type */
3901 Ada_getit (inf
, "/t");
3903 break; /* from switch */
3904 continue; /* advance char */
3906 if (!packages_only
&& nocase_tail ("task"))
3907 Ada_getit (inf
, "/k");
3908 else if (typedefs
&& !packages_only
&& nocase_tail ("type"))
3910 Ada_getit (inf
, "/t");
3911 while (*dbp
!= '\0')
3915 break; /* from switch */
3916 continue; /* advance char */
3919 /* Look for the end of the token. */
3920 while (!endtoken (*dbp
))
3923 } /* advance char */
3924 } /* advance line */
3929 * Unix and microcontroller assembly tag handling
3930 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
3931 * Idea by Bob Weiner, Motorola Inc. (1994)
3939 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
3941 /* If first char is alphabetic or one of [_.$], test for colon
3942 following identifier. */
3943 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3945 /* Read past label. */
3947 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3949 if (*cp
== ':' || iswhite (*cp
))
3951 /* Found end of label, so copy it and add it to the table. */
3952 pfnote (savenstr(lb
.buffer
, cp
-lb
.buffer
), TRUE
,
3953 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3962 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
3963 * Perl variable names: /^(my|local).../
3964 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
3965 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
3966 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
3969 Perl_functions (inf
)
3972 char *package
= savestr ("main"); /* current package name */
3975 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
3979 if (LOOKING_AT (cp
, "package"))
3982 package
= get_tag (cp
);
3983 if (package
== NULL
) /* can't parse package name */
3984 package
= savestr ("");
3986 package
= savestr(package
); /* make a copy */
3988 else if (LOOKING_AT (cp
, "sub"))
3990 char *name
, *fullname
, *pos
;
3993 while (!notinname (*cp
))
3997 name
= savenstr (sp
, cp
-sp
);
3998 if ((pos
= etags_strchr (name
, ':')) != NULL
&& pos
[1] == ':')
4001 fullname
= concat (package
, "::", name
);
4002 pfnote (fullname
, TRUE
,
4003 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4004 if (name
!= fullname
)
4007 else if (globals
/* only if tagging global vars is enabled */
4008 && (LOOKING_AT (cp
, "my") || LOOKING_AT (cp
, "local")))
4010 /* After "my" or "local", but before any following paren or space. */
4011 char *varname
= NULL
;
4013 if (*cp
== '$' || *cp
== '@' || *cp
== '%')
4015 char* varstart
= ++cp
;
4016 while (ISALNUM (*cp
) || *cp
== '_')
4018 varname
= savenstr (varstart
, cp
-varstart
);
4022 /* Should be examining a variable list at this point;
4023 could insist on seeing an open parenthesis. */
4024 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4028 /* Perhaps I should back cp up one character, so the TAGS table
4029 doesn't mention (and so depend upon) the following char. */
4030 pfnote ((CTAGS
) ? savenstr (lb
.buffer
, cp
-lb
.buffer
) : varname
,
4031 FALSE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4039 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4040 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4043 Python_functions (inf
)
4048 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4049 if (LOOKING_AT (cp
, "def") || LOOKING_AT (cp
, "class"))
4051 while (!notinname (*cp
) && *cp
!= ':')
4054 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4062 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4063 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4064 * - /^[ \t]*define\(\"[^\"]+/
4065 * Only with --members:
4066 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4067 * Idea by Diez B. Roggisch (2001)
4074 bool search_identifier
= FALSE
;
4076 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4078 cp
= skip_spaces (cp
);
4079 if (search_identifier
4082 while (!notinname (*cp
))
4085 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4086 search_identifier
= FALSE
;
4088 else if (LOOKING_AT (cp
, "function"))
4091 cp
= skip_spaces (cp
+1);
4094 while (!notinname (*cp
))
4097 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4100 search_identifier
= TRUE
;
4102 else if (LOOKING_AT (cp
, "class"))
4106 while (*cp
!= '\0' && !iswhite (*cp
))
4108 pfnote (NULL
, FALSE
,
4109 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4112 search_identifier
= TRUE
;
4114 else if (strneq (cp
, "define", 6)
4115 && (cp
= skip_spaces (cp
+6))
4117 && (*cp
== '"' || *cp
== '\''))
4120 while (*cp
!= quote
&& *cp
!= '\0')
4122 pfnote (NULL
, FALSE
,
4123 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4126 && LOOKING_AT (cp
, "var")
4129 while (!notinname(*cp
))
4131 pfnote (NULL
, FALSE
,
4132 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4139 * Cobol tag functions
4140 * We could look for anything that could be a paragraph name.
4141 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4142 * Idea by Corny de Souza (1993)
4145 Cobol_paragraphs (inf
)
4148 register char *bp
, *ep
;
4150 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4156 /* If eoln, compiler option or comment ignore whole line. */
4157 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4160 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4163 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4164 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4171 * Idea by Assar Westerlund <assar@sics.se> (2001)
4174 Makefile_targets (inf
)
4179 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4181 if (*bp
== '\t' || *bp
== '#')
4183 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4186 pfnote (savenstr (lb
.buffer
, bp
- lb
.buffer
), TRUE
,
4187 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4194 * Original code by Mosur K. Mohan (1989)
4196 * Locates tags for procedures & functions. Doesn't do any type- or
4197 * var-definitions. It does look for the keyword "extern" or
4198 * "forward" immediately following the procedure statement; if found,
4199 * the tag is skipped.
4202 Pascal_functions (inf
)
4205 linebuffer tline
; /* mostly copied from C_entries */
4207 int save_lineno
, save_len
;
4208 char c
, *cp
, *namebuf
;
4210 bool /* each of these flags is TRUE iff: */
4211 incomment
, /* point is inside a comment */
4212 inquote
, /* point is inside '..' string */
4213 get_tagname
, /* point is after PROCEDURE/FUNCTION
4214 keyword, so next item = potential tag */
4215 found_tag
, /* point is after a potential tag */
4216 inparms
, /* point is within parameter-list */
4217 verify_tag
; /* point has passed the parm-list, so the
4218 next token will determine whether this
4219 is a FORWARD/EXTERN to be ignored, or
4220 whether it is a real tag */
4222 save_lcno
= save_lineno
= save_len
= 0; /* keep compiler quiet */
4223 namebuf
= NULL
; /* keep compiler quiet */
4228 initbuffer (&tline
);
4230 incomment
= inquote
= FALSE
;
4231 found_tag
= FALSE
; /* have a proc name; check if extern */
4232 get_tagname
= FALSE
; /* have found "procedure" keyword */
4233 inparms
= FALSE
; /* found '(' after "proc" */
4234 verify_tag
= FALSE
; /* check if "extern" is ahead */
4237 while (!feof (inf
)) /* long main loop to get next char */
4240 if (c
== '\0') /* if end of line */
4243 linecharno
= charno
;
4244 charno
+= readline (&lb
, inf
);
4248 if (!((found_tag
&& verify_tag
)
4250 c
= *dbp
++; /* only if don't need *dbp pointing
4251 to the beginning of the name of
4252 the procedure or function */
4256 if (c
== '}') /* within { } comments */
4258 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4275 inquote
= TRUE
; /* found first quote */
4277 case '{': /* found open { comment */
4281 if (*dbp
== '*') /* found open (* comment */
4286 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4289 case ')': /* end of parms list */
4294 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4301 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4303 /* check if this is an "extern" declaration */
4306 if (lowcase (*dbp
== 'e'))
4308 if (nocase_tail ("extern")) /* superfluous, really! */
4314 else if (lowcase (*dbp
) == 'f')
4316 if (nocase_tail ("forward")) /* check for forward reference */
4322 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4326 pfnote (namebuf
, TRUE
,
4327 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
4331 if (get_tagname
) /* grab name of proc or fn */
4336 /* save all values for later tagging */
4337 linebuffer_setlen (&tline
, lb
.len
);
4338 strcpy (tline
.buffer
, lb
.buffer
);
4339 save_lineno
= lineno
;
4340 save_lcno
= linecharno
;
4342 /* grab block name */
4343 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4345 namebuf
= savenstr (dbp
, cp
-dbp
);
4346 dbp
= cp
; /* set dbp to e-o-token */
4347 save_len
= dbp
- lb
.buffer
+ 1;
4348 get_tagname
= FALSE
;
4352 /* and proceed to check for "extern" */
4354 else if (!incomment
&& !inquote
&& !found_tag
)
4356 /* check for proc/fn keywords */
4357 switch (lowcase (c
))
4360 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4364 if (nocase_tail ("unction"))
4369 } /* while not eof */
4371 free (tline
.buffer
);
4376 * Lisp tag functions
4377 * look for (def or (DEF, quote or QUOTE
4380 static void L_getit
__P((void));
4385 if (*dbp
== '\'') /* Skip prefix quote */
4387 else if (*dbp
== '(')
4390 /* Try to skip "(quote " */
4391 if (!LOOKING_AT (dbp
, "quote") && !LOOKING_AT (dbp
, "QUOTE"))
4392 /* Ok, then skip "(" before name in (defstruct (foo)) */
4393 dbp
= skip_spaces (dbp
);
4399 Lisp_functions (inf
)
4402 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4407 if (strneq (dbp
+1, "def", 3) || strneq (dbp
+1, "DEF", 3))
4409 dbp
= skip_non_spaces (dbp
);
4410 dbp
= skip_spaces (dbp
);
4415 /* Check for (foo::defmumble name-defined ... */
4418 while (!notinname (*dbp
) && *dbp
!= ':');
4423 while (*dbp
== ':');
4425 if (strneq (dbp
, "def", 3) || strneq (dbp
, "DEF", 3))
4427 dbp
= skip_non_spaces (dbp
);
4428 dbp
= skip_spaces (dbp
);
4438 * Postscript tag functions
4439 * Just look for lines where the first character is '/'
4440 * Also look at "defineps" for PSWrap
4442 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4443 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4446 Postscript_functions (inf
)
4449 register char *bp
, *ep
;
4451 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4456 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4459 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4460 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4462 else if (LOOKING_AT (bp
, "defineps"))
4469 * Scheme tag functions
4470 * look for (def... xyzzy
4472 * (def ... ((...(xyzzy ....
4474 * Original code by Ken Haase (1985?)
4478 Scheme_functions (inf
)
4483 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4485 if (strneq (bp
, "(def", 4) || strneq (bp
, "(DEF", 4))
4487 bp
= skip_non_spaces (bp
+4);
4488 /* Skip over open parens and white space */
4489 while (notinname (*bp
))
4493 if (LOOKING_AT (bp
, "(SET!") || LOOKING_AT (bp
, "(set!"))
4499 /* Find tags in TeX and LaTeX input files. */
4501 /* TEX_toktab is a table of TeX control sequences that define tags.
4502 Each TEX_tabent records one such control sequence.
4503 CONVERT THIS TO USE THE Stab TYPE!! */
4510 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
4512 /* Default set of control sequences to put into TEX_toktab.
4513 The value of environment var TEXTAGS is prepended to this. */
4515 char *TEX_defenv
= "\
4516 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4517 :part:appendix:entry:index";
4519 static void TEX_mode
__P((FILE *));
4520 static struct TEX_tabent
*TEX_decode_env
__P((char *, char *));
4521 static int TEX_Token
__P((char *));
4523 char TEX_esc
= '\\';
4524 char TEX_opgrp
= '{';
4525 char TEX_clgrp
= '}';
4528 * TeX/LaTeX scanning loop.
4537 /* Select either \ or ! as escape character. */
4540 /* Initialize token table once from environment. */
4542 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
4544 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4547 /* Look at each esc in line. */
4548 while ((cp
= etags_strchr (cp
, TEX_esc
)) != NULL
)
4552 linecharno
+= cp
- lasthit
;
4554 i
= TEX_Token (lasthit
);
4557 /* We seem to include the TeX command in the tag name.
4559 for (p = lasthit + TEX_toktab[i].len;
4560 *p != '\0' && *p != TEX_clgrp;
4563 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL
, TRUE
,
4564 lb
.buffer
, lb
.len
, lineno
, linecharno
);
4565 break; /* We only tag a line once */
4571 #define TEX_LESC '\\'
4572 #define TEX_SESC '!'
4575 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4576 chars accordingly. */
4583 while ((c
= getc (inf
)) != EOF
)
4585 /* Skip to next line if we hit the TeX comment char. */
4589 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
4605 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4606 No attempt is made to correct the situation. */
4610 /* Read environment and prepend it to the default string.
4611 Build token table. */
4612 static struct TEX_tabent
*
4613 TEX_decode_env (evarname
, defenv
)
4617 register char *env
, *p
;
4619 struct TEX_tabent
*tab
;
4622 /* Append default string to environment. */
4623 env
= getenv (evarname
);
4629 env
= concat (oldenv
, defenv
, "");
4632 /* Allocate a token table */
4633 for (size
= 1, p
= env
; p
;)
4634 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
4636 /* Add 1 to leave room for null terminator. */
4637 tab
= xnew (size
+ 1, struct TEX_tabent
);
4639 /* Unpack environment string into token table. Be careful about */
4640 /* zero-length strings (leading ':', "::" and trailing ':') */
4643 p
= etags_strchr (env
, ':');
4644 if (!p
) /* End of environment string. */
4645 p
= env
+ strlen (env
);
4647 { /* Only non-zero strings. */
4648 tab
[i
].name
= savenstr (env
, p
- env
);
4649 tab
[i
].len
= strlen (tab
[i
].name
);
4656 tab
[i
].name
= NULL
; /* Mark end of table. */
4664 /* If the text at CP matches one of the tag-defining TeX command names,
4665 return the pointer to the first occurrence of that command in TEX_toktab.
4666 Otherwise return -1.
4667 Keep the capital `T' in `token' for dumb truncating compilers
4668 (this distinguishes it from `TEX_toktab' */
4675 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
4676 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
4682 /* Texinfo support. Dave Love, Mar. 2000. */
4688 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4689 if (LOOKING_AT (cp
, "@node"))
4692 while (*cp
!= '\0' && *cp
!= ',')
4694 pfnote (savenstr (start
, cp
- start
), TRUE
,
4695 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4703 * Assumes that the predicate or rule starts at column 0.
4704 * Only the first clause of a predicate or rule is added.
4705 * Original code by Sunichirou Sugou (1989)
4706 * Rewritten by Anders Lindgren (1996)
4708 static int prolog_pr
__P((char *, char *));
4709 static void prolog_skip_comment
__P((linebuffer
*, FILE *));
4710 static int prolog_atom
__P((char *, int));
4713 Prolog_functions (inf
)
4724 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4726 if (cp
[0] == '\0') /* Empty line */
4728 else if (iswhite (cp
[0])) /* Not a predicate */
4730 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
4731 prolog_skip_comment (&lb
, inf
);
4732 else if ((len
= prolog_pr (cp
, last
)) > 0)
4734 /* Predicate or rule. Store the function name so that we
4735 only generate a tag for the first clause. */
4737 last
= xnew(len
+ 1, char);
4738 else if (len
+ 1 > allocated
)
4739 xrnew (last
, len
+ 1, char);
4740 allocated
= len
+ 1;
4741 strncpy (last
, cp
, len
);
4749 prolog_skip_comment (plb
, inf
)
4757 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
4758 if (cp
[0] == '*' && cp
[1] == '/')
4761 linecharno
+= readline (plb
, inf
);
4767 * A predicate or rule definition is added if it matches:
4768 * <beginning of line><Prolog Atom><whitespace>(
4769 * or <beginning of line><Prolog Atom><whitespace>:-
4771 * It is added to the tags database if it doesn't match the
4772 * name of the previous clause header.
4774 * Return the size of the name of the predicate or rule, or 0 if no
4780 char *last
; /* Name of last clause. */
4785 pos
= prolog_atom (s
, 0);
4790 pos
= skip_spaces (s
+ pos
) - s
;
4793 || (s
[pos
] == '(' && (pos
+= 1))
4794 || (s
[pos
] == ':' && s
[pos
+ 1] == '-' && (pos
+= 2)))
4795 && (last
== NULL
/* save only the first clause */
4796 || len
!= strlen (last
)
4797 || !strneq (s
, last
, len
)))
4799 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4807 * Consume a Prolog atom.
4808 * Return the number of bytes consumed, or -1 if there was an error.
4810 * A prolog atom, in this context, could be one of:
4811 * - An alphanumeric sequence, starting with a lower case letter.
4812 * - A quoted arbitrary string. Single quotes can escape themselves.
4813 * Backslash quotes everything.
4816 prolog_atom (s
, pos
)
4824 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
4826 /* The atom is unquoted. */
4828 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
4832 return pos
- origpos
;
4834 else if (s
[pos
] == '\'')
4845 pos
++; /* A double quote */
4847 else if (s
[pos
] == '\0')
4848 /* Multiline quoted atoms are ignored. */
4850 else if (s
[pos
] == '\\')
4852 if (s
[pos
+1] == '\0')
4859 return pos
- origpos
;
4867 * Support for Erlang
4869 * Generates tags for functions, defines, and records.
4870 * Assumes that Erlang functions start at column 0.
4871 * Original code by Anders Lindgren (1996)
4873 static int erlang_func
__P((char *, char *));
4874 static void erlang_attribute
__P((char *));
4875 static int erlang_atom
__P((char *, int));
4878 Erlang_functions (inf
)
4889 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4891 if (cp
[0] == '\0') /* Empty line */
4893 else if (iswhite (cp
[0])) /* Not function nor attribute */
4895 else if (cp
[0] == '%') /* comment */
4897 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
4899 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
4901 erlang_attribute (cp
);
4904 else if ((len
= erlang_func (cp
, last
)) > 0)
4907 * Function. Store the function name so that we only
4908 * generates a tag for the first clause.
4911 last
= xnew (len
+ 1, char);
4912 else if (len
+ 1 > allocated
)
4913 xrnew (last
, len
+ 1, char);
4914 allocated
= len
+ 1;
4915 strncpy (last
, cp
, len
);
4923 * A function definition is added if it matches:
4924 * <beginning of line><Erlang Atom><whitespace>(
4926 * It is added to the tags database if it doesn't match the
4927 * name of the previous clause header.
4929 * Return the size of the name of the function, or 0 if no function
4933 erlang_func (s
, last
)
4935 char *last
; /* Name of last clause. */
4940 pos
= erlang_atom (s
, 0);
4945 pos
= skip_spaces (s
+ pos
) - s
;
4947 /* Save only the first clause. */
4950 || len
!= (int)strlen (last
)
4951 || !strneq (s
, last
, len
)))
4953 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4962 * Handle attributes. Currently, tags are generated for defines
4965 * They are on the form:
4966 * -define(foo, bar).
4967 * -define(Foo(M, N), M+N).
4968 * -record(graph, {vtab = notable, cyclic = true}).
4971 erlang_attribute (s
)
4977 if (LOOKING_AT (s
, "-define") || LOOKING_AT (s
, "-record"))
4979 if (s
[pos
++] == '(')
4981 pos
= skip_spaces (s
+ pos
) - s
;
4982 len
= erlang_atom (s
, pos
);
4984 pfnote (savenstr (& s
[pos
], len
), TRUE
,
4985 s
, pos
+ len
, lineno
, linecharno
);
4993 * Consume an Erlang atom (or variable).
4994 * Return the number of bytes consumed, or -1 if there was an error.
4997 erlang_atom (s
, pos
)
5005 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
5007 /* The atom is unquoted. */
5009 while (ISALNUM (s
[pos
]) || s
[pos
] == '_')
5011 return pos
- origpos
;
5013 else if (s
[pos
] == '\'')
5024 else if (s
[pos
] == '\0')
5025 /* Multiline quoted atoms are ignored. */
5027 else if (s
[pos
] == '\\')
5029 if (s
[pos
+1] == '\0')
5036 return pos
- origpos
;
5043 #ifdef ETAGS_REGEXPS
5045 static char *scan_separators
__P((char *));
5046 static void analyse_regex
__P((char *, bool));
5047 static void add_regex
__P((char *, bool, language
*));
5048 static char *substitute
__P((char *, char *, struct re_registers
*));
5050 /* Take a string like "/blah/" and turn it into "blah", making sure
5051 that the first and last characters are the same, and handling
5052 quoted separator characters. Actually, stops on the occurrence of
5053 an unquoted separator. Also turns "\t" into a Tab character.
5054 Returns pointer to terminating separator. Works in place. Null
5055 terminates name string. */
5057 scan_separators (name
)
5061 char *copyto
= name
;
5062 bool quoted
= FALSE
;
5064 for (++name
; *name
!= '\0'; ++name
)
5070 else if (*name
== sep
)
5074 /* Something else is quoted, so preserve the quote. */
5080 else if (*name
== '\\')
5082 else if (*name
== sep
)
5088 /* Terminate copied string. */
5093 /* Look at the argument of --regex or --no-regex and do the right
5094 thing. Same for each line of a regexp file. */
5096 analyse_regex (regex_arg
, ignore_case
)
5100 if (regex_arg
== NULL
)
5102 free_patterns (); /* --no-regex: remove existing regexps */
5106 /* A real --regexp option or a line in a regexp file. */
5107 switch (regex_arg
[0])
5109 /* Comments in regexp file or null arg to --regex. */
5115 /* Read a regex file. This is recursive and may result in a
5116 loop, which will stop when the file descriptors are exhausted. */
5120 linebuffer regexbuf
;
5121 char *regexfile
= regex_arg
+ 1;
5123 /* regexfile is a file containing regexps, one per line. */
5124 regexfp
= fopen (regexfile
, "r");
5125 if (regexfp
== NULL
)
5130 initbuffer (®exbuf
);
5131 while (readline_internal (®exbuf
, regexfp
) > 0)
5132 analyse_regex (regexbuf
.buffer
, ignore_case
);
5133 free (regexbuf
.buffer
);
5138 /* Regexp to be used for a specific language only. */
5142 char *lang_name
= regex_arg
+ 1;
5145 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5148 error ("unterminated language name in regex: %s", regex_arg
);
5152 lang
= get_language_from_langname (lang_name
);
5155 add_regex (cp
+ 1, ignore_case
, lang
);
5159 /* Regexp to be used for any language. */
5161 add_regex (regex_arg
, ignore_case
, NULL
);
5166 /* Turn a name, which is an ed-style (but Emacs syntax) regular
5167 expression, into a real regular expression by compiling it. */
5169 add_regex (regexp_pattern
, ignore_case
, lang
)
5170 char *regexp_pattern
;
5174 static struct re_pattern_buffer zeropattern
;
5177 struct re_pattern_buffer
*patbuf
;
5181 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
5183 error ("%s: unterminated regexp", regexp_pattern
);
5186 name
= scan_separators (regexp_pattern
);
5187 if (regexp_pattern
[0] == '\0')
5189 error ("null regexp", (char *)NULL
);
5192 (void) scan_separators (name
);
5194 patbuf
= xnew (1, struct re_pattern_buffer
);
5195 *patbuf
= zeropattern
;
5197 patbuf
->translate
= lc_trans
; /* translation table to fold case */
5199 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
5202 error ("%s while compiling pattern", err
);
5207 p_head
= xnew (1, pattern
);
5208 p_head
->regex
= savestr (regexp_pattern
);
5209 p_head
->p_next
= pp
;
5210 p_head
->lang
= lang
;
5211 p_head
->pat
= patbuf
;
5212 p_head
->name_pattern
= savestr (name
);
5213 p_head
->error_signaled
= FALSE
;
5217 * Do the substitutions indicated by the regular expression and
5221 substitute (in
, out
, regs
)
5223 struct re_registers
*regs
;
5226 int size
, dig
, diglen
;
5229 size
= strlen (out
);
5231 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5232 if (out
[size
- 1] == '\\')
5233 fatal ("pattern error in \"%s\"", out
);
5234 for (t
= etags_strchr (out
, '\\');
5236 t
= etags_strchr (t
+ 2, '\\'))
5240 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5246 /* Allocate space and do the substitutions. */
5247 result
= xnew (size
+ 1, char);
5249 for (t
= result
; *out
!= '\0'; out
++)
5250 if (*out
== '\\' && ISDIGIT (*++out
))
5253 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5254 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5261 assert (t
<= result
+ size
&& t
- result
== (int)strlen (result
));
5266 /* Deallocate all patterns. */
5271 while (p_head
!= NULL
)
5273 pp
= p_head
->p_next
;
5274 free (p_head
->regex
);
5275 free (p_head
->name_pattern
);
5281 #endif /* ETAGS_REGEXPS */
5288 register int len
= 0;
5290 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
5292 if (*cp
== '\0' && !intoken (dbp
[len
]))
5304 register char *cp
, *name
;
5308 /* Go till you get to white space or a syntactic break */
5309 for (cp
= bp
+ 1; !notinname (*cp
); cp
++)
5311 name
= savenstr (bp
, cp
-bp
);
5313 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5317 /* Initialize a linebuffer for use */
5322 lbp
->size
= (DEBUG
) ? 3 : 200;
5323 lbp
->buffer
= xnew (lbp
->size
, char);
5324 lbp
->buffer
[0] = '\0';
5329 * Read a line of text from `stream' into `lbp', excluding the
5330 * newline or CR-NL, if any. Return the number of characters read from
5331 * `stream', which is the length of the line including the newline.
5333 * On DOS or Windows we do not count the CR character, if any, before the
5334 * NL, in the returned length; this mirrors the behavior of emacs on those
5335 * platforms (for text files, it translates CR-NL to NL as it reads in the
5339 readline_internal (lbp
, stream
)
5341 register FILE *stream
;
5343 char *buffer
= lbp
->buffer
;
5344 register char *p
= lbp
->buffer
;
5345 register char *pend
;
5348 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
5352 register int c
= getc (stream
);
5355 /* We're at the end of linebuffer: expand it. */
5357 xrnew (buffer
, lbp
->size
, char);
5358 p
+= buffer
- lbp
->buffer
;
5359 pend
= buffer
+ lbp
->size
;
5360 lbp
->buffer
= buffer
;
5370 if (p
> buffer
&& p
[-1] == '\r')
5374 /* Assume CRLF->LF translation will be performed by Emacs
5375 when loading this file, so CRs won't appear in the buffer.
5376 It would be cleaner to compensate within Emacs;
5377 however, Emacs does not know how many CRs were deleted
5378 before any given point in the file. */
5393 lbp
->len
= p
- buffer
;
5395 return lbp
->len
+ chars_deleted
;
5399 * Like readline_internal, above, but in addition try to match the
5400 * input line against relevant regular expressions.
5403 readline (lbp
, stream
)
5407 /* Read new line. */
5408 long result
= readline_internal (lbp
, stream
);
5409 #ifdef ETAGS_REGEXPS
5413 /* Match against relevant patterns. */
5415 for (pp
= p_head
; pp
!= NULL
; pp
= pp
->p_next
)
5417 /* Only use generic regexps or those for the current language. */
5418 if (pp
->lang
!= NULL
&& pp
->lang
!= curlang
)
5421 match
= re_match (pp
->pat
, lbp
->buffer
, lbp
->len
, 0, &pp
->regs
);
5426 if (!pp
->error_signaled
)
5428 error ("error while matching \"%s\"", pp
->regex
);
5429 pp
->error_signaled
= TRUE
;
5436 /* Match occurred. Construct a tag. */
5437 if (pp
->name_pattern
[0] != '\0')
5439 /* Make a named tag. */
5440 char *name
= substitute (lbp
->buffer
,
5441 pp
->name_pattern
, &pp
->regs
);
5443 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
5447 /* Make an unnamed tag. */
5448 pfnote ((char *)NULL
, TRUE
,
5449 lbp
->buffer
, match
, lineno
, linecharno
);
5454 #endif /* ETAGS_REGEXPS */
5461 * Return a pointer to a space of size strlen(cp)+1 allocated
5462 * with xnew where the string CP has been copied.
5468 return savenstr (cp
, strlen (cp
));
5472 * Return a pointer to a space of size LEN+1 allocated with xnew where
5473 * the string CP has been copied for at most the first LEN characters.
5482 dp
= xnew (len
+ 1, char);
5483 strncpy (dp
, cp
, len
);
5489 * Return the ptr in sp at which the character c last
5490 * appears; NULL if not found
5492 * Identical to POSIX strrchr, included for portability.
5495 etags_strrchr (sp
, c
)
5496 register const char *sp
;
5499 register const char *r
;
5512 * Return the ptr in sp at which the character c first
5513 * appears; NULL if not found
5515 * Identical to POSIX strchr, included for portability.
5518 etags_strchr (sp
, c
)
5519 register const char *sp
;
5530 /* Skip spaces, return new pointer. */
5535 while (iswhite (*cp
))
5540 /* Skip non spaces, return new pointer. */
5542 skip_non_spaces (cp
)
5545 while (*cp
!= '\0' && !iswhite (*cp
))
5550 /* Print error message and exit. */
5568 suggest_asking_for_help ()
5570 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
5581 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5584 const char *s1
, *s2
;
5586 fprintf (stderr
, "%s: ", progname
);
5587 fprintf (stderr
, s1
, s2
);
5588 fprintf (stderr
, "\n");
5591 /* Return a newly-allocated string whose contents
5592 concatenate those of s1, s2, s3. */
5597 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
5598 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
5600 strcpy (result
, s1
);
5601 strcpy (result
+ len1
, s2
);
5602 strcpy (result
+ len1
+ len2
, s3
);
5603 result
[len1
+ len2
+ len3
] = '\0';
5609 /* Does the same work as the system V getcwd, but does not need to
5610 guess the buffer size in advance. */
5616 char *path
= xnew (bufsize
, char);
5618 while (getcwd (path
, bufsize
) == NULL
)
5620 if (errno
!= ERANGE
)
5624 path
= xnew (bufsize
, char);
5627 canonicalize_filename (path
);
5630 #else /* not HAVE_GETCWD */
5633 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
5637 for (p
= path
; *p
!= '\0'; p
++)
5643 return strdup (path
);
5644 #else /* not MSDOS */
5649 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
5650 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
5655 #endif /* not MSDOS */
5656 #endif /* not HAVE_GETCWD */
5659 /* Return a newly allocated string containing the file name of FILE
5660 relative to the absolute directory DIR (which should end with a slash). */
5662 relative_filename (file
, dir
)
5665 char *fp
, *dp
, *afn
, *res
;
5668 /* Find the common root of file and dir (with a trailing slash). */
5669 afn
= absolute_filename (file
, cwd
);
5672 while (*fp
++ == *dp
++)
5674 fp
--, dp
--; /* back to the first differing char */
5676 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
5679 do /* look at the equal chars until '/' */
5683 /* Build a sequence of "../" strings for the resulting relative file name. */
5685 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
5687 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
5690 strcat (res
, "../");
5692 /* Add the file name relative to the common root of file and dir. */
5693 strcat (res
, fp
+ 1);
5699 /* Return a newly allocated string containing the absolute file name
5700 of FILE given DIR (which should end with a slash). */
5702 absolute_filename (file
, dir
)
5705 char *slashp
, *cp
, *res
;
5707 if (filename_is_absolute (file
))
5708 res
= savestr (file
);
5710 /* We don't support non-absolute file names with a drive
5711 letter, like `d:NAME' (it's too much hassle). */
5712 else if (file
[1] == ':')
5713 fatal ("%s: relative file names with drive letters not supported", file
);
5716 res
= concat (dir
, file
, "");
5718 /* Delete the "/dirname/.." and "/." substrings. */
5719 slashp
= etags_strchr (res
, '/');
5720 while (slashp
!= NULL
&& slashp
[0] != '\0')
5722 if (slashp
[1] == '.')
5724 if (slashp
[2] == '.'
5725 && (slashp
[3] == '/' || slashp
[3] == '\0'))
5730 while (cp
>= res
&& !filename_is_absolute (cp
));
5732 cp
= slashp
; /* the absolute name begins with "/.." */
5734 /* Under MSDOS and NT we get `d:/NAME' as absolute
5735 file name, so the luser could say `d:/../NAME'.
5736 We silently treat this as `d:/NAME'. */
5737 else if (cp
[0] != '/')
5740 strcpy (cp
, slashp
+ 3);
5744 else if (slashp
[2] == '/' || slashp
[2] == '\0')
5746 strcpy (slashp
, slashp
+ 2);
5751 slashp
= etags_strchr (slashp
+ 1, '/');
5755 return savestr ("/");
5760 /* Return a newly allocated string containing the absolute
5761 file name of dir where FILE resides given DIR (which should
5762 end with a slash). */
5764 absolute_dirname (file
, dir
)
5770 canonicalize_filename (file
);
5771 slashp
= etags_strrchr (file
, '/');
5773 return savestr (dir
);
5776 res
= absolute_filename (file
, dir
);
5782 /* Whether the argument string is an absolute file name. The argument
5783 string must have been canonicalized with canonicalize_filename. */
5785 filename_is_absolute (fn
)
5788 return (fn
[0] == '/'
5790 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
5795 /* Translate backslashes into slashes. Works in place. */
5797 canonicalize_filename (fn
)
5801 /* Canonicalize drive letter case. */
5802 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
5803 fn
[0] = upcase (fn
[0]);
5804 /* Convert backslashes to slashes. */
5805 for (; *fn
!= '\0'; fn
++)
5810 fn
= NULL
; /* shut up the compiler */
5814 /* Set the minimum size of a string contained in a linebuffer. */
5816 linebuffer_setlen (lbp
, toksize
)
5820 while (lbp
->size
<= toksize
)
5823 xrnew (lbp
->buffer
, lbp
->size
, char);
5828 /* Like malloc but get fatal error if memory is exhausted. */
5833 PTR result
= (PTR
) malloc (size
);
5835 fatal ("virtual memory exhausted", (char *)NULL
);
5840 xrealloc (ptr
, size
)
5844 PTR result
= (PTR
) realloc (ptr
, size
);
5846 fatal ("virtual memory exhausted", (char *)NULL
);
5852 * c-indentation-style: gnu
5853 * indent-tabs-mode: t
5855 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer")