1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98, 99, 2000, 2001
3 Free Software Foundation, Inc. and Ken Arnold
5 This file is not considered part of GNU Emacs.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS?
27 * 1989 Sam Kendall added C++.
28 * 1993 Francesco Potortì reorganised C and C++ based on work by Joe Wells.
29 * 1994 Regexp tags by Tom Tromey.
30 * 2001 Nested classes by Francesco Potortì based on work by Mykola Dzyuba.
32 * Francesco Potortì <pot@gnu.org> has maintained it since 1993.
35 char pot_etags_version
[] = "@(#) pot revision number is 14.13";
45 # define NDEBUG /* disable assert */
48 #if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
49 # define P_(proto) proto
56 /* On some systems, Emacs defines static as nothing for the sake
57 of unexec. We don't want that here since we don't use unexec. */
59 # define ETAGS_REGEXPS /* use the regexp features */
60 # define LONG_OPTIONS /* accept long options */
61 #endif /* HAVE_CONFIG_H */
64 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
67 /* WIN32_NATIVE is for Xemacs.
68 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
73 #endif /* WIN32_NATIVE */
79 # include <sys/param.h>
81 # ifndef HAVE_CONFIG_H
83 # include <sys/config.h>
95 # define MAXPATHLEN _MAX_PATH
101 # endif /* undef HAVE_GETCWD */
102 #else /* !WINDOWSNT */
107 extern char *getenv ();
109 #endif /* !WINDOWSNT */
114 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
115 extern char *getcwd (char *buf
, size_t size
);
117 #endif /* HAVE_UNISTD_H */
126 #include <sys/types.h>
127 #include <sys/stat.h>
129 #if !defined (S_ISREG) && defined (S_IFREG)
130 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
136 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
138 extern int optind
, opterr
;
139 #endif /* LONG_OPTIONS */
143 #endif /* ETAGS_REGEXPS */
145 /* Define CTAGS to make the program "ctags" compatible with the usual one.
146 Leave it undefined to make the program "etags", which makes emacs-style
147 tag tables and tags typedefs, #defines and struct/union/enum by default. */
155 /* Exit codes for success and failure. */
164 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
165 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
167 #define CHARS 256 /* 2^sizeof(char) */
168 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
169 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
170 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
171 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
172 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
173 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
175 #define ISALNUM(c) isalnum (CHAR(c))
176 #define ISALPHA(c) isalpha (CHAR(c))
177 #define ISDIGIT(c) isdigit (CHAR(c))
178 #define ISLOWER(c) islower (CHAR(c))
180 #define lowcase(c) tolower (CHAR(c))
181 #define upcase(c) toupper (CHAR(c))
185 * xnew, xrnew -- allocate, reallocate storage
187 * SYNOPSIS: Type *xnew (int n, Type);
188 * void xrnew (OldPointer, int n, Type);
191 # include "chkmalloc.h"
192 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
193 (n) * sizeof (Type)))
194 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
195 (char *) (op), (n) * sizeof (Type)))
197 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
198 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
199 (char *) (op), (n) * sizeof (Type)))
204 typedef void Lang_function
P_((FILE *));
209 char *command
; /* Takes one arg and decompresses to stdout */
215 Lang_function
*function
;
221 typedef struct node_st
222 { /* sorting structure */
223 char *name
; /* function or type name */
224 char *file
; /* file name */
225 bool is_func
; /* use pattern or line no */
226 bool been_warned
; /* set if noticed dup */
227 int lno
; /* line number tag is on */
228 long cno
; /* character number line starts on */
229 char *pat
; /* search pattern */
230 struct node_st
*left
, *right
; /* left and right sons */
234 * A `linebuffer' is a structure which holds a line of text.
235 * `readline_internal' reads a line from a stream into a linebuffer
236 * and works regardless of the length of the line.
237 * SIZE is the size of BUFFER, LEN is the length of the string in
238 * BUFFER after readline reads it.
247 /* Many compilers barf on this:
248 Lang_function Ada_funcs;
249 so let's write it this way */
250 static void Ada_funcs
P_((FILE *));
251 static void Asm_labels
P_((FILE *));
252 static void C_entries
P_((int c_ext
, FILE *));
253 static void default_C_entries
P_((FILE *));
254 static void plain_C_entries
P_((FILE *));
255 static void Cjava_entries
P_((FILE *));
256 static void Cobol_paragraphs
P_((FILE *));
257 static void Cplusplus_entries
P_((FILE *));
258 static void Cstar_entries
P_((FILE *));
259 static void Erlang_functions
P_((FILE *));
260 static void Fortran_functions
P_((FILE *));
261 static void Yacc_entries
P_((FILE *));
262 static void Lisp_functions
P_((FILE *));
263 static void Makefile_targets
P_((FILE *));
264 static void Pascal_functions
P_((FILE *));
265 static void Perl_functions
P_((FILE *));
266 static void Postscript_functions
P_((FILE *));
267 static void Prolog_functions
P_((FILE *));
268 static void Python_functions
P_((FILE *));
269 static void Scheme_functions
P_((FILE *));
270 static void TeX_commands
P_((FILE *));
271 static void Texinfo_nodes
P_((FILE *));
272 static void just_read_file
P_((FILE *));
274 static void print_language_names
P_((void));
275 static void print_version
P_((void));
276 static void print_help
P_((void));
277 int main
P_((int, char **));
278 static int number_len
P_((long));
280 static compressor
*get_compressor_from_suffix
P_((char *, char **));
281 static language
*get_language_from_langname
P_((char *));
282 static language
*get_language_from_interpreter
P_((char *));
283 static language
*get_language_from_filename
P_((char *));
284 static int total_size_of_entries
P_((node
*));
285 static long readline
P_((linebuffer
*, FILE *));
286 static long readline_internal
P_((linebuffer
*, FILE *));
287 static void get_tag
P_((char *));
290 static void analyse_regex
P_((char *, bool));
291 static void add_regex
P_((char *, bool, language
*));
292 static void free_patterns
P_((void));
293 #endif /* ETAGS_REGEXPS */
294 static void error
P_((const char *, const char *));
295 static void suggest_asking_for_help
P_((void));
296 void fatal
P_((char *, char *));
297 static void pfatal
P_((char *));
298 static void add_node
P_((node
*, node
**));
300 static void init
P_((void));
301 static void initbuffer
P_((linebuffer
*));
302 static void find_entries
P_((char *, FILE *));
303 static void free_tree
P_((node
*));
304 static void pfnote
P_((char *, bool, char *, int, int, long));
305 static void new_pfnote
P_((char *, int, bool, char *, int, int, long));
306 static void process_file
P_((char *));
307 static void put_entries
P_((node
*));
308 static void takeprec
P_((void));
310 static char *concat
P_((char *, char *, char *));
311 static char *skip_spaces
P_((char *));
312 static char *skip_non_spaces
P_((char *));
313 static char *savenstr
P_((char *, int));
314 static char *savestr
P_((char *));
315 static char *etags_strchr
P_((const char *, int));
316 static char *etags_strrchr
P_((const char *, int));
317 static char *etags_getcwd
P_((void));
318 static char *relative_filename
P_((char *, char *));
319 static char *absolute_filename
P_((char *, char *));
320 static char *absolute_dirname
P_((char *, char *));
321 static bool filename_is_absolute
P_((char *f
));
322 static void canonicalize_filename
P_((char *));
323 static void linebuffer_setlen
P_((linebuffer
*, int));
324 long *xmalloc
P_((unsigned int));
325 long *xrealloc
P_((char *, unsigned int));
328 char searchar
= '/'; /* use /.../ searches */
330 char *tagfile
; /* output file */
331 char *progname
; /* name this program was invoked with */
332 char *cwd
; /* current working directory */
333 char *tagfiledir
; /* directory of tagfile */
334 FILE *tagf
; /* ioptr for tags file */
336 char *curfile
; /* current input file name */
337 language
*curlang
; /* current language */
339 int lineno
; /* line number of current line */
340 long charno
; /* current character number */
341 long linecharno
; /* charno of start of current line */
342 char *dbp
; /* pointer to start of current tag */
344 node
*head
; /* the head of the binary tree of tags */
346 linebuffer lb
; /* the current line */
348 /* boolean "functions" (see init) */
349 bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
352 *white
= " \f\t\n\r\v",
354 *nonam
= " \f\t\n\r(=,[;",
355 /* token ending chars */
356 *endtk
= " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?",
357 /* token starting chars */
358 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
359 /* valid in-token chars */
360 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
362 bool append_to_tagfile
; /* -a: append to tags */
363 /* The following four default to TRUE for etags, but to FALSE for ctags. */
364 bool typedefs
; /* -t: create tags for C and Ada typedefs */
365 bool typedefs_or_cplusplus
; /* -T: create tags for C typedefs, level */
366 /* 0 struct/enum/union decls, and C++ */
367 /* member functions. */
368 bool constantypedefs
; /* -d: create tags for C #define, enum */
369 /* constants and variables. */
370 /* -D: opposite of -d. Default under ctags. */
371 bool declarations
; /* --declarations: tag them and extern in C&Co*/
372 bool globals
; /* create tags for global variables */
373 bool members
; /* create tags for C member variables */
374 bool update
; /* -u: update tags */
375 bool vgrind_style
; /* -v: create vgrind style index output */
376 bool no_warnings
; /* -w: suppress warnings */
377 bool cxref_style
; /* -x: create cxref style output */
378 bool cplusplus
; /* .[hc] means C++, not C */
379 bool noindentypedefs
; /* -I: ignore indentation in C */
380 bool packages_only
; /* --packages-only: in Ada, only tag packages*/
383 struct option longopts
[] =
385 { "packages-only", no_argument
, &packages_only
, TRUE
},
386 { "append", no_argument
, NULL
, 'a' },
387 { "backward-search", no_argument
, NULL
, 'B' },
388 { "c++", no_argument
, NULL
, 'C' },
389 { "cxref", no_argument
, NULL
, 'x' },
390 { "defines", no_argument
, NULL
, 'd' },
391 { "declarations", no_argument
, &declarations
, TRUE
},
392 { "no-defines", no_argument
, NULL
, 'D' },
393 { "globals", no_argument
, &globals
, TRUE
},
394 { "no-globals", no_argument
, &globals
, FALSE
},
395 { "help", no_argument
, NULL
, 'h' },
396 { "help", no_argument
, NULL
, 'H' },
397 { "ignore-indentation", no_argument
, NULL
, 'I' },
398 { "include", required_argument
, NULL
, 'i' },
399 { "language", required_argument
, NULL
, 'l' },
400 { "members", no_argument
, &members
, TRUE
},
401 { "no-members", no_argument
, &members
, FALSE
},
402 { "no-warn", no_argument
, NULL
, 'w' },
403 { "output", required_argument
, NULL
, 'o' },
405 { "regex", required_argument
, NULL
, 'r' },
406 { "no-regex", no_argument
, NULL
, 'R' },
407 { "ignore-case-regex", required_argument
, NULL
, 'c' },
408 #endif /* ETAGS_REGEXPS */
409 { "typedefs", no_argument
, NULL
, 't' },
410 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
411 { "update", no_argument
, NULL
, 'u' },
412 { "version", no_argument
, NULL
, 'V' },
413 { "vgrind", no_argument
, NULL
, 'v' },
416 #endif /* LONG_OPTIONS */
419 /* Structure defining a regular expression. Elements are
420 the compiled pattern, and the name string. */
421 typedef struct pattern
423 struct pattern
*p_next
;
426 struct re_pattern_buffer
*pattern
;
427 struct re_registers regs
;
432 /* List of all regexps. */
433 pattern
*p_head
= NULL
;
435 /* How many characters in the character set. (From regex.c.) */
436 #define CHAR_SET_SIZE 256
437 /* Translation table for case-insensitive matching. */
438 char lc_trans
[CHAR_SET_SIZE
];
439 #endif /* ETAGS_REGEXPS */
441 compressor compressors
[] =
443 { "z", "gzip -d -c"},
444 { "Z", "gzip -d -c"},
445 { "gz", "gzip -d -c"},
446 { "GZ", "gzip -d -c"},
447 { "bz2", "bzip2 -d -c" },
455 /* Non-NULL if language fixed. */
456 language
*forced_lang
= NULL
;
459 char *Ada_suffixes
[] =
460 { "ads", "adb", "ada", NULL
};
463 char *Asm_suffixes
[] = { "a", /* Unix assembler */
464 "asm", /* Microcontroller assembly */
465 "def", /* BSO/Tasking definition includes */
466 "inc", /* Microcontroller include files */
467 "ins", /* Microcontroller include files */
468 "s", "sa", /* Unix assembler */
469 "S", /* cpp-processed Unix assembler */
470 "src", /* BSO/Tasking C compiler output */
474 /* Note that .c and .h can be considered C++, if the --c++ flag was
475 given, or if the `class' keyowrd is met inside the file.
476 That is why default_C_entries is called for these. */
477 char *default_C_suffixes
[] =
480 char *Cplusplus_suffixes
[] =
481 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
482 "M", /* Objective C++ */
483 "pdb", /* Postscript with C syntax */
486 char *Cjava_suffixes
[] =
489 char *Cobol_suffixes
[] =
490 { "COB", "cob", NULL
};
492 char *Cstar_suffixes
[] =
493 { "cs", "hs", NULL
};
495 char *Erlang_suffixes
[] =
496 { "erl", "hrl", NULL
};
498 char *Fortran_suffixes
[] =
499 { "F", "f", "f90", "for", NULL
};
501 char *Lisp_suffixes
[] =
502 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL
};
504 char *Makefile_filenames
[] =
505 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL
};
507 char *Pascal_suffixes
[] =
508 { "p", "pas", NULL
};
510 char *Perl_suffixes
[] =
511 { "pl", "pm", NULL
};
512 char *Perl_interpreters
[] =
513 { "perl", "@PERL@", NULL
};
515 char *plain_C_suffixes
[] =
516 { "lm", /* Objective lex file */
517 "m", /* Objective C file */
518 "pc", /* Pro*C file */
521 char *Postscript_suffixes
[] =
522 { "ps", "psw", NULL
}; /* .psw is for PSWrap */
524 char *Prolog_suffixes
[] =
527 char *Python_suffixes
[] =
530 /* Can't do the `SCM' or `scm' prefix with a version number. */
531 char *Scheme_suffixes
[] =
532 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL
};
534 char *TeX_suffixes
[] =
535 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL
};
537 char *Texinfo_suffixes
[] =
538 { "texi", "texinfo", "txi", NULL
};
540 char *Yacc_suffixes
[] =
541 { "y", "y++", "ym", "yxx", "yy", NULL
}; /* .ym is Objective yacc file */
544 * Table of languages.
546 * It is ok for a given function to be listed under more than one
547 * name. I just didn't.
550 language lang_names
[] =
552 { "ada", Ada_funcs
, NULL
, Ada_suffixes
, NULL
},
553 { "asm", Asm_labels
, NULL
, Asm_suffixes
, NULL
},
554 { "c", default_C_entries
, NULL
, default_C_suffixes
, NULL
},
555 { "c++", Cplusplus_entries
, NULL
, Cplusplus_suffixes
, NULL
},
556 { "c*", Cstar_entries
, NULL
, Cstar_suffixes
, NULL
},
557 { "cobol", Cobol_paragraphs
, NULL
, Cobol_suffixes
, NULL
},
558 { "erlang", Erlang_functions
, NULL
, Erlang_suffixes
, NULL
},
559 { "fortran", Fortran_functions
, NULL
, Fortran_suffixes
, NULL
},
560 { "java", Cjava_entries
, NULL
, Cjava_suffixes
, NULL
},
561 { "lisp", Lisp_functions
, NULL
, Lisp_suffixes
, NULL
},
562 { "makefile", Makefile_targets
, Makefile_filenames
, NULL
, NULL
},
563 { "pascal", Pascal_functions
, NULL
, Pascal_suffixes
, NULL
},
564 { "perl", Perl_functions
, NULL
, Perl_suffixes
, Perl_interpreters
},
565 { "postscript", Postscript_functions
, NULL
, Postscript_suffixes
, NULL
},
566 { "proc", plain_C_entries
, NULL
, plain_C_suffixes
, NULL
},
567 { "prolog", Prolog_functions
, NULL
, Prolog_suffixes
, NULL
},
568 { "python", Python_functions
, NULL
, Python_suffixes
, NULL
},
569 { "scheme", Scheme_functions
, NULL
, Scheme_suffixes
, NULL
},
570 { "tex", TeX_commands
, NULL
, TeX_suffixes
, NULL
},
571 { "texinfo", Texinfo_nodes
, NULL
, Texinfo_suffixes
, NULL
},
572 { "yacc", Yacc_entries
, NULL
, Yacc_suffixes
, NULL
},
573 { "auto", NULL
}, /* default guessing scheme */
574 { "none", just_read_file
}, /* regexp matching only */
575 { NULL
, NULL
} /* end of list */
580 print_language_names ()
585 puts ("\nThese are the currently supported languages, along with the\n\
586 default file names and dot suffixes:");
587 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
589 printf (" %-*s", 10, lang
->name
);
590 if (lang
->filenames
!= NULL
)
591 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
592 printf (" %s", *name
);
593 if (lang
->suffixes
!= NULL
)
594 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
595 printf (" .%s", *ext
);
598 puts ("Where `auto' means use default language for files based on file\n\
599 name suffix, and `none' means only do regexp processing on files.\n\
600 If no language is specified and no matching suffix is found,\n\
601 the first line of the file is read for a sharp-bang (#!) sequence\n\
602 followed by the name of an interpreter. If no such sequence is found,\n\
603 Fortran is tried first; if no tags are found, C is tried next.\n\
604 When parsing any C file, a \"class\" keyword switches to C++.\n\
605 Compressed files are supported using gzip and bzip2.");
609 # define EMACS_NAME "GNU Emacs"
612 # define VERSION "21"
617 printf ("%s (%s %s)\n", (CTAGS
) ? "ctags" : "etags", EMACS_NAME
, VERSION
);
618 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold");
619 puts ("This program is distributed under the same terms as Emacs");
627 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
629 These are the options accepted by %s.\n", progname
, progname
);
631 puts ("You may use unambiguous abbreviations for the long option names.");
633 puts ("Long option names do not work with this executable, as it is not\n\
634 linked with GNU getopt.");
635 #endif /* LONG_OPTIONS */
636 puts ("A - as file name means read names from stdin (one per line).");
638 printf (" Absolute names are stored in the output file as they are.\n\
639 Relative ones are stored relative to the output file's directory.");
642 puts ("-a, --append\n\
643 Append tag entries to existing tags file.");
645 puts ("--packages-only\n\
646 For Ada files, only generate tags for packages .");
649 puts ("-B, --backward-search\n\
650 Write the search commands for the tag entries using '?', the\n\
651 backward-search command instead of '/', the forward-search command.");
653 /* This option is mostly obsolete, because etags can now automatically
654 detect C++. Retained for backward compatibility and for debugging and
655 experimentation. In principle, we could want to tag as C++ even
656 before any "class" keyword.
658 Treat files whose name suffix defaults to C language as C++ files.");
661 puts ("--declarations\n\
662 In C and derived languages, create tags for function declarations,");
664 puts ("\tand create tags for extern variables if --globals is used.");
667 ("\tand create tags for extern variables unless --no-globals is used.");
670 puts ("-d, --defines\n\
671 Create tag entries for C #define constants and enum constants, too.");
673 puts ("-D, --no-defines\n\
674 Don't create tag entries for C #define constants and enum constants.\n\
675 This makes the tags file smaller.");
679 puts ("-i FILE, --include=FILE\n\
680 Include a note in tag file indicating that, when searching for\n\
681 a tag, one should also consult the tags file FILE after\n\
682 checking the current file.");
683 puts ("-l LANG, --language=LANG\n\
684 Force the following files to be considered as written in the\n\
685 named language up to the next --language=LANG option.");
690 Create tag entries for global variables in some languages.");
692 puts ("--no-globals\n\
693 Do not create tag entries for global variables in some\n\
694 languages. This makes the tags file smaller.");
696 Create tag entries for member variables in C and derived languages.");
699 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
700 Make a tag for each line matching pattern REGEXP in the following\n\
701 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\
702 regexfile is a file containing one REGEXP per line.\n\
703 REGEXP is anchored (as if preceded by ^).\n\
704 The form /REGEXP/NAME/ creates a named tag.\n\
705 For example Tcl named tags can be created with:\n\
706 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
707 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\
708 Like -r, --regex but ignore case when matching expressions.");
709 puts ("-R, --no-regex\n\
710 Don't create tags from regexps for the following files.");
711 #endif /* ETAGS_REGEXPS */
712 puts ("-o FILE, --output=FILE\n\
713 Write the tags to FILE.");
714 puts ("-I, --ignore-indentation\n\
715 Don't rely on indentation quite as much as normal. Currently,\n\
716 this means not to assume that a closing brace in the first\n\
717 column is the final brace of a function or structure\n\
718 definition in C and C++.");
722 puts ("-t, --typedefs\n\
723 Generate tag entries for C and Ada typedefs.");
724 puts ("-T, --typedefs-and-c++\n\
725 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
726 and C++ member functions.");
727 puts ("-u, --update\n\
728 Update the tag entries for the given files, leaving tag\n\
729 entries for other files in place. Currently, this is\n\
730 implemented by deleting the existing entries for the given\n\
731 files and then rewriting the new entries at the end of the\n\
732 tags file. It is often faster to simply rebuild the entire\n\
733 tag file than to use this.");
734 puts ("-v, --vgrind\n\
735 Generates an index of items intended for human consumption,\n\
736 similar to the output of vgrind. The index is sorted, and\n\
737 gives the page number of each item.");
738 puts ("-w, --no-warn\n\
739 Suppress warning messages about entries defined in multiple\n\
741 puts ("-x, --cxref\n\
742 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
743 The output uses line numbers instead of page numbers, but\n\
744 beyond that the differences are cosmetic; try both to see\n\
748 puts ("-V, --version\n\
749 Print the version of the program.\n\
751 Print this help message.");
753 print_language_names ();
756 puts ("Report bugs to bug-gnu-emacs@gnu.org");
770 /* This structure helps us allow mixing of --lang and file names. */
773 enum argument_type arg_type
;
775 language
*lang
; /* language of the regexp */
778 #ifdef VMS /* VMS specific functions */
782 /* This is a BUG! ANY arbitrary limit is a BUG!
783 Won't someone please fix this? */
784 #define MAX_FILE_SPEC_LEN 255
787 char body
[MAX_FILE_SPEC_LEN
+ 1];
791 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
792 returning in each successive call the next file name matching the input
793 spec. The function expects that each in_spec passed
794 to it will be processed to completion; in particular, up to and
795 including the call following that in which the last matching name
796 is returned, the function ignores the value of in_spec, and will
797 only start processing a new spec with the following call.
798 If an error occurs, on return out_spec contains the value
799 of in_spec when the error occurred.
801 With each successive file name returned in out_spec, the
802 function's return value is one. When there are no more matching
803 names the function returns zero. If on the first call no file
804 matches in_spec, or there is any other error, -1 is returned.
809 #define OUTSIZE MAX_FILE_SPEC_LEN
815 static long context
= 0;
816 static struct dsc$descriptor_s o
;
817 static struct dsc$descriptor_s i
;
818 static bool pass1
= TRUE
;
825 o
.dsc$a_pointer
= (char *) out
;
826 o
.dsc$w_length
= (short)OUTSIZE
;
827 i
.dsc$a_pointer
= in
;
828 i
.dsc$w_length
= (short)strlen(in
);
829 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
830 i
.dsc$b_class
= DSC$K_CLASS_S
;
831 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
832 o
.dsc$b_class
= DSC$K_CLASS_VS
;
834 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
836 out
->body
[out
->curlen
] = EOS
;
839 else if (status
== RMS$_NMF
)
843 strcpy(out
->body
, in
);
846 lib$
find_file_end(&context
);
852 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
853 name of each file specified by the provided arg expanding wildcards.
856 gfnames (arg
, p_error
)
860 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
862 switch (fn_exp (&filename
, arg
))
866 return filename
.body
;
872 return filename
.body
;
876 #ifndef OLD /* Newer versions of VMS do provide `system'. */
880 error ("%s", "system() function not implemented under VMS");
884 #define VERSION_DELIM ';'
885 char *massage_name (s
)
891 if (*s
== VERSION_DELIM
)
909 unsigned int nincluded_files
;
910 char **included_files
;
913 int current_arg
, file_count
;
914 linebuffer filename_lb
;
920 _fmode
= O_BINARY
; /* all of files are treated as binary files */
925 included_files
= xnew (argc
, char *);
929 /* Allocate enough no matter what happens. Overkill, but each one
931 argbuffer
= xnew (argc
, argument
);
934 /* Set syntax for regular expression routines. */
935 re_set_syntax (RE_SYNTAX_EMACS
| RE_INTERVALS
);
936 /* Translation table for case-insensitive search. */
937 for (i
= 0; i
< CHAR_SET_SIZE
; i
++)
938 lc_trans
[i
] = lowcase (i
);
939 #endif /* ETAGS_REGEXPS */
942 * If etags, always find typedefs and structure tags. Why not?
943 * Also default to find macro constants, enum constants and
948 typedefs
= typedefs_or_cplusplus
= constantypedefs
= TRUE
;
950 declarations
= FALSE
;
960 optstring
= "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH";
962 optstring
= "-aCdDf:Il:o:StTi:BuvxwVhH";
963 #endif /* ETAGS_REGEXPS */
966 optstring
= optstring
+ 1;
967 #endif /* LONG_OPTIONS */
969 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
976 /* If getopt returns 0, then it has already processed a
977 long-named option. We should do nothing. */
981 /* This means that a file name has been seen. Record it. */
982 argbuffer
[current_arg
].arg_type
= at_filename
;
983 argbuffer
[current_arg
].what
= optarg
;
988 /* Common options. */
989 case 'a': append_to_tagfile
= TRUE
; break;
990 case 'C': cplusplus
= TRUE
; break;
991 case 'd': constantypedefs
= TRUE
; break;
992 case 'D': constantypedefs
= FALSE
; break;
993 case 'f': /* for compatibility with old makefiles */
997 error ("-o option may only be given once.", (char *)NULL
);
998 suggest_asking_for_help ();
1003 case 'S': /* for backward compatibility */
1004 noindentypedefs
= TRUE
;
1008 language
*lang
= get_language_from_langname (optarg
);
1011 argbuffer
[current_arg
].lang
= lang
;
1012 argbuffer
[current_arg
].arg_type
= at_language
;
1017 #ifdef ETAGS_REGEXPS
1019 argbuffer
[current_arg
].arg_type
= at_regexp
;
1020 argbuffer
[current_arg
].what
= optarg
;
1024 argbuffer
[current_arg
].arg_type
= at_regexp
;
1025 argbuffer
[current_arg
].what
= NULL
;
1029 argbuffer
[current_arg
].arg_type
= at_icregexp
;
1030 argbuffer
[current_arg
].what
= optarg
;
1033 #endif /* ETAGS_REGEXPS */
1045 typedefs
= typedefs_or_cplusplus
= TRUE
;
1050 included_files
[nincluded_files
++] = optarg
;
1053 /* Ctags options. */
1054 case 'B': searchar
= '?'; break;
1055 case 'u': update
= TRUE
; break;
1056 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
1057 case 'x': cxref_style
= TRUE
; break;
1058 case 'w': no_warnings
= TRUE
; break;
1061 suggest_asking_for_help ();
1065 for (; optind
< argc
; ++optind
)
1067 argbuffer
[current_arg
].arg_type
= at_filename
;
1068 argbuffer
[current_arg
].what
= argv
[optind
];
1073 if (nincluded_files
== 0 && file_count
== 0)
1075 error ("no input files specified.", (char *)NULL
);
1076 suggest_asking_for_help ();
1079 if (tagfile
== NULL
)
1080 tagfile
= CTAGS
? "tags" : "TAGS";
1081 cwd
= etags_getcwd (); /* the current working directory */
1082 if (cwd
[strlen (cwd
) - 1] != '/')
1085 cwd
= concat (oldcwd
, "/", "");
1088 if (streq (tagfile
, "-"))
1091 tagfiledir
= absolute_dirname (tagfile
, cwd
);
1093 init (); /* set up boolean "functions" */
1096 initbuffer (&filename_lb
);
1100 if (streq (tagfile
, "-"))
1104 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1105 doesn't take effect until after `stdout' is already open). */
1106 if (!isatty (fileno (stdout
)))
1107 setmode (fileno (stdout
), O_BINARY
);
1111 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1117 * Loop through files finding functions.
1119 for (i
= 0; i
< current_arg
; ++i
)
1121 switch (argbuffer
[i
].arg_type
)
1124 forced_lang
= argbuffer
[i
].lang
;
1126 #ifdef ETAGS_REGEXPS
1128 analyse_regex (argbuffer
[i
].what
, FALSE
);
1131 analyse_regex (argbuffer
[i
].what
, TRUE
);
1136 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
1140 error ("can't find file %s\n", this_file
);
1145 this_file
= massage_name (this_file
);
1148 this_file
= argbuffer
[i
].what
;
1150 /* Input file named "-" means read file names from stdin
1151 (one per line) and use them. */
1152 if (streq (this_file
, "-"))
1153 while (readline_internal (&filename_lb
, stdin
) > 0)
1154 process_file (filename_lb
.buffer
);
1156 process_file (this_file
);
1164 #ifdef ETAGS_REGEXPS
1166 #endif /* ETAGS_REGEXPS */
1170 while (nincluded_files
-- > 0)
1171 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1177 /* If CTAGS, we are here. process_file did not write the tags yet,
1178 because we want them ordered. Let's do it now. */
1190 for (i
= 0; i
< current_arg
; ++i
)
1192 if (argbuffer
[i
].arg_type
!= at_filename
)
1195 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1196 tagfile
, argbuffer
[i
].what
, tagfile
);
1197 if (system (cmd
) != GOOD
)
1198 fatal ("failed to execute shell command", (char *)NULL
);
1200 append_to_tagfile
= TRUE
;
1203 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1214 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
1215 exit (system (cmd
));
1223 * Return a compressor given the file name. If EXTPTR is non-zero,
1224 * return a pointer into FILE where the compressor-specific
1225 * extension begins. If no compressor is found, NULL is returned
1226 * and EXTPTR is not significant.
1227 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1230 get_compressor_from_suffix (file
, extptr
)
1235 char *slash
, *suffix
;
1237 /* This relies on FN to be after canonicalize_filename,
1238 so we don't need to consider backslashes on DOS_NT. */
1239 slash
= etags_strrchr (file
, '/');
1240 suffix
= etags_strrchr (file
, '.');
1241 if (suffix
== NULL
|| suffix
< slash
)
1246 /* Let those poor souls who live with DOS 8+3 file name limits get
1247 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1248 Only the first do loop is run if not MSDOS */
1251 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1252 if (streq (compr
->suffix
, suffix
))
1255 break; /* do it only once: not really a loop */
1258 } while (*suffix
!= '\0');
1265 * Return a language given the name.
1268 get_language_from_langname (name
)
1274 error ("empty language name", (char *)NULL
);
1277 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1278 if (streq (name
, lang
->name
))
1280 error ("unknown language \"%s\"", name
);
1288 * Return a language given the interpreter name.
1291 get_language_from_interpreter (interpreter
)
1297 if (interpreter
== NULL
)
1299 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1300 if (lang
->interpreters
!= NULL
)
1301 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1302 if (streq (*iname
, interpreter
))
1311 * Return a language given the file name.
1314 get_language_from_filename (file
)
1318 char **name
, **ext
, *suffix
;
1320 /* Try whole file name first. */
1321 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1322 if (lang
->filenames
!= NULL
)
1323 for (name
= lang
->filenames
; *name
!= NULL
; name
++)
1324 if (streq (*name
, file
))
1327 /* If not found, try suffix after last dot. */
1328 suffix
= etags_strrchr (file
, '.');
1332 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1333 if (lang
->suffixes
!= NULL
)
1334 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1335 if (streq (*ext
, suffix
))
1343 * This routine is called on each file argument.
1349 struct stat stat_buf
;
1352 char *compressed_name
, *uncompressed_name
;
1353 char *ext
, *real_name
;
1356 canonicalize_filename (file
);
1357 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1359 error ("skipping inclusion of %s in self.", file
);
1362 if ((compr
= get_compressor_from_suffix (file
, &ext
)) == NULL
)
1364 compressed_name
= NULL
;
1365 real_name
= uncompressed_name
= savestr (file
);
1369 real_name
= compressed_name
= savestr (file
);
1370 uncompressed_name
= savenstr (file
, ext
- file
);
1373 /* If the canonicalised uncompressed name has already be dealt with,
1374 skip it silently, else add it to the list. */
1376 typedef struct processed_file
1379 struct processed_file
*next
;
1381 static processed_file
*pf_head
= NULL
;
1382 register processed_file
*fnp
;
1384 for (fnp
= pf_head
; fnp
!= NULL
; fnp
= fnp
->next
)
1385 if (streq (uncompressed_name
, fnp
->filename
))
1388 pf_head
= xnew (1, struct processed_file
);
1389 pf_head
->filename
= savestr (uncompressed_name
);
1390 pf_head
->next
= fnp
;
1393 if (stat (real_name
, &stat_buf
) != 0)
1395 /* Reset real_name and try with a different name. */
1397 if (compressed_name
!= NULL
) /* try with the given suffix */
1399 if (stat (uncompressed_name
, &stat_buf
) == 0)
1400 real_name
= uncompressed_name
;
1402 else /* try all possible suffixes */
1404 for (compr
= compressors
; compr
->suffix
!= NULL
; compr
++)
1406 compressed_name
= concat (file
, ".", compr
->suffix
);
1407 if (stat (compressed_name
, &stat_buf
) != 0)
1411 char *suf
= compressed_name
+ strlen (file
);
1412 size_t suflen
= strlen (compr
->suffix
) + 1;
1413 for ( ; suf
[1]; suf
++, suflen
--)
1415 memmove (suf
, suf
+ 1, suflen
);
1416 if (stat (compressed_name
, &stat_buf
) == 0)
1418 real_name
= compressed_name
;
1422 if (real_name
!= NULL
)
1425 free (compressed_name
);
1426 compressed_name
= NULL
;
1430 real_name
= compressed_name
;
1435 if (real_name
== NULL
)
1440 } /* try with a different name */
1442 if (!S_ISREG (stat_buf
.st_mode
))
1444 error ("skipping %s: it is not a regular file.", real_name
);
1447 if (real_name
== compressed_name
)
1449 char *cmd
= concat (compr
->command
, " ", real_name
);
1450 inf
= (FILE *) popen (cmd
, "r");
1454 inf
= fopen (real_name
, "r");
1461 find_entries (uncompressed_name
, inf
);
1463 if (real_name
== compressed_name
)
1472 if (filename_is_absolute (uncompressed_name
))
1474 /* file is an absolute file name. Canonicalise it. */
1475 filename
= absolute_filename (uncompressed_name
, cwd
);
1479 /* file is a file name relative to cwd. Make it relative
1480 to the directory of the tags file. */
1481 filename
= relative_filename (uncompressed_name
, tagfiledir
);
1483 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1491 if (compressed_name
) free(compressed_name
);
1492 if (uncompressed_name
) free(uncompressed_name
);
1497 * This routine sets up the boolean pseudo-functions which work
1498 * by setting boolean flags dependent upon the corresponding character.
1499 * Every char which is NOT in that string is not a white char. Therefore,
1500 * all of the array "_wht" is set to FALSE, and then the elements
1501 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1502 * of a char is TRUE if it is the string "white", else FALSE.
1510 for (i
= 0; i
< CHARS
; i
++)
1511 iswhite(i
) = notinname(i
) = begtoken(i
) = intoken(i
) = endtoken(i
) = FALSE
;
1512 for (sp
= white
; *sp
!= '\0'; sp
++) iswhite (*sp
) = TRUE
;
1513 for (sp
= nonam
; *sp
!= '\0'; sp
++) notinname (*sp
) = TRUE
;
1514 notinname('\0') = notinname('\n');
1515 for (sp
= begtk
; *sp
!= '\0'; sp
++) begtoken (*sp
) = TRUE
;
1516 begtoken('\0') = begtoken('\n');
1517 for (sp
= midtk
; *sp
!= '\0'; sp
++) intoken (*sp
) = TRUE
;
1518 intoken('\0') = intoken('\n');
1519 for (sp
= endtk
; *sp
!= '\0'; sp
++) endtoken (*sp
) = TRUE
;
1520 endtoken('\0') = endtoken('\n');
1524 * This routine opens the specified file and calls the function
1525 * which finds the function and type definitions.
1527 node
*last_node
= NULL
;
1530 find_entries (file
, inf
)
1536 node
*old_last_node
;
1538 /* Memory leakage here: the string pointed by curfile is
1539 never released, because curfile is copied into np->file
1540 for each node, to be used in CTAGS mode. The amount of
1541 memory leaked here is the sum of the lengths of the
1543 curfile
= savestr (file
);
1545 /* If user specified a language, use it. */
1547 if (lang
!= NULL
&& lang
->function
!= NULL
)
1550 lang
->function (inf
);
1554 /* Try to guess the language given the file name. */
1555 lang
= get_language_from_filename (file
);
1556 if (lang
!= NULL
&& lang
->function
!= NULL
)
1559 lang
->function (inf
);
1563 /* Look for sharp-bang as the first two characters. */
1564 if (readline_internal (&lb
, inf
) > 0
1566 && lb
.buffer
[0] == '#'
1567 && lb
.buffer
[1] == '!')
1571 /* Set lp to point at the first char after the last slash in the
1572 line or, if no slashes, at the first nonblank. Then set cp to
1573 the first successive blank and terminate the string. */
1574 lp
= etags_strrchr (lb
.buffer
+2, '/');
1578 lp
= skip_spaces (lb
.buffer
+ 2);
1579 cp
= skip_non_spaces (lp
);
1582 if (strlen (lp
) > 0)
1584 lang
= get_language_from_interpreter (lp
);
1585 if (lang
!= NULL
&& lang
->function
!= NULL
)
1588 lang
->function (inf
);
1593 /* We rewind here, even if inf may be a pipe. We fail if the
1594 length of the first line is longer than the pipe block size,
1595 which is unlikely. */
1599 old_last_node
= last_node
;
1600 curlang
= get_language_from_langname ("fortran");
1601 Fortran_functions (inf
);
1603 /* No Fortran entries found. Try C. */
1604 if (old_last_node
== last_node
)
1606 /* We do not tag if rewind fails.
1607 Only the file name will be recorded in the tags file. */
1609 curlang
= get_language_from_langname (cplusplus
? "c++" : "c");
1610 default_C_entries (inf
);
1618 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1619 char *name
; /* tag name, or NULL if unnamed */
1620 bool is_func
; /* tag is a function */
1621 char *linestart
; /* start of the line where tag is */
1622 int linelen
; /* length of the line where tag is */
1623 int lno
; /* line number */
1624 long cno
; /* character number */
1628 if (CTAGS
&& name
== NULL
)
1631 np
= xnew (1, node
);
1633 /* If ctags mode, change name "main" to M<thisfilename>. */
1634 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1636 register char *fp
= etags_strrchr (curfile
, '/');
1637 np
->name
= concat ("M", fp
== NULL
? curfile
: fp
+ 1, "");
1638 fp
= etags_strrchr (np
->name
, '.');
1639 if (fp
!= NULL
&& fp
[1] != '\0' && fp
[2] == '\0')
1644 np
->been_warned
= FALSE
;
1646 np
->is_func
= is_func
;
1648 /* Our char numbers are 0-base, because of C language tradition?
1649 ctags compatibility? old versions compatibility? I don't know.
1650 Anyway, since emacs's are 1-base we expect etags.el to take care
1651 of the difference. If we wanted to have 1-based numbers, we would
1652 uncomment the +1 below. */
1653 np
->cno
= cno
/* + 1 */ ;
1654 np
->left
= np
->right
= NULL
;
1655 if (CTAGS
&& !cxref_style
)
1657 if (strlen (linestart
) < 50)
1658 np
->pat
= concat (linestart
, "$", "");
1660 np
->pat
= savenstr (linestart
, 50);
1663 np
->pat
= savenstr (linestart
, linelen
);
1665 add_node (np
, &head
);
1669 * TAGS format specification
1670 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1672 * pfnote should emit the optimized form [unnamed tag] only if:
1673 * 1. name does not contain any of the characters " \t\r\n(),;";
1674 * 2. linestart contains name as either a rightmost, or rightmost but
1675 * one character, substring;
1676 * 3. the character, if any, immediately before name in linestart must
1677 * be one of the characters " \t(),;";
1678 * 4. the character, if any, immediately after name in linestart must
1679 * also be one of the characters " \t(),;".
1681 * The real implementation uses the notinname() macro, which recognises
1682 * characters slightly different form " \t\r\n(),;". See the variable
1685 #define traditional_tag_style TRUE
1687 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1688 char *name
; /* tag name, or NULL if unnamed */
1689 int namelen
; /* tag length */
1690 bool is_func
; /* tag is a function */
1691 char *linestart
; /* start of the line where tag is */
1692 int linelen
; /* length of the line where tag is */
1693 int lno
; /* line number */
1694 long cno
; /* character number */
1702 for (cp
= name
; !notinname (*cp
); cp
++)
1704 if (*cp
== '\0') /* rule #1 */
1706 cp
= linestart
+ linelen
- namelen
;
1707 if (notinname (linestart
[linelen
-1]))
1708 cp
-= 1; /* rule #4 */
1709 if (cp
>= linestart
/* rule #2 */
1711 || notinname (cp
[-1])) /* rule #3 */
1712 && strneq (name
, cp
, namelen
)) /* rule #2 */
1713 named
= FALSE
; /* use unnamed tag */
1718 name
= savenstr (name
, namelen
);
1721 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1726 * recurse on left children, iterate on right children.
1734 register node
*node_right
= np
->right
;
1735 free_tree (np
->left
);
1736 if (np
->name
!= NULL
)
1746 * Adds a node to the tree of nodes. In etags mode, we don't keep
1747 * it sorted; we just keep a linear list. In ctags mode, maintain
1748 * an ordered tree, with no attempt at balancing.
1750 * add_node is the only function allowed to add nodes, so it can
1754 add_node (np
, cur_node_p
)
1755 node
*np
, **cur_node_p
;
1758 register node
*cur_node
= *cur_node_p
;
1760 if (cur_node
== NULL
)
1770 if (last_node
== NULL
)
1771 fatal ("internal error in add_node", (char *)NULL
);
1772 last_node
->right
= np
;
1778 dif
= strcmp (np
->name
, cur_node
->name
);
1781 * If this tag name matches an existing one, then
1782 * do not add the node, but maybe print a warning.
1786 if (streq (np
->file
, cur_node
->file
))
1790 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1791 np
->file
, lineno
, np
->name
);
1792 fprintf (stderr
, "Second entry ignored\n");
1795 else if (!cur_node
->been_warned
&& !no_warnings
)
1799 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1800 np
->file
, cur_node
->file
, np
->name
);
1801 cur_node
->been_warned
= TRUE
;
1806 /* Actually add the node */
1807 add_node (np
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1821 /* Output subentries that precede this one */
1822 put_entries (np
->left
);
1824 /* Output this entry */
1828 if (np
->name
!= NULL
)
1829 fprintf (tagf
, "%s\177%s\001%d,%ld\n",
1830 np
->pat
, np
->name
, np
->lno
, np
->cno
);
1832 fprintf (tagf
, "%s\177%d,%ld\n",
1833 np
->pat
, np
->lno
, np
->cno
);
1837 if (np
->name
== NULL
)
1838 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
1843 fprintf (stdout
, "%s %s %d\n",
1844 np
->name
, np
->file
, (np
->lno
+ 63) / 64);
1846 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1847 np
->name
, np
->lno
, np
->file
, np
->pat
);
1851 fprintf (tagf
, "%s\t%s\t", np
->name
, np
->file
);
1855 putc (searchar
, tagf
);
1858 for (sp
= np
->pat
; *sp
; sp
++)
1860 if (*sp
== '\\' || *sp
== searchar
)
1864 putc (searchar
, tagf
);
1867 { /* a typedef; text pattern inadequate */
1868 fprintf (tagf
, "%d", np
->lno
);
1874 /* Output subentries that follow this one */
1875 put_entries (np
->right
);
1878 /* Length of a number's decimal representation. */
1884 while ((num
/= 10) > 0)
1890 * Return total number of characters that put_entries will output for
1891 * the nodes in the subtree of the specified node. Works only if
1892 * we are not ctags, but called only in that case. This count
1893 * is irrelevant with the new tags.el, but is still supplied for
1894 * backward compatibility.
1897 total_size_of_entries (np
)
1905 for (total
= 0; np
!= NULL
; np
= np
->right
)
1907 /* Count left subentries. */
1908 total
+= total_size_of_entries (np
->left
);
1910 /* Count this entry */
1911 total
+= strlen (np
->pat
) + 1;
1912 total
+= number_len ((long) np
->lno
) + 1 + number_len (np
->cno
) + 1;
1913 if (np
->name
!= NULL
)
1914 total
+= 1 + strlen (np
->name
); /* \001name */
1922 #define C_EXT 0x00fff /* C extensions */
1923 #define C_PLAIN 0x00000 /* C */
1924 #define C_PLPL 0x00001 /* C++ */
1925 #define C_STAR 0x00003 /* C* */
1926 #define C_JAVA 0x00005 /* JAVA */
1927 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
1928 #define YACC 0x10000 /* yacc file */
1931 * The C symbol tables.
1936 st_C_objprot
, st_C_objimpl
, st_C_objend
,
1942 st_C_struct
, st_C_extern
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1945 static unsigned int hash
P_((const char *, unsigned int));
1946 static struct C_stab_entry
* in_word_set
P_((const char *, unsigned int));
1947 static enum sym_type C_symtype
P_((char *, int, int));
1949 /* Feed stuff between (but not including) %[ and %] lines to:
1950 gperf -c -k 1,3 -o -p -r -t
1952 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1956 while, 0, st_C_ignore
1957 switch, 0, st_C_ignore
1958 return, 0, st_C_ignore
1959 @interface, 0, st_C_objprot
1960 @protocol, 0, st_C_objprot
1961 @implementation,0, st_C_objimpl
1962 @end, 0, st_C_objend
1963 import, C_JAVA, st_C_ignore
1964 package, C_JAVA, st_C_ignore
1965 friend, C_PLPL, st_C_ignore
1966 extends, C_JAVA, st_C_javastruct
1967 implements, C_JAVA, st_C_javastruct
1968 interface, C_JAVA, st_C_struct
1969 class, 0, st_C_class
1970 namespace, C_PLPL, st_C_struct
1971 domain, C_STAR, st_C_struct
1972 union, 0, st_C_struct
1973 struct, 0, st_C_struct
1974 extern, 0, st_C_extern
1976 typedef, 0, st_C_typedef
1977 define, 0, st_C_define
1978 operator, C_PLPL, st_C_operator
1979 bool, C_PLPL, st_C_typespec
1980 long, 0, st_C_typespec
1981 short, 0, st_C_typespec
1982 int, 0, st_C_typespec
1983 char, 0, st_C_typespec
1984 float, 0, st_C_typespec
1985 double, 0, st_C_typespec
1986 signed, 0, st_C_typespec
1987 unsigned, 0, st_C_typespec
1988 auto, 0, st_C_typespec
1989 void, 0, st_C_typespec
1990 static, 0, st_C_typespec
1991 const, 0, st_C_typespec
1992 volatile, 0, st_C_typespec
1993 explicit, C_PLPL, st_C_typespec
1994 mutable, C_PLPL, st_C_typespec
1995 typename, C_PLPL, st_C_typespec
1996 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1997 DEFUN, 0, st_C_gnumacro
1998 SYSCALL, 0, st_C_gnumacro
1999 ENTRY, 0, st_C_gnumacro
2000 PSEUDO, 0, st_C_gnumacro
2001 # These are defined inside C functions, so currently they are not met.
2002 # EXFUN used in glibc, DEFVAR_* in emacs.
2003 #EXFUN, 0, st_C_gnumacro
2004 #DEFVAR_, 0, st_C_gnumacro
2006 and replace lines between %< and %> with its output,
2007 then make in_word_set static. */
2009 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
2010 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
2011 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
2013 #define TOTAL_KEYWORDS 46
2014 #define MIN_WORD_LENGTH 2
2015 #define MAX_WORD_LENGTH 15
2016 #define MIN_HASH_VALUE 13
2017 #define MAX_HASH_VALUE 121
2018 /* maximum key range = 109, duplicates = 0 */
2025 register const char *str
;
2026 register unsigned int len
;
2028 static unsigned char asso_values
[] =
2030 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2031 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2032 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2033 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2034 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2035 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2036 122, 122, 122, 122, 57, 122, 122, 122, 55, 6,
2037 60, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2038 51, 122, 122, 10, 2, 122, 122, 122, 122, 122,
2039 122, 122, 122, 122, 122, 122, 122, 2, 52, 59,
2040 49, 38, 56, 41, 122, 22, 122, 122, 9, 32,
2041 33, 60, 26, 122, 1, 28, 46, 59, 44, 51,
2042 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2043 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2044 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2045 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2046 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2047 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2048 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2049 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2050 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2051 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2052 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2053 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2054 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
2055 122, 122, 122, 122, 122, 122
2057 register int hval
= len
;
2063 hval
+= asso_values
[(unsigned char)str
[2]];
2066 hval
+= asso_values
[(unsigned char)str
[0]];
2075 struct C_stab_entry
*
2076 in_word_set (str
, len
)
2077 register const char *str
;
2078 register unsigned int len
;
2080 static struct C_stab_entry wordlist
[] =
2082 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2083 {""}, {""}, {""}, {""},
2084 {"ENTRY", 0, st_C_gnumacro
},
2085 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2087 {"if", 0, st_C_ignore
},
2089 {"SYSCALL", 0, st_C_gnumacro
},
2090 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2091 {"struct", 0, st_C_struct
},
2092 {"static", 0, st_C_typespec
},
2093 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2094 {"long", 0, st_C_typespec
},
2095 {""}, {""}, {""}, {""}, {""},
2096 {"auto", 0, st_C_typespec
},
2097 {"return", 0, st_C_ignore
},
2098 {"import", C_JAVA
, st_C_ignore
},
2100 {"switch", 0, st_C_ignore
},
2102 {"implements", C_JAVA
, st_C_javastruct
},
2104 {"for", 0, st_C_ignore
},
2105 {"volatile", 0, st_C_typespec
},
2107 {"PSEUDO", 0, st_C_gnumacro
},
2109 {"char", 0, st_C_typespec
},
2110 {"class", 0, st_C_class
},
2111 {"@protocol", 0, st_C_objprot
},
2113 {"void", 0, st_C_typespec
},
2114 {"int", 0, st_C_typespec
},
2115 {"explicit", C_PLPL
, st_C_typespec
},
2117 {"namespace", C_PLPL
, st_C_struct
},
2118 {"signed", 0, st_C_typespec
},
2120 {"interface", C_JAVA
, st_C_struct
},
2121 {"while", 0, st_C_ignore
},
2122 {"typedef", 0, st_C_typedef
},
2123 {"typename", C_PLPL
, st_C_typespec
},
2125 {"friend", C_PLPL
, st_C_ignore
},
2126 {"mutable", C_PLPL
, st_C_typespec
},
2127 {"union", 0, st_C_struct
},
2128 {"domain", C_STAR
, st_C_struct
},
2130 {"extern", 0, st_C_extern
},
2131 {"extends", C_JAVA
, st_C_javastruct
},
2132 {"package", C_JAVA
, st_C_ignore
},
2133 {"short", 0, st_C_typespec
},
2134 {"@end", 0, st_C_objend
},
2135 {"unsigned", 0, st_C_typespec
},
2137 {"const", 0, st_C_typespec
},
2139 {"@interface", 0, st_C_objprot
},
2140 {"enum", 0, st_C_enum
},
2142 {"@implementation",0, st_C_objimpl
},
2144 {"operator", C_PLPL
, st_C_operator
},
2145 {""}, {""}, {""}, {""},
2146 {"define", 0, st_C_define
},
2148 {"double", 0, st_C_typespec
},
2150 {"bool", C_PLPL
, st_C_typespec
},
2152 {"DEFUN", 0, st_C_gnumacro
},
2153 {"float", 0, st_C_typespec
}
2156 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
2158 register int key
= hash (str
, len
);
2160 if (key
<= MAX_HASH_VALUE
&& key
>= 0)
2162 register const char *s
= wordlist
[key
].name
;
2164 if (*str
== *s
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
2165 return &wordlist
[key
];
2172 static enum sym_type
2173 C_symtype (str
, len
, c_ext
)
2178 register struct C_stab_entry
*se
= in_word_set (str
, len
);
2180 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
2187 * C functions and variables are recognized using a simple
2188 * finite automaton. fvdef is its state variable.
2192 fvnone
, /* nothing seen */
2193 fdefunkey
, /* Emacs DEFUN keyword seen */
2194 fdefunname
, /* Emacs DEFUN name seen */
2195 foperator
, /* func: operator keyword seen (cplpl) */
2196 fvnameseen
, /* function or variable name seen */
2197 fstartlist
, /* func: just after open parenthesis */
2198 finlist
, /* func: in parameter list */
2199 flistseen
, /* func: after parameter list */
2200 fignore
, /* func: before open brace */
2201 vignore
/* var-like: ignore until ';' */
2204 bool fvextern
; /* func or var: extern keyword seen; */
2207 * typedefs are recognized using a simple finite automaton.
2208 * typdef is its state variable.
2212 tnone
, /* nothing seen */
2213 tkeyseen
, /* typedef keyword seen */
2214 ttypeseen
, /* defined type seen */
2215 tinbody
, /* inside typedef body */
2216 tend
, /* just before typedef tag */
2217 tignore
/* junk after typedef tag */
2221 * struct-like structures (enum, struct and union) are recognized
2222 * using another simple finite automaton. `structdef' is its state
2227 snone
, /* nothing seen yet,
2228 or in struct body if cblev > 0 */
2229 skeyseen
, /* struct-like keyword seen */
2230 stagseen
, /* struct-like tag seen */
2231 sintemplate
, /* inside template (ignore) */
2232 scolonseen
/* colon seen after struct-like tag */
2236 * When objdef is different from onone, objtag is the name of the class.
2238 char *objtag
= "<uninited>";
2241 * Yet another little state machine to deal with preprocessor lines.
2245 dnone
, /* nothing seen */
2246 dsharpseen
, /* '#' seen as first char on line */
2247 ddefineseen
, /* '#' and 'define' seen */
2248 dignorerest
/* ignore rest of line */
2252 * State machine for Objective C protocols and implementations.
2253 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2257 onone
, /* nothing seen */
2258 oprotocol
, /* @interface or @protocol seen */
2259 oimplementation
, /* @implementations seen */
2260 otagseen
, /* class name seen */
2261 oparenseen
, /* parenthesis before category seen */
2262 ocatseen
, /* category name seen */
2263 oinbody
, /* in @implementation body */
2264 omethodsign
, /* in @implementation body, after +/- */
2265 omethodtag
, /* after method name */
2266 omethodcolon
, /* after method colon */
2267 omethodparm
, /* after method parameter */
2268 oignore
/* wait for @end */
2273 * Use this structure to keep info about the token read, and how it
2274 * should be tagged. Used by the make_C_tag function to build a tag.
2285 } token
; /* latest token read */
2286 linebuffer token_name
; /* its name */
2289 * Variables and functions for dealing with nested structures.
2290 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2292 static void pushclass_above
P_((int, char *, int));
2293 static void popclass_above
P_((int));
2294 static void write_classname
P_((linebuffer
*, char *qualifier
));
2297 char **cname
; /* nested class names */
2298 int *cblev
; /* nested class curly brace level */
2299 int nl
; /* class nesting level (elements used) */
2300 int size
; /* length of the array */
2301 } cstack
; /* stack for nested declaration tags */
2302 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2303 #define nestlev (cstack.nl)
2304 /* After struct keyword or in struct body, not inside an nested function. */
2305 #define instruct (structdef == snone && nestlev > 0 \
2306 && cblev == cstack.cblev[nestlev-1] + 1)
2309 pushclass_above (cblev
, str
, len
)
2316 popclass_above (cblev
);
2318 if (nl
>= cstack
.size
)
2320 int size
= cstack
.size
*= 2;
2321 xrnew (cstack
.cname
, size
, char *);
2322 xrnew (cstack
.cblev
, size
, int);
2324 assert (nl
== 0 || cstack
.cblev
[nl
-1] < cblev
);
2325 cstack
.cname
[nl
] = (str
== NULL
) ? NULL
: savenstr (str
, len
);
2326 cstack
.cblev
[nl
] = cblev
;
2331 popclass_above (cblev
)
2336 for (nl
= cstack
.nl
- 1;
2337 nl
>= 0 && cstack
.cblev
[nl
] >= cblev
;
2340 if (cstack
.cname
[nl
] != NULL
)
2341 free (cstack
.cname
[nl
]);
2347 write_classname (cn
, qualifier
)
2352 int qlen
= strlen (qualifier
);
2354 if (cstack
.nl
== 0 || cstack
.cname
[0] == NULL
)
2358 cn
->buffer
[0] = '\0';
2362 len
= strlen (cstack
.cname
[0]);
2363 linebuffer_setlen (cn
, len
);
2364 strcpy (cn
->buffer
, cstack
.cname
[0]);
2366 for (i
= 1; i
< cstack
.nl
; i
++)
2371 s
= cstack
.cname
[i
];
2376 linebuffer_setlen (cn
, len
);
2377 strncat (cn
->buffer
, qualifier
, qlen
);
2378 strncat (cn
->buffer
, s
, slen
);
2383 static bool consider_token
P_((char *, int, int, int *, int, int, bool *));
2384 static void make_C_tag
P_((bool));
2388 * checks to see if the current token is at the start of a
2389 * function or variable, or corresponds to a typedef, or
2390 * is a struct/union/enum tag, or #define, or an enum constant.
2392 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2393 * with args. C_EXTP points to which language we are looking at.
2404 consider_token (str
, len
, c
, c_extp
, cblev
, parlev
, is_func_or_var
)
2405 register char *str
; /* IN: token pointer */
2406 register int len
; /* IN: token length */
2407 register int c
; /* IN: first char after the token */
2408 int *c_extp
; /* IN, OUT: C extensions mask */
2409 int cblev
; /* IN: curly brace level */
2410 int parlev
; /* IN: parenthesis level */
2411 bool *is_func_or_var
; /* OUT: function or variable found */
2413 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2414 structtype is the type of the preceding struct-like keyword, and
2415 structcblev is the curly brace level where it has been seen. */
2416 static enum sym_type structtype
;
2417 static int structcblev
;
2418 static enum sym_type toktype
;
2421 toktype
= C_symtype (str
, len
, *c_extp
);
2424 * Advance the definedef state machine.
2429 /* We're not on a preprocessor line. */
2430 if (toktype
== st_C_gnumacro
)
2437 if (toktype
== st_C_define
)
2439 definedef
= ddefineseen
;
2443 definedef
= dignorerest
;
2448 * Make a tag for any macro, unless it is a constant
2449 * and constantypedefs is FALSE.
2451 definedef
= dignorerest
;
2452 *is_func_or_var
= (c
== '(');
2453 if (!*is_func_or_var
&& !constantypedefs
)
2460 error ("internal error: definedef value.", (char *)NULL
);
2469 if (toktype
== st_C_typedef
)
2491 if (structdef
== snone
&& fvdef
== fvnone
)
2510 * This structdef business is NOT invoked when we are ctags and the
2511 * file is plain C. This is because a struct tag may have the same
2512 * name as another tag, and this loses with ctags.
2516 case st_C_javastruct
:
2517 if (structdef
== stagseen
)
2518 structdef
= scolonseen
;
2522 && (*c_extp
& C_AUTO
) /* automatic detection of C++ language */
2523 && definedef
== dnone
&& structdef
== snone
2524 && typdef
== tnone
&& fvdef
== fvnone
)
2525 *c_extp
= (*c_extp
| C_PLPL
) & ~C_AUTO
;
2531 && (typdef
== tkeyseen
2532 || (typedefs_or_cplusplus
&& structdef
== snone
)))
2534 structdef
= skeyseen
;
2535 structtype
= toktype
;
2536 structcblev
= cblev
;
2541 if (structdef
== skeyseen
)
2543 structdef
= stagseen
;
2547 if (typdef
!= tnone
)
2550 /* Detect Objective C constructs. */
2560 objdef
= oimplementation
;
2564 case oimplementation
:
2565 /* Save the class tag for functions or variables defined inside. */
2566 objtag
= savenstr (str
, len
);
2570 /* Save the class tag for categories. */
2571 objtag
= savenstr (str
, len
);
2573 *is_func_or_var
= TRUE
;
2577 *is_func_or_var
= TRUE
;
2584 objdef
= omethodtag
;
2585 linebuffer_setlen (&token_name
, len
);
2586 strncpy (token_name
.buffer
, str
, len
);
2587 token_name
.buffer
[len
] = '\0';
2593 objdef
= omethodparm
;
2598 objdef
= omethodtag
;
2599 linebuffer_setlen (&token_name
, token_name
.len
+ len
);
2600 strncat (token_name
.buffer
, str
, len
);
2605 if (toktype
== st_C_objend
)
2607 /* Memory leakage here: the string pointed by objtag is
2608 never released, because many tests would be needed to
2609 avoid breaking on incorrect input code. The amount of
2610 memory leaked here is the sum of the lengths of the
2618 /* A function, variable or enum constant? */
2625 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2626 fvdef
= fvnone
; /* should be useless */
2634 *is_func_or_var
= TRUE
;
2638 && structdef
== snone
2639 && structtype
== st_C_enum
&& cblev
> structcblev
)
2640 return TRUE
; /* enum constant */
2646 fvdef
= fdefunname
; /* GNU macro */
2647 *is_func_or_var
= TRUE
;
2650 if ((strneq (str
, "asm", 3) && endtoken (str
[3]))
2651 || (strneq (str
, "__asm__", 7) && endtoken (str
[7])))
2656 if ((*c_extp
& C_PLPL
) && strneq (str
+len
-10, "::operator", 10))
2659 *is_func_or_var
= TRUE
;
2662 if (cblev
> 0 && !instruct
)
2664 fvdef
= fvnameseen
; /* function or variable */
2665 *is_func_or_var
= TRUE
;
2676 * C_entries often keeps pointers to tokens or lines which are older than
2677 * the line currently read. By keeping two line buffers, and switching
2678 * them at end of line, it is possible to use those pointers.
2686 #define current_lb_is_new (newndx == curndx)
2687 #define switch_line_buffers() (curndx = 1 - curndx)
2689 #define curlb (lbs[curndx].lb)
2690 #define newlb (lbs[newndx].lb)
2691 #define curlinepos (lbs[curndx].linepos)
2692 #define newlinepos (lbs[newndx].linepos)
2694 #define CNL_SAVE_DEFINEDEF() \
2696 curlinepos = charno; \
2698 linecharno = charno; \
2699 charno += readline (&curlb, inf); \
2700 lp = curlb.buffer; \
2707 CNL_SAVE_DEFINEDEF(); \
2708 if (savetoken.valid) \
2710 token = savetoken; \
2711 savetoken.valid = FALSE; \
2713 definedef = dnone; \
2721 /* This function should never be called when token.valid is FALSE, but
2722 we must protect against invalid input or internal errors. */
2723 if (DEBUG
|| token
.valid
)
2725 if (traditional_tag_style
)
2727 /* This was the original code. Now we call new_pfnote instead,
2728 which uses the new method for naming tags (see new_pfnote). */
2731 if (CTAGS
|| token
.named
)
2732 name
= savestr (token_name
.buffer
);
2733 if (DEBUG
&& !token
.valid
)
2736 name
= concat (name
, "##invalid##", "");
2738 name
= savestr ("##invalid##");
2740 pfnote (name
, isfun
, token
.line
,
2741 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2744 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
, token
.line
,
2745 token
.offset
+token
.length
+1, token
.lineno
, token
.linepos
);
2746 token
.valid
= FALSE
;
2753 * This routine finds functions, variables, typedefs,
2754 * #define's, enum constants and struct/union/enum definitions in
2755 * C syntax and adds them to the list.
2758 C_entries (c_ext
, inf
)
2759 int c_ext
; /* extension of C */
2760 FILE *inf
; /* input file */
2762 register char c
; /* latest char read; '\0' for end of line */
2763 register char *lp
; /* pointer one beyond the character `c' */
2764 int curndx
, newndx
; /* indices for current and new lb */
2765 register int tokoff
; /* offset in line of start of current token */
2766 register int toklen
; /* length of current token */
2767 char *qualifier
; /* string used to qualify names */
2768 int qlen
; /* length of qualifier */
2769 int cblev
; /* current curly brace level */
2770 int parlev
; /* current parenthesis level */
2771 int typdefcblev
; /* cblev where a typedef struct body begun */
2772 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2774 bool yacc_rules
; /* in the rules part of a yacc file */
2775 struct tok savetoken
; /* token saved during preprocessor handling */
2778 initbuffer (&token_name
);
2779 initbuffer (&lbs
[0].lb
);
2780 initbuffer (&lbs
[1].lb
);
2781 if (cstack
.size
== 0)
2783 cstack
.size
= (DEBUG
) ? 1 : 4;
2785 cstack
.cname
= xnew (cstack
.size
, char *);
2786 cstack
.cblev
= xnew (cstack
.size
, int);
2789 tokoff
= toklen
= 0; /* keep compiler quiet */
2790 curndx
= newndx
= 0;
2796 fvdef
= fvnone
; fvextern
= FALSE
; typdef
= tnone
;
2797 structdef
= snone
; definedef
= dnone
; objdef
= onone
;
2799 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2800 token
.valid
= savetoken
.valid
= FALSE
;
2803 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2804 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2806 { qualifier
= "."; qlen
= 1; }
2808 { qualifier
= "::"; qlen
= 2; }
2816 /* If we're at the end of the line, the next character is a
2817 '\0'; don't skip it, because it's the thing that tells us
2818 to read the next line. */
2839 /* Newlines inside comments do not end macro definitions in
2841 CNL_SAVE_DEFINEDEF ();
2854 /* Newlines inside strings do not end macro definitions
2855 in traditional cpp, even though compilers don't
2856 usually accept them. */
2857 CNL_SAVE_DEFINEDEF ();
2867 /* Hmmm, something went wrong. */
2896 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2909 else if (/* cplpl && */ *lp
== '/')
2917 if ((c_ext
& YACC
) && *lp
== '%')
2919 /* Entering or exiting rules section in yacc file. */
2921 definedef
= dnone
; fvdef
= fvnone
; fvextern
= FALSE
;
2922 typdef
= tnone
; structdef
= snone
;
2923 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2925 yacc_rules
= !yacc_rules
;
2931 if (definedef
== dnone
)
2934 bool cpptoken
= TRUE
;
2936 /* Look back on this line. If all blanks, or nonblanks
2937 followed by an end of comment, this is a preprocessor
2939 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2942 if (*cp
== '*' && *(cp
+1) == '/')
2951 definedef
= dsharpseen
;
2952 } /* if (definedef == dnone) */
2958 /* Consider token only if some involved conditions are satisfied. */
2959 if (typdef
!= tignore
2960 && definedef
!= dignorerest
2962 && structdef
!= sintemplate
2963 && (definedef
!= dnone
2964 || structdef
!= scolonseen
))
2970 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken (lp
[1]))
2973 * This handles :: in the middle, but not at the
2974 * beginning of an identifier. Also, space-separated
2975 * :: is not recognised.
2984 bool funorvar
= FALSE
;
2987 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
2988 &c_ext
, cblev
, parlev
, &funorvar
))
2990 if (fvdef
== foperator
)
2993 lp
= skip_spaces (lp
-1);
2997 && !iswhite (*lp
) && *lp
!= '(')
3000 toklen
+= lp
- oldlp
;
3002 token
.named
= FALSE
;
3003 if ((c_ext
& C_EXT
) /* not pure C */
3004 && nestlev
> 0 && definedef
== dnone
)
3005 /* in struct body */
3007 write_classname (&token_name
, qualifier
);
3008 linebuffer_setlen (&token_name
,
3009 token_name
.len
+qlen
+toklen
);
3010 strcat (token_name
.buffer
, qualifier
);
3011 strncat (token_name
.buffer
,
3012 newlb
.buffer
+ tokoff
, toklen
);
3015 else if (objdef
== ocatseen
)
3016 /* Objective C category */
3018 int len
= strlen (objtag
) + 2 + toklen
;
3019 linebuffer_setlen (&token_name
, len
);
3020 strcpy (token_name
.buffer
, objtag
);
3021 strcat (token_name
.buffer
, "(");
3022 strncat (token_name
.buffer
,
3023 newlb
.buffer
+ tokoff
, toklen
);
3024 strcat (token_name
.buffer
, ")");
3027 else if (objdef
== omethodtag
3028 || objdef
== omethodparm
)
3029 /* Objective C method */
3033 else if (fvdef
== fdefunname
)
3034 /* GNU DEFUN and similar macros */
3036 bool defun
= (newlb
.buffer
[tokoff
] == 'F');
3040 /* Rewrite the tag so that emacs lisp DEFUNs
3041 can be found by their elisp name */
3048 linebuffer_setlen (&token_name
, len
);
3049 strncpy (token_name
.buffer
,
3050 newlb
.buffer
+ off
, len
);
3051 token_name
.buffer
[len
] = '\0';
3054 if (token_name
.buffer
[len
] == '_')
3055 token_name
.buffer
[len
] = '-';
3056 token
.named
= defun
;
3060 linebuffer_setlen (&token_name
, toklen
);
3061 strncpy (token_name
.buffer
,
3062 newlb
.buffer
+ tokoff
, toklen
);
3063 token_name
.buffer
[toklen
] = '\0';
3064 /* Name macros and members. */
3065 token
.named
= (structdef
== stagseen
3066 || typdef
== ttypeseen
3069 && definedef
== dignorerest
)
3071 && definedef
== dnone
3072 && structdef
== snone
3075 token
.lineno
= lineno
;
3076 token
.offset
= tokoff
;
3077 token
.length
= toklen
;
3078 token
.line
= newlb
.buffer
;
3079 token
.linepos
= newlinepos
;
3082 if (definedef
== dnone
3083 && (fvdef
== fvnameseen
3084 || fvdef
== foperator
3085 || structdef
== stagseen
3087 || typdef
== ttypeseen
3088 || objdef
!= onone
))
3090 if (current_lb_is_new
)
3091 switch_line_buffers ();
3093 else if (definedef
!= dnone
3094 || fvdef
== fdefunname
3096 make_C_tag (funorvar
);
3100 } /* if (endtoken (c)) */
3101 else if (intoken (c
))
3107 } /* if (midtoken) */
3108 else if (begtoken (c
))
3119 make_C_tag (TRUE
); /* a function */
3126 if (structdef
== stagseen
&& !cjava
)
3128 popclass_above (cblev
);
3135 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
3137 tokoff
= lp
- 1 - newlb
.buffer
;
3142 } /* if (begtoken) */
3143 } /* if must look at token */
3146 /* Detect end of line, colon, comma, semicolon and various braces
3147 after having handled a token.*/
3151 if (yacc_rules
&& token
.offset
== 0 && token
.valid
)
3153 make_C_tag (FALSE
); /* a yacc function */
3156 if (definedef
!= dnone
)
3162 make_C_tag (TRUE
); /* an Objective C class */
3166 objdef
= omethodcolon
;
3167 linebuffer_setlen (&token_name
, token_name
.len
+ 1);
3168 strcat (token_name
.buffer
, ":");
3171 if (structdef
== stagseen
)
3172 structdef
= scolonseen
;
3175 if (definedef
!= dnone
)
3181 make_C_tag (FALSE
); /* a typedef */
3191 if (typdef
== tignore
)
3195 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3196 || (members
&& instruct
))
3197 make_C_tag (FALSE
); /* a variable */
3200 token
.valid
= FALSE
;
3203 if ((declarations
&& typdef
== tnone
&& !instruct
)
3204 || (members
&& typdef
!= tignore
&& instruct
))
3205 make_C_tag (TRUE
); /* a function declaration */
3211 && structdef
== stagseen
&& (c_ext
& C_PLPL
))
3212 make_C_tag (FALSE
); /* forward declaration */
3214 /* The following instruction invalidates the token.
3215 Probably the token should be invalidated in all other
3216 cases where some state machine is reset prematurely. */
3217 token
.valid
= FALSE
;
3218 } /* switch (fvdef) */
3224 if (structdef
== stagseen
)
3228 if (definedef
!= dnone
)
3234 make_C_tag (TRUE
); /* an Objective C method */
3250 case fvnameseen
: /* a variable */
3251 if ((globals
&& cblev
== 0 && (!fvextern
|| declarations
))
3252 || (members
&& instruct
))
3255 case flistseen
: /* a function */
3256 if ((declarations
&& typdef
== tnone
&& !instruct
)
3257 || (members
&& typdef
!= tignore
&& instruct
))
3259 make_C_tag (TRUE
); /* a function declaration */
3262 else if (!declarations
)
3264 token
.valid
= FALSE
;
3269 if (structdef
== stagseen
)
3273 if (definedef
!= dnone
)
3275 if (structdef
== stagseen
)
3282 make_C_tag (FALSE
); /* a typedef */
3294 if ((members
&& cblev
== 1)
3295 || (globals
&& cblev
== 0
3296 && (!fvextern
|| declarations
)))
3297 make_C_tag (FALSE
); /* a variable */
3306 if (definedef
!= dnone
)
3308 if (objdef
== otagseen
&& parlev
== 0)
3309 objdef
= oparenseen
;
3313 if (typdef
== ttypeseen
3317 /* This handles constructs like:
3318 typedef void OperatorFun (int fun); */
3335 if (definedef
!= dnone
)
3337 if (objdef
== ocatseen
&& parlev
== 1)
3339 make_C_tag (TRUE
); /* an Objective C category */
3353 || typdef
== ttypeseen
))
3356 make_C_tag (FALSE
); /* a typedef */
3359 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
3363 if (definedef
!= dnone
)
3365 if (typdef
== ttypeseen
)
3367 typdefcblev
= cblev
;
3373 make_C_tag (TRUE
); /* a function */
3382 make_C_tag (TRUE
); /* an Objective C class */
3387 make_C_tag (TRUE
); /* an Objective C method */
3391 /* Neutralize `extern "C" {' grot. */
3392 if (cblev
== 0 && structdef
== snone
&& nestlev
== 0
3399 case skeyseen
: /* unnamed struct */
3400 pushclass_above (cblev
, NULL
, 0);
3403 case stagseen
: /* named struct or enum */
3404 case scolonseen
: /* a class */
3405 pushclass_above (cblev
, token
.line
+token
.offset
, token
.length
);
3407 make_C_tag (FALSE
); /* a struct or enum */
3413 if (definedef
!= dnone
)
3415 if (fvdef
== fstartlist
)
3416 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
3419 if (definedef
!= dnone
)
3421 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
3423 cblev
= 0; /* reset curly brace level if first column */
3424 parlev
= 0; /* also reset paren level, just in case... */
3428 popclass_above (cblev
);
3430 if (typdef
== tinbody
&& cblev
<= typdefcblev
)
3432 assert (cblev
== typdefcblev
);
3437 if (definedef
!= dnone
)
3447 if ((members
&& cblev
== 1)
3448 || (globals
&& cblev
== 0 && (!fvextern
|| declarations
)))
3449 make_C_tag (FALSE
); /* a variable */
3456 if (cplpl
&& structdef
== stagseen
)
3458 structdef
= sintemplate
;
3463 if (structdef
== sintemplate
)
3465 structdef
= stagseen
;
3471 if (objdef
== oinbody
&& cblev
== 0)
3473 objdef
= omethodsign
;
3478 case '#': case '~': case '&': case '%': case '/': case '|':
3479 case '^': case '!': case '.': case '?': case ']':
3480 if (definedef
!= dnone
)
3482 /* These surely cannot follow a function tag in C. */
3495 if (objdef
== otagseen
)
3497 make_C_tag (TRUE
); /* an Objective C class */
3500 /* If a macro spans multiple lines don't reset its state. */
3502 CNL_SAVE_DEFINEDEF ();
3508 } /* while not eof */
3510 free (token_name
.buffer
);
3511 free (lbs
[0].lb
.buffer
);
3512 free (lbs
[1].lb
.buffer
);
3516 * Process either a C++ file or a C file depending on the setting
3520 default_C_entries (inf
)
3523 C_entries (cplusplus
? C_PLPL
: C_AUTO
, inf
);
3526 /* Always do plain C. */
3528 plain_C_entries (inf
)
3534 /* Always do C++. */
3536 Cplusplus_entries (inf
)
3539 C_entries (C_PLPL
, inf
);
3542 /* Always do Java. */
3547 C_entries (C_JAVA
, inf
);
3555 C_entries (C_STAR
, inf
);
3558 /* Always do Yacc. */
3563 C_entries (YACC
, inf
);
3567 /* A useful macro. */
3568 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3569 for (lineno = charno = 0; /* loop initialization */ \
3570 !feof (file_pointer) /* loop test */ \
3571 && (lineno++, /* instructions at start of loop */ \
3572 linecharno = charno, \
3573 charno += readline (&line_buffer, file_pointer), \
3574 char_pointer = lb.buffer, \
3580 * Read a file, but do no processing. This is used to do regexp
3581 * matching on files that have no language defined.
3584 just_read_file (inf
)
3587 register char *dummy
;
3589 LOOP_ON_INPUT_LINES (inf
, lb
, dummy
)
3594 /* Fortran parsing */
3596 static bool tail
P_((char *));
3597 static void takeprec
P_((void));
3598 static void getit
P_((FILE *));
3604 register int len
= 0;
3606 while (*cp
!= '\0' && lowcase (*cp
) == lowcase (dbp
[len
]))
3608 if (*cp
== '\0' && !intoken (dbp
[len
]))
3619 dbp
= skip_spaces (dbp
);
3623 dbp
= skip_spaces (dbp
);
3624 if (strneq (dbp
, "(*)", 3))
3629 if (!ISDIGIT (*dbp
))
3631 --dbp
; /* force failure */
3636 while (ISDIGIT (*dbp
));
3645 dbp
= skip_spaces (dbp
);
3649 linecharno
= charno
;
3650 charno
+= readline (&lb
, inf
);
3655 dbp
= skip_spaces (dbp
);
3657 if (!ISALPHA (*dbp
) && *dbp
!= '_' && *dbp
!= '$')
3659 for (cp
= dbp
+ 1; *cp
!= '\0' && intoken (*cp
); cp
++)
3661 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3662 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3667 Fortran_functions (inf
)
3670 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3673 dbp
++; /* Ratfor escape to fortran */
3674 dbp
= skip_spaces (dbp
);
3677 switch (lowcase (*dbp
))
3680 if (tail ("integer"))
3688 if (tail ("logical"))
3692 if (tail ("complex") || tail ("character"))
3696 if (tail ("double"))
3698 dbp
= skip_spaces (dbp
);
3701 if (tail ("precision"))
3707 dbp
= skip_spaces (dbp
);
3710 switch (lowcase (*dbp
))
3713 if (tail ("function"))
3717 if (tail ("subroutine"))
3725 if (tail ("blockdata") || tail ("block data"))
3727 dbp
= skip_spaces (dbp
);
3728 if (*dbp
== '\0') /* assume un-named */
3729 pfnote (savestr ("blockdata"), TRUE
,
3730 lb
.buffer
, dbp
- lb
.buffer
, lineno
, linecharno
);
3732 getit (inf
); /* look for name */
3742 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3745 static void adagetit
P_((FILE *, char *));
3747 /* Once we are positioned after an "interesting" keyword, let's get
3748 the real tag value necessary. */
3750 adagetit (inf
, name_qualifier
)
3752 char *name_qualifier
;
3760 dbp
= skip_spaces (dbp
);
3762 || (dbp
[0] == '-' && dbp
[1] == '-'))
3765 linecharno
= charno
;
3766 charno
+= readline (&lb
, inf
);
3775 /* Skipping body of procedure body or package body or ....
3776 resetting qualifier to body instead of spec. */
3777 name_qualifier
= "/b";
3783 /* Skipping type of task type or protected type ... */
3791 for (cp
= dbp
; *cp
!= '\0' && *cp
!= '"'; cp
++)
3796 dbp
= skip_spaces (dbp
);
3799 && (ISALPHA (*cp
) || ISDIGIT (*cp
) || *cp
== '_' || *cp
== '.'));
3807 name
= concat (dbp
, name_qualifier
, "");
3809 pfnote (name
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3820 bool inquote
= FALSE
;
3822 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
3824 while (*dbp
!= '\0')
3826 /* Skip a string i.e. "abcd". */
3827 if (inquote
|| (*dbp
== '"'))
3829 dbp
= etags_strchr ((inquote
) ? dbp
: dbp
+1, '"');
3834 continue; /* advance char */
3839 break; /* advance line */
3843 /* Skip comments. */
3844 if (dbp
[0] == '-' && dbp
[1] == '-')
3845 break; /* advance line */
3847 /* Skip character enclosed in single quote i.e. 'a'
3848 and skip single quote starting an attribute i.e. 'Image. */
3857 /* Search for beginning of a token. */
3858 if (!begtoken (*dbp
))
3861 continue; /* advance char */
3864 /* We are at the beginning of a token. */
3869 if (!packages_only
&& tail ("function"))
3870 adagetit (inf
, "/f");
3872 break; /* from switch */
3873 continue; /* advance char */
3876 if (!packages_only
&& tail ("procedure"))
3877 adagetit (inf
, "/p");
3878 else if (tail ("package"))
3879 adagetit (inf
, "/s");
3880 else if (tail ("protected")) /* protected type */
3881 adagetit (inf
, "/t");
3883 break; /* from switch */
3884 continue; /* advance char */
3887 if (!packages_only
&& tail ("task"))
3888 adagetit (inf
, "/k");
3889 else if (typedefs
&& !packages_only
&& tail ("type"))
3891 adagetit (inf
, "/t");
3892 while (*dbp
!= '\0')
3896 break; /* from switch */
3897 continue; /* advance char */
3900 /* Look for the end of the token. */
3901 while (!endtoken (*dbp
))
3904 } /* advance char */
3905 } /* advance line */
3910 * Bob Weiner, Motorola Inc., 4/3/94
3911 * Unix and microcontroller assembly tag handling
3912 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3920 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
3922 /* If first char is alphabetic or one of [_.$], test for colon
3923 following identifier. */
3924 if (ISALPHA (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3926 /* Read past label. */
3928 while (ISALNUM (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3930 if (*cp
== ':' || iswhite (*cp
))
3932 /* Found end of label, so copy it and add it to the table. */
3933 pfnote (savenstr(lb
.buffer
, cp
-lb
.buffer
), TRUE
,
3934 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3943 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3944 * Perl variable names: /^(my|local).../
3945 * Bart Robinson <lomew@cs.utah.edu> (1995)
3946 * Michael Ernst <mernst@alum.mit.edu> (1997)
3949 Perl_functions (inf
)
3954 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
3958 && *cp
++ == 'b' && iswhite (*cp
++))
3960 cp
= skip_spaces (cp
);
3965 && !iswhite (*cp
) && *cp
!= '{' && *cp
!= '(')
3967 pfnote (savenstr (sp
, cp
-sp
), TRUE
,
3968 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3971 else if (globals
/* only if tagging global vars is enabled */
3972 && ((cp
= lb
.buffer
,
3981 && (*cp
== '(' || iswhite (*cp
)))
3983 /* After "my" or "local", but before any following paren or space. */
3984 char *varname
= NULL
;
3986 cp
= skip_spaces (cp
);
3987 if (*cp
== '$' || *cp
== '@' || *cp
== '%')
3989 char* varstart
= ++cp
;
3990 while (ISALNUM (*cp
) || *cp
== '_')
3992 varname
= savenstr (varstart
, cp
-varstart
);
3996 /* Should be examining a variable list at this point;
3997 could insist on seeing an open parenthesis. */
3998 while (*cp
!= '\0' && *cp
!= ';' && *cp
!= '=' && *cp
!= ')')
4002 /* Perhaps I should back cp up one character, so the TAGS table
4003 doesn't mention (and so depend upon) the following char. */
4004 pfnote ((CTAGS
) ? savenstr (lb
.buffer
, cp
-lb
.buffer
) : varname
,
4005 FALSE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4013 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4014 * Eric S. Raymond <esr@thyrsus.com> (1997)
4017 Python_functions (inf
)
4022 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4026 && *cp
++ == 'f' && iswhite (*cp
++))
4028 cp
= skip_spaces (cp
);
4029 while (*cp
!= '\0' && !iswhite (*cp
) && *cp
!= '(' && *cp
!= ':')
4032 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4040 && *cp
++ == 's' && iswhite (*cp
++))
4042 cp
= skip_spaces (cp
);
4043 while (*cp
!= '\0' && !iswhite (*cp
) && *cp
!= '(' && *cp
!= ':')
4046 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4052 /* Idea by Corny de Souza
4053 * Cobol tag functions
4054 * We could look for anything that could be a paragraph name.
4055 * i.e. anything that starts in column 8 is one word and ends in a full stop.
4058 Cobol_paragraphs (inf
)
4061 register char *bp
, *ep
;
4063 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4069 /* If eoln, compiler option or comment ignore whole line. */
4070 if (bp
[-1] != ' ' || !ISALNUM (bp
[0]))
4073 for (ep
= bp
; ISALNUM (*ep
) || *ep
== '-'; ep
++)
4076 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4077 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4084 * Idea by Assar Westerlund <assar@sics.se> (2001)
4087 Makefile_targets (inf
)
4092 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4094 if (*bp
== '\t' || *bp
== '#')
4096 while (*bp
!= '\0' && *bp
!= '=' && *bp
!= ':')
4099 pfnote (savenstr (lb
.buffer
, bp
- lb
.buffer
), TRUE
,
4100 lb
.buffer
, bp
- lb
.buffer
+ 1, lineno
, linecharno
);
4105 /* Added by Mosur Mohan, 4/22/88 */
4106 /* Pascal parsing */
4109 * Locates tags for procedures & functions. Doesn't do any type- or
4110 * var-definitions. It does look for the keyword "extern" or
4111 * "forward" immediately following the procedure statement; if found,
4112 * the tag is skipped.
4115 Pascal_functions (inf
)
4118 linebuffer tline
; /* mostly copied from C_entries */
4120 int save_lineno
, save_len
;
4121 char c
, *cp
, *namebuf
;
4123 bool /* each of these flags is TRUE iff: */
4124 incomment
, /* point is inside a comment */
4125 inquote
, /* point is inside '..' string */
4126 get_tagname
, /* point is after PROCEDURE/FUNCTION
4127 keyword, so next item = potential tag */
4128 found_tag
, /* point is after a potential tag */
4129 inparms
, /* point is within parameter-list */
4130 verify_tag
; /* point has passed the parm-list, so the
4131 next token will determine whether this
4132 is a FORWARD/EXTERN to be ignored, or
4133 whether it is a real tag */
4135 save_lcno
= save_lineno
= save_len
= 0; /* keep compiler quiet */
4136 namebuf
= NULL
; /* keep compiler quiet */
4141 initbuffer (&tline
);
4143 incomment
= inquote
= FALSE
;
4144 found_tag
= FALSE
; /* have a proc name; check if extern */
4145 get_tagname
= FALSE
; /* have found "procedure" keyword */
4146 inparms
= FALSE
; /* found '(' after "proc" */
4147 verify_tag
= FALSE
; /* check if "extern" is ahead */
4150 while (!feof (inf
)) /* long main loop to get next char */
4153 if (c
== '\0') /* if end of line */
4156 linecharno
= charno
;
4157 charno
+= readline (&lb
, inf
);
4161 if (!((found_tag
&& verify_tag
)
4163 c
= *dbp
++; /* only if don't need *dbp pointing
4164 to the beginning of the name of
4165 the procedure or function */
4169 if (c
== '}') /* within { } comments */
4171 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
4188 inquote
= TRUE
; /* found first quote */
4190 case '{': /* found open { comment */
4194 if (*dbp
== '*') /* found open (* comment */
4199 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
4202 case ')': /* end of parms list */
4207 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
4214 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
4216 /* check if this is an "extern" declaration */
4219 if (lowcase (*dbp
== 'e'))
4221 if (tail ("extern")) /* superfluous, really! */
4227 else if (lowcase (*dbp
) == 'f')
4229 if (tail ("forward")) /* check for forward reference */
4235 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
4239 pfnote (namebuf
, TRUE
,
4240 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
4244 if (get_tagname
) /* grab name of proc or fn */
4249 /* save all values for later tagging */
4250 linebuffer_setlen (&tline
, lb
.len
);
4251 strcpy (tline
.buffer
, lb
.buffer
);
4252 save_lineno
= lineno
;
4253 save_lcno
= linecharno
;
4255 /* grab block name */
4256 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
4258 namebuf
= savenstr (dbp
, cp
-dbp
);
4259 dbp
= cp
; /* set dbp to e-o-token */
4260 save_len
= dbp
- lb
.buffer
+ 1;
4261 get_tagname
= FALSE
;
4265 /* and proceed to check for "extern" */
4267 else if (!incomment
&& !inquote
&& !found_tag
)
4269 /* check for proc/fn keywords */
4270 switch (lowcase (c
))
4273 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
4277 if (tail ("unction"))
4282 } /* while not eof */
4284 free (tline
.buffer
);
4289 * Lisp tag functions
4290 * look for (def or (DEF, quote or QUOTE
4293 static int L_isdef
P_((char *));
4294 static int L_isquote
P_((char *));
4295 static void L_getit
P_((void));
4299 register char *strp
;
4301 return ((strp
[1] == 'd' || strp
[1] == 'D')
4302 && (strp
[2] == 'e' || strp
[2] == 'E')
4303 && (strp
[3] == 'f' || strp
[3] == 'F'));
4308 register char *strp
;
4310 return ((*++strp
== 'q' || *strp
== 'Q')
4311 && (*++strp
== 'u' || *strp
== 'U')
4312 && (*++strp
== 'o' || *strp
== 'O')
4313 && (*++strp
== 't' || *strp
== 'T')
4314 && (*++strp
== 'e' || *strp
== 'E')
4315 && iswhite (*++strp
));
4323 if (*dbp
== '\'') /* Skip prefix quote */
4325 else if (*dbp
== '(')
4327 if (L_isquote (dbp
))
4328 dbp
+= 7; /* Skip "(quote " */
4330 dbp
+= 1; /* Skip "(" before name in (defstruct (foo)) */
4331 dbp
= skip_spaces (dbp
);
4334 for (cp
= dbp
/*+1*/;
4335 *cp
!= '\0' && *cp
!= '(' && !iswhite(*cp
) && *cp
!= ')';
4341 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
4342 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4346 Lisp_functions (inf
)
4349 LOOP_ON_INPUT_LINES (inf
, lb
, dbp
)
4355 dbp
= skip_non_spaces (dbp
);
4356 dbp
= skip_spaces (dbp
);
4361 /* Check for (foo::defmumble name-defined ... */
4364 while (*dbp
!= '\0' && !iswhite (*dbp
)
4365 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
4370 while (*dbp
== ':');
4372 if (L_isdef (dbp
- 1))
4374 dbp
= skip_non_spaces (dbp
);
4375 dbp
= skip_spaces (dbp
);
4386 * Postscript tag functions
4387 * Just look for lines where the first character is '/'
4388 * Also look at "defineps" for PSWrap
4389 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4390 * Ideas by Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4393 Postscript_functions (inf
)
4396 register char *bp
, *ep
;
4398 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4403 *ep
!= '\0' && *ep
!= ' ' && *ep
!= '{';
4406 pfnote (savenstr (bp
, ep
-bp
), TRUE
,
4407 lb
.buffer
, ep
- lb
.buffer
+ 1, lineno
, linecharno
);
4409 else if (strneq (bp
, "defineps", 8))
4411 bp
= skip_non_spaces (bp
);
4412 bp
= skip_spaces (bp
);
4420 * Scheme tag functions
4421 * look for (def... xyzzy
4422 * look for (def... (xyzzy
4423 * look for (def ... ((...(xyzzy ....
4424 * look for (set! xyzzy
4428 Scheme_functions (inf
)
4433 LOOP_ON_INPUT_LINES (inf
, lb
, bp
)
4436 && (bp
[1] == 'D' || bp
[1] == 'd')
4437 && (bp
[2] == 'E' || bp
[2] == 'e')
4438 && (bp
[3] == 'F' || bp
[3] == 'f'))
4440 bp
= skip_non_spaces (bp
);
4441 /* Skip over open parens and white space */
4442 while (iswhite (*bp
) || *bp
== '(')
4447 && (bp
[1] == 'S' || bp
[1] == 's')
4448 && (bp
[2] == 'E' || bp
[2] == 'e')
4449 && (bp
[3] == 'T' || bp
[3] == 't')
4450 && (bp
[4] == '!' || bp
[4] == '!')
4451 && (iswhite (bp
[5])))
4453 bp
= skip_non_spaces (bp
);
4454 bp
= skip_spaces (bp
);
4461 /* Find tags in TeX and LaTeX input files. */
4463 /* TEX_toktab is a table of TeX control sequences that define tags.
4464 Each TEX_tabent records one such control sequence.
4465 CONVERT THIS TO USE THE Stab TYPE!! */
4472 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
4474 /* Default set of control sequences to put into TEX_toktab.
4475 The value of environment var TEXTAGS is prepended to this. */
4477 char *TEX_defenv
= "\
4478 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
4479 :part:appendix:entry:index";
4481 static void TEX_mode
P_((FILE *));
4482 static struct TEX_tabent
*TEX_decode_env
P_((char *, char *));
4483 static int TEX_Token
P_((char *));
4485 char TEX_esc
= '\\';
4486 char TEX_opgrp
= '{';
4487 char TEX_clgrp
= '}';
4490 * TeX/LaTeX scanning loop.
4499 /* Select either \ or ! as escape character. */
4502 /* Initialize token table once from environment. */
4504 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
4506 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4509 /* Look at each esc in line. */
4510 while ((cp
= etags_strchr (cp
, TEX_esc
)) != NULL
)
4514 linecharno
+= cp
- lasthit
;
4516 i
= TEX_Token (lasthit
);
4519 /* We seem to include the TeX command in the tag name.
4521 for (p = lasthit + TEX_toktab[i].len;
4522 *p != '\0' && *p != TEX_clgrp;
4525 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL
, TRUE
,
4526 lb
.buffer
, lb
.len
, lineno
, linecharno
);
4527 break; /* We only tag a line once */
4533 #define TEX_LESC '\\'
4534 #define TEX_SESC '!'
4537 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
4538 chars accordingly. */
4545 while ((c
= getc (inf
)) != EOF
)
4547 /* Skip to next line if we hit the TeX comment char. */
4551 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
4567 /* If the input file is compressed, inf is a pipe, and rewind may fail.
4568 No attempt is made to correct the situation. */
4572 /* Read environment and prepend it to the default string.
4573 Build token table. */
4574 static struct TEX_tabent
*
4575 TEX_decode_env (evarname
, defenv
)
4579 register char *env
, *p
;
4581 struct TEX_tabent
*tab
;
4584 /* Append default string to environment. */
4585 env
= getenv (evarname
);
4591 env
= concat (oldenv
, defenv
, "");
4594 /* Allocate a token table */
4595 for (size
= 1, p
= env
; p
;)
4596 if ((p
= etags_strchr (p
, ':')) && *++p
!= '\0')
4598 /* Add 1 to leave room for null terminator. */
4599 tab
= xnew (size
+ 1, struct TEX_tabent
);
4601 /* Unpack environment string into token table. Be careful about */
4602 /* zero-length strings (leading ':', "::" and trailing ':') */
4605 p
= etags_strchr (env
, ':');
4606 if (!p
) /* End of environment string. */
4607 p
= env
+ strlen (env
);
4609 { /* Only non-zero strings. */
4610 tab
[i
].name
= savenstr (env
, p
- env
);
4611 tab
[i
].len
= strlen (tab
[i
].name
);
4618 tab
[i
].name
= NULL
; /* Mark end of table. */
4626 /* If the text at CP matches one of the tag-defining TeX command names,
4627 return the pointer to the first occurrence of that command in TEX_toktab.
4628 Otherwise return -1.
4629 Keep the capital `T' in `token' for dumb truncating compilers
4630 (this distinguishes it from `TEX_toktab' */
4637 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
4638 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
4644 /* Texinfo support. Dave Love, Mar. 2000. */
4650 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4656 && *cp
++ == 'e' && iswhite (*cp
++)))
4658 start
= cp
= skip_spaces(cp
);
4659 while (*cp
!= '\0' && *cp
!= ',')
4661 pfnote (savenstr (start
, cp
- start
), TRUE
,
4662 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
4669 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
4671 * Assumes that the predicate starts at column 0.
4672 * Only the first clause of a predicate is added.
4674 static int prolog_pred
P_((char *, char *));
4675 static void prolog_skip_comment
P_((linebuffer
*, FILE *));
4676 static int prolog_atom
P_((char *, int));
4679 Prolog_functions (inf
)
4690 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4692 if (cp
[0] == '\0') /* Empty line */
4694 else if (iswhite (cp
[0])) /* Not a predicate */
4696 else if (cp
[0] == '/' && cp
[1] == '*') /* comment. */
4697 prolog_skip_comment (&lb
, inf
);
4698 else if ((len
= prolog_pred (cp
, last
)) > 0)
4700 /* Predicate. Store the function name so that we only
4701 generate a tag for the first clause. */
4703 last
= xnew(len
+ 1, char);
4704 else if (len
+ 1 > allocated
)
4705 xrnew (last
, len
+ 1, char);
4706 allocated
= len
+ 1;
4707 strncpy (last
, cp
, len
);
4715 prolog_skip_comment (plb
, inf
)
4723 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
4724 if (cp
[0] == '*' && cp
[1] == '/')
4727 linecharno
+= readline (plb
, inf
);
4733 * A predicate definition is added if it matches:
4734 * <beginning of line><Prolog Atom><whitespace>(
4736 * It is added to the tags database if it doesn't match the
4737 * name of the previous clause header.
4739 * Return the size of the name of the predicate, or 0 if no header
4743 prolog_pred (s
, last
)
4745 char *last
; /* Name of last clause. */
4750 pos
= prolog_atom (s
, 0);
4755 pos
= skip_spaces (s
+ pos
) - s
;
4757 if ((s
[pos
] == '(') || (s
[pos
] == '.'))
4762 /* Save only the first clause. */
4764 || len
!= (int)strlen (last
)
4765 || !strneq (s
, last
, len
))
4767 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4775 * Consume a Prolog atom.
4776 * Return the number of bytes consumed, or -1 if there was an error.
4778 * A prolog atom, in this context, could be one of:
4779 * - An alphanumeric sequence, starting with a lower case letter.
4780 * - A quoted arbitrary string. Single quotes can escape themselves.
4781 * Backslash quotes everything.
4784 prolog_atom (s
, pos
)
4792 if (ISLOWER(s
[pos
]) || (s
[pos
] == '_'))
4794 /* The atom is unquoted. */
4796 while (ISALNUM(s
[pos
]) || (s
[pos
] == '_'))
4800 return pos
- origpos
;
4802 else if (s
[pos
] == '\'')
4813 pos
++; /* A double quote */
4815 else if (s
[pos
] == '\0')
4816 /* Multiline quoted atoms are ignored. */
4818 else if (s
[pos
] == '\\')
4820 if (s
[pos
+1] == '\0')
4827 return pos
- origpos
;
4835 * Support for Erlang -- Anders Lindgren, Feb 1996.
4837 * Generates tags for functions, defines, and records.
4839 * Assumes that Erlang functions start at column 0.
4841 static int erlang_func
P_((char *, char *));
4842 static void erlang_attribute
P_((char *));
4843 static int erlang_atom
P_((char *, int));
4846 Erlang_functions (inf
)
4857 LOOP_ON_INPUT_LINES (inf
, lb
, cp
)
4859 if (cp
[0] == '\0') /* Empty line */
4861 else if (iswhite (cp
[0])) /* Not function nor attribute */
4863 else if (cp
[0] == '%') /* comment */
4865 else if (cp
[0] == '"') /* Sometimes, strings start in column one */
4867 else if (cp
[0] == '-') /* attribute, e.g. "-define" */
4869 erlang_attribute (cp
);
4872 else if ((len
= erlang_func (cp
, last
)) > 0)
4875 * Function. Store the function name so that we only
4876 * generates a tag for the first clause.
4879 last
= xnew (len
+ 1, char);
4880 else if (len
+ 1 > allocated
)
4881 xrnew (last
, len
+ 1, char);
4882 allocated
= len
+ 1;
4883 strncpy (last
, cp
, len
);
4891 * A function definition is added if it matches:
4892 * <beginning of line><Erlang Atom><whitespace>(
4894 * It is added to the tags database if it doesn't match the
4895 * name of the previous clause header.
4897 * Return the size of the name of the function, or 0 if no function
4901 erlang_func (s
, last
)
4903 char *last
; /* Name of last clause. */
4908 pos
= erlang_atom (s
, 0);
4913 pos
= skip_spaces (s
+ pos
) - s
;
4915 /* Save only the first clause. */
4918 || len
!= (int)strlen (last
)
4919 || !strneq (s
, last
, len
)))
4921 pfnote (savenstr (s
, len
), TRUE
, s
, pos
, lineno
, linecharno
);
4930 * Handle attributes. Currently, tags are generated for defines
4933 * They are on the form:
4934 * -define(foo, bar).
4935 * -define(Foo(M, N), M+N).
4936 * -record(graph, {vtab = notable, cyclic = true}).
4939 erlang_attribute (s
)
4945 if (strneq (s
, "-define", 7) || strneq (s
, "-record", 7))
4947 pos
= skip_spaces (s
+ 7) - s
;
4948 if (s
[pos
++] == '(')
4950 pos
= skip_spaces (s
+ pos
) - s
;
4951 len
= erlang_atom (s
, pos
);
4953 pfnote (savenstr (& s
[pos
], len
), TRUE
,
4954 s
, pos
+ len
, lineno
, linecharno
);
4962 * Consume an Erlang atom (or variable).
4963 * Return the number of bytes consumed, or -1 if there was an error.
4966 erlang_atom (s
, pos
)
4974 if (ISALPHA (s
[pos
]) || s
[pos
] == '_')
4976 /* The atom is unquoted. */
4978 while (ISALNUM (s
[pos
]) || s
[pos
] == '_')
4980 return pos
- origpos
;
4982 else if (s
[pos
] == '\'')
4993 else if (s
[pos
] == '\0')
4994 /* Multiline quoted atoms are ignored. */
4996 else if (s
[pos
] == '\\')
4998 if (s
[pos
+1] == '\0')
5005 return pos
- origpos
;
5012 #ifdef ETAGS_REGEXPS
5014 static char *scan_separators
P_((char *));
5015 static void analyse_regex
P_((char *, bool));
5016 static void add_regex
P_((char *, bool, language
*));
5017 static char *substitute
P_((char *, char *, struct re_registers
*));
5019 /* Take a string like "/blah/" and turn it into "blah", making sure
5020 that the first and last characters are the same, and handling
5021 quoted separator characters. Actually, stops on the occurrence of
5022 an unquoted separator. Also turns "\t" into a Tab character.
5023 Returns pointer to terminating separator. Works in place. Null
5024 terminates name string. */
5026 scan_separators (name
)
5030 char *copyto
= name
;
5031 bool quoted
= FALSE
;
5033 for (++name
; *name
!= '\0'; ++name
)
5039 else if (*name
== sep
)
5043 /* Something else is quoted, so preserve the quote. */
5049 else if (*name
== '\\')
5051 else if (*name
== sep
)
5057 /* Terminate copied string. */
5062 /* Look at the argument of --regex or --no-regex and do the right
5063 thing. Same for each line of a regexp file. */
5065 analyse_regex (regex_arg
, ignore_case
)
5069 if (regex_arg
== NULL
)
5070 free_patterns (); /* --no-regex: remove existing regexps */
5072 /* A real --regexp option or a line in a regexp file. */
5073 switch (regex_arg
[0])
5075 /* Comments in regexp file or null arg to --regex. */
5081 /* Read a regex file. This is recursive and may result in a
5082 loop, which will stop when the file descriptors are exhausted. */
5086 linebuffer regexbuf
;
5087 char *regexfile
= regex_arg
+ 1;
5089 /* regexfile is a file containing regexps, one per line. */
5090 regexfp
= fopen (regexfile
, "r");
5091 if (regexfp
== NULL
)
5096 initbuffer (®exbuf
);
5097 while (readline_internal (®exbuf
, regexfp
) > 0)
5098 analyse_regex (regexbuf
.buffer
, ignore_case
);
5099 free (regexbuf
.buffer
);
5104 /* Regexp to be used for a specific language only. */
5108 char *lang_name
= regex_arg
+ 1;
5111 for (cp
= lang_name
; *cp
!= '}'; cp
++)
5114 error ("unterminated language name in regex: %s", regex_arg
);
5118 lang
= get_language_from_langname (lang_name
);
5121 add_regex (cp
+ 1, ignore_case
, lang
);
5125 /* Regexp to be used for any language. */
5127 add_regex (regex_arg
, ignore_case
, NULL
);
5132 /* Turn a name, which is an ed-style (but Emacs syntax) regular
5133 expression, into a real regular expression by compiling it. */
5135 add_regex (regexp_pattern
, ignore_case
, lang
)
5136 char *regexp_pattern
;
5142 struct re_pattern_buffer
*patbuf
;
5146 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
5148 error ("%s: unterminated regexp", regexp_pattern
);
5151 name
= scan_separators (regexp_pattern
);
5152 if (regexp_pattern
[0] == '\0')
5154 error ("null regexp", (char *)NULL
);
5157 (void) scan_separators (name
);
5159 patbuf
= xnew (1, struct re_pattern_buffer
);
5160 /* Translation table to fold case if appropriate. */
5161 patbuf
->translate
= (ignore_case
) ? lc_trans
: NULL
;
5162 patbuf
->fastmap
= NULL
;
5163 patbuf
->buffer
= NULL
;
5164 patbuf
->allocated
= 0;
5166 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
5169 error ("%s while compiling pattern", err
);
5174 p_head
= xnew (1, pattern
);
5175 p_head
->regex
= savestr (regexp_pattern
);
5176 p_head
->p_next
= pp
;
5177 p_head
->language
= lang
;
5178 p_head
->pattern
= patbuf
;
5179 p_head
->name_pattern
= savestr (name
);
5180 p_head
->error_signaled
= FALSE
;
5184 * Do the substitutions indicated by the regular expression and
5188 substitute (in
, out
, regs
)
5190 struct re_registers
*regs
;
5193 int size
, dig
, diglen
;
5196 size
= strlen (out
);
5198 /* Pass 1: figure out how much to allocate by finding all \N strings. */
5199 if (out
[size
- 1] == '\\')
5200 fatal ("pattern error in \"%s\"", out
);
5201 for (t
= etags_strchr (out
, '\\');
5203 t
= etags_strchr (t
+ 2, '\\'))
5207 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5213 /* Allocate space and do the substitutions. */
5214 result
= xnew (size
+ 1, char);
5216 for (t
= result
; *out
!= '\0'; out
++)
5217 if (*out
== '\\' && ISDIGIT (*++out
))
5220 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
5221 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
5228 assert (t
<= result
+ size
&& t
- result
== (int)strlen (result
));
5233 /* Deallocate all patterns. */
5238 while (p_head
!= NULL
)
5240 pp
= p_head
->p_next
;
5241 free (p_head
->regex
);
5242 free (p_head
->name_pattern
);
5248 #endif /* ETAGS_REGEXPS */
5259 /* Go till you get to white space or a syntactic break */
5261 *cp
!= '\0' && *cp
!= '(' && *cp
!= ')' && !iswhite (*cp
);
5264 pfnote (savenstr (bp
, cp
-bp
), TRUE
,
5265 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
5268 /* Initialize a linebuffer for use */
5273 lbp
->size
= (DEBUG
) ? 3 : 200;
5274 lbp
->buffer
= xnew (lbp
->size
, char);
5275 lbp
->buffer
[0] = '\0';
5280 * Read a line of text from `stream' into `lbp', excluding the
5281 * newline or CR-NL, if any. Return the number of characters read from
5282 * `stream', which is the length of the line including the newline.
5284 * On DOS or Windows we do not count the CR character, if any, before the
5285 * NL, in the returned length; this mirrors the behavior of emacs on those
5286 * platforms (for text files, it translates CR-NL to NL as it reads in the
5290 readline_internal (lbp
, stream
)
5292 register FILE *stream
;
5294 char *buffer
= lbp
->buffer
;
5295 register char *p
= lbp
->buffer
;
5296 register char *pend
;
5299 pend
= p
+ lbp
->size
; /* Separate to avoid 386/IX compiler bug. */
5303 register int c
= getc (stream
);
5306 /* We're at the end of linebuffer: expand it. */
5308 xrnew (buffer
, lbp
->size
, char);
5309 p
+= buffer
- lbp
->buffer
;
5310 pend
= buffer
+ lbp
->size
;
5311 lbp
->buffer
= buffer
;
5321 if (p
> buffer
&& p
[-1] == '\r')
5325 /* Assume CRLF->LF translation will be performed by Emacs
5326 when loading this file, so CRs won't appear in the buffer.
5327 It would be cleaner to compensate within Emacs;
5328 however, Emacs does not know how many CRs were deleted
5329 before any given point in the file. */
5344 lbp
->len
= p
- buffer
;
5346 return lbp
->len
+ chars_deleted
;
5350 * Like readline_internal, above, but in addition try to match the
5351 * input line against relevant regular expressions.
5354 readline (lbp
, stream
)
5358 /* Read new line. */
5359 long result
= readline_internal (lbp
, stream
);
5360 #ifdef ETAGS_REGEXPS
5364 /* Match against relevant patterns. */
5366 for (pp
= p_head
; pp
!= NULL
; pp
= pp
->p_next
)
5368 /* Only use generic regexps or those for the current language. */
5369 if (pp
->language
!= NULL
&& pp
->language
!= curlang
)
5372 match
= re_match (pp
->pattern
, lbp
->buffer
, lbp
->len
, 0, &pp
->regs
);
5377 if (!pp
->error_signaled
)
5379 error ("error while matching \"%s\"", pp
->regex
);
5380 pp
->error_signaled
= TRUE
;
5387 /* Match occurred. Construct a tag. */
5388 if (pp
->name_pattern
[0] != '\0')
5390 /* Make a named tag. */
5391 char *name
= substitute (lbp
->buffer
,
5392 pp
->name_pattern
, &pp
->regs
);
5394 pfnote (name
, TRUE
, lbp
->buffer
, match
, lineno
, linecharno
);
5398 /* Make an unnamed tag. */
5399 pfnote ((char *)NULL
, TRUE
,
5400 lbp
->buffer
, match
, lineno
, linecharno
);
5405 #endif /* ETAGS_REGEXPS */
5412 * Return a pointer to a space of size strlen(cp)+1 allocated
5413 * with xnew where the string CP has been copied.
5419 return savenstr (cp
, strlen (cp
));
5423 * Return a pointer to a space of size LEN+1 allocated with xnew where
5424 * the string CP has been copied for at most the first LEN characters.
5433 dp
= xnew (len
+ 1, char);
5434 strncpy (dp
, cp
, len
);
5440 * Return the ptr in sp at which the character c last
5441 * appears; NULL if not found
5443 * Identical to POSIX strrchr, included for portability.
5446 etags_strrchr (sp
, c
)
5447 register const char *sp
;
5450 register const char *r
;
5463 * Return the ptr in sp at which the character c first
5464 * appears; NULL if not found
5466 * Identical to POSIX strchr, included for portability.
5469 etags_strchr (sp
, c
)
5470 register const char *sp
;
5481 /* Skip spaces, return new pointer. */
5486 while (iswhite (*cp
))
5491 /* Skip non spaces, return new pointer. */
5493 skip_non_spaces (cp
)
5496 while (*cp
!= '\0' && !iswhite (*cp
))
5501 /* Print error message and exit. */
5519 suggest_asking_for_help ()
5521 fprintf (stderr
, "\tTry `%s %s' for a complete list of options.\n",
5532 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
5535 const char *s1
, *s2
;
5537 fprintf (stderr
, "%s: ", progname
);
5538 fprintf (stderr
, s1
, s2
);
5539 fprintf (stderr
, "\n");
5542 /* Return a newly-allocated string whose contents
5543 concatenate those of s1, s2, s3. */
5548 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
5549 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
5551 strcpy (result
, s1
);
5552 strcpy (result
+ len1
, s2
);
5553 strcpy (result
+ len1
+ len2
, s3
);
5554 result
[len1
+ len2
+ len3
] = '\0';
5560 /* Does the same work as the system V getcwd, but does not need to
5561 guess the buffer size in advance. */
5567 char *path
= xnew (bufsize
, char);
5569 while (getcwd (path
, bufsize
) == NULL
)
5571 if (errno
!= ERANGE
)
5575 path
= xnew (bufsize
, char);
5578 canonicalize_filename (path
);
5581 #else /* not HAVE_GETCWD */
5584 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
5588 for (p
= path
; *p
!= '\0'; p
++)
5594 return strdup (path
);
5595 #else /* not MSDOS */
5600 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
5601 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
5606 #endif /* not MSDOS */
5607 #endif /* not HAVE_GETCWD */
5610 /* Return a newly allocated string containing the file name of FILE
5611 relative to the absolute directory DIR (which should end with a slash). */
5613 relative_filename (file
, dir
)
5616 char *fp
, *dp
, *afn
, *res
;
5619 /* Find the common root of file and dir (with a trailing slash). */
5620 afn
= absolute_filename (file
, cwd
);
5623 while (*fp
++ == *dp
++)
5625 fp
--, dp
--; /* back to the first differing char */
5627 if (fp
== afn
&& afn
[0] != '/') /* cannot build a relative name */
5630 do /* look at the equal chars until '/' */
5634 /* Build a sequence of "../" strings for the resulting relative file name. */
5636 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
5638 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
5641 strcat (res
, "../");
5643 /* Add the file name relative to the common root of file and dir. */
5644 strcat (res
, fp
+ 1);
5650 /* Return a newly allocated string containing the absolute file name
5651 of FILE given DIR (which should end with a slash). */
5653 absolute_filename (file
, dir
)
5656 char *slashp
, *cp
, *res
;
5658 if (filename_is_absolute (file
))
5659 res
= savestr (file
);
5661 /* We don't support non-absolute file names with a drive
5662 letter, like `d:NAME' (it's too much hassle). */
5663 else if (file
[1] == ':')
5664 fatal ("%s: relative file names with drive letters not supported", file
);
5667 res
= concat (dir
, file
, "");
5669 /* Delete the "/dirname/.." and "/." substrings. */
5670 slashp
= etags_strchr (res
, '/');
5671 while (slashp
!= NULL
&& slashp
[0] != '\0')
5673 if (slashp
[1] == '.')
5675 if (slashp
[2] == '.'
5676 && (slashp
[3] == '/' || slashp
[3] == '\0'))
5681 while (cp
>= res
&& !filename_is_absolute (cp
));
5683 cp
= slashp
; /* the absolute name begins with "/.." */
5685 /* Under MSDOS and NT we get `d:/NAME' as absolute
5686 file name, so the luser could say `d:/../NAME'.
5687 We silently treat this as `d:/NAME'. */
5688 else if (cp
[0] != '/')
5691 strcpy (cp
, slashp
+ 3);
5695 else if (slashp
[2] == '/' || slashp
[2] == '\0')
5697 strcpy (slashp
, slashp
+ 2);
5702 slashp
= etags_strchr (slashp
+ 1, '/');
5706 return savestr ("/");
5711 /* Return a newly allocated string containing the absolute
5712 file name of dir where FILE resides given DIR (which should
5713 end with a slash). */
5715 absolute_dirname (file
, dir
)
5721 canonicalize_filename (file
);
5722 slashp
= etags_strrchr (file
, '/');
5724 return savestr (dir
);
5727 res
= absolute_filename (file
, dir
);
5733 /* Whether the argument string is an absolute file name. The argument
5734 string must have been canonicalized with canonicalize_filename. */
5736 filename_is_absolute (fn
)
5739 return (fn
[0] == '/'
5741 || (ISALPHA(fn
[0]) && fn
[1] == ':' && fn
[2] == '/')
5746 /* Translate backslashes into slashes. Works in place. */
5748 canonicalize_filename (fn
)
5752 /* Canonicalize drive letter case. */
5753 if (fn
[0] != '\0' && fn
[1] == ':' && ISLOWER (fn
[0]))
5754 fn
[0] = upcase (fn
[0]);
5755 /* Convert backslashes to slashes. */
5756 for (; *fn
!= '\0'; fn
++)
5761 fn
= NULL
; /* shut up the compiler */
5765 /* Set the minimum size of a string contained in a linebuffer. */
5767 linebuffer_setlen (lbp
, toksize
)
5771 while (lbp
->size
<= toksize
)
5774 xrnew (lbp
->buffer
, lbp
->size
, char);
5779 /* Like malloc but get fatal error if memory is exhausted. */
5784 long *result
= (long *) malloc (size
);
5786 fatal ("virtual memory exhausted", (char *)NULL
);
5791 xrealloc (ptr
, size
)
5795 long *result
= (long *) realloc (ptr
, size
);
5797 fatal ("virtual memory exhausted", (char *)NULL
);