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 Regexp tags by Tom Tromey.
31 * 2001 Nested classes by Francesco Potortì (ideas by Mykola Dzyuba).
33 * Francesco Potortì <pot@gnu.org> has maintained it since 1993.
36 char pot_etags_version
[] = "@(#) pot revision number is 15.10";
46 # define NDEBUG /* disable assert */
51 /* On some systems, Emacs defines static as nothing for the sake
52 of unexec. We don't want that here since we don't use unexec. */
54 # define ETAGS_REGEXPS /* use the regexp features */
55 # define LONG_OPTIONS /* accept long options */
56 # ifndef PTR /* for Xemacs */
59 # ifndef __P /* for Xemacs */
60 # define __P(args) args
63 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
64 # define __P(args) args /* use prototypes */
65 # define PTR void * /* for generic pointers */
67 # define __P(args) () /* no prototypes */
68 # define const /* remove const for old compilers' sake */
69 # define PTR long * /* don't use void* */
71 #endif /* !HAVE_CONFIG_H */
74 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
77 /* WIN32_NATIVE is for Xemacs.
78 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
83 #endif /* WIN32_NATIVE */
89 # include <sys/param.h>
91 # ifndef HAVE_CONFIG_H
93 # include <sys/config.h>
105 # define MAXPATHLEN _MAX_PATH
111 # endif /* undef HAVE_GETCWD */
112 #else /* !WINDOWSNT */
117 extern char *getenv ();
119 #endif /* !WINDOWSNT */
124 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
125 extern char *getcwd (char *buf
, size_t size
);
127 #endif /* HAVE_UNISTD_H */
135 #include <sys/types.h>
136 #include <sys/stat.h>
140 # undef assert /* some systems have a buggy assert.h */
141 # define assert(x) ((void) 0)
144 #if !defined (S_ISREG) && defined (S_IFREG)
145 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
151 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
153 extern int optind
, opterr
;
154 #endif /* LONG_OPTIONS */
157 # ifndef HAVE_CONFIG_H /* this is a standalone compilation */
158 # ifdef __CYGWIN__ /* compiling on Cygwin */
160 the regex
.h distributed with Cygwin is
not compatible with etags
, alas
!
161 If you want regular expression support
, you should
delete this notice
and
162 arrange to use the GNU regex
.h
and regex
.c
.
166 #endif /* ETAGS_REGEXPS */
168 /* Define CTAGS to make the program "ctags" compatible with the usual one.
169 Leave it undefined to make the program "etags", which makes emacs-style
170 tag tables and tags typedefs, #defines and struct/union/enum by default. */
178 /* Exit codes for success and failure. */
187 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
188 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
190 #define CHARS 256 /* 2^sizeof(char) */
191 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
192 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
193 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
194 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
195 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
196 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
198 #define ISALNUM(c) isalnum (CHAR(c))
199 #define ISALPHA(c) isalpha (CHAR(c))
200 #define ISDIGIT(c) isdigit (CHAR(c))
201 #define ISLOWER(c) islower (CHAR(c))
203 #define lowcase(c) tolower (CHAR(c))
204 #define upcase(c) toupper (CHAR(c))
208 * xnew, xrnew -- allocate, reallocate storage
210 * SYNOPSIS: Type *xnew (int n, Type);
211 * void xrnew (OldPointer, int n, Type);
214 # include "chkmalloc.h"
215 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
216 (n) * sizeof (Type)))
217 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
218 (char *) (op), (n) * sizeof (Type)))
220 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
221 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
222 (char *) (op), (n) * sizeof (Type)))
227 typedef void Lang_function
__P((FILE *));
231 char *suffix
; /* file name suffix for this compressor */
232 char *command
; /* takes one arg and decompresses to stdout */
237 char *name
; /* language name */
238 bool metasource
; /* source used to generate other sources */
239 Lang_function
*function
; /* parse function */
240 char **filenames
; /* names of this language's files */
241 char **suffixes
; /* name suffixes of this language's files */
242 char **interpreters
; /* interpreters for this language */
247 struct fdesc
*next
; /* for the linked list */
248 char *infname
; /* uncompressed input file name */
249 char *infabsname
; /* absolute uncompressed input file name */
250 char *infabsdir
; /* absolute dir of input file */
251 char *taggedfname
; /* file name to write in tagfile */
252 language
*lang
; /* language of file */
253 char *prop
; /* file properties to write in tagfile */
254 bool usecharno
; /* etags tags shall contain char number */
257 typedef struct node_st
258 { /* sorting structure */
259 struct node_st
*left
, *right
; /* left and right sons */
260 fdesc
*fdp
; /* description of file to whom tag belongs */
261 char *name
; /* tag name */
262 char *pat
; /* search pattern */
263 bool valid
; /* write this tag on the tag file */
264 bool is_func
; /* function tag: use pattern in CTAGS mode */
265 bool been_warned
; /* warning already given for duplicated tag */
266 int lno
; /* line number tag is on */
267 long cno
; /* character number line starts on */
271 * A `linebuffer' is a structure which holds a line of text.
272 * `readline_internal' reads a line from a stream into a linebuffer
273 * and works regardless of the length of the line.
274 * SIZE is the size of BUFFER, LEN is the length of the string in
275 * BUFFER after readline reads it.
284 /* Used to support mixing of --lang and file names. */
288 at_language
, /* a language specification */
289 at_regexp
, /* a regular expression */
290 at_icregexp
, /* same, but with case ignored */
291 at_filename
/* a file name */
292 } arg_type
; /* argument type */
293 language
*lang
; /* language associated with the argument */
294 char *what
; /* the argument itself */
298 /* Structure defining a regular expression. */
299 typedef struct pattern
301 struct pattern
*p_next
;
304 struct re_pattern_buffer
*pat
;
305 struct re_registers regs
;
310 #endif /* ETAGS_REGEXPS */
313 /* Many compilers barf on this:
314 Lang_function Ada_funcs;
315 so let's write it this way */
316 static void Ada_funcs
__P((FILE *));
317 static void Asm_labels
__P((FILE *));
318 static void C_entries
__P((int c_ext
, FILE *));
319 static void default_C_entries
__P((FILE *));
320 static void plain_C_entries
__P((FILE *));
321 static void Cjava_entries
__P((FILE *));
322 static void Cobol_paragraphs
__P((FILE *));
323 static void Cplusplus_entries
__P((FILE *));
324 static void Cstar_entries
__P((FILE *));
325 static void Erlang_functions
__P((FILE *));
326 static void Fortran_functions
__P((FILE *));
327 static void Yacc_entries
__P((FILE *));
328 static void Lisp_functions
__P((FILE *));
329 static void Makefile_targets
__P((FILE *));
330 static void Pascal_functions
__P((FILE *));
331 static void Perl_functions
__P((FILE *));
332 static void PHP_functions
__P((FILE *));
333 static void Postscript_functions
__P((FILE *));
334 static void Prolog_functions
__P((FILE *));
335 static void Python_functions
__P((FILE *));
336 static void Scheme_functions
__P((FILE *));
337 static void TeX_commands
__P((FILE *));
338 static void Texinfo_nodes
__P((FILE *));
339 static void just_read_file
__P((FILE *));
341 static void print_language_names
__P((void));
342 static void print_version
__P((void));
343 static void print_help
__P((void));
344 int main
__P((int, char **));
346 static compressor
*get_compressor_from_suffix
__P((char *, char **));
347 static language
*get_language_from_langname
__P((const char *));
348 static language
*get_language_from_interpreter
__P((char *));
349 static language
*get_language_from_filename
__P((char *));
350 static long readline
__P((linebuffer
*, FILE *));
351 static long readline_internal
__P((linebuffer
*, FILE *));
352 static bool nocase_tail
__P((char *));
353 static char *get_tag
__P((char *));
356 static void analyse_regex
__P((char *, bool));
357 static void add_regex
__P((char *, bool, language
*));
358 static void free_patterns
__P((void));
359 #endif /* ETAGS_REGEXPS */
360 static void error
__P((const char *, const char *));
361 static void suggest_asking_for_help
__P((void));
362 void fatal
__P((char *, char *));
363 static void pfatal
__P((char *));
364 static void add_node
__P((node
*, node
**));
366 static void init
__P((void));
367 static void initbuffer
__P((linebuffer
*));
368 static void process_file
__P((char *, language
*));
369 static void find_entries
__P((FILE *));
370 static void free_tree
__P((node
*));
371 static void pfnote
__P((char *, bool, char *, int, int, long));
372 static void new_pfnote
__P((char *, int, bool, char *, int, int, long));
373 static void invalidate_nodes
__P((fdesc
*, node
*));
374 static void put_entries
__P((node
*));
376 static char *concat
__P((char *, char *, char *));
377 static char *skip_spaces
__P((char *));
378 static char *skip_non_spaces
__P((char *));
379 static char *savenstr
__P((char *, int));
380 static char *savestr
__P((char *));
381 static char *etags_strchr
__P((const char *, int));
382 static char *etags_strrchr
__P((const char *, int));
383 static char *etags_getcwd
__P((void));
384 static char *relative_filename
__P((char *, char *));
385 static char *absolute_filename
__P((char *, char *));
386 static char *absolute_dirname
__P((char *, char *));
387 static bool filename_is_absolute
__P((char *f
));
388 static void canonicalize_filename
__P((char *));
389 static void linebuffer_setlen
__P((linebuffer
*, int));
390 static PTR xmalloc
__P((unsigned int));
391 static PTR xrealloc
__P((char *, unsigned int));
394 static char searchar
= '/'; /* use /.../ searches */
396 static char *tagfile
; /* output file */
397 static char *progname
; /* name this program was invoked with */
398 static char *cwd
; /* current working directory */
399 static char *tagfiledir
; /* directory of tagfile */
400 static FILE *tagf
; /* ioptr for tags file */
402 static fdesc
*fdhead
; /* head of file description list */
403 static fdesc
*curfdp
; /* current file description */
404 static int lineno
; /* line number of current line */
405 static long charno
; /* current character number */
406 static long linecharno
; /* charno of start of current line */
407 static char *dbp
; /* pointer to start of current tag */
409 static const int invalidcharno
= -1;
411 static node
*nodehead
; /* the head of the binary tree of tags */
413 static linebuffer lb
; /* the current line */
415 /* boolean "functions" (see init) */
416 static bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
419 *white
= " \f\t\n\r\v",
421 *nonam
= " \f\t\n\r()=,;",
422 /* token ending chars */
423 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
424 /* token starting chars */
425 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
426 /* valid in-token chars */
427 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
429 static bool append_to_tagfile
; /* -a: append to tags */
430 /* The next four default to TRUE for etags, but to FALSE for ctags. */
431 static bool typedefs
; /* -t: create tags for C and Ada typedefs */
432 static bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
433 /* 0 struct/enum/union decls, and C++ */
434 /* member functions. */
435 static bool constantypedefs
; /* -d: create tags for C #define, enum */
436 /* constants and variables. */
437 /* -D: opposite of -d. Default under ctags. */
438 static bool globals
; /* create tags for global variables */
439 static bool declarations
; /* --declarations: tag them and extern in C&Co*/
440 static bool members
; /* create tags for C member variables */
441 static bool no_line_directive
; /* ignore #line directives */
442 static bool update
; /* -u: update tags */
443 static bool vgrind_style
; /* -v: create vgrind style index output */
444 static bool no_warnings
; /* -w: suppress warnings */
445 static bool cxref_style
; /* -x: create cxref style output */
446 static bool cplusplus
; /* .[hc] means C++, not C */
447 static bool noindentypedefs
; /* -I: ignore indentation in C */
448 static bool packages_only
; /* --packages-only: in Ada, only tag packages*/
451 /* List of all regexps. */
452 static pattern
*p_head
;
454 /* How many characters in the character set. (From regex.c.) */
455 #define CHAR_SET_SIZE 256
456 /* Translation table for case-insensitive matching. */
457 static char lc_trans
[CHAR_SET_SIZE
];
458 #endif /* ETAGS_REGEXPS */
461 static struct option longopts
[] =
463 { "packages-only", no_argument
, &packages_only
, TRUE
},
464 { "c++", no_argument
, NULL
, 'C' },
465 { "declarations", no_argument
, &declarations
, TRUE
},
466 { "no-line-directive", no_argument
, &no_line_directive
, TRUE
},
467 { "help", no_argument
, NULL
, 'h' },
468 { "help", no_argument
, NULL
, 'H' },
469 { "ignore-indentation", no_argument
, NULL
, 'I' },
470 { "language", required_argument
, NULL
, 'l' },
471 { "members", no_argument
, &members
, TRUE
},
472 { "no-members", no_argument
, &members
, FALSE
},
473 { "output", required_argument
, NULL
, 'o' },
475 { "regex", required_argument
, NULL
, 'r' },
476 { "no-regex", no_argument
, NULL
, 'R' },
477 { "ignore-case-regex", required_argument
, NULL
, 'c' },
478 #endif /* ETAGS_REGEXPS */
479 { "version", no_argument
, NULL
, 'V' },
481 #if CTAGS /* Etags options */
482 { "backward-search", no_argument
, NULL
, 'B' },
483 { "cxref", no_argument
, NULL
, 'x' },
484 { "defines", no_argument
, NULL
, 'd' },
485 { "globals", no_argument
, &globals
, TRUE
},
486 { "typedefs", no_argument
, NULL
, 't' },
487 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
488 { "update", no_argument
, NULL
, 'u' },
489 { "vgrind", no_argument
, NULL
, 'v' },
490 { "no-warn", no_argument
, NULL
, 'w' },
492 #else /* Ctags options */
493 { "append", no_argument
, NULL
, 'a' },
494 { "no-defines", no_argument
, NULL
, 'D' },
495 { "no-globals", no_argument
, &globals
, FALSE
},
496 { "include", required_argument
, NULL
, 'i' },
500 #endif /* LONG_OPTIONS */
502 static compressor compressors
[] =
504 { "z", "gzip -d -c"},
505 { "Z", "gzip -d -c"},
506 { "gz", "gzip -d -c"},
507 { "GZ", "gzip -d -c"},
508 { "bz2", "bzip2 -d -c" },
517 static char *Ada_suffixes
[] =
518 { "ads", "adb", "ada", NULL
};
521 static char *Asm_suffixes
[] =
522 { "a", /* Unix assembler */
523 "asm", /* Microcontroller assembly */
524 "def", /* BSO/Tasking definition includes */
525 "inc", /* Microcontroller include files */
526 "ins", /* Microcontroller include files */
527 "s", "sa", /* Unix assembler */
528 "S", /* cpp-processed Unix assembler */
529 "src", /* BSO/Tasking C compiler output */
533 /* Note that .c and .h can be considered C++, if the --c++ flag was
534 given, or if the `class' keyowrd is met inside the file.
535 That is why default_C_entries is called for these. */
536 static char *default_C_suffixes
[] =
539 static char *Cplusplus_suffixes
[] =
540 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
541 "M", /* Objective C++ */
542 "pdb", /* Postscript with C syntax */
545 static char *Cjava_suffixes
[] =
548 static char *Cobol_suffixes
[] =
549 { "COB", "cob", NULL
};
551 static char *Cstar_suffixes
[] =
552 { "cs", "hs", NULL
};
554 static char *Erlang_suffixes
[] =
555 { "erl", "hrl", NULL
};
557 static char *Fortran_suffixes
[] =
558 { "F", "f", "f90", "for", NULL
};
560 static char *Lisp_suffixes
[] =
561 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
563 static char *Makefile_filenames
[] =
564 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
566 static char *Pascal_suffixes
[] =
567 { "p", "pas", NULL
};
569 static char *Perl_suffixes
[] =
570 { "pl", "pm", NULL
};
572 static char *Perl_interpreters
[] =
573 { "perl", "@PERL@", NULL
};
575 static char *PHP_suffixes
[] =
576 { "php", "php3", "php4", NULL
};
578 static char *plain_C_suffixes
[] =
579 { "lm", /* Objective lex file */
580 "m", /* Objective C file */
581 "pc", /* Pro*C file */
584 static char *Postscript_suffixes
[] =
585 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
587 static char *Prolog_suffixes
[] =
590 static char *Python_suffixes
[] =
593 /* Can't do the `SCM' or `scm' prefix with a version number. */
594 static char *Scheme_suffixes
[] =
595 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
597 static char *TeX_suffixes
[] =
598 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
600 static char *Texinfo_suffixes
[] =
601 { "texi", "texinfo", "txi", NULL
};
603 static char *Yacc_suffixes
[] =
604 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
607 * Table of languages.
609 * It is ok for a given function to be listed under more than one
610 * name. I just didn't.
613 static language lang_names
[] =
615 { "ada", FALSE
, Ada_funcs
, NULL
, Ada_suffixes
, NULL
},
616 { "asm", FALSE
, Asm_labels
, NULL
, Asm_suffixes
, NULL
},
617 { "c", FALSE
, default_C_entries
, NULL
, default_C_suffixes
, NULL
},
618 { "c++", FALSE
, Cplusplus_entries
, NULL
, Cplusplus_suffixes
, NULL
},
619 { "c*", FALSE
, Cstar_entries
, NULL
, Cstar_suffixes
, NULL
},
620 { "cobol", FALSE
, Cobol_paragraphs
, NULL
, Cobol_suffixes
, NULL
},
621 { "erlang", FALSE
, Erlang_functions
, NULL
, Erlang_suffixes
, NULL
},
622 { "fortran", FALSE
, Fortran_functions
, NULL
, Fortran_suffixes
, NULL
},
623 { "java", FALSE
, Cjava_entries
, NULL
, Cjava_suffixes
, NULL
},
624 { "lisp", FALSE
, Lisp_functions
, NULL
, Lisp_suffixes
, NULL
},
625 { "makefile", FALSE
, Makefile_targets
, Makefile_filenames
, NULL
, NULL
},
626 { "pascal", FALSE
, Pascal_functions
, NULL
, Pascal_suffixes
, NULL
},
627 { "perl", FALSE
, Perl_functions
,NULL
, Perl_suffixes
, Perl_interpreters
},
628 { "php", FALSE
, PHP_functions
, NULL
, PHP_suffixes
, NULL
},
629 { "postscript",FALSE
, Postscript_functions
,NULL
, Postscript_suffixes
, NULL
},
630 { "proc", FALSE
, plain_C_entries
, NULL
, plain_C_suffixes
, NULL
},
631 { "prolog", FALSE
, Prolog_functions
, NULL
, Prolog_suffixes
, NULL
},
632 { "python", FALSE
, Python_functions
, NULL
, Python_suffixes
, NULL
},
633 { "scheme", FALSE
, Scheme_functions
, NULL
, Scheme_suffixes
, NULL
},
634 { "tex", FALSE
, TeX_commands
, NULL
, TeX_suffixes
, NULL
},
635 { "texinfo", FALSE
, Texinfo_nodes
, NULL
, Texinfo_suffixes
, NULL
},
636 { "yacc", TRUE
, Yacc_entries
, NULL
, Yacc_suffixes
, NULL
},
637 { "auto", FALSE
, NULL
}, /* default guessing scheme */
638 { "none", FALSE
, just_read_file
}, /* regexp matching only */
639 { NULL
, FALSE
, NULL
} /* end of list */
644 print_language_names ()
649 puts ("\nThese are the currently supported languages, along with the\n\
650 default file names and dot suffixes:");
651 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
653 printf (" %-*s", 10, lang
->name
);
654 if (lang
->filenames
!= NULL
)
655 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
656 printf (" %s", *name
);
657 if (lang
->suffixes
!= NULL
)
658 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
659 printf (" .%s", *ext
);
662 puts ("Where `auto' means use default language for files based on file\n\
663 name suffix, and `none' means only do regexp processing on files.\n\
664 If no language is specified and no matching suffix is found,\n\
665 the first line of the file is read for a sharp-bang (#!) sequence\n\
666 followed by the name of an interpreter. If no such sequence is found,\n\
667 Fortran is tried first; if no tags are found, C is tried next.\n\
668 When parsing any C file, a \"class\" keyword switches to C++.\n\
669 Compressed files are supported using gzip and bzip2.");
673 # define EMACS_NAME "GNU Emacs"
676 # define VERSION "21"
681 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
682 puts ("Copyright (C) 2002 Free Software Foundation, Inc. and Ken Arnold");
683 puts ("This program is distributed under the same terms as Emacs");
691 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
693 These are the options accepted by %s.\n", progname
, progname
);
695 puts ("You may use unambiguous abbreviations for the long option names.");
697 puts ("Long option names do not work with this executable, as it is not\n\
698 linked with GNU getopt.");
699 #endif /* LONG_OPTIONS */
700 puts (" A - as file name means read names from stdin (one per line).\n\
701 Absolute names are stored in the output file as they are.\n\
702 Relative ones are stored relative to the output file's directory.\n");
705 puts ("-a, --append\n\
706 Append tag entries to existing tags file.");
708 puts ("--packages-only\n\
709 For Ada files, only generate tags for packages.");
712 puts ("-B, --backward-search\n\
713 Write the search commands for the tag entries using '?', the\n\
714 backward-search command instead of '/', the forward-search command.");
716 /* This option is mostly obsolete, because etags can now automatically
717 detect C++. Retained for backward compatibility and for debugging and
718 experimentation. In principle, we could want to tag as C++ even
719 before any "class" keyword.
721 Treat files whose name suffix defaults to C language as C++ files.");
724 puts ("--declarations\n\
725 In C and derived languages, create tags for function declarations,");
727 puts ("\tand create tags for extern variables if --globals is used.");
730 ("\tand create tags for extern variables unless --no-globals is used.");
733 puts ("-d, --defines\n\
734 Create tag entries for C #define constants and enum constants, too.");
736 puts ("-D, --no-defines\n\
737 Don't create tag entries for C #define constants and enum constants.\n\
738 This makes the tags file smaller.");
741 puts ("-i FILE, --include=FILE\n\
742 Include a note in tag file indicating that, when searching for\n\
743 a tag, one should also consult the tags file FILE after\n\
744 checking the current file.");
746 puts ("-l LANG, --language=LANG\n\
747 Force the following files to be considered as written in the\n\
748 named language up to the next --language=LANG option.");
752 Create tag entries for global variables in some languages.");
754 puts ("--no-globals\n\
755 Do not create tag entries for global variables in some\n\
756 languages. This makes the tags file smaller.");
758 Create tag entries for member variables in C and derived languages.");
761 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
762 Make a tag for each line matching pattern REGEXP in the following\n\
763 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
764 regexfile is a file containing one REGEXP per line.\n\
765 REGEXP is anchored (as if preceded by ^).\n\
766 The form /REGEXP/NAME/ creates a named tag.\n\
767 For example Tcl named tags can be created with:\n\
768 --regex=\"/proc[ \\t]+\\([^ \\t]+\\)/\\1/.\"");
769 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
770 Like -r, --regex but ignore case when matching expressions.");
771 puts ("-R, --no-regex\n\
772 Don't create tags from regexps for the following files.");
773 #endif /* ETAGS_REGEXPS */
774 puts ("-o FILE, --output=FILE\n\
775 Write the tags to FILE.");
776 puts ("-I, --ignore-indentation\n\
777 Don't rely on indentation quite as much as normal. Currently,\n\
778 this means not to assume that a closing brace in the first\n\
779 column is the final brace of a function or structure\n\
780 definition in C and C++.");
784 puts ("-t, --typedefs\n\
785 Generate tag entries for C and Ada typedefs.");
786 puts ("-T, --typedefs-and-c++\n\
787 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
788 and C++ member functions.");
792 puts ("-u, --update\n\
793 Update the tag entries for the given files, leaving tag\n\
794 entries for other files in place. Currently, this is\n\
795 implemented by deleting the existing entries for the given\n\
796 files and then rewriting the new entries at the end of the\n\
797 tags file. It is often faster to simply rebuild the entire\n\
798 tag file than to use this.");
802 puts ("-v, --vgrind\n\
803 Generates an index of items intended for human consumption,\n\
804 similar to the output of vgrind. The index is sorted, and\n\
805 gives the page number of each item.");
806 puts ("-w, --no-warn\n\
807 Suppress warning messages about entries defined in multiple\n\
809 puts ("-x, --cxref\n\
810 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
811 The output uses line numbers instead of page numbers, but\n\
812 beyond that the differences are cosmetic; try both to see\n\
816 puts ("-V, --version\n\
817 Print the version of the program.\n\
819 Print this help message.");
821 print_language_names ();
824 puts ("Report bugs to bug-gnu-emacs@gnu.org");
830 #ifdef VMS /* VMS specific functions */
834 /* This is a BUG! ANY arbitrary limit is a BUG!
835 Won't someone please fix this? */
836 #define MAX_FILE_SPEC_LEN 255
839 char body
[MAX_FILE_SPEC_LEN
+ 1];
843 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
844 returning in each successive call the next file name matching the input
845 spec. The function expects that each in_spec passed
846 to it will be processed to completion; in particular, up to and
847 including the call following that in which the last matching name
848 is returned, the function ignores the value of in_spec, and will
849 only start processing a new spec with the following call.
850 If an error occurs, on return out_spec contains the value
851 of in_spec when the error occurred.
853 With each successive file name returned in out_spec, the
854 function's return value is one. When there are no more matching
855 names the function returns zero. If on the first call no file
856 matches in_spec, or there is any other error, -1 is returned.
861 #define OUTSIZE MAX_FILE_SPEC_LEN
867 static long context
= 0;
868 static struct dsc$descriptor_s o
;
869 static struct dsc$descriptor_s i
;
870 static bool pass1
= TRUE
;
877 o
.dsc$a_pointer
= (char *) out
;
878 o
.dsc$w_length
= (short)OUTSIZE
;
879 i
.dsc$a_pointer
= in
;
880 i
.dsc$w_length
= (short)strlen(in
);
881 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
882 i
.dsc$b_class
= DSC$K_CLASS_S
;
883 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
884 o
.dsc$b_class
= DSC$K_CLASS_VS
;
886 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
888 out
->body
[out
->curlen
] = EOS
;
891 else if (status
== RMS$_NMF
)
895 strcpy(out
->body
, in
);
898 lib$
find_file_end(&context
);
904 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
905 name of each file specified by the provided arg expanding wildcards.
908 gfnames (arg
, p_error
)
912 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
914 switch (fn_exp (&filename
, arg
))
918 return filename
.body
;
924 return filename
.body
;
928 #ifndef OLD /* Newer versions of VMS do provide `system'. */
932 error ("%s", "system() function not implemented under VMS");
936 #define VERSION_DELIM ';'
937 char *massage_name (s
)
943 if (*s
== VERSION_DELIM
)
961 unsigned int nincluded_files
;
962 char **included_files
;
964 int current_arg
, file_count
;
965 linebuffer filename_lb
;
971 _fmode
= O_BINARY
; /* all of files are treated as binary files */
976 included_files
= xnew (argc
, char *);
980 /* Allocate enough no matter what happens. Overkill, but each one
982 argbuffer
= xnew (argc
, argument
);
985 /* Set syntax for regular expression routines. */
986 re_set_syntax (RE_SYNTAX_EMACS
| RE_INTERVALS
);
987 /* Translation table for case-insensitive search. */
988 for (i
= 0; i
< CHAR_SET_SIZE
; i
++)
989 lc_trans
[i
] = lowcase (i
);
990 #endif /* ETAGS_REGEXPS */
993 * If etags, always find typedefs and structure tags. Why not?
994 * Also default to find macro constants, enum constants and
999 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
1006 char *optstring
= "-";
1008 #ifdef ETAGS_REGEXPS
1009 optstring
= "-r:Rc:";
1010 #endif /* ETAGS_REGEXPS */
1012 #ifndef LONG_OPTIONS
1013 optstring
= optstring
+ 1;
1014 #endif /* LONG_OPTIONS */
1016 optstring
= concat (optstring
,
1018 (CTAGS
) ? "BxdtTuvw" : "aDi:");
1020 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
1027 /* If getopt returns 0, then it has already processed a
1028 long-named option. We should do nothing. */
1032 /* This means that a file name has been seen. Record it. */
1033 argbuffer
[current_arg
].arg_type
= at_filename
;
1034 argbuffer
[current_arg
].what
= optarg
;
1039 /* Common options. */
1040 case 'C': cplusplus
= TRUE
; break;
1041 case 'f': /* for compatibility with old makefiles */
1045 error ("-o option may only be given once.", (char *)NULL
);
1046 suggest_asking_for_help ();
1051 case 'S': /* for backward compatibility */
1052 noindentypedefs
= TRUE
;
1056 language
*lang
= get_language_from_langname (optarg
);
1059 argbuffer
[current_arg
].lang
= lang
;
1060 argbuffer
[current_arg
].arg_type
= at_language
;
1066 argbuffer
[current_arg
].arg_type
= at_regexp
;
1067 argbuffer
[current_arg
].what
= optarg
;
1071 argbuffer
[current_arg
].arg_type
= at_regexp
;
1072 argbuffer
[current_arg
].what
= NULL
;
1076 argbuffer
[current_arg
].arg_type
= at_icregexp
;
1077 argbuffer
[current_arg
].what
= optarg
;
1089 case 'a': append_to_tagfile
= TRUE
; break;
1090 case 'D': constantypedefs
= FALSE
; break;
1091 case 'i': included_files
[nincluded_files
++] = optarg
; break;
1093 /* Ctags options. */
1094 case 'B': searchar
= '?'; break;
1095 case 'd': constantypedefs
= TRUE
; break;
1096 case 't': typedefs
= TRUE
; break;
1097 case 'T': typedefs
= typedefs_or_cplusplus
= TRUE
; break;
1098 case 'u': update
= TRUE
; break;
1099 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1100 case 'x': cxref_style
= TRUE
; break;
1101 case 'w': no_warnings
= TRUE
; break;
1103 suggest_asking_for_help ();
1107 for (; optind
< argc
; ++optind
)
1109 argbuffer
[current_arg
].arg_type
= at_filename
;
1110 argbuffer
[current_arg
].what
= argv
[optind
];
1115 if (nincluded_files
== 0 && file_count
== 0)
1117 error ("no input files specified.", (char *)NULL
);
1118 suggest_asking_for_help ();
1121 if (tagfile
== NULL
)
1122 tagfile
= CTAGS
? "tags" : "TAGS";
1123 cwd
= etags_getcwd (); /* the current working directory */
1124 if (cwd
[strlen (cwd
) - 1] != '/')
1127 cwd
= concat (oldcwd
, "/", "");
1130 if (streq (tagfile
, "-"))
1133 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1135 init (); /* set up boolean "functions" */
1138 initbuffer (&filename_lb
);
1142 if (streq (tagfile
, "-"))
1146 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1147 doesn't take effect until after `stdout' is already open). */
1148 if (!isatty (fileno (stdout
)))
1149 setmode (fileno (stdout
), O_BINARY
);
1153 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1159 * Loop through files finding functions.
1161 for (i
= 0; i
< current_arg
; ++i
)
1163 static language
*lang
; /* non-NULL if language is forced */
1166 switch (argbuffer
[i
].arg_type
)
1169 lang
= argbuffer
[i
].lang
;
1171 #ifdef ETAGS_REGEXPS
1173 analyse_regex (argbuffer
[i
].what
, FALSE
);
1176 analyse_regex (argbuffer
[i
].what
, TRUE
);
1181 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1185 error ("can't find file %s\n", this_file
);
1190 this_file
= massage_name (this_file
);
1193 this_file
= argbuffer
[i
].what
;
1195 /* Input file named "-" means read file names from stdin
1196 (one per line) and use them. */
1197 if (streq (this_file
, "-"))
1198 while (readline_internal (&filename_lb
, stdin
) > 0)
1199 process_file (filename_lb
.buffer
, lang
);
1201 process_file (this_file
, lang
);
1209 #ifdef ETAGS_REGEXPS
1211 #endif /* ETAGS_REGEXPS */
1213 if (!CTAGS
|| cxref_style
)
1215 put_entries (nodehead
);
1216 free_tree (nodehead
);
1219 while (nincluded_files
-- > 0)
1220 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1222 if (fclose (tagf
) == EOF
)
1230 for (i
= 0; i
< current_arg
; ++i
)
1232 if (argbuffer
[i
].arg_type
!= at_filename
)
1235 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1236 tagfile
, argbuffer
[i
].what
, tagfile
);
1237 if (system (cmd
) != GOOD
)
1238 fatal ("failed to execute shell command", (char *)NULL
);
1240 append_to_tagfile
= TRUE
;
1243 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1246 put_entries (nodehead
);
1247 free_tree (nodehead
);
1249 if (fclose (tagf
) == EOF
)
1255 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
1256 exit (system (cmd
));
1263 * Return a compressor given the file name. If EXTPTR is non-zero,
1264 * return a pointer into FILE where the compressor-specific
1265 * extension begins. If no compressor is found, NULL is returned
1266 * and EXTPTR is not significant.
1267 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1270 get_compressor_from_suffix (file
, extptr
)
1275 char *slash
, *suffix
;
1277 /* This relies on FN to be after canonicalize_filename,
1278 so we don't need to consider backslashes on DOS_NT. */
1279 slash
= etags_strrchr (file
, '/');
1280 suffix
= etags_strrchr (file
, '.');
1281 if (suffix
== NULL
|| suffix
< slash
)
1286 /* Let those poor souls who live with DOS 8+3 file name limits get
1287 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1288 Only the first do loop is run if not MSDOS */
1291 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1292 if (streq (compr
->suffix
, suffix
))
1295 break; /* do it only once: not really a loop */
1298 } while (*suffix
!= '\0');
1305 * Return a language given the name.
1308 get_language_from_langname (name
)
1314 error ("empty language name", (char *)NULL
);
1317 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1318 if (streq (name
, lang
->name
))
1320 error ("unknown language \"%s\"", name
);
1328 * Return a language given the interpreter name.
1331 get_language_from_interpreter (interpreter
)
1337 if (interpreter
== NULL
)
1339 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1340 if (lang
->interpreters
!= NULL
)
1341 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1342 if (streq (*iname
, interpreter
))
1351 * Return a language given the file name.
1354 get_language_from_filename (file
)
1358 char **name
, **ext
, *suffix
;
1360 /* Try whole file name first. */
1361 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1362 if (lang
->filenames
!= NULL
)
1363 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1364 if (streq (*name
, file
))
1367 /* If not found, try suffix after last dot. */
1368 suffix
= etags_strrchr (file
, '.');
1372 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1373 if (lang
->suffixes
!= NULL
)
1374 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1375 if (streq (*ext
, suffix
))
1382 * This routine is called on each file argument.
1385 process_file (file
, lang
)
1389 struct stat stat_buf
;
1391 static const fdesc emptyfdesc
;
1394 char *compressed_name
, *uncompressed_name
;
1395 char *ext
, *real_name
;
1399 canonicalize_filename (file
);
1400 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1402 error ("skipping inclusion of %s in self.", file
);
1405 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1407 compressed_name
= NULL
;
1408 real_name
= uncompressed_name
= savestr (file
);
1412 real_name
= compressed_name
= savestr (file
);
1413 uncompressed_name
= savenstr (file
, ext
- file
);
1416 /* If the canonicalized uncompressed name
1417 has already been dealt with, skip it silently. */
1418 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
1420 assert (fdp
->infname
!= NULL
);
1421 if (streq (uncompressed_name
, fdp
->infname
))
1425 /* Create a new input file description entry. */
1427 fdhead
= xnew (1, fdesc
);
1428 *fdhead
= emptyfdesc
;
1431 if (stat (real_name
, &stat_buf
) != 0)
1433 /* Reset real_name and try with a different name. */
1435 if (compressed_name
!= NULL
) /* try with the given suffix */
1437 if (stat (uncompressed_name
, &stat_buf
) == 0)
1438 real_name
= uncompressed_name
;
1440 else /* try all possible suffixes */
1442 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1444 compressed_name
= concat (file
, ".", compr
->suffix
);
1445 if (stat (compressed_name
, &stat_buf
) != 0)
1449 char *suf
= compressed_name
+ strlen (file
);
1450 size_t suflen
= strlen (compr
->suffix
) + 1;
1451 for ( ; suf
[1]; suf
++, suflen
--)
1453 memmove (suf
, suf
+ 1, suflen
);
1454 if (stat (compressed_name
, &stat_buf
) == 0)
1456 real_name
= compressed_name
;
1460 if (real_name
!= NULL
)
1463 free (compressed_name
);
1464 compressed_name
= NULL
;
1468 real_name
= compressed_name
;
1473 if (real_name
== NULL
)
1478 } /* try with a different name */
1480 if (!S_ISREG (stat_buf
.st_mode
))
1482 error ("skipping %s: it is not a regular file.", real_name
);
1485 if (real_name
== compressed_name
)
1487 char *cmd
= concat (compr
->command
, " ", real_name
);
1488 inf
= (FILE *) popen (cmd
, "r");
1492 inf
= fopen (real_name
, "r");
1499 fdhead
->infname
= savestr (uncompressed_name
);
1500 fdhead
->lang
= lang
;
1501 fdhead
->infabsname
= absolute_filename (uncompressed_name
, cwd
);
1502 fdhead
->infabsdir
= absolute_dirname (uncompressed_name
, cwd
);
1503 if (filename_is_absolute (uncompressed_name
))
1505 /* file is an absolute file name. Canonicalize it. */
1506 fdhead
->taggedfname
= absolute_filename (uncompressed_name
, NULL
);
1510 /* file is a file name relative to cwd. Make it relative
1511 to the directory of the tags file. */
1512 fdhead
->taggedfname
= relative_filename (uncompressed_name
, tagfiledir
);
1514 fdhead
->usecharno
= TRUE
; /* use char position when making tags */
1515 fdhead
->prop
= NULL
;
1517 curfdp
= fdhead
; /* the current file description */
1521 if (real_name
== compressed_name
)
1522 retval
= pclose (inf
);
1524 retval
= fclose (inf
);
1529 /* XXX if no more useful, delete head of file description list */
1530 if (compressed_name
) free (compressed_name
);
1531 if (uncompressed_name
) free (uncompressed_name
);
1536 * This routine sets up the boolean pseudo-functions which work
1537 * by setting boolean flags dependent upon the corresponding character.
1538 * Every char which is NOT in that string is not a white char. Therefore,
1539 * all of the array "_wht" is set to FALSE, and then the elements
1540 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1541 * of a char is TRUE if it is the string "white", else FALSE.
1549 for (i
= 0; i
< CHARS
; i
++)
1550 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1551 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1552 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1553 notinname('\0') = notinname('\n');
1554 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1555 begtoken('\0') = begtoken('\n');
1556 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1557 intoken('\0') = intoken('\n');
1558 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1559 endtoken('\0') = endtoken('\n');
1563 * This routine opens the specified file and calls the function
1564 * which finds the function and type definitions.
1566 static node
*last_node
= NULL
;
1573 node
*old_last_node
;
1574 language
*lang
= curfdp
->lang
;
1575 Lang_function
*parser
= NULL
;
1577 /* If user specified a language, use it. */
1578 if (lang
!= NULL
&& lang
->function
!= NULL
)
1580 parser
= lang
->function
;
1583 /* Else try to guess the language given the file name. */
1586 lang
= get_language_from_filename (curfdp
->infname
);
1587 if (lang
!= NULL
&& lang
->function
!= NULL
)
1589 curfdp
->lang
= lang
;
1590 parser
= lang
->function
;
1594 /* Else look for sharp-bang as the first two characters. */
1596 && readline_internal (&lb
, inf
) > 0
1598 && lb
.buffer
[0] == '#'
1599 && lb
.buffer
[1] == '!')
1603 /* Set lp to point at the first char after the last slash in the
1604 line or, if no slashes, at the first nonblank. Then set cp to
1605 the first successive blank and terminate the string. */
1606 lp
= etags_strrchr (lb
.buffer
+2, '/');
1610 lp
= skip_spaces (lb
.buffer
+ 2);
1611 cp
= skip_non_spaces (lp
);
1614 if (strlen (lp
) > 0)
1616 lang
= get_language_from_interpreter (lp
);
1617 if (lang
!= NULL
&& lang
->function
!= NULL
)
1619 curfdp
->lang
= lang
;
1620 parser
= lang
->function
;
1625 if (!no_line_directive
1626 && curfdp
->lang
!= NULL
&& curfdp
->lang
->metasource
)
1627 /* It may be that this is an xxx.y file, and we already parsed an xxx.c
1628 file, or anyway we parsed a file that is automatically generated from
1629 this one. If this is the case, the xxx.c file contained #line
1630 directives that generated tags pointing to this file. Let's delete
1631 them all before parsing this file, which is the real source. */
1633 fdesc
**fdpp
= &fdhead
;
1634 while (*fdpp
!= NULL
)
1636 && streq ((*fdpp
)->taggedfname
, curfdp
->taggedfname
))
1637 /* We found one of those! We must delete both the file description
1638 and all tags referring to it. */
1640 fdesc
*badfdp
= *fdpp
;
1642 *fdpp
= badfdp
->next
; /* remove the bad description from the list */
1643 fdpp
= &badfdp
->next
; /* advance the list pointer */
1645 fprintf (stderr
, "Removing references to \"%s\" obtained from \"%s\"\n",
1646 badfdp
->taggedfname
, badfdp
->infname
);
1647 /* Delete the tags referring to badfdp. */
1648 invalidate_nodes (badfdp
, nodehead
);
1650 /* Delete badfdp. */
1651 if (badfdp
->infname
!= NULL
) free (badfdp
->infname
);
1652 if (badfdp
->infabsname
!= NULL
) free (badfdp
->infabsname
);
1653 if (badfdp
->infabsdir
!= NULL
) free (badfdp
->infabsdir
);
1654 if (badfdp
->taggedfname
!= NULL
) free (badfdp
->taggedfname
);
1655 if (badfdp
->prop
!= NULL
) free (badfdp
->prop
);
1659 fdpp
= &(*fdpp
)->next
; /* advance the list pointer */
1668 /* We rewind here, even if inf may be a pipe. We fail if the
1669 length of the first line is longer than the pipe block size,
1670 which is unlikely. */
1673 /* Else try Fortran. */
1674 old_last_node
= last_node
;
1675 curfdp
->lang
= get_language_from_langname ("fortran");
1676 Fortran_functions (inf
);
1678 if (old_last_node
== last_node
)
1679 /* No Fortran entries found. Try C. */
1681 /* We do not tag if rewind fails.
1682 Only the file name will be recorded in the tags file. */
1684 curfdp
->lang
= get_language_from_langname (cplusplus
? "c++" : "c");
1685 default_C_entries (inf
);
1693 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1694 char *name
; /* tag name, or NULL if unnamed */
1695 bool is_func
; /* tag is a function */
1696 char *linestart
; /* start of the line where tag is */
1697 int linelen
; /* length of the line where tag is */
1698 int lno
; /* line number */
1699 long cno
; /* character number */
1703 if (CTAGS
&& name
== NULL
)
1706 np
= xnew (1, node
);
1708 /* If ctags mode, change name "main" to M<thisfilename>. */
1709 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1711 register char *fp
= etags_strrchr (curfdp
->taggedfname
, '/');
1712 np
->name
= concat ("M", fp
== NULL
? curfdp
->taggedfname
: fp
+ 1, "");
1713 fp
= etags_strrchr (np
->name
, '.');
1714 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
1720 np
->been_warned
= FALSE
;
1722 np
->is_func
= is_func
;
1724 if (np
->fdp
->usecharno
)
1725 /* Our char numbers are 0-base, because of C language tradition?
1726 ctags compatibility? old versions compatibility? I don't know.
1727 Anyway, since emacs's are 1-base we expect etags.el to take care
1728 of the difference. If we wanted to have 1-based numbers, we would
1729 uncomment the +1 below. */
1730 np
->cno
= cno
/* + 1 */ ;
1732 np
->cno
= invalidcharno
;
1733 np
->left
= np
->right
= NULL
;
1734 if (CTAGS
&& !cxref_style
)
1736 if (strlen (linestart
) < 50)
1737 np
->pat
= concat (linestart
, "$", "");
1739 np
->pat
= savenstr (linestart
, 50);
1742 np
->pat
= savenstr (linestart
, linelen
);
1744 add_node (np
, &nodehead
);
1748 * TAGS format specification
1749 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1751 * pfnote should emit the optimized form [unnamed tag] only if:
1752 * 1. name does not contain any of the characters " \t\r\n(),;";
1753 * 2. linestart contains name as either a rightmost, or rightmost but
1754 * one character, substring;
1755 * 3. the character, if any, immediately before name in linestart must
1756 * be one of the characters " \t(),;";
1757 * 4. the character, if any, immediately after name in linestart must
1758 * also be one of the characters " \t(),;".
1760 * The real implementation uses the notinname() macro, which recognises
1761 * characters slightly different from " \t\r\n(),;". See the variable
1764 #define traditional_tag_style TRUE
1766 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1767 char *name
; /* tag name, or NULL if unnamed */
1768 int namelen
; /* tag length */
1769 bool is_func
; /* tag is a function */
1770 char *linestart
; /* start of the line where tag is */
1771 int linelen
; /* length of the line where tag is */
1772 int lno
; /* line number */
1773 long cno
; /* character number */
1781 for (cp
= name
; !notinname (*cp
); cp
++)
1783 if (*cp
== '\0') /* rule #1 */
1785 cp
= linestart
+ linelen
- namelen
;
1786 if (notinname (linestart
[linelen
-1]))
1787 cp
-= 1; /* rule #4 */
1788 if (cp
>= linestart
/* rule #2 */
1790 || notinname (cp
[-1])) /* rule #3 */
1791 && strneq (name
, cp
, namelen
)) /* rule #2 */
1792 named
= FALSE
; /* use unnamed tag */
1797 name
= savenstr (name
, namelen
);
1800 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1805 * recurse on left children, iterate on right children.
1813 register node
*node_right
= np
->right
;
1814 free_tree (np
->left
);
1815 if (np
->name
!= NULL
)
1825 * Adds a node to the tree of nodes. In etags mode, sort by file
1826 * name. In ctags mode, sort by tag name. Make no attempt at
1829 * add_node is the only function allowed to add nodes, so it can
1833 add_node (np
, cur_node_p
)
1834 node
*np
, **cur_node_p
;
1837 register node
*cur_node
= *cur_node_p
;
1839 if (cur_node
== NULL
)
1849 assert (last_node
!= NULL
);
1850 /* For each file name, tags are in a linked sublist on the right
1851 pointer. The first tags of different files are a linked list
1852 on the left pointer. last_node points to the end of the last
1854 if (last_node
->fdp
== np
->fdp
)
1856 /* Let's use the same sublist as the last added node. */
1857 last_node
->right
= np
;
1860 else if (cur_node
->fdp
== np
->fdp
)
1862 /* Scanning the list we found the head of a sublist which is
1863 good for us. Let's scan this sublist. */
1864 add_node (np
, &cur_node
->right
);
1867 /* The head of this sublist is not good for us. Let's try the
1869 add_node (np
, &cur_node
->left
);
1874 dif
= strcmp (np
->name
, cur_node
->name
);
1877 * If this tag name matches an existing one, then
1878 * do not add the node, but maybe print a warning.
1882 if (np
->fdp
== cur_node
->fdp
)
1886 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1887 np
->fdp
->infname
, lineno
, np
->name
);
1888 fprintf (stderr
, "Second entry ignored\n");
1891 else if (!cur_node
->been_warned
&& !no_warnings
)
1895 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1896 np
->fdp
->infname
, cur_node
->fdp
->infname
, np
->name
);
1897 cur_node
->been_warned
= TRUE
;
1902 /* Actually add the node */
1903 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1908 * invalidate_nodes ()
1909 * Scan the node tree and invalidate all nodes pointing to the
1910 * given file description.
1913 invalidate_nodes (badfdp
, np
)
1917 if (np
->left
!= NULL
)
1918 invalidate_nodes (badfdp
, np
->left
);
1919 if (np
->fdp
== badfdp
)
1921 if (np
->right
!= NULL
)
1922 invalidate_nodes (badfdp
, np
->right
);
1926 static int total_size_of_entries
__P((node
*));
1927 static int number_len
__P((long));
1929 /* Length of a non-negative number's decimal representation. */
1935 while ((num
/= 10) > 0)
1941 * Return total number of characters that put_entries will output for
1942 * the nodes in the linked list at the right of the specified node.
1943 * This count is irrelevant with etags.el since emacs 19.34 at least,
1944 * but is still supplied for backward compatibility.
1947 total_size_of_entries (np
)
1950 register int total
= 0;
1952 for (; np
!= NULL
; np
= np
->right
)
1954 total
+= strlen (np
->pat
) + 1; /* pat\177 */
1955 if (np
->name
!= NULL
)
1956 total
+= strlen (np
->name
) + 1; /* name\001 */
1957 total
+= number_len ((long) np
->lno
) + 1; /* lno, */
1958 if (np
->cno
!= invalidcharno
) /* cno */
1959 total
+= number_len (np
->cno
);
1960 total
+= 1; /* newline */
1971 static fdesc
*fdp
= NULL
;
1976 /* Output subentries that precede this one */
1978 put_entries (np
->left
);
1980 /* Output this entry */
1989 fprintf (tagf
, "\f\n%s,%d\n",
1990 fdp
->taggedfname
, total_size_of_entries (np
));
1992 fputs (np
->pat
, tagf
);
1993 fputc ('\177', tagf
);
1994 if (np
->name
!= NULL
)
1996 fputs (np
->name
, tagf
);
1997 fputc ('\001', tagf
);
1999 fprintf (tagf
, "%d,", np
->lno
);
2000 if (np
->cno
!= invalidcharno
)
2001 fprintf (tagf
, "%ld", np
->cno
);
2007 if (np
->name
== NULL
)
2008 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
2013 fprintf (stdout
, "%s %s %d\n",
2014 np
->name
, np
->fdp
->taggedfname
, (np
->lno
+ 63) / 64);
2016 fprintf (stdout
, "%-16s %3d %-16s %s\n",
2017 np
->name
, np
->lno
, np
->fdp
->taggedfname
, np
->pat
);
2021 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->fdp
->taggedfname
);
2024 { /* function or #define macro with args */
2025 putc (searchar
, tagf
);
2028 for (sp
= np
->pat
; *sp
; sp
++)
2030 if (*sp
== '\\' || *sp
== searchar
)
2034 putc (searchar
, tagf
);
2037 { /* anything else; text pattern inadequate */
2038 fprintf (tagf
, "%d", np
->lno
);
2043 } /* if this node contains a valid tag */
2045 /* Output subentries that follow this one */
2046 put_entries (np
->right
);
2048 put_entries (np
->left
);
2053 #define C_EXT 0x00fff /* C extensions */
2054 #define C_PLAIN 0x00000 /* C */
2055 #define C_PLPL 0x00001 /* C++ */
2056 #define C_STAR 0x00003 /* C* */
2057 #define C_JAVA 0x00005 /* JAVA */
2058 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
2059 #define YACC 0x10000 /* yacc file */
2062 * The C symbol tables.
2067 st_C_objprot
, st_C_objimpl
, st_C_objend
,
2072 st_C_class
, st_C_template
,
2073 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
2076 static unsigned int hash
__P((const char *, unsigned int));
2077 static struct C_stab_entry
* in_word_set
__P((const char *, unsigned int));
2078 static enum sym_type C_symtype
__P((char *, int, int));
2080 /* Feed stuff between (but not including) %[ and %] lines to:
2081 gperf -c -k 1,3 -o -p -r -t
2083 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
2087 while, 0, st_C_ignore
2088 switch, 0, st_C_ignore
2089 return, 0, st_C_ignore
2090 @interface, 0, st_C_objprot
2091 @protocol, 0, st_C_objprot
2092 @implementation,0, st_C_objimpl
2093 @end, 0, st_C_objend
2094 import, C_JAVA, st_C_ignore
2095 package, C_JAVA, st_C_ignore
2096 friend, C_PLPL, st_C_ignore
2097 extends, C_JAVA, st_C_javastruct
2098 implements, C_JAVA, st_C_javastruct
2099 interface, C_JAVA, st_C_struct
2100 class, 0, st_C_class
2101 namespace, C_PLPL, st_C_struct
2102 domain, C_STAR, st_C_struct
2103 union, 0, st_C_struct
2104 struct, 0, st_C_struct
2105 extern, 0, st_C_extern
2107 typedef, 0, st_C_typedef
2108 define, 0, st_C_define
2109 operator, C_PLPL, st_C_operator
2110 template, 0, st_C_template
2111 bool, C_PLPL, st_C_typespec
2112 long, 0, st_C_typespec
2113 short, 0, st_C_typespec
2114 int, 0, st_C_typespec
2115 char, 0, st_C_typespec
2116 float, 0, st_C_typespec
2117 double, 0, st_C_typespec
2118 signed, 0, st_C_typespec
2119 unsigned, 0, st_C_typespec
2120 auto, 0, st_C_typespec
2121 void, 0, st_C_typespec
2122 static, 0, st_C_typespec
2123 const, 0, st_C_typespec
2124 volatile, 0, st_C_typespec
2125 explicit, C_PLPL, st_C_typespec
2126 mutable, C_PLPL, st_C_typespec
2127 typename, C_PLPL, st_C_typespec
2128 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
2129 DEFUN, 0, st_C_gnumacro
2130 SYSCALL, 0, st_C_gnumacro
2131 ENTRY, 0, st_C_gnumacro
2132 PSEUDO, 0, st_C_gnumacro
2133 # These are defined inside C functions, so currently they are not met.
2134 # EXFUN used in glibc, DEFVAR_* in emacs.
2135 #EXFUN, 0, st_C_gnumacro
2136 #DEFVAR_, 0, st_C_gnumacro
2138 and replace lines between %< and %> with its output,
2139 then make in_word_set and C_stab_entry static. */
2141 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
2142 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
2143 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2145 #define TOTAL_KEYWORDS 47
2146 #define MIN_WORD_LENGTH 2
2147 #define MAX_WORD_LENGTH 15
2148 #define MIN_HASH_VALUE 18
2149 #define MAX_HASH_VALUE 138
2150 /* maximum key range = 121, duplicates = 0 */
2157 register const char *str
;
2158 register unsigned int len
;
2160 static unsigned char asso_values
[] =
2162 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2163 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2164 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2165 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2166 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2167 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2168 139, 139, 139, 139, 63, 139, 139, 139, 33, 44,
2169 62, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2170 42, 139, 139, 12, 32, 139, 139, 139, 139, 139,
2171 139, 139, 139, 139, 139, 139, 139, 34, 59, 37,
2172 24, 58, 33, 3, 139, 16, 139, 139, 42, 60,
2173 18, 11, 39, 139, 23, 57, 4, 63, 6, 20,
2174 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2175 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2176 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2177 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2178 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2179 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2180 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2181 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2182 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2183 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2184 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2185 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2186 139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
2187 139, 139, 139, 139, 139, 139
2189 register int hval
= len
;
2195 hval
+= asso_values
[(unsigned char)str
[2]];
2198 hval
+= asso_values
[(unsigned char)str
[0]];
2207 static struct C_stab_entry
*
2208 in_word_set (str
, len
)
2209 register const char *str
;
2210 register unsigned int len
;
2212 static struct C_stab_entry wordlist
[] =
2214 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2215 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2216 {"if", 0, st_C_ignore
},
2217 {""}, {""}, {""}, {""},
2218 {"int", 0, st_C_typespec
},
2220 {"void", 0, st_C_typespec
},
2222 {"interface", C_JAVA
, st_C_struct
},
2224 {"SYSCALL", 0, st_C_gnumacro
},
2226 {"return", 0, st_C_ignore
},
2227 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2228 {"while", 0, st_C_ignore
},
2229 {"auto", 0, st_C_typespec
},
2230 {""}, {""}, {""}, {""}, {""}, {""},
2231 {"float", 0, st_C_typespec
},
2232 {"typedef", 0, st_C_typedef
},
2233 {"typename", C_PLPL
, st_C_typespec
},
2235 {"friend", C_PLPL
, st_C_ignore
},
2236 {"volatile", 0, st_C_typespec
},
2238 {"for", 0, st_C_ignore
},
2239 {"const", 0, st_C_typespec
},
2240 {"import", C_JAVA
, st_C_ignore
},
2242 {"define", 0, st_C_define
},
2243 {"long", 0, st_C_typespec
},
2244 {"implements", C_JAVA
, st_C_javastruct
},
2245 {"signed", 0, st_C_typespec
},
2247 {"extern", 0, st_C_extern
},
2248 {"extends", C_JAVA
, st_C_javastruct
},
2250 {"mutable", C_PLPL
, st_C_typespec
},
2251 {"template", 0, st_C_template
},
2252 {"short", 0, st_C_typespec
},
2253 {"bool", C_PLPL
, st_C_typespec
},
2254 {"char", 0, st_C_typespec
},
2255 {"class", 0, st_C_class
},
2256 {"operator", C_PLPL
, st_C_operator
},
2258 {"switch", 0, st_C_ignore
},
2260 {"ENTRY", 0, st_C_gnumacro
},
2262 {"package", C_JAVA
, st_C_ignore
},
2263 {"union", 0, st_C_struct
},
2264 {"@end", 0, st_C_objend
},
2265 {"struct", 0, st_C_struct
},
2266 {"namespace", C_PLPL
, st_C_struct
},
2268 {"domain", C_STAR
, st_C_struct
},
2269 {"@interface", 0, st_C_objprot
},
2270 {"PSEUDO", 0, st_C_gnumacro
},
2271 {"double", 0, st_C_typespec
},
2273 {"@protocol", 0, st_C_objprot
},
2275 {"static", 0, st_C_typespec
},
2277 {"DEFUN", 0, st_C_gnumacro
},
2278 {""}, {""}, {""}, {""},
2279 {"explicit", C_PLPL
, st_C_typespec
},
2280 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2281 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2283 {"enum", 0, st_C_enum
},
2285 {"unsigned", 0, st_C_typespec
},
2286 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2287 {"@implementation",0, st_C_objimpl
}
2290 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2292 register int key
= hash (str
, len
);
2294 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2296 register const char *s
= wordlist
[key
].name
;
2298 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
2299 return &wordlist
[key
];
2306 static enum sym_type
2307 C_symtype (str
, len
, c_ext
)
2312 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2314 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2321 * C functions and variables are recognized using a simple
2322 * finite automaton. fvdef is its state variable.
2326 fvnone
, /* nothing seen */
2327 fdefunkey
, /* Emacs DEFUN keyword seen */
2328 fdefunname
, /* Emacs DEFUN name seen */
2329 foperator
, /* func: operator keyword seen (cplpl) */
2330 fvnameseen
, /* function or variable name seen */
2331 fstartlist
, /* func: just after open parenthesis */
2332 finlist
, /* func: in parameter list */
2333 flistseen
, /* func: after parameter list */
2334 fignore
, /* func: before open brace */
2335 vignore
/* var-like: ignore until ';' */
2338 static bool fvextern
; /* func or var: extern keyword seen; */
2341 * typedefs are recognized using a simple finite automaton.
2342 * typdef is its state variable.
2346 tnone
, /* nothing seen */
2347 tkeyseen
, /* typedef keyword seen */
2348 ttypeseen
, /* defined type seen */
2349 tinbody
, /* inside typedef body */
2350 tend
, /* just before typedef tag */
2351 tignore
/* junk after typedef tag */
2355 * struct-like structures (enum, struct and union) are recognized
2356 * using another simple finite automaton. `structdef' is its state
2361 snone
, /* nothing seen yet,
2362 or in struct body if cblev > 0 */
2363 skeyseen
, /* struct-like keyword seen */
2364 stagseen
, /* struct-like tag seen */
2365 sintemplate
, /* inside template (ignore) */
2366 scolonseen
/* colon seen after struct-like tag */
2370 * When objdef is different from onone, objtag is the name of the class.
2372 static char *objtag
= "<uninited>";
2375 * Yet another little state machine to deal with preprocessor lines.
2379 dnone
, /* nothing seen */
2380 dsharpseen
, /* '#' seen as first char on line */
2381 ddefineseen
, /* '#' and 'define' seen */
2382 dignorerest
/* ignore rest of line */
2386 * State machine for Objective C protocols and implementations.
2387 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2391 onone
, /* nothing seen */
2392 oprotocol
, /* @interface or @protocol seen */
2393 oimplementation
, /* @implementations seen */
2394 otagseen
, /* class name seen */
2395 oparenseen
, /* parenthesis before category seen */
2396 ocatseen
, /* category name seen */
2397 oinbody
, /* in @implementation body */
2398 omethodsign
, /* in @implementation body, after +/- */
2399 omethodtag
, /* after method name */
2400 omethodcolon
, /* after method colon */
2401 omethodparm
, /* after method parameter */
2402 oignore
/* wait for @end */
2407 * Use this structure to keep info about the token read, and how it
2408 * should be tagged. Used by the make_C_tag function to build a tag.
2419 } token
; /* latest token read */
2420 static linebuffer token_name
; /* its name */
2423 * Variables and functions for dealing with nested structures.
2424 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2426 static void pushclass_above
__P((int, char *, int));
2427 static void popclass_above
__P((int));
2428 static void write_classname
__P((linebuffer
*, char *qualifier
));
2431 char **cname
; /* nested class names */
2432 int *cblev
; /* nested class curly brace level */
2433 int nl
; /* class nesting level (elements used) */
2434 int size
; /* length of the array */
2435 } cstack
; /* stack for nested declaration tags */
2436 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2437 #define nestlev (cstack.nl)
2438 /* After struct keyword or in struct body, not inside an nested function. */
2439 #define instruct (structdef == snone && nestlev > 0 \
2440 && cblev == cstack.cblev[nestlev-1] + 1)
2443 pushclass_above (cblev
, str
, len
)
2450 popclass_above (cblev
);
2452 if (nl
>= cstack
.size
)
2454 int size
= cstack
.size
*= 2;
2455 xrnew (cstack
.cname
, size
, char *);
2456 xrnew (cstack
.cblev
, size
, int);
2458 assert (nl
== 0 || cstack
.cblev
[nl
-1] < cblev
);
2459 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2460 cstack
.cblev
[nl
] = cblev
;
2465 popclass_above (cblev
)
2470 for (nl
= cstack
.nl
- 1;
2471 nl
>= 0 && cstack
.cblev
[nl
] >= cblev
;
2474 if (cstack
.cname
[nl
] != NULL
)
2475 free (cstack
.cname
[nl
]);
2481 write_classname (cn
, qualifier
)
2486 int qlen
= strlen (qualifier
);
2488 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2492 cn
->buffer
[0] = '\0';
2496 len
= strlen (cstack
.cname
[0]);
2497 linebuffer_setlen (cn
, len
);
2498 strcpy (cn
->buffer
, cstack
.cname
[0]);
2500 for (i
= 1; i
< cstack
.nl
; i
++)
2505 s
= cstack
.cname
[i
];
2510 linebuffer_setlen (cn
, len
);
2511 strncat (cn
->buffer
, qualifier
, qlen
);
2512 strncat (cn
->buffer
, s
, slen
);
2517 static bool consider_token
__P((char *, int, int, int *, int, int, bool *));
2518 static void make_C_tag
__P((bool));
2522 * checks to see if the current token is at the start of a
2523 * function or variable, or corresponds to a typedef, or
2524 * is a struct/union/enum tag, or #define, or an enum constant.
2526 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2527 * with args. C_EXTP points to which language we are looking at.
2538 consider_token (str
, len
, c
, c_extp
, cblev
, parlev
, is_func_or_var
)
2539 register char *str
; /* IN: token pointer */
2540 register int len
; /* IN: token length */
2541 register int c
; /* IN: first char after the token */
2542 int *c_extp
; /* IN, OUT: C extensions mask */
2543 int cblev
; /* IN: curly brace level */
2544 int parlev
; /* IN: parenthesis level */
2545 bool *is_func_or_var
; /* OUT: function or variable found */
2547 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2548 structtype is the type of the preceding struct-like keyword, and
2549 structcblev is the curly brace level where it has been seen. */
2550 static enum sym_type structtype
;
2551 static int structcblev
;
2552 static enum sym_type toktype
;
2555 toktype
= C_symtype (str
, len
, *c_extp
);
2558 * Advance the definedef state machine.
2563 /* We're not on a preprocessor line. */
2564 if (toktype
== st_C_gnumacro
)
2571 if (toktype
== st_C_define
)
2573 definedef
= ddefineseen
;
2577 definedef
= dignorerest
;
2582 * Make a tag for any macro, unless it is a constant
2583 * and constantypedefs is FALSE.
2585 definedef
= dignorerest
;
2586 *is_func_or_var
= (c
== '(');
2587 if (!*is_func_or_var
&& !constantypedefs
)
2594 error ("internal error: definedef value.", (char *)NULL
);
2603 if (toktype
== st_C_typedef
)
2625 if (structdef
== snone
&& fvdef
== fvnone
)
2644 * This structdef business is NOT invoked when we are ctags and the
2645 * file is plain C. This is because a struct tag may have the same
2646 * name as another tag, and this loses with ctags.
2650 case st_C_javastruct
:
2651 if (structdef
== stagseen
)
2652 structdef
= scolonseen
;
2657 && (*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2658 && definedef
== dnone
&& structdef
== snone
2659 && typdef
== tnone
&& fvdef
== fvnone
)
2660 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2661 if (toktype
== st_C_template
)
2668 && (typdef
== tkeyseen
2669 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2671 structdef
= skeyseen
;
2672 structtype
= toktype
;
2673 structcblev
= cblev
;
2678 if (structdef
== skeyseen
)
2680 structdef
= stagseen
;
2684 if (typdef
!= tnone
)
2687 /* Detect Objective C constructs. */
2697 objdef
= oimplementation
;
2701 case oimplementation
:
2702 /* Save the class tag for functions or variables defined inside. */
2703 objtag
= savenstr (str
, len
);
2707 /* Save the class tag for categories. */
2708 objtag
= savenstr (str
, len
);
2710 *is_func_or_var
= TRUE
;
2714 *is_func_or_var
= TRUE
;
2721 objdef
= omethodtag
;
2722 linebuffer_setlen (&token_name
, len
);
2723 strncpy (token_name
.buffer
, str
, len
);
2724 token_name
.buffer
[len
] = '\0';
2730 objdef
= omethodparm
;
2735 objdef
= omethodtag
;
2736 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
2737 strncat (token_name
.buffer
, str
, len
);
2742 if (toktype
== st_C_objend
)
2744 /* Memory leakage here: the string pointed by objtag is
2745 never released, because many tests would be needed to
2746 avoid breaking on incorrect input code. The amount of
2747 memory leaked here is the sum of the lengths of the
2755 /* A function, variable or enum constant? */
2762 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2763 fvdef
= fvnone
; /* should be useless */
2771 *is_func_or_var
= TRUE
;
2775 && structdef
== snone
2776 && structtype
== st_C_enum
&& cblev
> structcblev
)
2777 return TRUE
; /* enum constant */
2783 fvdef
= fdefunname
; /* GNU macro */
2784 *is_func_or_var
= TRUE
;
2787 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
2788 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
2793 if ((*c_extp
& C_PLPL
) && strneq (str
+len
-10, "::operator", 10))
2796 *is_func_or_var
= TRUE
;
2799 if (cblev
> 0 && !instruct
)
2801 fvdef
= fvnameseen
; /* function or variable */
2802 *is_func_or_var
= TRUE
;
2813 * C_entries often keeps pointers to tokens or lines which are older than
2814 * the line currently read. By keeping two line buffers, and switching
2815 * them at end of line, it is possible to use those pointers.
2823 #define current_lb_is_new (newndx == curndx)
2824 #define switch_line_buffers() (curndx = 1 - curndx)
2826 #define curlb (lbs[curndx].lb)
2827 #define newlb (lbs[newndx].lb)
2828 #define curlinepos (lbs[curndx].linepos)
2829 #define newlinepos (lbs[newndx].linepos)
2831 #define CNL_SAVE_DEFINEDEF() \
2833 curlinepos = charno; \
2835 linecharno = charno; \
2836 charno += readline (&curlb, inf); \
2837 lp = curlb.buffer; \
2844 CNL_SAVE_DEFINEDEF(); \
2845 if (savetoken.valid) \
2847 token = savetoken; \
2848 savetoken.valid = FALSE; \
2850 definedef = dnone; \
2858 /* This function should never be called when token.valid is FALSE, but
2859 we must protect against invalid input or internal errors. */
2860 if (DEBUG
|| token
.valid
)
2862 if (traditional_tag_style
)
2864 /* This was the original code. Now we call new_pfnote instead,
2865 which uses the new method for naming tags (see new_pfnote). */
2868 if (CTAGS
|| token
.named
)
2869 name
= savestr (token_name
.buffer
);
2870 if (DEBUG
&& !token
.valid
)
2873 name
= concat (name
, "##invalid##", "");
2875 name
= savestr ("##invalid##");
2877 pfnote (name
, isfun
, token
.line
,
2878 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2881 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
2882 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2883 token
.valid
= FALSE
;
2890 * This routine finds functions, variables, typedefs,
2891 * #define's, enum constants and struct/union/enum definitions in
2892 * C syntax and adds them to the list.
2895 C_entries (c_ext
, inf
)
2896 int c_ext
; /* extension of C */
2897 FILE *inf
; /* input file */
2899 register char c
; /* latest char read; '\0' for end of line */
2900 register char *lp
; /* pointer one beyond the character `c' */
2901 int curndx
, newndx
; /* indices for current and new lb */
2902 register int tokoff
; /* offset in line of start of current token */
2903 register int toklen
; /* length of current token */
2904 char *qualifier
; /* string used to qualify names */
2905 int qlen
; /* length of qualifier */
2906 int cblev
; /* current curly brace level */
2907 int parlev
; /* current parenthesis level */
2908 int typdefcblev
; /* cblev where a typedef struct body begun */
2909 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2911 bool yacc_rules
; /* in the rules part of a yacc file */
2912 struct tok savetoken
; /* token saved during preprocessor handling */
2915 initbuffer (&token_name
);
2916 initbuffer (&lbs
[0].lb
);
2917 initbuffer (&lbs
[1].lb
);
2918 if (cstack
.size
== 0)
2920 cstack
.size
= (DEBUG
) ? 1 : 4;
2922 cstack
.cname
= xnew (cstack
.size
, char *);
2923 cstack
.cblev
= xnew (cstack
.size
, int);
2926 tokoff
= toklen
= typdefcblev
= 0; /* keep compiler quiet */
2927 curndx
= newndx
= 0;
2933 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
2934 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
2936 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2937 token
.valid
= savetoken
.valid
= FALSE
;
2940 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2941 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2943 { qualifier
= "."; qlen
= 1; }
2945 { qualifier
= "::"; qlen
= 2; }
2953 /* If we're at the end of the line, the next character is a
2954 '\0'; don't skip it, because it's the thing that tells us
2955 to read the next line. */
2976 /* Newlines inside comments do not end macro definitions in
2978 CNL_SAVE_DEFINEDEF ();
2991 /* Newlines inside strings do not end macro definitions
2992 in traditional cpp, even though compilers don't
2993 usually accept them. */
2994 CNL_SAVE_DEFINEDEF ();
3004 /* Hmmm, something went wrong. */
3033 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
3046 else if (/* cplpl && */ *lp
== '/')
3054 if ((c_ext
& YACC
) && *lp
== '%')
3056 /* Entering or exiting rules section in yacc file. */
3058 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
3059 typdef
= tnone
; structdef
= snone
;
3060 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
3062 yacc_rules
= !yacc_rules
;
3068 if (definedef
== dnone
)
3071 bool cpptoken
= TRUE
;
3073 /* Look back on this line. If all blanks, or nonblanks
3074 followed by an end of comment, this is a preprocessor
3076 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
3079 if (*cp
== '*' && *(cp
+1) == '/')
3088 definedef
= dsharpseen
;
3089 } /* if (definedef == dnone) */
3095 /* Consider token only if some involved conditions are satisfied. */
3096 if (typdef
!= tignore
3097 && definedef
!= dignorerest
3099 && structdef
!= sintemplate
3100 && (definedef
!= dnone
3101 || structdef
!= scolonseen
))
3107 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken (lp
[1]))
3110 * This handles :: in the middle, but not at the
3111 * beginning of an identifier. Also, space-separated
3112 * :: is not recognised.
3117 goto still_in_token
;
3121 bool funorvar
= FALSE
;
3124 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
3125 &c_ext
, cblev
, parlev
, &funorvar
))
3127 if (fvdef
== foperator
)
3130 lp
= skip_spaces (lp
-1);
3134 && !iswhite (*lp
) && *lp
!= '(')
3137 toklen
+= lp
- oldlp
;
3139 token
.named
= FALSE
;
3140 if ((c_ext
& C_EXT
) /* not pure C */
3141 && nestlev
> 0 && definedef
== dnone
)
3142 /* in struct body */
3144 write_classname (&token_name
, qualifier
);
3145 linebuffer_setlen (&token_name
,
3146 token_name
.len
+qlen
+toklen
);
3147 strcat (token_name
.buffer
, qualifier
);
3148 strncat (token_name
.buffer
,
3149 newlb
.buffer
+ tokoff
, toklen
);
3152 else if (objdef
== ocatseen
)
3153 /* Objective C category */
3155 int len
= strlen (objtag
) + 2 + toklen
;
3156 linebuffer_setlen (&token_name
, len
);
3157 strcpy (token_name
.buffer
, objtag
);
3158 strcat (token_name
.buffer
, "(");
3159 strncat (token_name
.buffer
,
3160 newlb
.buffer
+ tokoff
, toklen
);
3161 strcat (token_name
.buffer
, ")");
3164 else if (objdef
== omethodtag
3165 || objdef
== omethodparm
)
3166 /* Objective C method */
3170 else if (fvdef
== fdefunname
)
3171 /* GNU DEFUN and similar macros */
3173 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3177 /* Rewrite the tag so that emacs lisp DEFUNs
3178 can be found by their elisp name */
3185 linebuffer_setlen (&token_name
, len
);
3186 strncpy (token_name
.buffer
,
3187 newlb
.buffer
+ off
, len
);
3188 token_name
.buffer
[len
] = '\0';
3191 if (token_name
.buffer
[len
] == '_')
3192 token_name
.buffer
[len
] = '-';
3193 token
.named
= defun
;
3197 linebuffer_setlen (&token_name
, toklen
);
3198 strncpy (token_name
.buffer
,
3199 newlb
.buffer
+ tokoff
, toklen
);
3200 token_name
.buffer
[toklen
] = '\0';
3201 /* Name macros and members. */
3202 token
.named
= (structdef
== stagseen
3203 || typdef
== ttypeseen
3206 && definedef
== dignorerest
)
3208 && definedef
== dnone
3209 && structdef
== snone
3212 token
.lineno
= lineno
;
3213 token
.offset
= tokoff
;
3214 token
.length
= toklen
;
3215 token
.line
= newlb
.buffer
;
3216 token
.linepos
= newlinepos
;
3219 if (definedef
== dnone
3220 && (fvdef
== fvnameseen
3221 || fvdef
== foperator
3222 || structdef
== stagseen
3224 || typdef
== ttypeseen
3225 || objdef
!= onone
))
3227 if (current_lb_is_new
)
3228 switch_line_buffers ();
3230 else if (definedef
!= dnone
3231 || fvdef
== fdefunname
3233 make_C_tag (funorvar
);
3237 } /* if (endtoken (c)) */
3238 else if (intoken (c
))
3244 } /* if (midtoken) */
3245 else if (begtoken (c
))
3256 make_C_tag (TRUE
); /* a function */
3263 if (structdef
== stagseen
&& !cjava
)
3265 popclass_above (cblev
);
3272 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3274 tokoff
= lp
- 1 - newlb
.buffer
;
3279 } /* if (begtoken) */
3280 } /* if must look at token */
3283 /* Detect end of line, colon, comma, semicolon and various braces
3284 after having handled a token.*/
3288 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3290 make_C_tag (FALSE
); /* a yacc function */
3293 if (definedef
!= dnone
)
3299 make_C_tag (TRUE
); /* an Objective C class */
3303 objdef
= omethodcolon
;
3304 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3305 strcat (token_name
.buffer
, ":");
3308 if (structdef
== stagseen
)
3309 structdef
= scolonseen
;
3312 if (definedef
!= dnone
)
3318 make_C_tag (FALSE
); /* a typedef */
3328 if (typdef
== tignore
)
3332 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3333 || (members
&& instruct
))
3334 make_C_tag (FALSE
); /* a variable */
3337 token
.valid
= FALSE
;
3340 if ((declarations
&& typdef
== tnone
&& !instruct
)
3341 || (members
&& typdef
!= tignore
&& instruct
))
3342 make_C_tag (TRUE
); /* a function declaration */
3348 && structdef
== stagseen
&& (c_ext
& C_PLPL
))
3349 make_C_tag (FALSE
); /* forward declaration */
3351 /* The following instruction invalidates the token.
3352 Probably the token should be invalidated in all other
3353 cases where some state machine is reset prematurely. */
3354 token
.valid
= FALSE
;
3355 } /* switch (fvdef) */
3361 if (structdef
== stagseen
)
3365 if (definedef
!= dnone
)
3371 make_C_tag (TRUE
); /* an Objective C method */
3387 case fvnameseen
: /* a variable */
3388 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3389 || (members
&& instruct
))
3392 case flistseen
: /* a function */
3393 if ((declarations
&& typdef
== tnone
&& !instruct
)
3394 || (members
&& typdef
!= tignore
&& instruct
))
3396 make_C_tag (TRUE
); /* a function declaration */
3399 else if (!declarations
)
3401 token
.valid
= FALSE
;
3406 if (structdef
== stagseen
)
3410 if (definedef
!= dnone
)
3412 if (structdef
== stagseen
)
3419 make_C_tag (FALSE
); /* a typedef */
3431 if ((members
&& cblev
== 1)
3432 || (globals
&& cblev
== 0
3433 && (!fvextern
|| declarations
)))
3434 make_C_tag (FALSE
); /* a variable */
3443 if (definedef
!= dnone
)
3445 if (objdef
== otagseen
&& parlev
== 0)
3446 objdef
= oparenseen
;
3450 if (typdef
== ttypeseen
3454 /* This handles constructs like:
3455 typedef void OperatorFun (int fun); */
3472 if (definedef
!= dnone
)
3474 if (objdef
== ocatseen
&& parlev
== 1)
3476 make_C_tag (TRUE
); /* an Objective C category */
3490 || typdef
== ttypeseen
))
3493 make_C_tag (FALSE
); /* a typedef */
3496 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3500 if (definedef
!= dnone
)
3502 if (typdef
== ttypeseen
)
3504 /* Whenever typdef is set to tinbody (currently only
3505 here), typdefcblev should be set to cblev. */
3507 typdefcblev
= cblev
;
3512 make_C_tag (TRUE
); /* a function */
3521 make_C_tag (TRUE
); /* an Objective C class */
3526 make_C_tag (TRUE
); /* an Objective C method */
3530 /* Neutralize `extern "C" {' grot. */
3531 if (cblev
== 0 && structdef
== snone
&& nestlev
== 0
3538 case skeyseen
: /* unnamed struct */
3539 pushclass_above (cblev
, NULL
, 0);
3542 case stagseen
: /* named struct or enum */
3543 case scolonseen
: /* a class */
3544 pushclass_above (cblev
, token
.line
+token
.offset
, token
.length
);
3546 make_C_tag (FALSE
); /* a struct or enum */
3552 if (definedef
!= dnone
)
3554 if (fvdef
== fstartlist
)
3555 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3558 if (definedef
!= dnone
)
3560 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
3562 cblev
= 0; /* reset curly brace level if first column */
3563 parlev
= 0; /* also reset paren level, just in case... */
3567 popclass_above (cblev
);
3569 /* Only if typdef == tinbody is typdefcblev significant. */
3570 if (typdef
== tinbody
&& cblev
<= typdefcblev
)
3572 assert (cblev
== typdefcblev
);
3577 if (definedef
!= dnone
)
3587 if ((members
&& cblev
== 1)
3588 || (globals
&& cblev
== 0 && (!fvextern
|| declarations
)))
3589 make_C_tag (FALSE
); /* a variable */
3596 if (cplpl
&& structdef
== stagseen
)
3598 structdef
= sintemplate
;
3603 if (structdef
== sintemplate
)
3605 structdef
= stagseen
;
3611 if (objdef
== oinbody
&& cblev
== 0)
3613 objdef
= omethodsign
;
3618 case '#': case '~': case '&': case '%': case '/': case '|':
3619 case '^': case '!': case '.': case '?': case ']':
3620 if (definedef
!= dnone
)
3622 /* These surely cannot follow a function tag in C. */
3635 if (objdef
== otagseen
)
3637 make_C_tag (TRUE
); /* an Objective C class */
3640 /* If a macro spans multiple lines don't reset its state. */
3642 CNL_SAVE_DEFINEDEF ();
3648 } /* while not eof */
3650 free (token_name
.buffer
);
3651 free (lbs
[0].lb
.buffer
);
3652 free (lbs
[1].lb
.buffer
);
3656 * Process either a C++ file or a C file depending on the setting
3660 default_C_entries (inf
)
3663 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
3666 /* Always do plain C. */
3668 plain_C_entries (inf
)
3674 /* Always do C++. */
3676 Cplusplus_entries (inf
)
3679 C_entries (C_PLPL
, inf
);
3682 /* Always do Java. */
3687 C_entries (C_JAVA
, inf
);
3695 C_entries (C_STAR
, inf
);
3698 /* Always do Yacc. */
3703 C_entries (YACC
, inf
);
3707 /* Useful macros. */
3708 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3709 for (lineno = charno = 0; /* loop initialization */ \
3710 !feof (file_pointer) /* loop test */ \
3711 && (lineno++, /* instructions at start of loop */ \
3712 linecharno = charno, \
3713 charno += readline (&line_buffer, file_pointer), \
3714 char_pointer = lb.buffer, \
3717 #define LOOKING_AT(cp, keyword) /* keyword is a constant string */ \
3718 (strneq ((cp), keyword, sizeof(keyword)-1) /* cp points at keyword */ \
3719 && notinname ((cp)[sizeof(keyword)-1]) /* end of keyword */ \
3720 && ((cp) = skip_spaces((cp)+sizeof(keyword)-1))) /* skip spaces */
3723 * Read a file, but do no processing. This is used to do regexp
3724 * matching on files that have no language defined.
3727 just_read_file (inf
)
3730 register char *dummy
;
3732 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
3737 /* Fortran parsing */
3739 static void F_takeprec
__P((void));
3740 static void F_getit
__P((FILE *));
3745 dbp
= skip_spaces (dbp
);
3749 dbp
= skip_spaces (dbp
);
3750 if (strneq (dbp
, "(*)", 3))
3755 if (!ISDIGIT (*dbp
))
3757 --dbp
; /* force failure */
3762 while (ISDIGIT (*dbp
));
3771 dbp
= skip_spaces (dbp
);
3775 linecharno
= charno
;
3776 charno
+= readline (&lb
, inf
);
3781 dbp
= skip_spaces (dbp
);
3783 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
3785 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
3787 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3788 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3793 Fortran_functions (inf
)
3796 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3799 dbp
++; /* Ratfor escape to fortran */
3800 dbp
= skip_spaces (dbp
);
3803 switch (lowcase (*dbp
))
3806 if (nocase_tail ("integer"))
3810 if (nocase_tail ("real"))
3814 if (nocase_tail ("logical"))
3818 if (nocase_tail ("complex") || nocase_tail ("character"))
3822 if (nocase_tail ("double"))
3824 dbp
= skip_spaces (dbp
);
3827 if (nocase_tail ("precision"))
3833 dbp
= skip_spaces (dbp
);
3836 switch (lowcase (*dbp
))
3839 if (nocase_tail ("function"))
3843 if (nocase_tail ("subroutine"))
3847 if (nocase_tail ("entry"))
3851 if (nocase_tail ("blockdata") || nocase_tail ("block data"))
3853 dbp
= skip_spaces (dbp
);
3854 if (*dbp
== '\0') /* assume un-named */
3855 pfnote (savestr ("blockdata"), TRUE
,
3856 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
3858 F_getit (inf
); /* look for name */
3869 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3872 static void Ada_getit
__P((FILE *, char *));
3874 /* Once we are positioned after an "interesting" keyword, let's get
3875 the real tag value necessary. */
3877 Ada_getit (inf
, name_qualifier
)
3879 char *name_qualifier
;
3887 dbp
= skip_spaces (dbp
);
3889 || (dbp
[0] == '-' && dbp
[1] == '-'))
3892 linecharno
= charno
;
3893 charno
+= readline (&lb
, inf
);
3896 switch (lowcase(*dbp
))
3899 if (nocase_tail ("body"))
3901 /* Skipping body of procedure body or package body or ....
3902 resetting qualifier to body instead of spec. */
3903 name_qualifier
= "/b";
3908 /* Skipping type of task type or protected type ... */
3909 if (nocase_tail ("type"))
3916 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
3921 dbp
= skip_spaces (dbp
);
3924 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
3932 name
= concat (dbp
, name_qualifier
, "");
3934 pfnote (name
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3945 bool inquote
= FALSE
;
3947 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3949 while (*dbp
!= '\0')
3951 /* Skip a string i.e. "abcd". */
3952 if (inquote
|| (*dbp
== '"'))
3954 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
3959 continue; /* advance char */
3964 break; /* advance line */
3968 /* Skip comments. */
3969 if (dbp
[0] == '-' && dbp
[1] == '-')
3970 break; /* advance line */
3972 /* Skip character enclosed in single quote i.e. 'a'
3973 and skip single quote starting an attribute i.e. 'Image. */
3982 /* Search for beginning of a token. */
3983 if (!begtoken (*dbp
))
3986 continue; /* advance char */
3989 /* We are at the beginning of a token. */
3990 switch (lowcase(*dbp
))
3993 if (!packages_only
&& nocase_tail ("function"))
3994 Ada_getit (inf
, "/f");
3996 break; /* from switch */
3997 continue; /* advance char */
3999 if (!packages_only
&& nocase_tail ("procedure"))
4000 Ada_getit (inf
, "/p");
4001 else if (nocase_tail ("package"))
4002 Ada_getit (inf
, "/s");
4003 else if (nocase_tail ("protected")) /* protected type */
4004 Ada_getit (inf
, "/t");
4006 break; /* from switch */
4007 continue; /* advance char */
4009 if (!packages_only
&& nocase_tail ("task"))
4010 Ada_getit (inf
, "/k");
4011 else if (typedefs
&& !packages_only
&& nocase_tail ("type"))
4013 Ada_getit (inf
, "/t");
4014 while (*dbp
!= '\0')
4018 break; /* from switch */
4019 continue; /* advance char */
4022 /* Look for the end of the token. */
4023 while (!endtoken (*dbp
))
4026 } /* advance char */
4027 } /* advance line */
4032 * Unix and microcontroller assembly tag handling
4033 * Labels: /^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]/
4034 * Idea by Bob Weiner, Motorola Inc. (1994)
4042 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4044 /* If first char is alphabetic or one of [_.$], test for colon
4045 following identifier. */
4046 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4048 /* Read past label. */
4050 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
4052 if (*cp
== ':' || iswhite (*cp
))
4054 /* Found end of label, so copy it and add it to the table. */
4055 pfnote (savenstr(lb
.buffer
, cp
-lb
.buffer
), TRUE
,
4056 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4065 * Perl sub names: /^sub[ \t\n]+[^ \t\n{]+/
4066 * Perl variable names: /^(my|local).../
4067 * Original code by Bart Robinson <lomew@cs.utah.edu> (1995)
4068 * Additions by Michael Ernst <mernst@alum.mit.edu> (1997)
4069 * Ideas by Kai Großjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> (2001)
4072 Perl_functions (inf
)
4075 char *package
= savestr ("main"); /* current package name */
4078 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4082 if (LOOKING_AT (cp
, "package"))
4085 package
= get_tag (cp
);
4086 if (package
== NULL
) /* can't parse package name */
4087 package
= savestr ("");
4089 package
= savestr(package
); /* make a copy */
4091 else if (LOOKING_AT (cp
, "sub"))
4093 char *name
, *fullname
, *pos
;
4096 while (!notinname (*cp
))
4100 name
= savenstr (sp
, cp
-sp
);
4101 if ((pos
= etags_strchr (name
, ':')) != NULL
&& pos
[1] == ':')
4104 fullname
= concat (package
, "::", name
);
4105 pfnote (fullname
, TRUE
,
4106 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4107 if (name
!= fullname
)
4110 else if (globals
/* only if tagging global vars is enabled */
4111 && (LOOKING_AT (cp
, "my") || LOOKING_AT (cp
, "local")))
4113 /* After "my" or "local", but before any following paren or space. */
4114 char *varname
= NULL
;
4116 if (*cp
== '$' || *cp
== '@' || *cp
== '%')
4118 char* varstart
= ++cp
;
4119 while (ISALNUM (*cp
) || *cp
== '_')
4121 varname
= savenstr (varstart
, cp
-varstart
);
4125 /* Should be examining a variable list at this point;
4126 could insist on seeing an open parenthesis. */
4127 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4131 /* Perhaps I should back cp up one character, so the TAGS table
4132 doesn't mention (and so depend upon) the following char. */
4133 pfnote (varname
, FALSE
,
4134 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4142 * Look for /^[\t]*def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4143 * Idea by Eric S. Raymond <esr@thyrsus.com> (1997)
4144 * More ideas by seb bacon <seb@jamkit.com> (2002)
4147 Python_functions (inf
)
4152 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4154 cp
= skip_spaces (cp
);
4155 if (LOOKING_AT (cp
, "def") || LOOKING_AT (cp
, "class"))
4158 while (!notinname (*cp
) && *cp
!= ':')
4160 pfnote (savenstr (name
, cp
-name
), TRUE
,
4161 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4170 * - /^[ \t]*function[ \t\n]+[^ \t\n(]+/
4171 * - /^[ \t]*class[ \t\n]+[^ \t\n]+/
4172 * - /^[ \t]*define\(\"[^\"]+/
4173 * Only with --members:
4174 * - /^[ \t]*var[ \t\n]+\$[^ \t\n=;]/
4175 * Idea by Diez B. Roggisch (2001)
4181 register char *cp
, *name
;
4182 bool search_identifier
= FALSE
;
4184 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4186 cp
= skip_spaces (cp
);
4188 if (search_identifier
4191 while (!notinname (*cp
))
4193 pfnote (savenstr (name
, cp
-name
), TRUE
,
4194 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4195 search_identifier
= FALSE
;
4197 else if (LOOKING_AT (cp
, "function"))
4200 cp
= skip_spaces (cp
+1);
4204 while (!notinname (*cp
))
4206 pfnote (savenstr (name
, cp
-name
), TRUE
,
4207 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4210 search_identifier
= TRUE
;
4212 else if (LOOKING_AT (cp
, "class"))
4217 while (*cp
!= '\0' && !iswhite (*cp
))
4219 pfnote (savenstr (name
, cp
-name
), FALSE
,
4220 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4223 search_identifier
= TRUE
;
4225 else if (strneq (cp
, "define", 6)
4226 && (cp
= skip_spaces (cp
+6))
4228 && (*cp
== '"' || *cp
== '\''))
4232 while (*cp
!= quote
&& *cp
!= '\0')
4234 pfnote (savenstr (name
, cp
-name
), FALSE
,
4235 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4238 && LOOKING_AT (cp
, "var")
4242 while (!notinname(*cp
))
4244 pfnote (savenstr (name
, cp
-name
), FALSE
,
4245 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4252 * Cobol tag functions
4253 * We could look for anything that could be a paragraph name.
4254 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4255 * Idea by Corny de Souza (1993)
4258 Cobol_paragraphs (inf
)
4261 register char *bp
, *ep
;
4263 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4269 /* If eoln, compiler option or comment ignore whole line. */
4270 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4273 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4276 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4277 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4284 * Idea by Assar Westerlund <assar@sics.se> (2001)
4287 Makefile_targets (inf
)
4292 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4294 if (*bp
== '\t' || *bp
== '#')
4296 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4299 pfnote (savenstr (lb
.buffer
, bp
- lb
.buffer
), TRUE
,
4300 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4307 * Original code by Mosur K. Mohan (1989)
4309 * Locates tags for procedures & functions. Doesn't do any type- or
4310 * var-definitions. It does look for the keyword "extern" or
4311 * "forward" immediately following the procedure statement; if found,
4312 * the tag is skipped.
4315 Pascal_functions (inf
)
4318 linebuffer tline
; /* mostly copied from C_entries */
4320 int save_lineno
, save_len
;
4321 char c
, *cp
, *namebuf
;
4323 bool /* each of these flags is TRUE iff: */
4324 incomment
, /* point is inside a comment */
4325 inquote
, /* point is inside '..' string */
4326 get_tagname
, /* point is after PROCEDURE/FUNCTION
4327 keyword, so next item = potential tag */
4328 found_tag
, /* point is after a potential tag */
4329 inparms
, /* point is within parameter-list */
4330 verify_tag
; /* point has passed the parm-list, so the
4331 next token will determine whether this
4332 is a FORWARD/EXTERN to be ignored, or
4333 whether it is a real tag */
4335 save_lcno
= save_lineno
= save_len
= 0; /* keep compiler quiet */
4336 namebuf
= NULL
; /* keep compiler quiet */
4341 initbuffer (&tline
);
4343 incomment
= inquote
= FALSE
;
4344 found_tag
= FALSE
; /* have a proc name; check if extern */
4345 get_tagname
= FALSE
; /* have found "procedure" keyword */
4346 inparms
= FALSE
; /* found '(' after "proc" */
4347 verify_tag
= FALSE
; /* check if "extern" is ahead */
4350 while (!feof (inf
)) /* long main loop to get next char */
4353 if (c
== '\0') /* if end of line */
4356 linecharno
= charno
;
4357 charno
+= readline (&lb
, inf
);
4361 if (!((found_tag
&& verify_tag
)
4363 c
= *dbp
++; /* only if don't need *dbp pointing
4364 to the beginning of the name of
4365 the procedure or function */
4369 if (c
== '}') /* within { } comments */
4371 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4388 inquote
= TRUE
; /* found first quote */
4390 case '{': /* found open { comment */
4394 if (*dbp
== '*') /* found open (* comment */
4399 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4402 case ')': /* end of parms list */
4407 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4414 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4416 /* check if this is an "extern" declaration */
4419 if (lowcase (*dbp
== 'e'))
4421 if (nocase_tail ("extern")) /* superfluous, really! */
4427 else if (lowcase (*dbp
) == 'f')
4429 if (nocase_tail ("forward")) /* check for forward reference */
4435 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4439 pfnote (namebuf
, TRUE
,
4440 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
4444 if (get_tagname
) /* grab name of proc or fn */
4449 /* save all values for later tagging */
4450 linebuffer_setlen (&tline
, lb
.len
);
4451 strcpy (tline
.buffer
, lb
.buffer
);
4452 save_lineno
= lineno
;
4453 save_lcno
= linecharno
;
4455 /* grab block name */
4456 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4458 namebuf
= savenstr (dbp
, cp
-dbp
);
4459 dbp
= cp
; /* set dbp to e-o-token */
4460 save_len
= dbp
- lb
.buffer
+ 1;
4461 get_tagname
= FALSE
;
4465 /* and proceed to check for "extern" */
4467 else if (!incomment
&& !inquote
&& !found_tag
)
4469 /* check for proc/fn keywords */
4470 switch (lowcase (c
))
4473 if (nocase_tail ("rocedure")) /* c = 'p', dbp has advanced */
4477 if (nocase_tail ("unction"))
4482 } /* while not eof */
4484 free (tline
.buffer
);
4489 * Lisp tag functions
4490 * look for (def or (DEF, quote or QUOTE
4493 static void L_getit
__P((void));
4498 if (*dbp
== '\'') /* Skip prefix quote */
4500 else if (*dbp
== '(')
4503 /* Try to skip "(quote " */
4504 if (!LOOKING_AT (dbp
, "quote") && !LOOKING_AT (dbp
, "QUOTE"))
4505 /* Ok, then skip "(" before name in (defstruct (foo)) */
4506 dbp
= skip_spaces (dbp
);
4512 Lisp_functions (inf
)
4515 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4520 if (strneq (dbp
+1, "def", 3) || strneq (dbp
+1, "DEF", 3))
4522 dbp
= skip_non_spaces (dbp
);
4523 dbp
= skip_spaces (dbp
);
4528 /* Check for (foo::defmumble name-defined ... */
4531 while (!notinname (*dbp
) && *dbp
!= ':');
4536 while (*dbp
== ':');
4538 if (strneq (dbp
, "def", 3) || strneq (dbp
, "DEF", 3))
4540 dbp
= skip_non_spaces (dbp
);
4541 dbp
= skip_spaces (dbp
);
4551 * Postscript tag functions
4552 * Just look for lines where the first character is '/'
4553 * Also look at "defineps" for PSWrap
4555 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4556 * Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4559 Postscript_functions (inf
)
4562 register char *bp
, *ep
;
4564 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4569 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4572 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4573 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4575 else if (LOOKING_AT (bp
, "defineps"))
4582 * Scheme tag functions
4583 * look for (def... xyzzy
4585 * (def ... ((...(xyzzy ....
4587 * Original code by Ken Haase (1985?)
4591 Scheme_functions (inf
)
4596 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4598 if (strneq (bp
, "(def", 4) || strneq (bp
, "(DEF", 4))
4600 bp
= skip_non_spaces (bp
+4);
4601 /* Skip over open parens and white space */
4602 while (notinname (*bp
))
4606 if (LOOKING_AT (bp
, "(SET!") || LOOKING_AT (bp
, "(set!"))
4612 /* Find tags in TeX and LaTeX input files. */
4614 /* TEX_toktab is a table of TeX control sequences that define tags.
4615 Each TEX_tabent records one such control sequence.
4616 CONVERT THIS TO USE THE Stab TYPE!! */
4623 static struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
4625 /* Default set of control sequences to put into TEX_toktab.
4626 The value of environment var TEXTAGS is prepended to this. */
4628 static char *TEX_defenv
= "\
4629 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4630 :part:appendix:entry:index";
4632 static void TEX_mode
__P((FILE *));
4633 static struct TEX_tabent
*TEX_decode_env
__P((char *, char *));
4634 static int TEX_Token
__P((char *));
4636 static char TEX_esc
= '\\';
4637 static char TEX_opgrp
= '{';
4638 static char TEX_clgrp
= '}';
4641 * TeX/LaTeX scanning loop.
4650 /* Select either \ or ! as escape character. */
4653 /* Initialize token table once from environment. */
4655 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
4657 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4660 /* Look at each esc in line. */
4661 while ((cp
= etags_strchr (cp
, TEX_esc
)) != NULL
)
4665 linecharno
+= cp
- lasthit
;
4667 i
= TEX_Token (lasthit
);
4671 for (lasthit
+= TEX_toktab
[i
].len
;
4672 *lasthit
== TEX_esc
|| *lasthit
== TEX_opgrp
;
4676 !iswhite (*p
) && *p
!= TEX_opgrp
&& *p
!= TEX_clgrp
;
4679 pfnote (savenstr (lasthit
, p
-lasthit
), TRUE
,
4680 lb
.buffer
, lb
.len
, lineno
, linecharno
);
4681 break; /* We only tag a line once */
4687 #define TEX_LESC '\\'
4688 #define TEX_SESC '!'
4691 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4692 chars accordingly. */
4699 while ((c
= getc (inf
)) != EOF
)
4701 /* Skip to next line if we hit the TeX comment char. */
4705 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
4721 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4722 No attempt is made to correct the situation. */
4726 /* Read environment and prepend it to the default string.
4727 Build token table. */
4728 static struct TEX_tabent
*
4729 TEX_decode_env (evarname
, defenv
)
4733 register char *env
, *p
;
4735 struct TEX_tabent
*tab
;
4738 /* Append default string to environment. */
4739 env
= getenv (evarname
);
4745 env
= concat (oldenv
, defenv
, "");
4748 /* Allocate a token table */
4749 for (size
= 1, p
= env
; p
;)
4750 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
4752 /* Add 1 to leave room for null terminator. */
4753 tab
= xnew (size
+ 1, struct TEX_tabent
);
4755 /* Unpack environment string into token table. Be careful about */
4756 /* zero-length strings (leading ':', "::" and trailing ':') */
4759 p
= etags_strchr (env
, ':');
4760 if (!p
) /* End of environment string. */
4761 p
= env
+ strlen (env
);
4763 { /* Only non-zero strings. */
4764 tab
[i
].name
= savenstr (env
, p
- env
);
4765 tab
[i
].len
= strlen (tab
[i
].name
);
4772 tab
[i
].name
= NULL
; /* Mark end of table. */
4780 /* If the text at CP matches one of the tag-defining TeX command names,
4781 return the pointer to the first occurrence of that command in TEX_toktab.
4782 Otherwise return -1.
4783 Keep the capital `T' in `token' for dumb truncating compilers
4784 (this distinguishes it from `TEX_toktab' */
4791 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
4792 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
4798 /* Texinfo support. Dave Love, Mar. 2000. */
4804 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4805 if (LOOKING_AT (cp
, "@node"))
4808 while (*cp
!= '\0' && *cp
!= ',')
4810 pfnote (savenstr (start
, cp
- start
), TRUE
,
4811 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4819 * Assumes that the predicate or rule starts at column 0.
4820 * Only the first clause of a predicate or rule is added.
4821 * Original code by Sunichirou Sugou (1989)
4822 * Rewritten by Anders Lindgren (1996)
4824 static int prolog_pr
__P((char *, char *));
4825 static void prolog_skip_comment
__P((linebuffer
*, FILE *));
4826 static int prolog_atom
__P((char *, int));
4829 Prolog_functions (inf
)
4840 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4842 if (cp
[0] == '\0') /* Empty line */
4844 else if (iswhite (cp
[0])) /* Not a predicate */
4846 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
4847 prolog_skip_comment (&lb
, inf
);
4848 else if ((len
= prolog_pr (cp
, last
)) > 0)
4850 /* Predicate or rule. Store the function name so that we
4851 only generate a tag for the first clause. */
4853 last
= xnew(len
+ 1, char);
4854 else if (len
+ 1 > allocated
)
4855 xrnew (last
, len
+ 1, char);
4856 allocated
= len
+ 1;
4857 strncpy (last
, cp
, len
);
4865 prolog_skip_comment (plb
, inf
)
4873 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
4874 if (cp
[0] == '*' && cp
[1] == '/')
4877 linecharno
+= readline (plb
, inf
);
4883 * A predicate or rule definition is added if it matches:
4884 * <beginning of line><Prolog Atom><whitespace>(
4885 * or <beginning of line><Prolog Atom><whitespace>:-
4887 * It is added to the tags database if it doesn't match the
4888 * name of the previous clause header.
4890 * Return the size of the name of the predicate or rule, or 0 if no
4896 char *last
; /* Name of last clause. */
4901 pos
= prolog_atom (s
, 0);
4906 pos
= skip_spaces (s
+ pos
) - s
;
4909 || (s
[pos
] == '(' && (pos
+= 1))
4910 || (s
[pos
] == ':' && s
[pos
+ 1] == '-' && (pos
+= 2)))
4911 && (last
== NULL
/* save only the first clause */
4912 || len
!= strlen (last
)
4913 || !strneq (s
, last
, len
)))
4915 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4923 * Consume a Prolog atom.
4924 * Return the number of bytes consumed, or -1 if there was an error.
4926 * A prolog atom, in this context, could be one of:
4927 * - An alphanumeric sequence, starting with a lower case letter.
4928 * - A quoted arbitrary string. Single quotes can escape themselves.
4929 * Backslash quotes everything.
4932 prolog_atom (s
, pos
)
4940 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
4942 /* The atom is unquoted. */
4944 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
4948 return pos
- origpos
;
4950 else if (s
[pos
] == '\'')
4961 pos
++; /* A double quote */
4963 else if (s
[pos
] == '\0')
4964 /* Multiline quoted atoms are ignored. */
4966 else if (s
[pos
] == '\\')
4968 if (s
[pos
+1] == '\0')
4975 return pos
- origpos
;
4983 * Support for Erlang
4985 * Generates tags for functions, defines, and records.
4986 * Assumes that Erlang functions start at column 0.
4987 * Original code by Anders Lindgren (1996)
4989 static int erlang_func
__P((char *, char *));
4990 static void erlang_attribute
__P((char *));
4991 static int erlang_atom
__P((char *, int));
4994 Erlang_functions (inf
)
5005 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
5007 if (cp
[0] == '\0') /* Empty line */
5009 else if (iswhite (cp
[0])) /* Not function nor attribute */
5011 else if (cp
[0] == '%') /* comment */
5013 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
5015 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
5017 erlang_attribute (cp
);
5020 else if ((len
= erlang_func (cp
, last
)) > 0)
5023 * Function. Store the function name so that we only
5024 * generates a tag for the first clause.
5027 last
= xnew (len
+ 1, char);
5028 else if (len
+ 1 > allocated
)
5029 xrnew (last
, len
+ 1, char);
5030 allocated
= len
+ 1;
5031 strncpy (last
, cp
, len
);
5039 * A function definition is added if it matches:
5040 * <beginning of line><Erlang Atom><whitespace>(
5042 * It is added to the tags database if it doesn't match the
5043 * name of the previous clause header.
5045 * Return the size of the name of the function, or 0 if no function
5049 erlang_func (s
, last
)
5051 char *last
; /* Name of last clause. */
5056 pos
= erlang_atom (s
, 0);
5061 pos
= skip_spaces (s
+ pos
) - s
;
5063 /* Save only the first clause. */
5066 || len
!= (int)strlen (last
)
5067 || !strneq (s
, last
, len
)))
5069 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
5078 * Handle attributes. Currently, tags are generated for defines
5081 * They are on the form:
5082 * -define(foo, bar).
5083 * -define(Foo(M, N), M+N).
5084 * -record(graph, {vtab = notable, cyclic = true}).
5087 erlang_attribute (s
)
5093 if (LOOKING_AT (s
, "-define") || LOOKING_AT (s
, "-record"))
5095 if (s
[pos
++] == '(')
5097 pos
= skip_spaces (s
+ pos
) - s
;
5098 len
= erlang_atom (s
, pos
);
5100 pfnote (savenstr (& s
[pos
], len
), TRUE
,
5101 s
, pos
+ len
, lineno
, linecharno
);
5109 * Consume an Erlang atom (or variable).
5110 * Return the number of bytes consumed, or -1 if there was an error.
5113 erlang_atom (s
, pos
)
5121 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
5123 /* The atom is unquoted. */
5125 while (ISALNUM (s
[pos
]) || s
[pos
] == '_')
5127 return pos
- origpos
;
5129 else if (s
[pos
] == '\'')
5140 else if (s
[pos
] == '\0')
5141 /* Multiline quoted atoms are ignored. */
5143 else if (s
[pos
] == '\\')
5145 if (s
[pos
+1] == '\0')
5152 return pos
- origpos
;
5159 #ifdef ETAGS_REGEXPS
5161 static char *scan_separators
__P((char *));
5162 static void analyse_regex
__P((char *, bool));
5163 static void add_regex
__P((char *, bool, language
*));
5164 static char *substitute
__P((char *, char *, struct re_registers
*));
5166 /* Take a string like "/blah/" and turn it into "blah", making sure
5167 that the first and last characters are the same, and handling
5168 quoted separator characters. Actually, stops on the occurrence of
5169 an unquoted separator. Also turns "\t" into a Tab character.
5170 Returns pointer to terminating separator. Works in place. Null
5171 terminates name string. */
5173 scan_separators (name
)
5177 char *copyto
= name
;
5178 bool quoted
= FALSE
;
5180 for (++name
; *name
!= '\0'; ++name
)
5186 else if (*name
== sep
)
5190 /* Something else is quoted, so preserve the quote. */
5196 else if (*name
== '\\')
5198 else if (*name
== sep
)
5204 /* Terminate copied string. */
5209 /* Look at the argument of --regex or --no-regex and do the right
5210 thing. Same for each line of a regexp file. */
5212 analyse_regex (regex_arg
, ignore_case
)
5216 if (regex_arg
== NULL
)
5218 free_patterns (); /* --no-regex: remove existing regexps */
5222 /* A real --regexp option or a line in a regexp file. */
5223 switch (regex_arg
[0])
5225 /* Comments in regexp file or null arg to --regex. */
5231 /* Read a regex file. This is recursive and may result in a
5232 loop, which will stop when the file descriptors are exhausted. */
5236 linebuffer regexbuf
;
5237 char *regexfile
= regex_arg
+ 1;
5239 /* regexfile is a file containing regexps, one per line. */
5240 regexfp
= fopen (regexfile
, "r");
5241 if (regexfp
== NULL
)
5246 initbuffer (®exbuf
);
5247 while (readline_internal (®exbuf
, regexfp
) > 0)
5248 analyse_regex (regexbuf
.buffer
, ignore_case
);
5249 free (regexbuf
.buffer
);
5254 /* Regexp to be used for a specific language only. */
5258 char *lang_name
= regex_arg
+ 1;
5261 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5264 error ("unterminated language name in regex: %s", regex_arg
);
5268 lang
= get_language_from_langname (lang_name
);
5271 add_regex (cp
+ 1, ignore_case
, lang
);
5275 /* Regexp to be used for any language. */
5277 add_regex (regex_arg
, ignore_case
, NULL
);
5282 /* Turn a name, which is an ed-style (but Emacs syntax) regular
5283 expression, into a real regular expression by compiling it. */
5285 add_regex (regexp_pattern
, ignore_case
, lang
)
5286 char *regexp_pattern
;
5290 static struct re_pattern_buffer zeropattern
;
5293 struct re_pattern_buffer
*patbuf
;
5297 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
5299 error ("%s: unterminated regexp", regexp_pattern
);
5302 name
= scan_separators (regexp_pattern
);
5303 if (regexp_pattern
[0] == '\0')
5305 error ("null regexp", (char *)NULL
);
5308 (void) scan_separators (name
);
5310 patbuf
= xnew (1, struct re_pattern_buffer
);
5311 *patbuf
= zeropattern
;
5313 patbuf
->translate
= lc_trans
; /* translation table to fold case */
5315 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
5318 error ("%s while compiling pattern", err
);
5323 p_head
= xnew (1, pattern
);
5324 p_head
->regex
= savestr (regexp_pattern
);
5325 p_head
->p_next
= pp
;
5326 p_head
->lang
= lang
;
5327 p_head
->pat
= patbuf
;
5328 p_head
->name_pattern
= savestr (name
);
5329 p_head
->error_signaled
= FALSE
;
5330 p_head
->ignore_case
= ignore_case
;
5334 * Do the substitutions indicated by the regular expression and
5338 substitute (in
, out
, regs
)
5340 struct re_registers
*regs
;
5343 int size
, dig
, diglen
;
5346 size
= strlen (out
);
5348 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5349 if (out
[size
- 1] == '\\')
5350 fatal ("pattern error in \"%s\"", out
);
5351 for (t
= etags_strchr (out
, '\\');
5353 t
= etags_strchr (t
+ 2, '\\'))
5357 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5363 /* Allocate space and do the substitutions. */
5364 result
= xnew (size
+ 1, char);
5366 for (t
= result
; *out
!= '\0'; out
++)
5367 if (*out
== '\\' && ISDIGIT (*++out
))
5370 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5371 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5378 assert (t
<= result
+ size
&& t
- result
== (int)strlen (result
));
5383 /* Deallocate all patterns. */
5388 while (p_head
!= NULL
)
5390 pp
= p_head
->p_next
;
5391 free (p_head
->regex
);
5392 free (p_head
->name_pattern
);
5398 #endif /* ETAGS_REGEXPS */
5405 register int len
= 0;
5407 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
5409 if (*cp
== '\0' && !intoken (dbp
[len
]))
5421 register char *cp
, *name
;
5425 /* Go till you get to white space or a syntactic break */
5426 for (cp
= bp
+ 1; !notinname (*cp
); cp
++)
5428 name
= savenstr (bp
, cp
-bp
);
5430 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5434 /* Initialize a linebuffer for use */
5439 lbp
->size
= (DEBUG
) ? 3 : 200;
5440 lbp
->buffer
= xnew (lbp
->size
, char);
5441 lbp
->buffer
[0] = '\0';
5446 * Read a line of text from `stream' into `lbp', excluding the
5447 * newline or CR-NL, if any. Return the number of characters read from
5448 * `stream', which is the length of the line including the newline.
5450 * On DOS or Windows we do not count the CR character, if any, before the
5451 * NL, in the returned length; this mirrors the behavior of emacs on those
5452 * platforms (for text files, it translates CR-NL to NL as it reads in the
5456 readline_internal (lbp
, stream
)
5458 register FILE *stream
;
5460 char *buffer
= lbp
->buffer
;
5461 register char *p
= lbp
->buffer
;
5462 register char *pend
;
5465 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
5469 register int c
= getc (stream
);
5472 /* We're at the end of linebuffer: expand it. */
5474 xrnew (buffer
, lbp
->size
, char);
5475 p
+= buffer
- lbp
->buffer
;
5476 pend
= buffer
+ lbp
->size
;
5477 lbp
->buffer
= buffer
;
5487 if (p
> buffer
&& p
[-1] == '\r')
5491 /* Assume CRLF->LF translation will be performed by Emacs
5492 when loading this file, so CRs won't appear in the buffer.
5493 It would be cleaner to compensate within Emacs;
5494 however, Emacs does not know how many CRs were deleted
5495 before any given point in the file. */
5510 lbp
->len
= p
- buffer
;
5512 return lbp
->len
+ chars_deleted
;
5516 * Like readline_internal, above, but in addition try to match the
5517 * input line against relevant regular expressions.
5520 readline (lbp
, stream
)
5524 /* Read new line. */
5525 long result
= readline_internal (lbp
, stream
);
5527 /* Honour #line directives. */
5528 if (!no_line_directive
)
5530 static bool discard_until_line_directive
;
5532 /* Check whether this is a #line directive. */
5533 if (result
> 12 && strneq (lbp
->buffer
, "#line ", 6))
5537 if (DEBUG
) start
= 0; /* shut up the compiler */
5538 if (sscanf (lbp
->buffer
, "#line %d \"%n", &lno
, &start
) == 1)
5540 char *endp
= lbp
->buffer
+ start
;
5543 while ((endp
= etags_strchr (endp
, '"')) != NULL
5544 && endp
[-1] == '\\')
5547 /* Ok, this is a real #line directive. Let's deal with it. */
5549 char *taggedabsname
; /* absolute name of original file */
5550 char *taggedfname
; /* name of original file as given */
5551 char *name
; /* temp var */
5553 discard_until_line_directive
= FALSE
; /* found it */
5554 name
= lbp
->buffer
+ start
;
5556 canonicalize_filename (name
); /* for DOS */
5557 taggedabsname
= absolute_filename (name
, curfdp
->infabsdir
);
5558 if (filename_is_absolute (name
)
5559 || filename_is_absolute (curfdp
->infname
))
5560 taggedfname
= savestr (taggedabsname
);
5562 taggedfname
= relative_filename (taggedabsname
,tagfiledir
);
5564 if (streq (curfdp
->taggedfname
, taggedfname
))
5565 /* The #line directive is only a line number change. We
5566 deal with this afterwards. */
5569 /* The tags following this #line directive should be
5570 attributed to taggedfname. In order to do this, set
5571 curfdp accordingly. */
5573 fdesc
*fdp
; /* file description pointer */
5575 /* Go look for a file description already set up for the
5576 file indicated in the #line directive. If there is
5577 one, use it from now until the next #line
5579 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
5580 if (streq (fdp
->infname
, curfdp
->infname
)
5581 && streq (fdp
->taggedfname
, taggedfname
))
5582 /* If we remove the second test above (after the &&)
5583 then all entries pertaining to the same file are
5584 coalesced in the tags file. If we use it, then
5585 entries pertaining to the same file but generated
5586 from different files (via #line directives) will
5587 go into separate sections in the tags file. These
5588 alternatives look equivalent. The first one
5589 destroys some apparently useless information. */
5595 /* Else, if we already tagged the real file, skip all
5596 input lines until the next #line directive. */
5597 if (fdp
== NULL
) /* not found */
5598 for (fdp
= fdhead
; fdp
!= NULL
; fdp
= fdp
->next
)
5599 if (streq (fdp
->infabsname
, taggedabsname
))
5601 discard_until_line_directive
= TRUE
;
5605 /* Else create a new file description and use that from
5606 now on, until the next #line directive. */
5607 if (fdp
== NULL
) /* not found */
5610 fdhead
= xnew (1, fdesc
);
5611 *fdhead
= *curfdp
; /* copy curr. file description */
5613 fdhead
->infname
= savestr (curfdp
->infname
);
5614 fdhead
->infabsname
= savestr (curfdp
->infabsname
);
5615 fdhead
->infabsdir
= savestr (curfdp
->infabsdir
);
5616 fdhead
->taggedfname
= taggedfname
;
5617 fdhead
->usecharno
= FALSE
;
5621 free (taggedabsname
);
5623 return readline (lbp
, stream
);
5624 } /* if a real #line directive */
5625 } /* if #line is followed by a a number */
5626 } /* if line begins with "#line " */
5628 /* If we are here, no #line directive was found. */
5629 if (discard_until_line_directive
)
5632 /* Do a tail recursion on ourselves, thus discarding the contents
5633 of the line buffer. */
5634 return readline (lbp
, stream
);
5636 discard_until_line_directive
= FALSE
;
5639 } /* if #line directives should be considered */
5641 #ifdef ETAGS_REGEXPS
5646 /* Match against relevant patterns. */
5648 for (pp
= p_head
; pp
!= NULL
; pp
= pp
->p_next
)
5650 /* Only use generic regexps or those for the current language. */
5651 if (pp
->lang
!= NULL
&& pp
->lang
!= fdhead
->lang
)
5654 match
= re_match (pp
->pat
, lbp
->buffer
, lbp
->len
, 0, &pp
->regs
);
5659 if (!pp
->error_signaled
)
5661 error ("error while matching \"%s\"", pp
->regex
);
5662 pp
->error_signaled
= TRUE
;
5669 /* Match occurred. Construct a tag. */
5670 if (pp
->name_pattern
[0] != '\0')
5672 /* Make a named tag. */
5673 char *name
= substitute (lbp
->buffer
,
5674 pp
->name_pattern
, &pp
->regs
);
5676 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
5680 /* Make an unnamed tag. */
5681 pfnote ((char *)NULL
, TRUE
,
5682 lbp
->buffer
, match
, lineno
, linecharno
);
5688 #endif /* ETAGS_REGEXPS */
5695 * Return a pointer to a space of size strlen(cp)+1 allocated
5696 * with xnew where the string CP has been copied.
5702 return savenstr (cp
, strlen (cp
));
5706 * Return a pointer to a space of size LEN+1 allocated with xnew where
5707 * the string CP has been copied for at most the first LEN characters.
5716 dp
= xnew (len
+ 1, char);
5717 strncpy (dp
, cp
, len
);
5723 * Return the ptr in sp at which the character c last
5724 * appears; NULL if not found
5726 * Identical to POSIX strrchr, included for portability.
5729 etags_strrchr (sp
, c
)
5730 register const char *sp
;
5733 register const char *r
;
5746 * Return the ptr in sp at which the character c first
5747 * appears; NULL if not found
5749 * Identical to POSIX strchr, included for portability.
5752 etags_strchr (sp
, c
)
5753 register const char *sp
;
5764 /* Skip spaces, return new pointer. */
5769 while (iswhite (*cp
))
5774 /* Skip non spaces, return new pointer. */
5776 skip_non_spaces (cp
)
5779 while (*cp
!= '\0' && !iswhite (*cp
))
5784 /* Print error message and exit. */
5802 suggest_asking_for_help ()
5804 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
5815 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5818 const char *s1
, *s2
;
5820 fprintf (stderr
, "%s: ", progname
);
5821 fprintf (stderr
, s1
, s2
);
5822 fprintf (stderr
, "\n");
5825 /* Return a newly-allocated string whose contents
5826 concatenate those of s1, s2, s3. */
5831 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
5832 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
5834 strcpy (result
, s1
);
5835 strcpy (result
+ len1
, s2
);
5836 strcpy (result
+ len1
+ len2
, s3
);
5837 result
[len1
+ len2
+ len3
] = '\0';
5843 /* Does the same work as the system V getcwd, but does not need to
5844 guess the buffer size in advance. */
5850 char *path
= xnew (bufsize
, char);
5852 while (getcwd (path
, bufsize
) == NULL
)
5854 if (errno
!= ERANGE
)
5858 path
= xnew (bufsize
, char);
5861 canonicalize_filename (path
);
5864 #else /* not HAVE_GETCWD */
5867 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
5871 for (p
= path
; *p
!= '\0'; p
++)
5877 return strdup (path
);
5878 #else /* not MSDOS */
5883 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
5884 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
5889 #endif /* not MSDOS */
5890 #endif /* not HAVE_GETCWD */
5893 /* Return a newly allocated string containing the file name of FILE
5894 relative to the absolute directory DIR (which should end with a slash). */
5896 relative_filename (file
, dir
)
5899 char *fp
, *dp
, *afn
, *res
;
5902 /* Find the common root of file and dir (with a trailing slash). */
5903 afn
= absolute_filename (file
, cwd
);
5906 while (*fp
++ == *dp
++)
5908 fp
--, dp
--; /* back to the first differing char */
5910 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
5913 do /* look at the equal chars until '/' */
5917 /* Build a sequence of "../" strings for the resulting relative file name. */
5919 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
5921 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
5924 strcat (res
, "../");
5926 /* Add the file name relative to the common root of file and dir. */
5927 strcat (res
, fp
+ 1);
5933 /* Return a newly allocated string containing the absolute file name
5934 of FILE given DIR (which should end with a slash). */
5936 absolute_filename (file
, dir
)
5939 char *slashp
, *cp
, *res
;
5941 if (filename_is_absolute (file
))
5942 res
= savestr (file
);
5944 /* We don't support non-absolute file names with a drive
5945 letter, like `d:NAME' (it's too much hassle). */
5946 else if (file
[1] == ':')
5947 fatal ("%s: relative file names with drive letters not supported", file
);
5950 res
= concat (dir
, file
, "");
5952 /* Delete the "/dirname/.." and "/." substrings. */
5953 slashp
= etags_strchr (res
, '/');
5954 while (slashp
!= NULL
&& slashp
[0] != '\0')
5956 if (slashp
[1] == '.')
5958 if (slashp
[2] == '.'
5959 && (slashp
[3] == '/' || slashp
[3] == '\0'))
5964 while (cp
>= res
&& !filename_is_absolute (cp
));
5966 cp
= slashp
; /* the absolute name begins with "/.." */
5968 /* Under MSDOS and NT we get `d:/NAME' as absolute
5969 file name, so the luser could say `d:/../NAME'.
5970 We silently treat this as `d:/NAME'. */
5971 else if (cp
[0] != '/')
5974 strcpy (cp
, slashp
+ 3);
5978 else if (slashp
[2] == '/' || slashp
[2] == '\0')
5980 strcpy (slashp
, slashp
+ 2);
5985 slashp
= etags_strchr (slashp
+ 1, '/');
5989 return savestr ("/");
5994 /* Return a newly allocated string containing the absolute
5995 file name of dir where FILE resides given DIR (which should
5996 end with a slash). */
5998 absolute_dirname (file
, dir
)
6004 canonicalize_filename (file
);
6005 slashp
= etags_strrchr (file
, '/');
6007 return savestr (dir
);
6010 res
= absolute_filename (file
, dir
);
6016 /* Whether the argument string is an absolute file name. The argument
6017 string must have been canonicalized with canonicalize_filename. */
6019 filename_is_absolute (fn
)
6022 return (fn
[0] == '/'
6024 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
6029 /* Translate backslashes into slashes. Works in place. */
6031 canonicalize_filename (fn
)
6035 /* Canonicalize drive letter case. */
6036 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
6037 fn
[0] = upcase (fn
[0]);
6038 /* Convert backslashes to slashes. */
6039 for (; *fn
!= '\0'; fn
++)
6044 fn
= NULL
; /* shut up the compiler */
6048 /* Set the minimum size of a string contained in a linebuffer. */
6050 linebuffer_setlen (lbp
, toksize
)
6054 while (lbp
->size
<= toksize
)
6057 xrnew (lbp
->buffer
, lbp
->size
, char);
6062 /* Like malloc but get fatal error if memory is exhausted. */
6067 PTR result
= (PTR
) malloc (size
);
6069 fatal ("virtual memory exhausted", (char *)NULL
);
6074 xrealloc (ptr
, size
)
6078 PTR result
= (PTR
) realloc (ptr
, size
);
6080 fatal ("virtual memory exhausted", (char *)NULL
);
6086 * c-indentation-style: gnu
6087 * indent-tabs-mode: t
6090 * c-font-lock-extra-types: ("FILE" "bool" "language" "linebuffer" "fdesc")