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 been_warned
; /* set if noticed dup */
137 int lno
; /* line number tag is on */
138 long cno
; /* character number line starts on */
139 char *pat
; /* search pattern */
140 struct nd_st
*left
, *right
; /* left and right sons */
143 extern char *getenv ();
146 char *savenstr (), *savestr ();
147 char *etags_strchr (), *etags_strrchr ();
148 char *etags_getcwd ();
149 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
150 long *xmalloc (), *xrealloc ();
152 typedef void Lang_function ();
153 #if FALSE /* many compilers barf on this */
154 Lang_function Asm_labels
;
155 Lang_function default_C_entries
;
156 Lang_function C_entries
;
157 Lang_function Cplusplus_entries
;
158 Lang_function Cstar_entries
;
159 Lang_function Fortran_functions
;
160 Lang_function Yacc_entries
;
161 Lang_function Lisp_functions
;
162 Lang_function Pascal_functions
;
163 Lang_function Prolog_functions
;
164 Lang_function Scheme_functions
;
165 Lang_function TeX_functions
;
166 Lang_function just_read_file
;
167 #else /* so let's write it this way */
170 void default_C_entries ();
171 void plain_C_entries ();
172 void Cplusplus_entries ();
173 void Cstar_entries ();
174 void Fortran_functions ();
175 void Yacc_entries ();
176 void Lisp_functions ();
177 void Pascal_functions ();
178 void Prolog_functions ();
179 void Scheme_functions ();
180 void TeX_functions ();
181 void just_read_file ();
184 logical
get_language ();
185 int total_size_of_entries ();
187 long readline_internal ();
193 void fatal (), pfatal ();
194 void find_entries ();
200 void process_file ();
205 char searchar
= '/'; /* use /.../ searches */
207 int lineno
; /* line number of current line */
208 long charno
; /* current character number */
210 long linecharno
; /* charno of start of line; not used by C,
211 but by every other language. */
213 char *curfile
; /* current input file name */
214 char *tagfile
; /* output file */
215 char *progname
; /* name this program was invoked with */
216 char *cwd
; /* current working directory */
217 char *tagfiledir
; /* directory of tagfile */
219 FILE *tagf
; /* ioptr for tags file */
220 NODE
*head
; /* the head of the binary tree of tags */
223 * A `struct linebuffer' is a structure which holds a line of text.
224 * `readline' reads a line from a stream into a linebuffer and works
225 * regardless of the length of the line.
233 struct linebuffer lb
; /* the current line */
234 struct linebuffer token_name
; /* used by C_entries as temporary area */
238 struct linebuffer lb
; /* used by C_entries instead of lb */
241 /* boolean "functions" (see init) */
242 logical _wht
[0177], _etk
[0177], _itk
[0177], _btk
[0177];
244 *white
= " \f\t\n\013", /* white chars */
245 *endtk
= " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */
246 /* token starting chars */
247 *begtk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~",
248 /* valid in-token chars */
249 *intk
= "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
251 logical append_to_tagfile
; /* -a: append to tags */
252 /* The following three default to TRUE for etags, but to FALSE for ctags. */
253 logical typedefs
; /* -t: create tags for typedefs */
254 logical typedefs_and_cplusplus
; /* -T: create tags for typedefs, level */
255 /* 0 struct/enum/union decls, and C++ */
256 /* member functions. */
257 logical constantypedefs
; /* -d: create tags for C #define and enum */
258 /* constants. Enum consts not implemented. */
259 /* -D: opposite of -d. Default under ctags. */
260 logical update
; /* -u: update tags */
261 logical vgrind_style
; /* -v: create vgrind style index output */
262 logical no_warnings
; /* -w: suppress warnings */
263 logical cxref_style
; /* -x: create cxref style output */
264 logical cplusplus
; /* .[hc] means C++, not C */
265 logical noindentypedefs
; /* -I: ignore indentation in C */
266 #define permit_duplicates TRUE /* allow duplicate tags */
268 struct option longopts
[] =
270 { "append", no_argument
, NULL
, 'a' },
271 { "backward-search", no_argument
, NULL
, 'B' },
272 { "c++", no_argument
, NULL
, 'C' },
273 { "cxref", no_argument
, NULL
, 'x' },
274 { "defines", no_argument
, NULL
, 'd' },
275 { "help", no_argument
, NULL
, 'h' },
276 { "help", no_argument
, NULL
, 'H' },
277 { "ignore-indentation", no_argument
, NULL
, 'I' },
278 { "include", required_argument
, NULL
, 'i' },
279 { "language", required_argument
, NULL
, 'l' },
280 { "no-defines", no_argument
, NULL
, 'D' },
281 { "no-regex", no_argument
, NULL
, 'R' },
282 { "no-warn", no_argument
, NULL
, 'w' },
283 { "output", required_argument
, NULL
, 'o' },
284 { "regex", required_argument
, NULL
, 'r' },
285 { "typedefs", no_argument
, NULL
, 't' },
286 { "typedefs-and-c++", no_argument
, NULL
, 'T' },
287 { "update", no_argument
, NULL
, 'u' },
288 { "version", no_argument
, NULL
, 'V' },
289 { "vgrind", no_argument
, NULL
, 'v' },
294 /* Structure defining a regular expression. Elements are
295 the compiled pattern, and the name string. */
298 struct re_pattern_buffer
*pattern
;
299 struct re_registers regs
;
301 logical error_signaled
;
304 /* Number of regexps found. */
305 int num_patterns
= 0;
307 /* Array of all regexps. */
308 struct pattern
*patterns
= NULL
;
309 #endif /* ETAGS_REGEXPS */
311 /* Language stuff. */
315 Lang_function
*function
;
318 /* Table of language names and corresponding functions. */
319 /* It is ok for a given function to be listed under more than one
320 name. I just didn't. */
321 /* "auto" language reverts to default behavior. */
322 struct lang_entry lang_names
[] =
324 { "asm", Asm_labels
},
325 { "c", default_C_entries
},
326 { "c++", Cplusplus_entries
},
327 { "c*", Cstar_entries
},
328 { "fortran", Fortran_functions
},
329 { "lisp", Lisp_functions
},
330 { "none", just_read_file
},
331 { "pascal", Pascal_functions
},
332 { "scheme" , Scheme_functions
},
333 { "tex", TeX_functions
},
338 /* Table of file name suffixes and corresponding language functions. */
339 struct lang_entry lang_suffixes
[] =
341 /* Assume that ".s" or ".a" is assembly code. -wolfgang.
343 { "a", Asm_labels
}, /* Unix assembler */
344 { "asm", Asm_labels
}, /* Microcontroller assembly */
345 { "def", Asm_labels
}, /* BSO/Tasking definition includes */
346 { "inc", Asm_labels
}, /* Microcontroller include files */
347 { "ins", Asm_labels
}, /* Microcontroller include files */
349 { "sa", Asm_labels
}, /* Unix assembler */
350 { "src", Asm_labels
}, /* BSO/Tasking C compiler output */
352 /* .aux, .bbl, .clo, .cls, .dtx or .tex implies LaTeX source code. */
353 { "aux", TeX_functions
},
354 { "bbl", TeX_functions
},
355 { "clo", TeX_functions
},
356 { "cls", TeX_functions
},
357 { "dtx", TeX_functions
},
358 { "sty", TeX_functions
},
359 { "tex", TeX_functions
},
361 /* .l or .el or .lisp (or .cl or .clisp or ...) implies lisp source code */
362 { "cl", Lisp_functions
},
363 { "clisp", Lisp_functions
},
364 { "el", Lisp_functions
},
365 { "l", Lisp_functions
},
366 { "lisp", Lisp_functions
},
367 { "lsp", Lisp_functions
},
369 /* .scm or .sm or .scheme implies scheme source code */
370 { "SCM", Scheme_functions
},
371 { "SM", Scheme_functions
},
372 { "oak", Scheme_functions
},
373 { "sch", Scheme_functions
},
374 { "scheme", Scheme_functions
},
375 { "scm", Scheme_functions
},
376 { "sm", Scheme_functions
},
377 { "t", Scheme_functions
},
378 /* FIXME Can't do the `SCM' or `scm' prefix with a version number */
380 /* Note that .c and .h can be considered C++, if the --c++ flag was
381 given. That is why default_C_entries is called here. */
382 { "c", default_C_entries
},
383 { "h", default_C_entries
},
385 /* .pc is a Pro*C file. */
386 { "pc", plain_C_entries
},
388 /* .C or .H or .c++ or .cc or .cpp or .cxx or .h++ or .hh or .hxx:
390 { "C", Cplusplus_entries
},
391 { "H", Cplusplus_entries
},
392 { "c++", Cplusplus_entries
},
393 { "cc", Cplusplus_entries
},
394 { "cpp", Cplusplus_entries
},
395 { "cxx", Cplusplus_entries
},
396 { "h++", Cplusplus_entries
},
397 { "hh", Cplusplus_entries
},
398 { "hxx", Cplusplus_entries
},
400 /* .y: a yacc file */
401 { "y", Yacc_entries
},
403 /* .cs or .hs: a C* file */
404 { "cs", Cstar_entries
},
405 { "hs", Cstar_entries
},
407 /* .F, .f and .for are FORTRAN. */
408 { "F", Fortran_functions
},
409 { "f", Fortran_functions
},
410 { "for", Fortran_functions
},
412 /* .pl implies prolog source code */
413 { "pl", Prolog_functions
},
415 /* .p or .pas: a Pascal file */
416 { "p", Pascal_functions
},
417 { "pas", Pascal_functions
},
422 /* Non-NULL if language fixed. */
423 Lang_function
*lang_func
= NULL
;
427 print_language_names ()
429 struct lang_entry
*name
, *ext
;
431 puts ("\nThese are the currently supported languages, along with the\n\
432 default file name suffixes:");
433 for (name
= lang_names
; name
->suffix
; ++name
)
435 printf ("\t%s\t", name
->suffix
);
436 for (ext
= lang_suffixes
; ext
->suffix
; ++ext
)
437 if (name
->function
== ext
->function
)
438 printf (" .%s", ext
->suffix
);
441 puts ("Where `auto' means use default language for files based on file\n\
442 name suffix, and `none' means only do regexp processing on files.\n\
443 If no language is specified and no matching suffix is found,\n\
444 Fortran is tried first; if no tags are found, C is tried next.");
451 printf ("%s for Emacs version %s.\n", (CTAGS
) ? "CTAGS" : "ETAGS", VERSION
);
453 printf ("%s for Emacs version 19.\n", (CTAGS
) ? "CTAGS" : "ETAGS");
462 printf ("These are the options accepted by %s. You may use unambiguous\n\
463 abbreviations for the long option names. A - as file name means read\n\
464 names from stdin.\n\n", progname
);
466 puts ("-a, --append\n\
467 Append tag entries to existing tags file.");
470 puts ("-B, --backward-search\n\
471 Write the search commands for the tag entries using '?', the\n\
472 backward-search command instead of '/', the forward-search command.");
475 Treat files whose name suffix defaults to C language as C++ files.");
478 puts ("-d, --defines\n\
479 Create tag entries for constant C #defines, too.");
481 puts ("-D, --no-defines\n\
482 Don't create tag entries for constant C #defines. This makes\n\
483 the tags file smaller.");
487 puts ("-i FILE, --include=FILE\n\
488 Include a note in tag file indicating that, when searching for\n\
489 a tag, one should also consult the tags file FILE after\n\
490 checking the current file.");
491 puts ("-l LANG, --language=LANG\n\
492 Force the following files to be considered as written in the\n\
493 named language up to the next --language=LANG option.");
497 puts ("-r /REGEXP/, --regex=/REGEXP/\n\
498 Make a tag for each line matching pattern REGEXP in the\n\
499 following files. REGEXP is anchored (as if preceded by ^).\n\
500 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\
501 named tags can be created with:\n\
502 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/.");
503 puts ("-R, --no-regex\n\
504 Don't create tags from regexps for the following files.");
505 #endif /* ETAGS_REGEXPS */
506 puts ("-o FILE, --output=FILE\n\
507 Write the tags to FILE.");
508 puts ("-I, --ignore-indentation\n\
509 Don't rely on indentation quite as much as normal. Currently,\n\
510 this means not to assume that a closing brace in the first\n\
511 column is the final brace of a function or structure\n\
512 definition in C and C++.");
516 puts ("-t, --typedefs\n\
517 Generate tag entries for C typedefs.");
518 puts ("-T, --typedefs-and-c++\n\
519 Generate tag entries for C typedefs, C struct/enum/union tags,\n\
520 and C++ member functions.");
521 puts ("-u, --update\n\
522 Update the tag entries for the given files, leaving tag\n\
523 entries for other files in place. Currently, this is\n\
524 implemented by deleting the existing entries for the given\n\
525 files and then rewriting the new entries at the end of the\n\
526 tags file. It is often faster to simply rebuild the entire\n\
527 tag file than to use this.");
528 puts ("-v, --vgrind\n\
529 Generates an index of items intended for human consumption,\n\
530 similar to the output of vgrind. The index is sorted, and\n\
531 gives the page number of each item.");
532 puts ("-w, --no-warn\n\
533 Suppress warning messages about entries defined in multiple\n\
535 puts ("-x, --cxref\n\
536 Like --vgrind, but in the style of cxref, rather than vgrind.\n\
537 The output uses line numbers instead of page numbers, but\n\
538 beyond that the differences are cosmetic; try both to see\n\
542 puts ("-V, --version\n\
543 Print the version of the program.\n\
545 Print this help message.");
547 print_language_names ();
560 /* This structure helps us allow mixing of --lang and filenames. */
563 enum argument_type arg_type
;
565 Lang_function
*function
;
568 #ifdef VMS /* VMS specific functions */
572 /* This is a BUG! ANY arbitrary limit is a BUG!
573 Won't someone please fix this? */
574 #define MAX_FILE_SPEC_LEN 255
577 char body
[MAX_FILE_SPEC_LEN
+ 1];
581 v1.05 nmm 26-Jun-86 fn_exp - expand specification of list of file names
582 returning in each successive call the next filename matching the input
583 spec. The function expects that each in_spec passed
584 to it will be processed to completion; in particular, up to and
585 including the call following that in which the last matching name
586 is returned, the function ignores the value of in_spec, and will
587 only start processing a new spec with the following call.
588 If an error occurs, on return out_spec contains the value
589 of in_spec when the error occurred.
591 With each successive filename returned in out_spec, the
592 function's return value is one. When there are no more matching
593 names the function returns zero. If on the first call no file
594 matches in_spec, or there is any other error, -1 is returned.
599 #define OUTSIZE MAX_FILE_SPEC_LEN
605 static long context
= 0;
606 static struct dsc$descriptor_s o
;
607 static struct dsc$descriptor_s i
;
608 static logical pass1
= TRUE
;
615 o
.dsc$a_pointer
= (char *) out
;
616 o
.dsc$w_length
= (short)OUTSIZE
;
617 i
.dsc$a_pointer
= in
;
618 i
.dsc$w_length
= (short)strlen(in
);
619 i
.dsc$b_dtype
= DSC$K_DTYPE_T
;
620 i
.dsc$b_class
= DSC$K_CLASS_S
;
621 o
.dsc$b_dtype
= DSC$K_DTYPE_VT
;
622 o
.dsc$b_class
= DSC$K_CLASS_VS
;
624 if ((status
= lib$
find_file(&i
, &o
, &context
, 0, 0)) == RMS$_NORMAL
)
626 out
->body
[out
->curlen
] = EOS
;
629 else if (status
== RMS$_NMF
)
633 strcpy(out
->body
, in
);
636 lib$
find_file_end(&context
);
642 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
643 name of each file specified by the provided arg expanding wildcards.
646 gfnames (arg
, p_error
)
650 static vspec filename
= {MAX_FILE_SPEC_LEN
, "\0"};
652 switch (fn_exp (&filename
, arg
))
656 return filename
.body
;
662 return filename
.body
;
666 #ifndef OLD /* Newer versions of VMS do provide `system'. */
670 fprintf (stderr
, "system() function not implemented under VMS\n");
674 #define VERSION_DELIM ';'
675 char *massage_name (s
)
681 if (*s
== VERSION_DELIM
)
699 unsigned int nincluded_files
= 0;
700 char **included_files
= xnew (argc
, char *);
703 int current_arg
= 0, file_count
= 0;
704 struct linebuffer filename_lb
;
710 _fmode
= O_BINARY
; /* all of files are treated as binary files */
715 /* Allocate enough no matter what happens. Overkill, but each one
717 argbuffer
= xnew (argc
, ARGUMENT
);
720 /* Set syntax for regular expression routines. */
721 re_set_syntax (RE_SYNTAX_EMACS
);
722 #endif /* ETAGS_REGEXPS */
725 * If etags, always find typedefs and structure tags. Why not?
726 * Also default is to find macro constants.
729 typedefs
= typedefs_and_cplusplus
= constantypedefs
= TRUE
;
733 int opt
= getopt_long (argc
, argv
,
734 "-aCdDf:Il:o:r:RStTi:BuvxwVhH", longopts
, 0);
742 /* If getopt returns 0, then it has already processed a
743 long-named option. We should do nothing. */
747 /* This means that a filename has been seen. Record it. */
748 argbuffer
[current_arg
].arg_type
= at_filename
;
749 argbuffer
[current_arg
].what
= optarg
;
754 /* Common options. */
756 append_to_tagfile
= TRUE
;
762 constantypedefs
= TRUE
;
765 constantypedefs
= FALSE
;
767 case 'f': /* for compatibility with old makefiles */
771 fprintf (stderr
, "%s: -%c option may only be given once.\n",
778 case 'S': /* for backward compatibility */
779 noindentypedefs
= TRUE
;
782 if (!get_language (optarg
, &argbuffer
[current_arg
].function
))
784 fprintf (stderr
, "%s: language \"%s\" not recognized.\n",
788 argbuffer
[current_arg
].arg_type
= at_language
;
793 argbuffer
[current_arg
].arg_type
= at_regexp
;
794 argbuffer
[current_arg
].what
= optarg
;
798 argbuffer
[current_arg
].arg_type
= at_regexp
;
799 argbuffer
[current_arg
].what
= NULL
;
802 #endif /* ETAGS_REGEXPS */
814 typedefs
= typedefs_and_cplusplus
= TRUE
;
819 included_files
[nincluded_files
++] = optarg
;
844 for (; optind
< argc
; ++optind
)
846 argbuffer
[current_arg
].arg_type
= at_filename
;
847 argbuffer
[current_arg
].what
= argv
[optind
];
852 if (nincluded_files
== 0 && file_count
== 0)
854 fprintf (stderr
, "%s: No input files specified.\n", progname
);
857 fprintf (stderr
, "\tTry `%s --help' for a complete list of options.\n",
864 tagfile
= CTAGS
? "tags" : "TAGS";
866 cwd
= etags_getcwd (); /* the current working directory */
868 if (streq (tagfile
, "-"))
874 tagfiledir
= absolute_dirname (tagfile
, cwd
);
877 init (); /* set up boolean "functions" */
880 initbuffer (&token_name
);
881 initbuffer (&lbs
[0].lb
);
882 initbuffer (&lbs
[1].lb
);
883 initbuffer (&filename_lb
);
887 if (streq (tagfile
, "-"))
890 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
896 * Loop through files finding functions.
898 for (i
= 0; i
< current_arg
; ++i
)
900 switch (argbuffer
[i
].arg_type
)
903 lang_func
= argbuffer
[i
].function
;
907 add_regex (argbuffer
[i
].what
);
912 while ((this_file
= gfnames (argbuffer
[i
].what
, &got_err
)) != NULL
)
916 error ("Can't find file %s\n", this_file
);
921 this_file
= massage_name (this_file
);
924 this_file
= argbuffer
[i
].what
;
926 /* Input file named "-" means read file names from stdin
928 if (streq (this_file
, "-"))
929 while (readline_internal (&filename_lb
, stdin
) > 0)
930 process_file (filename_lb
.buffer
);
932 process_file (this_file
);
942 while (nincluded_files
-- > 0)
943 fprintf (tagf
, "\f\n%s,include\n", *included_files
++);
949 /* If CTAGS, we are here. process_file did not write the tags yet,
950 because we want them ordered. Let's do it now. */
953 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
963 for (i
= 0; i
< current_arg
; ++i
)
965 if (argbuffer
[i
].arg_type
!= at_filename
)
968 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
969 tagfile
, argbuffer
[i
].what
, tagfile
);
970 if (system (cmd
) != GOOD
)
971 fatal ("failed to execute shell command");
973 append_to_tagfile
= TRUE
;
976 tagf
= fopen (tagfile
, append_to_tagfile
? "a" : "w");
985 sprintf (cmd
, "sort %s -o %s", tagfile
, tagfile
);
993 * Set the language, given the name.
996 get_language (language
, func
)
998 Lang_function
**func
;
1000 struct lang_entry
*lang
;
1002 for (lang
= lang_names
; lang
->suffix
; ++lang
)
1004 if (streq (language
, lang
->suffix
))
1006 *func
= lang
->function
;
1016 * This routine is called on each file argument.
1022 struct stat stat_buf
;
1025 if (stat (file
, &stat_buf
) == 0 && !S_ISREG (stat_buf
.st_mode
))
1027 fprintf (stderr
, "Skipping %s: it is not a regular file.\n", file
);
1030 if (streq (file
, tagfile
) && !streq (tagfile
, "-"))
1032 fprintf (stderr
, "Skipping inclusion of %s in self.\n", file
);
1035 inf
= fopen (file
, "r");
1042 find_entries (file
, inf
);
1048 if (absolutefn (file
))
1050 /* file is an absolute filename. Canonicalise it. */
1051 filename
= absolute_filename (file
, cwd
);
1055 /* file is a filename relative to cwd. Make it relative
1056 to the directory of the tags file. */
1057 filename
= relative_filename (file
, tagfiledir
);
1059 fprintf (tagf
, "\f\n%s,%d\n", filename
, total_size_of_entries (head
));
1068 * This routine sets up the boolean pseudo-functions which work
1069 * by setting boolean flags dependent upon the corresponding character
1070 * Every char which is NOT in that string is not a white char. Therefore,
1071 * all of the array "_wht" is set to FALSE, and then the elements
1072 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1073 * of a char is TRUE if it is the string "white", else FALSE.
1081 for (i
= 0; i
< 0177; i
++)
1082 _wht
[i
] = _etk
[i
] = _itk
[i
] = _btk
[i
] = FALSE
;
1083 for (sp
= white
; *sp
; sp
++)
1085 for (sp
= endtk
; *sp
; sp
++)
1087 for (sp
= intk
; *sp
; sp
++)
1089 for (sp
= begtk
; *sp
; sp
++)
1091 _wht
[0] = _wht
['\n'];
1092 _etk
[0] = _etk
['\n'];
1093 _btk
[0] = _btk
['\n'];
1094 _itk
[0] = _itk
['\n'];
1098 * This routine opens the specified file and calls the function
1099 * which finds the function and type definitions.
1102 find_entries (file
, inf
)
1107 struct lang_entry
*lang
;
1108 NODE
*old_last_node
;
1109 extern NODE
*last_node
;
1111 /* The memory block pointed by curfile is never released for simplicity. */
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
, linestart
, linelen
, lno
, cno
)
1153 char *name
; /* tag name, if different from definition */
1154 logical is_func
; /* tag is a function */
1155 char *linestart
; /* start of the line where tag is */
1156 int linelen
; /* length of the line where tag is */
1157 int lno
; /* line number */
1158 long cno
; /* character number */
1160 register NODE
*np
= xnew (1, NODE
);
1162 /* If ctags mode, change name "main" to M<thisfilename>. */
1163 if (CTAGS
&& !cxref_style
&& streq (name
, "main"))
1165 register char *fp
= etags_strrchr (curfile
, '/');
1166 np
->name
= concat ("M", fp
== 0 ? curfile
: fp
+ 1, "");
1167 fp
= etags_strrchr (np
->name
, '.');
1168 if (fp
&& fp
[1] != '\0' && fp
[2] == '\0')
1173 np
->been_warned
= FALSE
;
1175 np
->is_func
= is_func
;
1177 /* Our char numbers are 0-base, because of C language tradition?
1178 ctags compatibility? old versions compatibility? I don't know.
1179 Anyway, since emacs's are 1-base we espect etags.el to take care
1180 of the difference. If we wanted to have 1-based numbers, we would
1181 uncomment the +1 below. */
1182 np
->cno
= cno
/* + 1 */ ;
1183 np
->left
= np
->right
= NULL
;
1184 np
->pat
= savenstr (linestart
, ((CTAGS
&& !cxref_style
) ? 50 : linelen
));
1186 add_node (np
, &head
);
1191 * recurse on left children, iterate on right children.
1195 register NODE
*node
;
1199 register NODE
*node_right
= node
->right
;
1200 free_tree (node
->left
);
1201 if (node
->name
!= NULL
)
1204 free ((char *) node
);
1211 * Adds a node to the tree of nodes. In etags mode, we don't keep
1212 * it sorted; we just keep a linear list. In ctags mode, maintain
1213 * an ordered tree, with no attempt at balancing.
1215 * add_node is the only function allowed to add nodes, so it can
1218 NODE
*last_node
= NULL
;
1220 add_node (node
, cur_node_p
)
1221 NODE
*node
, **cur_node_p
;
1224 register NODE
*cur_node
= *cur_node_p
;
1226 if (cur_node
== NULL
)
1236 if (last_node
== NULL
)
1237 fatal ("internal error in add_node", 0);
1238 last_node
->right
= node
;
1244 dif
= strcmp (node
->name
, cur_node
->name
);
1247 * If this tag name matches an existing one, then
1248 * do not add the node, but maybe print a warning.
1252 if (streq (node
->file
, cur_node
->file
))
1256 fprintf (stderr
, "Duplicate entry in file %s, line %d: %s\n",
1257 node
->file
, lineno
, node
->name
);
1258 fprintf (stderr
, "Second entry ignored\n");
1262 if (!cur_node
->been_warned
&& !no_warnings
)
1265 "Duplicate entry in files %s and %s: %s (Warning only)\n",
1266 node
->file
, cur_node
->file
, node
->name
);
1268 cur_node
->been_warned
= TRUE
;
1272 /* Maybe refuse to add duplicate nodes. */
1273 if (!permit_duplicates
)
1275 if (streq (node
->name
, cur_node
->name
)
1276 && streq (node
->file
, cur_node
->file
))
1280 /* Actually add the node */
1281 add_node (node
, dif
< 0 ? &cur_node
->left
: &cur_node
->right
);
1287 register NODE
*node
;
1294 /* Output subentries that precede this one */
1295 put_entries (node
->left
);
1297 /* Output this entry */
1301 if (node
->name
!= NULL
)
1302 fprintf (tagf
, "%s\177%s\001%d,%d\n",
1303 node
->pat
, node
->name
, node
->lno
, node
->cno
);
1305 fprintf (tagf
, "%s\177%d,%d\n",
1306 node
->pat
, node
->lno
, node
->cno
);
1308 else if (!cxref_style
)
1310 fprintf (tagf
, "%s\t%s\t",
1311 node
->name
, node
->file
);
1315 putc (searchar
, tagf
);
1318 for (sp
= node
->pat
; *sp
; sp
++)
1320 if (*sp
== '\\' || *sp
== searchar
)
1324 putc (searchar
, tagf
);
1327 { /* a typedef; text pattern inadequate */
1328 fprintf (tagf
, "%d", node
->lno
);
1332 else if (vgrind_style
)
1333 fprintf (stdout
, "%s %s %d\n",
1334 node
->name
, node
->file
, (node
->lno
+ 63) / 64);
1336 fprintf (stdout
, "%-16s %3d %-16s %s\n",
1337 node
->name
, node
->lno
, node
->file
, node
->pat
);
1339 /* Output subentries that follow this one */
1340 put_entries (node
->right
);
1343 /* Length of a number's decimal representation. */
1351 for (; num
; num
/= 10)
1357 * Return total number of characters that put_entries will output for
1358 * the nodes in the subtree of the specified node. Works only if
1359 * we are not ctags, but called only in that case. This count
1360 * is irrelevant with the new tags.el, but is still supplied for
1361 * backward compatibility.
1364 total_size_of_entries (node
)
1365 register NODE
*node
;
1373 for (; node
; node
= node
->right
)
1375 /* Count left subentries. */
1376 total
+= total_size_of_entries (node
->left
);
1378 /* Count this entry */
1379 total
+= strlen (node
->pat
) + 1;
1380 total
+= number_len ((long) node
->lno
) + 1 + number_len (node
->cno
) + 1;
1381 if (node
->name
!= NULL
)
1382 total
+= 1 + strlen (node
->name
); /* \001name */
1389 * The C symbol tables.
1393 st_none
, st_C_struct
, st_C_enum
, st_C_define
, st_C_typedef
, st_C_typespec
1396 /* Feed stuff between (but not including) %[ and %] lines to:
1397 gperf -c -k1,3 -o -p -r -t
1399 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1401 class, C_PLPL, st_C_struct
1402 domain, C_STAR, st_C_struct
1403 union, 0, st_C_struct
1404 struct, 0, st_C_struct
1406 typedef, 0, st_C_typedef
1407 define, 0, st_C_define
1408 long, 0, st_C_typespec
1409 short, 0, st_C_typespec
1410 int, 0, st_C_typespec
1411 char, 0, st_C_typespec
1412 float, 0, st_C_typespec
1413 double, 0, st_C_typespec
1414 signed, 0, st_C_typespec
1415 unsigned, 0, st_C_typespec
1416 auto, 0, st_C_typespec
1417 void, 0, st_C_typespec
1418 extern, 0, st_C_typespec
1419 static, 0, st_C_typespec
1420 const, 0, st_C_typespec
1421 volatile, 0, st_C_typespec
1423 and replace lines between %< and %> with its output. */
1425 /* C code produced by gperf version 1.8.1 (K&R C version) */
1426 /* Command-line: gperf -c -k1,3 -o -p -r -t */
1429 struct C_stab_entry
{ char *name
; int c_ext
; enum sym_type type
; };
1431 #define MIN_WORD_LENGTH 3
1432 #define MAX_WORD_LENGTH 8
1433 #define MIN_HASH_VALUE 10
1434 #define MAX_HASH_VALUE 62
1437 53 is the maximum key range
1445 static unsigned char hash_table
[] =
1447 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1448 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1449 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1450 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1451 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1452 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1453 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1454 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1455 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
1456 62, 62, 62, 62, 62, 62, 62, 2, 62, 7,
1457 6, 9, 15, 30, 62, 24, 62, 62, 1, 24,
1458 7, 27, 13, 62, 19, 26, 18, 27, 1, 62,
1459 62, 62, 62, 62, 62, 62, 62, 62,
1461 return len
+ hash_table
[str
[2]] + hash_table
[str
[0]];
1464 struct C_stab_entry
*
1465 in_word_set (str
, len
)
1470 static struct C_stab_entry wordlist
[] =
1472 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1474 {"volatile", 0, st_C_typespec
},
1476 {"long", 0, st_C_typespec
},
1477 {"char", 0, st_C_typespec
},
1478 {"class", C_PLPL
, st_C_struct
},
1479 {"",}, {"",}, {"",}, {"",},
1480 {"const", 0, st_C_typespec
},
1481 {"",}, {"",}, {"",}, {"",},
1482 {"auto", 0, st_C_typespec
},
1484 {"define", 0, st_C_define
},
1486 {"void", 0, st_C_typespec
},
1487 {"",}, {"",}, {"",},
1488 {"extern", 0, st_C_typespec
},
1489 {"static", 0, st_C_typespec
},
1491 {"domain", C_STAR
, st_C_struct
},
1493 {"typedef", 0, st_C_typedef
},
1494 {"double", 0, st_C_typespec
},
1495 {"enum", 0, st_C_enum
},
1496 {"",}, {"",}, {"",}, {"",},
1497 {"int", 0, st_C_typespec
},
1499 {"float", 0, st_C_typespec
},
1500 {"",}, {"",}, {"",},
1501 {"struct", 0, st_C_struct
},
1502 {"",}, {"",}, {"",}, {"",},
1503 {"union", 0, st_C_struct
},
1505 {"short", 0, st_C_typespec
},
1507 {"unsigned", 0, st_C_typespec
},
1508 {"signed", 0, st_C_typespec
},
1511 if (len
<= MAX_WORD_LENGTH
&& len
>= MIN_WORD_LENGTH
)
1513 register int key
= hash (str
, len
);
1515 if (key
<= MAX_HASH_VALUE
&& key
>= MIN_HASH_VALUE
)
1517 register char *s
= wordlist
[key
].name
;
1519 if (*s
== *str
&& strneq (str
+ 1, s
+ 1, len
- 1))
1520 return &wordlist
[key
];
1528 C_symtype(str
, len
, c_ext
)
1533 register struct C_stab_entry
*se
= in_word_set(str
, len
);
1535 if (se
== NULL
|| (se
->c_ext
&& !(c_ext
& se
->c_ext
)))
1541 * C functions are recognized using a simple finite automaton.
1542 * funcdef is its state variable.
1546 fnone
, /* nothing seen */
1547 ftagseen
, /* function-like tag seen */
1548 fstartlist
, /* just after open parenthesis */
1549 finlist
, /* in parameter list */
1550 flistseen
, /* after parameter list */
1551 fignore
/* before open brace */
1557 * typedefs are recognized using a simple finite automaton.
1558 * typeddef is its state variable.
1562 tnone
, /* nothing seen */
1563 ttypedseen
, /* typedef keyword seen */
1564 tinbody
, /* inside typedef body */
1565 tend
, /* just before typedef tag */
1566 tignore
/* junk after typedef tag */
1572 * struct-like structures (enum, struct and union) are recognized
1573 * using another simple finite automaton. `structdef' is its state
1578 snone
, /* nothing seen yet */
1579 skeyseen
, /* struct-like keyword seen */
1580 stagseen
, /* struct-like tag seen */
1581 scolonseen
, /* colon seen after struct-like tag */
1582 sinbody
/* in struct body: recognize member func defs*/
1587 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1588 * struct tag, and structtype is the type of the preceding struct-like
1591 char *structtag
= "<uninited>";
1592 enum sym_type structtype
;
1595 * Yet another little state machine to deal with preprocessor lines.
1599 dnone
, /* nothing seen */
1600 dsharpseen
, /* '#' seen as first char on line */
1601 ddefineseen
, /* '#' and 'define' seen */
1602 dignorerest
/* ignore rest of line */
1607 * Set this to TRUE, and the next token considered is called a function.
1608 * Used only for GNU emacs's function-defining macros.
1610 logical next_token_is_func
;
1613 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1619 * checks to see if the current token is at the start of a
1620 * function, or corresponds to a typedef, or is a struct/union/enum
1623 * *IS_FUNC gets TRUE iff the token is a function or macro with args.
1624 * C_EXT is which language we are looking at.
1626 * In the future we will need some way to adjust where the end of
1627 * the token is; for instance, implementing the C++ keyword
1628 * `operator' properly will adjust the end of the token to be after
1629 * whatever follows `operator'.
1636 * next_token_is_func IN OUT
1640 consider_token (str
, len
, c
, c_ext
, cblev
, is_func
)
1641 register char *str
; /* IN: token pointer */
1642 register int len
; /* IN: token length */
1643 register char c
; /* IN: first char after the token */
1644 int c_ext
; /* IN: C extensions mask */
1645 int cblev
; /* IN: curly brace level */
1646 logical
*is_func
; /* OUT: function found */
1648 enum sym_type toktype
= C_symtype (str
, len
, c_ext
);
1651 * Advance the definedef state machine.
1656 /* We're not on a preprocessor line. */
1659 if (toktype
== st_C_define
)
1661 definedef
= ddefineseen
;
1665 definedef
= dignorerest
;
1670 * Make a tag for any macro, unless it is a constant
1671 * and constantypedefs is FALSE.
1673 definedef
= dignorerest
;
1674 *is_func
= (c
== '(');
1675 if (!*is_func
&& !constantypedefs
)
1682 error ("internal error: definedef value.", 0);
1691 if (toktype
== st_C_typedef
)
1694 typdef
= ttypedseen
;
1710 /* Do not return here, so the structdef stuff has a chance. */
1724 * This structdef business is currently only invoked when cblev==0.
1725 * It should be recursively invoked whatever the curly brace level,
1726 * and a stack of states kept, to allow for definitions of structs
1729 * This structdef business is NOT invoked when we are ctags and the
1730 * file is plain C. This is because a struct tag may have the same
1731 * name as another tag, and this loses with ctags.
1733 * This if statement deals with the typdef state machine as
1734 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1735 * return FALSE. All the other code here is for the structdef
1742 if (typdef
== ttypedseen
1743 || (typedefs_and_cplusplus
&& cblev
== 0 && structdef
== snone
))
1745 structdef
= skeyseen
;
1746 structtype
= toktype
;
1750 if (structdef
== skeyseen
)
1752 /* Save the tag for struct/union/class, for functions that may be
1754 if (structtype
== st_C_struct
)
1755 structtag
= savenstr (str
, len
);
1757 structtag
= "<enum>";
1758 structdef
= stagseen
;
1762 /* Avoid entering funcdef stuff if typdef is going on. */
1763 if (typdef
!= tnone
)
1769 /* Detect GNU macros. */
1770 if (definedef
== dnone
)
1771 if (strneq (str
, "DEFUN", len
) /* Used in emacs */
1773 These are defined inside C functions
, so currently they
1775 || strneq (str
, "EXFUN", len
) /* Used in glibc */
1776 || strneq (str
, "DEFVAR_", 7) /* Used in emacs */
1778 || strneq (str
, "SYSCALL", len
) /* Used in glibc (mach) */
1779 || strneq (str
, "ENTRY", len
) /* Used in glibc */
1780 || strneq (str
, "PSEUDO", len
)) /* Used in glibc */
1783 next_token_is_func
= TRUE
;
1786 if (next_token_is_func
)
1788 next_token_is_func
= FALSE
;
1798 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1799 funcdef
= fnone
; /* should be useless */
1802 if (funcdef
== fnone
)
1815 * This routine finds functions, typedefs, #define's and
1816 * struct/union/enum definitions in C syntax and adds them
1830 #define current_lb_is_new (newndx == curndx)
1831 #define switch_line_buffers() (curndx = 1 - curndx)
1833 #define curlb (lbs[curndx].lb)
1834 #define othlb (lbs[1-curndx].lb)
1835 #define newlb (lbs[newndx].lb)
1836 #define curlinepos (lbs[curndx].linepos)
1837 #define othlinepos (lbs[1-curndx].linepos)
1838 #define newlinepos (lbs[newndx].linepos)
1840 #define CNL_SAVE_DEFINEDEF \
1842 curlinepos = charno; \
1844 charno += readline (&curlb, inf); \
1845 lp = curlb.buffer; \
1852 CNL_SAVE_DEFINEDEF; \
1853 if (savetok.valid) \
1856 savetok.valid = FALSE; \
1858 definedef = dnone; \
1861 #define make_tag(isfun) do \
1865 char *name = NULL; \
1867 name = savestr (token_name.buffer); \
1868 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1870 else if (DEBUG) abort (); \
1871 tok.valid = FALSE; \
1875 C_entries (c_ext
, inf
)
1876 int c_ext
; /* extension of C */
1877 FILE *inf
; /* input file */
1879 register char c
; /* latest char read; '\0' for end of line */
1880 register char *lp
; /* pointer one beyond the character `c' */
1881 int curndx
, newndx
; /* indices for current and new lb */
1882 TOKEN tok
; /* latest token read */
1883 register int tokoff
; /* offset in line of start of current token */
1884 register int toklen
; /* length of current token */
1885 int cblev
; /* current curly brace level */
1886 int parlev
; /* current parenthesis level */
1887 logical incomm
, inquote
, inchar
, quotednl
, midtoken
;
1889 TOKEN savetok
; /* token saved during preprocessor handling */
1892 curndx
= newndx
= 0;
1898 definedef
= dnone
; funcdef
= fnone
; typdef
= tnone
; structdef
= snone
;
1899 next_token_is_func
= yacc_rules
= FALSE
;
1900 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
1901 tok
.valid
= savetok
.valid
= FALSE
;
1904 cplpl
= c_ext
& C_PLPL
;
1911 /* If we're at the end of the line, the next character is a
1912 '\0'; don't skip it, because it's the thing that tells us
1913 to read the next line. */
1934 /* Newlines inside comments do not end macro definitions in
1949 /* Newlines inside strings do not end macro definitions
1950 in traditional cpp, even though compilers don't
1951 usually accept them. */
1962 /* Hmmm, something went wrong. */
1976 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1981 if (funcdef
!= finlist
&& funcdef
!= fignore
)
1991 else if (cplpl
&& *lp
== '/')
1999 if ((c_ext
& YACC
) && *lp
== '%')
2001 /* entering or exiting rules section in yacc file */
2003 definedef
= dnone
; funcdef
= fnone
;
2004 typdef
= tnone
; structdef
= snone
;
2005 next_token_is_func
= FALSE
;
2006 midtoken
= inquote
= inchar
= incomm
= quotednl
= FALSE
;
2008 yacc_rules
= !yacc_rules
;
2014 if (definedef
== dnone
)
2017 logical cpptoken
= TRUE
;
2019 /* Look back on this line. If all blanks, or nonblanks
2020 followed by an end of comment, this is a preprocessor
2022 for (cp
= newlb
.buffer
; cp
< lp
-1; cp
++)
2025 if (*cp
== '*' && *(cp
+1) == '/')
2034 definedef
= dsharpseen
;
2035 } /* if (definedef == dnone) */
2041 /* Consider token only if some complicated conditions are satisfied. */
2042 if ((definedef
!= dnone
2043 || (cblev
== 0 && structdef
!= scolonseen
)
2044 || (cblev
== 1 && cplpl
&& structdef
== sinbody
))
2045 && typdef
!= tignore
2046 && definedef
!= dignorerest
2047 && funcdef
!= finlist
)
2053 if (cplpl
&& c
== ':' && *lp
== ':' && begtoken(*(lp
+ 1)))
2056 * This handles :: in the middle, but not at the
2057 * beginning of an identifier.
2064 logical is_func
= FALSE
;
2067 || consider_token (newlb
.buffer
+ tokoff
, toklen
,
2068 c
, c_ext
, cblev
, &is_func
))
2070 if (structdef
== sinbody
2071 && definedef
== dnone
2073 /* function defined in C++ class body */
2075 int strsize
= strlen(structtag
) + 2 + toklen
+ 1;
2076 while (token_name
.size
< strsize
)
2078 token_name
.size
*= 2;
2080 = (char *) xrealloc (token_name
.buffer
,
2083 strcpy (token_name
.buffer
, structtag
);
2084 strcat (token_name
.buffer
, "::");
2085 strncat (token_name
.buffer
,
2086 newlb
.buffer
+tokoff
, toklen
);
2091 while (token_name
.size
< toklen
+ 1)
2093 token_name
.size
*= 2;
2095 = (char *) xrealloc (token_name
.buffer
,
2098 strncpy (token_name
.buffer
,
2099 newlb
.buffer
+tokoff
, toklen
);
2100 token_name
.buffer
[toklen
] = '\0';
2101 if (structdef
== stagseen
2104 && definedef
== dignorerest
)) /* macro */
2109 tok
.lineno
= lineno
;
2110 tok
.linelen
= tokoff
+ toklen
+ 1;
2111 tok
.buffer
= newlb
.buffer
;
2112 tok
.linepos
= newlinepos
;
2115 if (definedef
== dnone
2116 && (funcdef
== ftagseen
2117 || structdef
== stagseen
2120 if (current_lb_is_new
)
2121 switch_line_buffers ();
2128 } /* if (endtoken (c)) */
2129 else if (intoken (c
))
2134 } /* if (midtoken) */
2135 else if (begtoken (c
))
2153 if (structdef
== stagseen
)
2159 if (!yacc_rules
|| lp
== newlb
.buffer
+ 1)
2161 tokoff
= lp
- 1 - newlb
.buffer
;
2166 } /* if (begtoken) */
2167 } /* if must look at token */
2170 /* Detect end of line, colon, comma, semicolon and various braces
2171 after having handled a token.*/
2175 if (definedef
!= dnone
)
2177 if (structdef
== stagseen
)
2178 structdef
= scolonseen
;
2195 if (definedef
!= dnone
)
2206 if (funcdef
!= fignore
)
2208 if (structdef
== stagseen
)
2212 if (definedef
!= dnone
)
2214 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2216 if (structdef
== stagseen
)
2220 if (definedef
!= dnone
)
2222 if (cblev
== 0 && typdef
== tend
)
2228 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2230 if (structdef
== stagseen
)
2234 if (definedef
!= dnone
)
2243 /* Make sure that the next char is not a '*'.
2244 This handles constructs like:
2245 typedef void OperatorFun (int fun); */
2252 } /* switch (typdef) */
2255 funcdef
= fstartlist
;
2264 if (definedef
!= dnone
)
2272 funcdef
= flistseen
;
2275 if (cblev
== 0 && typdef
== tend
)
2281 else if (parlev
< 0) /* can happen due to ill-conceived #if's. */
2285 if (definedef
!= dnone
)
2287 if (typdef
== ttypedseen
)
2291 case skeyseen
: /* unnamed struct */
2292 structtag
= "_anonymous_";
2293 structdef
= sinbody
;
2296 case scolonseen
: /* named struct */
2297 structdef
= sinbody
;
2310 /* Neutralize `extern "C" {' grot and look inside structs. */
2311 if (cblev
== 0 && structdef
== snone
&& typdef
== tnone
)
2317 if (definedef
!= dnone
)
2319 if (funcdef
== fstartlist
)
2320 funcdef
= fnone
; /* avoid tagging `foo' in `foo (*bar()) ()' */
2323 if (definedef
!= dnone
)
2325 if (!noindentypedefs
&& lp
== newlb
.buffer
+ 1)
2327 cblev
= 0; /* reset curly brace level if first column */
2328 parlev
= 0; /* also reset paren level, just in case... */
2334 if (typdef
== tinbody
)
2336 if (FALSE
) /* too risky */
2337 if (structdef
== sinbody
)
2341 structtag
= "<error>";
2345 case '#': case '+': case '-': case '~': case '&': case '%': case '/':
2346 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2347 if (definedef
!= dnone
)
2349 /* These surely cannot follow a function tag. */
2350 if (funcdef
!= finlist
&& funcdef
!= fignore
)
2354 /* If a macro spans multiple lines don't reset its state. */
2362 } /* while not eof */
2366 * Process either a C++ file or a C file depending on the setting
2370 default_C_entries (inf
)
2373 C_entries (cplusplus
? C_PLPL
: 0, inf
);
2376 /* Always do plain ANSI C. */
2378 plain_C_entries (inf
)
2384 /* Always do C++. */
2386 Cplusplus_entries (inf
)
2389 C_entries (C_PLPL
, inf
);
2397 C_entries (C_STAR
, inf
);
2400 /* Always do Yacc. */
2405 C_entries (YACC
, inf
);
2408 /* Fortran parsing */
2416 register int len
= 0;
2418 while (*cp
&& lowcase(*cp
) == lowcase(dbp
[len
]))
2420 if (*cp
== '\0' && !intoken(dbp
[len
]))
2431 while (isspace (*dbp
))
2436 while (isspace (*dbp
))
2438 if (strneq (dbp
, "(*)", 3))
2443 if (!isdigit (*dbp
))
2445 --dbp
; /* force failure */
2450 while (isdigit (*dbp
));
2459 while (isspace (*dbp
))
2464 linecharno
= charno
;
2465 charno
+= readline (&lb
, inf
);
2470 while (isspace (*dbp
))
2479 && (isalpha (*cp
) || isdigit (*cp
) || (*cp
== '_') || (*cp
== '$')));
2482 pfnote (NULL
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2486 Fortran_functions (inf
)
2495 linecharno
= charno
;
2496 charno
+= readline (&lb
, inf
);
2499 dbp
++; /* Ratfor escape to fortran */
2500 while (isspace (*dbp
))
2504 switch (lowcase (*dbp
))
2507 if (tail ("integer"))
2515 if (tail ("logical"))
2519 if (tail ("complex") || tail ("character"))
2523 if (tail ("double"))
2525 while (isspace (*dbp
))
2529 if (tail ("precision"))
2535 while (isspace (*dbp
))
2539 switch (lowcase (*dbp
))
2542 if (tail ("function"))
2546 if (tail ("subroutine"))
2554 if (tail ("program"))
2559 if (tail ("procedure"))
2567 * Bob Weiner, Motorola Inc., 4/3/94
2568 * Unix and microcontroller assembly tag handling
2569 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
2583 linecharno
= charno
;
2584 charno
+= readline (&lb
, inf
);
2587 /* If first char is alphabetic or one of [_.$], test for colon
2588 following identifier. */
2589 if (isalpha (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2591 /* Read past label. */
2593 while (isalnum (*cp
) || *cp
== '_' || *cp
== '.' || *cp
== '$')
2595 if (*cp
== ':' || isspace (*cp
))
2597 /* Found end of label, so copy it and add it to the table. */
2599 lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2605 /* Added by Mosur Mohan, 4/22/88 */
2606 /* Pascal parsing */
2608 #define GET_NEW_LINE \
2610 linecharno = charno; lineno++; \
2611 charno += 1 + readline (&lb, inf); \
2616 * Locates tags for procedures & functions. Doesn't do any type- or
2617 * var-definitions. It does look for the keyword "extern" or
2618 * "forward" immediately following the procedure statement; if found,
2619 * the tag is skipped.
2622 Pascal_functions (inf
)
2625 struct linebuffer tline
; /* mostly copied from C_entries */
2627 int save_lineno
, save_len
;
2630 logical
/* each of these flags is TRUE iff: */
2631 incomment
, /* point is inside a comment */
2632 inquote
, /* point is inside '..' string */
2633 get_tagname
, /* point is after PROCEDURE/FUNCTION
2634 keyword, so next item = potential tag */
2635 found_tag
, /* point is after a potential tag */
2636 inparms
, /* point is within parameter-list */
2637 verify_tag
; /* point has passed the parm-list, so the
2638 next token will determine whether this
2639 is a FORWARD/EXTERN to be ignored, or
2640 whether it is a real tag */
2647 initbuffer (&tline
);
2649 incomment
= inquote
= FALSE
;
2650 found_tag
= FALSE
; /* have a proc name; check if extern */
2651 get_tagname
= FALSE
; /* have found "procedure" keyword */
2652 inparms
= FALSE
; /* found '(' after "proc" */
2653 verify_tag
= FALSE
; /* check if "extern" is ahead */
2655 /* long main loop to get next char */
2659 if (c
== '\0') /* if end of line */
2664 if (!((found_tag
&& verify_tag
) ||
2666 c
= *dbp
++; /* only if don't need *dbp pointing
2667 to the beginning of the name of
2668 the procedure or function */
2672 if (c
== '}') /* within { } comments */
2674 else if (c
== '*' && *dbp
== ')') /* within (* *) comments */
2691 inquote
= TRUE
; /* found first quote */
2693 case '{': /* found open { comment */
2697 if (*dbp
== '*') /* found open (* comment */
2702 else if (found_tag
) /* found '(' after tag, i.e., parm-list */
2705 case ')': /* end of parms list */
2710 if (found_tag
&& !inparms
) /* end of proc or fn stmt */
2717 if (found_tag
&& verify_tag
&& (*dbp
!= ' '))
2719 /* check if this is an "extern" declaration */
2722 if (lowcase (*dbp
== 'e'))
2724 if (tail ("extern")) /* superfluous, really! */
2730 else if (lowcase (*dbp
) == 'f')
2732 if (tail ("forward")) /* check for forward reference */
2738 if (found_tag
&& verify_tag
) /* not external proc, so make tag */
2743 tline
.buffer
, save_len
, save_lineno
, save_lcno
);
2747 if (get_tagname
) /* grab name of proc or fn */
2754 /* save all values for later tagging */
2755 size
= strlen (lb
.buffer
) + 1;
2756 while (size
> tline
.size
)
2759 tline
.buffer
= (char *) xrealloc (tline
.buffer
, tline
.size
);
2761 strcpy (tline
.buffer
, lb
.buffer
);
2762 save_lineno
= lineno
;
2763 save_lcno
= linecharno
;
2765 /* grab block name */
2766 for (dbp
++; *dbp
&& (!endtoken (*dbp
)); dbp
++)
2768 save_len
= dbp
- lb
.buffer
+ 1;
2769 get_tagname
= FALSE
;
2773 /* and proceed to check for "extern" */
2775 else if (!incomment
&& !inquote
&& !found_tag
)
2777 /* check for proc/fn keywords */
2778 switch (lowcase (c
))
2781 if (tail ("rocedure")) /* c = 'p', dbp has advanced */
2785 if (tail ("unction"))
2790 } /* while not eof */
2792 free (tline
.buffer
);
2796 * lisp tag functions
2797 * look for (def or (DEF, quote or QUOTE
2801 register char *strp
;
2803 return ((strp
[1] == 'd' || strp
[1] == 'D')
2804 && (strp
[2] == 'e' || strp
[2] == 'E')
2805 && (strp
[3] == 'f' || strp
[3] == 'F'));
2810 register char *strp
;
2812 return ((*(++strp
) == 'q' || *strp
== 'Q')
2813 && (*(++strp
) == 'u' || *strp
== 'U')
2814 && (*(++strp
) == 'o' || *strp
== 'O')
2815 && (*(++strp
) == 't' || *strp
== 'T')
2816 && (*(++strp
) == 'e' || *strp
== 'E')
2817 && isspace(*(++strp
)));
2825 if (*dbp
== '\'') /* Skip prefix quote */
2827 else if (*dbp
== '(' && L_isquote (dbp
)) /* Skip "(quote " */
2830 while (isspace(*dbp
))
2833 for (cp
= dbp
/*+1*/;
2834 *cp
&& *cp
!= '(' && *cp
!= ' ' && *cp
!= ')';
2840 pfnote (NULL
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2844 Lisp_functions (inf
)
2853 linecharno
= charno
;
2854 charno
+= readline (&lb
, inf
);
2860 while (!isspace (*dbp
))
2862 while (isspace (*dbp
))
2868 /* Check for (foo::defmumble name-defined ... */
2871 while (*dbp
&& !isspace (*dbp
)
2872 && *dbp
!= ':' && *dbp
!= '(' && *dbp
!= ')');
2877 while (*dbp
== ':');
2879 if (L_isdef (dbp
- 1))
2881 while (!isspace (*dbp
))
2883 while (isspace (*dbp
))
2894 * Scheme tag functions
2895 * look for (def... xyzzy
2896 * look for (def... (xyzzy
2897 * look for (def ... ((...(xyzzy ....
2898 * look for (set! xyzzy
2904 Scheme_functions (inf
)
2913 linecharno
= charno
;
2914 charno
+= readline (&lb
, inf
);
2916 if (dbp
[0] == '(' &&
2917 (dbp
[1] == 'D' || dbp
[1] == 'd') &&
2918 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2919 (dbp
[3] == 'F' || dbp
[3] == 'f'))
2921 while (!isspace (*dbp
))
2923 /* Skip over open parens and white space */
2924 while (*dbp
&& (isspace (*dbp
) || *dbp
== '('))
2928 if (dbp
[0] == '(' &&
2929 (dbp
[1] == 'S' || dbp
[1] == 's') &&
2930 (dbp
[2] == 'E' || dbp
[2] == 'e') &&
2931 (dbp
[3] == 'T' || dbp
[3] == 't') &&
2932 (dbp
[4] == '!' || dbp
[4] == '!') &&
2935 while (!isspace (*dbp
))
2937 /* Skip over white space */
2938 while (isspace (*dbp
))
2952 /* Go till you get to white space or a syntactic break */
2954 *cp
&& *cp
!= '(' && *cp
!= ')' && !isspace (*cp
);
2957 pfnote (NULL
, TRUE
, lb
.buffer
, cp
- lb
.buffer
+ 1, lineno
, linecharno
);
2960 /* Find tags in TeX and LaTeX input files. */
2962 /* TEX_toktab is a table of TeX control sequences that define tags.
2963 Each TEX_tabent records one such control sequence.
2964 CONVERT THIS TO USE THE Stab TYPE!! */
2971 struct TEX_tabent
*TEX_toktab
= NULL
; /* Table with tag tokens */
2973 /* Default set of control sequences to put into TEX_toktab.
2974 The value of environment var TEXTAGS is prepended to this. */
2976 char *TEX_defenv
= "\
2977 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
2980 struct TEX_tabent
*TEX_decode_env ();
2982 #if TeX_named_tokens
2986 char TEX_esc
= '\\';
2987 char TEX_opgrp
= '{';
2988 char TEX_clgrp
= '}';
2991 * TeX/LaTeX scanning loop.
3002 /* Select either \ or ! as escape character. */
3005 /* Initialize token table once from environment. */
3007 TEX_toktab
= TEX_decode_env ("TEXTAGS", TEX_defenv
);
3010 { /* Scan each line in file */
3012 linecharno
= charno
;
3013 charno
+= readline (&lb
, inf
);
3016 while (dbp
= etags_strchr (dbp
, TEX_esc
)) /* Look at each esc in line */
3022 linecharno
+= dbp
- lasthit
;
3024 i
= TEX_Token (lasthit
);
3028 lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
3029 #if TeX_named_tokens
3030 TEX_getit (lasthit
, TEX_toktab
[i
].len
);
3032 break; /* We only save a line once */
3038 #define TEX_LESC '\\'
3039 #define TEX_SESC '!'
3042 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3043 chars accordingly. */
3050 while ((c
= getc (inf
)) != EOF
)
3052 /* Skip to next line if we hit the TeX comment char. */
3056 else if (c
== TEX_LESC
|| c
== TEX_SESC
)
3075 /* Read environment and prepend it to the default string.
3076 Build token table. */
3078 TEX_decode_env (evarname
, defenv
)
3082 register char *env
, *p
;
3084 struct TEX_tabent
*tab
;
3087 /* Append default string to environment. */
3088 env
= getenv (evarname
);
3092 env
= concat (env
, defenv
, "");
3094 /* Allocate a token table */
3095 for (size
= 1, p
= env
; p
;)
3096 if ((p
= etags_strchr (p
, ':')) && *(++p
))
3098 /* Add 1 to leave room for null terminator. */
3099 tab
= xnew (size
+ 1, struct TEX_tabent
);
3101 /* Unpack environment string into token table. Be careful about */
3102 /* zero-length strings (leading ':', "::" and trailing ':') */
3105 p
= etags_strchr (env
, ':');
3106 if (!p
) /* End of environment string. */
3107 p
= env
+ strlen (env
);
3109 { /* Only non-zero strings. */
3110 tab
[i
].name
= savenstr (env
, p
- env
);
3111 tab
[i
].len
= strlen (tab
[i
].name
);
3118 tab
[i
].name
= NULL
; /* Mark end of table. */
3126 #if TeX_named_tokens
3127 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
3128 The name being defined actually starts at (NAME + LEN + 1).
3129 But we seem to include the TeX command in the tag name. */
3131 TEX_getit (name
, len
)
3135 char *p
= name
+ len
;
3140 /* Let tag name extend to next group close (or end of line) */
3141 while (*p
&& *p
!= TEX_clgrp
)
3143 pfnote (savenstr (name
, p
-name
), TRUE
,
3144 lb
.buffer
, strlen (lb
.buffer
), lineno
, linecharno
);
3148 /* If the text at CP matches one of the tag-defining TeX command names,
3149 return the pointer to the first occurrence of that command in TEX_toktab.
3150 Otherwise return -1.
3151 Keep the capital `T' in `Token' for dumb truncating compilers
3152 (this distinguishes it from `TEX_toktab' */
3159 for (i
= 0; TEX_toktab
[i
].len
> 0; i
++)
3160 if (strneq (TEX_toktab
[i
].name
, cp
, TEX_toktab
[i
].len
))
3165 /* Support for Prolog. */
3167 /* Whole head (not only functor, but also arguments)
3168 is gotten in compound term. */
3181 if (s
[0] == '\0') /* syntax error. */
3183 else if (insquote
&& s
[0] == '\'' && s
[1] == '\'')
3185 else if (s
[0] == '\'')
3187 insquote
= !insquote
;
3190 else if (!insquote
&& s
[0] == '(')
3195 else if (!insquote
&& s
[0] == ')')
3201 else if (npar
< 0) /* syntax error. */
3204 else if (!insquote
&& s
[0] == '.'
3205 && (isspace (s
[1]) || s
[1] == '\0'))
3207 if (npar
!= 0) /* syntax error. */
3215 pfnote (NULL
, TRUE
, save_s
, s
-save_s
, lineno
, linecharno
);
3218 /* It is assumed that prolog predicate starts from column 0. */
3220 Prolog_functions (inf
)
3223 void skip_comment (), prolog_getit ();
3225 lineno
= linecharno
= charno
= 0;
3229 linecharno
+= charno
;
3230 charno
= readline (&lb
, inf
) + 1; /* 1 for newline. */
3232 if (isspace (dbp
[0])) /* not predicate header. */
3234 else if (dbp
[0] == '%') /* comment. */
3236 else if (dbp
[0] == '/' && dbp
[1] == '*') /* comment. */
3237 skip_comment (&lb
, inf
, &lineno
, &linecharno
);
3244 skip_comment (plb
, inf
, plineno
, plinecharno
)
3245 struct linebuffer
*plb
;
3247 int *plineno
; /* result */
3248 long *plinecharno
; /* result */
3254 for (cp
= plb
->buffer
; *cp
!= '\0'; cp
++)
3255 if (cp
[0] == '*' && cp
[1] == '/')
3258 *plinecharno
+= readline (plb
, inf
) + 1; /* 1 for newline. */
3263 #ifdef ETAGS_REGEXPS
3264 /* Take a string like "/blah/" and turn it into "blah", making sure
3265 that the first and last characters are the same, and handling
3266 quoted separator characters. Actually, stops on the occurence of
3267 an unquoted separator. Also turns "\t" into a Tab character.
3268 Returns pointer to terminating separator. Works in place. Null
3269 terminates name string. */
3271 scan_separators (name
)
3275 char *copyto
= name
;
3276 logical quoted
= FALSE
;
3278 for (++name
; *name
!= '\0'; ++name
)
3284 else if (*name
== sep
)
3288 /* Something else is quoted, so preserve the quote. */
3294 else if (*name
== '\\')
3296 else if (*name
== sep
)
3302 /* Terminate copied string. */
3307 /* Turn a name, which is an ed-style (but Emacs syntax) regular
3308 expression, into a real regular expression by compiling it. */
3310 add_regex (regexp_pattern
)
3311 char *regexp_pattern
;
3315 struct re_pattern_buffer
*patbuf
;
3317 if (regexp_pattern
== NULL
)
3319 /* Remove existing regexps. */
3325 if (regexp_pattern
[0] == '\0')
3327 error ("missing regexp", 0);
3330 if (regexp_pattern
[strlen(regexp_pattern
)-1] != regexp_pattern
[0])
3332 error ("%s: unterminated regexp", regexp_pattern
);
3335 name
= scan_separators (regexp_pattern
);
3336 if (regexp_pattern
[0] == '\0')
3338 error ("null regexp", 0);
3341 (void) scan_separators (name
);
3343 patbuf
= xnew (1, struct re_pattern_buffer
);
3344 patbuf
->translate
= NULL
;
3345 patbuf
->fastmap
= NULL
;
3346 patbuf
->buffer
= NULL
;
3347 patbuf
->allocated
= 0;
3349 err
= re_compile_pattern (regexp_pattern
, strlen (regexp_pattern
), patbuf
);
3352 error ("%s while compiling pattern", err
);
3357 if (num_patterns
== 1)
3358 patterns
= xnew (1, struct pattern
);
3360 patterns
= ((struct pattern
*)
3362 (num_patterns
* sizeof (struct pattern
))));
3363 patterns
[num_patterns
- 1].pattern
= patbuf
;
3364 patterns
[num_patterns
- 1].name_pattern
= savestr (name
);
3365 patterns
[num_patterns
- 1].error_signaled
= FALSE
;
3369 * Do the subtitutions indicated by the regular expression and
3373 substitute (in
, out
, regs
)
3375 struct re_registers
*regs
;
3377 char *result
= NULL
, *t
;
3380 /* Pass 1: figure out how much size to allocate. */
3381 for (t
= out
; *t
; ++t
)
3388 fprintf (stderr
, "%s: pattern subtitution ends prematurely\n",
3395 size
+= regs
->end
[dig
] - regs
->start
[dig
];
3400 /* Allocate space and do the substitutions. */
3401 result
= xnew (size
+ 1, char);
3410 /* Using "dig2" satisfies my debugger. Bleah. */
3411 int dig2
= *out
- '0';
3412 strncpy (result
+ size
, in
+ regs
->start
[dig2
],
3413 regs
->end
[dig2
] - regs
->start
[dig2
]);
3414 size
+= regs
->end
[dig2
] - regs
->start
[dig2
];
3421 result
[size
++] = '\t';
3427 result
[size
++] = *out
;
3433 result
[size
++] = *out
;
3435 result
[size
] = '\0';
3440 #endif /* ETAGS_REGEXPS */
3441 /* Initialize a linebuffer for use */
3443 initbuffer (linebuffer
)
3444 struct linebuffer
*linebuffer
;
3446 linebuffer
->size
= 200;
3447 linebuffer
->buffer
= xnew (200, char);
3451 * Read a line of text from `stream' into `linebuffer'.
3452 * Return the number of characters read from `stream',
3453 * which is the length of the line including the newline, if any.
3456 readline_internal (linebuffer
, stream
)
3457 struct linebuffer
*linebuffer
;
3458 register FILE *stream
;
3460 char *buffer
= linebuffer
->buffer
;
3461 register char *p
= linebuffer
->buffer
;
3462 register char *pend
;
3465 pend
= p
+ linebuffer
->size
; /* Separate to avoid 386/IX compiler bug. */
3469 register int c
= getc (stream
);
3472 linebuffer
->size
*= 2;
3473 buffer
= (char *) xrealloc (buffer
, linebuffer
->size
);
3474 p
+= buffer
- linebuffer
->buffer
;
3475 pend
= buffer
+ linebuffer
->size
;
3476 linebuffer
->buffer
= buffer
;
3485 if (p
> buffer
&& p
[-1] == '\r')
3500 return p
- buffer
+ chars_deleted
;
3504 * Like readline_internal, above, but try to match the input
3505 * line against any existing regular expressions.
3508 readline (linebuffer
, stream
)
3509 struct linebuffer
*linebuffer
;
3512 /* Read new line. */
3514 long result
= readline_internal (linebuffer
, stream
);
3516 #ifdef ETAGS_REGEXPS
3517 /* Match against all listed patterns. */
3518 for (i
= 0; i
< num_patterns
; ++i
)
3520 int match
= re_match (patterns
[i
].pattern
, linebuffer
->buffer
,
3521 (int)result
, 0, &patterns
[i
].regs
);
3526 if (!patterns
[i
].error_signaled
)
3528 error ("error while matching pattern %d", i
);
3529 patterns
[i
].error_signaled
= TRUE
;
3536 /* Match occurred. Construct a tag. */
3537 if (patterns
[i
].name_pattern
[0] != '\0')
3539 /* Make a named tag. */
3540 char *name
= substitute (linebuffer
->buffer
,
3541 patterns
[i
].name_pattern
,
3545 linebuffer
->buffer
, match
, lineno
, linecharno
);
3549 /* Make an unnamed tag. */
3551 linebuffer
->buffer
, match
, lineno
, linecharno
);
3556 #endif /* ETAGS_REGEXPS */
3562 * Read a file, but do no processing. This is used to do regexp
3563 * matching on files that have no language defined.
3566 just_read_file (inf
)
3572 linecharno
= charno
;
3573 charno
+= readline (&lb
, inf
) + 1;
3579 * Return a pointer to a space of size strlen(cp)+1 allocated
3580 * with xnew where the string CP has been copied.
3586 return savenstr (cp
, strlen (cp
));
3590 * Return a pointer to a space of size LEN+1 allocated with xnew where
3591 * the string CP has been copied for at most the first LEN characters.
3600 dp
= xnew (len
+ 1, char);
3601 strncpy (dp
, cp
, len
);
3607 * Return the ptr in sp at which the character c last
3608 * appears; NULL if not found
3610 * Identical to System V strrchr, included for portability.
3613 etags_strrchr (sp
, c
)
3614 register char *sp
, c
;
3629 * Return the ptr in sp at which the character c first
3630 * appears; NULL if not found
3632 * Identical to System V strchr, included for portability.
3635 etags_strchr (sp
, c
)
3636 register char *sp
, c
;
3646 /* Print error message and exit. */
3663 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
3668 fprintf (stderr
, "%s: ", progname
);
3669 fprintf (stderr
, s1
, s2
);
3670 fprintf (stderr
, "\n");
3673 /* Return a newly-allocated string whose contents
3674 concatenate those of s1, s2, s3. */
3679 int len1
= strlen (s1
), len2
= strlen (s2
), len3
= strlen (s3
);
3680 char *result
= xnew (len1
+ len2
+ len3
+ 1, char);
3682 strcpy (result
, s1
);
3683 strcpy (result
+ len1
, s2
);
3684 strcpy (result
+ len1
+ len2
, s3
);
3685 result
[len1
+ len2
+ len3
] = '\0';
3690 /* Does the same work as the system V getcwd, but does not need to
3691 guess buffer size in advance. */
3696 char *p
, path
[MAXPATHLEN
+ 1]; /* Fixed size is safe on MSDOS. */
3704 *p
++ = tolower (*p
);
3706 return strdup (path
);
3707 #else /* not DOS_NT */
3710 char *path
= xnew (bufsize
, char);
3712 while (getcwd (path
, bufsize
) == NULL
)
3714 if (errno
!= ERANGE
)
3717 path
= xnew (bufsize
, char);
3721 #else /* not DOS_NT and not HAVE_GETCWD */
3722 struct linebuffer path
;
3726 pipe
= (FILE *) popen ("pwd 2>/dev/null", "r");
3727 if (pipe
== NULL
|| readline_internal (&path
, pipe
) == 0)
3732 #endif /* not HAVE_GETCWD */
3733 #endif /* not DOS_NT */
3736 /* Return a newly allocated string containing the filename
3737 of FILE relative to the absolute directory DIR (which
3738 should end with a slash). */
3740 relative_filename (file
, dir
)
3743 char *fp
, *dp
, *abs
, *res
;
3745 /* Find the common root of file and dir. */
3746 abs
= absolute_filename (file
, cwd
);
3749 while (*fp
++ == *dp
++)
3758 /* Build a sequence of "../" strings for the resulting relative filename. */
3759 for (dp
= etags_strchr (dp
+ 1, '/'), res
= "";
3761 dp
= etags_strchr (dp
+ 1, '/'))
3763 res
= concat (res
, "../", "");
3766 /* Add the filename relative to the common root of file and dir. */
3767 res
= concat (res
, fp
+ 1, "");
3773 /* Return a newly allocated string containing the
3774 absolute filename of FILE given CWD (which should
3775 end with a slash). */
3777 absolute_filename (file
, cwd
)
3780 char *slashp
, *cp
, *res
;
3782 if (absolutefn (file
))
3783 res
= concat (file
, "", "");
3785 res
= concat (cwd
, file
, "");
3787 /* Delete the "/dirname/.." and "/." substrings. */
3788 slashp
= etags_strchr (res
, '/');
3789 while (slashp
!= NULL
&& slashp
[0] != '\0')
3791 if (slashp
[1] == '.')
3793 if (slashp
[2] == '.'
3794 && (slashp
[3] == '/' || slashp
[3] == '\0'))
3799 while (cp
>= res
&& *cp
!= '/');
3802 strcpy (cp
, slashp
+ 3);
3804 else /* else (cp == res) */
3806 if (slashp
[3] != '\0')
3807 strcpy (cp
, slashp
+ 4);
3814 else if (slashp
[2] == '/' || slashp
[2] == '\0')
3816 strcpy (slashp
, slashp
+ 2);
3821 slashp
= etags_strchr (slashp
+ 1, '/');
3827 /* Return a newly allocated string containing the absolute
3828 filename of dir where FILE resides given CWD (which should
3829 end with a slash). */
3831 absolute_dirname (file
, cwd
)
3837 slashp
= etags_strrchr (file
, '/');
3842 res
= absolute_filename (file
, cwd
);
3848 /* Like malloc but get fatal error if memory is exhausted. */
3853 long *result
= (long *) malloc (size
);
3855 fatal ("virtual memory exhausted", 0);
3860 xrealloc (ptr
, size
)
3864 long *result
= (long *) realloc (ptr
, size
);
3866 fatal ("virtual memory exhausted");