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
4 This file is not considered part of GNU Emacs.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 * Ctags originally by Ken Arnold.
23 * Fortran added by Jim Kleckner.
24 * Ed Pelegri-Llopart added C typedefs.
25 * Gnu Emacs TAGS format and modifications by RMS?
26 * Sam Kendall added C++.
27 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey.
32 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer.
35 char pot_etags_version
[] = "@(#) pot revision number is 11.30";
45 #include <sys/param.h>
52 #define MAXPATHLEN _MAX_PATH
57 /* On some systems, Emacs defines static as nothing for the sake
58 of unexec. We don't want that here since we don't use unexec. */
68 #include <sys/types.h>
71 #if !defined (S_ISREG) && defined (S_IFREG)
72 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
79 #endif /* ETAGS_REGEXPS */
81 /* Define CTAGS to make the program "ctags" compatible with the usual one.
82 Let it undefined to make the program "etags", which makes emacs-style
83 tag tables and tags typedefs, #defines and struct/union/enum by default. */
91 /* Exit codes for success and failure. */
101 #define C_PLPL 0x00001 /* C++ */
102 #define C_STAR 0x00003 /* C* */
103 #define YACC 0x10000 /* yacc file */
105 #define streq(s,t) (strcmp (s, t) == 0)
106 #define strneq(s,t,n) (strncmp (s, t, n) == 0)
108 #define lowcase(c) ((c) | ' ')
110 #define iswhite(arg) (_wht[arg]) /* T if char is white */
111 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
112 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
113 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
116 # define absolutefn(fn) (fn[0] == '/' || (isalpha (fn[0]) && fn[1] == ':'))
118 # define absolutefn(fn) (fn[0] == '/')
123 * xnew -- allocate storage
125 * SYNOPSIS: Type *xnew (int n, Type);
127 #define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
132 { /* sorting structure */
133 char *name
; /* function or type name */
134 char *file
; /* file name */
135 logical is_func
; /* use pattern or line no */
136 logical named
; /* list name separately */
137 logical been_warned
; /* set if noticed dup */
138 int lno
; /* line number tag is on */
139 long cno
; /* character number line starts on */
140 char *pat
; /* search pattern */
141 struct nd_st
*left
, *right
; /* left and right sons */
144 extern char *getenv ();
147 char *savenstr (), *savestr ();
148 char *etags_strchr (), *etags_strrchr ();
149 char *etags_getcwd ();
150 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
151 long *xmalloc (), *xrealloc ();
153 typedef void Lang_function ();
154 #if FALSE /* many compilers barf on this */
155 Lang_function Asm_labels
;
156 Lang_function default_C_entries
;
157 Lang_function C_entries
;
158 Lang_function Cplusplus_entries
;
159 Lang_function Cstar_entries
;
160 Lang_function Fortran_functions
;
161 Lang_function Yacc_entries
;
162 Lang_function Lisp_functions
;
163 Lang_function Pascal_functions
;
164 Lang_function Prolog_functions
;
165 Lang_function Scheme_functions
;
166 Lang_function TeX_functions
;
167 Lang_function just_read_file
;
168 #else /* so let's write it this way */
171 void default_C_entries ();
172 void plain_C_entries ();
173 void Cplusplus_entries ();
174 void Cstar_entries ();
175 void Fortran_functions ();
176 void Yacc_entries ();
177 void Lisp_functions ();
178 void Pascal_functions ();
179 void Prolog_functions ();
180 void Scheme_functions ();
181 void TeX_functions ();
182 void just_read_file ();
185 logical
get_language ();
186 int total_size_of_entries ();
188 long readline_internal ();
194 void fatal (), pfatal ();
195 void find_entries ();
201 void process_file ();
206 char searchar
= '/'; /* use /.../ searches */
208 int lineno
; /* line number of current line */
209 long charno
; /* current character number */
211 long linecharno
; /* charno of start of line; not used by C,
212 but by every other language. */
214 char *curfile
; /* current input file name */
215 char *tagfile
; /* output file */
216 char *progname
; /* name this program was invoked with */
217 char *cwd
; /* current working directory */
218 char *tagfiledir
; /* directory of tagfile */
220 FILE *tagf
; /* ioptr for tags file */
221 NODE
*head
; /* the head of the binary tree of tags */
224 * A `struct linebuffer' is a structure which holds a line of text.
225 * `readline' reads a line from a stream into a linebuffer and works
226 * regardless of the length of the line.
234 struct linebuffer lb
; /* the current line */
235 struct linebuffer token_name
; /* used by C_entries as temporary area */
239 struct linebuffer lb
; /* used by C_entries instead of lb */
242 /* boolean "functions" (see init) */
243 logical _wht
[0177], _etk
[0177], _itk
[0177], _btk
[0177];
245 *white
= " \f\t\n\013", /* white chars */
246 *endtk
= " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */
247 /* token starting chars */
248 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~",
249 /* valid in-token chars */
250 *intk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
252 logical append_to_tagfile
; /* -a: append to tags */
253 /* The following three default to TRUE for etags, but to FALSE for ctags. */
254 logical typedefs
; /* -t: create tags for typedefs */
255 logical typedefs_and_cplusplus
; /* -T: create tags for typedefs, level */
256 /* 0 struct/enum/union decls, and C++ */
257 /* member functions. */
258 logical constantypedefs
; /* -d: create tags for C #define and enum */
259 /* constants. Enum consts not implemented. */
260 /* -D: opposite of -d. Default under ctags. */
261 logical update
; /* -u: update tags */
262 logical vgrind_style
; /* -v: create vgrind style index output */
263 logical no_warnings
; /* -w: suppress warnings */
264 logical cxref_style
; /* -x: create cxref style output */
265 logical cplusplus
; /* .[hc] means C++, not C */
266 logical noindentypedefs
; /* -I: ignore indentation in C */
267 #define permit_duplicates TRUE /* allow duplicate tags */
269 struct option longopts
[] =
271 { "append", no_argument
, NULL
, 'a' },
272 { "backward-search", no_argument
, NULL
, 'B' },
273 { "c++", no_argument
, NULL
, 'C' },
274 { "cxref", no_argument
, NULL
, 'x' },
275 { "defines", no_argument
, NULL
, 'd' },
276 { "help", no_argument
, NULL
, 'h' },
277 { "help", no_argument
, NULL
, 'H' },
278 { "ignore-indentation", no_argument
, NULL
, 'I' },
279 { "include", required_argument
, NULL
, 'i' },
280 { "language", required_argument
, NULL
, 'l' },
281 { "no-defines", no_argument
, NULL
, 'D' },
282 { "no-regex", no_argument
, NULL
, 'R' },
283 { "no-warn", no_argument
, NULL
, 'w' },
284 { "output", required_argument
, NULL
, 'o' },
285 { "regex", required_argument
, NULL
, 'r' },
286 { "typedefs", no_argument
, NULL
, 't' },
287 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
288 { "update", no_argument
, NULL
, 'u' },
289 { "version", no_argument
, NULL
, 'V' },
290 { "vgrind", no_argument
, NULL
, 'v' },
295 /* Structure defining a regular expression. Elements are
296 the compiled pattern, and the name string. */
299 struct re_pattern_buffer
*pattern
;
300 struct re_registers regs
;
302 logical error_signaled
;
305 /* Number of regexps found. */
306 int num_patterns
= 0;
308 /* Array of all regexps. */
309 struct pattern
*patterns
= NULL
;
310 #endif /* ETAGS_REGEXPS */
312 /* Language stuff. */
316 Lang_function
*function
;
319 /* Table of language names and corresponding functions. */
320 /* It is ok for a given function to be listed under more than one
321 name. I just didn't. */
322 /* "auto" language reverts to default behavior. */
323 struct lang_entry lang_names
[] =
325 { "asm", Asm_labels
},
326 { "c", default_C_entries
},
327 { "c++", Cplusplus_entries
},
328 { "c*", Cstar_entries
},
329 { "fortran", Fortran_functions
},
330 { "lisp", Lisp_functions
},
331 { "none", just_read_file
},
332 { "pascal", Pascal_functions
},
333 { "scheme" , Scheme_functions
},
334 { "tex", TeX_functions
},
339 /* Table of file name suffixes and corresponding language functions. */
340 struct lang_entry lang_suffixes
[] =
342 /* Assume that ".s" or ".a" is assembly code. -wolfgang.
344 { "a", Asm_labels
}, /* Unix assembler */
345 { "asm", Asm_labels
}, /* Microcontroller assembly */
346 { "def", Asm_labels
}, /* BSO/Tasking definition includes */
347 { "inc", Asm_labels
}, /* Microcontroller include files */
348 { "ins", Asm_labels
}, /* Microcontroller include files */
350 { "sa", Asm_labels
}, /* Unix assembler */
351 { "src", Asm_labels
}, /* BSO/Tasking C compiler output */
353 /* .aux, .bbl, .clo, .cls, .dtx or .tex implies LaTeX source code. */
354 { "aux", TeX_functions
},
355 { "bbl", TeX_functions
},
356 { "clo", TeX_functions
},
357 { "cls", TeX_functions
},
358 { "dtx", TeX_functions
},
359 { "sty", TeX_functions
},
360 { "tex", TeX_functions
},
362 /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
363 { "cl", Lisp_functions
},
364 { "clisp", Lisp_functions
},
365 { "el", Lisp_functions
},
366 { "l", Lisp_functions
},
367 { "lisp", Lisp_functions
},
368 { "lsp", Lisp_functions
},
370 /* .scm or .sm or .scheme implies scheme source code */
371 { "SCM", Scheme_functions
},
372 { "SM", Scheme_functions
},
373 { "oak", Scheme_functions
},
374 { "sch", Scheme_functions
},
375 { "scheme", Scheme_functions
},
376 { "scm", Scheme_functions
},
377 { "sm", Scheme_functions
},
378 { "t", Scheme_functions
},
379 /* FIXME Can't do the `SCM' or `scm' prefix with a version number */
381 /* Note that .c and .h can be considered C++, if the --c++ flag was
382 given. That is why default_C_entries is called here. */
383 { "c", default_C_entries
},
384 { "h", default_C_entries
},
386 /* .pc is a Pro*C file. */
387 { "pc", plain_C_entries
},
389 /* .C or .H or .c++ or .cc or .cpp or .cxx or .h++ or .hh or .hxx:
391 { "C", Cplusplus_entries
},
392 { "H", Cplusplus_entries
},
393 { "c++", Cplusplus_entries
},
394 { "cc", Cplusplus_entries
},
395 { "cpp", Cplusplus_entries
},
396 { "cxx", Cplusplus_entries
},
397 { "h++", Cplusplus_entries
},
398 { "hh", Cplusplus_entries
},
399 { "hxx", Cplusplus_entries
},
401 /* .y: a yacc file */
402 { "y", Yacc_entries
},
404 /* .cs or .hs: a C* file */
405 { "cs", Cstar_entries
},
406 { "hs", Cstar_entries
},
408 /* .F, .f and .for are FORTRAN. */
409 { "F", Fortran_functions
},
410 { "f", Fortran_functions
},
411 { "for", Fortran_functions
},
413 /* .pl implies prolog source code */
414 { "pl", Prolog_functions
},
416 /* .p or .pas: a Pascal file */
417 { "p", Pascal_functions
},
418 { "pas", Pascal_functions
},
423 /* Non-NULL if language fixed. */
424 Lang_function
*lang_func
= NULL
;
428 print_language_names ()
430 struct lang_entry
*name
, *ext
;
432 puts ("\nThese are the currently supported languages, along with the\n\
433 default file name suffixes:");
434 for (name
= lang_names
; name
->suffix
; ++name
)
436 printf ("\t%s\t", name
->suffix
);
437 for (ext
= lang_suffixes
; ext
->suffix
; ++ext
)
438 if (name
->function
== ext
->function
)
439 printf (" .%s", ext
->suffix
);
442 puts ("Where `auto' means use default language for files based on file\n\
443 name suffix, and `none' means only do regexp processing on files.\n\
444 If no language is specified and no matching suffix is found,\n\
445 Fortran is tried first; if no tags are found, C is tried next.");
452 printf ("%s for Emacs version %s.\n", (CTAGS
) ? "CTAGS" : "ETAGS", VERSION
);
454 printf ("%s for Emacs version 19.\n", (CTAGS
) ? "CTAGS" : "ETAGS");
463 printf ("These are the options accepted by %s. You may use unambiguous\n\
464 abbreviations for the long option names. A - as file name means read\n\
465 names from stdin.\n\n", progname
);
467 puts ("-a, --append\n\
468 Append tag entries to existing tags file.");
471 puts ("-B, --backward-search\n\
472 Write the search commands for the tag entries using '?', the\n\
473 backward-search command instead of '/', the forward-search command.");
476 Treat files whose name suffix defaults to C language as C++ files.");
479 puts ("-d, --defines\n\
480 Create tag entries for constant C #defines, too.");
482 puts ("-D, --no-defines\n\
483 Don't create tag entries for constant C #defines. This makes\n\
484 the tags file smaller.");
488 puts ("-i FILE, --include=FILE\n\
489 Include a note in tag file indicating that, when searching for\n\
490 a tag, one should also consult the tags file FILE after\n\
491 checking the current file.");
492 puts ("-l LANG, --language=LANG\n\
493 Force the following files to be considered as written in the\n\
494 named language up to the next --language=LANG option.");
498 puts ("-r /REGEXP/, --regex=/REGEXP/\n\
499 Make a tag for each line matching pattern REGEXP in the\n\
500 following files. REGEXP is anchored (as if preceded by ^).\n\
501 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
502 named tags can be created with:\n\
503 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
504 puts ("-R, --no-regex\n\
505 Don't create tags from regexps for the following files.");
506 #endif /* ETAGS_REGEXPS */
507 puts ("-o FILE, --output=FILE\n\
508 Write the tags to FILE.");
509 puts ("-I, --ignore-indentation\n\
510 Don't rely on indentation quite as much as normal. Currently,\n\
511 this means not to assume that a closing brace in the first\n\
512 column is the final brace of a function or structure\n\
513 definition in C and C++.");
517 puts ("-t, --typedefs\n\
518 Generate tag entries for C typedefs.");
519 puts ("-T, --typedefs-and-c++\n\
520 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
521 and C++ member functions.");
522 puts ("-u, --update\n\
523 Update the tag entries for the given files, leaving tag\n\
524 entries for other files in place. Currently, this is\n\
525 implemented by deleting the existing entries for the given\n\
526 files and then rewriting the new entries at the end of the\n\
527 tags file. It is often faster to simply rebuild the entire\n\
528 tag file than to use this.");
529 puts ("-v, --vgrind\n\
530 Generates an index of items intended for human consumption,\n\
531 similar to the output of vgrind. The index is sorted, and\n\
532 gives the page number of each item.");
533 puts ("-w, --no-warn\n\
534 Suppress warning messages about entries defined in multiple\n\
536 puts ("-x, --cxref\n\
537 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
538 The output uses line numbers instead of page numbers, but\n\
539 beyond that the differences are cosmetic; try both to see\n\
543 puts ("-V, --version\n\
544 Print the version of the program.\n\
546 Print this help message.");
548 print_language_names ();
561 /* This structure helps us allow mixing of --lang and filenames. */
564 enum argument_type arg_type
;
566 Lang_function
*function
;
569 #ifdef VMS /* VMS specific functions */
573 /* This is a BUG! ANY arbitrary limit is a BUG!
574 Won't someone please fix this? */
575 #define MAX_FILE_SPEC_LEN 255
578 char body
[MAX_FILE_SPEC_LEN
+ 1];
582 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
583 returning in each successive call the next filename matching the input
584 spec. The function expects that each in_spec passed
585 to it will be processed to completion; in particular, up to and
586 including the call following that in which the last matching name
587 is returned, the function ignores the value of in_spec, and will
588 only start processing a new spec with the following call.
589 If an error occurs, on return out_spec contains the value
590 of in_spec when the error occurred.
592 With each successive filename returned in out_spec, the
593 function's return value is one. When there are no more matching
594 names the function returns zero. If on the first call no file
595 matches in_spec, or there is any other error, -1 is returned.
600 #define OUTSIZE MAX_FILE_SPEC_LEN
606 static long context
= 0;
607 static struct dsc$descriptor_s o
;
608 static struct dsc$descriptor_s i
;
609 static logical pass1
= TRUE
;
616 o
.dsc$a_pointer
= (char *) out
;
617 o
.dsc$w_length
= (short)OUTSIZE
;
618 i
.dsc$a_pointer
= in
;
619 i
.dsc$w_length
= (short)strlen(in
);
620 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
621 i
.dsc$b_class
= DSC$K_CLASS_S
;
622 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
623 o
.dsc$b_class
= DSC$K_CLASS_VS
;
625 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
627 out
->body
[out
->curlen
] = EOS
;
630 else if (status
== RMS$_NMF
)
634 strcpy(out
->body
, in
);
637 lib$
find_file_end(&context
);
643 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
644 name of each file specified by the provided arg expanding wildcards.
647 gfnames (arg
, p_error
)
651 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
653 switch (fn_exp (&filename
, arg
))
657 return filename
.body
;
663 return filename
.body
;
667 #ifndef OLD /* Newer versions of VMS do provide `system'. */
671 fprintf (stderr
, "system() function not implemented under VMS\n");
675 #define VERSION_DELIM ';'
676 char *massage_name (s
)
682 if (*s
== VERSION_DELIM
)
700 unsigned int nincluded_files
= 0;
701 char **included_files
= xnew (argc
, char *);
704 int current_arg
= 0, file_count
= 0;
705 struct linebuffer filename_lb
;
711 _fmode
= O_BINARY
; /* all of files are treated as binary files */
716 /* Allocate enough no matter what happens. Overkill, but each one
718 argbuffer
= xnew (argc
, ARGUMENT
);
721 /* Set syntax for regular expression routines. */
722 re_set_syntax (RE_SYNTAX_EMACS
);
723 #endif /* ETAGS_REGEXPS */
726 * If etags, always find typedefs and structure tags. Why not?
727 * Also default is to find macro constants.
730 typedefs
= typedefs_and_cplusplus
= constantypedefs
= TRUE
;
734 int opt
= getopt_long (argc
, argv
,
735 "-aCdDf:Il:o:r:RStTi:BuvxwVhH", longopts
, 0);
743 /* If getopt returns 0, then it has already processed a
744 long-named option. We should do nothing. */
748 /* This means that a filename has been seen. Record it. */
749 argbuffer
[current_arg
].arg_type
= at_filename
;
750 argbuffer
[current_arg
].what
= optarg
;
755 /* Common options. */
757 append_to_tagfile
= TRUE
;
763 constantypedefs
= TRUE
;
766 constantypedefs
= FALSE
;
768 case 'f': /* for compatibility with old makefiles */
772 fprintf (stderr
, "%s: -%c option may only be given once.\n",
779 case 'S': /* for backward compatibility */
780 noindentypedefs
= TRUE
;
783 if (!get_language (optarg
, &argbuffer
[current_arg
].function
))
785 fprintf (stderr
, "%s: language \"%s\" not recognized.\n",
789 argbuffer
[current_arg
].arg_type
= at_language
;
794 argbuffer
[current_arg
].arg_type
= at_regexp
;
795 argbuffer
[current_arg
].what
= optarg
;
799 argbuffer
[current_arg
].arg_type
= at_regexp
;
800 argbuffer
[current_arg
].what
= NULL
;
803 #endif /* ETAGS_REGEXPS */
815 typedefs
= typedefs_and_cplusplus
= TRUE
;
820 included_files
[nincluded_files
++] = optarg
;
845 for (; optind
< argc
; ++optind
)
847 argbuffer
[current_arg
].arg_type
= at_filename
;
848 argbuffer
[current_arg
].what
= argv
[optind
];
853 if (nincluded_files
== 0 && file_count
== 0)
855 fprintf (stderr
, "%s: No input files specified.\n", progname
);
858 fprintf (stderr
, "\tTry `%s --help' for a complete list of options.\n",
865 tagfile
= CTAGS
? "tags" : "TAGS";
867 cwd
= etags_getcwd (); /* the current working directory */
869 if (streq (tagfile
, "-"))
875 tagfiledir
= absolute_dirname (tagfile
, cwd
);
878 init (); /* set up boolean "functions" */
881 initbuffer (&token_name
);
882 initbuffer (&lbs
[0].lb
);
883 initbuffer (&lbs
[1].lb
);
884 initbuffer (&filename_lb
);
888 if (streq (tagfile
, "-"))
891 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
897 * Loop through files finding functions.
899 for (i
= 0; i
< current_arg
; ++i
)
901 switch (argbuffer
[i
].arg_type
)
904 lang_func
= argbuffer
[i
].function
;
908 add_regex (argbuffer
[i
].what
);
913 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
917 error ("Can't find file %s\n", this_file
);
922 this_file
= massage_name (this_file
);
925 this_file
= argbuffer
[i
].what
;
927 /* Input file named "-" means read file names from stdin
929 if (streq (this_file
, "-"))
930 while (readline_internal (&filename_lb
, stdin
) > 0)
931 process_file (filename_lb
.buffer
);
933 process_file (this_file
);
943 while (nincluded_files
-- > 0)
944 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
950 /* If CTAGS, we are here. process_file did not write the tags yet,
951 because we want them ordered. Let's do it now. */
954 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
964 for (i
= 0; i
< current_arg
; ++i
)
966 if (argbuffer
[i
].arg_type
!= at_filename
)
969 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
970 tagfile
, argbuffer
[i
].what
, tagfile
);
971 if (system (cmd
) != GOOD
)
972 fatal ("failed to execute shell command");
974 append_to_tagfile
= TRUE
;
977 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
986 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
994 * Set the language, given the name.
997 get_language (language
, func
)
999 Lang_function
**func
;
1001 struct lang_entry
*lang
;
1003 for (lang
= lang_names
; lang
->suffix
; ++lang
)
1005 if (streq (language
, lang
->suffix
))
1007 *func
= lang
->function
;
1017 * This routine is called on each file argument.
1023 struct stat stat_buf
;
1026 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
1028 fprintf (stderr
, "Skipping %s: it is not a regular file.\n", file
);
1031 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1033 fprintf (stderr
, "Skipping inclusion of %s in self.\n", file
);
1036 inf
= fopen (file
, "r");
1043 find_entries (file
, inf
);
1049 if (absolutefn (file
))
1051 /* file is an absolute filename. Canonicalise it. */
1052 filename
= absolute_filename (file
, cwd
);
1056 /* file is a filename relative to cwd. Make it relative
1057 to the directory of the tags file. */
1058 filename
= relative_filename (file
, tagfiledir
);
1060 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1069 * This routine sets up the boolean pseudo-functions which work
1070 * by setting boolean flags dependent upon the corresponding character
1071 * Every char which is NOT in that string is not a white char. Therefore,
1072 * all of the array "_wht" is set to FALSE, and then the elements
1073 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1074 * of a char is TRUE if it is the string "white", else FALSE.
1082 for (i
= 0; i
< 0177; i
++)
1083 _wht
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
1084 for (sp
= white
; *sp
; sp
++)
1086 for (sp
= endtk
; *sp
; sp
++)
1088 for (sp
= intk
; *sp
; sp
++)
1090 for (sp
= begtk
; *sp
; sp
++)
1092 _wht
[0] = _wht
['\n'];
1093 _etk
[0] = _etk
['\n'];
1094 _btk
[0] = _btk
['\n'];
1095 _itk
[0] = _itk
['\n'];
1099 * This routine opens the specified file and calls the function
1100 * which finds the function and type definitions.
1103 find_entries (file
, inf
)
1108 struct lang_entry
*lang
;
1109 NODE
*old_last_node
;
1110 extern NODE
*last_node
;
1112 curfile
= savestr (file
);
1113 cp
= etags_strrchr (file
, '.');
1115 /* If user specified a language, use it. */
1116 if (lang_func
!= NULL
)
1126 for (lang
= lang_suffixes
; lang
->suffix
; ++lang
)
1128 if (streq (cp
, lang
->suffix
))
1130 lang
->function (inf
);
1138 old_last_node
= last_node
;
1139 Fortran_functions (inf
);
1141 /* No Fortran entries found. Try C. */
1142 if (old_last_node
== last_node
)
1145 default_C_entries (inf
);
1152 pfnote (name
, is_func
, named
, linestart
, linelen
, lno
, cno
)
1153 char *name
; /* tag name */
1154 logical is_func
; /* tag is a function */
1155 logical named
; /* tag different from text of definition */
1156 char *linestart
; /* start of the line where tag is */
1157 int linelen
; /* length of the line where tag is */
1158 int lno
; /* line number */
1159 long cno
; /* character number */
1161 register NODE
*np
= xnew (1, NODE
);
1164 /* If ctags mode, change name "main" to M<thisfilename>. */
1165 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1167 fp
= etags_strrchr (curfile
, '/');
1168 np
->name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
1169 fp
= etags_strrchr (np
->name
, '.');
1170 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
1179 np
->been_warned
= FALSE
;
1181 np
->is_func
= is_func
;
1183 /* Our char numbers are 0-base, because of C language tradition?
1184 ctags compatibility? old versions compatibility? I don't know.
1185 Anyway, since emacs's are 1-base we espect etags.el to take care
1186 of the difference. If we wanted to have 1-based numbers, we would
1187 uncomment the +1 below. */
1188 np
->cno
= cno
/* + 1 */ ;
1189 np
->left
= np
->right
= NULL
;
1190 np
->pat
= savenstr (linestart
, ((CTAGS
&& !cxref_style
) ? 50 : linelen
));
1192 add_node (np
, &head
);
1197 * recurse on left children, iterate on right children.
1201 register NODE
*node
;
1205 register NODE
*node_right
= node
->right
;
1206 free_tree (node
->left
);
1210 free ((char *) node
);
1217 * Adds a node to the tree of nodes. In etags mode, we don't keep
1218 * it sorted; we just keep a linear list. In ctags mode, maintain
1219 * an ordered tree, with no attempt at balancing.
1221 * add_node is the only function allowed to add nodes, so it can
1224 NODE
*last_node
= NULL
;
1226 add_node (node
, cur_node_p
)
1227 NODE
*node
, **cur_node_p
;
1230 register NODE
*cur_node
= *cur_node_p
;
1232 if (cur_node
== NULL
)
1242 if (last_node
== NULL
)
1243 fatal ("internal error in add_node", 0);
1244 last_node
->right
= node
;
1250 dif
= strcmp (node
->name
, cur_node
->name
);
1253 * If this tag name matches an existing one, then
1254 * do not add the node, but maybe print a warning.
1258 if (node
->file
== cur_node
->file
)
1262 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1263 node
->file
, lineno
, node
->name
);
1264 fprintf (stderr
, "Second entry ignored\n");
1268 if (!cur_node
->been_warned
&& !no_warnings
)
1271 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1272 node
->file
, cur_node
->file
, node
->name
);
1274 cur_node
->been_warned
= TRUE
;
1278 /* Maybe refuse to add duplicate nodes. */
1279 if (!permit_duplicates
)
1281 if (streq (node
->name
, cur_node
->name
)
1282 && streq (node
->file
, cur_node
->file
))
1286 /* Actually add the node */
1287 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1293 register NODE
*node
;
1300 /* Output subentries that precede this one */
1301 put_entries (node
->left
);
1303 /* Output this entry */
1309 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1310 node
->pat
, node
->name
,
1311 node
->lno
, node
->cno
);
1315 fprintf (tagf
, "%s\177%d,%d\n",
1317 node
->lno
, node
->cno
);
1320 else if (!cxref_style
)
1322 fprintf (tagf
, "%s\t%s\t",
1323 node
->name
, node
->file
);
1327 putc (searchar
, tagf
);
1330 for (sp
= node
->pat
; *sp
; sp
++)
1332 if (*sp
== '\\' || *sp
== searchar
)
1336 putc (searchar
, tagf
);
1339 { /* a typedef; text pattern inadequate */
1340 fprintf (tagf
, "%d", node
->lno
);
1344 else if (vgrind_style
)
1345 fprintf (stdout
, "%s %s %d\n",
1346 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1348 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1349 node
->name
, node
->lno
, node
->file
, node
->pat
);
1351 /* Output subentries that follow this one */
1352 put_entries (node
->right
);
1355 /* Length of a number's decimal representation. */
1363 for (; num
; num
/= 10)
1369 * Return total number of characters that put_entries will output for
1370 * the nodes in the subtree of the specified node. Works only if
1371 * we are not ctags, but called only in that case. This count
1372 * is irrelevant with the new tags.el, but is still supplied for
1373 * backward compatibility.
1376 total_size_of_entries (node
)
1377 register NODE
*node
;
1385 for (; node
; node
= node
->right
)
1387 /* Count left subentries. */
1388 total
+= total_size_of_entries (node
->left
);
1390 /* Count this entry */
1391 total
+= strlen (node
->pat
) + 1;
1392 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1394 total
+= 1 + strlen (node
->name
); /* \001name */
1401 * The C symbol tables.
1405 st_none
, st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1408 /* Feed stuff between (but not including) %[ and %] lines to:
1409 gperf -c -k1,3 -o -p -r -t
1411 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1413 class, C_PLPL, st_C_struct
1414 domain, C_STAR, st_C_struct
1415 union, 0, st_C_struct
1416 struct, 0, st_C_struct
1418 typedef, 0, st_C_typedef
1419 define, 0, st_C_define
1420 long, 0, st_C_typespec
1421 short, 0, st_C_typespec
1422 int, 0, st_C_typespec
1423 char, 0, st_C_typespec
1424 float, 0, st_C_typespec
1425 double, 0, st_C_typespec
1426 signed, 0, st_C_typespec
1427 unsigned, 0, st_C_typespec
1428 auto, 0, st_C_typespec
1429 void, 0, st_C_typespec
1430 extern, 0, st_C_typespec
1431 static, 0, st_C_typespec
1432 const, 0, st_C_typespec
1433 volatile, 0, st_C_typespec
1435 and replace lines between %< and %> with its output. */
1437 /* C code produced by gperf version 1.8.1 (K&R C version) */
1438 /* Command-line: gperf -c -k1,3 -o -p -r -t */
1441 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1443 #define MIN_WORD_LENGTH 3
1444 #define MAX_WORD_LENGTH 8
1445 #define MIN_HASH_VALUE 10
1446 #define MAX_HASH_VALUE 62
1449 53 is the maximum key range
1457 static unsigned char hash_table
[] =
1459 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1460 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1461 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1462 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1463 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1464 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1465 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1466 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1467 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1468 62, 62, 62, 62, 62, 62, 62, 2, 62, 7,
1469 6, 9, 15, 30, 62, 24, 62, 62, 1, 24,
1470 7, 27, 13, 62, 19, 26, 18, 27, 1, 62,
1471 62, 62, 62, 62, 62, 62, 62, 62,
1473 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1476 struct C_stab_entry
*
1477 in_word_set (str
, len
)
1482 static struct C_stab_entry wordlist
[] =
1484 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1486 {"volatile", 0, st_C_typespec
},
1488 {"long", 0, st_C_typespec
},
1489 {"char", 0, st_C_typespec
},
1490 {"class", C_PLPL
, st_C_struct
},
1491 {"",}, {"",}, {"",}, {"",},
1492 {"const", 0, st_C_typespec
},
1493 {"",}, {"",}, {"",}, {"",},
1494 {"auto", 0, st_C_typespec
},
1496 {"define", 0, st_C_define
},
1498 {"void", 0, st_C_typespec
},
1499 {"",}, {"",}, {"",},
1500 {"extern", 0, st_C_typespec
},
1501 {"static", 0, st_C_typespec
},
1503 {"domain", C_STAR
, st_C_struct
},
1505 {"typedef", 0, st_C_typedef
},
1506 {"double", 0, st_C_typespec
},
1507 {"enum", 0, st_C_enum
},
1508 {"",}, {"",}, {"",}, {"",},
1509 {"int", 0, st_C_typespec
},
1511 {"float", 0, st_C_typespec
},
1512 {"",}, {"",}, {"",},
1513 {"struct", 0, st_C_struct
},
1514 {"",}, {"",}, {"",}, {"",},
1515 {"union", 0, st_C_struct
},
1517 {"short", 0, st_C_typespec
},
1519 {"unsigned", 0, st_C_typespec
},
1520 {"signed", 0, st_C_typespec
},
1523 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1525 register int key
= hash (str
, len
);
1527 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1529 register char *s
= wordlist
[key
].name
;
1531 if (*s
== *str
&& strneq (str
+ 1, s
+ 1, len
- 1))
1532 return &wordlist
[key
];
1540 C_symtype(str
, len
, c_ext
)
1545 register struct C_stab_entry
*se
= in_word_set(str
, len
);
1547 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1553 * C functions are recognized using a simple finite automaton.
1554 * funcdef is its state variable.
1558 fnone
, /* nothing seen */
1559 ftagseen
, /* function-like tag seen */
1560 fstartlist
, /* just after open parenthesis */
1561 finlist
, /* in parameter list */
1562 flistseen
, /* after parameter list */
1563 fignore
/* before open brace */
1569 * typedefs are recognized using a simple finite automaton.
1570 * typeddef is its state variable.
1574 tnone
, /* nothing seen */
1575 ttypedseen
, /* typedef keyword seen */
1576 tinbody
, /* inside typedef body */
1577 tend
, /* just before typedef tag */
1578 tignore
/* junk after typedef tag */
1584 * struct-like structures (enum, struct and union) are recognized
1585 * using another simple finite automaton. `structdef' is its state
1590 snone
, /* nothing seen yet */
1591 skeyseen
, /* struct-like keyword seen */
1592 stagseen
, /* struct-like tag seen */
1593 scolonseen
, /* colon seen after struct-like tag */
1594 sinbody
/* in struct body: recognize member func defs*/
1599 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1600 * struct tag, and structtype is the type of the preceding struct-like
1603 char *structtag
= "<uninited>";
1604 enum sym_type structtype
;
1607 * Yet another little state machine to deal with preprocessor lines.
1611 dnone
, /* nothing seen */
1612 dsharpseen
, /* '#' seen as first char on line */
1613 ddefineseen
, /* '#' and 'define' seen */
1614 dignorerest
/* ignore rest of line */
1619 * Set this to TRUE, and the next token considered is called a function.
1620 * Used only for GNU emacs's function-defining macros.
1622 logical next_token_is_func
;
1625 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1631 * checks to see if the current token is at the start of a
1632 * function, or corresponds to a typedef, or is a struct/union/enum
1635 * *IS_FUNC gets TRUE iff the token is a function or macro with args.
1636 * C_EXT is which language we are looking at.
1638 * In the future we will need some way to adjust where the end of
1639 * the token is; for instance, implementing the C++ keyword
1640 * `operator' properly will adjust the end of the token to be after
1641 * whatever follows `operator'.
1648 * next_token_is_func IN OUT
1652 consider_token (str
, len
, c
, c_ext
, cblev
, is_func
)
1653 register char *str
; /* IN: token pointer */
1654 register int len
; /* IN: token length */
1655 register char c
; /* IN: first char after the token */
1656 int c_ext
; /* IN: C extensions mask */
1657 int cblev
; /* IN: curly brace level */
1658 logical
*is_func
; /* OUT: function found */
1660 enum sym_type toktype
= C_symtype (str
, len
, c_ext
);
1663 * Advance the definedef state machine.
1668 /* We're not on a preprocessor line. */
1671 if (toktype
== st_C_define
)
1673 definedef
= ddefineseen
;
1677 definedef
= dignorerest
;
1682 * Make a tag for any macro, unless it is a constant
1683 * and constantypedefs is FALSE.
1685 definedef
= dignorerest
;
1686 *is_func
= (c
== '(');
1687 if (!*is_func
&& !constantypedefs
)
1694 error ("internal error: definedef value.", 0);
1703 if (toktype
== st_C_typedef
)
1706 typdef
= ttypedseen
;
1722 /* Do not return here, so the structdef stuff has a chance. */
1736 * This structdef business is currently only invoked when cblev==0.
1737 * It should be recursively invoked whatever the curly brace level,
1738 * and a stack of states kept, to allow for definitions of structs
1741 * This structdef business is NOT invoked when we are ctags and the
1742 * file is plain C. This is because a struct tag may have the same
1743 * name as another tag, and this loses with ctags.
1745 * This if statement deals with the typdef state machine as
1746 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1747 * return FALSE. All the other code here is for the structdef
1754 if (typdef
== ttypedseen
1755 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
1757 structdef
= skeyseen
;
1758 structtype
= toktype
;
1762 if (structdef
== skeyseen
)
1764 /* Save the tag for struct/union/class, for functions that may be
1766 if (structtype
== st_C_struct
)
1767 structtag
= savenstr (str
, len
);
1769 structtag
= "<enum>";
1770 structdef
= stagseen
;
1774 /* Avoid entering funcdef stuff if typdef is going on. */
1775 if (typdef
!= tnone
)
1781 /* Detect GNU macros. */
1782 if (definedef
== dnone
)
1783 if (strneq (str
, "DEFUN", len
) /* Used in emacs */
1785 These are defined inside C functions
, so currently they
1787 || strneq (str
, "EXFUN", len
) /* Used in glibc */
1788 || strneq (str
, "DEFVAR_", 7) /* Used in emacs */
1790 || strneq (str
, "SYSCALL", len
) /* Used in glibc (mach) */
1791 || strneq (str
, "ENTRY", len
) /* Used in glibc */
1792 || strneq (str
, "PSEUDO", len
)) /* Used in glibc */
1795 next_token_is_func
= TRUE
;
1798 if (next_token_is_func
)
1800 next_token_is_func
= FALSE
;
1810 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1811 funcdef
= fnone
; /* should be useless */
1814 if (funcdef
== fnone
)
1827 * This routine finds functions, typedefs, #define's and
1828 * struct/union/enum definitions in C syntax and adds them
1842 #define current_lb_is_new (newndx == curndx)
1843 #define switch_line_buffers() (curndx = 1 - curndx)
1845 #define curlb (lbs[curndx].lb)
1846 #define othlb (lbs[1-curndx].lb)
1847 #define newlb (lbs[newndx].lb)
1848 #define curlinepos (lbs[curndx].linepos)
1849 #define othlinepos (lbs[1-curndx].linepos)
1850 #define newlinepos (lbs[newndx].linepos)
1852 #define CNL_SAVE_DEFINEDEF \
1854 curlinepos = charno; \
1856 charno += readline (&curlb, inf); \
1857 lp = curlb.buffer; \
1864 CNL_SAVE_DEFINEDEF; \
1865 if (savetok.valid) \
1868 savetok.valid = FALSE; \
1870 definedef = dnone; \
1873 #define make_tag(isfun) do \
1876 pfnote (savestr (token_name.buffer), isfun, tok.named, \
1877 tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1878 else if (DEBUG) abort (); \
1879 tok.valid = FALSE; \
1883 C_entries (c_ext
, inf
)
1884 int c_ext
; /* extension of C */
1885 FILE *inf
; /* input file */
1887 register char c
; /* latest char read; '\0' for end of line */
1888 register char *lp
; /* pointer one beyond the character `c' */
1889 int curndx
, newndx
; /* indices for current and new lb */
1890 TOKEN tok
; /* latest token read */
1891 register int tokoff
; /* offset in line of start of current token */
1892 register int toklen
; /* length of current token */
1893 int cblev
; /* current curly brace level */
1894 int parlev
; /* current parenthesis level */
1895 logical incomm
, inquote
, inchar
, quotednl
, midtoken
;
1897 TOKEN savetok
; /* token saved during preprocessor handling */
1900 curndx
= newndx
= 0;
1906 definedef
= dnone
; funcdef
= fnone
; typdef
= tnone
; structdef
= snone
;
1907 next_token_is_func
= yacc_rules
= FALSE
;
1908 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1909 tok
.valid
= savetok
.valid
= FALSE
;
1912 cplpl
= c_ext
& C_PLPL
;
1919 /* If we're at the end of the line, the next character is a
1920 '\0'; don't skip it, because it's the thing that tells us
1921 to read the next line. */
1942 /* Newlines inside comments do not end macro definitions in
1957 /* Newlines inside strings do not end macro definitions
1958 in traditional cpp, even though compilers don't
1959 usually accept them. */
1970 /* Hmmm, something went wrong. */
1984 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1989 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1999 else if (cplpl
&& *lp
== '/')
2007 if ((c_ext
& YACC
) && *lp
== '%')
2009 /* entering or exiting rules section in yacc file */
2011 definedef
= dnone
; funcdef
= fnone
;
2012 typdef
= tnone
; structdef
= snone
;
2013 next_token_is_func
= FALSE
;
2014 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2016 yacc_rules
= !yacc_rules
;
2022 if (definedef
== dnone
)
2025 logical cpptoken
= TRUE
;
2027 /* Look back on this line. If all blanks, or nonblanks
2028 followed by an end of comment, this is a preprocessor
2030 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2033 if (*cp
== '*' && *(cp
+1) == '/')
2042 definedef
= dsharpseen
;
2043 } /* if (definedef == dnone) */
2049 /* Consider token only if some complicated conditions are satisfied. */
2050 if ((definedef
!= dnone
2051 || (cblev
== 0 && structdef
!= scolonseen
)
2052 || (cblev
== 1 && cplpl
&& structdef
== sinbody
))
2053 && typdef
!= tignore
2054 && definedef
!= dignorerest
2055 && funcdef
!= finlist
)
2061 if (cplpl
&& c
== ':' && *lp
== ':' && begtoken(*(lp
+ 1)))
2064 * This handles :: in the middle, but not at the
2065 * beginning of an identifier.
2072 logical is_func
= FALSE
;
2075 || consider_token (newlb
.buffer
+ tokoff
, toklen
,
2076 c
, c_ext
, cblev
, &is_func
))
2078 if (structdef
== sinbody
2079 && definedef
== dnone
2081 /* function defined in C++ class body */
2083 int strsize
= strlen(structtag
) + 2 + toklen
+ 1;
2084 while (token_name
.size
< strsize
)
2086 token_name
.size
*= 2;
2088 = (char *) xrealloc (token_name
.buffer
,
2091 strcpy (token_name
.buffer
, structtag
);
2092 strcat (token_name
.buffer
, "::");
2093 strncat (token_name
.buffer
,
2094 newlb
.buffer
+tokoff
, toklen
);
2099 while (token_name
.size
< toklen
+ 1)
2101 token_name
.size
*= 2;
2103 = (char *) xrealloc (token_name
.buffer
,
2106 strncpy (token_name
.buffer
,
2107 newlb
.buffer
+tokoff
, toklen
);
2108 token_name
.buffer
[toklen
] = '\0';
2109 if (structdef
== stagseen
2112 && definedef
== dignorerest
)) /* macro */
2117 tok
.lineno
= lineno
;
2118 tok
.linelen
= tokoff
+ toklen
+ 1;
2119 tok
.buffer
= newlb
.buffer
;
2120 tok
.linepos
= newlinepos
;
2123 if (definedef
== dnone
2124 && (funcdef
== ftagseen
2125 || structdef
== stagseen
2128 if (current_lb_is_new
)
2129 switch_line_buffers ();
2136 } /* if (endtoken (c)) */
2137 else if (intoken (c
))
2142 } /* if (midtoken) */
2143 else if (begtoken (c
))
2161 if (structdef
== stagseen
)
2167 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
2169 tokoff
= lp
- 1 - newlb
.buffer
;
2174 } /* if (begtoken) */
2175 } /* if must look at token */
2178 /* Detect end of line, colon, comma, semicolon and various braces
2179 after having handled a token.*/
2183 if (definedef
!= dnone
)
2185 if (structdef
== stagseen
)
2186 structdef
= scolonseen
;
2203 if (definedef
!= dnone
)
2214 if (funcdef
!= fignore
)
2216 if (structdef
== stagseen
)
2220 if (definedef
!= dnone
)
2222 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2224 if (structdef
== stagseen
)
2228 if (definedef
!= dnone
)
2230 if (cblev
== 0 && typdef
== tend
)
2236 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2238 if (structdef
== stagseen
)
2242 if (definedef
!= dnone
)
2251 /* Make sure that the next char is not a '*'.
2252 This handles constructs like:
2253 typedef void OperatorFun (int fun); */
2260 } /* switch (typdef) */
2263 funcdef
= fstartlist
;
2272 if (definedef
!= dnone
)
2280 funcdef
= flistseen
;
2283 if (cblev
== 0 && typdef
== tend
)
2289 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
2293 if (definedef
!= dnone
)
2295 if (typdef
== ttypedseen
)
2299 case skeyseen
: /* unnamed struct */
2300 structtag
= "_anonymous_";
2301 structdef
= sinbody
;
2304 case scolonseen
: /* named struct */
2305 structdef
= sinbody
;
2318 /* Neutralize `extern "C" {' grot and look inside structs. */
2319 if (cblev
== 0 && structdef
== snone
&& typdef
== tnone
)
2325 if (definedef
!= dnone
)
2327 if (funcdef
== fstartlist
)
2328 funcdef
= fnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2331 if (definedef
!= dnone
)
2333 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2335 cblev
= 0; /* reset curly brace level if first column */
2336 parlev
= 0; /* also reset paren level, just in case... */
2342 if (typdef
== tinbody
)
2344 #if FALSE /* too risky */
2345 if (structdef
== sinbody
)
2350 structtag
= "<error>";
2354 case '#': case '+': case '-': case '~': case '&': case '%': case '/':
2355 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2356 if (definedef
!= dnone
)
2358 /* These surely cannot follow a function tag. */
2359 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2363 /* If a macro spans multiple lines don't reset its state. */
2371 } /* while not eof */
2375 * Process either a C++ file or a C file depending on the setting
2379 default_C_entries (inf
)
2382 C_entries (cplusplus
? C_PLPL
: 0, inf
);
2385 /* Always do plain ANSI C. */
2387 plain_C_entries (inf
)
2393 /* Always do C++. */
2395 Cplusplus_entries (inf
)
2398 C_entries (C_PLPL
, inf
);
2406 C_entries (C_STAR
, inf
);
2409 /* Always do Yacc. */
2414 C_entries (YACC
, inf
);
2417 /* Fortran parsing */
2425 register int len
= 0;
2427 while (*cp
&& lowcase(*cp
) == lowcase(dbp
[len
]))
2429 if (*cp
== 0 && !intoken(dbp
[len
]))
2440 while (isspace (*dbp
))
2445 while (isspace (*dbp
))
2447 if (strneq (dbp
, "(*)", 3))
2452 if (!isdigit (*dbp
))
2454 --dbp
; /* force failure */
2459 while (isdigit (*dbp
));
2468 while (isspace (*dbp
))
2473 linecharno
= charno
;
2474 charno
+= readline (&lb
, inf
);
2479 while (isspace (*dbp
))
2488 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
2491 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
, FALSE
, lb
.buffer
,
2492 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2496 Fortran_functions (inf
)
2505 linecharno
= charno
;
2506 charno
+= readline (&lb
, inf
);
2509 dbp
++; /* Ratfor escape to fortran */
2510 while (isspace (*dbp
))
2514 switch (lowcase (*dbp
))
2517 if (tail ("integer"))
2525 if (tail ("logical"))
2529 if (tail ("complex") || tail ("character"))
2533 if (tail ("double"))
2535 while (isspace (*dbp
))
2539 if (tail ("precision"))
2545 while (isspace (*dbp
))
2549 switch (lowcase (*dbp
))
2552 if (tail ("function"))
2556 if (tail ("subroutine"))
2564 if (tail ("program"))
2569 if (tail ("procedure"))
2577 * Bob Weiner, Motorola Inc., 4/3/94
2578 * Unix and microcontroller assembly tag handling
2579 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
2593 linecharno
= charno
;
2594 charno
+= readline (&lb
, inf
);
2597 /* If first char is alphabetic or one of [_.$], test for colon
2598 following identifier. */
2599 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2601 /* Read past label. */
2603 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2605 if (*cp
== ':' || isspace (*cp
))
2607 /* Found end of label, so copy it and add it to the table. */
2608 pfnote (savenstr (lb
.buffer
, cp
-lb
.buffer
), TRUE
, FALSE
,
2609 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2615 /* Added by Mosur Mohan, 4/22/88 */
2616 /* Pascal parsing */
2618 #define GET_NEW_LINE \
2620 linecharno = charno; lineno++; \
2621 charno += 1 + readline (&lb, inf); \
2626 * Locates tags for procedures & functions. Doesn't do any type- or
2627 * var-definitions. It does look for the keyword "extern" or
2628 * "forward" immediately following the procedure statement; if found,
2629 * the tag is skipped.
2632 Pascal_functions (inf
)
2635 struct linebuffer tline
; /* mostly copied from C_entries */
2641 logical
/* each of these flags is TRUE iff: */
2642 incomment
, /* point is inside a comment */
2643 inquote
, /* point is inside '..' string */
2644 get_tagname
, /* point is after PROCEDURE/FUNCTION */
2645 /* keyword, so next item = potential tag */
2646 found_tag
, /* point is after a potential tag */
2647 inparms
, /* point is within parameter-list */
2648 verify_tag
; /* point has passed the parm-list, so the */
2649 /* next token will determine whether */
2650 /* this is a FORWARD/EXTERN to be */
2651 /* ignored, or whether it is a real tag */
2657 initbuffer (&tline
);
2659 incomment
= inquote
= FALSE
;
2660 found_tag
= FALSE
; /* have a proc name; check if extern */
2661 get_tagname
= FALSE
; /* have found "procedure" keyword */
2662 inparms
= FALSE
; /* found '(' after "proc" */
2663 verify_tag
= FALSE
; /* check if "extern" is ahead */
2665 /* long main loop to get next char */
2669 if (c
== '\0') /* if end of line */
2674 if (!((found_tag
&& verify_tag
) ||
2676 c
= *dbp
++; /* only if don't need *dbp pointing */
2677 /* to the beginning of the name of */
2678 /* the procedure or function */
2682 if (c
== '}') /* within { - } comments */
2684 else if (c
== '*' && dbp
[1] == ')') /* within (* - *) comments */
2701 inquote
= TRUE
; /* found first quote */
2703 case '{': /* found open-{-comment */
2707 if (*dbp
== '*') /* found open-(*-comment */
2712 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
2715 case ')': /* end of parms list */
2720 if ((found_tag
) && (!inparms
)) /* end of proc or fn stmt */
2727 if ((found_tag
) && (verify_tag
) && (*dbp
!= ' '))
2729 /* check if this is an "extern" declaration */
2732 if ((*dbp
== 'e') || (*dbp
== 'E'))
2734 if (tail ("extern")) /* superfluous, really! */
2740 else if ((*dbp
== 'f') || (*dbp
== 'F'))
2742 if (tail ("forward")) /* check for forward reference */
2748 if ((found_tag
) && (verify_tag
)) /* not external proc, so make tag */
2752 pfnote (nambuf
, TRUE
, FALSE
, tline
.buffer
,
2753 cp
- tline
.buffer
+ 1, save_lineno
, save_lcno
);
2757 if (get_tagname
) /* grab name of proc or fn */
2762 /* save all values for later tagging */
2763 tline
.size
= lb
.size
;
2764 strcpy (tline
.buffer
, lb
.buffer
);
2765 save_lineno
= lineno
;
2766 save_lcno
= linecharno
;
2768 /* grab block name */
2769 for (cp
= dbp
+ 1; *cp
&& (!endtoken (*cp
)); cp
++)
2771 nambuf
= savenstr (dbp
, cp
-dbp
);
2772 dbp
= cp
; /* restore dbp to e-o-token */
2773 get_tagname
= FALSE
;
2777 /* and proceed to check for "extern" */
2779 else if (!incomment
&& !inquote
&& !found_tag
)
2781 /* check for proc/fn keywords */
2782 switch (lowcase (c
))
2785 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
2789 if (tail ("unction"))
2794 } /* while not eof */
2798 * lisp tag functions
2799 * look for (def or (DEF, quote or QUOTE
2803 register char *strp
;
2805 return ((strp
[1] == 'd' || strp
[1] == 'D')
2806 && (strp
[2] == 'e' || strp
[2] == 'E')
2807 && (strp
[3] == 'f' || strp
[3] == 'F'));
2812 register char *strp
;
2814 return ((*(++strp
) == 'q' || *strp
== 'Q')
2815 && (*(++strp
) == 'u' || *strp
== 'U')
2816 && (*(++strp
) == 'o' || *strp
== 'O')
2817 && (*(++strp
) == 't' || *strp
== 'T')
2818 && (*(++strp
) == 'e' || *strp
== 'E')
2819 && isspace(*(++strp
)));
2827 if (*dbp
== '\'') /* Skip prefix quote */
2829 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
2832 while (isspace(*dbp
))
2835 for (cp
= dbp
/*+1*/;
2836 *cp
&& *cp
!= '(' && *cp
!= ' ' && *cp
!= ')';
2842 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
, FALSE
, lb
.buffer
,
2843 cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2847 Lisp_functions (inf
)
2856 linecharno
= charno
;
2857 charno
+= readline (&lb
, inf
);
2863 while (!isspace (*dbp
))
2865 while (isspace (*dbp
))
2871 /* Check for (foo::defmumble name-defined ... */
2874 while (*dbp
&& !isspace (*dbp
)
2875 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
2880 while (*dbp
== ':');
2882 if (L_isdef (dbp
- 1))
2884 while (!isspace (*dbp
))
2886 while (isspace (*dbp
))
2897 * Scheme tag functions
2898 * look for (def... xyzzy
2899 * look for (def... (xyzzy
2900 * look for (def ... ((...(xyzzy ....
2901 * look for (set! xyzzy
2907 Scheme_functions (inf
)
2916 linecharno
= charno
;
2917 charno
+= readline (&lb
, inf
);
2919 if (dbp
[0] == '(' &&
2920 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
2921 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2922 (dbp
[3] == 'F' || dbp
[3] == 'f'))
2924 while (!isspace (*dbp
))
2926 /* Skip over open parens and white space */
2927 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
2931 if (dbp
[0] == '(' &&
2932 (dbp
[1] == 'S' || dbp
[1] == 's') &&
2933 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2934 (dbp
[3] == 'T' || dbp
[3] == 't') &&
2935 (dbp
[4] == '!' || dbp
[4] == '!') &&
2938 while (!isspace (*dbp
))
2940 /* Skip over white space */
2941 while (isspace (*dbp
))
2955 /* Go till you get to white space or a syntactic break */
2957 *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
);
2960 pfnote (savenstr (dbp
, cp
-dbp
), TRUE
, FALSE
,
2961 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2964 /* Find tags in TeX and LaTeX input files. */
2966 /* TEX_toktab is a table of TeX control sequences that define tags.
2967 Each TEX_tabent records one such control sequence.
2968 CONVERT THIS TO USE THE Stab TYPE!! */
2975 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
2977 /* Default set of control sequences to put into TEX_toktab.
2978 The value of environment var TEXTAGS is prepended to this. */
2980 char *TEX_defenv
= "\
2981 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
2984 struct TEX_tabent
*TEX_decode_env ();
2988 char TEX_esc
= '\\';
2989 char TEX_opgrp
= '{';
2990 char TEX_clgrp
= '}';
2993 * TeX/LaTeX scanning loop.
3004 /* Select either \ or ! as escape character. */
3007 /* Initialize token table once from environment. */
3009 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
3012 { /* Scan each line in file */
3014 linecharno
= charno
;
3015 charno
+= readline (&lb
, inf
);
3018 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
3024 linecharno
+= dbp
- lasthit
;
3026 i
= TEX_Token (lasthit
);
3029 TEX_getit (lasthit
, TEX_toktab
[i
].len
);
3030 break; /* We only save a line once */
3036 #define TEX_LESC '\\'
3037 #define TEX_SESC '!'
3040 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3041 chars accordingly. */
3048 while ((c
= getc (inf
)) != EOF
)
3050 /* Skip to next line if we hit the TeX comment char. */
3054 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
3073 /* Read environment and prepend it to the default string.
3074 Build token table. */
3076 TEX_decode_env (evarname
, defenv
)
3080 register char *env
, *p
;
3082 struct TEX_tabent
*tab
;
3085 /* Append default string to environment. */
3086 env
= getenv (evarname
);
3090 env
= concat (env
, defenv
, "");
3092 /* Allocate a token table */
3093 for (size
= 1, p
= env
; p
;)
3094 if ((p
= etags_strchr (p
, ':')) && *(++p
))
3096 /* Add 1 to leave room for null terminator. */
3097 tab
= xnew (size
+ 1, struct TEX_tabent
);
3099 /* Unpack environment string into token table. Be careful about */
3100 /* zero-length strings (leading ':', "::" and trailing ':') */
3103 p
= etags_strchr (env
, ':');
3104 if (!p
) /* End of environment string. */
3105 p
= env
+ strlen (env
);
3107 { /* Only non-zero strings. */
3108 tab
[i
].name
= savenstr (env
, p
- env
);
3109 tab
[i
].len
= strlen (tab
[i
].name
);
3116 tab
[i
].name
= NULL
; /* Mark end of table. */
3124 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
3125 The name being defined actually starts at (NAME + LEN + 1).
3126 But we seem to include the TeX command in the tag name. */
3128 TEX_getit (name
, len
)
3132 char *p
= name
+ len
;
3137 /* Let tag name extend to next group close (or end of line) */
3138 while (*p
&& *p
!= TEX_clgrp
)
3140 pfnote (savenstr (name
, p
-name
), TRUE
, FALSE
, lb
.buffer
,
3141 strlen (lb
.buffer
), lineno
, linecharno
);
3144 /* If the text at CP matches one of the tag-defining TeX command names,
3145 return the pointer to the first occurrence of that command in TEX_toktab.
3146 Otherwise return -1.
3147 Keep the capital `T' in `Token' for dumb truncating compilers
3148 (this distinguishes it from `TEX_toktab' */
3155 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
3156 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
3161 /* Support for Prolog. */
3163 /* Whole head (not only functor, but also arguments)
3164 is gotten in compound term. */
3177 if (s
[0] == '\0') /* syntax error. */
3179 else if (insquote
&& s
[0] == '\'' && s
[1] == '\'')
3181 else if (s
[0] == '\'')
3183 insquote
= !insquote
;
3186 else if (!insquote
&& s
[0] == '(')
3191 else if (!insquote
&& s
[0] == ')')
3197 else if (npar
< 0) /* syntax error. */
3200 else if (!insquote
&& s
[0] == '.'
3201 && (isspace (s
[1]) || s
[1] == '\0'))
3203 if (npar
!= 0) /* syntax error. */
3211 pfnote (savenstr (save_s
, s
-save_s
), TRUE
, FALSE
,
3212 save_s
, s
-save_s
, lineno
, linecharno
);
3215 /* It is assumed that prolog predicate starts from column 0. */
3217 Prolog_functions (inf
)
3220 void skip_comment (), prolog_getit ();
3222 lineno
= linecharno
= charno
= 0;
3226 linecharno
+= charno
;
3227 charno
= readline (&lb
, inf
) + 1; /* 1 for newline. */
3229 if (isspace (dbp
[0])) /* not predicate header. */
3231 else if (dbp
[0] == '%') /* comment. */
3233 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
3234 skip_comment (&lb
, inf
, &lineno
, &linecharno
);
3241 skip_comment (plb
, inf
, plineno
, plinecharno
)
3242 struct linebuffer
*plb
;
3244 int *plineno
; /* result */
3245 long *plinecharno
; /* result */
3251 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
3252 if (cp
[0] == '*' && cp
[1] == '/')
3255 *plinecharno
+= readline (plb
, inf
) + 1; /* 1 for newline. */
3260 #ifdef ETAGS_REGEXPS
3261 /* Take a string like "/blah/" and turn it into "blah", making sure
3262 that the first and last characters are the same, and handling
3263 quoted separator characters. Actually, stops on the occurence of
3264 an unquoted separator. Also turns "\t" into a Tab character.
3265 Returns pointer to terminating separator. Works in place. Null
3266 terminates name string. */
3268 scan_separators (name
)
3272 char *copyto
= name
;
3273 logical quoted
= FALSE
;
3275 for (++name
; *name
!= '\0'; ++name
)
3281 else if (*name
== sep
)
3285 /* Something else is quoted, so preserve the quote. */
3291 else if (*name
== '\\')
3293 else if (*name
== sep
)
3299 /* Terminate copied string. */
3304 /* Turn a name, which is an ed-style (but Emacs syntax) regular
3305 expression, into a real regular expression by compiling it. */
3307 add_regex (regexp_pattern
)
3308 char *regexp_pattern
;
3312 struct re_pattern_buffer
*patbuf
;
3314 if (regexp_pattern
== NULL
)
3316 /* Remove existing regexps. */
3322 if (regexp_pattern
[0] == '\0')
3324 error ("missing regexp", 0);
3327 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
3329 error ("%s: unterminated regexp", regexp_pattern
);
3332 name
= scan_separators (regexp_pattern
);
3333 if (regexp_pattern
[0] == '\0')
3335 error ("null regexp", 0);
3338 (void) scan_separators (name
);
3340 patbuf
= xnew (1, struct re_pattern_buffer
);
3341 patbuf
->translate
= NULL
;
3342 patbuf
->fastmap
= NULL
;
3343 patbuf
->buffer
= NULL
;
3344 patbuf
->allocated
= 0;
3346 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
3349 error ("%s while compiling pattern", err
);
3354 if (num_patterns
== 1)
3355 patterns
= xnew (1, struct pattern
);
3357 patterns
= ((struct pattern
*)
3359 (num_patterns
* sizeof (struct pattern
))));
3360 patterns
[num_patterns
- 1].pattern
= patbuf
;
3361 patterns
[num_patterns
- 1].name_pattern
= savestr (name
);
3362 patterns
[num_patterns
- 1].error_signaled
= FALSE
;
3366 * Do the subtitutions indicated by the regular expression and
3370 substitute (in
, out
, regs
)
3372 struct re_registers
*regs
;
3374 char *result
= NULL
, *t
;
3377 /* Pass 1: figure out how much size to allocate. */
3378 for (t
= out
; *t
; ++t
)
3385 fprintf (stderr
, "%s: pattern subtitution ends prematurely\n",
3392 size
+= regs
->end
[dig
] - regs
->start
[dig
];
3397 /* Allocate space and do the substitutions. */
3398 result
= xnew (size
+ 1, char);
3407 /* Using "dig2" satisfies my debugger. Bleah. */
3408 int dig2
= *out
- '0';
3409 strncpy (result
+ size
, in
+ regs
->start
[dig2
],
3410 regs
->end
[dig2
] - regs
->start
[dig2
]);
3411 size
+= regs
->end
[dig2
] - regs
->start
[dig2
];
3418 result
[size
++] = '\t';
3424 result
[size
++] = *out
;
3430 result
[size
++] = *out
;
3432 result
[size
] = '\0';
3437 #endif /* ETAGS_REGEXPS */
3438 /* Initialize a linebuffer for use */
3440 initbuffer (linebuffer
)
3441 struct linebuffer
*linebuffer
;
3443 linebuffer
->size
= 200;
3444 linebuffer
->buffer
= xnew (200, char);
3448 * Read a line of text from `stream' into `linebuffer'.
3449 * Return the number of characters read from `stream',
3450 * which is the length of the line including the newline, if any.
3453 readline_internal (linebuffer
, stream
)
3454 struct linebuffer
*linebuffer
;
3455 register FILE *stream
;
3457 char *buffer
= linebuffer
->buffer
;
3458 register char *p
= linebuffer
->buffer
;
3459 register char *pend
;
3462 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
3466 register int c
= getc (stream
);
3469 linebuffer
->size
*= 2;
3470 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
3471 p
+= buffer
- linebuffer
->buffer
;
3472 pend
= buffer
+ linebuffer
->size
;
3473 linebuffer
->buffer
= buffer
;
3482 if (p
> buffer
&& p
[-1] == '\r')
3497 return p
- buffer
+ chars_deleted
;
3501 * Like readline_internal, above, but try to match the input
3502 * line against any existing regular expressions.
3505 readline (linebuffer
, stream
)
3506 struct linebuffer
*linebuffer
;
3509 /* Read new line. */
3511 long result
= readline_internal (linebuffer
, stream
);
3513 #ifdef ETAGS_REGEXPS
3514 /* Match against all listed patterns. */
3515 for (i
= 0; i
< num_patterns
; ++i
)
3517 int match
= re_match (patterns
[i
].pattern
, linebuffer
->buffer
,
3518 (int)result
, 0, &patterns
[i
].regs
);
3523 if (!patterns
[i
].error_signaled
)
3525 error ("error while matching pattern %d", i
);
3526 patterns
[i
].error_signaled
= TRUE
;
3533 /* Match occurred. Construct a tag. */
3534 if (patterns
[i
].name_pattern
[0] != '\0')
3536 /* Make a named tag. */
3537 char *name
= substitute (linebuffer
->buffer
,
3538 patterns
[i
].name_pattern
,
3541 pfnote (name
, TRUE
, TRUE
, linebuffer
->buffer
,
3542 match
, lineno
, linecharno
);
3546 /* Make an unnamed tag. */
3547 pfnote (NULL
, TRUE
, FALSE
, linebuffer
->buffer
,
3548 match
, lineno
, linecharno
);
3553 #endif /* ETAGS_REGEXPS */
3559 * Read a file, but do no processing. This is used to do regexp
3560 * matching on files that have no language defined.
3563 just_read_file (inf
)
3569 linecharno
= charno
;
3570 charno
+= readline (&lb
, inf
) + 1;
3576 * Return a pointer to a space of size strlen(cp)+1 allocated
3577 * with xnew where the string CP has been copied.
3583 return savenstr (cp
, strlen (cp
));
3587 * Return a pointer to a space of size LEN+1 allocated with xnew where
3588 * the string CP has been copied for at most the first LEN characters.
3597 dp
= xnew (len
+ 1, char);
3598 strncpy (dp
, cp
, len
);
3604 * Return the ptr in sp at which the character c last
3605 * appears; NULL if not found
3607 * Identical to System V strrchr, included for portability.
3610 etags_strrchr (sp
, c
)
3611 register char *sp
, c
;
3626 * Return the ptr in sp at which the character c first
3627 * appears; NULL if not found
3629 * Identical to System V strchr, included for portability.
3632 etags_strchr (sp
, c
)
3633 register char *sp
, c
;
3643 /* Print error message and exit. */
3660 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
3665 fprintf (stderr
, "%s: ", progname
);
3666 fprintf (stderr
, s1
, s2
);
3667 fprintf (stderr
, "\n");
3670 /* Return a newly-allocated string whose contents
3671 concatenate those of s1, s2, s3. */
3676 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
3677 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
3679 strcpy (result
, s1
);
3680 strcpy (result
+ len1
, s2
);
3681 strcpy (result
+ len1
+ len2
, s3
);
3682 result
[len1
+ len2
+ len3
] = '\0';
3687 /* Does the same work as the system V getcwd, but does not need to
3688 guess buffer size in advance. */
3693 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
3701 *p
++ = tolower (*p
);
3703 return strdup (path
);
3704 #else /* not DOS_NT */
3707 char *path
= xnew (bufsize
, char);
3709 while (getcwd (path
, bufsize
) == NULL
)
3711 if (errno
!= ERANGE
)
3714 path
= xnew (bufsize
, char);
3718 #else /* not DOS_NT and not HAVE_GETCWD */
3719 struct linebuffer path
;
3723 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
3724 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
3729 #endif /* not HAVE_GETCWD */
3730 #endif /* not DOS_NT */
3733 /* Return a newly allocated string containing the filename
3734 of FILE relative to the absolute directory DIR (which
3735 should end with a slash). */
3737 relative_filename (file
, dir
)
3740 char *fp
, *dp
, *res
;
3742 /* Find the common root of file and dir. */
3743 fp
= absolute_filename (file
, cwd
);
3745 while (*fp
++ == *dp
++)
3754 /* Build a sequence of "../" strings for the resulting relative filename. */
3755 for (dp
= etags_strchr (dp
+ 1, '/'), res
= "";
3757 dp
= etags_strchr (dp
+ 1, '/'))
3759 res
= concat (res
, "../", "");
3762 /* Add the filename relative to the common root of file and dir. */
3763 res
= concat (res
, fp
+ 1, "");
3765 return res
; /* temporary stub */
3768 /* Return a newly allocated string containing the
3769 absolute filename of FILE given CWD (which should
3770 end with a slash). */
3772 absolute_filename (file
, cwd
)
3775 char *slashp
, *cp
, *res
;
3777 if (absolutefn (file
))
3778 res
= concat (file
, "", "");
3780 res
= concat (cwd
, file
, "");
3782 /* Delete the "/dirname/.." and "/." substrings. */
3783 slashp
= etags_strchr (res
, '/');
3784 while (slashp
!= NULL
&& slashp
[0] != '\0')
3786 if (slashp
[1] == '.')
3788 if (slashp
[2] == '.'
3789 && (slashp
[3] == '/' || slashp
[3] == '\0'))
3794 while (cp
>= res
&& *cp
!= '/');
3797 strcpy (cp
, slashp
+ 3);
3799 else /* else (cp == res) */
3801 if (slashp
[3] != '\0')
3802 strcpy (cp
, slashp
+ 4);
3809 else if (slashp
[2] == '/' || slashp
[2] == '\0')
3811 strcpy (slashp
, slashp
+ 2);
3816 slashp
= etags_strchr (slashp
+ 1, '/');
3822 /* Return a newly allocated string containing the absolute
3823 filename of dir where FILE resides given CWD (which should
3824 end with a slash). */
3826 absolute_dirname (file
, cwd
)
3832 slashp
= etags_strrchr (file
, '/');
3837 res
= absolute_filename (file
, cwd
);
3843 /* Like malloc but get fatal error if memory is exhausted. */
3848 long *result
= (long *) malloc (size
);
3850 fatal ("virtual memory exhausted", 0);
3855 xrealloc (ptr
, size
)
3859 long *result
= (long *) realloc (ptr
, size
);
3861 fatal ("virtual memory exhausted");