1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95
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 * Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey.
31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer.
34 char pot_etags_version
[] = "@(#) pot revision number is 12.11";
46 # include <sys/param.h>
54 # define MAXPATHLEN _MAX_PATH
59 /* On some systems, Emacs defines static as nothing for the sake
60 of unexec. We don't want that here since we don't use unexec. */
62 # define ETAGS_REGEXPS
66 #if !defined (MSDOS) && !defined (WINDOWSNT) && defined (STDC_HEADERS)
77 #include <sys/types.h>
80 /* This is to declare getcwd. */
85 #if !defined (S_ISREG) && defined (S_IFREG)
86 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
92 # define getopt_long(argc,argv,optstr,lopts,lind) getopt (argc, argv, optstr)
94 extern int optind
, opterr
;
95 #endif /* LONG_OPTIONS */
99 #endif /* ETAGS_REGEXPS */
101 /* Define CTAGS to make the program "ctags" compatible with the usual one.
102 Leave it undefined to make the program "etags", which makes emacs-style
103 tag tables and tags typedefs, #defines and struct/union/enum by default. */
111 /* Exit codes for success and failure. */
121 #define C_PLPL 0x00001 /* C++ */
122 #define C_STAR 0x00003 /* C* */
123 #define C_JAVA 0x00005 /* JAVA */
124 #define YACC 0x10000 /* yacc file */
126 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
127 && (abort (), 1)) || !strcmp (s, t))
128 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
129 && (abort (), 1)) || !strncmp (s, t, n))
131 #define lowcase(c) tolower ((char)c)
133 #define CHARS 256 /* 2^sizeof(char) */
134 #define CHAR(x) ((int)x & (CHARS - 1))
135 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
136 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
137 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
138 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
139 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
142 # define absolutefn(fn) (fn[0] == '/' \
143 || (fn[1] == ':' && fn[2] == '/'))
145 # define absolutefn(fn) (fn[0] == '/')
150 * xnew -- allocate storage
152 * SYNOPSIS: Type *xnew (int n, Type);
155 # include "chkmalloc.h"
156 # define xnew(n,Type) ((Type *) trace_xmalloc (__FILE__, __LINE__, \
157 (n) * sizeof (Type)))
159 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
165 { /* sorting structure */
166 char *name
; /* function or type name */
167 char *file
; /* file name */
168 bool is_func
; /* use pattern or line no */
169 bool been_warned
; /* set if noticed dup */
170 int lno
; /* line number tag is on */
171 long cno
; /* character number line starts on */
172 char *pat
; /* search pattern */
173 struct nd_st
*left
, *right
; /* left and right sons */
176 extern char *getenv ();
179 char *savenstr (), *savestr ();
180 char *etags_strchr (), *etags_strrchr ();
181 char *etags_getcwd ();
182 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
183 void grow_linebuffer ();
184 long *xmalloc (), *xrealloc ();
186 typedef void Lang_function ();
187 /* Many compilers barf on this:
188 Lang_function Asm_labels;
189 so let's write it this way */
192 void default_C_entries ();
193 void plain_C_entries ();
194 void Cjava_entries ();
195 void Cobol_paragraphs ();
196 void Cplusplus_entries ();
197 void Cstar_entries ();
198 void Erlang_functions ();
199 void Fortran_functions ();
200 void Yacc_entries ();
201 void Lisp_functions ();
202 void Pascal_functions ();
203 void Perl_functions ();
204 void Postscript_functions ();
205 void Prolog_functions ();
206 void Scheme_functions ();
207 void TeX_functions ();
208 void just_read_file ();
210 Lang_function
*get_language_from_name ();
211 Lang_function
*get_language_from_interpreter ();
212 Lang_function
*get_language_from_suffix ();
213 int total_size_of_entries ();
215 long readline_internal ();
217 void analyse_regex ();
219 #endif /* ETAGS_REGEXPS */
222 void suggest_asking_for_help ();
223 void fatal (), pfatal ();
224 void find_entries ();
229 void pfnote (), new_pfnote ();
230 void process_file ();
235 char searchar
= '/'; /* use /.../ searches */
237 int lineno
; /* line number of current line */
238 long charno
; /* current character number */
239 long linecharno
; /* charno of start of line */
241 char *curfile
; /* current input file name */
242 char *tagfile
; /* output file */
243 char *progname
; /* name this program was invoked with */
244 char *cwd
; /* current working directory */
245 char *tagfiledir
; /* directory of tagfile */
247 FILE *tagf
; /* ioptr for tags file */
248 NODE
*head
; /* the head of the binary tree of tags */
251 * A `struct linebuffer' is a structure which holds a line of text.
252 * `readline' reads a line from a stream into a linebuffer and works
253 * regardless of the length of the line.
254 * SIZE is the size of BUFFER, LEN is the length of the string in
255 * BUFFER after readline reads it.
264 struct linebuffer lb
; /* the current line */
265 struct linebuffer token_name
; /* used by C_entries as a temporary area */
269 struct linebuffer lb
; /* used by C_entries instead of lb */
272 /* boolean "functions" (see init) */
273 bool _wht
[CHARS
], _nin
[CHARS
], _itk
[CHARS
], _btk
[CHARS
], _etk
[CHARS
];
276 *white
= " \f\t\n\013",
278 *nonam
=" \f\t\n\013(=,[;",
279 /* token ending chars */
280 *endtk
= " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?",
281 /* token starting chars */
282 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
283 /* valid in-token chars */
284 *midtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
286 bool append_to_tagfile
; /* -a: append to tags */
287 /* The following four default to TRUE for etags, but to FALSE for ctags. */
288 bool typedefs
; /* -t: create tags for C typedefs */
289 bool typedefs_and_cplusplus
; /* -T: create tags for C typedefs, level */
290 /* 0 struct/enum/union decls, and C++ */
291 /* member functions. */
292 bool constantypedefs
; /* -d: create tags for C #define, enum */
293 /* constants and variables. */
294 /* -D: opposite of -d. Default under ctags. */
295 bool globals
; /* create tags for C global variables */
296 bool members
; /* create tags for C member variables */
297 bool update
; /* -u: update tags */
298 bool vgrind_style
; /* -v: create vgrind style index output */
299 bool no_warnings
; /* -w: suppress warnings */
300 bool cxref_style
; /* -x: create cxref style output */
301 bool cplusplus
; /* .[hc] means C++, not C */
302 bool noindentypedefs
; /* -I: ignore indentation in C */
305 struct option longopts
[] =
307 { "append", no_argument
, NULL
, 'a' },
308 { "backward-search", no_argument
, NULL
, 'B' },
309 { "c++", no_argument
, NULL
, 'C' },
310 { "cxref", no_argument
, NULL
, 'x' },
311 { "defines", no_argument
, NULL
, 'd' },
312 { "no-defines", no_argument
, NULL
, 'D' },
313 { "globals", no_argument
, &globals
, TRUE
},
314 { "no-globals", no_argument
, &globals
, FALSE
},
315 { "help", no_argument
, NULL
, 'h' },
316 { "help", no_argument
, NULL
, 'H' },
317 { "ignore-indentation", no_argument
, NULL
, 'I' },
318 { "include", required_argument
, NULL
, 'i' },
319 { "language", required_argument
, NULL
, 'l' },
320 { "members", no_argument
, &members
, TRUE
},
321 { "no-members", no_argument
, &members
, FALSE
},
322 { "no-warn", no_argument
, NULL
, 'w' },
323 { "output", required_argument
, NULL
, 'o' },
325 { "regex", required_argument
, NULL
, 'r' },
326 { "no-regex", no_argument
, NULL
, 'R' },
327 #endif /* ETAGS_REGEXPS */
328 { "typedefs", no_argument
, NULL
, 't' },
329 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
330 { "update", no_argument
, NULL
, 'u' },
331 { "version", no_argument
, NULL
, 'V' },
332 { "vgrind", no_argument
, NULL
, 'v' },
335 #endif /* LONG_OPTIONS */
338 /* Structure defining a regular expression. Elements are
339 the compiled pattern, and the name string. */
342 struct re_pattern_buffer
*pattern
;
343 struct re_registers regs
;
348 /* Number of regexps found. */
349 int num_patterns
= 0;
351 /* Array of all regexps. */
352 struct pattern
*patterns
= NULL
;
353 #endif /* ETAGS_REGEXPS */
359 /* Non-NULL if language fixed. */
360 Lang_function
*lang_func
= NULL
;
363 char *Asm_suffixes
[] = { "a", /* Unix assembler */
364 "asm", /* Microcontroller assembly */
365 "def", /* BSO/Tasking definition includes */
366 "inc", /* Microcontroller include files */
367 "ins", /* Microcontroller include files */
368 "s", "sa", /* Unix assembler */
369 "S", /* cpp-processed Unix assembler */
370 "src", /* BSO/Tasking C compiler output */
374 /* Note that .c and .h can be considered C++, if the --c++ flag was
375 given. That is why default_C_entries is called here. */
376 char *default_C_suffixes
[] =
379 char *Cplusplus_suffixes
[] =
380 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx",
381 "M", /* Objective C++ */
382 "pdb", /* Postscript with C syntax */
385 char *Cjava_suffixes
[] =
388 char *Cobol_suffixes
[] =
389 { "COB", "cob", NULL
};
391 char *Cstar_suffixes
[] =
392 { "cs", "hs", NULL
};
394 char *Erlang_suffixes
[] =
395 { "erl", "hrl", NULL
};
397 char *Fortran_suffixes
[] =
398 { "F", "f", "f90", "for", NULL
};
400 char *Lisp_suffixes
[] =
401 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL
};
403 char *Pascal_suffixes
[] =
404 { "p", "pas", NULL
};
406 char *Perl_suffixes
[] =
407 { "pl", "pm", NULL
};
408 char *Perl_interpreters
[] =
409 { "perl", "@PERL@", NULL
};
411 char *plain_C_suffixes
[] =
412 { "pc", /* Pro*C file */
413 "m", /* Objective C file */
414 "lm", /* Objective lex file */
417 char *Postscript_suffixes
[] =
420 char *Prolog_suffixes
[] =
423 /* Can't do the `SCM' or `scm' prefix with a version number. */
424 char *Scheme_suffixes
[] =
425 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL
};
427 char *TeX_suffixes
[] =
428 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL
};
430 char *Yacc_suffixes
[] =
431 { "y", "ym", "yy", "yxx", "y++", NULL
}; /* .ym is Objective yacc file */
433 /* Table of language names and corresponding functions, file suffixes
434 and interpreter names.
435 It is ok for a given function to be listed under more than one
436 name. I just didn't. */
440 Lang_function
*function
;
445 struct lang_entry lang_names
[] =
447 { "asm", Asm_labels
, Asm_suffixes
, NULL
},
448 { "c", default_C_entries
, default_C_suffixes
, NULL
},
449 { "c++", Cplusplus_entries
, Cplusplus_suffixes
, NULL
},
450 { "c*", Cstar_entries
, Cstar_suffixes
, NULL
},
451 { "cobol", Cobol_paragraphs
, Cobol_suffixes
, NULL
},
452 { "erlang", Erlang_functions
, Erlang_suffixes
, NULL
},
453 { "fortran", Fortran_functions
, Fortran_suffixes
, NULL
},
454 { "java", Cjava_entries
, Cjava_suffixes
, NULL
},
455 { "lisp", Lisp_functions
, Lisp_suffixes
, NULL
},
456 { "pascal", Pascal_functions
, Pascal_suffixes
, NULL
},
457 { "perl", Perl_functions
, Perl_suffixes
, Perl_interpreters
},
458 { "postscript", Postscript_functions
, Postscript_suffixes
, NULL
},
459 { "proc", plain_C_entries
, plain_C_suffixes
, NULL
},
460 { "prolog", Prolog_functions
, Prolog_suffixes
, NULL
},
461 { "scheme", Scheme_functions
, Scheme_suffixes
, NULL
},
462 { "tex", TeX_functions
, TeX_suffixes
, NULL
},
463 { "yacc", Yacc_entries
, Yacc_suffixes
, NULL
},
464 { "auto", NULL
}, /* default guessing scheme */
465 { "none", just_read_file
}, /* regexp matching only */
466 { NULL
, NULL
} /* end of list */
471 print_language_names ()
473 struct lang_entry
*lang
;
476 puts ("\nThese are the currently supported languages, along with the\n\
477 default file name suffixes:");
478 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
480 printf ("\t%s\t", lang
->name
);
481 if (lang
->suffixes
!= NULL
)
482 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
483 printf (" .%s", *ext
);
486 puts ("Where `auto' means use default language for files based on file\n\
487 name suffix, and `none' means only do regexp processing on files.\n\
488 If no language is specified and no matching suffix is found,\n\
489 the first line of the file is read for a sharp-bang (#!) sequence\n\
490 followed by the name of an interpreter. If no such sequence is found,\n\
491 Fortran is tried first; if no tags are found, C is tried next.");
495 # define VERSION "19"
500 printf ("%s (GNU Emacs %s)\n", (CTAGS
) ? "ctags" : "etags", VERSION
);
501 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold");
502 puts ("This program is distributed under the same terms as Emacs");
510 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\
512 These are the options accepted by %s.\n", progname
, progname
);
514 puts ("You may use unambiguous abbreviations for the long option names.");
516 puts ("Long option names do not work with this executable, as it is not\n\
517 linked with GNU getopt.");
518 #endif /* LONG_OPTIONS */
519 puts ("A - as file name means read names from stdin.");
521 printf (" Absolute names are stored in the output file as they\n\
522 are. Relative ones are stored relative to the output file's directory.");
525 puts ("-a, --append\n\
526 Append tag entries to existing tags file.");
529 puts ("-B, --backward-search\n\
530 Write the search commands for the tag entries using '?', the\n\
531 backward-search command instead of '/', the forward-search command.");
534 Treat files whose name suffix defaults to C language as C++ files.");
537 puts ("-d, --defines\n\
538 Create tag entries for C #define constants and enum constants, too.");
540 puts ("-D, --no-defines\n\
541 Don't create tag entries for C #define constants and enum constants.\n\
542 This makes the tags file smaller.");
546 puts ("-i FILE, --include=FILE\n\
547 Include a note in tag file indicating that, when searching for\n\
548 a tag, one should also consult the tags file FILE after\n\
549 checking the current file.");
550 puts ("-l LANG, --language=LANG\n\
551 Force the following files to be considered as written in the\n\
552 named language up to the next --language=LANG option.");
557 Create tag entries for global variables in C and derived languages.");
559 puts ("--no-globals\n\
560 Do not create tag entries for global variables in C and\n\
561 derived languages. This makes the tags file smaller.");
563 Create tag entries for member variables in C and derived languages.");
566 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\
567 Make a tag for each line matching pattern REGEXP in the\n\
568 following files. regexfile is a file containing one REGEXP\n\
569 per line. REGEXP is anchored (as if preceded by ^).\n\
570 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
571 named tags can be created with:\n\
572 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
573 puts ("-R, --no-regex\n\
574 Don't create tags from regexps for the following files.");
575 #endif /* ETAGS_REGEXPS */
576 puts ("-o FILE, --output=FILE\n\
577 Write the tags to FILE.");
578 puts ("-I, --ignore-indentation\n\
579 Don't rely on indentation quite as much as normal. Currently,\n\
580 this means not to assume that a closing brace in the first\n\
581 column is the final brace of a function or structure\n\
582 definition in C and C++.");
586 puts ("-t, --typedefs\n\
587 Generate tag entries for C typedefs.");
588 puts ("-T, --typedefs-and-c++\n\
589 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
590 and C++ member functions.");
591 puts ("-u, --update\n\
592 Update the tag entries for the given files, leaving tag\n\
593 entries for other files in place. Currently, this is\n\
594 implemented by deleting the existing entries for the given\n\
595 files and then rewriting the new entries at the end of the\n\
596 tags file. It is often faster to simply rebuild the entire\n\
597 tag file than to use this.");
598 puts ("-v, --vgrind\n\
599 Generates an index of items intended for human consumption,\n\
600 similar to the output of vgrind. The index is sorted, and\n\
601 gives the page number of each item.");
602 puts ("-w, --no-warn\n\
603 Suppress warning messages about entries defined in multiple\n\
605 puts ("-x, --cxref\n\
606 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
607 The output uses line numbers instead of page numbers, but\n\
608 beyond that the differences are cosmetic; try both to see\n\
612 puts ("-V, --version\n\
613 Print the version of the program.\n\
615 Print this help message.");
617 print_language_names ();
620 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu");
633 /* This structure helps us allow mixing of --lang and file names. */
636 enum argument_type arg_type
;
638 Lang_function
*function
;
641 #ifdef VMS /* VMS specific functions */
645 /* This is a BUG! ANY arbitrary limit is a BUG!
646 Won't someone please fix this? */
647 #define MAX_FILE_SPEC_LEN 255
650 char body
[MAX_FILE_SPEC_LEN
+ 1];
654 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
655 returning in each successive call the next file name matching the input
656 spec. The function expects that each in_spec passed
657 to it will be processed to completion; in particular, up to and
658 including the call following that in which the last matching name
659 is returned, the function ignores the value of in_spec, and will
660 only start processing a new spec with the following call.
661 If an error occurs, on return out_spec contains the value
662 of in_spec when the error occurred.
664 With each successive file name returned in out_spec, the
665 function's return value is one. When there are no more matching
666 names the function returns zero. If on the first call no file
667 matches in_spec, or there is any other error, -1 is returned.
672 #define OUTSIZE MAX_FILE_SPEC_LEN
678 static long context
= 0;
679 static struct dsc$descriptor_s o
;
680 static struct dsc$descriptor_s i
;
681 static bool pass1
= TRUE
;
688 o
.dsc$a_pointer
= (char *) out
;
689 o
.dsc$w_length
= (short)OUTSIZE
;
690 i
.dsc$a_pointer
= in
;
691 i
.dsc$w_length
= (short)strlen(in
);
692 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
693 i
.dsc$b_class
= DSC$K_CLASS_S
;
694 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
695 o
.dsc$b_class
= DSC$K_CLASS_VS
;
697 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
699 out
->body
[out
->curlen
] = EOS
;
702 else if (status
== RMS$_NMF
)
706 strcpy(out
->body
, in
);
709 lib$
find_file_end(&context
);
715 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
716 name of each file specified by the provided arg expanding wildcards.
719 gfnames (arg
, p_error
)
723 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
725 switch (fn_exp (&filename
, arg
))
729 return filename
.body
;
735 return filename
.body
;
739 #ifndef OLD /* Newer versions of VMS do provide `system'. */
743 error ("%s", "system() function not implemented under VMS");
747 #define VERSION_DELIM ';'
748 char *massage_name (s
)
754 if (*s
== VERSION_DELIM
)
772 unsigned int nincluded_files
;
773 char **included_files
;
776 int current_arg
, file_count
;
777 struct linebuffer filename_lb
;
783 _fmode
= O_BINARY
; /* all of files are treated as binary files */
788 included_files
= xnew (argc
, char *);
792 /* Allocate enough no matter what happens. Overkill, but each one
794 argbuffer
= xnew (argc
, argument
);
797 /* Set syntax for regular expression routines. */
798 re_set_syntax (RE_SYNTAX_EMACS
);
799 #endif /* ETAGS_REGEXPS */
802 * If etags, always find typedefs and structure tags. Why not?
803 * Also default is to find macro constants, enum constants and
808 typedefs
= typedefs_and_cplusplus
= constantypedefs
= TRUE
;
819 optstring
= "-aCdDf:Il:o:r:RStTi:BuvxwVhH";
821 optstring
= "-aCdDf:Il:o:StTi:BuvxwVhH";
822 #endif /* ETAGS_REGEXPS */
825 optstring
= optstring
+ 1;
826 #endif /* LONG_OPTIONS */
828 opt
= getopt_long (argc
, argv
, optstring
, longopts
, 0);
835 /* If getopt returns 0, then it has already processed a
836 long-named option. We should do nothing. */
840 /* This means that a file name has been seen. Record it. */
841 argbuffer
[current_arg
].arg_type
= at_filename
;
842 argbuffer
[current_arg
].what
= optarg
;
847 /* Common options. */
848 case 'a': append_to_tagfile
= TRUE
; break;
849 case 'C': cplusplus
= TRUE
; break;
850 case 'd': constantypedefs
= TRUE
; break;
851 case 'D': constantypedefs
= FALSE
; break;
852 case 'f': /* for compatibility with old makefiles */
856 error ("-%c option may only be given once.", opt
);
857 suggest_asking_for_help ();
862 case 'S': /* for backward compatibility */
863 noindentypedefs
= TRUE
;
866 argbuffer
[current_arg
].function
= get_language_from_name (optarg
);
867 argbuffer
[current_arg
].arg_type
= at_language
;
872 argbuffer
[current_arg
].arg_type
= at_regexp
;
873 argbuffer
[current_arg
].what
= optarg
;
877 argbuffer
[current_arg
].arg_type
= at_regexp
;
878 argbuffer
[current_arg
].what
= NULL
;
881 #endif /* ETAGS_REGEXPS */
893 typedefs
= typedefs_and_cplusplus
= TRUE
;
898 included_files
[nincluded_files
++] = optarg
;
902 case 'B': searchar
= '?'; break;
903 case 'u': update
= TRUE
; break;
904 case 'v': vgrind_style
= TRUE
; /*FALLTHRU*/
905 case 'x': cxref_style
= TRUE
; break;
906 case 'w': no_warnings
= TRUE
; break;
909 suggest_asking_for_help ();
913 for (; optind
< argc
; ++optind
)
915 argbuffer
[current_arg
].arg_type
= at_filename
;
916 argbuffer
[current_arg
].what
= argv
[optind
];
921 if (nincluded_files
== 0 && file_count
== 0)
923 error ("no input files specified.", 0);
924 suggest_asking_for_help ();
928 tagfile
= CTAGS
? "tags" : "TAGS";
929 cwd
= etags_getcwd (); /* the current working directory */
930 if (cwd
[strlen (cwd
) - 1] != '/')
933 cwd
= concat (oldcwd
, "/", "");
936 if (streq (tagfile
, "-"))
939 tagfiledir
= absolute_dirname (tagfile
, cwd
);
941 init (); /* set up boolean "functions" */
944 initbuffer (&token_name
);
945 initbuffer (&lbs
[0].lb
);
946 initbuffer (&lbs
[1].lb
);
947 initbuffer (&filename_lb
);
951 if (streq (tagfile
, "-"))
955 /* Switch redirected `stdout' to binary mode (setting `_fmode'
956 doesn't take effect until after `stdout' is already open). */
957 if (!isatty (fileno (stdout
)))
958 setmode (fileno (stdout
), O_BINARY
);
962 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
968 * Loop through files finding functions.
970 for (i
= 0; i
< current_arg
; ++i
)
972 switch (argbuffer
[i
].arg_type
)
975 lang_func
= argbuffer
[i
].function
;
979 analyse_regex (argbuffer
[i
].what
);
984 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
988 error ("can't find file %s\n", this_file
);
993 this_file
= massage_name (this_file
);
996 this_file
= argbuffer
[i
].what
;
998 /* Input file named "-" means read file names from stdin
1000 if (streq (this_file
, "-"))
1001 while (readline_internal (&filename_lb
, stdin
) > 0)
1002 process_file (filename_lb
.buffer
);
1004 process_file (this_file
);
1014 while (nincluded_files
-- > 0)
1015 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
1021 /* If CTAGS, we are here. process_file did not write the tags yet,
1022 because we want them ordered. Let's do it now. */
1032 for (i
= 0; i
< current_arg
; ++i
)
1034 if (argbuffer
[i
].arg_type
!= at_filename
)
1037 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
1038 tagfile
, argbuffer
[i
].what
, tagfile
);
1039 if (system (cmd
) != GOOD
)
1040 fatal ("failed to execute shell command", (char *)NULL
);
1042 append_to_tagfile
= TRUE
;
1045 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
1054 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
1055 exit (system (cmd
));
1062 * Return a Lang_function given the name.
1065 get_language_from_name (name
)
1068 struct lang_entry
*lang
;
1071 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1073 if (streq (name
, lang
->name
))
1074 return lang
->function
;
1077 error ("language \"%s\" not recognized.", optarg
);
1078 suggest_asking_for_help ();
1080 /* This point should never be reached. The function should either
1081 return a function pointer or never return. Note that a NULL
1082 pointer cannot be considered as an error, as it means that the
1083 language has not been explicitely imposed by the user ("auto"). */
1084 return NULL
; /* avoid warnings from compiler */
1089 * Return a Lang_function given the interpreter name.
1092 get_language_from_interpreter (interpreter
)
1095 struct lang_entry
*lang
;
1098 if (interpreter
== NULL
)
1100 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1101 if (lang
->interpreters
!= NULL
)
1102 for (iname
= lang
->interpreters
; *iname
!= NULL
; iname
++)
1103 if (streq (*iname
, interpreter
))
1104 return lang
->function
;
1112 * Return a Lang_function given the file suffix.
1115 get_language_from_suffix (suffix
)
1118 struct lang_entry
*lang
;
1123 for (lang
= lang_names
; lang
->name
!= NULL
; lang
++)
1124 if (lang
->suffixes
!= NULL
)
1125 for (ext
= lang
->suffixes
; *ext
!= NULL
; ext
++)
1126 if (streq (*ext
, suffix
))
1127 return lang
->function
;
1134 * This routine is called on each file argument.
1140 struct stat stat_buf
;
1145 for (p
= file
; *p
!= '\0'; p
++)
1150 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
1152 error ("skipping %s: it is not a regular file.", file
);
1155 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1157 error ("skipping inclusion of %s in self.", file
);
1160 inf
= fopen (file
, "r");
1167 find_entries (file
, inf
);
1173 if (absolutefn (file
))
1175 /* file is an absolute file name. Canonicalise it. */
1176 filename
= absolute_filename (file
, cwd
);
1180 /* file is a file name relative to cwd. Make it relative
1181 to the directory of the tags file. */
1182 filename
= relative_filename (file
, tagfiledir
);
1184 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1193 * This routine sets up the boolean pseudo-functions which work
1194 * by setting boolean flags dependent upon the corresponding character
1195 * Every char which is NOT in that string is not a white char. Therefore,
1196 * all of the array "_wht" is set to FALSE, and then the elements
1197 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1198 * of a char is TRUE if it is the string "white", else FALSE.
1206 for (i
= 0; i
< CHARS
; i
++)
1207 _wht
[i
] = _nin
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
1208 for (sp
= white
; *sp
; sp
++) _wht
[*sp
] = TRUE
; _wht
[0] = _wht
['\n'];
1209 for (sp
= nonam
; *sp
; sp
++) _nin
[*sp
] = TRUE
; _nin
[0] = _nin
['\n'];
1210 for (sp
= endtk
; *sp
; sp
++) _etk
[*sp
] = TRUE
; _etk
[0] = _etk
['\n'];
1211 for (sp
= midtk
; *sp
; sp
++) _itk
[*sp
] = TRUE
; _btk
[0] = _btk
['\n'];
1212 for (sp
= begtk
; *sp
; sp
++) _btk
[*sp
] = TRUE
; _itk
[0] = _itk
['\n'];
1216 * This routine opens the specified file and calls the function
1217 * which finds the function and type definitions.
1220 find_entries (file
, inf
)
1225 Lang_function
*function
;
1226 NODE
*old_last_node
;
1227 extern NODE
*last_node
;
1230 /* Memory leakage here: the memory block pointed by curfile is never
1231 released. The amount of memory leaked here is the sum of the
1232 lengths of the input file names. */
1233 curfile
= savestr (file
);
1235 /* If user specified a language, use it. */
1236 function
= lang_func
;
1237 if (function
!= NULL
)
1244 cp
= etags_strrchr (file
, '.');
1248 function
= get_language_from_suffix (cp
);
1249 if (function
!= NULL
)
1257 /* Look for sharp-bang as the first two characters. */
1258 if (readline_internal (&lb
, inf
)
1260 && lb
.buffer
[0] == '#'
1261 && lb
.buffer
[1] == '!')
1265 /* Set lp to point at the first char after the last slash in the
1266 line or, if no slashes, at the first nonblank. Then set cp to
1267 the first successive blank and terminate the string. */
1268 lp
= etags_strrchr (lb
.buffer
+2, '/');
1272 for (lp
= lb
.buffer
+2; *lp
!= '\0' && isspace (*lp
); lp
++)
1274 for (cp
= lp
; *cp
!= '\0' && !isspace (*cp
); cp
++)
1278 if (strlen (lp
) > 0)
1280 function
= get_language_from_interpreter (lp
);
1281 if (function
!= NULL
)
1292 old_last_node
= last_node
;
1293 Fortran_functions (inf
);
1295 /* No Fortran entries found. Try C. */
1296 if (old_last_node
== last_node
)
1299 default_C_entries (inf
);
1307 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
)
1308 char *name
; /* tag name, or NULL if unnamed */
1309 bool is_func
; /* tag is a function */
1310 char *linestart
; /* start of the line where tag is */
1311 int linelen
; /* length of the line where tag is */
1312 int lno
; /* line number */
1313 long cno
; /* character number */
1317 if (CTAGS
&& name
== NULL
)
1320 np
= xnew (1, NODE
);
1322 /* If ctags mode, change name "main" to M<thisfilename>. */
1323 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1325 register char *fp
= etags_strrchr (curfile
, '/');
1326 np
->name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
1327 fp
= etags_strrchr (np
->name
, '.');
1328 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
1333 np
->been_warned
= FALSE
;
1335 np
->is_func
= is_func
;
1337 /* Our char numbers are 0-base, because of C language tradition?
1338 ctags compatibility? old versions compatibility? I don't know.
1339 Anyway, since emacs's are 1-base we expect etags.el to take care
1340 of the difference. If we wanted to have 1-based numbers, we would
1341 uncomment the +1 below. */
1342 np
->cno
= cno
/* + 1 */ ;
1343 np
->left
= np
->right
= NULL
;
1344 if (CTAGS
&& !cxref_style
)
1346 if (strlen (linestart
) < 50)
1347 np
->pat
= concat (linestart
, "$", "");
1349 np
->pat
= savenstr (linestart
, 50);
1352 np
->pat
= savenstr (linestart
, linelen
);
1354 add_node (np
, &head
);
1357 /* Date: Wed, 22 Jan 1997 02:56:31 -0500
1358 * From: Sam Kendall <kendall@cybercom.net>
1359 * Subject: Proposal for firming up the TAGS format specification
1360 * To: F.Potorti@cnuce.cnr.it
1362 * pfnote should emit the optimized form [unnamed tag] only if:
1363 * 1. name does not contain any of the characters " \t\r\n()";
1364 * 2. linestart contains name as either a rightmost, or rightmost but
1365 * one character, substring;
1366 * 3. the character, if any, immediately before name in linestart must
1367 * be one of the characters " \t()";
1368 * 4. the character, if any, immediately after name in linestart must
1369 * also be one of the characters " \t()".
1371 #define traditional_tag_style TRUE
1373 new_pfnote (name
, namelen
, is_func
, linestart
, linelen
, lno
, cno
)
1374 char *name
; /* tag name, or NULL if unnamed */
1375 int namelen
; /* tag length */
1376 bool is_func
; /* tag is a function */
1377 char *linestart
; /* start of the line where tag is */
1378 int linelen
; /* length of the line where tag is */
1379 int lno
; /* line number */
1380 long cno
; /* character number */
1388 for (cp
= name
; !notinname (*cp
); cp
++)
1390 if (*cp
== '\0') /* rule #1 */
1392 cp
= linestart
+ linelen
- namelen
;
1393 if (notinname (linestart
[linelen
-1]))
1394 cp
-= 1; /* rule #4 */
1395 if (cp
>= linestart
/* rule #2 */
1397 || notinname (cp
[-1])) /* rule #3 */
1398 && strneq (name
, cp
, namelen
)) /* rule #2 */
1399 named
= FALSE
; /* use unnamed tag */
1404 name
= savenstr (name
, namelen
);
1407 pfnote (name
, is_func
, linestart
, linelen
, lno
, cno
);
1412 * recurse on left children, iterate on right children.
1416 register NODE
*node
;
1420 register NODE
*node_right
= node
->right
;
1421 free_tree (node
->left
);
1422 if (node
->name
!= NULL
)
1425 free ((char *) node
);
1432 * Adds a node to the tree of nodes. In etags mode, we don't keep
1433 * it sorted; we just keep a linear list. In ctags mode, maintain
1434 * an ordered tree, with no attempt at balancing.
1436 * add_node is the only function allowed to add nodes, so it can
1439 NODE
*last_node
= NULL
;
1441 add_node (node
, cur_node_p
)
1442 NODE
*node
, **cur_node_p
;
1445 register NODE
*cur_node
= *cur_node_p
;
1447 if (cur_node
== NULL
)
1457 if (last_node
== NULL
)
1458 fatal ("internal error in add_node", (char *)NULL
);
1459 last_node
->right
= node
;
1465 dif
= strcmp (node
->name
, cur_node
->name
);
1468 * If this tag name matches an existing one, then
1469 * do not add the node, but maybe print a warning.
1473 if (streq (node
->file
, cur_node
->file
))
1477 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1478 node
->file
, lineno
, node
->name
);
1479 fprintf (stderr
, "Second entry ignored\n");
1482 else if (!cur_node
->been_warned
&& !no_warnings
)
1486 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1487 node
->file
, cur_node
->file
, node
->name
);
1488 cur_node
->been_warned
= TRUE
;
1493 /* Actually add the node */
1494 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1500 register NODE
*node
;
1507 /* Output subentries that precede this one */
1508 put_entries (node
->left
);
1510 /* Output this entry */
1514 if (node
->name
!= NULL
)
1515 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1516 node
->pat
, node
->name
, node
->lno
, node
->cno
);
1518 fprintf (tagf
, "%s\177%d,%d\n",
1519 node
->pat
, node
->lno
, node
->cno
);
1523 if (node
->name
== NULL
)
1524 error ("internal error: NULL name in ctags mode.", (char *)NULL
);
1529 fprintf (stdout
, "%s %s %d\n",
1530 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1532 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1533 node
->name
, node
->lno
, node
->file
, node
->pat
);
1537 fprintf (tagf
, "%s\t%s\t", node
->name
, node
->file
);
1541 putc (searchar
, tagf
);
1544 for (sp
= node
->pat
; *sp
; sp
++)
1546 if (*sp
== '\\' || *sp
== searchar
)
1550 putc (searchar
, tagf
);
1553 { /* a typedef; text pattern inadequate */
1554 fprintf (tagf
, "%d", node
->lno
);
1560 /* Output subentries that follow this one */
1561 put_entries (node
->right
);
1564 /* Length of a number's decimal representation. */
1572 for (; num
; num
/= 10)
1578 * Return total number of characters that put_entries will output for
1579 * the nodes in the subtree of the specified node. Works only if
1580 * we are not ctags, but called only in that case. This count
1581 * is irrelevant with the new tags.el, but is still supplied for
1582 * backward compatibility.
1585 total_size_of_entries (node
)
1586 register NODE
*node
;
1594 for (; node
; node
= node
->right
)
1596 /* Count left subentries. */
1597 total
+= total_size_of_entries (node
->left
);
1599 /* Count this entry */
1600 total
+= strlen (node
->pat
) + 1;
1601 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1602 if (node
->name
!= NULL
)
1603 total
+= 1 + strlen (node
->name
); /* \001name */
1610 * The C symbol tables.
1615 st_C_objprot
, st_C_objimpl
, st_C_objend
,
1619 st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1622 /* Feed stuff between (but not including) %[ and %] lines to:
1623 gperf -c -k 1,3 -o -p -r -t
1625 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1627 @interface, 0, st_C_objprot
1628 @protocol, 0, st_C_objprot
1629 @implementation,0, st_C_objimpl
1630 @end, 0, st_C_objend
1631 import, C_JAVA, st_C_ignore
1632 package, C_JAVA, st_C_ignore
1633 friend, C_PLPL, st_C_ignore
1634 extends, C_JAVA, st_C_javastruct
1635 implements, C_JAVA, st_C_javastruct
1636 class, C_PLPL, st_C_struct
1637 namespace, C_PLPL, st_C_struct
1638 domain, C_STAR, st_C_struct
1639 union, 0, st_C_struct
1640 struct, 0, st_C_struct
1642 typedef, 0, st_C_typedef
1643 define, 0, st_C_define
1644 bool, C_PLPL, st_C_typespec
1645 long, 0, st_C_typespec
1646 short, 0, st_C_typespec
1647 int, 0, st_C_typespec
1648 char, 0, st_C_typespec
1649 float, 0, st_C_typespec
1650 double, 0, st_C_typespec
1651 signed, 0, st_C_typespec
1652 unsigned, 0, st_C_typespec
1653 auto, 0, st_C_typespec
1654 void, 0, st_C_typespec
1655 extern, 0, st_C_typespec
1656 static, 0, st_C_typespec
1657 const, 0, st_C_typespec
1658 volatile, 0, st_C_typespec
1659 explicit, C_PLPL, st_C_typespec
1660 mutable, C_PLPL, st_C_typespec
1661 typename, C_PLPL, st_C_typespec
1662 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1663 DEFUN, 0, st_C_gnumacro
1664 SYSCALL, 0, st_C_gnumacro
1665 ENTRY, 0, st_C_gnumacro
1666 PSEUDO, 0, st_C_gnumacro
1667 # These are defined inside C functions, so currently they are not met.
1668 # EXFUN used in glibc, DEFVAR_* in emacs.
1669 #EXFUN, 0, st_C_gnumacro
1670 #DEFVAR_, 0, st_C_gnumacro
1672 and replace lines between %< and %> with its output. */
1674 /* starting time is 10:31:16 */
1675 /* C code produced by gperf version 2.1 (K&R C version) */
1676 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1679 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1681 #define MIN_WORD_LENGTH 3
1682 #define MAX_WORD_LENGTH 15
1683 #define MIN_HASH_VALUE 15
1684 #define MAX_HASH_VALUE 128
1687 114 is the maximum key range
1693 register unsigned int len
;
1695 static unsigned char hash_table
[] =
1697 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1698 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1699 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1700 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1701 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1702 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1703 128, 128, 128, 128, 39, 128, 128, 128, 54, 48,
1704 46, 128, 128, 128, 128, 128, 128, 128, 128, 128,
1705 28, 128, 128, 40, 32, 128, 128, 128, 128, 128,
1706 128, 128, 128, 128, 128, 128, 128, 24, 30, 47,
1707 62, 7, 60, 27, 128, 60, 128, 128, 59, 16,
1708 31, 23, 45, 128, 4, 14, 2, 55, 5, 128,
1709 128, 128, 128, 128, 128, 128, 128, 128,
1711 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1714 struct C_stab_entry
*
1715 in_word_set (str
, len
)
1717 register unsigned int len
;
1720 static struct C_stab_entry wordlist
[] =
1722 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1723 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1724 {"extern", 0, st_C_typespec
},
1725 {"extends", C_JAVA
, st_C_javastruct
},
1726 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1727 {"struct", 0, st_C_struct
},
1728 {"mutable", C_PLPL
, st_C_typespec
},
1729 {"",}, {"",}, {"",}, {"",},
1730 {"auto", 0, st_C_typespec
},
1731 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1733 {"short", 0, st_C_typespec
},
1735 {"static", 0, st_C_typespec
},
1737 {"signed", 0, st_C_typespec
},
1738 {"",}, {"",}, {"",}, {"",},
1739 {"@protocol", 0, st_C_objprot
},
1741 {"typedef", 0, st_C_typedef
},
1742 {"typename", C_PLPL
, st_C_typespec
},
1743 {"namespace", C_PLPL
, st_C_struct
},
1744 {"bool", C_PLPL
, st_C_typespec
},
1746 {"explicit", C_PLPL
, st_C_typespec
},
1747 {"",}, {"",}, {"",}, {"",},
1748 {"int", 0, st_C_typespec
},
1749 {"enum", 0, st_C_enum
},
1751 {"void", 0, st_C_typespec
},
1752 {"@implementation", 0, st_C_objimpl
},
1754 {"volatile", 0, st_C_typespec
},
1756 {"@end", 0, st_C_objend
},
1757 {"char", 0, st_C_typespec
},
1758 {"class", C_PLPL
, st_C_struct
},
1759 {"unsigned", 0, st_C_typespec
},
1761 {"@interface", 0, st_C_objprot
},
1763 {"PSEUDO", 0, st_C_gnumacro
},
1764 {"const", 0, st_C_typespec
},
1765 {"domain", C_STAR
, st_C_struct
},
1766 {"ENTRY", 0, st_C_gnumacro
},
1768 {"SYSCALL", 0, st_C_gnumacro
},
1769 {"float", 0, st_C_typespec
},
1770 {"",}, {"",}, {"",}, {"",}, {"",},
1771 {"long", 0, st_C_typespec
},
1772 {"",}, {"",}, {"",}, {"",},
1773 {"package", C_JAVA
, st_C_ignore
},
1774 {"",}, {"",}, {"",}, {"",}, {"",},
1775 {"DEFUN", 0, st_C_gnumacro
},
1776 {"",}, {"",}, {"",}, {"",}, {"",},
1777 {"import", C_JAVA
, st_C_ignore
},
1778 {"",}, {"",}, {"",},
1779 {"implements", C_JAVA
, st_C_javastruct
},
1780 {"",}, {"",}, {"",}, {"",},
1781 {"union", 0, st_C_struct
},
1783 {"double", 0, st_C_typespec
},
1785 {"friend", C_PLPL
, st_C_ignore
},
1787 {"define", 0, st_C_define
},
1790 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1792 register int key
= hash (str
, len
);
1794 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1796 register char *s
= wordlist
[key
].name
;
1798 if (*s
== *str
&& !strncmp (str
+ 1, s
+ 1, len
- 1))
1799 return &wordlist
[key
];
1804 /* ending time is 10:31:16 */
1808 C_symtype (str
, len
, c_ext
)
1813 register struct C_stab_entry
*se
= in_word_set (str
, len
);
1815 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1821 * C functions and variables are recognized using a simple
1822 * finite automaton. fvdef is its state variable.
1826 fvnone
, /* nothing seen */
1827 fvnameseen
, /* function or variable name seen */
1828 fstartlist
, /* func: just after open parenthesis */
1829 finlist
, /* func: in parameter list */
1830 flistseen
, /* func: after parameter list */
1831 fignore
, /* func: before open brace */
1832 vignore
/* var-like: ignore until ';' */
1837 * typedefs are recognized using a simple finite automaton.
1838 * typdef is its state variable.
1842 tnone
, /* nothing seen */
1843 ttypedseen
, /* typedef keyword seen */
1844 tinbody
, /* inside typedef body */
1845 tend
, /* just before typedef tag */
1846 tignore
/* junk after typedef tag */
1851 * struct-like structures (enum, struct and union) are recognized
1852 * using another simple finite automaton. `structdef' is its state
1857 snone
, /* nothing seen yet */
1858 skeyseen
, /* struct-like keyword seen */
1859 stagseen
, /* struct-like tag seen */
1860 scolonseen
, /* colon seen after struct-like tag */
1861 sinbody
/* in struct body: recognize member func defs*/
1865 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1866 * struct tag, and structtype is the type of the preceding struct-like
1869 char *structtag
= "<uninited>";
1870 enum sym_type structtype
;
1873 * When objdef is different from onone, objtag is the name of the class.
1875 char *objtag
= "<uninited>";
1878 * Yet another little state machine to deal with preprocessor lines.
1882 dnone
, /* nothing seen */
1883 dsharpseen
, /* '#' seen as first char on line */
1884 ddefineseen
, /* '#' and 'define' seen */
1885 dignorerest
/* ignore rest of line */
1889 * State machine for Objective C protocols and implementations.
1890 * Tom R.Hageman <tom@basil.icce.rug.nl>
1894 onone
, /* nothing seen */
1895 oprotocol
, /* @interface or @protocol seen */
1896 oimplementation
, /* @implementations seen */
1897 otagseen
, /* class name seen */
1898 oparenseen
, /* parenthesis before category seen */
1899 ocatseen
, /* category name seen */
1900 oinbody
, /* in @implementation body */
1901 omethodsign
, /* in @implementation body, after +/- */
1902 omethodtag
, /* after method name */
1903 omethodcolon
, /* after method colon */
1904 omethodparm
, /* after method parameter */
1905 oignore
/* wait for @end */
1910 * Use this structure to keep info about the token read, and how it
1911 * should be tagged. Used by the make_C_tag function to build a tag.
1923 TOKEN tok
; /* latest token read */
1927 * Set this to TRUE, and the next token considered is called a function.
1928 * Used only for GNU emacs's function-defining macros.
1930 bool next_token_is_func
;
1933 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1938 * methodlen is the length of the method name stored in token_name.
1944 * checks to see if the current token is at the start of a
1945 * function or variable, or corresponds to a typedef, or
1946 * is a struct/union/enum tag, or #define, or an enum constant.
1948 * *IS_FUNC gets TRUE iff the token is a function or #define macro
1949 * with args. C_EXT is which language we are looking at.
1951 * In the future we will need some way to adjust where the end of
1952 * the token is; for instance, implementing the C++ keyword
1953 * `operator' properly will adjust the end of the token to be after
1954 * whatever follows `operator'.
1962 * next_token_is_func IN OUT
1966 consider_token (str
, len
, c
, c_ext
, cblev
, parlev
, is_func_or_var
)
1967 register char *str
; /* IN: token pointer */
1968 register int len
; /* IN: token length */
1969 register char c
; /* IN: first char after the token */
1970 int c_ext
; /* IN: C extensions mask */
1971 int cblev
; /* IN: curly brace level */
1972 int parlev
; /* IN: parenthesis level */
1973 bool *is_func_or_var
; /* OUT: function or variable found */
1975 enum sym_type toktype
= C_symtype (str
, len
, c_ext
);
1978 * Advance the definedef state machine.
1983 /* We're not on a preprocessor line. */
1986 if (toktype
== st_C_define
)
1988 definedef
= ddefineseen
;
1992 definedef
= dignorerest
;
1997 * Make a tag for any macro, unless it is a constant
1998 * and constantypedefs is FALSE.
2000 definedef
= dignorerest
;
2001 *is_func_or_var
= (c
== '(');
2002 if (!*is_func_or_var
&& !constantypedefs
)
2009 error ("internal error: definedef value.", (char *)NULL
);
2018 if (toktype
== st_C_typedef
)
2021 typdef
= ttypedseen
;
2037 /* Do not return here, so the structdef stuff has a chance. */
2051 * This structdef business is currently only invoked when cblev==0.
2052 * It should be recursively invoked whatever the curly brace level,
2053 * and a stack of states kept, to allow for definitions of structs
2056 * This structdef business is NOT invoked when we are ctags and the
2057 * file is plain C. This is because a struct tag may have the same
2058 * name as another tag, and this loses with ctags.
2062 case st_C_javastruct
:
2063 if (structdef
== stagseen
)
2064 structdef
= scolonseen
;
2069 if (typdef
== ttypedseen
2070 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
2072 structdef
= skeyseen
;
2073 structtype
= toktype
;
2078 if (structdef
== skeyseen
)
2080 /* Save the tag for struct/union/class, for functions and variables
2081 that may be defined inside. */
2082 if (structtype
== st_C_struct
)
2083 structtag
= savenstr (str
, len
);
2085 structtag
= "<enum>";
2086 structdef
= stagseen
;
2090 /* Avoid entering fvdef stuff if typdef is going on. */
2091 if (typdef
!= tnone
)
2097 /* Detect GNU macros.
2099 DEFUN note for writers of emacs C code:
2100 The DEFUN macro, used in emacs C source code, has a first arg
2101 that is a string (the lisp function name), and a second arg that
2102 is a C function name. Since etags skips strings, the second arg
2103 is tagged. This is unfortunate, as it would be better to tag the
2104 first arg. The simplest way to deal with this problem would be
2105 to name the tag with a name built from the function name, by
2106 removing the initial 'F' character and substituting '-' for '_'.
2107 Anyway, this assumes that the conventions of naming lisp
2108 functions will never change. Currently, this method is not
2109 implemented, so writers of emacs code are recommended to put the
2110 first two args of a DEFUN on the same line. */
2111 if (definedef
== dnone
&& toktype
== st_C_gnumacro
)
2113 next_token_is_func
= TRUE
;
2116 if (next_token_is_func
)
2118 next_token_is_func
= FALSE
;
2120 *is_func_or_var
= TRUE
;
2124 /* Detect Objective C constructs. */
2134 objdef
= oimplementation
;
2138 case oimplementation
:
2139 /* Save the class tag for functions or variables defined inside. */
2140 objtag
= savenstr (str
, len
);
2144 /* Save the class tag for categories. */
2145 objtag
= savenstr (str
, len
);
2147 *is_func_or_var
= TRUE
;
2151 *is_func_or_var
= TRUE
;
2158 objdef
= omethodtag
;
2160 grow_linebuffer (&token_name
, methodlen
+ 1);
2161 strncpy (token_name
.buffer
, str
, len
);
2162 token_name
.buffer
[methodlen
] = '\0';
2163 token_name
.len
= methodlen
;
2169 objdef
= omethodparm
;
2174 objdef
= omethodtag
;
2176 grow_linebuffer (&token_name
, methodlen
+ 1);
2177 strncat (token_name
.buffer
, str
, len
);
2178 token_name
.len
= methodlen
;
2183 if (toktype
== st_C_objend
)
2185 /* Memory leakage here: the string pointed by objtag is
2186 never released, because many tests would be needed to
2187 avoid breaking on incorrect input code. The amount of
2188 memory leaked here is the sum of the lengths of the
2196 /* A function, variable or enum constant? */
2200 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2201 fvdef
= fvnone
; /* should be useless */
2207 if (constantypedefs
&& structdef
== sinbody
&& structtype
== st_C_enum
)
2209 if (fvdef
== fvnone
)
2211 fvdef
= fvnameseen
; /* function or variable */
2212 *is_func_or_var
= TRUE
;
2222 * This routine finds functions, variables, typedefs,
2223 * #define's, enum constants and struct/union/enum definitions in
2224 * #C syntax and adds them to the list.
2226 #define current_lb_is_new (newndx == curndx)
2227 #define switch_line_buffers() (curndx = 1 - curndx)
2229 #define curlb (lbs[curndx].lb)
2230 #define othlb (lbs[1-curndx].lb)
2231 #define newlb (lbs[newndx].lb)
2232 #define curlinepos (lbs[curndx].linepos)
2233 #define othlinepos (lbs[1-curndx].linepos)
2234 #define newlinepos (lbs[newndx].linepos)
2236 #define CNL_SAVE_DEFINEDEF \
2238 curlinepos = charno; \
2240 linecharno = charno; \
2241 charno += readline (&curlb, inf); \
2242 lp = curlb.buffer; \
2249 CNL_SAVE_DEFINEDEF; \
2250 if (savetok.valid) \
2253 savetok.valid = FALSE; \
2255 definedef = dnone; \
2263 /* This function should never be called when tok.valid is FALSE, but
2264 we must protect against invalid input or internal errors. */
2267 if (traditional_tag_style
)
2269 /* This was the original code. Now we call new_pfnote instead,
2270 which uses the new method for naming tags (see new_pfnote). */
2273 if (CTAGS
|| tok
.named
)
2274 name
= savestr (token_name
.buffer
);
2275 pfnote (name
, isfun
,
2276 tok
.buffer
, tok
.linelen
, tok
.lineno
, tok
.linepos
);
2279 new_pfnote (token_name
.buffer
, token_name
.len
, isfun
,
2280 tok
.buffer
, tok
.linelen
, tok
.lineno
, tok
.linepos
);
2289 C_entries (c_ext
, inf
)
2290 int c_ext
; /* extension of C */
2291 FILE *inf
; /* input file */
2293 register char c
; /* latest char read; '\0' for end of line */
2294 register char *lp
; /* pointer one beyond the character `c' */
2295 int curndx
, newndx
; /* indices for current and new lb */
2296 register int tokoff
; /* offset in line of start of current token */
2297 register int toklen
; /* length of current token */
2298 char *qualifier
; /* string used to qualify names */
2299 int qlen
; /* length of qualifier */
2300 int cblev
; /* current curly brace level */
2301 int parlev
; /* current parenthesis level */
2302 bool incomm
, inquote
, inchar
, quotednl
, midtoken
;
2304 TOKEN savetok
; /* token saved during preprocessor handling */
2307 curndx
= newndx
= 0;
2313 fvdef
= fvnone
; typdef
= tnone
; structdef
= snone
;
2314 definedef
= dnone
; objdef
= onone
;
2315 next_token_is_func
= yacc_rules
= FALSE
;
2316 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2317 tok
.valid
= savetok
.valid
= FALSE
;
2320 cplpl
= (c_ext
& C_PLPL
) == C_PLPL
;
2321 cjava
= (c_ext
& C_JAVA
) == C_JAVA
;
2323 { qualifier
= "."; qlen
= 1; }
2325 { qualifier
= "::"; qlen
= 2; }
2332 /* If we're at the end of the line, the next character is a
2333 '\0'; don't skip it, because it's the thing that tells us
2334 to read the next line. */
2355 /* Newlines inside comments do not end macro definitions in
2370 /* Newlines inside strings do not end macro definitions
2371 in traditional cpp, even though compilers don't
2372 usually accept them. */
2383 /* Hmmm, something went wrong. */
2397 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2402 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!=vignore
)
2412 else if (/* cplpl && */ *lp
== '/')
2420 if ((c_ext
& YACC
) && *lp
== '%')
2422 /* entering or exiting rules section in yacc file */
2424 definedef
= dnone
; fvdef
= fvnone
;
2425 typdef
= tnone
; structdef
= snone
;
2426 next_token_is_func
= FALSE
;
2427 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2429 yacc_rules
= !yacc_rules
;
2435 if (definedef
== dnone
)
2438 bool cpptoken
= TRUE
;
2440 /* Look back on this line. If all blanks, or nonblanks
2441 followed by an end of comment, this is a preprocessor
2443 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2446 if (*cp
== '*' && *(cp
+1) == '/')
2455 definedef
= dsharpseen
;
2456 } /* if (definedef == dnone) */
2462 /* Consider token only if some complicated conditions are satisfied. */
2463 if ((definedef
!= dnone
2464 || (cblev
== 0 && structdef
!= scolonseen
)
2465 || (cblev
== 1 && cplpl
&& structdef
== sinbody
)
2466 || (structdef
== sinbody
&& structtype
== st_C_enum
))
2467 && typdef
!= tignore
2468 && definedef
!= dignorerest
2469 && fvdef
!= finlist
)
2475 if (c
== ':' && cplpl
&& *lp
== ':' && begtoken(*(lp
+ 1)))
2478 * This handles :: in the middle, but not at the
2479 * beginning of an identifier.
2486 bool funorvar
= FALSE
;
2489 || consider_token (newlb
.buffer
+ tokoff
, toklen
, c
,
2490 c_ext
, cblev
, parlev
, &funorvar
))
2493 if (structdef
== sinbody
2494 && definedef
== dnone
2496 /* function or var defined in C++ class body */
2498 int len
= strlen (structtag
) + qlen
+ toklen
;
2499 grow_linebuffer (&token_name
, len
+ 1);
2500 strcpy (token_name
.buffer
, structtag
);
2501 strcat (token_name
.buffer
, qualifier
);
2502 strncat (token_name
.buffer
,
2503 newlb
.buffer
+ tokoff
, toklen
);
2504 token_name
.len
= len
;
2507 else if (objdef
== ocatseen
)
2508 /* Objective C category */
2510 int len
= strlen (objtag
) + 2 + toklen
;
2511 grow_linebuffer (&token_name
, len
+ 1);
2512 strcpy (token_name
.buffer
, objtag
);
2513 strcat (token_name
.buffer
, "(");
2514 strncat (token_name
.buffer
,
2515 newlb
.buffer
+ tokoff
, toklen
);
2516 strcat (token_name
.buffer
, ")");
2517 token_name
.len
= len
;
2520 else if (objdef
== omethodtag
2521 || objdef
== omethodparm
)
2522 /* Objective C method */
2528 grow_linebuffer (&token_name
, toklen
+ 1);
2529 strncpy (token_name
.buffer
,
2530 newlb
.buffer
+ tokoff
, toklen
);
2531 token_name
.buffer
[toklen
] = '\0';
2532 token_name
.len
= toklen
;
2534 tok
.named
= (structdef
== stagseen
2537 && definedef
== dignorerest
));
2539 tok
.lineno
= lineno
;
2540 tok
.linelen
= tokoff
+ toklen
+ 1;
2541 tok
.buffer
= newlb
.buffer
;
2542 tok
.linepos
= newlinepos
;
2545 if (definedef
== dnone
2546 && (fvdef
== fvnameseen
2547 || structdef
== stagseen
2549 || objdef
!= onone
))
2551 if (current_lb_is_new
)
2552 switch_line_buffers ();
2555 make_C_tag (funorvar
);
2559 } /* if (endtoken (c)) */
2560 else if (intoken (c
))
2565 } /* if (midtoken) */
2566 else if (begtoken (c
))
2577 make_C_tag (TRUE
); /* a function */
2584 if (structdef
== stagseen
&& !cjava
)
2590 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
2592 tokoff
= lp
- 1 - newlb
.buffer
;
2597 } /* if (begtoken) */
2598 } /* if must look at token */
2601 /* Detect end of line, colon, comma, semicolon and various braces
2602 after having handled a token.*/
2606 if (definedef
!= dnone
)
2612 make_C_tag (TRUE
); /* an Objective C class */
2616 objdef
= omethodcolon
;
2618 grow_linebuffer (&token_name
, methodlen
+ 1);
2619 strcat (token_name
.buffer
, ":");
2620 token_name
.len
= methodlen
;
2623 if (structdef
== stagseen
)
2624 structdef
= scolonseen
;
2631 make_C_tag (FALSE
); /* a yacc function */
2641 if (definedef
!= dnone
)
2647 make_C_tag (FALSE
); /* a typedef */
2657 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2658 make_C_tag (FALSE
); /* a variable */
2662 /* The following instruction invalidates the token.
2663 Probably the token should be invalidated in all
2664 other cases where some state machine is reset. */
2667 if (structdef
== stagseen
)
2671 if (definedef
!= dnone
)
2677 make_C_tag (TRUE
); /* an Objective C method */
2688 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2689 make_C_tag (FALSE
); /* a variable */
2694 if (structdef
== stagseen
)
2698 if (definedef
!= dnone
)
2700 if (cblev
== 0 && typdef
== tend
)
2703 make_C_tag (FALSE
); /* a typedef */
2713 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2714 make_C_tag (FALSE
); /* a variable */
2719 if (structdef
== stagseen
)
2723 if (definedef
!= dnone
)
2725 if (objdef
== otagseen
&& parlev
== 0)
2726 objdef
= oparenseen
;
2734 if (tok
.valid
&& *lp
!= '*')
2736 /* This handles constructs like:
2737 typedef void OperatorFun (int fun); */
2742 } /* switch (typdef) */
2754 if (definedef
!= dnone
)
2756 if (objdef
== ocatseen
&& parlev
== 1)
2758 make_C_tag (TRUE
); /* an Objective C category */
2770 if (cblev
== 0 && typdef
== tend
)
2773 make_C_tag (FALSE
); /* a typedef */
2776 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
2780 if (definedef
!= dnone
)
2782 if (typdef
== ttypedseen
)
2786 case skeyseen
: /* unnamed struct */
2787 structdef
= sinbody
;
2788 structtag
= "_anonymous_";
2791 case scolonseen
: /* named struct */
2792 structdef
= sinbody
;
2793 make_C_tag (FALSE
); /* a struct */
2799 make_C_tag (TRUE
); /* a function */
2808 make_C_tag (TRUE
); /* an Objective C class */
2813 make_C_tag (TRUE
); /* an Objective C method */
2817 /* Neutralize `extern "C" {' grot. */
2818 if (cblev
== 0 && structdef
== snone
&& typdef
== tnone
)
2825 if (definedef
!= dnone
)
2827 if (fvdef
== fstartlist
)
2828 fvdef
= fvnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2831 if (definedef
!= dnone
)
2833 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2835 cblev
= 0; /* reset curly brace level if first column */
2836 parlev
= 0; /* also reset paren level, just in case... */
2842 if (typdef
== tinbody
)
2844 /* Memory leakage here: the string pointed by structtag is
2845 never released, because I fear to miss something and
2846 break things while freeing the area. The amount of
2847 memory leaked here is the sum of the lengths of the
2849 if (structdef == sinbody)
2850 free (structtag); */
2853 structtag
= "<error>";
2857 if (definedef
!= dnone
)
2866 if ((globals
&& cblev
== 0) || (members
&& cblev
== 1))
2867 make_C_tag (FALSE
); /* a variable */
2875 if (objdef
== oinbody
&& cblev
== 0)
2877 objdef
= omethodsign
;
2881 case '#': case '~': case '&': case '%': case '/': case '|':
2882 case '^': case '!': case '<': case '>': case '.': case '?': case ']':
2883 if (definedef
!= dnone
)
2885 /* These surely cannot follow a function tag. */
2886 if (fvdef
!= finlist
&& fvdef
!= fignore
&& fvdef
!= vignore
)
2890 if (objdef
== otagseen
)
2892 make_C_tag (TRUE
); /* an Objective C class */
2895 /* If a macro spans multiple lines don't reset its state. */
2903 } /* while not eof */
2907 * Process either a C++ file or a C file depending on the setting
2911 default_C_entries (inf
)
2914 C_entries (cplusplus
? C_PLPL
: 0, inf
);
2917 /* Always do plain ANSI C. */
2919 plain_C_entries (inf
)
2925 /* Always do C++. */
2927 Cplusplus_entries (inf
)
2930 C_entries (C_PLPL
, inf
);
2933 /* Always do Java. */
2938 C_entries (C_JAVA
, inf
);
2946 C_entries (C_STAR
, inf
);
2949 /* Always do Yacc. */
2954 C_entries (YACC
, inf
);
2957 /* Fortran parsing */
2965 register int len
= 0;
2967 while (*cp
&& lowcase(*cp
) == lowcase(dbp
[len
]))
2969 if (*cp
== '\0' && !intoken(dbp
[len
]))
2980 while (isspace (*dbp
))
2985 while (isspace (*dbp
))
2987 if (strneq (dbp
, "(*)", 3))
2992 if (!isdigit (*dbp
))
2994 --dbp
; /* force failure */
2999 while (isdigit (*dbp
));
3008 while (isspace (*dbp
))
3013 linecharno
= charno
;
3014 charno
+= readline (&lb
, inf
);
3019 while (isspace (*dbp
))
3028 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
3031 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3032 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3036 Fortran_functions (inf
)
3045 linecharno
= charno
;
3046 charno
+= readline (&lb
, inf
);
3049 dbp
++; /* Ratfor escape to fortran */
3050 while (isspace (*dbp
))
3054 switch (lowcase (*dbp
))
3057 if (tail ("integer"))
3065 if (tail ("logical"))
3069 if (tail ("complex") || tail ("character"))
3073 if (tail ("double"))
3075 while (isspace (*dbp
))
3079 if (tail ("precision"))
3085 while (isspace (*dbp
))
3089 switch (lowcase (*dbp
))
3092 if (tail ("function"))
3096 if (tail ("subroutine"))
3104 if (tail ("program"))
3109 if (tail ("procedure"))
3117 * Bob Weiner, Motorola Inc., 4/3/94
3118 * Unix and microcontroller assembly tag handling
3119 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3133 linecharno
= charno
;
3134 charno
+= readline (&lb
, inf
);
3137 /* If first char is alphabetic or one of [_.$], test for colon
3138 following identifier. */
3139 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3141 /* Read past label. */
3143 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
3145 if (*cp
== ':' || isspace (*cp
))
3147 /* Found end of label, so copy it and add it to the table. */
3148 pfnote ((CTAGS
) ? savenstr(lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
3149 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3156 * Perl support by Bart Robinson <lomew@cs.utah.edu>
3157 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3160 Perl_functions (inf
)
3171 linecharno
= charno
;
3172 charno
+= readline (&lb
, inf
);
3175 if (*cp
++ == 's' && *cp
++ == 'u' && *cp
++ == 'b' && isspace (*cp
++))
3177 while (*cp
&& isspace (*cp
))
3179 while (*cp
&& ! isspace (*cp
) && *cp
!= '{')
3181 pfnote ((CTAGS
) ? savenstr (lb
.buffer
, cp
-lb
.buffer
) : NULL
, TRUE
,
3182 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3187 /* Idea by Corny de Souza
3188 * Cobol tag functions
3189 * We could look for anything that could be a paragraph name.
3190 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3193 Cobol_paragraphs (inf
)
3204 linecharno
= charno
;
3205 charno
+= readline (&lb
, inf
);
3209 dbp
= lb
.buffer
+ 8;
3211 /* If eoln, compiler option or comment ignore whole line. */
3212 if (dbp
[-1] != ' ' || !isalnum (dbp
[0]))
3215 for (cp
= dbp
; isalnum (*cp
) || *cp
== '-'; cp
++)
3218 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3219 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3223 /* Added by Mosur Mohan, 4/22/88 */
3224 /* Pascal parsing */
3227 * Locates tags for procedures & functions. Doesn't do any type- or
3228 * var-definitions. It does look for the keyword "extern" or
3229 * "forward" immediately following the procedure statement; if found,
3230 * the tag is skipped.
3233 Pascal_functions (inf
)
3236 struct linebuffer tline
; /* mostly copied from C_entries */
3238 int save_lineno
, save_len
;
3239 char c
, *cp
, *namebuf
;
3241 bool /* each of these flags is TRUE iff: */
3242 incomment
, /* point is inside a comment */
3243 inquote
, /* point is inside '..' string */
3244 get_tagname
, /* point is after PROCEDURE/FUNCTION
3245 keyword, so next item = potential tag */
3246 found_tag
, /* point is after a potential tag */
3247 inparms
, /* point is within parameter-list */
3248 verify_tag
; /* point has passed the parm-list, so the
3249 next token will determine whether this
3250 is a FORWARD/EXTERN to be ignored, or
3251 whether it is a real tag */
3258 initbuffer (&tline
);
3260 incomment
= inquote
= FALSE
;
3261 found_tag
= FALSE
; /* have a proc name; check if extern */
3262 get_tagname
= FALSE
; /* have found "procedure" keyword */
3263 inparms
= FALSE
; /* found '(' after "proc" */
3264 verify_tag
= FALSE
; /* check if "extern" is ahead */
3266 /* long main loop to get next char */
3270 if (c
== '\0') /* if end of line */
3273 linecharno
= charno
;
3274 charno
+= readline (&lb
, inf
);
3278 if (!((found_tag
&& verify_tag
) ||
3280 c
= *dbp
++; /* only if don't need *dbp pointing
3281 to the beginning of the name of
3282 the procedure or function */
3286 if (c
== '}') /* within { } comments */
3288 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
3305 inquote
= TRUE
; /* found first quote */
3307 case '{': /* found open { comment */
3311 if (*dbp
== '*') /* found open (* comment */
3316 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
3319 case ')': /* end of parms list */
3324 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
3331 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
3333 /* check if this is an "extern" declaration */
3336 if (lowcase (*dbp
== 'e'))
3338 if (tail ("extern")) /* superfluous, really! */
3344 else if (lowcase (*dbp
) == 'f')
3346 if (tail ("forward")) /* check for forward reference */
3352 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
3356 pfnote (namebuf
, TRUE
,
3357 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
3361 if (get_tagname
) /* grab name of proc or fn */
3366 /* save all values for later tagging */
3367 grow_linebuffer (&tline
, lb
.len
+ 1);
3368 strcpy (tline
.buffer
, lb
.buffer
);
3369 save_lineno
= lineno
;
3370 save_lcno
= linecharno
;
3372 /* grab block name */
3373 for (cp
= dbp
+ 1; *cp
!= '\0' && !endtoken (*cp
); cp
++)
3375 namebuf
= (CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
;
3376 dbp
= cp
; /* set dbp to e-o-token */
3377 save_len
= dbp
- lb
.buffer
+ 1;
3378 get_tagname
= FALSE
;
3382 /* and proceed to check for "extern" */
3384 else if (!incomment
&& !inquote
&& !found_tag
)
3386 /* check for proc/fn keywords */
3387 switch (lowcase (c
))
3390 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
3394 if (tail ("unction"))
3399 } /* while not eof */
3401 free (tline
.buffer
);
3405 * lisp tag functions
3406 * look for (def or (DEF, quote or QUOTE
3410 register char *strp
;
3412 return ((strp
[1] == 'd' || strp
[1] == 'D')
3413 && (strp
[2] == 'e' || strp
[2] == 'E')
3414 && (strp
[3] == 'f' || strp
[3] == 'F'));
3419 register char *strp
;
3421 return ((*(++strp
) == 'q' || *strp
== 'Q')
3422 && (*(++strp
) == 'u' || *strp
== 'U')
3423 && (*(++strp
) == 'o' || *strp
== 'O')
3424 && (*(++strp
) == 't' || *strp
== 'T')
3425 && (*(++strp
) == 'e' || *strp
== 'E')
3426 && isspace (*(++strp
)));
3434 if (*dbp
== '\'') /* Skip prefix quote */
3436 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
3439 while (isspace (*dbp
))
3442 for (cp
= dbp
/*+1*/;
3443 *cp
!= '\0' && *cp
!= '(' && *cp
!= ' ' && *cp
!= ')';
3449 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3450 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3454 Lisp_functions (inf
)
3463 linecharno
= charno
;
3464 charno
+= readline (&lb
, inf
);
3470 while (!isspace (*dbp
))
3472 while (isspace (*dbp
))
3478 /* Check for (foo::defmumble name-defined ... */
3481 while (*dbp
&& !isspace (*dbp
)
3482 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
3487 while (*dbp
== ':');
3489 if (L_isdef (dbp
- 1))
3491 while (!isspace (*dbp
))
3493 while (isspace (*dbp
))
3504 * Postscript tag functions
3505 * Just look for lines where the first character is '/'
3506 * Richard Mlynarik <mly@adoc.xerox.com>
3509 Postscript_functions (inf
)
3518 linecharno
= charno
;
3519 charno
+= readline (&lb
, inf
);
3525 *cp
!= '\0' && *cp
!= ' ' && *cp
!= '{';
3528 pfnote ((CTAGS
) ? savenstr (dbp
, cp
-dbp
) : NULL
, TRUE
,
3529 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3536 * Scheme tag functions
3537 * look for (def... xyzzy
3538 * look for (def... (xyzzy
3539 * look for (def ... ((...(xyzzy ....
3540 * look for (set! xyzzy
3546 Scheme_functions (inf
)
3555 linecharno
= charno
;
3556 charno
+= readline (&lb
, inf
);
3558 if (dbp
[0] == '(' &&
3559 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
3560 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3561 (dbp
[3] == 'F' || dbp
[3] == 'f'))
3563 while (!isspace (*dbp
))
3565 /* Skip over open parens and white space */
3566 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
3570 if (dbp
[0] == '(' &&
3571 (dbp
[1] == 'S' || dbp
[1] == 's') &&
3572 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
3573 (dbp
[3] == 'T' || dbp
[3] == 't') &&
3574 (dbp
[4] == '!' || dbp
[4] == '!') &&
3577 while (!isspace (*dbp
))
3579 /* Skip over white space */
3580 while (isspace (*dbp
))
3594 /* Go till you get to white space or a syntactic break */
3596 *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
);
3599 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
,
3600 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
3603 /* Find tags in TeX and LaTeX input files. */
3605 /* TEX_toktab is a table of TeX control sequences that define tags.
3606 Each TEX_tabent records one such control sequence.
3607 CONVERT THIS TO USE THE Stab TYPE!! */
3614 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
3616 /* Default set of control sequences to put into TEX_toktab.
3617 The value of environment var TEXTAGS is prepended to this. */
3619 char *TEX_defenv
= "\
3620 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
3621 :part:appendix:entry:index";
3624 struct TEX_tabent
*TEX_decode_env ();
3627 char TEX_esc
= '\\';
3628 char TEX_opgrp
= '{';
3629 char TEX_clgrp
= '}';
3632 * TeX/LaTeX scanning loop.
3644 /* Select either \ or ! as escape character. */
3647 /* Initialize token table once from environment. */
3649 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
3652 { /* Scan each line in file */
3654 linecharno
= charno
;
3655 charno
+= readline (&lb
, inf
);
3658 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
3662 linecharno
+= dbp
- lasthit
;
3664 i
= TEX_Token (lasthit
);
3667 /* We seem to include the TeX command in the tag name.
3669 for (p = lasthit + TEX_toktab[i].len;
3670 *p != '\0' && *p != TEX_clgrp;
3673 pfnote (/*savenstr (lasthit, p-lasthit)*/ (char *)NULL
, TRUE
,
3674 lb
.buffer
, lb
.len
, lineno
, linecharno
);
3675 break; /* We only tag a line once */
3681 #define TEX_LESC '\\'
3682 #define TEX_SESC '!'
3685 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3686 chars accordingly. */
3693 while ((c
= getc (inf
)) != EOF
)
3695 /* Skip to next line if we hit the TeX comment char. */
3699 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
3718 /* Read environment and prepend it to the default string.
3719 Build token table. */
3721 TEX_decode_env (evarname
, defenv
)
3725 register char *env
, *p
;
3727 struct TEX_tabent
*tab
;
3730 /* Append default string to environment. */
3731 env
= getenv (evarname
);
3737 env
= concat (oldenv
, defenv
, "");
3741 /* Allocate a token table */
3742 for (size
= 1, p
= env
; p
;)
3743 if ((p
= etags_strchr (p
, ':')) && *(++p
))
3745 /* Add 1 to leave room for null terminator. */
3746 tab
= xnew (size
+ 1, struct TEX_tabent
);
3748 /* Unpack environment string into token table. Be careful about */
3749 /* zero-length strings (leading ':', "::" and trailing ':') */
3752 p
= etags_strchr (env
, ':');
3753 if (!p
) /* End of environment string. */
3754 p
= env
+ strlen (env
);
3756 { /* Only non-zero strings. */
3757 tab
[i
].name
= savenstr (env
, p
- env
);
3758 tab
[i
].len
= strlen (tab
[i
].name
);
3765 tab
[i
].name
= NULL
; /* Mark end of table. */
3773 /* If the text at CP matches one of the tag-defining TeX command names,
3774 return the pointer to the first occurrence of that command in TEX_toktab.
3775 Otherwise return -1.
3776 Keep the capital `T' in `Token' for dumb truncating compilers
3777 (this distinguishes it from `TEX_toktab' */
3784 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
3785 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
3791 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
3793 * Assumes that the predicate starts at column 0.
3794 * Only the first clause of a predicate is added.
3797 void prolog_skip_comment ();
3802 Prolog_functions (inf
)
3820 linecharno
+= charno
;
3821 charno
= readline (&lb
, inf
);
3823 if (dbp
[0] == '\0') /* Empty line */
3825 else if (isspace (dbp
[0])) /* Not a predicate */
3827 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
3828 prolog_skip_comment (&lb
, inf
);
3829 else if (len
= prolog_pred (dbp
, last
))
3831 /* Predicate. Store the function name so that we only
3832 generate a tag for the first clause. */
3834 last
= xnew(len
+ 1, char);
3835 else if (len
+ 1 > allocated
)
3836 last
= (char *) xrealloc(last
, len
+ 1);
3837 allocated
= len
+ 1;
3838 strncpy (last
, dbp
, len
);
3846 prolog_skip_comment (plb
, inf
)
3847 struct linebuffer
*plb
;
3854 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
3855 if (cp
[0] == '*' && cp
[1] == '/')
3858 linecharno
+= readline (plb
, inf
);
3864 * A predicate definition is added if it matches:
3865 * <beginning of line><Prolog Atom><whitespace>(
3867 * It is added to the tags database if it doesn't match the
3868 * name of the previous clause header.
3870 * Return the size of the name of the predicate, or 0 if no header
3874 prolog_pred (s
, last
)
3876 char *last
; /* Name of last clause. */
3881 pos
= prolog_atom (s
, 0);
3886 pos
+= eat_white (s
, pos
);
3888 if ((s
[pos
] == '(') || (s
[pos
] == '.'))
3893 /* Save only the first clause. */
3895 || len
!= strlen (last
)
3896 || !strneq (s
, last
, len
))
3898 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
3899 s
, pos
, lineno
, linecharno
);
3907 * Consume a Prolog atom.
3908 * Return the number of bytes consumed, or -1 if there was an error.
3910 * A prolog atom, in this context, could be one of:
3911 * - An alphanumeric sequence, starting with a lower case letter.
3912 * - A quoted arbitrary string. Single quotes can escape themselves.
3913 * Backslash quotes everything.
3916 prolog_atom (s
, pos
)
3924 if (islower(s
[pos
]) || (s
[pos
] == '_'))
3926 /* The atom is unquoted. */
3928 while (isalnum(s
[pos
]) || (s
[pos
] == '_'))
3932 return pos
- origpos
;
3934 else if (s
[pos
] == '\'')
3945 pos
++; /* A double quote */
3947 else if (s
[pos
] == '\0')
3948 /* Multiline quoted atoms are ignored. */
3950 else if (s
[pos
] == '\\')
3952 if (s
[pos
+1] == '\0')
3959 return pos
- origpos
;
3965 /* Consume whitespace. Return the number of bytes eaten. */
3975 while (isspace (s
[pos
]))
3978 return pos
- origpos
;
3982 * Support for Erlang -- Anders Lindgren, Feb 1996.
3984 * Generates tags for functions, defines, and records.
3986 * Assumes that Erlang functions start at column 0.
3989 void erlang_attribute ();
3993 Erlang_functions (inf
)
4011 linecharno
+= charno
;
4012 charno
= readline (&lb
, inf
);
4014 if (dbp
[0] == '\0') /* Empty line */
4016 else if (isspace (dbp
[0])) /* Not function nor attribute */
4018 else if (dbp
[0] == '%') /* comment */
4020 else if (dbp
[0] == '"') /* Sometimes, strings start in column one */
4022 else if (dbp
[0] == '-') /* attribute, e.g. "-define" */
4024 erlang_attribute (dbp
);
4027 else if (len
= erlang_func (dbp
, last
))
4030 * Function. Store the function name so that we only
4031 * generates a tag for the first clause.
4034 last
= xnew (len
+ 1, char);
4035 else if (len
+ 1 > allocated
)
4036 last
= (char *) xrealloc (last
, len
+ 1);
4037 allocated
= len
+ 1;
4038 strncpy (last
, dbp
, len
);
4046 * A function definition is added if it matches:
4047 * <beginning of line><Erlang Atom><whitespace>(
4049 * It is added to the tags database if it doesn't match the
4050 * name of the previous clause header.
4052 * Return the size of the name of the function, or 0 if no function
4056 erlang_func (s
, last
)
4058 char *last
; /* Name of last clause. */
4063 pos
= erlang_atom (s
, 0);
4068 pos
+= eat_white (s
, pos
);
4070 /* Save only the first clause. */
4073 || len
!= strlen (last
)
4074 || !strneq (s
, last
, len
)))
4076 pfnote ((CTAGS
) ? savenstr (s
, len
) : NULL
, TRUE
,
4077 s
, pos
, lineno
, linecharno
);
4086 * Handle attributes. Currently, tags are generated for defines
4089 * They are on the form:
4090 * -define(foo, bar).
4091 * -define(Foo(M, N), M+N).
4092 * -record(graph, {vtab = notable, cyclic = true}).
4095 erlang_attribute (s
)
4101 if (strneq (s
, "-define", 7) || strneq (s
, "-record", 7))
4103 pos
= 7 + eat_white (s
, pos
);
4104 if (s
[pos
++] == '(')
4106 pos
+= eat_white (s
, pos
);
4107 if (len
= erlang_atom (s
, pos
))
4108 pfnote ((CTAGS
) ? savenstr (& s
[pos
], len
) : NULL
, TRUE
,
4109 s
, pos
+ len
, lineno
, linecharno
);
4117 * Consume an Erlang atom (or variable).
4118 * Return the number of bytes consumed, or -1 if there was an error.
4121 erlang_atom (s
, pos
)
4129 if (isalpha (s
[pos
]) || s
[pos
] == '_')
4131 /* The atom is unquoted. */
4133 while (isalnum (s
[pos
]) || s
[pos
] == '_')
4135 return pos
- origpos
;
4137 else if (s
[pos
] == '\'')
4148 else if (s
[pos
] == '\0')
4149 /* Multiline quoted atoms are ignored. */
4151 else if (s
[pos
] == '\\')
4153 if (s
[pos
+1] == '\0')
4160 return pos
- origpos
;
4166 #ifdef ETAGS_REGEXPS
4167 /* Take a string like "/blah/" and turn it into "blah", making sure
4168 that the first and last characters are the same, and handling
4169 quoted separator characters. Actually, stops on the occurrence of
4170 an unquoted separator. Also turns "\t" into a Tab character.
4171 Returns pointer to terminating separator. Works in place. Null
4172 terminates name string. */
4174 scan_separators (name
)
4178 char *copyto
= name
;
4179 bool quoted
= FALSE
;
4181 for (++name
; *name
!= '\0'; ++name
)
4187 else if (*name
== sep
)
4191 /* Something else is quoted, so preserve the quote. */
4197 else if (*name
== '\\')
4199 else if (*name
== sep
)
4205 /* Terminate copied string. */
4210 /* Look at the argument of --regex or --no-regex and do the right
4213 analyse_regex (regex_arg
)
4216 struct stat stat_buf
;
4218 if (regex_arg
== NULL
)
4220 /* Remove existing regexps. */
4225 if (regex_arg
[0] == '\0')
4227 error ("missing regexp", (char *)NULL
);
4230 if (regex_arg
[0] == '@'
4231 && stat (regex_arg
+ 1, &stat_buf
) == 0)
4234 struct linebuffer regexbuf
;
4235 char *regexfile
= regex_arg
+ 1;
4237 /* regexfile is a file containing regexps, one per line. */
4238 regexfp
= fopen (regexfile
, "r");
4239 if (regexfp
== NULL
)
4244 initbuffer (®exbuf
);
4245 while (readline_internal (®exbuf
, regexfp
))
4246 add_regex (regexbuf
.buffer
);
4247 free (regexbuf
.buffer
);
4252 add_regex (regex_arg
);
4256 /* Turn a name, which is an ed-style (but Emacs syntax) regular
4257 expression, into a real regular expression by compiling it. */
4259 add_regex (regexp_pattern
)
4260 char *regexp_pattern
;
4264 struct re_pattern_buffer
*patbuf
;
4267 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
4269 error ("%s: unterminated regexp", regexp_pattern
);
4272 name
= scan_separators (regexp_pattern
);
4273 if (regexp_pattern
[0] == '\0')
4275 error ("null regexp", (char *)NULL
);
4278 (void) scan_separators (name
);
4280 patbuf
= xnew (1, struct re_pattern_buffer
);
4281 patbuf
->translate
= NULL
;
4282 patbuf
->fastmap
= NULL
;
4283 patbuf
->buffer
= NULL
;
4284 patbuf
->allocated
= 0;
4286 re_syntax_options
= RE_INTERVALS
;
4287 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
4290 error ("%s while compiling pattern", err
);
4295 if (num_patterns
== 1)
4296 patterns
= xnew (1, struct pattern
);
4298 patterns
= ((struct pattern
*)
4300 (num_patterns
* sizeof (struct pattern
))));
4301 patterns
[num_patterns
- 1].pattern
= patbuf
;
4302 patterns
[num_patterns
- 1].name_pattern
= savestr (name
);
4303 patterns
[num_patterns
- 1].error_signaled
= FALSE
;
4307 * Do the substitutions indicated by the regular expression and
4311 substitute (in
, out
, regs
)
4313 struct re_registers
*regs
;
4316 int size
, dig
, diglen
;
4319 size
= strlen (out
);
4321 /* Pass 1: figure out how much to allocate by finding all \N strings. */
4322 if (out
[size
- 1] == '\\')
4323 fatal ("pattern error in \"%s\"", out
);
4324 for (t
= etags_strchr (out
, '\\');
4326 t
= etags_strchr (t
+ 2, '\\'))
4330 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
4336 /* Allocate space and do the substitutions. */
4337 result
= xnew (size
+ 1, char);
4339 for (t
= result
; *out
!= '\0'; out
++)
4340 if (*out
== '\\' && isdigit (*++out
))
4342 /* Using "dig2" satisfies my debugger. Bleah. */
4344 diglen
= regs
->end
[dig
] - regs
->start
[dig
];
4345 strncpy (t
, in
+ regs
->start
[dig
], diglen
);
4352 if (DEBUG
&& (t
> result
+ size
|| t
- result
!= strlen (result
)))
4358 #endif /* ETAGS_REGEXPS */
4359 /* Initialize a linebuffer for use */
4361 initbuffer (linebuffer
)
4362 struct linebuffer
*linebuffer
;
4364 linebuffer
->size
= 200;
4365 linebuffer
->buffer
= xnew (200, char);
4369 * Read a line of text from `stream' into `linebuffer'.
4370 * Return the number of characters read from `stream',
4371 * which is the length of the line including the newline, if any.
4374 readline_internal (linebuffer
, stream
)
4375 struct linebuffer
*linebuffer
;
4376 register FILE *stream
;
4378 char *buffer
= linebuffer
->buffer
;
4379 register char *p
= linebuffer
->buffer
;
4380 register char *pend
;
4383 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
4387 register int c
= getc (stream
);
4390 linebuffer
->size
*= 2;
4391 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
4392 p
+= buffer
- linebuffer
->buffer
;
4393 pend
= buffer
+ linebuffer
->size
;
4394 linebuffer
->buffer
= buffer
;
4404 if (p
> buffer
&& p
[-1] == '\r')
4408 /* Assume CRLF->LF translation will be performed by Emacs
4409 when loading this file, so CRs won't appear in the buffer.
4410 It would be cleaner to compensate within Emacs;
4411 however, Emacs does not know how many CRs were deleted
4412 before any given point in the file. */
4427 linebuffer
->len
= p
- buffer
;
4429 return linebuffer
->len
+ chars_deleted
;
4433 * Like readline_internal, above, but in addition try to match the
4434 * input line against any existing regular expressions.
4437 readline (linebuffer
, stream
)
4438 struct linebuffer
*linebuffer
;
4441 /* Read new line. */
4442 long result
= readline_internal (linebuffer
, stream
);
4443 #ifdef ETAGS_REGEXPS
4446 /* Match against all listed patterns. */
4447 if (linebuffer
->len
> 0)
4448 for (i
= 0; i
< num_patterns
; ++i
)
4450 int match
= re_match (patterns
[i
].pattern
, linebuffer
->buffer
,
4451 linebuffer
->len
, 0, &patterns
[i
].regs
);
4456 if (!patterns
[i
].error_signaled
)
4458 error ("error while matching pattern %d", i
);
4459 patterns
[i
].error_signaled
= TRUE
;
4466 /* Match occurred. Construct a tag. */
4467 if (patterns
[i
].name_pattern
[0] != '\0')
4469 /* Make a named tag. */
4470 char *name
= substitute (linebuffer
->buffer
,
4471 patterns
[i
].name_pattern
,
4475 linebuffer
->buffer
, match
, lineno
, linecharno
);
4479 /* Make an unnamed tag. */
4480 pfnote ((char *)NULL
, TRUE
,
4481 linebuffer
->buffer
, match
, lineno
, linecharno
);
4486 #endif /* ETAGS_REGEXPS */
4492 * Read a file, but do no processing. This is used to do regexp
4493 * matching on files that have no language defined.
4496 just_read_file (inf
)
4505 linecharno
= charno
;
4506 charno
+= readline (&lb
, inf
);
4512 * Return a pointer to a space of size strlen(cp)+1 allocated
4513 * with xnew where the string CP has been copied.
4519 return savenstr (cp
, strlen (cp
));
4523 * Return a pointer to a space of size LEN+1 allocated with xnew where
4524 * the string CP has been copied for at most the first LEN characters.
4533 dp
= xnew (len
+ 1, char);
4534 strncpy (dp
, cp
, len
);
4540 * Return the ptr in sp at which the character c last
4541 * appears; NULL if not found
4543 * Identical to System V strrchr, included for portability.
4546 etags_strrchr (sp
, c
)
4547 register char *sp
, c
;
4562 * Return the ptr in sp at which the character c first
4563 * appears; NULL if not found
4565 * Identical to System V strchr, included for portability.
4568 etags_strchr (sp
, c
)
4569 register char *sp
, c
;
4579 /* Print error message and exit. */
4597 suggest_asking_for_help ()
4599 fprintf (stderr
, "\tTry `%s --help' for a complete list of options.\n",
4604 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
4609 fprintf (stderr
, "%s: ", progname
);
4610 fprintf (stderr
, s1
, s2
);
4611 fprintf (stderr
, "\n");
4614 /* Return a newly-allocated string whose contents
4615 concatenate those of s1, s2, s3. */
4620 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
4621 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
4623 strcpy (result
, s1
);
4624 strcpy (result
+ len1
, s2
);
4625 strcpy (result
+ len1
+ len2
, s3
);
4626 result
[len1
+ len2
+ len3
] = '\0';
4631 /* Does the same work as the system V getcwd, but does not need to
4632 guess the buffer size in advance. */
4638 char *path
= xnew (bufsize
, char);
4640 while (getcwd (path
, bufsize
) == NULL
)
4642 if (errno
!= ERANGE
)
4646 path
= xnew (bufsize
, char);
4651 /* Convert backslashes to slashes. */
4653 for (p
= path
; *p
!= '\0'; p
++)
4661 #else /* not HAVE_GETCWD */
4663 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
4667 for (p
= path
; *p
!= '\0'; p
++)
4673 return strdup (path
);
4674 #else /* not MSDOS */
4675 struct linebuffer path
;
4679 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
4680 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
4685 #endif /* not MSDOS */
4686 #endif /* not HAVE_GETCWD */
4689 /* Return a newly allocated string containing the file name
4690 of FILE relative to the absolute directory DIR (which
4691 should end with a slash). */
4693 relative_filename (file
, dir
)
4696 char *fp
, *dp
, *abs
, *res
;
4699 /* Find the common root of file and dir (with a trailing slash). */
4700 abs
= absolute_filename (file
, cwd
);
4703 while (*fp
++ == *dp
++)
4705 fp
--, dp
--; /* back to the first differing char */
4706 do /* look at the equal chars until '/' */
4710 /* Build a sequence of "../" strings for the resulting relative file name. */
4712 while ((dp
= etags_strchr (dp
+ 1, '/')) != NULL
)
4714 res
= xnew (3*i
+ strlen (fp
+ 1) + 1, char);
4717 strcat (res
, "../");
4719 /* Add the file name relative to the common root of file and dir. */
4720 strcat (res
, fp
+ 1);
4726 /* Return a newly allocated string containing the
4727 absolute file name of FILE given CWD (which should
4728 end with a slash). */
4730 absolute_filename (file
, cwd
)
4733 char *slashp
, *cp
, *res
;
4735 if (absolutefn (file
))
4736 res
= savestr (file
);
4738 /* We don't support non-absolute file names with a drive
4739 letter, like `d:NAME' (it's too much hassle). */
4740 else if (file
[1] == ':')
4741 fatal ("%s: relative file names with drive letters not supported", file
);
4744 res
= concat (cwd
, file
, "");
4746 /* Delete the "/dirname/.." and "/." substrings. */
4747 slashp
= etags_strchr (res
, '/');
4748 while (slashp
!= NULL
&& slashp
[0] != '\0')
4750 if (slashp
[1] == '.')
4752 if (slashp
[2] == '.'
4753 && (slashp
[3] == '/' || slashp
[3] == '\0'))
4758 while (cp
>= res
&& !absolutefn (cp
));
4760 cp
= slashp
; /* the absolute name begins with "/.." */
4762 /* Under MSDOS and NT we get `d:/NAME' as absolute
4763 file name, so the luser could say `d:/../NAME'.
4764 We silently treat this as `d:/NAME'. */
4765 else if (cp
[0] != '/')
4768 strcpy (cp
, slashp
+ 3);
4772 else if (slashp
[2] == '/' || slashp
[2] == '\0')
4774 strcpy (slashp
, slashp
+ 2);
4779 slashp
= etags_strchr (slashp
+ 1, '/');
4783 return savestr ("/");
4788 /* Return a newly allocated string containing the absolute
4789 file name of dir where FILE resides given CWD (which should
4790 end with a slash). */
4792 absolute_dirname (file
, cwd
)
4800 for (p
= file
; *p
!= '\0'; p
++)
4805 slashp
= etags_strrchr (file
, '/');
4807 return savestr (cwd
);
4810 res
= absolute_filename (file
, cwd
);
4816 /* Increase the size of a linebuffer. */
4818 grow_linebuffer (bufp
, toksize
)
4819 struct linebuffer
*bufp
;
4822 while (bufp
->size
< toksize
)
4824 bufp
->buffer
= (char *) xrealloc (bufp
->buffer
, bufp
->size
);
4827 /* Like malloc but get fatal error if memory is exhausted. */
4832 long *result
= (long *) malloc (size
);
4834 fatal ("virtual memory exhausted", (char *)NULL
);
4839 xrealloc (ptr
, size
)
4843 long *result
= (long *) realloc (ptr
, size
);
4845 fatal ("virtual memory exhausted", (char *)NULL
);