1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
2 Copyright (C) 1984, 1987-1989, 1993-1995, 1998-2001, 2002
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * 1989 Sam Kendall added C++.
28 * 1992 Joseph B. Wells improved C and C++ parsing.
29 * 1993 Francesco Potortì reorganised C and C++.
30 * 1994 Line-by-line regexp tags by Tom Tromey.
31 * 2001 Nested classes by Francesco Potortì (concept by Mykola Dzyuba).
32 * 2002 #line directives by Francesco Potortì.
34 * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
38 char pot_etags_version
[] = "@(#) pot revision number is 16.54";
48 # define NDEBUG /* disable assert */
53 /* On some systems, Emacs defines static as nothing for the sake
54 of unexec. We don't want that here since we don't use unexec. */
56 # define ETAGS_REGEXPS /* use the regexp features */
57 # define LONG_OPTIONS /* accept long options */
58 # ifndef PTR /* for Xemacs */
61 # ifndef __P /* for Xemacs */
62 # define __P(args) args
65 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
66 # define __P(args) args /* use prototypes */
67 # define PTR void * /* for generic pointers */
69 # define __P(args) () /* no prototypes */
70 # define const /* remove const for old compilers' sake */
71 # define PTR long * /* don't use void* */
73 #endif /* !HAVE_CONFIG_H */
76 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
79 /* WIN32_NATIVE is for Xemacs.
80 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
85 #endif /* WIN32_NATIVE */
91 # include <sys/param.h>
93 # ifndef HAVE_CONFIG_H
95 # include <sys/config.h>
107 # define MAXPATHLEN _MAX_PATH
113 # endif /* undef HAVE_GETCWD */
114 #else /* !WINDOWSNT */
119 extern char *getenv ();
121 #endif /* !WINDOWSNT */
126 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
127 extern char *getcwd (char *buf
, size_t size
);
129 #endif /* HAVE_UNISTD_H */
137 #include <sys/types.h>
138 #include <sys/stat.h>
142 # undef assert /* some systems have a buggy assert.h */
143 # define assert(x) ((void) 0)
146 #if !defined (S_ISREG) && defined (S_IFREG)
147 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
153 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
155 extern int optind
, opterr
;
156 #endif /* LONG_OPTIONS */
159 # ifndef HAVE_CONFIG_H /* this is a standalone compilation */
160 # ifdef __CYGWIN__ /* compiling on Cygwin */
162 the regex
.h distributed with Cygwin is
not compatible with etags
, alas
!
163 If you want regular expression support
, you should
delete this notice
and
164 arrange to use the GNU regex
.h
and regex
.c
.
168 #endif /* ETAGS_REGEXPS */
170 /* Define CTAGS to make the program "ctags" compatible with the usual one.
171 Leave it undefined to make the program "etags", which makes emacs-style
172 tag tables and tags typedefs, #defines and struct/union/enum by default. */
180 /* Exit codes for success and failure. */
189 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
190 #define strcaseeq(s,t) (assert((s)!=NULL && (t)!=NULL), !etags_strcasecmp (s, t))
191 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
192 #define strncaseeq(s,t,n) (assert((s)!=NULL && (t)!=NULL), !etags_strncasecmp (s, t, n))
194 #define CHARS 256 /* 2^sizeof(char) */
195 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
196 #define iswhite(c) (_wht[CHAR(c)]) /* c is white (see white) */
197 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name (see nonam) */
198 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token (see begtk) */
199 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token (see midtk) */
200 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens (see endtk) */
202 #define ISALNUM(c) isalnum (CHAR(c))
203 #define ISALPHA(c) isalpha (CHAR(c))
204 #define ISDIGIT(c) isdigit (CHAR(c))
205 #define ISLOWER(c) islower (CHAR(c))
207 #define lowcase(c) tolower (CHAR(c))
208 #define upcase(c) toupper (CHAR(c))
212 * xnew, xrnew -- allocate, reallocate storage
214 * SYNOPSIS: Type *xnew (int n, Type);
215 * void xrnew (OldPointer, int n, Type);
218 # include "chkmalloc.h"
219 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
220 (n) * sizeof (Type)))
221 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
222 (char *) (op), (n) * sizeof (Type)))
224 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
225 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
226 (char *) (op), (n) * sizeof (Type)))
231 typedef void Lang_function
__P((FILE *));
235 char *suffix
; /* file name suffix for this compressor */
236 char *command
; /* takes one arg and decompresses to stdout */
241 char *name
; /* language name */
242 bool metasource
; /* source used to generate other sources */
243 Lang_function
*function
; /* parse function */
244 char **filenames
; /* names of this language's files */
245 char **suffixes
; /* name suffixes of this language's files */
246 char **interpreters
; /* interpreters for this language */
251 struct fdesc
*next
; /* for the linked list */
252 char *infname
; /* uncompressed input file name */
253 char *infabsname
; /* absolute uncompressed input file name */
254 char *infabsdir
; /* absolute dir of input file */
255 char *taggedfname
; /* file name to write in tagfile */
256 language
*lang
; /* language of file */
257 char *prop
; /* file properties to write in tagfile */
258 bool usecharno
; /* etags tags shall contain char number */
259 bool written
; /* entry written in the tags file */
262 typedef struct node_st
263 { /* sorting structure */
264 struct node_st
*left
, *right
; /* left and right sons */
265 fdesc
*fdp
; /* description of file to whom tag belongs */
266 char *name
; /* tag name */
267 char *regex
; /* search regexp */
268 bool valid
; /* write this tag on the tag file */
269 bool is_func
; /* function tag: use regexp in CTAGS mode */
270 bool been_warned
; /* warning already given for duplicated tag */
271 int lno
; /* line number tag is on */
272 long cno
; /* character number line starts on */
276 * A `linebuffer' is a structure which holds a line of text.
277 * `readline_internal' reads a line from a stream into a linebuffer
278 * and works regardless of the length of the line.
279 * SIZE is the size of BUFFER, LEN is the length of the string in
280 * BUFFER after readline reads it.
289 /* Used to support mixing of --lang and file names. */
293 at_language
, /* a language specification */
294 at_regexp
, /* a regular expression */
295 at_filename
, /* a file name */
296 at_stdin
/* read from stdin here */
297 } arg_type
; /* argument type */
298 language
*lang
; /* language associated with the argument */
299 char *what
; /* the argument itself */
303 /* Structure defining a regular expression. */
304 typedef struct regexp
306 struct regexp
*p_next
; /* pointer to next in list */
307 language
*lang
; /* if set, use only for this language */
308 char *pattern
; /* the regexp pattern */
309 char *name
; /* tag name */
310 struct re_pattern_buffer
*pat
; /* the compiled pattern */
311 struct re_registers regs
; /* re registers */
312 bool error_signaled
; /* already signaled for this regexp */
313 bool force_explicit_name
; /* do not allow implict tag name */
314 bool ignore_case
; /* ignore case when matching */
315 bool multi_line
; /* do a multi-line match on the whole file */
317 #endif /* ETAGS_REGEXPS */
320 /* Many compilers barf on this:
321 Lang_function Ada_funcs;
322 so let's write it this way */
323 static void Ada_funcs
__P((FILE *));
324 static void Asm_labels
__P((FILE *));
325 static void C_entries
__P((int c_ext
, FILE *));
326 static void default_C_entries
__P((FILE *));
327 static void plain_C_entries
__P((FILE *));
328 static void Cjava_entries
__P((FILE *));
329 static void Cobol_paragraphs
__P((FILE *));
330 static void Cplusplus_entries
__P((FILE *));
331 static void Cstar_entries
__P((FILE *));
332 static void Erlang_functions
__P((FILE *));
333 static void Fortran_functions
__P((FILE *));
334 static void HTML_labels
__P((FILE *));
335 static void Lisp_functions
__P((FILE *));
336 static void Makefile_targets
__P((FILE *));
337 static void Pascal_functions
__P((FILE *));
338 static void Perl_functions
__P((FILE *));
339 static void PHP_functions
__P((FILE *));
340 static void Postscript_functions
__P((FILE *));
341 static void Prolog_functions
__P((FILE *));
342 static void Python_functions
__P((FILE *));
343 static void Scheme_functions
__P((FILE *));
344 static void TeX_commands
__P((FILE *));
345 static void Texinfo_nodes
__P((FILE *));
346 static void Yacc_entries
__P((FILE *));
347 static void just_read_file
__P((FILE *));
349 static void print_language_names
__P((void));
350 static void print_version
__P((void));
351 static void print_help
__P((void));
352 int main
__P((int, char **));
354 static compressor
*get_compressor_from_suffix
__P((char *, char **));
355 static language
*get_language_from_langname
__P((const char *));
356 static language
*get_language_from_interpreter
__P((char *));
357 static language
*get_language_from_filename
__P((char *, bool));
358 static void readline
__P((linebuffer
*, FILE *));
359 static long readline_internal
__P((linebuffer
*, FILE *));
360 static bool nocase_tail
__P((char *));
361 static void get_tag
__P((char *, char **));
364 static void analyse_regex
__P((char *));
365 static void free_regexps
__P((void));
366 static void regex_tag_multiline
__P((void));
367 #endif /* ETAGS_REGEXPS */
368 static void error
__P((const char *, const char *));
369 static void suggest_asking_for_help
__P((void));
370 void fatal
__P((char *, char *));
371 static void pfatal
__P((char *));
372 static void add_node
__P((node
*, node
**));
374 static void init
__P((void));
375 static void process_file_name
__P((char *, language
*));
376 static void process_file
__P((FILE *, char *, language
*));
377 static void find_entries
__P((FILE *));
378 static void free_tree
__P((node
*));
379 static void free_fdesc
__P((fdesc
*));
380 static void pfnote
__P((char *, bool, char *, int, int, long));
381 static void make_tag
__P((char *, int, bool, char *, int, int, long));
382 static void invalidate_nodes
__P((fdesc
*, node
**));
383 static void put_entries
__P((node
*));
385 static char *concat
__P((char *, char *, char *));
386 static char *skip_spaces
__P((char *));
387 static char *skip_non_spaces
__P((char *));
388 static char *savenstr
__P((char *, int));
389 static char *savestr
__P((char *));
390 static char *etags_strchr
__P((const char *, int));
391 static char *etags_strrchr
__P((const char *, int));
392 static int etags_strcasecmp
__P((const char *, const char *));
393 static int etags_strncasecmp
__P((const char *, const char *, int));
394 static char *etags_getcwd
__P((void));
395 static char *relative_filename
__P((char *, char *));
396 static char *absolute_filename
__P((char *, char *));
397 static char *absolute_dirname
__P((char *, char *));
398 static bool filename_is_absolute
__P((char *f
));
399 static void canonicalize_filename
__P((char *));
400 static void linebuffer_init
__P((linebuffer
*));
401 static void linebuffer_setlen
__P((linebuffer
*, int));
402 static PTR xmalloc
__P((unsigned int));
403 static PTR xrealloc
__P((char *, unsigned int));
406 static char searchar
= '/'; /* use /.../ searches */
408 static char *tagfile
; /* output file */
409 static char *progname
; /* name this program was invoked with */
410 static char *cwd
; /* current working directory */
411 static char *tagfiledir
; /* directory of tagfile */
412 static FILE *tagf
; /* ioptr for tags file */
414 static fdesc
*fdhead
; /* head of file description list */
415 static fdesc
*curfdp
; /* current file description */
416 static int lineno
; /* line number of current line */
417 static long charno
; /* current character number */
418 static long linecharno
; /* charno of start of current line */
419 static char *dbp
; /* pointer to start of current tag */
421 static const int invalidcharno
= -1;
423 static node
*nodehead
; /* the head of the binary tree of tags */
424 static node
*last_node
; /* the last node created */
426 static linebuffer lb
; /* the current line */
427 static linebuffer filebuf
; /* a buffer containing the whole file */
428 static linebuffer token_name
; /* a buffer containing a tag name */
430 /* boolean "functions" (see init) */
431 static bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
434 *white
= " \f\t\n\r\v",
436 *nonam
= " \f\t\n\r()=,;", /* look at make_tag before modifying! */
437 /* token ending chars */
438 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
439 /* token starting chars */
440 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
441 /* valid in-token chars */
442 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
444 static bool append_to_tagfile
; /* -a: append to tags */
445 /* The next four default to TRUE for etags, but to FALSE for ctags. */
446 static bool typedefs
; /* -t: create tags for C and Ada typedefs */
447 static bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
448 /* 0 struct/enum/union decls, and C++ */
449 /* member functions. */
450 static bool constantypedefs
; /* -d: create tags for C #define, enum */
451 /* constants and variables. */
452 /* -D: opposite of -d. Default under ctags. */
453 static bool globals
; /* create tags for global variables */
454 static bool declarations
; /* --declarations: tag them and extern in C&Co*/
455 static bool members
; /* create tags for C member variables */
456 static bool no_line_directive
; /* ignore #line directives (undocumented) */
457 static bool update
; /* -u: update tags */
458 static bool vgrind_style
; /* -v: create vgrind style index output */
459 static bool no_warnings
; /* -w: suppress warnings */
460 static bool cxref_style
; /* -x: create cxref style output */
461 static bool cplusplus
; /* .[hc] means C++, not C */
462 static bool ignoreindent
; /* -I: ignore indentation in C */
463 static bool packages_only
; /* --packages-only: in Ada, only tag packages*/
465 #define STDIN 0x1001 /* returned by getopt_long on --parse-stdin */
466 static bool parsing_stdin
; /* --parse-stdin used */
469 static regexp
*p_head
; /* list of all regexps */
470 static bool need_filebuf
; /* some regexes are multi-line */
472 # define need_filebuf FALSE
473 #endif /* ETAGS_REGEXPS */
476 static struct option longopts
[] =
478 { "packages-only", no_argument
, &packages_only
, TRUE
},
479 { "c++", no_argument
, NULL
, 'C' },
480 { "declarations", no_argument
, &declarations
, TRUE
},
481 { "no-line-directive", no_argument
, &no_line_directive
, TRUE
},
482 { "help", no_argument
, NULL
, 'h' },
483 { "help", no_argument
, NULL
, 'H' },
484 { "ignore-indentation", no_argument
, NULL
, 'I' },
485 { "language", required_argument
, NULL
, 'l' },
486 { "members", no_argument
, &members
, TRUE
},
487 { "no-members", no_argument
, &members
, FALSE
},
488 { "output", required_argument
, NULL
, 'o' },
490 { "regex", required_argument
, NULL
, 'r' },
491 { "no-regex", no_argument
, NULL
, 'R' },
492 { "ignore-case-regex", required_argument
, NULL
, 'c' },
493 #endif /* ETAGS_REGEXPS */
494 { "parse-stdin", required_argument
, NULL
, STDIN
},
495 { "version", no_argument
, NULL
, 'V' },
497 #if CTAGS /* Etags options */
498 { "backward-search", no_argument
, NULL
, 'B' },
499 { "cxref", no_argument
, NULL
, 'x' },
500 { "defines", no_argument
, NULL
, 'd' },
501 { "globals", no_argument
, &globals
, TRUE
},
502 { "typedefs", no_argument
, NULL
, 't' },
503 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
504 { "update", no_argument
, NULL
, 'u' },
505 { "vgrind", no_argument
, NULL
, 'v' },
506 { "no-warn", no_argument
, NULL
, 'w' },
508 #else /* Ctags options */
509 { "append", no_argument
, NULL
, 'a' },
510 { "no-defines", no_argument
, NULL
, 'D' },
511 { "no-globals", no_argument
, &globals
, FALSE
},
512 { "include", required_argument
, NULL
, 'i' },
516 #endif /* LONG_OPTIONS */
518 static compressor compressors
[] =
520 { "z", "gzip -d -c"},
521 { "Z", "gzip -d -c"},
522 { "gz", "gzip -d -c"},
523 { "GZ", "gzip -d -c"},
524 { "bz2", "bzip2 -d -c" },
533 static char *Ada_suffixes
[] =
534 { "ads", "adb", "ada", NULL
};
537 static char *Asm_suffixes
[] =
538 { "a", /* Unix assembler */
539 "asm", /* Microcontroller assembly */
540 "def", /* BSO/Tasking definition includes */
541 "inc", /* Microcontroller include files */
542 "ins", /* Microcontroller include files */
543 "s", "sa", /* Unix assembler */
544 "S", /* cpp-processed Unix assembler */
545 "src", /* BSO/Tasking C compiler output */
549 /* Note that .c and .h can be considered C++, if the --c++ flag was
550 given, or if the `class' keyowrd is met inside the file.
551 That is why default_C_entries is called for these. */
552 static char *default_C_suffixes
[] =
555 static char *Cplusplus_suffixes
[] =
556 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
557 "M", /* Objective C++ */
558 "pdb", /* Postscript with C syntax */
561 static char *Cjava_suffixes
[] =
564 static char *Cobol_suffixes
[] =
565 { "COB", "cob", NULL
};
567 static char *Cstar_suffixes
[] =
568 { "cs", "hs", NULL
};
570 static char *Erlang_suffixes
[] =
571 { "erl", "hrl", NULL
};
573 static char *Fortran_suffixes
[] =
574 { "F", "f", "f90", "for", NULL
};
576 static char *HTML_suffixes
[] =
577 { "htm", "html", "shtml", NULL
};
579 static char *Lisp_suffixes
[] =
580 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
582 static char *Makefile_filenames
[] =
583 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
585 static char *Pascal_suffixes
[] =
586 { "p", "pas", NULL
};
588 static char *Perl_suffixes
[] =
589 { "pl", "pm", NULL
};
591 static char *Perl_interpreters
[] =
592 { "perl", "@PERL@", NULL
};
594 static char *PHP_suffixes
[] =
595 { "php", "php3", "php4", NULL
};
597 static char *plain_C_suffixes
[] =
598 { "lm", /* Objective lex file */
599 "m", /* Objective C file */
600 "pc", /* Pro*C file */
603 static char *Postscript_suffixes
[] =
604 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
606 static char *Prolog_suffixes
[] =
609 static char *Python_suffixes
[] =
612 /* Can't do the `SCM' or `scm' prefix with a version number. */
613 static char *Scheme_suffixes
[] =
614 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
616 static char *TeX_suffixes
[] =
617 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
619 static char *Texinfo_suffixes
[] =
620 { "texi", "texinfo", "txi", NULL
};
622 static char *Yacc_suffixes
[] =
623 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
626 * Table of languages.
628 * It is ok for a given function to be listed under more than one
629 * name. I just didn't.
632 static language lang_names
[] =
634 { "ada", FALSE
, Ada_funcs
, NULL
, Ada_suffixes
, NULL
},
635 { "asm", FALSE
, Asm_labels
, NULL
, Asm_suffixes
, NULL
},
636 { "c", FALSE
, default_C_entries
, NULL
, default_C_suffixes
, NULL
},
637 { "c++", FALSE
, Cplusplus_entries
, NULL
, Cplusplus_suffixes
, NULL
},
638 { "c*", FALSE
, Cstar_entries
, NULL
, Cstar_suffixes
, NULL
},
639 { "cobol", FALSE
, Cobol_paragraphs
, NULL
, Cobol_suffixes
, NULL
},
640 { "erlang", FALSE
, Erlang_functions
, NULL
, Erlang_suffixes
, NULL
},
641 { "fortran", FALSE
, Fortran_functions
, NULL
, Fortran_suffixes
, NULL
},
642 { "html", FALSE
, HTML_labels
, NULL
, HTML_suffixes
, NULL
},
643 { "java", FALSE
, Cjava_entries
, NULL
, Cjava_suffixes
, NULL
},
644 { "lisp", FALSE
, Lisp_functions
, NULL
, Lisp_suffixes
, NULL
},
645 { "makefile", FALSE
, Makefile_targets
, Makefile_filenames
, NULL
, NULL
},
646 { "pascal", FALSE
, Pascal_functions
, NULL
, Pascal_suffixes
, NULL
},
647 { "perl", FALSE
, Perl_functions
,NULL
, Perl_suffixes
, Perl_interpreters
},
648 { "php", FALSE
, PHP_functions
, NULL
, PHP_suffixes
, NULL
},
649 { "postscript",FALSE
, Postscript_functions
,NULL
, Postscript_suffixes
, NULL
},
650 { "proc", FALSE
, plain_C_entries
, NULL
, plain_C_suffixes
, NULL
},
651 { "prolog", FALSE
, Prolog_functions
, NULL
, Prolog_suffixes
, NULL
},
652 { "python", FALSE
, Python_functions
, NULL
, Python_suffixes
, NULL
},
653 { "scheme", FALSE
, Scheme_functions
, NULL
, Scheme_suffixes
, NULL
},
654 { "tex", FALSE
, TeX_commands
, NULL
, TeX_suffixes
, NULL
},
655 { "texinfo", FALSE
, Texinfo_nodes
, NULL
, Texinfo_suffixes
, NULL
},
656 { "yacc", TRUE
, Yacc_entries
, NULL
, Yacc_suffixes
, NULL
},
657 { "auto", FALSE
, NULL
}, /* default guessing scheme */
658 { "none", FALSE
, just_read_file
}, /* regexp matching only */
659 { NULL
, FALSE
, NULL
} /* end of list */
664 print_language_names ()
669 puts ("\nThese are the currently supported languages, along with the\n\
670 default file names and dot suffixes:");
671 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
673 printf (" %-*s", 10, lang
->name
);
674 if (lang
->filenames
!= NULL
)
675 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
676 printf (" %s", *name
);
677 if (lang
->suffixes
!= NULL
)
678 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
679 printf (" .%s", *ext
);
682 puts ("Where `auto' means use default language for files based on file\n\
683 name suffix, and `none' means only do regexp processing on files.\n\
684 If no language is specified and no matching suffix is found,\n\
685 the first line of the file is read for a sharp-bang (#!) sequence\n\
686 followed by the name of an interpreter. If no such sequence is found,\n\
687 Fortran is tried first; if no tags are found, C is tried next.\n\
688 When parsing any C file, a \"class\" keyword switches to C++.\n\
689 Compressed files are supported using gzip and bzip2.");
693 # define EMACS_NAME "standalone"
696 # define VERSION "version"
701 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
702 puts ("Copyright (C) 2002 Free Software Foundation, Inc. and Ken Arnold");
703 puts ("This program is distributed under the same terms as Emacs");
711 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
713 These are the options accepted by %s.\n", progname
, progname
);
715 puts ("You may use unambiguous abbreviations for the long option names.");
717 puts ("Long option names do not work with this executable, as it is not\n\
718 linked with GNU getopt.");
719 #endif /* LONG_OPTIONS */
720 puts (" A - as file name means read names from stdin (one per line).\n\
721 Absolute names are stored in the output file as they are.\n\
722 Relative ones are stored relative to the output file's directory.\n");
725 puts ("-a, --append\n\
726 Append tag entries to existing tags file.");
728 puts ("--packages-only\n\
729 For Ada files, only generate tags for packages.");
732 puts ("-B, --backward-search\n\
733 Write the search commands for the tag entries using '?', the\n\
734 backward-search command instead of '/', the forward-search command.");
736 /* This option is mostly obsolete, because etags can now automatically
737 detect C++. Retained for backward compatibility and for debugging and
738 experimentation. In principle, we could want to tag as C++ even
739 before any "class" keyword.
741 Treat files whose name suffix defaults to C language as C++ files.");
744 puts ("--declarations\n\
745 In C and derived languages, create tags for function declarations,");
747 puts ("\tand create tags for extern variables if --globals is used.");
750 ("\tand create tags for extern variables unless --no-globals is used.");
753 puts ("-d, --defines\n\
754 Create tag entries for C #define constants and enum constants, too.");
756 puts ("-D, --no-defines\n\
757 Don't create tag entries for C #define constants and enum constants.\n\
758 This makes the tags file smaller.");
761 puts ("-i FILE, --include=FILE\n\
762 Include a note in tag file indicating that, when searching for\n\
763 a tag, one should also consult the tags file FILE after\n\
764 checking the current file.");
766 puts ("-l LANG, --language=LANG\n\
767 Force the following files to be considered as written in the\n\
768 named language up to the next --language=LANG option.");
772 Create tag entries for global variables in some languages.");
774 puts ("--no-globals\n\
775 Do not create tag entries for global variables in some\n\
776 languages. This makes the tags file smaller.");
778 Create tag entries for member variables in some languages.");
781 puts ("-r REGEXP, --regex=REGEXP or --regex=@regexfile\n\
782 Make a tag for each line matching a regular expression pattern\n\
783 in the following files. {LANGUAGE}REGEXP uses REGEXP for LANGUAGE\n\
784 files only. REGEXFILE is a file containing one REGEXP per line.\n\
785 REGEXP takes the form /TAGREGEXP/TAGNAME/MODS, where TAGNAME/ is\n\
786 optional. The TAGREGEXP pattern is anchored (as if preceded by ^).");
787 puts (" If TAGNAME/ is present, the tags created are named.\n\
788 For example Tcl named tags can be created with:\n\
789 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\".\n\
790 MODS are optional one-letter modifiers: `i' means to ignore case,\n\
791 `m' means to allow multi-line matches, `s' implies `m' and\n\
792 causes dot to match any character, including newline.");
793 puts ("-R, --no-regex\n\
794 Don't create tags from regexps for the following files.");
795 #endif /* ETAGS_REGEXPS */
796 puts ("-I, --ignore-indentation\n\
797 In C and C++ do not assume that a closing brace in the first\n\
798 column is the final brace of a function or structure definition.");
799 puts ("-o FILE, --output=FILE\n\
800 Write the tags to FILE.");
801 puts ("--parse-stdin=NAME\n\
802 Read from standard input and record tags as belonging to file NAME.");
806 puts ("-t, --typedefs\n\
807 Generate tag entries for C and Ada typedefs.");
808 puts ("-T, --typedefs-and-c++\n\
809 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
810 and C++ member functions.");
814 puts ("-u, --update\n\
815 Update the tag entries for the given files, leaving tag\n\
816 entries for other files in place. Currently, this is\n\
817 implemented by deleting the existing entries for the given\n\
818 files and then rewriting the new entries at the end of the\n\
819 tags file. It is often faster to simply rebuild the entire\n\
820 tag file than to use this.");
824 puts ("-v, --vgrind\n\
825 Generates an index of items intended for human consumption,\n\
826 similar to the output of vgrind. The index is sorted, and\n\
827 gives the page number of each item.");
828 puts ("-w, --no-warn\n\
829 Suppress warning messages about entries defined in multiple\n\
831 puts ("-x, --cxref\n\
832 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
833 The output uses line numbers instead of page numbers, but\n\
834 beyond that the differences are cosmetic; try both to see\n\
838 puts ("-V, --version\n\
839 Print the version of the program.\n\
841 Print this help message.");
843 print_language_names ();
846 puts ("Report bugs to bug-gnu-emacs@gnu.org");
852 #ifdef VMS /* VMS specific functions */
856 /* This is a BUG! ANY arbitrary limit is a BUG!
857 Won't someone please fix this? */
858 #define MAX_FILE_SPEC_LEN 255
861 char body
[MAX_FILE_SPEC_LEN
+ 1];
865 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
866 returning in each successive call the next file name matching the input
867 spec. The function expects that each in_spec passed
868 to it will be processed to completion; in particular, up to and
869 including the call following that in which the last matching name
870 is returned, the function ignores the value of in_spec, and will
871 only start processing a new spec with the following call.
872 If an error occurs, on return out_spec contains the value
873 of in_spec when the error occurred.
875 With each successive file name returned in out_spec, the
876 function's return value is one. When there are no more matching
877 names the function returns zero. If on the first call no file
878 matches in_spec, or there is any other error, -1 is returned.
883 #define OUTSIZE MAX_FILE_SPEC_LEN
889 static long context
= 0;
890 static struct dsc$descriptor_s o
;
891 static struct dsc$descriptor_s i
;
892 static bool pass1
= TRUE
;
899 o
.dsc$a_pointer
= (char *) out
;
900 o
.dsc$w_length
= (short)OUTSIZE
;
901 i
.dsc$a_pointer
= in
;
902 i
.dsc$w_length
= (short)strlen(in
);
903 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
904 i
.dsc$b_class
= DSC$K_CLASS_S
;
905 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
906 o
.dsc$b_class
= DSC$K_CLASS_VS
;
908 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
910 out
->body
[out
->curlen
] = EOS
;
913 else if (status
== RMS$_NMF
)
917 strcpy(out
->body
, in
);
920 lib$
find_file_end(&context
);
926 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
927 name of each file specified by the provided arg expanding wildcards.
930 gfnames (arg
, p_error
)
934 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
936 switch (fn_exp (&filename
, arg
))
940 return filename
.body
;
946 return filename
.body
;
950 #ifndef OLD /* Newer versions of VMS do provide `system'. */
954 error ("%s", "system() function not implemented under VMS");
958 #define VERSION_DELIM ';'
959 char *massage_name (s
)
965 if (*s
== VERSION_DELIM
)
983 unsigned int nincluded_files
;
984 char **included_files
;
986 int current_arg
, file_count
;
987 linebuffer filename_lb
;
996 _fmode
= O_BINARY
; /* all of files are treated as binary files */
1000 nincluded_files
= 0;
1001 included_files
= xnew (argc
, char *);
1005 /* Allocate enough no matter what happens. Overkill, but each one
1007 argbuffer
= xnew (argc
, argument
);
1010 * If etags, always find typedefs and structure tags. Why not?
1011 * Also default to find macro constants, enum constants and
1016 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
1021 #ifdef ETAGS_REGEXPS
1022 optstring
= "-r:Rc:";
1023 #endif /* ETAGS_REGEXPS */
1024 #ifndef LONG_OPTIONS
1025 optstring
= optstring
+ 1;
1026 #endif /* LONG_OPTIONS */
1027 optstring
= concat (optstring
,
1029 (CTAGS
) ? "BxdtTuvw" : "aDi:");
1031 while ((opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0)) != EOF
)
1035 /* If getopt returns 0, then it has already processed a
1036 long-named option. We should do nothing. */
1040 /* This means that a file name has been seen. Record it. */
1041 argbuffer
[current_arg
].arg_type
= at_filename
;
1042 argbuffer
[current_arg
].what
= optarg
;
1048 /* Parse standard input. Idea by Vivek <vivek@etla.org>. */
1049 argbuffer
[current_arg
].arg_type
= at_stdin
;
1050 argbuffer
[current_arg
].what
= optarg
;
1054 fatal ("cannot parse standard input more than once", (char *)NULL
);
1055 parsing_stdin
= TRUE
;
1058 /* Common options. */
1059 case 'C': cplusplus
= TRUE
; break;
1060 case 'f': /* for compatibility with old makefiles */
1064 error ("-o option may only be given once.", (char *)NULL
);
1065 suggest_asking_for_help ();
1070 case 'S': /* for backward compatibility */
1071 ignoreindent
= TRUE
;
1075 language
*lang
= get_language_from_langname (optarg
);
1078 argbuffer
[current_arg
].lang
= lang
;
1079 argbuffer
[current_arg
].arg_type
= at_language
;
1085 /* Backward compatibility: support obsolete --ignore-case-regexp. */
1086 optarg
= concat (optarg
, "i", ""); /* memory leak here */
1089 argbuffer
[current_arg
].arg_type
= at_regexp
;
1090 argbuffer
[current_arg
].what
= optarg
;
1094 argbuffer
[current_arg
].arg_type
= at_regexp
;
1095 argbuffer
[current_arg
].what
= NULL
;
1107 case 'a': append_to_tagfile
= TRUE
; break;
1108 case 'D': constantypedefs
= FALSE
; break;
1109 case 'i': included_files
[nincluded_files
++] = optarg
; break;
1111 /* Ctags options. */
1112 case 'B': searchar
= '?'; break;
1113 case 'd': constantypedefs
= TRUE
; break;
1114 case 't': typedefs
= TRUE
; break;
1115 case 'T': typedefs
= typedefs_or_cplusplus
= TRUE
; break;
1116 case 'u': update
= TRUE
; break;
1117 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1118 case 'x': cxref_style
= TRUE
; break;
1119 case 'w': no_warnings
= TRUE
; break;
1121 suggest_asking_for_help ();
1124 for (; optind
< argc
; ++optind
)
1126 argbuffer
[current_arg
].arg_type
= at_filename
;
1127 argbuffer
[current_arg
].what
= argv
[optind
];
1132 if (nincluded_files
== 0 && file_count
== 0)
1134 error ("no input files specified.", (char *)NULL
);
1135 suggest_asking_for_help ();
1138 if (tagfile
== NULL
)
1139 tagfile
= CTAGS
? "tags" : "TAGS";
1140 cwd
= etags_getcwd (); /* the current working directory */
1141 if (cwd
[strlen (cwd
) - 1] != '/')
1144 cwd
= concat (oldcwd
, "/", "");
1147 if (streq (tagfile
, "-"))
1150 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1152 init (); /* set up boolean "functions" */
1154 linebuffer_init (&lb
);
1155 linebuffer_init (&filename_lb
);
1156 linebuffer_init (&filebuf
);
1157 linebuffer_init (&token_name
);
1161 if (streq (tagfile
, "-"))
1165 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1166 doesn't take effect until after `stdout' is already open). */
1167 if (!isatty (fileno (stdout
)))
1168 setmode (fileno (stdout
), O_BINARY
);
1172 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1178 * Loop through files finding functions.
1180 for (i
= 0; i
< current_arg
; ++i
)
1182 static language
*lang
; /* non-NULL if language is forced */
1185 switch (argbuffer
[i
].arg_type
)
1188 lang
= argbuffer
[i
].lang
;
1190 #ifdef ETAGS_REGEXPS
1192 analyse_regex (argbuffer
[i
].what
);
1197 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1201 error ("can't find file %s\n", this_file
);
1206 this_file
= massage_name (this_file
);
1209 this_file
= argbuffer
[i
].what
;
1211 /* Input file named "-" means read file names from stdin
1212 (one per line) and use them. */
1213 if (streq (this_file
, "-"))
1216 fatal ("cannot parse standard input AND read file names from it",
1218 while (readline_internal (&filename_lb
, stdin
) > 0)
1219 process_file_name (filename_lb
.buffer
, lang
);
1222 process_file_name (this_file
, lang
);
1228 this_file
= argbuffer
[i
].what
;
1229 process_file (stdin
, this_file
, lang
);
1234 #ifdef ETAGS_REGEXPS
1236 #endif /* ETAGS_REGEXPS */
1238 free (filebuf
.buffer
);
1239 free (token_name
.buffer
);
1241 if (!CTAGS
|| cxref_style
)
1243 put_entries (nodehead
); /* write the remainig tags (ETAGS) */
1244 free_tree (nodehead
);
1250 /* Output file entries that have no tags. */
1251 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
1253 fprintf (tagf
, "\f\n%s,0\n", fdp
->taggedfname
);
1255 while (nincluded_files
-- > 0)
1256 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1259 if (fclose (tagf
) == EOF
)
1267 for (i
= 0; i
< current_arg
; ++i
)
1269 switch (argbuffer
[i
].arg_type
)
1275 continue; /* the for loop */
1278 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1279 tagfile
, argbuffer
[i
].what
, tagfile
);
1280 if (system (cmd
) != GOOD
)
1281 fatal ("failed to execute shell command", (char *)NULL
);
1283 append_to_tagfile
= TRUE
;
1286 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1289 put_entries (nodehead
); /* write all the tags (CTAGS) */
1290 free_tree (nodehead
);
1292 if (fclose (tagf
) == EOF
)
1297 char cmd
[2*BUFSIZ
+10];
1298 sprintf (cmd
, "sort -o %.*s %.*s", BUFSIZ
, tagfile
, BUFSIZ
, tagfile
);
1299 exit (system (cmd
));
1306 * Return a compressor given the file name. If EXTPTR is non-zero,
1307 * return a pointer into FILE where the compressor-specific
1308 * extension begins. If no compressor is found, NULL is returned
1309 * and EXTPTR is not significant.
1310 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1313 get_compressor_from_suffix (file
, extptr
)
1318 char *slash
, *suffix
;
1320 /* This relies on FN to be after canonicalize_filename,
1321 so we don't need to consider backslashes on DOS_NT. */
1322 slash
= etags_strrchr (file
, '/');
1323 suffix
= etags_strrchr (file
, '.');
1324 if (suffix
== NULL
|| suffix
< slash
)
1329 /* Let those poor souls who live with DOS 8+3 file name limits get
1330 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1331 Only the first do loop is run if not MSDOS */
1334 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1335 if (streq (compr
->suffix
, suffix
))
1338 break; /* do it only once: not really a loop */
1341 } while (*suffix
!= '\0');
1348 * Return a language given the name.
1351 get_language_from_langname (name
)
1357 error ("empty language name", (char *)NULL
);
1360 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1361 if (streq (name
, lang
->name
))
1363 error ("unknown language \"%s\"", name
);
1371 * Return a language given the interpreter name.
1374 get_language_from_interpreter (interpreter
)
1380 if (interpreter
== NULL
)
1382 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1383 if (lang
->interpreters
!= NULL
)
1384 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1385 if (streq (*iname
, interpreter
))
1394 * Return a language given the file name.
1397 get_language_from_filename (file
, case_sensitive
)
1399 bool case_sensitive
;
1402 char **name
, **ext
, *suffix
;
1404 /* Try whole file name first. */
1405 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1406 if (lang
->filenames
!= NULL
)
1407 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1408 if ((case_sensitive
)
1409 ? streq (*name
, file
)
1410 : strcaseeq (*name
, file
))
1413 /* If not found, try suffix after last dot. */
1414 suffix
= etags_strrchr (file
, '.');
1418 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1419 if (lang
->suffixes
!= NULL
)
1420 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1421 if ((case_sensitive
)
1422 ? streq (*ext
, suffix
)
1423 : strcaseeq (*ext
, suffix
))
1430 * This routine is called on each file argument.
1433 process_file_name (file
, lang
)
1437 struct stat stat_buf
;
1441 char *compressed_name
, *uncompressed_name
;
1442 char *ext
, *real_name
;
1445 canonicalize_filename (file
);
1446 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1448 error ("skipping inclusion of %s in self.", file
);
1451 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1453 compressed_name
= NULL
;
1454 real_name
= uncompressed_name
= savestr (file
);
1458 real_name
= compressed_name
= savestr (file
);
1459 uncompressed_name
= savenstr (file
, ext
- file
);
1462 /* If the canonicalized uncompressed name
1463 has already been dealt with, skip it silently. */
1464 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
1466 assert (fdp
->infname
!= NULL
);
1467 if (streq (uncompressed_name
, fdp
->infname
))
1471 if (stat (real_name
, &stat_buf
) != 0)
1473 /* Reset real_name and try with a different name. */
1475 if (compressed_name
!= NULL
) /* try with the given suffix */
1477 if (stat (uncompressed_name
, &stat_buf
) == 0)
1478 real_name
= uncompressed_name
;
1480 else /* try all possible suffixes */
1482 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1484 compressed_name
= concat (file
, ".", compr
->suffix
);
1485 if (stat (compressed_name
, &stat_buf
) != 0)
1489 char *suf
= compressed_name
+ strlen (file
);
1490 size_t suflen
= strlen (compr
->suffix
) + 1;
1491 for ( ; suf
[1]; suf
++, suflen
--)
1493 memmove (suf
, suf
+ 1, suflen
);
1494 if (stat (compressed_name
, &stat_buf
) == 0)
1496 real_name
= compressed_name
;
1500 if (real_name
!= NULL
)
1503 free (compressed_name
);
1504 compressed_name
= NULL
;
1508 real_name
= compressed_name
;
1513 if (real_name
== NULL
)
1518 } /* try with a different name */
1520 if (!S_ISREG (stat_buf
.st_mode
))
1522 error ("skipping %s: it is not a regular file.", real_name
);
1525 if (real_name
== compressed_name
)
1527 char *cmd
= concat (compr
->command
, " ", real_name
);
1528 inf
= (FILE *) popen (cmd
, "r");
1532 inf
= fopen (real_name
, "r");
1539 process_file (inf
, uncompressed_name
, lang
);
1541 if (real_name
== compressed_name
)
1542 retval
= pclose (inf
);
1544 retval
= fclose (inf
);
1549 if (compressed_name
) free (compressed_name
);
1550 if (uncompressed_name
) free (uncompressed_name
);
1557 process_file (fh
, fn
, lang
)
1562 static const fdesc emptyfdesc
;
1565 /* Create a new input file description entry. */
1566 fdp
= xnew (1, fdesc
);
1569 fdp
->infname
= savestr (fn
);
1571 fdp
->infabsname
= absolute_filename (fn
, cwd
);
1572 fdp
->infabsdir
= absolute_dirname (fn
, cwd
);
1573 if (filename_is_absolute (fn
))
1575 /* An absolute file name. Canonicalize it. */
1576 fdp
->taggedfname
= absolute_filename (fn
, NULL
);
1580 /* A file name relative to cwd. Make it relative
1581 to the directory of the tags file. */
1582 fdp
->taggedfname
= relative_filename (fn
, tagfiledir
);
1584 fdp
->usecharno
= TRUE
; /* use char position when making tags */
1586 fdp
->written
= FALSE
; /* not written on tags file yet */
1589 curfdp
= fdhead
; /* the current file description */
1593 /* If not Ctags, and if this is not metasource and if it contained no #line
1594 directives, we can write the tags and free all nodes pointing to
1597 && curfdp
->usecharno
/* no #line directives in this file */
1598 && !curfdp
->lang
->metasource
)
1602 /* Look for the head of the sublist relative to this file. See add_node
1603 for the structure of the node tree. */
1605 for (np
= nodehead
; np
!= NULL
; prev
= np
, np
= np
->left
)
1606 if (np
->fdp
== curfdp
)
1609 /* If we generated tags for this file, write and delete them. */
1612 /* This is the head of the last sublist, if any. The following
1613 instructions depend on this being true. */
1614 assert (np
->left
== NULL
);
1616 assert (fdhead
== curfdp
);
1617 assert (last_node
->fdp
== curfdp
);
1618 put_entries (np
); /* write tags for file curfdp->taggedfname */
1619 free_tree (np
); /* remove the written nodes */
1621 nodehead
= NULL
; /* no nodes left */
1623 prev
->left
= NULL
; /* delete the pointer to the sublist */
1629 * This routine sets up the boolean pseudo-functions which work
1630 * by setting boolean flags dependent upon the corresponding character.
1631 * Every char which is NOT in that string is not a white char. Therefore,
1632 * all of the array "_wht" is set to FALSE, and then the elements
1633 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1634 * of a char is TRUE if it is the string "white", else FALSE.
1642 for (i
= 0; i
< CHARS
; i
++)
1643 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1644 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1645 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1646 notinname('\0') = notinname('\n');
1647 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1648 begtoken('\0') = begtoken('\n');
1649 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1650 intoken('\0') = intoken('\n');
1651 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1652 endtoken('\0') = endtoken('\n');
1656 * This routine opens the specified file and calls the function
1657 * which finds the function and type definitions.
1664 language
*lang
= curfdp
->lang
;
1665 Lang_function
*parser
= NULL
;
1667 /* If user specified a language, use it. */
1668 if (lang
!= NULL
&& lang
->function
!= NULL
)
1670 parser
= lang
->function
;
1673 /* Else try to guess the language given the file name. */
1676 lang
= get_language_from_filename (curfdp
->infname
, TRUE
);
1677 if (lang
!= NULL
&& lang
->function
!= NULL
)
1679 curfdp
->lang
= lang
;
1680 parser
= lang
->function
;
1684 /* Else look for sharp-bang as the first two characters. */
1686 && readline_internal (&lb
, inf
) > 0
1688 && lb
.buffer
[0] == '#'
1689 && lb
.buffer
[1] == '!')
1693 /* Set lp to point at the first char after the last slash in the
1694 line or, if no slashes, at the first nonblank. Then set cp to
1695 the first successive blank and terminate the string. */
1696 lp
= etags_strrchr (lb
.buffer
+2, '/');
1700 lp
= skip_spaces (lb
.buffer
+ 2);
1701 cp
= skip_non_spaces (lp
);
1704 if (strlen (lp
) > 0)
1706 lang
= get_language_from_interpreter (lp
);
1707 if (lang
!= NULL
&& lang
->function
!= NULL
)
1709 curfdp
->lang
= lang
;
1710 parser
= lang
->function
;
1715 /* We rewind here, even if inf may be a pipe. We fail if the
1716 length of the first line is longer than the pipe block size,
1717 which is unlikely. */
1720 /* Else try to guess the language given the case insensitive file name. */
1723 lang
= get_language_from_filename (curfdp
->infname
, FALSE
);
1724 if (lang
!= NULL
&& lang
->function
!= NULL
)
1726 curfdp
->lang
= lang
;
1727 parser
= lang
->function
;
1731 /* Else try Fortran or C. */
1734 node
*old_last_node
= last_node
;
1736 curfdp
->lang
= get_language_from_langname ("fortran");
1739 if (old_last_node
== last_node
)
1740 /* No Fortran entries found. Try C. */
1742 /* We do not tag if rewind fails.
1743 Only the file name will be recorded in the tags file. */
1745 curfdp
->lang
= get_language_from_langname (cplusplus
? "c++" : "c");
1751 if (!no_line_directive
1752 && curfdp
->lang
!= NULL
&& curfdp
->lang
->metasource
)
1753 /* It may be that this is a bingo.y file, and we already parsed a bingo.c
1754 file, or anyway we parsed a file that is automatically generated from
1755 this one. If this is the case, the bingo.c file contained #line
1756 directives that generated tags pointing to this file. Let's delete
1757 them all before parsing this file, which is the real source. */
1759 fdesc
**fdpp
= &fdhead
;
1760 while (*fdpp
!= NULL
)
1762 && streq ((*fdpp
)->taggedfname
, curfdp
->taggedfname
))
1763 /* We found one of those! We must delete both the file description
1764 and all tags referring to it. */
1766 fdesc
*badfdp
= *fdpp
;
1768 /* Delete the tags referring to badfdp->taggedfname
1769 that were obtained from badfdp->infname. */
1770 invalidate_nodes (badfdp
, &nodehead
);
1772 *fdpp
= badfdp
->next
; /* remove the bad description from the list */
1773 free_fdesc (badfdp
);
1776 fdpp
= &(*fdpp
)->next
; /* advance the list pointer */
1779 assert (parser
!= NULL
);
1781 /* Generic initialisations before reading from file. */
1782 linebuffer_setlen (&filebuf
, 0); /* reset the file buffer */
1784 /* Generic initialisations before parsing file with readline. */
1785 lineno
= 0; /* reset global line number */
1786 charno
= 0; /* reset global char number */
1787 linecharno
= 0; /* reset global char number of line start */
1791 #ifdef ETAGS_REGEXPS
1792 regex_tag_multiline ();
1793 #endif /* ETAGS_REGEXPS */
1798 * Check whether an implicitly named tag should be created,
1799 * then call `pfnote'.
1800 * NAME is a string that is internally copied by this function.
1802 * TAGS format specification
1803 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1804 * The following is explained in some more detail in etc/ETAGS.EBNF.
1806 * make_tag creates tags with "implicit tag names" (unnamed tags)
1807 * if the following are all true, assuming NONAM=" \f\t\n\r()=,;":
1808 * 1. NAME does not contain any of the characters in NONAM;
1809 * 2. LINESTART contains name as either a rightmost, or rightmost but
1810 * one character, substring;
1811 * 3. the character, if any, immediately before NAME in LINESTART must
1812 * be a character in NONAM;
1813 * 4. the character, if any, immediately after NAME in LINESTART must
1814 * also be a character in NONAM.
1816 * The implementation uses the notinname() macro, which recognises the
1817 * characters stored in the string `nonam'.
1818 * etags.el needs to use the same characters that are in NONAM.
1821 make_tag (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1822 char *name
; /* tag name, or NULL if unnamed */
1823 int namelen
; /* tag length */
1824 bool is_func
; /* tag is a function */
1825 char *linestart
; /* start of the line where tag is */
1826 int linelen
; /* length of the line where tag is */
1827 int lno
; /* line number */
1828 long cno
; /* character number */
1830 bool named
= (name
!= NULL
&& namelen
> 0);
1832 if (!CTAGS
&& named
) /* maybe set named to false */
1833 /* Let's try to make an implicit tag name, that is, create an unnamed tag
1834 such that etags.el can guess a name from it. */
1837 register char *cp
= name
;
1839 for (i
= 0; i
< namelen
; i
++)
1840 if (notinname (*cp
++))
1842 if (i
== namelen
) /* rule #1 */
1844 cp
= linestart
+ linelen
- namelen
;
1845 if (notinname (linestart
[linelen
-1]))
1846 cp
-= 1; /* rule #4 */
1847 if (cp
>= linestart
/* rule #2 */
1849 || notinname (cp
[-1])) /* rule #3 */
1850 && strneq (name
, cp
, namelen
)) /* rule #2 */
1851 named
= FALSE
; /* use implicit tag name */
1856 name
= savenstr (name
, namelen
);
1859 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1864 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1865 char *name
; /* tag name, or NULL if unnamed */
1866 bool is_func
; /* tag is a function */
1867 char *linestart
; /* start of the line where tag is */
1868 int linelen
; /* length of the line where tag is */
1869 int lno
; /* line number */
1870 long cno
; /* character number */
1874 if (CTAGS
&& name
== NULL
)
1877 np
= xnew (1, node
);
1879 /* If ctags mode, change name "main" to M<thisfilename>. */
1880 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1882 register char *fp
= etags_strrchr (curfdp
->taggedfname
, '/');
1883 np
->name
= concat ("M", fp
== NULL
? curfdp
->taggedfname
: fp
+ 1, "");
1884 fp
= etags_strrchr (np
->name
, '.');
1885 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
1891 np
->been_warned
= FALSE
;
1893 np
->is_func
= is_func
;
1895 if (np
->fdp
->usecharno
)
1896 /* Our char numbers are 0-base, because of C language tradition?
1897 ctags compatibility? old versions compatibility? I don't know.
1898 Anyway, since emacs's are 1-base we expect etags.el to take care
1899 of the difference. If we wanted to have 1-based numbers, we would
1900 uncomment the +1 below. */
1901 np
->cno
= cno
/* + 1 */ ;
1903 np
->cno
= invalidcharno
;
1904 np
->left
= np
->right
= NULL
;
1905 if (CTAGS
&& !cxref_style
)
1907 if (strlen (linestart
) < 50)
1908 np
->regex
= concat (linestart
, "$", "");
1910 np
->regex
= savenstr (linestart
, 50);
1913 np
->regex
= savenstr (linestart
, linelen
);
1915 add_node (np
, &nodehead
);
1920 * recurse on left children, iterate on right children.
1928 register node
*node_right
= np
->right
;
1929 free_tree (np
->left
);
1930 if (np
->name
!= NULL
)
1940 * delete a file description
1944 register fdesc
*fdp
;
1946 if (fdp
->infname
!= NULL
) free (fdp
->infname
);
1947 if (fdp
->infabsname
!= NULL
) free (fdp
->infabsname
);
1948 if (fdp
->infabsdir
!= NULL
) free (fdp
->infabsdir
);
1949 if (fdp
->taggedfname
!= NULL
) free (fdp
->taggedfname
);
1950 if (fdp
->prop
!= NULL
) free (fdp
->prop
);
1956 * Adds a node to the tree of nodes. In etags mode, sort by file
1957 * name. In ctags mode, sort by tag name. Make no attempt at
1960 * add_node is the only function allowed to add nodes, so it can
1964 add_node (np
, cur_node_p
)
1965 node
*np
, **cur_node_p
;
1968 register node
*cur_node
= *cur_node_p
;
1970 if (cur_node
== NULL
)
1980 /* For each file name, tags are in a linked sublist on the right
1981 pointer. The first tags of different files are a linked list
1982 on the left pointer. last_node points to the end of the last
1984 if (last_node
!= NULL
&& last_node
->fdp
== np
->fdp
)
1986 /* Let's use the same sublist as the last added node. */
1987 assert (last_node
->right
== NULL
);
1988 last_node
->right
= np
;
1991 else if (cur_node
->fdp
== np
->fdp
)
1993 /* Scanning the list we found the head of a sublist which is
1994 good for us. Let's scan this sublist. */
1995 add_node (np
, &cur_node
->right
);
1998 /* The head of this sublist is not good for us. Let's try the
2000 add_node (np
, &cur_node
->left
);
2001 } /* if ETAGS mode */
2006 dif
= strcmp (np
->name
, cur_node
->name
);
2009 * If this tag name matches an existing one, then
2010 * do not add the node, but maybe print a warning.
2014 if (np
->fdp
== cur_node
->fdp
)
2018 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
2019 np
->fdp
->infname
, lineno
, np
->name
);
2020 fprintf (stderr
, "Second entry ignored\n");
2023 else if (!cur_node
->been_warned
&& !no_warnings
)
2027 "Duplicate entry in files %s and %s: %s (Warning only)\n",
2028 np
->fdp
->infname
, cur_node
->fdp
->infname
, np
->name
);
2029 cur_node
->been_warned
= TRUE
;
2034 /* Actually add the node */
2035 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
2036 } /* if CTAGS mode */
2040 * invalidate_nodes ()
2041 * Scan the node tree and invalidate all nodes pointing to the
2042 * given file description (CTAGS case) or free them (ETAGS case).
2045 invalidate_nodes (badfdp
, npp
)
2056 if (np
->left
!= NULL
)
2057 invalidate_nodes (badfdp
, &np
->left
);
2058 if (np
->fdp
== badfdp
)
2060 if (np
->right
!= NULL
)
2061 invalidate_nodes (badfdp
, &np
->right
);
2065 assert (np
->fdp
!= NULL
);
2066 if (np
->fdp
== badfdp
)
2068 *npp
= np
->left
; /* detach the sublist from the list */
2069 np
->left
= NULL
; /* isolate it */
2070 free_tree (np
); /* free it */
2071 invalidate_nodes (badfdp
, npp
);
2074 invalidate_nodes (badfdp
, &np
->left
);
2079 static int total_size_of_entries
__P((node
*));
2080 static int number_len
__P((long));
2082 /* Length of a non-negative number's decimal representation. */
2088 while ((num
/= 10) > 0)
2094 * Return total number of characters that put_entries will output for
2095 * the nodes in the linked list at the right of the specified node.
2096 * This count is irrelevant with etags.el since emacs 19.34 at least,
2097 * but is still supplied for backward compatibility.
2100 total_size_of_entries (np
)
2103 register int total
= 0;
2105 for (; np
!= NULL
; np
= np
->right
)
2108 total
+= strlen (np
->regex
) + 1; /* pat\177 */
2109 if (np
->name
!= NULL
)
2110 total
+= strlen (np
->name
) + 1; /* name\001 */
2111 total
+= number_len ((long) np
->lno
) + 1; /* lno, */
2112 if (np
->cno
!= invalidcharno
) /* cno */
2113 total
+= number_len (np
->cno
);
2114 total
+= 1; /* newline */
2125 static fdesc
*fdp
= NULL
;
2130 /* Output subentries that precede this one */
2132 put_entries (np
->left
);
2134 /* Output this entry */
2143 fprintf (tagf
, "\f\n%s,%d\n",
2144 fdp
->taggedfname
, total_size_of_entries (np
));
2145 fdp
->written
= TRUE
;
2147 fputs (np
->regex
, tagf
);
2148 fputc ('\177', tagf
);
2149 if (np
->name
!= NULL
)
2151 fputs (np
->name
, tagf
);
2152 fputc ('\001', tagf
);
2154 fprintf (tagf
, "%d,", np
->lno
);
2155 if (np
->cno
!= invalidcharno
)
2156 fprintf (tagf
, "%ld", np
->cno
);
2162 if (np
->name
== NULL
)
2163 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
2168 fprintf (stdout
, "%s %s %d\n",
2169 np
->name
, np
->fdp
->taggedfname
, (np
->lno
+ 63) / 64);
2171 fprintf (stdout
, "%-16s %3d %-16s %s\n",
2172 np
->name
, np
->lno
, np
->fdp
->taggedfname
, np
->regex
);
2176 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->fdp
->taggedfname
);
2179 { /* function or #define macro with args */
2180 putc (searchar
, tagf
);
2183 for (sp
= np
->regex
; *sp
; sp
++)
2185 if (*sp
== '\\' || *sp
== searchar
)
2189 putc (searchar
, tagf
);
2192 { /* anything else; text pattern inadequate */
2193 fprintf (tagf
, "%d", np
->lno
);
2198 } /* if this node contains a valid tag */
2200 /* Output subentries that follow this one */
2201 put_entries (np
->right
);
2203 put_entries (np
->left
);
2208 #define C_EXT 0x00fff /* C extensions */
2209 #define C_PLAIN 0x00000 /* C */
2210 #define C_PLPL 0x00001 /* C++ */
2211 #define C_STAR 0x00003 /* C* */
2212 #define C_JAVA 0x00005 /* JAVA */
2213 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
2214 #define YACC 0x10000 /* yacc file */
2217 * The C symbol tables.
2222 st_C_objprot
, st_C_objimpl
, st_C_objend
,
2227 st_C_class
, st_C_template
,
2228 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
2231 static unsigned int hash
__P((const char *, unsigned int));
2232 static struct C_stab_entry
* in_word_set
__P((const char *, unsigned int));
2233 static enum sym_type C_symtype
__P((char *, int, int));
2235 /* Feed stuff between (but not including) %[ and %] lines to:
2236 gperf -c -k 1,3 -o -p -r -t
2238 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2242 while, 0, st_C_ignore
2243 switch, 0, st_C_ignore
2244 return, 0, st_C_ignore
2245 @interface, 0, st_C_objprot
2246 @protocol, 0, st_C_objprot
2247 @implementation,0, st_C_objimpl
2248 @end, 0, st_C_objend
2249 import, C_JAVA, st_C_ignore
2250 package, C_JAVA, st_C_ignore
2251 friend, C_PLPL, st_C_ignore
2252 extends, C_JAVA, st_C_javastruct
2253 implements, C_JAVA, st_C_javastruct
2254 interface, C_JAVA, st_C_struct
2255 class, 0, st_C_class
2256 namespace, C_PLPL, st_C_struct
2257 domain, C_STAR, st_C_struct
2258 union, 0, st_C_struct
2259 struct, 0, st_C_struct
2260 extern, 0, st_C_extern
2262 typedef, 0, st_C_typedef
2263 define, 0, st_C_define
2264 operator, C_PLPL, st_C_operator
2265 template, 0, st_C_template
2266 bool, C_PLPL, st_C_typespec
2267 long, 0, st_C_typespec
2268 short, 0, st_C_typespec
2269 int, 0, st_C_typespec
2270 char, 0, st_C_typespec
2271 float, 0, st_C_typespec
2272 double, 0, st_C_typespec
2273 signed, 0, st_C_typespec
2274 unsigned, 0, st_C_typespec
2275 auto, 0, st_C_typespec
2276 void, 0, st_C_typespec
2277 static, 0, st_C_typespec
2278 const, 0, st_C_typespec
2279 volatile, 0, st_C_typespec
2280 explicit, C_PLPL, st_C_typespec
2281 mutable, C_PLPL, st_C_typespec
2282 typename, C_PLPL, st_C_typespec
2283 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2284 DEFUN, 0, st_C_gnumacro
2285 SYSCALL, 0, st_C_gnumacro
2286 ENTRY, 0, st_C_gnumacro
2287 PSEUDO, 0, st_C_gnumacro
2288 # These are defined inside C functions, so currently they are not met.
2289 # EXFUN used in glibc, DEFVAR_* in emacs.
2290 #EXFUN, 0, st_C_gnumacro
2291 #DEFVAR_, 0, st_C_gnumacro
2293 and replace lines between %< and %> with its output,
2294 then make in_word_set and C_stab_entry static. */
2296 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
2297 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
2298 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2300 #define TOTAL_KEYWORDS 47
2301 #define MIN_WORD_LENGTH 2
2302 #define MAX_WORD_LENGTH 15
2303 #define MIN_HASH_VALUE 18
2304 #define MAX_HASH_VALUE 138
2305 /* maximum key range = 121, duplicates = 0 */
2312 register const char *str
;
2313 register unsigned int len
;
2315 static unsigned char asso_values
[] =
2317 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2318 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2319 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2320 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2321 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2322 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2323 139, 139, 139, 139, 63, 139, 139, 139, 33, 44,
2324 62, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2325 42, 139, 139, 12, 32, 139, 139, 139, 139, 139,
2326 139, 139, 139, 139, 139, 139, 139, 34, 59, 37,
2327 24, 58, 33, 3, 139, 16, 139, 139, 42, 60,
2328 18, 11, 39, 139, 23, 57, 4, 63, 6, 20,
2329 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2330 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2331 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2332 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2333 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2334 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2335 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2336 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2337 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2338 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2339 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2340 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2341 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2342 139, 139, 139, 139, 139, 139
2344 register int hval
= len
;
2350 hval
+= asso_values
[(unsigned char)str
[2]];
2353 hval
+= asso_values
[(unsigned char)str
[0]];
2362 static struct C_stab_entry
*
2363 in_word_set (str
, len
)
2364 register const char *str
;
2365 register unsigned int len
;
2367 static struct C_stab_entry wordlist
[] =
2369 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2370 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2371 {"if", 0, st_C_ignore
},
2372 {""}, {""}, {""}, {""},
2373 {"int", 0, st_C_typespec
},
2375 {"void", 0, st_C_typespec
},
2377 {"interface", C_JAVA
, st_C_struct
},
2379 {"SYSCALL", 0, st_C_gnumacro
},
2381 {"return", 0, st_C_ignore
},
2382 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2383 {"while", 0, st_C_ignore
},
2384 {"auto", 0, st_C_typespec
},
2385 {""}, {""}, {""}, {""}, {""}, {""},
2386 {"float", 0, st_C_typespec
},
2387 {"typedef", 0, st_C_typedef
},
2388 {"typename", C_PLPL
, st_C_typespec
},
2390 {"friend", C_PLPL
, st_C_ignore
},
2391 {"volatile", 0, st_C_typespec
},
2393 {"for", 0, st_C_ignore
},
2394 {"const", 0, st_C_typespec
},
2395 {"import", C_JAVA
, st_C_ignore
},
2397 {"define", 0, st_C_define
},
2398 {"long", 0, st_C_typespec
},
2399 {"implements", C_JAVA
, st_C_javastruct
},
2400 {"signed", 0, st_C_typespec
},
2402 {"extern", 0, st_C_extern
},
2403 {"extends", C_JAVA
, st_C_javastruct
},
2405 {"mutable", C_PLPL
, st_C_typespec
},
2406 {"template", 0, st_C_template
},
2407 {"short", 0, st_C_typespec
},
2408 {"bool", C_PLPL
, st_C_typespec
},
2409 {"char", 0, st_C_typespec
},
2410 {"class", 0, st_C_class
},
2411 {"operator", C_PLPL
, st_C_operator
},
2413 {"switch", 0, st_C_ignore
},
2415 {"ENTRY", 0, st_C_gnumacro
},
2417 {"package", C_JAVA
, st_C_ignore
},
2418 {"union", 0, st_C_struct
},
2419 {"@end", 0, st_C_objend
},
2420 {"struct", 0, st_C_struct
},
2421 {"namespace", C_PLPL
, st_C_struct
},
2423 {"domain", C_STAR
, st_C_struct
},
2424 {"@interface", 0, st_C_objprot
},
2425 {"PSEUDO", 0, st_C_gnumacro
},
2426 {"double", 0, st_C_typespec
},
2428 {"@protocol", 0, st_C_objprot
},
2430 {"static", 0, st_C_typespec
},
2432 {"DEFUN", 0, st_C_gnumacro
},
2433 {""}, {""}, {""}, {""},
2434 {"explicit", C_PLPL
, st_C_typespec
},
2435 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2436 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2438 {"enum", 0, st_C_enum
},
2440 {"unsigned", 0, st_C_typespec
},
2441 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2442 {"@implementation",0, st_C_objimpl
}
2445 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2447 register int key
= hash (str
, len
);
2449 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2451 register const char *s
= wordlist
[key
].name
;
2453 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
2454 return &wordlist
[key
];
2461 static enum sym_type
2462 C_symtype (str
, len
, c_ext
)
2467 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2469 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2476 * C functions and variables are recognized using a simple
2477 * finite automaton. fvdef is its state variable.
2481 fvnone
, /* nothing seen */
2482 fdefunkey
, /* Emacs DEFUN keyword seen */
2483 fdefunname
, /* Emacs DEFUN name seen */
2484 foperator
, /* func: operator keyword seen (cplpl) */
2485 fvnameseen
, /* function or variable name seen */
2486 fstartlist
, /* func: just after open parenthesis */
2487 finlist
, /* func: in parameter list */
2488 flistseen
, /* func: after parameter list */
2489 fignore
, /* func: before open brace */
2490 vignore
/* var-like: ignore until ';' */
2493 static bool fvextern
; /* func or var: extern keyword seen; */
2496 * typedefs are recognized using a simple finite automaton.
2497 * typdef is its state variable.
2501 tnone
, /* nothing seen */
2502 tkeyseen
, /* typedef keyword seen */
2503 ttypeseen
, /* defined type seen */
2504 tinbody
, /* inside typedef body */
2505 tend
, /* just before typedef tag */
2506 tignore
/* junk after typedef tag */
2510 * struct-like structures (enum, struct and union) are recognized
2511 * using another simple finite automaton. `structdef' is its state
2516 snone
, /* nothing seen yet,
2517 or in struct body if cblev > 0 */
2518 skeyseen
, /* struct-like keyword seen */
2519 stagseen
, /* struct-like tag seen */
2520 sintemplate
, /* inside template (ignore) */
2521 scolonseen
/* colon seen after struct-like tag */
2525 * When objdef is different from onone, objtag is the name of the class.
2527 static char *objtag
= "<uninited>";
2530 * Yet another little state machine to deal with preprocessor lines.
2534 dnone
, /* nothing seen */
2535 dsharpseen
, /* '#' seen as first char on line */
2536 ddefineseen
, /* '#' and 'define' seen */
2537 dignorerest
/* ignore rest of line */
2541 * State machine for Objective C protocols and implementations.
2542 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2546 onone
, /* nothing seen */
2547 oprotocol
, /* @interface or @protocol seen */
2548 oimplementation
, /* @implementations seen */
2549 otagseen
, /* class name seen */
2550 oparenseen
, /* parenthesis before category seen */
2551 ocatseen
, /* category name seen */
2552 oinbody
, /* in @implementation body */
2553 omethodsign
, /* in @implementation body, after +/- */
2554 omethodtag
, /* after method name */
2555 omethodcolon
, /* after method colon */
2556 omethodparm
, /* after method parameter */
2557 oignore
/* wait for @end */
2562 * Use this structure to keep info about the token read, and how it
2563 * should be tagged. Used by the make_C_tag function to build a tag.
2567 char *line
; /* string containing the token */
2568 int offset
; /* where the token starts in LINE */
2569 int length
; /* token length */
2571 The previous members can be used to pass strings around for generic
2572 purposes. The following ones specifically refer to creating tags. In this
2573 case the token contained here is the pattern that will be used to create a
2576 bool valid
; /* do not create a tag; the token should be
2577 invalidated whenever a state machine is
2578 reset prematurely */
2579 bool named
; /* create a named tag */
2580 int lineno
; /* source line number of tag */
2581 long linepos
; /* source char number of tag */
2582 } token
; /* latest token read */
2585 * Variables and functions for dealing with nested structures.
2586 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2588 static void pushclass_above
__P((int, char *, int));
2589 static void popclass_above
__P((int));
2590 static void write_classname
__P((linebuffer
*, char *qualifier
));
2593 char **cname
; /* nested class names */
2594 int *cblev
; /* nested class curly brace level */
2595 int nl
; /* class nesting level (elements used) */
2596 int size
; /* length of the array */
2597 } cstack
; /* stack for nested declaration tags */
2598 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2599 #define nestlev (cstack.nl)
2600 /* After struct keyword or in struct body, not inside a nested function. */
2601 #define instruct (structdef == snone && nestlev > 0 \
2602 && cblev == cstack.cblev[nestlev-1] + 1)
2605 pushclass_above (cblev
, str
, len
)
2612 popclass_above (cblev
);
2614 if (nl
>= cstack
.size
)
2616 int size
= cstack
.size
*= 2;
2617 xrnew (cstack
.cname
, size
, char *);
2618 xrnew (cstack
.cblev
, size
, int);
2620 assert (nl
== 0 || cstack
.cblev
[nl
-1] < cblev
);
2621 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2622 cstack
.cblev
[nl
] = cblev
;
2627 popclass_above (cblev
)
2632 for (nl
= cstack
.nl
- 1;
2633 nl
>= 0 && cstack
.cblev
[nl
] >= cblev
;
2636 if (cstack
.cname
[nl
] != NULL
)
2637 free (cstack
.cname
[nl
]);
2643 write_classname (cn
, qualifier
)
2648 int qlen
= strlen (qualifier
);
2650 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2654 cn
->buffer
[0] = '\0';
2658 len
= strlen (cstack
.cname
[0]);
2659 linebuffer_setlen (cn
, len
);
2660 strcpy (cn
->buffer
, cstack
.cname
[0]);
2662 for (i
= 1; i
< cstack
.nl
; i
++)
2667 s
= cstack
.cname
[i
];
2672 linebuffer_setlen (cn
, len
);
2673 strncat (cn
->buffer
, qualifier
, qlen
);
2674 strncat (cn
->buffer
, s
, slen
);
2679 static bool consider_token
__P((char *, int, int, int *, int, int, bool *));
2680 static void make_C_tag
__P((bool));
2684 * checks to see if the current token is at the start of a
2685 * function or variable, or corresponds to a typedef, or
2686 * is a struct/union/enum tag, or #define, or an enum constant.
2688 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2689 * with args. C_EXTP points to which language we are looking at.
2700 consider_token (str
, len
, c
, c_extp
, cblev
, parlev
, is_func_or_var
)
2701 register char *str
; /* IN: token pointer */
2702 register int len
; /* IN: token length */
2703 register int c
; /* IN: first char after the token */
2704 int *c_extp
; /* IN, OUT: C extensions mask */
2705 int cblev
; /* IN: curly brace level */
2706 int parlev
; /* IN: parenthesis level */
2707 bool *is_func_or_var
; /* OUT: function or variable found */
2709 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2710 structtype is the type of the preceding struct-like keyword, and
2711 structcblev is the curly brace level where it has been seen. */
2712 static enum sym_type structtype
;
2713 static int structcblev
;
2714 static enum sym_type toktype
;
2717 toktype
= C_symtype (str
, len
, *c_extp
);
2720 * Advance the definedef state machine.
2725 /* We're not on a preprocessor line. */
2726 if (toktype
== st_C_gnumacro
)
2733 if (toktype
== st_C_define
)
2735 definedef
= ddefineseen
;
2739 definedef
= dignorerest
;
2744 * Make a tag for any macro, unless it is a constant
2745 * and constantypedefs is FALSE.
2747 definedef
= dignorerest
;
2748 *is_func_or_var
= (c
== '(');
2749 if (!*is_func_or_var
&& !constantypedefs
)
2756 error ("internal error: definedef value.", (char *)NULL
);
2765 if (toktype
== st_C_typedef
)
2787 if (structdef
== snone
&& fvdef
== fvnone
)
2806 * This structdef business is NOT invoked when we are ctags and the
2807 * file is plain C. This is because a struct tag may have the same
2808 * name as another tag, and this loses with ctags.
2812 case st_C_javastruct
:
2813 if (structdef
== stagseen
)
2814 structdef
= scolonseen
;
2818 if ((*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2820 && definedef
== dnone
&& structdef
== snone
2821 && typdef
== tnone
&& fvdef
== fvnone
)
2822 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2823 if (toktype
== st_C_template
)
2830 && (typdef
== tkeyseen
2831 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2833 structdef
= skeyseen
;
2834 structtype
= toktype
;
2835 structcblev
= cblev
;
2840 if (structdef
== skeyseen
)
2842 structdef
= stagseen
;
2846 if (typdef
!= tnone
)
2849 /* Detect Objective C constructs. */
2859 objdef
= oimplementation
;
2863 case oimplementation
:
2864 /* Save the class tag for functions or variables defined inside. */
2865 objtag
= savenstr (str
, len
);
2869 /* Save the class tag for categories. */
2870 objtag
= savenstr (str
, len
);
2872 *is_func_or_var
= TRUE
;
2876 *is_func_or_var
= TRUE
;
2883 objdef
= omethodtag
;
2884 linebuffer_setlen (&token_name
, len
);
2885 strncpy (token_name
.buffer
, str
, len
);
2886 token_name
.buffer
[len
] = '\0';
2892 objdef
= omethodparm
;
2897 objdef
= omethodtag
;
2898 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
2899 strncat (token_name
.buffer
, str
, len
);
2904 if (toktype
== st_C_objend
)
2906 /* Memory leakage here: the string pointed by objtag is
2907 never released, because many tests would be needed to
2908 avoid breaking on incorrect input code. The amount of
2909 memory leaked here is the sum of the lengths of the
2917 /* A function, variable or enum constant? */
2941 *is_func_or_var
= TRUE
;
2945 && structdef
== snone
2946 && structtype
== st_C_enum
&& cblev
> structcblev
)
2947 return TRUE
; /* enum constant */
2953 fvdef
= fdefunname
; /* GNU macro */
2954 *is_func_or_var
= TRUE
;
2957 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
2958 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
2963 if (strneq (str
+len
-10, "::operator", 10))
2965 if (*c_extp
& C_AUTO
) /* automatic detection of C++ */
2966 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2968 *is_func_or_var
= TRUE
;
2971 if (cblev
> 0 && !instruct
)
2973 fvdef
= fvnameseen
; /* function or variable */
2974 *is_func_or_var
= TRUE
;
2985 * C_entries often keeps pointers to tokens or lines which are older than
2986 * the line currently read. By keeping two line buffers, and switching
2987 * them at end of line, it is possible to use those pointers.
2995 #define current_lb_is_new (newndx == curndx)
2996 #define switch_line_buffers() (curndx = 1 - curndx)
2998 #define curlb (lbs[curndx].lb)
2999 #define newlb (lbs[newndx].lb)
3000 #define curlinepos (lbs[curndx].linepos)
3001 #define newlinepos (lbs[newndx].linepos)
3003 #define plainc ((c_ext & C_EXT) == C_PLAIN)
3004 #define cplpl (c_ext & C_PLPL)
3005 #define cjava ((c_ext & C_JAVA) == C_JAVA)
3007 #define CNL_SAVE_DEFINEDEF() \
3009 curlinepos = charno; \
3010 readline (&curlb, inf); \
3011 lp = curlb.buffer; \
3018 CNL_SAVE_DEFINEDEF(); \
3019 if (savetoken.valid) \
3021 token = savetoken; \
3022 savetoken.valid = FALSE; \
3024 definedef = dnone; \
3032 /* This function should never be called when token.valid is FALSE, but
3033 we must protect against invalid input or internal errors. */
3034 if (!DEBUG
&& !token
.valid
)
3038 make_tag (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
3039 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
3040 else /* this case is optimised away if !DEBUG */
3041 make_tag (concat ("INVALID TOKEN:-->", token_name
.buffer
, ""),
3042 token_name
.len
+ 17, isfun
, token
.line
,
3043 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
3045 token
.valid
= FALSE
;
3051 * This routine finds functions, variables, typedefs,
3052 * #define's, enum constants and struct/union/enum definitions in
3053 * C syntax and adds them to the list.
3056 C_entries (c_ext
, inf
)
3057 int c_ext
; /* extension of C */
3058 FILE *inf
; /* input file */
3060 register char c
; /* latest char read; '\0' for end of line */
3061 register char *lp
; /* pointer one beyond the character `c' */
3062 int curndx
, newndx
; /* indices for current and new lb */
3063 register int tokoff
; /* offset in line of start of current token */
3064 register int toklen
; /* length of current token */
3065 char *qualifier
; /* string used to qualify names */
3066 int qlen
; /* length of qualifier */
3067 int cblev
; /* current curly brace level */
3068 int parlev
; /* current parenthesis level */
3069 int typdefcblev
; /* cblev where a typedef struct body begun */
3070 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
3071 bool yacc_rules
; /* in the rules part of a yacc file */
3072 struct tok savetoken
; /* token saved during preprocessor handling */
3075 linebuffer_init (&lbs
[0].lb
);
3076 linebuffer_init (&lbs
[1].lb
);
3077 if (cstack
.size
== 0)
3079 cstack
.size
= (DEBUG
) ? 1 : 4;
3081 cstack
.cname
= xnew (cstack
.size
, char *);
3082 cstack
.cblev
= xnew (cstack
.size
, int);
3085 tokoff
= toklen
= typdefcblev
= 0; /* keep compiler quiet */
3086 curndx
= newndx
= 0;
3090 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
3091 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
3093 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
3094 token
.valid
= savetoken
.valid
= FALSE
;
3098 { qualifier
= "."; qlen
= 1; }
3100 { qualifier
= "::"; qlen
= 2; }
3108 /* If we're at the end of the line, the next character is a
3109 '\0'; don't skip it, because it's the thing that tells us
3110 to read the next line. */
3131 /* Newlines inside comments do not end macro definitions in
3133 CNL_SAVE_DEFINEDEF ();
3146 /* Newlines inside strings do not end macro definitions
3147 in traditional cpp, even though compilers don't
3148 usually accept them. */
3149 CNL_SAVE_DEFINEDEF ();
3159 /* Hmmm, something went wrong. */
3188 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
3201 else if (/* cplpl && */ *lp
== '/')
3209 if ((c_ext
& YACC
) && *lp
== '%')
3211 /* Entering or exiting rules section in yacc file. */
3213 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
3214 typdef
= tnone
; structdef
= snone
;
3215 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
3217 yacc_rules
= !yacc_rules
;
3223 if (definedef
== dnone
)
3226 bool cpptoken
= TRUE
;
3228 /* Look back on this line. If all blanks, or nonblanks
3229 followed by an end of comment, this is a preprocessor
3231 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
3234 if (*cp
== '*' && *(cp
+1) == '/')
3243 definedef
= dsharpseen
;
3244 } /* if (definedef == dnone) */
3250 /* Consider token only if some involved conditions are satisfied. */
3251 if (typdef
!= tignore
3252 && definedef
!= dignorerest
3254 && structdef
!= sintemplate
3255 && (definedef
!= dnone
3256 || structdef
!= scolonseen
))
3262 if (c
== ':' && *lp
== ':' && begtoken (lp
[1]))
3263 /* This handles :: in the middle,
3264 but not at the beginning of an identifier.
3265 Also, space-separated :: is not recognised. */
3267 if (c_ext
& C_AUTO
) /* automatic detection of C++ */
3268 c_ext
= (c_ext
| C_PLPL
) & ~C_AUTO
;
3272 goto still_in_token
;
3276 bool funorvar
= FALSE
;
3279 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
3280 &c_ext
, cblev
, parlev
, &funorvar
))
3282 if (fvdef
== foperator
)
3285 lp
= skip_spaces (lp
-1);
3289 && !iswhite (*lp
) && *lp
!= '(')
3292 toklen
+= lp
- oldlp
;
3294 token
.named
= FALSE
;
3296 && nestlev
> 0 && definedef
== dnone
)
3297 /* in struct body */
3299 write_classname (&token_name
, qualifier
);
3300 linebuffer_setlen (&token_name
,
3301 token_name
.len
+qlen
+toklen
);
3302 strcat (token_name
.buffer
, qualifier
);
3303 strncat (token_name
.buffer
,
3304 newlb
.buffer
+ tokoff
, toklen
);
3307 else if (objdef
== ocatseen
)
3308 /* Objective C category */
3310 int len
= strlen (objtag
) + 2 + toklen
;
3311 linebuffer_setlen (&token_name
, len
);
3312 strcpy (token_name
.buffer
, objtag
);
3313 strcat (token_name
.buffer
, "(");
3314 strncat (token_name
.buffer
,
3315 newlb
.buffer
+ tokoff
, toklen
);
3316 strcat (token_name
.buffer
, ")");
3319 else if (objdef
== omethodtag
3320 || objdef
== omethodparm
)
3321 /* Objective C method */
3325 else if (fvdef
== fdefunname
)
3326 /* GNU DEFUN and similar macros */
3328 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3332 /* Rewrite the tag so that emacs lisp DEFUNs
3333 can be found by their elisp name */
3340 linebuffer_setlen (&token_name
, len
);
3341 strncpy (token_name
.buffer
,
3342 newlb
.buffer
+ off
, len
);
3343 token_name
.buffer
[len
] = '\0';
3346 if (token_name
.buffer
[len
] == '_')
3347 token_name
.buffer
[len
] = '-';
3348 token
.named
= defun
;
3352 linebuffer_setlen (&token_name
, toklen
);
3353 strncpy (token_name
.buffer
,
3354 newlb
.buffer
+ tokoff
, toklen
);
3355 token_name
.buffer
[toklen
] = '\0';
3356 /* Name macros and members. */
3357 token
.named
= (structdef
== stagseen
3358 || typdef
== ttypeseen
3361 && definedef
== dignorerest
)
3363 && definedef
== dnone
3364 && structdef
== snone
3367 token
.lineno
= lineno
;
3368 token
.offset
= tokoff
;
3369 token
.length
= toklen
;
3370 token
.line
= newlb
.buffer
;
3371 token
.linepos
= newlinepos
;
3374 if (definedef
== dnone
3375 && (fvdef
== fvnameseen
3376 || fvdef
== foperator
3377 || structdef
== stagseen
3379 || typdef
== ttypeseen
3380 || objdef
!= onone
))
3382 if (current_lb_is_new
)
3383 switch_line_buffers ();
3385 else if (definedef
!= dnone
3386 || fvdef
== fdefunname
3388 make_C_tag (funorvar
);
3392 } /* if (endtoken (c)) */
3393 else if (intoken (c
))
3399 } /* if (midtoken) */
3400 else if (begtoken (c
))
3411 if (plainc
|| declarations
)
3413 make_C_tag (TRUE
); /* a function */
3421 if (structdef
== stagseen
&& !cjava
)
3423 popclass_above (cblev
);
3431 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3433 tokoff
= lp
- 1 - newlb
.buffer
;
3438 } /* if (begtoken) */
3439 } /* if must look at token */
3442 /* Detect end of line, colon, comma, semicolon and various braces
3443 after having handled a token.*/
3447 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3449 make_C_tag (FALSE
); /* a yacc function */
3452 if (definedef
!= dnone
)
3458 make_C_tag (TRUE
); /* an Objective C class */
3462 objdef
= omethodcolon
;
3463 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3464 strcat (token_name
.buffer
, ":");
3467 if (structdef
== stagseen
)
3469 structdef
= scolonseen
;
3472 /* Should be useless, but may be work as a safety net. */
3473 if (cplpl
&& fvdef
== flistseen
)
3475 make_C_tag (TRUE
); /* a function */
3481 if (definedef
!= dnone
)
3487 make_C_tag (FALSE
); /* a typedef */
3497 if (typdef
== tignore
|| cplpl
)
3501 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3502 || (members
&& instruct
))
3503 make_C_tag (FALSE
); /* a variable */
3506 token
.valid
= FALSE
;
3510 && (typdef
== tnone
|| (typdef
!= tignore
&& instruct
)))
3511 make_C_tag (TRUE
); /* a function declaration */
3517 && cplpl
&& structdef
== stagseen
)
3518 make_C_tag (FALSE
); /* forward declaration */
3520 token
.valid
= FALSE
;
3521 } /* switch (fvdef) */
3527 if (structdef
== stagseen
)
3531 if (definedef
!= dnone
)
3537 make_C_tag (TRUE
); /* an Objective C method */
3553 case fvnameseen
: /* a variable */
3554 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3555 || (members
&& instruct
))
3558 case flistseen
: /* a function */
3559 if ((declarations
&& typdef
== tnone
&& !instruct
)
3560 || (members
&& typdef
!= tignore
&& instruct
))
3562 make_C_tag (TRUE
); /* a function declaration */
3565 else if (!declarations
)
3567 token
.valid
= FALSE
;
3572 if (structdef
== stagseen
)
3576 if (definedef
!= dnone
)
3578 if (structdef
== stagseen
)
3585 make_C_tag (FALSE
); /* a typedef */
3597 if ((members
&& cblev
== 1)
3598 || (globals
&& cblev
== 0
3599 && (!fvextern
|| declarations
)))
3600 make_C_tag (FALSE
); /* a variable */
3609 if (definedef
!= dnone
)
3611 if (objdef
== otagseen
&& parlev
== 0)
3612 objdef
= oparenseen
;
3616 if (typdef
== ttypeseen
3620 /* This handles constructs like:
3621 typedef void OperatorFun (int fun); */
3638 if (definedef
!= dnone
)
3640 if (objdef
== ocatseen
&& parlev
== 1)
3642 make_C_tag (TRUE
); /* an Objective C category */
3656 || typdef
== ttypeseen
))
3659 make_C_tag (FALSE
); /* a typedef */
3662 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3666 if (definedef
!= dnone
)
3668 if (typdef
== ttypeseen
)
3670 /* Whenever typdef is set to tinbody (currently only
3671 here), typdefcblev should be set to cblev. */
3673 typdefcblev
= cblev
;
3678 make_C_tag (TRUE
); /* a function */
3687 make_C_tag (TRUE
); /* an Objective C class */
3692 make_C_tag (TRUE
); /* an Objective C method */
3696 /* Neutralize `extern "C" {' grot. */
3697 if (cblev
== 0 && structdef
== snone
&& nestlev
== 0
3705 case skeyseen
: /* unnamed struct */
3706 pushclass_above (cblev
, NULL
, 0);
3709 case stagseen
: /* named struct or enum */
3710 case scolonseen
: /* a class */
3711 pushclass_above (cblev
, token
.line
+token
.offset
, token
.length
);
3713 make_C_tag (FALSE
); /* a struct or enum */
3719 if (definedef
!= dnone
)
3721 if (fvdef
== fstartlist
)
3723 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3724 token
.valid
= FALSE
;
3728 if (definedef
!= dnone
)
3730 if (!ignoreindent
&& lp
== newlb
.buffer
+ 1)
3733 token
.valid
= FALSE
;
3734 cblev
= 0; /* reset curly brace level if first column */
3735 parlev
= 0; /* also reset paren level, just in case... */
3740 token
.valid
= FALSE
; /* something gone amiss, token unreliable */
3741 popclass_above (cblev
);
3743 /* Only if typdef == tinbody is typdefcblev significant. */
3744 if (typdef
== tinbody
&& cblev
<= typdefcblev
)
3746 assert (cblev
== typdefcblev
);
3751 if (definedef
!= dnone
)
3761 if ((members
&& cblev
== 1)
3762 || (globals
&& cblev
== 0 && (!fvextern
|| declarations
)))
3763 make_C_tag (FALSE
); /* a variable */
3770 if (cplpl
&& structdef
== stagseen
)
3772 structdef
= sintemplate
;
3777 if (structdef
== sintemplate
)
3779 structdef
= stagseen
;
3785 if (objdef
== oinbody
&& cblev
== 0)
3787 objdef
= omethodsign
;
3792 case '#': case '~': case '&': case '%': case '/': case '|':
3793 case '^': case '!': case '.': case '?': case ']':
3794 if (definedef
!= dnone
)
3796 /* These surely cannot follow a function tag in C. */
3809 if (objdef
== otagseen
)
3811 make_C_tag (TRUE
); /* an Objective C class */
3814 /* If a macro spans multiple lines don't reset its state. */
3816 CNL_SAVE_DEFINEDEF ();
3822 } /* while not eof */
3824 free (lbs
[0].lb
.buffer
);
3825 free (lbs
[1].lb
.buffer
);
3829 * Process either a C++ file or a C file depending on the setting
3833 default_C_entries (inf
)
3836 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
3839 /* Always do plain C. */
3841 plain_C_entries (inf
)
3847 /* Always do C++. */
3849 Cplusplus_entries (inf
)
3852 C_entries (C_PLPL
, inf
);
3855 /* Always do Java. */
3860 C_entries (C_JAVA
, inf
);
3868 C_entries (C_STAR
, inf
);
3871 /* Always do Yacc. */
3876 C_entries (YACC
, inf
);
3880 /* Useful macros. */
3881 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3882 for (; /* loop initialization */ \
3883 !feof (file_pointer) /* loop test */ \
3884 && /* instructions at start of loop */ \
3885 (readline (&line_buffer, file_pointer), \
3886 char_pointer = line_buffer.buffer, \
3889 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
3890 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \
3891 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \
3892 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */
3895 * Read a file, but do no processing. This is used to do regexp
3896 * matching on files that have no language defined.
3899 just_read_file (inf
)
3902 register char *dummy
;
3904 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
3909 /* Fortran parsing */
3911 static void F_takeprec
__P((void));
3912 static void F_getit
__P((FILE *));
3917 dbp
= skip_spaces (dbp
);
3921 dbp
= skip_spaces (dbp
);
3922 if (strneq (dbp
, "(*)", 3))
3927 if (!ISDIGIT (*dbp
))
3929 --dbp
; /* force failure */
3934 while (ISDIGIT (*dbp
));
3943 dbp
= skip_spaces (dbp
);
3946 readline (&lb
, inf
);
3951 dbp
= skip_spaces (dbp
);
3953 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
3955 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
3957 make_tag (dbp
, cp
-dbp
, TRUE
,
3958 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3963 Fortran_functions (inf
)
3966 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3969 dbp
++; /* Ratfor escape to fortran */
3970 dbp
= skip_spaces (dbp
);
3973 switch (lowcase (*dbp
))
3976 if (nocase_tail ("integer"))
3980 if (nocase_tail ("real"))
3984 if (nocase_tail ("logical"))
3988 if (nocase_tail ("complex") || nocase_tail ("character"))
3992 if (nocase_tail ("double"))
3994 dbp
= skip_spaces (dbp
);
3997 if (nocase_tail ("precision"))
4003 dbp
= skip_spaces (dbp
);
4006 switch (lowcase (*dbp
))
4009 if (nocase_tail ("function"))
4013 if (nocase_tail ("subroutine"))
4017 if (nocase_tail ("entry"))
4021 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
4023 dbp
= skip_spaces (dbp
);
4024 if (*dbp
== '\0') /* assume un-named */
4025 make_tag ("blockdata", 9, TRUE
,
4026 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
4028 F_getit (inf
); /* look for name */
4039 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.int> (1998)
4042 static void Ada_getit
__P((FILE *, char *));
4044 /* Once we are positioned after an "interesting" keyword, let's get
4045 the real tag value necessary. */
4047 Ada_getit (inf
, name_qualifier
)
4049 char *name_qualifier
;
4057 dbp
= skip_spaces (dbp
);
4059 || (dbp
[0] == '-' && dbp
[1] == '-'))
4061 readline (&lb
, inf
);
4064 switch (lowcase(*dbp
))
4067 if (nocase_tail ("body"))
4069 /* Skipping body of procedure body or package body or ....
4070 resetting qualifier to body instead of spec. */
4071 name_qualifier
= "/b";
4076 /* Skipping type of task type or protected type ... */
4077 if (nocase_tail ("type"))
4084 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
4089 dbp
= skip_spaces (dbp
);
4092 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
4100 name
= concat (dbp
, name_qualifier
, "");
4102 make_tag (name
, strlen (name
), TRUE
,
4103 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4115 bool inquote
= FALSE
;
4116 bool skip_till_semicolumn
= FALSE
;
4118 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4120 while (*dbp
!= '\0')
4122 /* Skip a string i.e. "abcd". */
4123 if (inquote
|| (*dbp
== '"'))
4125 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
4130 continue; /* advance char */
4135 break; /* advance line */
4139 /* Skip comments. */
4140 if (dbp
[0] == '-' && dbp
[1] == '-')
4141 break; /* advance line */
4143 /* Skip character enclosed in single quote i.e. 'a'
4144 and skip single quote starting an attribute i.e. 'Image. */
4153 if (skip_till_semicolumn
)
4156 skip_till_semicolumn
= FALSE
;
4158 continue; /* advance char */
4161 /* Search for beginning of a token. */
4162 if (!begtoken (*dbp
))
4165 continue; /* advance char */
4168 /* We are at the beginning of a token. */
4169 switch (lowcase(*dbp
))
4172 if (!packages_only
&& nocase_tail ("function"))
4173 Ada_getit (inf
, "/f");
4175 break; /* from switch */
4176 continue; /* advance char */
4178 if (!packages_only
&& nocase_tail ("procedure"))
4179 Ada_getit (inf
, "/p");
4180 else if (nocase_tail ("package"))
4181 Ada_getit (inf
, "/s");
4182 else if (nocase_tail ("protected")) /* protected type */
4183 Ada_getit (inf
, "/t");
4185 break; /* from switch */
4186 continue; /* advance char */
4189 if (typedefs
&& !packages_only
&& nocase_tail ("use"))
4191 /* when tagging types, avoid tagging use type Pack.Typename;
4192 for this, we will skip everything till a ; */
4193 skip_till_semicolumn
= TRUE
;
4194 continue; /* advance char */
4198 if (!packages_only
&& nocase_tail ("task"))
4199 Ada_getit (inf
, "/k");
4200 else if (typedefs
&& !packages_only
&& nocase_tail ("type"))
4202 Ada_getit (inf
, "/t");
4203 while (*dbp
!= '\0')
4207 break; /* from switch */
4208 continue; /* advance char */
4211 /* Look for the end of the token. */
4212 while (!endtoken (*dbp
))
4215 } /* advance char */
4216 } /* advance line */
4221 * Unix and microcontroller assembly tag handling
4222 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
4223 * Idea by Bob Weiner, Motorola Inc. (1994)
4231 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4233 /* If first char is alphabetic or one of [_.$], test for colon
4234 following identifier. */
4235 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4237 /* Read past label. */
4239 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4241 if (*cp
== ':' || iswhite (*cp
))
4242 /* Found end of label, so copy it and add it to the table. */
4243 make_tag (lb
.buffer
, cp
- lb
.buffer
, TRUE
,
4244 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4252 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
4253 * Perl variable names: /^(my|local).../
4254 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
4255 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
4256 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
4259 Perl_functions (inf
)
4262 char *package
= savestr ("main"); /* current package name */
4265 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4269 if (LOOKING_AT (cp
, "package"))
4272 get_tag (cp
, &package
);
4274 else if (LOOKING_AT (cp
, "sub"))
4279 while (!notinname (*cp
))
4282 continue; /* nothing found */
4283 if ((pos
= etags_strchr (sp
, ':')) != NULL
4284 && pos
< cp
&& pos
[1] == ':')
4285 /* The name is already qualified. */
4286 make_tag (sp
, cp
- sp
, TRUE
,
4287 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4291 char savechar
, *name
;
4295 name
= concat (package
, "::", sp
);
4297 make_tag (name
, strlen(name
), TRUE
,
4298 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4302 else if (globals
) /* only if we are tagging global vars */
4304 /* Skip a qualifier, if any. */
4305 bool qual
= LOOKING_AT (cp
, "my") || LOOKING_AT (cp
, "local");
4306 /* After "my" or "local", but before any following paren or space. */
4307 char *varstart
= cp
;
4309 if (qual
/* should this be removed? If yes, how? */
4310 && (*cp
== '$' || *cp
== '@' || *cp
== '%'))
4315 while (ISALNUM (*cp
) || *cp
== '_');
4319 /* Should be examining a variable list at this point;
4320 could insist on seeing an open parenthesis. */
4321 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4327 make_tag (varstart
, cp
- varstart
, FALSE
,
4328 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4336 * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4337 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4338 * More ideas by seb bacon <seb@jamkit.com> (2002)
4341 Python_functions (inf
)
4346 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4348 cp
= skip_spaces (cp
);
4349 if (LOOKING_AT (cp
, "def") || LOOKING_AT (cp
, "class"))
4352 while (!notinname (*cp
) && *cp
!= ':')
4354 make_tag (name
, cp
- name
, TRUE
,
4355 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4364 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4365 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4366 * - /^[ \t]*define\(\"[^\"]+/
4367 * Only with --members:
4368 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4369 * Idea by Diez B. Roggisch (2001)
4375 register char *cp
, *name
;
4376 bool search_identifier
= FALSE
;
4378 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4380 cp
= skip_spaces (cp
);
4382 if (search_identifier
4385 while (!notinname (*cp
))
4387 make_tag (name
, cp
- name
, TRUE
,
4388 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4389 search_identifier
= FALSE
;
4391 else if (LOOKING_AT (cp
, "function"))
4394 cp
= skip_spaces (cp
+1);
4398 while (!notinname (*cp
))
4400 make_tag (name
, cp
- name
, TRUE
,
4401 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4404 search_identifier
= TRUE
;
4406 else if (LOOKING_AT (cp
, "class"))
4411 while (*cp
!= '\0' && !iswhite (*cp
))
4413 make_tag (name
, cp
- name
, FALSE
,
4414 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4417 search_identifier
= TRUE
;
4419 else if (strneq (cp
, "define", 6)
4420 && (cp
= skip_spaces (cp
+6))
4422 && (*cp
== '"' || *cp
== '\''))
4426 while (*cp
!= quote
&& *cp
!= '\0')
4428 make_tag (name
, cp
- name
, FALSE
,
4429 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4432 && LOOKING_AT (cp
, "var")
4436 while (!notinname(*cp
))
4438 make_tag (name
, cp
- name
, FALSE
,
4439 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4446 * Cobol tag functions
4447 * We could look for anything that could be a paragraph name.
4448 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4449 * Idea by Corny de Souza (1993)
4452 Cobol_paragraphs (inf
)
4455 register char *bp
, *ep
;
4457 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4463 /* If eoln, compiler option or comment ignore whole line. */
4464 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4467 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4470 make_tag (bp
, ep
- bp
, TRUE
,
4471 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4478 * Ideas by Assar Westerlund <assar@sics.se> (2001)
4481 Makefile_targets (inf
)
4486 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4488 if (*bp
== '\t' || *bp
== '#')
4490 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4492 if (*bp
== ':' || (globals
&& *bp
== '='))
4493 make_tag (lb
.buffer
, bp
- lb
.buffer
, TRUE
,
4494 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4501 * Original code by Mosur K. Mohan (1989)
4503 * Locates tags for procedures & functions. Doesn't do any type- or
4504 * var-definitions. It does look for the keyword "extern" or
4505 * "forward" immediately following the procedure statement; if found,
4506 * the tag is skipped.
4509 Pascal_functions (inf
)
4512 linebuffer tline
; /* mostly copied from C_entries */
4514 int save_lineno
, namelen
, taglen
;
4517 bool /* each of these flags is TRUE iff: */
4518 incomment
, /* point is inside a comment */
4519 inquote
, /* point is inside '..' string */
4520 get_tagname
, /* point is after PROCEDURE/FUNCTION
4521 keyword, so next item = potential tag */
4522 found_tag
, /* point is after a potential tag */
4523 inparms
, /* point is within parameter-list */
4524 verify_tag
; /* point has passed the parm-list, so the
4525 next token will determine whether this
4526 is a FORWARD/EXTERN to be ignored, or
4527 whether it is a real tag */
4529 save_lcno
= save_lineno
= namelen
= taglen
= 0; /* keep compiler quiet */
4530 name
= NULL
; /* keep compiler quiet */
4533 linebuffer_init (&tline
);
4535 incomment
= inquote
= FALSE
;
4536 found_tag
= FALSE
; /* have a proc name; check if extern */
4537 get_tagname
= FALSE
; /* found "procedure" keyword */
4538 inparms
= FALSE
; /* found '(' after "proc" */
4539 verify_tag
= FALSE
; /* check if "extern" is ahead */
4542 while (!feof (inf
)) /* long main loop to get next char */
4545 if (c
== '\0') /* if end of line */
4547 readline (&lb
, inf
);
4551 if (!((found_tag
&& verify_tag
)
4553 c
= *dbp
++; /* only if don't need *dbp pointing
4554 to the beginning of the name of
4555 the procedure or function */
4559 if (c
== '}') /* within { } comments */
4561 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4578 inquote
= TRUE
; /* found first quote */
4580 case '{': /* found open { comment */
4584 if (*dbp
== '*') /* found open (* comment */
4589 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4592 case ')': /* end of parms list */
4597 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4604 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4606 /* Check if this is an "extern" declaration. */
4609 if (lowcase (*dbp
== 'e'))
4611 if (nocase_tail ("extern")) /* superfluous, really! */
4617 else if (lowcase (*dbp
) == 'f')
4619 if (nocase_tail ("forward")) /* check for forward reference */
4625 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4629 make_tag (name
, namelen
, TRUE
,
4630 tline
.buffer
, taglen
, save_lineno
, save_lcno
);
4634 if (get_tagname
) /* grab name of proc or fn */
4641 /* Find block name. */
4642 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4645 /* Save all values for later tagging. */
4646 linebuffer_setlen (&tline
, lb
.len
);
4647 strcpy (tline
.buffer
, lb
.buffer
);
4648 save_lineno
= lineno
;
4649 save_lcno
= linecharno
;
4650 name
= tline
.buffer
+ (dbp
- lb
.buffer
);
4652 taglen
= cp
- lb
.buffer
+ 1;
4654 dbp
= cp
; /* set dbp to e-o-token */
4655 get_tagname
= FALSE
;
4659 /* And proceed to check for "extern". */
4661 else if (!incomment
&& !inquote
&& !found_tag
)
4663 /* Check for proc/fn keywords. */
4664 switch (lowcase (c
))
4667 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4671 if (nocase_tail ("unction"))
4676 } /* while not eof */
4678 free (tline
.buffer
);
4683 * Lisp tag functions
4684 * look for (def or (DEF, quote or QUOTE
4687 static void L_getit
__P((void));
4692 if (*dbp
== '\'') /* Skip prefix quote */
4694 else if (*dbp
== '(')
4697 /* Try to skip "(quote " */
4698 if (!LOOKING_AT (dbp
, "quote") && !LOOKING_AT (dbp
, "QUOTE"))
4699 /* Ok, then skip "(" before name in (defstruct (foo)) */
4700 dbp
= skip_spaces (dbp
);
4702 get_tag (dbp
, NULL
);
4706 Lisp_functions (inf
)
4709 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4714 if (strneq (dbp
+1, "def", 3) || strneq (dbp
+1, "DEF", 3))
4716 dbp
= skip_non_spaces (dbp
);
4717 dbp
= skip_spaces (dbp
);
4722 /* Check for (foo::defmumble name-defined ... */
4725 while (!notinname (*dbp
) && *dbp
!= ':');
4730 while (*dbp
== ':');
4732 if (strneq (dbp
, "def", 3) || strneq (dbp
, "DEF", 3))
4734 dbp
= skip_non_spaces (dbp
);
4735 dbp
= skip_spaces (dbp
);
4745 * Postscript tag functions
4746 * Just look for lines where the first character is '/'
4747 * Also look at "defineps" for PSWrap
4749 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4750 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4753 Postscript_functions (inf
)
4756 register char *bp
, *ep
;
4758 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4763 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4766 make_tag (bp
, ep
- bp
, TRUE
,
4767 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4769 else if (LOOKING_AT (bp
, "defineps"))
4776 * Scheme tag functions
4777 * look for (def... xyzzy
4779 * (def ... ((...(xyzzy ....
4781 * Original code by Ken Haase (1985?)
4785 Scheme_functions (inf
)
4790 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4792 if (strneq (bp
, "(def", 4) || strneq (bp
, "(DEF", 4))
4794 bp
= skip_non_spaces (bp
+4);
4795 /* Skip over open parens and white space */
4796 while (notinname (*bp
))
4800 if (LOOKING_AT (bp
, "(SET!") || LOOKING_AT (bp
, "(set!"))
4806 /* Find tags in TeX and LaTeX input files. */
4808 /* TEX_toktab is a table of TeX control sequences that define tags.
4809 * Each entry records one such control sequence.
4811 * Original code from who knows whom.
4813 * Stefan Monnier (2002)
4816 static linebuffer
*TEX_toktab
= NULL
; /* Table with tag tokens */
4818 /* Default set of control sequences to put into TEX_toktab.
4819 The value of environment var TEXTAGS is prepended to this. */
4820 static char *TEX_defenv
= "\
4821 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4822 :part:appendix:entry:index:def\
4823 :newcommand:renewcommand:newenvironment:renewenvironment";
4825 static void TEX_mode
__P((FILE *));
4826 static void TEX_decode_env
__P((char *, char *));
4828 static char TEX_esc
= '\\';
4829 static char TEX_opgrp
= '{';
4830 static char TEX_clgrp
= '}';
4833 * TeX/LaTeX scanning loop.
4842 /* Select either \ or ! as escape character. */
4845 /* Initialize token table once from environment. */
4846 if (TEX_toktab
== NULL
)
4847 TEX_decode_env ("TEXTAGS", TEX_defenv
);
4849 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4851 /* Look at each TEX keyword in line. */
4854 /* Look for a TEX escape. */
4855 while (*cp
++ != TEX_esc
)
4856 if (cp
[-1] == '\0' || cp
[-1] == '%')
4859 for (key
= TEX_toktab
; key
->buffer
!= NULL
; key
++)
4860 if (strneq (cp
, key
->buffer
, key
->len
))
4863 int namelen
, linelen
;
4866 cp
= skip_spaces (cp
+ key
->len
);
4867 if (*cp
== TEX_opgrp
)
4873 (!iswhite (*p
) && *p
!= '#' &&
4874 *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
);
4879 if (!opgrp
|| *p
== TEX_clgrp
)
4881 while (*p
!= '\0' && *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
)
4883 linelen
= p
- lb
.buffer
+ 1;
4885 make_tag (cp
, namelen
, TRUE
,
4886 lb
.buffer
, linelen
, lineno
, linecharno
);
4887 goto tex_next_line
; /* We only tag a line once */
4895 #define TEX_LESC '\\'
4896 #define TEX_SESC '!'
4898 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4899 chars accordingly. */
4906 while ((c
= getc (inf
)) != EOF
)
4908 /* Skip to next line if we hit the TeX comment char. */
4912 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
4928 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4929 No attempt is made to correct the situation. */
4933 /* Read environment and prepend it to the default string.
4934 Build token table. */
4936 TEX_decode_env (evarname
, defenv
)
4940 register char *env
, *p
;
4943 /* Append default string to environment. */
4944 env
= getenv (evarname
);
4950 env
= concat (oldenv
, defenv
, "");
4953 /* Allocate a token table */
4954 for (len
= 1, p
= env
; p
;)
4955 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
4957 TEX_toktab
= xnew (len
, linebuffer
);
4959 /* Unpack environment string into token table. Be careful about */
4960 /* zero-length strings (leading ':', "::" and trailing ':') */
4961 for (i
= 0; *env
!= '\0';)
4963 p
= etags_strchr (env
, ':');
4964 if (!p
) /* End of environment string. */
4965 p
= env
+ strlen (env
);
4967 { /* Only non-zero strings. */
4968 TEX_toktab
[i
].buffer
= savenstr (env
, p
- env
);
4969 TEX_toktab
[i
].len
= p
- env
;
4976 TEX_toktab
[i
].buffer
= NULL
; /* Mark end of table. */
4977 TEX_toktab
[i
].len
= 0;
4984 /* Texinfo support. Dave Love, Mar. 2000. */
4990 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4991 if (LOOKING_AT (cp
, "@node"))
4994 while (*cp
!= '\0' && *cp
!= ',')
4996 make_tag (start
, cp
- start
, TRUE
,
4997 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5002 /* Similar to LOOKING_AT but does not use notinname, does not skip */
5003 #define LOOKING_AT_NOCASE(cp, kw) /* kw is a constant string */ \
5004 (strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
5005 && ((cp) += sizeof(kw)-1)) /* skip spaces */
5009 * Contents of <title>, <h1>, <h2>, <h3> are tags.
5010 * Contents of <a name=xxx> are tags with name xxx.
5012 * Francesco Potortì, 2002.
5018 bool getnext
= FALSE
; /* next text outside of HTML tags is a tag */
5019 bool skiptag
= FALSE
; /* skip to the end of the current HTML tag */
5020 bool intag
= FALSE
; /* inside an html tag, looking for ID= */
5021 bool inanchor
= FALSE
; /* when INTAG, is an anchor, look for NAME= */
5025 linebuffer_setlen (&token_name
, 0); /* no name in buffer */
5027 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
5028 for (;;) /* loop on the same line */
5030 if (skiptag
) /* skip HTML tag */
5032 while (*dbp
!= '\0' && *dbp
!= '>')
5038 continue; /* look on the same line */
5040 break; /* go to next line */
5043 else if (intag
) /* look for "name=" or "id=" */
5045 while (*dbp
!= '\0' && *dbp
!= '>'
5046 && lowcase (*dbp
) != 'n' && lowcase (*dbp
) != 'i')
5049 break; /* go to next line */
5054 continue; /* look on the same line */
5056 if ((inanchor
&& LOOKING_AT_NOCASE (dbp
, "name="))
5057 || LOOKING_AT_NOCASE (dbp
, "id="))
5059 bool quoted
= (dbp
[0] == '"');
5062 for (end
= ++dbp
; *end
!= '\0' && *end
!= '"'; end
++)
5065 for (end
= dbp
; *end
!= '\0' && intoken (*end
); end
++)
5067 linebuffer_setlen (&token_name
, end
- dbp
);
5068 strncpy (token_name
.buffer
, dbp
, end
- dbp
);
5069 token_name
.buffer
[end
- dbp
] = '\0';
5072 intag
= FALSE
; /* we found what we looked for */
5073 skiptag
= TRUE
; /* skip to the end of the tag */
5074 getnext
= TRUE
; /* then grab the text */
5075 continue; /* look on the same line */
5080 else if (getnext
) /* grab next tokens and tag them */
5082 dbp
= skip_spaces (dbp
);
5084 break; /* go to next line */
5088 inanchor
= (lowcase (dbp
[1]) == 'a' && !intoken (dbp
[2]));
5089 continue; /* look on the same line */
5092 for (end
= dbp
+ 1; *end
!= '\0' && *end
!= '<'; end
++)
5094 make_tag (token_name
.buffer
, token_name
.len
, TRUE
,
5095 dbp
, end
- dbp
, lineno
, linecharno
);
5096 linebuffer_setlen (&token_name
, 0); /* no name in buffer */
5098 break; /* go to next line */
5101 else /* look for an interesting HTML tag */
5103 while (*dbp
!= '\0' && *dbp
!= '<')
5106 break; /* go to next line */
5108 if (lowcase (dbp
[1]) == 'a' && !intoken (dbp
[2]))
5111 continue; /* look on the same line */
5113 else if (LOOKING_AT_NOCASE (dbp
, "<title>")
5114 || LOOKING_AT_NOCASE (dbp
, "<h1>")
5115 || LOOKING_AT_NOCASE (dbp
, "<h2>")
5116 || LOOKING_AT_NOCASE (dbp
, "<h3>"))
5120 continue; /* look on the same line */
5131 * Assumes that the predicate or rule starts at column 0.
5132 * Only the first clause of a predicate or rule is added.
5133 * Original code by Sunichirou Sugou (1989)
5134 * Rewritten by Anders Lindgren (1996)
5136 static int prolog_pr
__P((char *, char *));
5137 static void prolog_skip_comment
__P((linebuffer
*, FILE *));
5138 static int prolog_atom
__P((char *, int));
5141 Prolog_functions (inf
)
5152 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5154 if (cp
[0] == '\0') /* Empty line */
5156 else if (iswhite (cp
[0])) /* Not a predicate */
5158 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
5159 prolog_skip_comment (&lb
, inf
);
5160 else if ((len
= prolog_pr (cp
, last
)) > 0)
5162 /* Predicate or rule. Store the function name so that we
5163 only generate a tag for the first clause. */
5165 last
= xnew(len
+ 1, char);
5166 else if (len
+ 1 > allocated
)
5167 xrnew (last
, len
+ 1, char);
5168 allocated
= len
+ 1;
5169 strncpy (last
, cp
, len
);
5177 prolog_skip_comment (plb
, inf
)
5185 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
5186 if (cp
[0] == '*' && cp
[1] == '/')
5188 readline (plb
, inf
);
5194 * A predicate or rule definition is added if it matches:
5195 * <beginning of line><Prolog Atom><whitespace>(
5196 * or <beginning of line><Prolog Atom><whitespace>:-
5198 * It is added to the tags database if it doesn't match the
5199 * name of the previous clause header.
5201 * Return the size of the name of the predicate or rule, or 0 if no
5207 char *last
; /* Name of last clause. */
5212 pos
= prolog_atom (s
, 0);
5217 pos
= skip_spaces (s
+ pos
) - s
;
5220 || (s
[pos
] == '(' && (pos
+= 1))
5221 || (s
[pos
] == ':' && s
[pos
+ 1] == '-' && (pos
+= 2)))
5222 && (last
== NULL
/* save only the first clause */
5223 || len
!= strlen (last
)
5224 || !strneq (s
, last
, len
)))
5226 make_tag (s
, len
, TRUE
, s
, pos
, lineno
, linecharno
);
5234 * Consume a Prolog atom.
5235 * Return the number of bytes consumed, or -1 if there was an error.
5237 * A prolog atom, in this context, could be one of:
5238 * - An alphanumeric sequence, starting with a lower case letter.
5239 * - A quoted arbitrary string. Single quotes can escape themselves.
5240 * Backslash quotes everything.
5243 prolog_atom (s
, pos
)
5251 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
5253 /* The atom is unquoted. */
5255 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
5259 return pos
- origpos
;
5261 else if (s
[pos
] == '\'')
5272 pos
++; /* A double quote */
5274 else if (s
[pos
] == '\0')
5275 /* Multiline quoted atoms are ignored. */
5277 else if (s
[pos
] == '\\')
5279 if (s
[pos
+1] == '\0')
5286 return pos
- origpos
;
5294 * Support for Erlang
5296 * Generates tags for functions, defines, and records.
5297 * Assumes that Erlang functions start at column 0.
5298 * Original code by Anders Lindgren (1996)
5300 static int erlang_func
__P((char *, char *));
5301 static void erlang_attribute
__P((char *));
5302 static int erlang_atom
__P((char *));
5305 Erlang_functions (inf
)
5316 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5318 if (cp
[0] == '\0') /* Empty line */
5320 else if (iswhite (cp
[0])) /* Not function nor attribute */
5322 else if (cp
[0] == '%') /* comment */
5324 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
5326 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
5328 erlang_attribute (cp
);
5331 else if ((len
= erlang_func (cp
, last
)) > 0)
5334 * Function. Store the function name so that we only
5335 * generates a tag for the first clause.
5338 last
= xnew (len
+ 1, char);
5339 else if (len
+ 1 > allocated
)
5340 xrnew (last
, len
+ 1, char);
5341 allocated
= len
+ 1;
5342 strncpy (last
, cp
, len
);
5350 * A function definition is added if it matches:
5351 * <beginning of line><Erlang Atom><whitespace>(
5353 * It is added to the tags database if it doesn't match the
5354 * name of the previous clause header.
5356 * Return the size of the name of the function, or 0 if no function
5360 erlang_func (s
, last
)
5362 char *last
; /* Name of last clause. */
5367 pos
= erlang_atom (s
);
5372 pos
= skip_spaces (s
+ pos
) - s
;
5374 /* Save only the first clause. */
5377 || len
!= (int)strlen (last
)
5378 || !strneq (s
, last
, len
)))
5380 make_tag (s
, len
, TRUE
, s
, pos
, lineno
, linecharno
);
5389 * Handle attributes. Currently, tags are generated for defines
5392 * They are on the form:
5393 * -define(foo, bar).
5394 * -define(Foo(M, N), M+N).
5395 * -record(graph, {vtab = notable, cyclic = true}).
5398 erlang_attribute (s
)
5403 if ((LOOKING_AT (cp
, "-define") || LOOKING_AT (cp
, "-record"))
5406 int len
= erlang_atom (skip_spaces (cp
));
5408 make_tag (cp
, len
, TRUE
, s
, cp
+ len
- s
, lineno
, linecharno
);
5415 * Consume an Erlang atom (or variable).
5416 * Return the number of bytes consumed, or -1 if there was an error.
5424 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
5426 /* The atom is unquoted. */
5429 while (ISALNUM (s
[pos
]) || s
[pos
] == '_');
5431 else if (s
[pos
] == '\'')
5433 for (pos
++; s
[pos
] != '\''; pos
++)
5434 if (s
[pos
] == '\0' /* multiline quoted atoms are ignored */
5435 || (s
[pos
] == '\\' && s
[++pos
] == '\0'))
5444 #ifdef ETAGS_REGEXPS
5446 static char *scan_separators
__P((char *));
5447 static void add_regex
__P((char *, language
*));
5448 static char *substitute
__P((char *, char *, struct re_registers
*));
5451 * Take a string like "/blah/" and turn it into "blah", verifying
5452 * that the first and last characters are the same, and handling
5453 * quoted separator characters. Actually, stops on the occurrence of
5454 * an unquoted separator. Also process \t, \n, etc. and turn into
5455 * appropriate characters. Works in place. Null terminates name string.
5456 * Returns pointer to terminating separator, or NULL for
5457 * unterminated regexps.
5460 scan_separators (name
)
5464 char *copyto
= name
;
5465 bool quoted
= FALSE
;
5467 for (++name
; *name
!= '\0'; ++name
)
5473 case 'a': *copyto
++ = '\007'; break; /* BEL (bell) */
5474 case 'b': *copyto
++ = '\b'; break; /* BS (back space) */
5475 case 'd': *copyto
++ = 0177; break; /* DEL (delete) */
5476 case 'e': *copyto
++ = 033; break; /* ESC (delete) */
5477 case 'f': *copyto
++ = '\f'; break; /* FF (form feed) */
5478 case 'n': *copyto
++ = '\n'; break; /* NL (new line) */
5479 case 'r': *copyto
++ = '\r'; break; /* CR (carriage return) */
5480 case 't': *copyto
++ = '\t'; break; /* TAB (horizontal tab) */
5481 case 'v': *copyto
++ = '\v'; break; /* VT (vertical tab) */
5487 /* Something else is quoted, so preserve the quote. */
5495 else if (*name
== '\\')
5497 else if (*name
== sep
)
5503 name
= NULL
; /* signal unterminated regexp */
5505 /* Terminate copied string. */
5510 /* Look at the argument of --regex or --no-regex and do the right
5511 thing. Same for each line of a regexp file. */
5513 analyse_regex (regex_arg
)
5516 if (regex_arg
== NULL
)
5518 free_regexps (); /* --no-regex: remove existing regexps */
5522 /* A real --regexp option or a line in a regexp file. */
5523 switch (regex_arg
[0])
5525 /* Comments in regexp file or null arg to --regex. */
5531 /* Read a regex file. This is recursive and may result in a
5532 loop, which will stop when the file descriptors are exhausted. */
5536 linebuffer regexbuf
;
5537 char *regexfile
= regex_arg
+ 1;
5539 /* regexfile is a file containing regexps, one per line. */
5540 regexfp
= fopen (regexfile
, "r");
5541 if (regexfp
== NULL
)
5546 linebuffer_init (®exbuf
);
5547 while (readline_internal (®exbuf
, regexfp
) > 0)
5548 analyse_regex (regexbuf
.buffer
);
5549 free (regexbuf
.buffer
);
5554 /* Regexp to be used for a specific language only. */
5558 char *lang_name
= regex_arg
+ 1;
5561 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5564 error ("unterminated language name in regex: %s", regex_arg
);
5568 lang
= get_language_from_langname (lang_name
);
5571 add_regex (cp
, lang
);
5575 /* Regexp to be used for any language. */
5577 add_regex (regex_arg
, NULL
);
5582 /* Separate the regexp pattern, compile it,
5583 and care for optional name and modifiers. */
5585 add_regex (regexp_pattern
, lang
)
5586 char *regexp_pattern
;
5589 static struct re_pattern_buffer zeropattern
;
5590 char sep
, *pat
, *name
, *modifiers
;
5592 struct re_pattern_buffer
*patbuf
;
5595 force_explicit_name
= TRUE
, /* do not use implicit tag names */
5596 ignore_case
= FALSE
, /* case is significant */
5597 multi_line
= FALSE
, /* matches are done one line at a time */
5598 single_line
= FALSE
; /* dot does not match newline */
5601 if (strlen(regexp_pattern
) < 3)
5603 error ("null regexp", (char *)NULL
);
5606 sep
= regexp_pattern
[0];
5607 name
= scan_separators (regexp_pattern
);
5610 error ("%s: unterminated regexp", regexp_pattern
);
5615 error ("null name for regexp \"%s\"", regexp_pattern
);
5618 modifiers
= scan_separators (name
);
5619 if (modifiers
== NULL
) /* no terminating separator --> no name */
5625 modifiers
+= 1; /* skip separator */
5627 /* Parse regex modifiers. */
5628 for (; modifiers
[0] != '\0'; modifiers
++)
5629 switch (modifiers
[0])
5632 if (modifiers
== name
)
5633 error ("forcing explicit tag name but no name, ignoring", NULL
);
5634 force_explicit_name
= TRUE
;
5644 need_filebuf
= TRUE
;
5649 wrongmod
[0] = modifiers
[0];
5651 error ("invalid regexp modifier `%s', ignoring", wrongmod
);
5656 patbuf
= xnew (1, struct re_pattern_buffer
);
5657 *patbuf
= zeropattern
;
5660 static char lc_trans
[CHARS
];
5662 for (i
= 0; i
< CHARS
; i
++)
5663 lc_trans
[i
] = lowcase (i
);
5664 patbuf
->translate
= lc_trans
; /* translation table to fold case */
5668 pat
= concat ("^", regexp_pattern
, ""); /* anchor to beginning of line */
5670 pat
= regexp_pattern
;
5673 re_set_syntax (RE_SYNTAX_EMACS
| RE_DOT_NEWLINE
);
5675 re_set_syntax (RE_SYNTAX_EMACS
);
5677 err
= re_compile_pattern (pat
, strlen (regexp_pattern
), patbuf
);
5682 error ("%s while compiling pattern", err
);
5687 p_head
= xnew (1, regexp
);
5688 p_head
->pattern
= savestr (regexp_pattern
);
5689 p_head
->p_next
= rp
;
5690 p_head
->lang
= lang
;
5691 p_head
->pat
= patbuf
;
5692 p_head
->name
= savestr (name
);
5693 p_head
->error_signaled
= FALSE
;
5694 p_head
->force_explicit_name
= force_explicit_name
;
5695 p_head
->ignore_case
= ignore_case
;
5696 p_head
->multi_line
= multi_line
;
5700 * Do the substitutions indicated by the regular expression and
5704 substitute (in
, out
, regs
)
5706 struct re_registers
*regs
;
5709 int size
, dig
, diglen
;
5712 size
= strlen (out
);
5714 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5715 if (out
[size
- 1] == '\\')
5716 fatal ("pattern error in \"%s\"", out
);
5717 for (t
= etags_strchr (out
, '\\');
5719 t
= etags_strchr (t
+ 2, '\\'))
5723 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5729 /* Allocate space and do the substitutions. */
5730 result
= xnew (size
+ 1, char);
5732 for (t
= result
; *out
!= '\0'; out
++)
5733 if (*out
== '\\' && ISDIGIT (*++out
))
5736 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5737 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5744 assert (t
<= result
+ size
&& t
- result
== (int)strlen (result
));
5749 /* Deallocate all regexps. */
5754 while (p_head
!= NULL
)
5756 rp
= p_head
->p_next
;
5757 free (p_head
->pattern
);
5758 free (p_head
->name
);
5766 * Reads the whole file as a single string from `filebuf' and looks for
5767 * multi-line regular expressions, creating tags on matches.
5768 * readline already dealt with normal regexps.
5770 * Idea by Ben Wing <ben@666.com> (2002).
5773 regex_tag_multiline ()
5775 char *buffer
= filebuf
.buffer
;
5779 for (rp
= p_head
; rp
!= NULL
; rp
= rp
->p_next
)
5783 if (!rp
->multi_line
)
5784 continue; /* skip normal regexps */
5786 /* Generic initialisations before parsing file from memory. */
5787 lineno
= 1; /* reset global line number */
5788 charno
= 0; /* reset global char number */
5789 linecharno
= 0; /* reset global char number of line start */
5791 /* Only use generic regexps or those for the current language. */
5792 if (rp
->lang
!= NULL
&& rp
->lang
!= curfdp
->lang
)
5795 while (match
>= 0 && match
< filebuf
.len
)
5797 match
= re_search (rp
->pat
, buffer
, filebuf
.len
, charno
,
5798 filebuf
.len
- match
, &rp
->regs
);
5803 if (!rp
->error_signaled
)
5805 error ("regexp stack overflow while matching \"%s\"",
5807 rp
->error_signaled
= TRUE
;
5814 if (match
== rp
->regs
.end
[0])
5816 if (!rp
->error_signaled
)
5818 error ("regexp matches the empty string: \"%s\"",
5820 rp
->error_signaled
= TRUE
;
5822 match
= -3; /* exit from while loop */
5826 /* Match occurred. Construct a tag. */
5827 while (charno
< rp
->regs
.end
[0])
5828 if (buffer
[charno
++] == '\n')
5829 lineno
++, linecharno
= charno
;
5831 if (name
[0] != '\0')
5832 /* Make a named tag. */
5833 name
= substitute (buffer
, rp
->name
, &rp
->regs
);
5834 if (rp
->force_explicit_name
)
5835 /* Force explicit tag name, if a name is there. */
5836 pfnote (name
, TRUE
, buffer
+ linecharno
,
5837 charno
- linecharno
+ 1, lineno
, linecharno
);
5839 make_tag (name
, strlen (name
), TRUE
, buffer
+ linecharno
,
5840 charno
- linecharno
+ 1, lineno
, linecharno
);
5847 #endif /* ETAGS_REGEXPS */
5854 register int len
= 0;
5856 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
5858 if (*cp
== '\0' && !intoken (dbp
[len
]))
5867 get_tag (bp
, namepp
)
5871 register char *cp
= bp
;
5875 /* Go till you get to white space or a syntactic break */
5876 for (cp
= bp
+ 1; !notinname (*cp
); cp
++)
5878 make_tag (bp
, cp
- bp
, TRUE
,
5879 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5883 *namepp
= savenstr (bp
, cp
- bp
);
5887 * Read a line of text from `stream' into `lbp', excluding the
5888 * newline or CR-NL, if any. Return the number of characters read from
5889 * `stream', which is the length of the line including the newline.
5891 * On DOS or Windows we do not count the CR character, if any before the
5892 * NL, in the returned length; this mirrors the behavior of Emacs on those
5893 * platforms (for text files, it translates CR-NL to NL as it reads in the
5896 * If multi-line regular expressions are requested, each line read is
5897 * appended to `filebuf'.
5900 readline_internal (lbp
, stream
)
5902 register FILE *stream
;
5904 char *buffer
= lbp
->buffer
;
5905 register char *p
= lbp
->buffer
;
5906 register char *pend
;
5909 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
5913 register int c
= getc (stream
);
5916 /* We're at the end of linebuffer: expand it. */
5918 xrnew (buffer
, lbp
->size
, char);
5919 p
+= buffer
- lbp
->buffer
;
5920 pend
= buffer
+ lbp
->size
;
5921 lbp
->buffer
= buffer
;
5931 if (p
> buffer
&& p
[-1] == '\r')
5935 /* Assume CRLF->LF translation will be performed by Emacs
5936 when loading this file, so CRs won't appear in the buffer.
5937 It would be cleaner to compensate within Emacs;
5938 however, Emacs does not know how many CRs were deleted
5939 before any given point in the file. */
5954 lbp
->len
= p
- buffer
;
5956 if (need_filebuf
/* we need filebuf for multi-line regexps */
5957 && chars_deleted
> 0) /* not at EOF */
5959 while (filebuf
.size
<= filebuf
.len
+ lbp
->len
+ 1) /* +1 for \n */
5961 /* Expand filebuf. */
5963 xrnew (filebuf
.buffer
, filebuf
.size
, char);
5965 strncpy (filebuf
.buffer
+ filebuf
.len
, lbp
->buffer
, lbp
->len
);
5966 filebuf
.len
+= lbp
->len
;
5967 filebuf
.buffer
[filebuf
.len
++] = '\n';
5968 filebuf
.buffer
[filebuf
.len
] = '\0';
5971 return lbp
->len
+ chars_deleted
;
5975 * Like readline_internal, above, but in addition try to match the
5976 * input line against relevant regular expressions and manage #line
5980 readline (lbp
, stream
)
5986 linecharno
= charno
; /* update global char number of line start */
5987 result
= readline_internal (lbp
, stream
); /* read line */
5988 lineno
+= 1; /* increment global line number */
5989 charno
+= result
; /* increment global char number */
5991 /* Honour #line directives. */
5992 if (!no_line_directive
)
5994 static bool discard_until_line_directive
;
5996 /* Check whether this is a #line directive. */
5997 if (result
> 12 && strneq (lbp
->buffer
, "#line ", 6))
6001 if (DEBUG
) start
= 0; /* shut up the compiler */
6002 if (sscanf (lbp
->buffer
, "#line %d \"%n", &lno
, &start
) == 1)
6004 char *endp
= lbp
->buffer
+ start
;
6007 while ((endp
= etags_strchr (endp
, '"')) != NULL
6008 && endp
[-1] == '\\')
6011 /* Ok, this is a real #line directive. Let's deal with it. */
6013 char *taggedabsname
; /* absolute name of original file */
6014 char *taggedfname
; /* name of original file as given */
6015 char *name
; /* temp var */
6017 discard_until_line_directive
= FALSE
; /* found it */
6018 name
= lbp
->buffer
+ start
;
6020 canonicalize_filename (name
); /* for DOS */
6021 taggedabsname
= absolute_filename (name
, curfdp
->infabsdir
);
6022 if (filename_is_absolute (name
)
6023 || filename_is_absolute (curfdp
->infname
))
6024 taggedfname
= savestr (taggedabsname
);
6026 taggedfname
= relative_filename (taggedabsname
,tagfiledir
);
6028 if (streq (curfdp
->taggedfname
, taggedfname
))
6029 /* The #line directive is only a line number change. We
6030 deal with this afterwards. */
6033 /* The tags following this #line directive should be
6034 attributed to taggedfname. In order to do this, set
6035 curfdp accordingly. */
6037 fdesc
*fdp
; /* file description pointer */
6039 /* Go look for a file description already set up for the
6040 file indicated in the #line directive. If there is
6041 one, use it from now until the next #line
6043 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
6044 if (streq (fdp
->infname
, curfdp
->infname
)
6045 && streq (fdp
->taggedfname
, taggedfname
))
6046 /* If we remove the second test above (after the &&)
6047 then all entries pertaining to the same file are
6048 coalesced in the tags file. If we use it, then
6049 entries pertaining to the same file but generated
6050 from different files (via #line directives) will
6051 go into separate sections in the tags file. These
6052 alternatives look equivalent. The first one
6053 destroys some apparently useless information. */
6059 /* Else, if we already tagged the real file, skip all
6060 input lines until the next #line directive. */
6061 if (fdp
== NULL
) /* not found */
6062 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
6063 if (streq (fdp
->infabsname
, taggedabsname
))
6065 discard_until_line_directive
= TRUE
;
6069 /* Else create a new file description and use that from
6070 now on, until the next #line directive. */
6071 if (fdp
== NULL
) /* not found */
6074 fdhead
= xnew (1, fdesc
);
6075 *fdhead
= *curfdp
; /* copy curr. file description */
6077 fdhead
->infname
= savestr (curfdp
->infname
);
6078 fdhead
->infabsname
= savestr (curfdp
->infabsname
);
6079 fdhead
->infabsdir
= savestr (curfdp
->infabsdir
);
6080 fdhead
->taggedfname
= taggedfname
;
6081 fdhead
->usecharno
= FALSE
;
6082 fdhead
->prop
= NULL
;
6083 fdhead
->written
= FALSE
;
6087 free (taggedabsname
);
6089 readline (lbp
, stream
);
6091 } /* if a real #line directive */
6092 } /* if #line is followed by a a number */
6093 } /* if line begins with "#line " */
6095 /* If we are here, no #line directive was found. */
6096 if (discard_until_line_directive
)
6100 /* Do a tail recursion on ourselves, thus discarding the contents
6101 of the line buffer. */
6102 readline (lbp
, stream
);
6106 discard_until_line_directive
= FALSE
;
6109 } /* if #line directives should be considered */
6111 #ifdef ETAGS_REGEXPS
6117 /* Match against relevant regexps. */
6119 for (rp
= p_head
; rp
!= NULL
; rp
= rp
->p_next
)
6121 /* Only use generic regexps or those for the current language.
6122 Also do not use multiline regexps, which is the job of
6123 regex_tag_multiline. */
6124 if ((rp
->lang
!= NULL
&& rp
->lang
!= fdhead
->lang
)
6128 match
= re_match (rp
->pat
, lbp
->buffer
, lbp
->len
, 0, &rp
->regs
);
6133 if (!rp
->error_signaled
)
6135 error ("regexp stack overflow while matching \"%s\"",
6137 rp
->error_signaled
= TRUE
;
6144 /* Empty string matched. */
6145 if (!rp
->error_signaled
)
6147 error ("regexp matches the empty string: \"%s\"", rp
->pattern
);
6148 rp
->error_signaled
= TRUE
;
6152 /* Match occurred. Construct a tag. */
6154 if (name
[0] != '\0')
6155 /* Make a named tag. */
6156 name
= substitute (lbp
->buffer
, rp
->name
, &rp
->regs
);
6157 if (rp
->force_explicit_name
)
6158 /* Force explicit tag name, if a name is there. */
6159 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
6161 make_tag (name
, strlen (name
), TRUE
,
6162 lbp
->buffer
, match
, lineno
, linecharno
);
6167 #endif /* ETAGS_REGEXPS */
6172 * Return a pointer to a space of size strlen(cp)+1 allocated
6173 * with xnew where the string CP has been copied.
6179 return savenstr (cp
, strlen (cp
));
6183 * Return a pointer to a space of size LEN+1 allocated with xnew where
6184 * the string CP has been copied for at most the first LEN characters.
6193 dp
= xnew (len
+ 1, char);
6194 strncpy (dp
, cp
, len
);
6200 * Return the ptr in sp at which the character c last
6201 * appears; NULL if not found
6203 * Identical to POSIX strrchr, included for portability.
6206 etags_strrchr (sp
, c
)
6207 register const char *sp
;
6210 register const char *r
;
6222 * Return the ptr in sp at which the character c first
6223 * appears; NULL if not found
6225 * Identical to POSIX strchr, included for portability.
6228 etags_strchr (sp
, c
)
6229 register const char *sp
;
6241 * Compare two strings, ignoring case for alphabetic characters.
6243 * Same as BSD's strcasecmp, included for portability.
6246 etags_strcasecmp (s1
, s2
)
6247 register const char *s1
;
6248 register const char *s2
;
6251 && (ISALPHA (*s1
) && ISALPHA (*s2
)
6252 ? lowcase (*s1
) == lowcase (*s2
)
6256 return (ISALPHA (*s1
) && ISALPHA (*s2
)
6257 ? lowcase (*s1
) - lowcase (*s2
)
6262 * Compare two strings, ignoring case for alphabetic characters.
6263 * Stop after a given number of characters
6265 * Same as BSD's strncasecmp, included for portability.
6268 etags_strncasecmp (s1
, s2
, n
)
6269 register const char *s1
;
6270 register const char *s2
;
6273 while (*s1
!= '\0' && n
-- > 0
6274 && (ISALPHA (*s1
) && ISALPHA (*s2
)
6275 ? lowcase (*s1
) == lowcase (*s2
)
6282 return (ISALPHA (*s1
) && ISALPHA (*s2
)
6283 ? lowcase (*s1
) - lowcase (*s2
)
6287 /* Skip spaces, return new pointer. */
6292 while (iswhite (*cp
))
6297 /* Skip non spaces, return new pointer. */
6299 skip_non_spaces (cp
)
6302 while (*cp
!= '\0' && !iswhite (*cp
))
6307 /* Print error message and exit. */
6325 suggest_asking_for_help ()
6327 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
6338 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
6341 const char *s1
, *s2
;
6343 fprintf (stderr
, "%s: ", progname
);
6344 fprintf (stderr
, s1
, s2
);
6345 fprintf (stderr
, "\n");
6348 /* Return a newly-allocated string whose contents
6349 concatenate those of s1, s2, s3. */
6354 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
6355 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
6357 strcpy (result
, s1
);
6358 strcpy (result
+ len1
, s2
);
6359 strcpy (result
+ len1
+ len2
, s3
);
6360 result
[len1
+ len2
+ len3
] = '\0';
6366 /* Does the same work as the system V getcwd, but does not need to
6367 guess the buffer size in advance. */
6373 char *path
= xnew (bufsize
, char);
6375 while (getcwd (path
, bufsize
) == NULL
)
6377 if (errno
!= ERANGE
)
6381 path
= xnew (bufsize
, char);
6384 canonicalize_filename (path
);
6387 #else /* not HAVE_GETCWD */
6390 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
6394 for (p
= path
; *p
!= '\0'; p
++)
6400 return strdup (path
);
6401 #else /* not MSDOS */
6405 linebuffer_init (&path
);
6406 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
6407 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
6412 #endif /* not MSDOS */
6413 #endif /* not HAVE_GETCWD */
6416 /* Return a newly allocated string containing the file name of FILE
6417 relative to the absolute directory DIR (which should end with a slash). */
6419 relative_filename (file
, dir
)
6422 char *fp
, *dp
, *afn
, *res
;
6425 /* Find the common root of file and dir (with a trailing slash). */
6426 afn
= absolute_filename (file
, cwd
);
6429 while (*fp
++ == *dp
++)
6431 fp
--, dp
--; /* back to the first differing char */
6433 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
6436 do /* look at the equal chars until '/' */
6440 /* Build a sequence of "../" strings for the resulting relative file name. */
6442 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
6444 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
6447 strcat (res
, "../");
6449 /* Add the file name relative to the common root of file and dir. */
6450 strcat (res
, fp
+ 1);
6456 /* Return a newly allocated string containing the absolute file name
6457 of FILE given DIR (which should end with a slash). */
6459 absolute_filename (file
, dir
)
6462 char *slashp
, *cp
, *res
;
6464 if (filename_is_absolute (file
))
6465 res
= savestr (file
);
6467 /* We don't support non-absolute file names with a drive
6468 letter, like `d:NAME' (it's too much hassle). */
6469 else if (file
[1] == ':')
6470 fatal ("%s: relative file names with drive letters not supported", file
);
6473 res
= concat (dir
, file
, "");
6475 /* Delete the "/dirname/.." and "/." substrings. */
6476 slashp
= etags_strchr (res
, '/');
6477 while (slashp
!= NULL
&& slashp
[0] != '\0')
6479 if (slashp
[1] == '.')
6481 if (slashp
[2] == '.'
6482 && (slashp
[3] == '/' || slashp
[3] == '\0'))
6487 while (cp
>= res
&& !filename_is_absolute (cp
));
6489 cp
= slashp
; /* the absolute name begins with "/.." */
6491 /* Under MSDOS and NT we get `d:/NAME' as absolute
6492 file name, so the luser could say `d:/../NAME'.
6493 We silently treat this as `d:/NAME'. */
6494 else if (cp
[0] != '/')
6497 strcpy (cp
, slashp
+ 3);
6501 else if (slashp
[2] == '/' || slashp
[2] == '\0')
6503 strcpy (slashp
, slashp
+ 2);
6508 slashp
= etags_strchr (slashp
+ 1, '/');
6512 return savestr ("/");
6517 /* Return a newly allocated string containing the absolute
6518 file name of dir where FILE resides given DIR (which should
6519 end with a slash). */
6521 absolute_dirname (file
, dir
)
6527 canonicalize_filename (file
);
6528 slashp
= etags_strrchr (file
, '/');
6530 return savestr (dir
);
6533 res
= absolute_filename (file
, dir
);
6539 /* Whether the argument string is an absolute file name. The argument
6540 string must have been canonicalized with canonicalize_filename. */
6542 filename_is_absolute (fn
)
6545 return (fn
[0] == '/'
6547 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
6552 /* Translate backslashes into slashes. Works in place. */
6554 canonicalize_filename (fn
)
6558 /* Canonicalize drive letter case. */
6559 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
6560 fn
[0] = upcase (fn
[0]);
6561 /* Convert backslashes to slashes. */
6562 for (; *fn
!= '\0'; fn
++)
6567 fn
= NULL
; /* shut up the compiler */
6572 /* Initialize a linebuffer for use */
6574 linebuffer_init (lbp
)
6577 lbp
->size
= (DEBUG
) ? 3 : 200;
6578 lbp
->buffer
= xnew (lbp
->size
, char);
6579 lbp
->buffer
[0] = '\0';
6583 /* Set the minimum size of a string contained in a linebuffer. */
6585 linebuffer_setlen (lbp
, toksize
)
6589 while (lbp
->size
<= toksize
)
6592 xrnew (lbp
->buffer
, lbp
->size
, char);
6597 /* Like malloc but get fatal error if memory is exhausted. */
6602 PTR result
= (PTR
) malloc (size
);
6604 fatal ("virtual memory exhausted", (char *)NULL
);
6609 xrealloc (ptr
, size
)
6613 PTR result
= (PTR
) realloc (ptr
, size
);
6615 fatal ("virtual memory exhausted", (char *)NULL
);
6621 * c-indentation-style: gnu
6622 * indent-tabs-mode: t
6625 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc" "node" "regexp")