comparison lib-src/etags.c @ 4:b82b59fe008d r19-15b3

Import from CVS: tag r19-15b3
author cvs
date Mon, 13 Aug 2007 08:46:56 +0200
parents ac2d302a0011
children 34a5b81f86ba
comparison
equal deleted inserted replaced
3:30df88044ec6 4:b82b59fe008d
1 /* Tags file maker to go with GNU Emacs 1 /* Tags file maker to go with GNU Emacs
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95 2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95
3 Free Software Foundation, Inc. and Ken Arnold 3 Free Software Foundation, Inc. and Ken Arnold
4
4 This file is not considered part of GNU Emacs. 5 This file is not considered part of GNU Emacs.
5 6
6 This program is free software; you can redistribute it and/or modify 7 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 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 the Free Software Foundation; either version 2 of the License, or
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 15 GNU General Public License for more details.
15 16
16 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to 18 along with this program; if not, write to the Free Software Foundation,
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 Boston, MA 02111-1307, USA. */
20
21 /* Synched up with: FSF 19.30. */
22 20
23 /* 21 /*
24 * Authors: 22 * Authors:
25 * Ctags originally by Ken Arnold. 23 * Ctags originally by Ken Arnold.
26 * Fortran added by Jim Kleckner. 24 * Fortran added by Jim Kleckner.
27 * Ed Pelegri-Llopart added C typedefs. 25 * Ed Pelegri-Llopart added C typedefs.
28 * Gnu Emacs TAGS format and modifications by RMS? 26 * Gnu Emacs TAGS format and modifications by RMS?
29 * Sam Kendall added C++. 27 * Sam Kendall added C++.
30 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells. 28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells.
31 #ifdef ETAGS_REGEXPS
32 * Regexp tags by Tom Tromey. 29 * Regexp tags by Tom Tromey.
33 #endif
34 * 30 *
35 * Francesco Potorti` (pot@cnuce.cnr.it) is the current maintainer. 31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer.
36 */ 32 */
37 33
38 char pot_etags_version[] = "@(#) pot revision number is 11.45"; 34 char pot_etags_version[] = "@(#) pot revision number is 11.78";
39 35
40 #define TRUE 1 36 #define TRUE 1
41 #define FALSE 0 37 #define FALSE 0
38
42 #ifndef DEBUG 39 #ifndef DEBUG
43 # define DEBUG FALSE 40 # define DEBUG FALSE
44 #endif 41 #endif
45 42
46 #ifdef MSDOS 43 #ifdef MSDOS
47 #include <fcntl.h> 44 # include <string.h>
48 #include <sys/param.h> 45 # include <fcntl.h>
46 # include <sys/param.h>
49 #endif /* MSDOS */ 47 #endif /* MSDOS */
50 48
51 #ifdef WINDOWSNT 49 #ifdef WINDOWSNT
50 # include <stdlib.h>
51 # include <fcntl.h>
52 # include <string.h>
53 # include <io.h>
54 # define MAXPATHLEN _MAX_PATH
55 #endif
56
57 #if !defined (MSDOS) && !defined (WINDOWSNT) && defined (STDC_HEADERS)
52 #include <stdlib.h> 58 #include <stdlib.h>
53 #include <fcntl.h>
54 #include <string.h> 59 #include <string.h>
55 #define MAXPATHLEN _MAX_PATH
56 #endif 60 #endif
57 61
58 #ifdef HAVE_CONFIG_H 62 #ifdef HAVE_CONFIG_H
59 #include <../src/config.h> 63 # include <config.h>
60 /* On some systems, Emacs defines static as nothing for the sake 64 /* On some systems, Emacs defines static as nothing for the sake
61 of unexec. We don't want that here since we don't use unexec. */ 65 of unexec. We don't want that here since we don't use unexec. */
62 #undef static 66 # undef static
63 #endif
64
65 #if __STDC__ || defined(STDC_HEADERS)
66 #include <stdlib.h>
67 #include <unistd.h>
68 #include <string.h>
69 #else
70 extern char *getenv ();
71 #endif 67 #endif
72 68
73 #include <stdio.h> 69 #include <stdio.h>
74 #include <ctype.h> 70 #include <ctype.h>
75 #include <errno.h> 71 #include <errno.h>
84 #endif 80 #endif
85 81
86 #include <getopt.h> 82 #include <getopt.h>
87 83
88 #ifdef ETAGS_REGEXPS 84 #ifdef ETAGS_REGEXPS
89 #include <regex.h> 85 # include <regex.h>
90 #endif /* ETAGS_REGEXPS */ 86 #endif /* ETAGS_REGEXPS */
91 87
92 /* Define CTAGS to make the program "ctags" compatible with the usual one. 88 /* Define CTAGS to make the program "ctags" compatible with the usual one.
93 Let it undefined to make the program "etags", which makes emacs-style 89 Let it undefined to make the program "etags", which makes emacs-style
94 tag tables and tags typedefs, #defines and struct/union/enum by default. */ 90 tag tables and tags typedefs, #defines and struct/union/enum by default. */
99 # define CTAGS FALSE 95 # define CTAGS FALSE
100 #endif 96 #endif
101 97
102 /* Exit codes for success and failure. */ 98 /* Exit codes for success and failure. */
103 #ifdef VMS 99 #ifdef VMS
104 #define GOOD 1 100 # define GOOD 1
105 #define BAD 0 101 # define BAD 0
106 #else 102 #else
107 #define GOOD 0 103 # define GOOD 0
108 #define BAD 1 104 # define BAD 1
109 #endif 105 #endif
110 106
111 /* C extensions. */ 107 /* C extensions. */
112 #define C_PLPL 0x00001 /* C++ */ 108 #define C_PLPL 0x00001 /* C++ */
113 #define C_STAR 0x00003 /* C* */ 109 #define C_STAR 0x00003 /* C* */
114 #define YACC 0x10000 /* yacc file */ 110 #define YACC 0x10000 /* yacc file */
115 111
116 #define streq(s,t) (strcmp (s, t) == 0) 112 #define streq(s,t) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strcmp(s,t))
117 #define strneq(s,t,n) (strncmp (s, t, n) == 0) 113 #define strneq(s,t,n) ((DEBUG &&!(s)&&!(t)&&(abort(),1)) || !strncmp(s,t,n))
118 114
119 #define lowcase(c) tolower ((unsigned char)c) 115 #define lowcase(c) tolower ((char)c)
120 116
121 #define iswhite(arg) (_wht[(unsigned int) arg]) /* T if char is white */ 117 #define iswhite(arg) (_wht[arg]) /* T if char is white */
122 #define begtoken(arg) (_btk[(unsigned int) arg]) /* T if char can start token */ 118 #define begtoken(arg) (_btk[arg]) /* T if char can start token */
123 #define intoken(arg) (_itk[(unsigned int) arg]) /* T if char can be in token */ 119 #define intoken(arg) (_itk[arg]) /* T if char can be in token */
124 #define endtoken(arg) (_etk[(unsigned int) arg]) /* T if char ends tokens */ 120 #define endtoken(arg) (_etk[arg]) /* T if char ends tokens */
125
126 /* typedefs from down below, moved up for prototypes */
127
128 /*
129 * A `struct linebuffer' is a structure which holds a line of text.
130 * `readline' reads a line from a stream into a linebuffer and works
131 * regardless of the length of the line.
132 */
133 struct linebuffer
134 {
135 long size;
136 char *buffer;
137 };
138 121
139 #ifdef DOS_NT 122 #ifdef DOS_NT
140 # define absolutefn(fn) (fn[0] == '/' || (isalpha (fn[0]) && fn[1] == ':')) 123 # define absolutefn(fn) (fn[0] == '/' \
124 || (fn[1] == ':' && fn[2] == '/'))
141 #else 125 #else
142 # define absolutefn(fn) (fn[0] == '/') 126 # define absolutefn(fn) (fn[0] == '/')
143 #endif 127 #endif
144 128
145 129
151 #define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) 135 #define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
152 136
153 typedef int logical; 137 typedef int logical;
154 138
155 typedef struct nd_st 139 typedef struct nd_st
156 { /* sorting structure */ 140 { /* sorting structure */
157 char *name; /* function or type name */ 141 char *name; /* function or type name */
158 char *file; /* file name */ 142 char *file; /* file name */
159 logical is_func; /* use pattern or line no */ 143 logical is_func; /* use pattern or line no */
160 logical been_warned; /* set if noticed dup */ 144 logical been_warned; /* set if noticed dup */
161 long lno; /* line number tag is on */ 145 int lno; /* line number tag is on */
162 long cno; /* character number line starts on */ 146 long cno; /* character number line starts on */
163 char *pat; /* search pattern */ 147 char *pat; /* search pattern */
164 struct nd_st *left, *right; /* left and right sons */ 148 struct nd_st *left, *right; /* left and right sons */
165 } NODE; 149 } NODE;
166 150
167 extern char *getenv (); 151 extern char *getenv ();
168 152
169 char *concat (CONST char *s1, CONST char *s2, CONST char *s3); 153 char *concat ();
170 char *savenstr (CONST char *cp, int len); 154 char *savenstr (), *savestr ();
171 char *savestr (CONST char *cp); 155 char *etags_strchr (), *etags_strrchr ();
172 char *etags_strchr (CONST char *sp, char c); 156 char *etags_getcwd ();
173 char *etags_strrchr (CONST char *sp, char c); 157 char *relative_filename (), *absolute_filename (), *absolute_dirname ();
174 char *etags_getcwd (void); 158 void grow_linebuffer ();
175 char *relative_filename (CONST char *file, CONST char *dir); 159 long *xmalloc (), *xrealloc ();
176 char *absolute_filename (CONST char *file, CONST char *cwd);
177 char *absolute_dirname (char *file, CONST char *cwd);
178 void *xmalloc (unsigned int size);
179 void *xrealloc (void *ptr, unsigned int size);
180 160
181 typedef void Lang_function (); 161 typedef void Lang_function ();
182 #if FALSE /* many compilers barf on this */ 162 #if FALSE /* many compilers barf on this */
183 Lang_function Asm_labels; 163 Lang_function Asm_labels;
184 Lang_function default_C_entries; 164 Lang_function default_C_entries;
185 Lang_function C_entries; 165 Lang_function C_entries;
186 Lang_function Cplusplus_entries; 166 Lang_function Cplusplus_entries;
187 Lang_function Cstar_entries; 167 Lang_function Cstar_entries;
168 Lang_function Erlang_functions;
188 Lang_function Fortran_functions; 169 Lang_function Fortran_functions;
189 Lang_function Yacc_entries; 170 Lang_function Yacc_entries;
190 Lang_function Lisp_functions; 171 Lang_function Lisp_functions;
191 Lang_function Pascal_functions; 172 Lang_function Pascal_functions;
192 Lang_function Perl_functions; 173 Lang_function Perl_functions;
193 Lang_function Postscript_functions;
194 Lang_function Prolog_functions; 174 Lang_function Prolog_functions;
195 Lang_function Scheme_functions; 175 Lang_function Scheme_functions;
196 Lang_function TeX_functions; 176 Lang_function TeX_functions;
197 Lang_function just_read_file; 177 Lang_function just_read_file;
198 #else /* so let's write it this way */ 178 #else /* so let's write it this way */
199 void Asm_labels (FILE *inf); 179 void Asm_labels ();
200 void C_entries (int c_ext, FILE *inf); 180 void C_entries ();
201 void default_C_entries (FILE *inf); 181 void default_C_entries ();
202 void plain_C_entries (FILE *inf); 182 void plain_C_entries ();
203 void Cplusplus_entries (FILE *inf); 183 void Cplusplus_entries ();
204 void Cstar_entries (FILE *inf); 184 void Cstar_entries ();
205 void Fortran_functions (FILE *inf); 185 void Erlang_functions ();
206 void Yacc_entries (FILE *inf); 186 void Fortran_functions ();
207 void Lisp_functions (FILE *inf); 187 void Yacc_entries ();
208 void Pascal_functions (FILE *inf); 188 void Lisp_functions ();
209 void Perl_functions (FILE *inf); 189 void Pascal_functions ();
210 void Postscript_functions (FILE *inf); 190 void Perl_functions ();
211 void Prolog_functions (FILE *inf); 191 void Prolog_functions ();
212 void Scheme_functions (FILE *inf); 192 void Scheme_functions ();
213 void TeX_functions (FILE *inf); 193 void TeX_functions ();
214 void just_read_file (FILE *inf); 194 void just_read_file ();
215 #endif 195 #endif
216 196
217 Lang_function *get_language_from_name (char *name); 197 Lang_function *get_language_from_name ();
218 Lang_function *get_language_from_interpreter (char *interpreter); 198 Lang_function *get_language_from_interpreter ();
219 Lang_function *get_language_from_suffix (CONST char *suffix); 199 Lang_function *get_language_from_suffix ();
220 int total_size_of_entries (NODE *node); 200 int total_size_of_entries ();
221 long readline (struct linebuffer *linebuffer, FILE *stream); 201 long readline ();
222 long readline_internal (struct linebuffer *linebuffer, FILE *stream); 202 long readline_internal ();
223 #ifdef ETAGS_REGEXPS 203 #ifdef ETAGS_REGEXPS
224 void add_regex (char *regexp_pattern); 204 void add_regex ();
225 #endif 205 #endif
226 void add_node (NODE *node, NODE **cur_node_p); 206 void add_node ();
227 void error (CONST char *s1, CONST void *s2); 207 void error ();
228 void fatal (CONST char *s1, CONST char *s2); 208 void suggest_asking_for_help ();
229 void pfatal (CONST char *s1); 209 void fatal (), pfatal ();
230 void find_entries (CONST char *file, FILE *inf); 210 void find_entries ();
231 void free_tree (NODE *); 211 void free_tree ();
232 void getit (FILE *inf); 212 void getit ();
233 void init (void); 213 void init ();
234 void initbuffer (struct linebuffer *linebuffer); 214 void initbuffer ();
235 void pfnote (char *name, logical is_func, char *linestart, 215 void pfnote ();
236 int linelen, int lno, long cno); 216 void process_file ();
237 void process_file (CONST char *file); 217 void put_entries ();
238 void put_entries (NODE *node); 218 void takeprec ();
239 void takeprec (void);
240 219
241 220
242 char searchar = '/'; /* use /.../ searches */ 221 char searchar = '/'; /* use /.../ searches */
243 222
244 int lineno; /* line number of current line */ 223 int lineno; /* line number of current line */
245 long charno; /* current character number */ 224 long charno; /* current character number */
246 225 long linecharno; /* charno of start of line */
247 long linecharno; /* charno of start of line; not used by C,
248 but by every other language. */
249 226
250 char *curfile; /* current input file name */ 227 char *curfile; /* current input file name */
251 char *tagfile; /* output file */ 228 char *tagfile; /* output file */
252 CONST char *progname; /* name this program was invoked with */ 229 char *progname; /* name this program was invoked with */
253 char *cwd; /* current working directory */ 230 char *cwd; /* current working directory */
254 char *tagfiledir; /* directory of tagfile */ 231 char *tagfiledir; /* directory of tagfile */
255 232
256 FILE *tagf; /* ioptr for tags file */ 233 FILE *tagf; /* ioptr for tags file */
257 NODE *head; /* the head of the binary tree of tags */ 234 NODE *head; /* the head of the binary tree of tags */
258 235
236 /*
237 * A `struct linebuffer' is a structure which holds a line of text.
238 * `readline' reads a line from a stream into a linebuffer and works
239 * regardless of the length of the line.
240 */
241 struct linebuffer
242 {
243 long size;
244 char *buffer;
245 };
246
259 struct linebuffer lb; /* the current line */ 247 struct linebuffer lb; /* the current line */
260 struct linebuffer token_name; /* used by C_entries as temporary area */ 248 struct linebuffer token_name; /* used by C_entries as a temporary area */
261 struct 249 struct
262 { 250 {
263 long linepos; 251 long linepos;
264 struct linebuffer lb; /* used by C_entries instead of lb */ 252 struct linebuffer lb; /* used by C_entries instead of lb */
265 } lbs[2]; 253 } lbs[2];
266 254
267 /* boolean "functions" (see init) */ 255 /* boolean "functions" (see init) */
268 logical _wht[0177], _etk[0177], _itk[0177], _btk[0177]; 256 logical _wht[0177], _etk[0177], _itk[0177], _btk[0177];
269 CONST char 257 char
270 *white = " \f\t\n\013", /* white chars */ 258 /* white chars */
271 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?", /* token ending chars */ 259 *white = " \f\t\n\013",
272 /* token starting chars */ 260 /* token ending chars */
273 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~", 261 *endtk = " \t\n\013\"'#()[]{}=-+%*/&|^~!<>;,.:?",
274 /* valid in-token chars */ 262 /* token starting chars */
275 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; 263 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$~@",
264 /* valid in-token chars */
265 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
276 266
277 logical append_to_tagfile; /* -a: append to tags */ 267 logical append_to_tagfile; /* -a: append to tags */
278 /* The following three default to TRUE for etags, but to FALSE for ctags. */ 268 /* The following three default to TRUE for etags, but to FALSE for ctags. */
279 logical typedefs; /* -t: create tags for typedefs */ 269 logical typedefs; /* -t: create tags for typedefs */
280 logical typedefs_and_cplusplus; /* -T: create tags for typedefs, level */ 270 logical typedefs_and_cplusplus; /* -T: create tags for typedefs, level */
281 /* 0 struct/enum/union decls, and C++ */ 271 /* 0 struct/enum/union decls, and C++ */
282 /* member functions. */ 272 /* member functions. */
283 logical constantypedefs; /* -d: create tags for C #define and enum */ 273 logical constantypedefs; /* -d: create tags for C #define and enum */
284 /* constants. Enum consts not implemented. */ 274 /* constants. */
285 /* -D: opposite of -d. Default under ctags. */ 275 /* -D: opposite of -d. Default under ctags. */
286 logical update; /* -u: update tags */ 276 logical update; /* -u: update tags */
287 logical vgrind_style; /* -v: create vgrind style index output */ 277 logical vgrind_style; /* -v: create vgrind style index output */
288 logical no_warnings; /* -w: suppress warnings */ 278 logical no_warnings; /* -w: suppress warnings */
289 logical cxref_style; /* -x: create cxref style output */ 279 logical cxref_style; /* -x: create cxref style output */
339 329
340 /* Non-NULL if language fixed. */ 330 /* Non-NULL if language fixed. */
341 Lang_function *lang_func = NULL; 331 Lang_function *lang_func = NULL;
342 332
343 /* Assembly code */ 333 /* Assembly code */
344 CONST char *Asm_suffixes [] = { "a", /* Unix assembler */ 334 char *Asm_suffixes [] = { "a", /* Unix assembler */
345 "asm", /* Microcontroller assembly */ 335 "asm", /* Microcontroller assembly */
346 "def", /* BSO/Tasking definition includes */ 336 "def", /* BSO/Tasking definition includes */
347 "inc", /* Microcontroller include files */ 337 "inc", /* Microcontroller include files */
348 "ins", /* Microcontroller include files */ 338 "ins", /* Microcontroller include files */
349 "s", "sa", /* Unix assembler */ 339 "s", "sa", /* Unix assembler */
351 NULL 341 NULL
352 }; 342 };
353 343
354 /* Note that .c and .h can be considered C++, if the --c++ flag was 344 /* Note that .c and .h can be considered C++, if the --c++ flag was
355 given. That is why default_C_entries is called here. */ 345 given. That is why default_C_entries is called here. */
356 CONST char *default_C_suffixes [] = 346 char *default_C_suffixes [] =
357 { "c", "h", NULL }; 347 { "c", "h", NULL };
358 348
359 /* C++ file */ 349 /* .M is for Objective C++ files. */
360 CONST char *Cplusplus_suffixes [] = 350 char *Cplusplus_suffixes [] =
361 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", 351 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", "M", NULL};
362 /* XEmacs addition: Postscript with C syntax */ 352
363 "pdb", NULL }; 353 char *Cstar_suffixes [] =
364
365 /* C* file */
366 CONST char *Cstar_suffixes [] =
367 { "cs", "hs", NULL }; 354 { "cs", "hs", NULL };
368 355
369 /* Fortran */ 356 char *Erlang_suffixes [] =
370 CONST char *Fortran_suffixes [] = 357 { "erl", "hrl", NULL };
358
359 char *Fortran_suffixes [] =
371 { "F", "f", "f90", "for", NULL }; 360 { "F", "f", "f90", "for", NULL };
372 361
373 /* Lisp source code */ 362 char *Lisp_suffixes [] =
374 CONST char *Lisp_suffixes [] =
375 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL }; 363 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL };
376 364
377 /* Pascal file */ 365 char *Pascal_suffixes [] =
378 CONST char *Pascal_suffixes [] =
379 { "p", "pas", NULL }; 366 { "p", "pas", NULL };
380 367
381 /* Perl file */ 368 char *Perl_suffixes [] =
382 CONST char *Perl_suffixes [] =
383 { "pl", "pm", NULL }; 369 { "pl", "pm", NULL };
384 CONST char *Perl_interpreters [] = 370 char *Perl_interpreters [] =
385 { "perl", NULL }; 371 { "perl", "@PERL@", NULL };
386 372
387 /* Pro*C file. */ 373 char *plain_C_suffixes [] =
388 CONST char *plain_C_suffixes [] = 374 { "pc", /* Pro*C file */
389 { "pc", NULL }; 375 "m", /* Objective C file */
390 376 "lm", /* Objective lex file */
391 /* XEmacs addition */ 377 NULL };
392 /* Postscript source code */ 378
393 CONST char *Postscript_suffixes [] = 379 char *Prolog_suffixes [] =
394 { "ps", NULL };
395
396 /* Prolog source code */
397 CONST char *Prolog_suffixes [] =
398 { "prolog", NULL }; 380 { "prolog", NULL };
399 381
400 /* Scheme source code */ 382 /* Can't do the `SCM' or `scm' prefix with a version number. */
401 /* FIXME Can't do the `SCM' or `scm' prefix with a version number */ 383 char *Scheme_suffixes [] =
402 CONST char *Scheme_suffixes [] =
403 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL }; 384 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "t", NULL };
404 385
405 /* TeX/LaTeX source code */ 386 char *TeX_suffixes [] =
406 CONST char *TeX_suffixes [] = 387 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL };
407 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL }; 388
408 389 char *Yacc_suffixes [] =
409 /* Yacc file */ 390 { "y", "ym", NULL }; /* .ym is Objective yacc file */
410 CONST char *Yacc_suffixes [] =
411 { "y", NULL };
412 391
413 /* Table of language names and corresponding functions, file suffixes 392 /* Table of language names and corresponding functions, file suffixes
414 and interpreter names. 393 and interpreter names.
415 It is ok for a given function to be listed under more than one 394 It is ok for a given function to be listed under more than one
416 name. I just didn't. */ 395 name. I just didn't. */
417 struct lang_entry 396 struct lang_entry
418 { 397 {
419 CONST char *name; 398 char *name;
420 Lang_function *function; 399 Lang_function *function;
421 CONST char **suffixes; 400 char **suffixes;
422 CONST char **interpreters; 401 char **interpreters;
423 }; 402 };
424 403
425 CONST struct lang_entry lang_names [] = 404 struct lang_entry lang_names [] =
426 { 405 {
427 { "asm", Asm_labels, Asm_suffixes }, 406 { "asm", Asm_labels, Asm_suffixes, NULL },
428 { "c", default_C_entries, default_C_suffixes }, 407 { "c", default_C_entries, default_C_suffixes, NULL },
429 { "c++", Cplusplus_entries, Cplusplus_suffixes }, 408 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL },
430 { "c*", Cstar_entries, Cstar_suffixes }, 409 { "c*", Cstar_entries, Cstar_suffixes, NULL },
431 { "fortran", Fortran_functions, Fortran_suffixes }, 410 { "erlang", Erlang_functions, Erlang_suffixes, NULL },
432 { "lisp", Lisp_functions, Lisp_suffixes }, 411 { "fortran", Fortran_functions, Fortran_suffixes, NULL },
433 { "pascal", Pascal_functions, Pascal_suffixes }, 412 { "lisp", Lisp_functions, Lisp_suffixes, NULL },
434 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters }, 413 { "pascal", Pascal_functions, Pascal_suffixes, NULL },
435 { "proc", plain_C_entries, plain_C_suffixes }, 414 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters },
436 { "prolog", Prolog_functions, Prolog_suffixes }, 415 { "proc", plain_C_entries, plain_C_suffixes, NULL },
437 { "postscript", Postscript_functions, Postscript_suffixes }, 416 { "prolog", Prolog_functions, Prolog_suffixes, NULL },
438 { "scheme" , Scheme_functions, Scheme_suffixes }, 417 { "scheme", Scheme_functions, Scheme_suffixes, NULL },
439 { "tex", TeX_functions, TeX_suffixes }, 418 { "tex", TeX_functions, TeX_suffixes, NULL },
440 { "yacc", Yacc_entries, Yacc_suffixes }, 419 { "yacc", Yacc_entries, Yacc_suffixes, NULL },
441 { "auto", NULL }, /* default guessing scheme */ 420 { "auto", NULL }, /* default guessing scheme */
442 { "none", just_read_file }, /* regexp matching only */ 421 { "none", just_read_file }, /* regexp matching only */
443 { NULL, NULL } /* end of list */ 422 { NULL, NULL } /* end of list */
444 }; 423 };
445 424
446 425
447 static void 426 void
448 print_language_names (void) 427 print_language_names ()
449 { 428 {
450 CONST struct lang_entry *lang; 429 struct lang_entry *lang;
451 CONST char **ext; 430 char **ext;
452 431
453 puts ("\nThese are the currently supported languages, along with the\n\ 432 puts ("\nThese are the currently supported languages, along with the\n\
454 default file name suffixes:"); 433 default file name suffixes:");
455 for (lang = lang_names; lang->name != NULL; lang++) 434 for (lang = lang_names; lang->name != NULL; lang++)
456 { 435 {
469 } 448 }
470 449
471 #ifndef VERSION 450 #ifndef VERSION
472 # define VERSION "19" 451 # define VERSION "19"
473 #endif 452 #endif
474 static void 453 void
475 print_version (void) 454 print_version ()
476 { 455 {
477 printf ("%s for Emacs version %s\n", (CTAGS) ? "ctags" : "etags", VERSION); 456 printf ("%s (GNU Emacs %s)\n", (CTAGS) ? "ctags" : "etags", VERSION);
457 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold");
458 puts ("This program is distributed under the same terms as Emacs");
478 459
479 exit (GOOD); 460 exit (GOOD);
480 } 461 }
481 462
482 static void 463 void
483 print_help (void) 464 print_help ()
484 { 465 {
485 printf ("These are the options accepted by %s. You may use unambiguous\n\ 466 printf ("These are the options accepted by %s. You may use unambiguous\n\
486 abbreviations for the long option names. A - as file name means read\n\ 467 abbreviations for the long option names. A - as file name means read\n\
487 names from stdin.\n\n", progname); 468 names from stdin.", progname);
469 if (!CTAGS)
470 printf (" Absolute names are stored in the output file as they\n\
471 are. Relative ones are stored relative to the output file's directory.");
472 puts ("\n");
488 473
489 puts ("-a, --append\n\ 474 puts ("-a, --append\n\
490 Append tag entries to existing tags file."); 475 Append tag entries to existing tags file.");
491 476
492 if (CTAGS) 477 if (CTAGS)
497 puts ("-C, --c++\n\ 482 puts ("-C, --c++\n\
498 Treat files whose name suffix defaults to C language as C++ files."); 483 Treat files whose name suffix defaults to C language as C++ files.");
499 484
500 if (CTAGS) 485 if (CTAGS)
501 puts ("-d, --defines\n\ 486 puts ("-d, --defines\n\
502 Create tag entries for constant C #defines, too."); 487 Create tag entries for C #define constants and enum constants, too.");
503 else 488 else
504 puts ("-D, --no-defines\n\ 489 puts ("-D, --no-defines\n\
505 Don't create tag entries for constant C #defines. This makes\n\ 490 Don't create tag entries for C #define constants and enum constants.\n\
506 the tags file smaller."); 491 This makes the tags file smaller.");
507 492
508 if (!CTAGS) 493 if (!CTAGS)
509 { 494 {
510 puts ("-i FILE, --include=FILE\n\ 495 puts ("-i FILE, --include=FILE\n\
511 Include a note in tag file indicating that, when searching for\n\ 496 Include a note in tag file indicating that, when searching for\n\
567 -h, --help\n\ 552 -h, --help\n\
568 Print this help message."); 553 Print this help message.");
569 554
570 print_language_names (); 555 print_language_names ();
571 556
557 puts ("");
558 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu");
559
572 exit (GOOD); 560 exit (GOOD);
573 } 561 }
574 562
575 563
576 #ifdef ETAGS_REGEXPS
577 enum argument_type 564 enum argument_type
578 { 565 {
579 at_language, 566 at_language,
580 at_regexp, 567 at_regexp,
581 at_filename 568 at_filename
582 }; 569 };
583 #else /* !ETAGS_REGEXPS */
584 enum argument_type
585 {
586 at_language,
587 at_filename
588 };
589 #endif /* !ETAGS_REGEXPS */
590 570
591 /* This structure helps us allow mixing of --lang and filenames. */ 571 /* This structure helps us allow mixing of --lang and filenames. */
592 typedef struct 572 typedef struct
593 { 573 {
594 enum argument_type arg_type; 574 enum argument_type arg_type;
627 607
628 #include <rmsdef.h> 608 #include <rmsdef.h>
629 #include <descrip.h> 609 #include <descrip.h>
630 #define OUTSIZE MAX_FILE_SPEC_LEN 610 #define OUTSIZE MAX_FILE_SPEC_LEN
631 short 611 short
632 fn_exp (vspec *out, char *in) 612 fn_exp (out, in)
613 vspec *out;
614 char *in;
633 { 615 {
634 static long context = 0; 616 static long context = 0;
635 static struct dsc$descriptor_s o; 617 static struct dsc$descriptor_s o;
636 static struct dsc$descriptor_s i; 618 static struct dsc$descriptor_s i;
637 static logical pass1 = TRUE; 619 static logical pass1 = TRUE;
670 /* 652 /*
671 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the 653 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the
672 name of each file specified by the provided arg expanding wildcards. 654 name of each file specified by the provided arg expanding wildcards.
673 */ 655 */
674 char * 656 char *
675 gfnames (char *arg, logical *p_error) 657 gfnames (arg, p_error)
658 char *arg;
659 logical *p_error;
676 { 660 {
677 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"}; 661 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"};
678 662
679 switch (fn_exp (&filename, arg)) 663 switch (fn_exp (&filename, arg))
680 { 664 {
689 return filename.body; 673 return filename.body;
690 } 674 }
691 } 675 }
692 676
693 #ifndef OLD /* Newer versions of VMS do provide `system'. */ 677 #ifndef OLD /* Newer versions of VMS do provide `system'. */
694 void 678 system (cmd)
695 system (char *cmd) 679 char *cmd;
696 { 680 {
697 fprintf (stderr, "system() function not implemented under VMS\n"); 681 fprintf (stderr, "system() function not implemented under VMS\n");
698 } 682 }
699 #endif 683 #endif
700 684
701 #define VERSION_DELIM ';' 685 #define VERSION_DELIM ';'
702 char * 686 char *massage_name (s)
703 massage_name (char *s) 687 char *s;
704 { 688 {
705 char *start = s; 689 char *start = s;
706 690
707 for ( ; *s; s++) 691 for ( ; *s; s++)
708 if (*s == VERSION_DELIM) 692 if (*s == VERSION_DELIM)
715 return start; 699 return start;
716 } 700 }
717 #endif /* VMS */ 701 #endif /* VMS */
718 702
719 703
720 void 704 int
721 main (int argc, char *argv[]) 705 main (argc, argv)
706 int argc;
707 char *argv[];
722 { 708 {
723 int i; 709 int i;
724 unsigned int nincluded_files = 0; 710 unsigned int nincluded_files = 0;
725 char **included_files = xnew (argc, char *); 711 char **included_files = xnew (argc, char *);
726 char *this_file; 712 char *this_file;
746 re_set_syntax (RE_SYNTAX_EMACS); 732 re_set_syntax (RE_SYNTAX_EMACS);
747 #endif /* ETAGS_REGEXPS */ 733 #endif /* ETAGS_REGEXPS */
748 734
749 /* 735 /*
750 * If etags, always find typedefs and structure tags. Why not? 736 * If etags, always find typedefs and structure tags. Why not?
751 * Also default is to find macro constants. 737 * Also default is to find macro constants and enum constants.
752 */ 738 */
753 if (!CTAGS) 739 if (!CTAGS)
754 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; 740 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE;
755 741
756 while (1) 742 while (1)
793 case 'o': 779 case 'o':
794 if (tagfile) 780 if (tagfile)
795 { 781 {
796 fprintf (stderr, "%s: -%c option may only be given once.\n", 782 fprintf (stderr, "%s: -%c option may only be given once.\n",
797 progname, opt); 783 progname, opt);
798 goto usage; 784 suggest_asking_for_help ();
799 } 785 }
800 tagfile = optarg; 786 tagfile = optarg;
801 break; 787 break;
802 case 'I': 788 case 'I':
803 case 'S': /* for backward compatibility */ 789 case 'S': /* for backward compatibility */
804 noindentypedefs = TRUE; 790 noindentypedefs = TRUE;
805 break; 791 break;
806 case 'l': 792 case 'l':
807 argbuffer[current_arg].function = get_language_from_name (optarg); 793 argbuffer[current_arg].function = get_language_from_name (optarg);
808 if (argbuffer[current_arg].function == NULL)
809 {
810 fprintf (stderr, "%s: language \"%s\" not recognized.\n",
811 progname, optarg);
812 goto usage;
813 }
814 argbuffer[current_arg].arg_type = at_language; 794 argbuffer[current_arg].arg_type = at_language;
815 ++current_arg; 795 ++current_arg;
816 break; 796 break;
817 #ifdef ETAGS_REGEXPS 797 #ifdef ETAGS_REGEXPS
818 case 'r': 798 case 'r':
861 case 'w': 841 case 'w':
862 no_warnings = TRUE; 842 no_warnings = TRUE;
863 break; 843 break;
864 #endif /* CTAGS */ 844 #endif /* CTAGS */
865 default: 845 default:
866 goto usage; 846 suggest_asking_for_help ();
867 } 847 }
868 } 848 }
869 849
870 for (; optind < argc; ++optind) 850 for (; optind < argc; ++optind)
871 { 851 {
876 } 856 }
877 857
878 if (nincluded_files == 0 && file_count == 0) 858 if (nincluded_files == 0 && file_count == 0)
879 { 859 {
880 fprintf (stderr, "%s: No input files specified.\n", progname); 860 fprintf (stderr, "%s: No input files specified.\n", progname);
881 861 suggest_asking_for_help ();
882 usage:
883 fprintf (stderr, "\tTry `%s --help' for a complete list of options.\n",
884 progname);
885 exit (BAD);
886 } 862 }
887 863
888 if (tagfile == NULL) 864 if (tagfile == NULL)
889 { 865 tagfile = CTAGS ? "tags" : "TAGS";
890 tagfile = CTAGS ? (char *) "tags" : (char *) "TAGS";
891 }
892 cwd = etags_getcwd (); /* the current working directory */ 866 cwd = etags_getcwd (); /* the current working directory */
893 strcat (cwd, "/"); 867 if (cwd[strlen (cwd) - 1] != '/')
868 cwd = concat (cwd, "/", "");
894 if (streq (tagfile, "-")) 869 if (streq (tagfile, "-"))
895 { 870 tagfiledir = cwd;
896 tagfiledir = cwd;
897 }
898 else 871 else
899 { 872 tagfiledir = absolute_dirname (tagfile, cwd);
900 tagfiledir = absolute_dirname (tagfile, cwd);
901 }
902 873
903 init (); /* set up boolean "functions" */ 874 init (); /* set up boolean "functions" */
904 875
905 initbuffer (&lb); 876 initbuffer (&lb);
906 initbuffer (&token_name); 877 initbuffer (&token_name);
909 initbuffer (&filename_lb); 880 initbuffer (&filename_lb);
910 881
911 if (!CTAGS) 882 if (!CTAGS)
912 { 883 {
913 if (streq (tagfile, "-")) 884 if (streq (tagfile, "-"))
914 tagf = stdout; 885 {
886 tagf = stdout;
887 #ifdef DOS_NT
888 /* Switch redirected `stdout' to binary mode (setting `_fmode'
889 doesn't take effect until after `stdout' is already open). */
890 if (!isatty (fileno (stdout)))
891 setmode (fileno (stdout), O_BINARY);
892 #endif /* DOS_NT */
893 }
915 else 894 else
916 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); 895 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
917 if (tagf == NULL) 896 if (tagf == NULL)
918 pfatal (tagfile); 897 pfatal (tagfile);
919 } 898 }
974 953
975 /* If CTAGS, we are here. process_file did not write the tags yet, 954 /* If CTAGS, we are here. process_file did not write the tags yet,
976 because we want them ordered. Let's do it now. */ 955 because we want them ordered. Let's do it now. */
977 if (cxref_style) 956 if (cxref_style)
978 { 957 {
979 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
980 if (tagf == NULL)
981 pfatal (tagfile);
982 put_entries (head); 958 put_entries (head);
983 exit (GOOD); 959 exit (GOOD);
984 } 960 }
985 961
986 if (update) 962 if (update)
992 continue; 968 continue;
993 sprintf (cmd, 969 sprintf (cmd,
994 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", 970 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
995 tagfile, argbuffer[i].what, tagfile); 971 tagfile, argbuffer[i].what, tagfile);
996 if (system (cmd) != GOOD) 972 if (system (cmd) != GOOD)
997 fatal ("failed to execute shell command", 0); 973 fatal ("failed to execute shell command", (char *)NULL);
998 } 974 }
999 append_to_tagfile = TRUE; 975 append_to_tagfile = TRUE;
1000 } 976 }
1001 977
1002 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); 978 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1009 { 985 {
1010 char cmd[BUFSIZ]; 986 char cmd[BUFSIZ];
1011 sprintf (cmd, "sort %s -o %s", tagfile, tagfile); 987 sprintf (cmd, "sort %s -o %s", tagfile, tagfile);
1012 exit (system (cmd)); 988 exit (system (cmd));
1013 } 989 }
1014 exit (GOOD); 990 return GOOD;
1015 } 991 }
1016 992
1017 993
1018 /* 994 /*
1019 * Return a Lang_function given the name. 995 * Return a Lang_function given the name.
1020 */ 996 */
1021 Lang_function * 997 Lang_function *
1022 get_language_from_name (char *name) 998 get_language_from_name (name)
1023 { 999 char *name;
1024 CONST struct lang_entry *lang; 1000 {
1025 1001 struct lang_entry *lang;
1026 if (name == NULL) 1002
1027 return NULL; 1003 if (name != NULL)
1028 for (lang = lang_names; lang->name != NULL; lang++) 1004 for (lang = lang_names; lang->name != NULL; lang++)
1029 { 1005 {
1030 if (streq (name, lang->name)) 1006 if (streq (name, lang->name))
1031 return lang->function; 1007 return lang->function;
1032 } 1008 }
1033 1009
1034 return NULL; 1010 fprintf (stderr, "%s: language \"%s\" not recognized.\n",
1011 progname, optarg);
1012 suggest_asking_for_help ();
1013
1014 /* This point should never be reached. The function should either
1015 return a function pointer or never return. Note that a NULL
1016 pointer cannot be considered as an error, as it means that the
1017 language has not been explicitely imposed by the user ("auto"). */
1018 return NULL; /* avoid warnings from compiler */
1035 } 1019 }
1036 1020
1037 1021
1038 /* 1022 /*
1039 * Return a Lang_function given the interpreter name. 1023 * Return a Lang_function given the interpreter name.
1040 */ 1024 */
1041 Lang_function * 1025 Lang_function *
1042 get_language_from_interpreter (char *interpreter) 1026 get_language_from_interpreter (interpreter)
1043 { 1027 char *interpreter;
1044 CONST struct lang_entry *lang; 1028 {
1045 CONST char **iname; 1029 struct lang_entry *lang;
1030 char **iname;
1046 1031
1047 if (interpreter == NULL) 1032 if (interpreter == NULL)
1048 return NULL; 1033 return NULL;
1049 for (lang = lang_names; lang->name != NULL; lang++) 1034 for (lang = lang_names; lang->name != NULL; lang++)
1050 if (lang->interpreters != NULL) 1035 if (lang->interpreters != NULL)
1059 1044
1060 /* 1045 /*
1061 * Return a Lang_function given the file suffix. 1046 * Return a Lang_function given the file suffix.
1062 */ 1047 */
1063 Lang_function * 1048 Lang_function *
1064 get_language_from_suffix (CONST char *suffix) 1049 get_language_from_suffix (suffix)
1065 { 1050 char *suffix;
1066 CONST struct lang_entry *lang; 1051 {
1067 CONST char **ext; 1052 struct lang_entry *lang;
1053 char **ext;
1068 1054
1069 if (suffix == NULL) 1055 if (suffix == NULL)
1070 return NULL; 1056 return NULL;
1071 for (lang = lang_names; lang->name != NULL; lang++) 1057 for (lang = lang_names; lang->name != NULL; lang++)
1072 if (lang->suffixes != NULL) 1058 if (lang->suffixes != NULL)
1080 1066
1081 /* 1067 /*
1082 * This routine is called on each file argument. 1068 * This routine is called on each file argument.
1083 */ 1069 */
1084 void 1070 void
1085 process_file (CONST char *file) 1071 process_file (file)
1072 char *file;
1086 { 1073 {
1087 struct stat stat_buf; 1074 struct stat stat_buf;
1088 FILE *inf; 1075 FILE *inf;
1076 #ifdef DOS_NT
1077 char *p;
1078
1079 for (p = file; *p != '\0'; p++)
1080 if (*p == '\\')
1081 *p = '/';
1082 #endif
1089 1083
1090 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode)) 1084 if (stat (file, &stat_buf) == 0 && !S_ISREG (stat_buf.st_mode))
1091 { 1085 {
1092 fprintf (stderr, "Skipping %s: it is not a regular file.\n", file); 1086 fprintf (stderr, "Skipping %s: it is not a regular file.\n", file);
1093 return; 1087 return;
1136 * all of the array "_wht" is set to FALSE, and then the elements 1130 * all of the array "_wht" is set to FALSE, and then the elements
1137 * subscripted by the chars in "white" are set to TRUE. Thus "_wht" 1131 * subscripted by the chars in "white" are set to TRUE. Thus "_wht"
1138 * of a char is TRUE if it is the string "white", else FALSE. 1132 * of a char is TRUE if it is the string "white", else FALSE.
1139 */ 1133 */
1140 void 1134 void
1141 init (void) 1135 init ()
1142 { 1136 {
1143 register CONST char *sp; 1137 register char *sp;
1144 register int i; 1138 register int i;
1145 1139
1146 for (i = 0; i < 0177; i++) 1140 for (i = 0; i < 0177; i++)
1147 _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE; 1141 _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE;
1148 for (sp = white; *sp; sp++) 1142 for (sp = white; *sp; sp++)
1149 _wht[(unsigned int) *sp] = TRUE; 1143 _wht[*sp] = TRUE;
1150 for (sp = endtk; *sp; sp++) 1144 for (sp = endtk; *sp; sp++)
1151 _etk[(unsigned int) *sp] = TRUE; 1145 _etk[*sp] = TRUE;
1152 for (sp = intk; *sp; sp++) 1146 for (sp = intk; *sp; sp++)
1153 _itk[(unsigned int) *sp] = TRUE; 1147 _itk[*sp] = TRUE;
1154 for (sp = begtk; *sp; sp++) 1148 for (sp = begtk; *sp; sp++)
1155 _btk[(unsigned int) *sp] = TRUE; 1149 _btk[*sp] = TRUE;
1156 _wht[0] = _wht['\n']; 1150 _wht[0] = _wht['\n'];
1157 _etk[0] = _etk['\n']; 1151 _etk[0] = _etk['\n'];
1158 _btk[0] = _btk['\n']; 1152 _btk[0] = _btk['\n'];
1159 _itk[0] = _itk['\n']; 1153 _itk[0] = _itk['\n'];
1160 } 1154 }
1162 /* 1156 /*
1163 * This routine opens the specified file and calls the function 1157 * This routine opens the specified file and calls the function
1164 * which finds the function and type definitions. 1158 * which finds the function and type definitions.
1165 */ 1159 */
1166 void 1160 void
1167 find_entries (CONST char *file, FILE *inf) 1161 find_entries (file, inf)
1162 char *file;
1163 FILE *inf;
1168 { 1164 {
1169 char *cp; 1165 char *cp;
1170 Lang_function *function; 1166 Lang_function *function;
1171 NODE *old_last_node; 1167 NODE *old_last_node;
1172 extern NODE *last_node; 1168 extern NODE *last_node;
1169
1173 1170
1174 /* Memory leakage here: the memory block pointed by curfile is never 1171 /* Memory leakage here: the memory block pointed by curfile is never
1175 released. The amount of memory leaked here is the sum of the 1172 released. The amount of memory leaked here is the sum of the
1176 lengths of the input file names. */ 1173 lengths of the input file names. */
1177 curfile = savestr (file); 1174 curfile = savestr (file);
1216 continue; 1213 continue;
1217 for (cp = lp; *cp != '\0' && !isspace (*cp); cp++) 1214 for (cp = lp; *cp != '\0' && !isspace (*cp); cp++)
1218 continue; 1215 continue;
1219 *cp = '\0'; 1216 *cp = '\0';
1220 1217
1221 if (strlen (lp) > (size_t) 0) 1218 if (strlen (lp) > 0)
1222 { 1219 {
1223 function = get_language_from_interpreter (lp); 1220 function = get_language_from_interpreter (lp);
1224 if (function != NULL) 1221 if (function != NULL)
1225 { 1222 {
1226 function (inf); 1223 function (inf);
1244 fclose (inf); 1241 fclose (inf);
1245 return; 1242 return;
1246 } 1243 }
1247 1244
1248 /* Record a tag. */ 1245 /* Record a tag. */
1249 #if 0 1246 void
1250 char *name; /* tag name, if different from definition */ 1247 pfnote (name, is_func, linestart, linelen, lno, cno)
1248 char *name; /* tag name, or NULL if unnamed */
1251 logical is_func; /* tag is a function */ 1249 logical is_func; /* tag is a function */
1252 char *linestart; /* start of the line where tag is */ 1250 char *linestart; /* start of the line where tag is */
1253 int linelen; /* length of the line where tag is */ 1251 int linelen; /* length of the line where tag is */
1254 int lno; /* line number */ 1252 int lno; /* line number */
1255 long cno; /* character number */ 1253 long cno; /* character number */
1256 #endif 1254 {
1257 void 1255 register NODE *np;
1258 pfnote (char *name, logical is_func, char *linestart, 1256
1259 int linelen, int lno, long cno) 1257 if (CTAGS && name == NULL)
1260 { 1258 return;
1261 register NODE *np = xnew (1, NODE); 1259
1260 np = xnew (1, NODE);
1262 1261
1263 /* If ctags mode, change name "main" to M<thisfilename>. */ 1262 /* If ctags mode, change name "main" to M<thisfilename>. */
1264 if (CTAGS && !cxref_style && streq (name, "main")) 1263 if (CTAGS && !cxref_style && streq (name, "main"))
1265 { 1264 {
1266 register char *fp = etags_strrchr (curfile, '/'); 1265 register char *fp = etags_strrchr (curfile, '/');
1275 np->file = curfile; 1274 np->file = curfile;
1276 np->is_func = is_func; 1275 np->is_func = is_func;
1277 np->lno = lno; 1276 np->lno = lno;
1278 /* Our char numbers are 0-base, because of C language tradition? 1277 /* Our char numbers are 0-base, because of C language tradition?
1279 ctags compatibility? old versions compatibility? I don't know. 1278 ctags compatibility? old versions compatibility? I don't know.
1280 Anyway, since emacs's are 1-base we espect etags.el to take care 1279 Anyway, since emacs's are 1-base we expect etags.el to take care
1281 of the difference. If we wanted to have 1-based numbers, we would 1280 of the difference. If we wanted to have 1-based numbers, we would
1282 uncomment the +1 below. */ 1281 uncomment the +1 below. */
1283 np->cno = cno /* + 1 */ ; 1282 np->cno = cno /* + 1 */ ;
1284 np->left = np->right = NULL; 1283 np->left = np->right = NULL;
1285 np->pat = savenstr (linestart, ((CTAGS && !cxref_style) ? 50 : linelen)); 1284 if (CTAGS && !cxref_style)
1285 {
1286 if (strlen (linestart) < 50)
1287 np->pat = concat (linestart, "$", "");
1288 else
1289 np->pat = savenstr (linestart, 50);
1290 }
1291 else
1292 np->pat = savenstr (linestart, linelen);
1286 1293
1287 add_node (np, &head); 1294 add_node (np, &head);
1288 } 1295 }
1289 1296
1290 /* 1297 /*
1291 * free_tree () 1298 * free_tree ()
1292 * recurse on left children, iterate on right children. 1299 * recurse on left children, iterate on right children.
1293 */ 1300 */
1294 void 1301 void
1295 free_tree (NODE *node) 1302 free_tree (node)
1303 register NODE *node;
1296 { 1304 {
1297 while (node) 1305 while (node)
1298 { 1306 {
1299 register NODE *node_right = node->right; 1307 register NODE *node_right = node->right;
1300 free_tree (node->left); 1308 free_tree (node->left);
1315 * add_node is the only function allowed to add nodes, so it can 1323 * add_node is the only function allowed to add nodes, so it can
1316 * maintain state. 1324 * maintain state.
1317 */ 1325 */
1318 NODE *last_node = NULL; 1326 NODE *last_node = NULL;
1319 void 1327 void
1320 add_node (NODE *node, NODE **cur_node_p) 1328 add_node (node, cur_node_p)
1329 NODE *node, **cur_node_p;
1321 { 1330 {
1322 register int dif; 1331 register int dif;
1323 register NODE *cur_node = *cur_node_p; 1332 register NODE *cur_node = *cur_node_p;
1324 1333
1325 if (cur_node == NULL) 1334 if (cur_node == NULL)
1331 1340
1332 if (!CTAGS) 1341 if (!CTAGS)
1333 { 1342 {
1334 /* Etags Mode */ 1343 /* Etags Mode */
1335 if (last_node == NULL) 1344 if (last_node == NULL)
1336 fatal ("internal error in add_node", 0); 1345 fatal ("internal error in add_node", (char *)NULL);
1337 last_node->right = node; 1346 last_node->right = node;
1338 last_node = node; 1347 last_node = node;
1339 } 1348 }
1340 else 1349 else
1341 { 1350 {
1372 add_node (node, dif < 0 ? &cur_node->left : &cur_node->right); 1381 add_node (node, dif < 0 ? &cur_node->left : &cur_node->right);
1373 } 1382 }
1374 } 1383 }
1375 1384
1376 void 1385 void
1377 put_entries (NODE *node) 1386 put_entries (node)
1387 register NODE *node;
1378 { 1388 {
1379 register char *sp; 1389 register char *sp;
1380 1390
1381 if (node == NULL) 1391 if (node == NULL)
1382 return; 1392 return;
1387 /* Output this entry */ 1397 /* Output this entry */
1388 1398
1389 if (!CTAGS) 1399 if (!CTAGS)
1390 { 1400 {
1391 if (node->name != NULL) 1401 if (node->name != NULL)
1392 fprintf (tagf, "%s\177%s\001%ld,%ld\n", 1402 fprintf (tagf, "%s\177%s\001%d,%d\n",
1393 node->pat, node->name, node->lno, node->cno); 1403 node->pat, node->name, node->lno, node->cno);
1394 else 1404 else
1395 fprintf (tagf, "%s\177%ld,%ld\n", 1405 fprintf (tagf, "%s\177%d,%d\n",
1396 node->pat, node->lno, node->cno); 1406 node->pat, node->lno, node->cno);
1397 } 1407 }
1398 else if (!cxref_style) 1408 else
1399 { 1409 {
1400 fprintf (tagf, "%s\t%s\t", 1410 if (node->name == NULL)
1401 node->name, node->file); 1411 error ("internal error: NULL name in ctags mode.", (char *)NULL);
1402 1412
1403 if (node->is_func) 1413 if (cxref_style)
1404 { /* a function */ 1414 {
1405 putc (searchar, tagf); 1415 if (vgrind_style)
1406 putc ('^', tagf); 1416 fprintf (stdout, "%s %s %d\n",
1407 1417 node->name, node->file, (node->lno + 63) / 64);
1408 for (sp = node->pat; *sp; sp++) 1418 else
1409 { 1419 fprintf (stdout, "%-16s %3d %-16s %s\n",
1410 if (*sp == '\\' || *sp == searchar) 1420 node->name, node->lno, node->file, node->pat);
1411 putc ('\\', tagf);
1412 putc (*sp, tagf);
1413 }
1414 putc (searchar, tagf);
1415 } 1421 }
1416 else 1422 else
1417 { /* a typedef; text pattern inadequate */ 1423 {
1418 fprintf (tagf, "%ld", node->lno); 1424 fprintf (tagf, "%s\t%s\t", node->name, node->file);
1419 } 1425
1420 putc ('\n', tagf); 1426 if (node->is_func)
1421 } 1427 { /* a function */
1422 else if (vgrind_style) 1428 putc (searchar, tagf);
1423 fprintf (stdout, "%s %s %ld\n", 1429 putc ('^', tagf);
1424 node->name, node->file, (node->lno + 63) / 64); 1430
1425 else 1431 for (sp = node->pat; *sp; sp++)
1426 fprintf (stdout, "%-16s %3ld %-16s %s\n", 1432 {
1427 node->name, node->lno, node->file, node->pat); 1433 if (*sp == '\\' || *sp == searchar)
1434 putc ('\\', tagf);
1435 putc (*sp, tagf);
1436 }
1437 putc (searchar, tagf);
1438 }
1439 else
1440 { /* a typedef; text pattern inadequate */
1441 fprintf (tagf, "%d", node->lno);
1442 }
1443 putc ('\n', tagf);
1444 }
1445 }
1428 1446
1429 /* Output subentries that follow this one */ 1447 /* Output subentries that follow this one */
1430 put_entries (node->right); 1448 put_entries (node->right);
1431 } 1449 }
1432 1450
1433 /* Length of a number's decimal representation. */ 1451 /* Length of a number's decimal representation. */
1434 static int 1452 int
1435 number_len (long num) 1453 number_len (num)
1454 long num;
1436 { 1455 {
1437 int len = 0; 1456 int len = 0;
1438 if (!num) 1457 if (!num)
1439 return 1; 1458 return 1;
1440 for (; num; num /= 10) 1459 for (; num; num /= 10)
1448 * we are not ctags, but called only in that case. This count 1467 * we are not ctags, but called only in that case. This count
1449 * is irrelevant with the new tags.el, but is still supplied for 1468 * is irrelevant with the new tags.el, but is still supplied for
1450 * backward compatibility. 1469 * backward compatibility.
1451 */ 1470 */
1452 int 1471 int
1453 total_size_of_entries (NODE *node) 1472 total_size_of_entries (node)
1473 register NODE *node;
1454 { 1474 {
1455 register int total; 1475 register int total;
1456 1476
1457 if (node == NULL) 1477 if (node == NULL)
1458 return 0; 1478 return 0;
1476 /* 1496 /*
1477 * The C symbol tables. 1497 * The C symbol tables.
1478 */ 1498 */
1479 enum sym_type 1499 enum sym_type
1480 { 1500 {
1481 st_none, st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec 1501 st_none, st_C_objprot, st_C_objimpl, st_C_objend, st_C_gnumacro,
1502 st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1482 }; 1503 };
1483 1504
1484 /* Feed stuff between (but not including) %[ and %] lines to: 1505 /* Feed stuff between (but not including) %[ and %] lines to:
1485 gperf -c -k1,3 -o -p -r -t 1506 gperf -c -k 1,3 -o -p -r -t
1486 %[ 1507 %[
1487 struct C_stab_entry { CONST char *name; int c_ext; enum sym_type type; } 1508 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1488 %% 1509 %%
1510 @interface, 0, st_C_objprot
1511 @protocol, 0, st_C_objprot
1512 @implementation,0, st_C_objimpl
1513 @end, 0, st_C_objend
1489 class, C_PLPL, st_C_struct 1514 class, C_PLPL, st_C_struct
1515 namespace, C_PLPL, st_C_struct
1490 domain, C_STAR, st_C_struct 1516 domain, C_STAR, st_C_struct
1491 union, 0, st_C_struct 1517 union, 0, st_C_struct
1492 struct, 0, st_C_struct 1518 struct, 0, st_C_struct
1493 enum, 0, st_C_enum 1519 enum, 0, st_C_enum
1494 typedef, 0, st_C_typedef 1520 typedef, 0, st_C_typedef
1495 define, 0, st_C_define 1521 define, 0, st_C_define
1522 bool, C_PLPL, st_C_typespec
1496 long, 0, st_C_typespec 1523 long, 0, st_C_typespec
1497 short, 0, st_C_typespec 1524 short, 0, st_C_typespec
1498 int, 0, st_C_typespec 1525 int, 0, st_C_typespec
1499 char, 0, st_C_typespec 1526 char, 0, st_C_typespec
1500 float, 0, st_C_typespec 1527 float, 0, st_C_typespec
1505 void, 0, st_C_typespec 1532 void, 0, st_C_typespec
1506 extern, 0, st_C_typespec 1533 extern, 0, st_C_typespec
1507 static, 0, st_C_typespec 1534 static, 0, st_C_typespec
1508 const, 0, st_C_typespec 1535 const, 0, st_C_typespec
1509 volatile, 0, st_C_typespec 1536 volatile, 0, st_C_typespec
1537 explicit, C_PLPL, st_C_typespec
1538 mutable, C_PLPL, st_C_typespec
1539 typename, C_PLPL, st_C_typespec
1540 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
1541 DEFUN, 0, st_C_gnumacro
1542 SYSCALL, 0, st_C_gnumacro
1543 ENTRY, 0, st_C_gnumacro
1544 PSEUDO, 0, st_C_gnumacro
1545 # These are defined inside C functions, so currently they are not met.
1546 # EXFUN used in glibc, DEFVAR_* in emacs.
1547 #EXFUN, 0, st_C_gnumacro
1548 #DEFVAR_, 0, st_C_gnumacro
1510 %] 1549 %]
1511 and replace lines between %< and %> with its output. */ 1550 and replace lines between %< and %> with its output. */
1512 /*%<*/ 1551 /*%<*/
1513 /* C code produced by gperf version 1.8.1 (K&R C version) */ 1552 /* C code produced by gperf version 2.1 (K&R C version) */
1514 /* Command-line: gperf -c -k1,3 -o -p -r -t */ 1553 /* Command-line: gperf -c -k 1,3 -o -p -r -t */
1515 1554
1516 1555
1517 struct C_stab_entry { CONST char *name; int c_ext; enum sym_type type; }; 1556 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1518 1557
1519 #define MIN_WORD_LENGTH 3 1558 #define MIN_WORD_LENGTH 3
1520 #define MAX_WORD_LENGTH 8 1559 #define MAX_WORD_LENGTH 15
1521 #define MIN_HASH_VALUE 10 1560 #define MIN_HASH_VALUE 34
1522 #define MAX_HASH_VALUE 62 1561 #define MAX_HASH_VALUE 121
1523 /* 1562 /*
1524 21 keywords 1563 34 keywords
1525 53 is the maximum key range 1564 88 is the maximum key range
1526 */ 1565 */
1527 1566
1528 static int 1567 static int
1529 hash (CONST char *str, int len) 1568 hash (str, len)
1569 register char *str;
1570 register unsigned int len;
1530 { 1571 {
1531 static unsigned char hash_table[] = 1572 static unsigned char hash_table[] =
1532 { 1573 {
1533 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1574 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1534 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1575 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1535 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1576 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1536 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1577 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1537 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1578 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1538 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1579 121, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1539 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1580 121, 121, 121, 121, 45, 121, 121, 121, 16, 19,
1540 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1581 61, 121, 121, 121, 121, 121, 121, 121, 121, 121,
1541 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 1582 10, 121, 121, 20, 53, 121, 121, 121, 121, 121,
1542 62, 62, 62, 62, 62, 62, 62, 2, 62, 7, 1583 121, 121, 121, 121, 121, 121, 121, 41, 45, 22,
1543 6, 9, 15, 30, 62, 24, 62, 62, 1, 24, 1584 60, 47, 37, 28, 121, 55, 121, 121, 20, 14,
1544 7, 27, 13, 62, 19, 26, 18, 27, 1, 62, 1585 29, 30, 5, 121, 50, 59, 30, 54, 6, 121,
1545 62, 62, 62, 62, 62, 62, 62, 62, 1586 121, 121, 121, 121, 121, 121, 121, 121,
1546 }; 1587 };
1547 return len + hash_table[(int) str[2]] + hash_table[(int) str[0]]; 1588 return len + hash_table[str[2]] + hash_table[str[0]];
1548 } 1589 }
1549 1590
1550 static struct C_stab_entry * 1591 struct C_stab_entry *
1551 in_word_set (CONST char *str, int len) 1592 in_word_set (str, len)
1593 register char *str;
1594 register unsigned int len;
1552 { 1595 {
1553 1596
1554 static struct C_stab_entry wordlist[] = 1597 static struct C_stab_entry wordlist[] =
1555 { 1598 {
1556 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, 1599 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1557 {"",}, 1600 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1601 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1602 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1558 {"volatile", 0, st_C_typespec}, 1603 {"volatile", 0, st_C_typespec},
1559 {"",}, 1604 {"PSEUDO", 0, st_C_gnumacro},
1605 {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1606 {"typedef", 0, st_C_typedef},
1607 {"typename", C_PLPL, st_C_typespec},
1608 {"",}, {"",}, {"",},
1609 {"SYSCALL", 0, st_C_gnumacro},
1610 {"",}, {"",}, {"",},
1611 {"mutable", C_PLPL, st_C_typespec},
1612 {"namespace", C_PLPL, st_C_struct},
1560 {"long", 0, st_C_typespec}, 1613 {"long", 0, st_C_typespec},
1614 {"",}, {"",},
1615 {"const", 0, st_C_typespec},
1616 {"",}, {"",}, {"",},
1617 {"explicit", C_PLPL, st_C_typespec},
1618 {"",}, {"",}, {"",}, {"",},
1619 {"void", 0, st_C_typespec},
1620 {"",},
1561 {"char", 0, st_C_typespec}, 1621 {"char", 0, st_C_typespec},
1562 {"class", C_PLPL, st_C_struct}, 1622 {"class", C_PLPL, st_C_struct},
1563 {"",}, {"",}, {"",}, {"",}, 1623 {"",}, {"",}, {"",},
1564 {"const", 0, st_C_typespec}, 1624 {"float", 0, st_C_typespec},
1565 {"",}, {"",}, {"",}, {"",}, 1625 {"",},
1626 {"@implementation", 0, st_C_objimpl},
1566 {"auto", 0, st_C_typespec}, 1627 {"auto", 0, st_C_typespec},
1567 {"",}, {"",}, 1628 {"",},
1629 {"ENTRY", 0, st_C_gnumacro},
1630 {"@end", 0, st_C_objend},
1631 {"bool", C_PLPL, st_C_typespec},
1632 {"domain", C_STAR, st_C_struct},
1633 {"",},
1634 {"DEFUN", 0, st_C_gnumacro},
1635 {"extern", 0, st_C_typespec},
1636 {"@interface", 0, st_C_objprot},
1637 {"",}, {"",}, {"",},
1638 {"int", 0, st_C_typespec},
1639 {"",}, {"",}, {"",}, {"",},
1640 {"signed", 0, st_C_typespec},
1641 {"short", 0, st_C_typespec},
1642 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1568 {"define", 0, st_C_define}, 1643 {"define", 0, st_C_define},
1569 {"",}, 1644 {"@protocol", 0, st_C_objprot},
1570 {"void", 0, st_C_typespec}, 1645 {"enum", 0, st_C_enum},
1571 {"",}, {"",}, {"",},
1572 {"extern", 0, st_C_typespec},
1573 {"static", 0, st_C_typespec}, 1646 {"static", 0, st_C_typespec},
1574 {"",}, 1647 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
1575 {"domain", C_STAR, st_C_struct}, 1648 {"union", 0, st_C_struct},
1576 {"",}, 1649 {"struct", 0, st_C_struct},
1577 {"typedef", 0, st_C_typedef}, 1650 {"",}, {"",}, {"",}, {"",},
1578 {"double", 0, st_C_typespec}, 1651 {"double", 0, st_C_typespec},
1579 {"enum", 0, st_C_enum},
1580 {"",}, {"",}, {"",}, {"",},
1581 {"int", 0, st_C_typespec},
1582 {"",},
1583 {"float", 0, st_C_typespec},
1584 {"",}, {"",}, {"",},
1585 {"struct", 0, st_C_struct},
1586 {"",}, {"",}, {"",}, {"",},
1587 {"union", 0, st_C_struct},
1588 {"",},
1589 {"short", 0, st_C_typespec},
1590 {"",}, {"",},
1591 {"unsigned", 0, st_C_typespec}, 1652 {"unsigned", 0, st_C_typespec},
1592 {"signed", 0, st_C_typespec},
1593 }; 1653 };
1594 1654
1595 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 1655 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
1596 { 1656 {
1597 register int key = hash (str, len); 1657 register int key = hash (str, len);
1598 1658
1599 if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE) 1659 if (key <= MAX_HASH_VALUE && key >= MIN_HASH_VALUE)
1600 { 1660 {
1601 register CONST char *s = wordlist[key].name; 1661 register char *s = wordlist[key].name;
1602 1662
1603 if (*s == *str && strneq (str + 1, s + 1, len - 1)) 1663 if (*s == *str && !strncmp (str + 1, s + 1, len - 1))
1604 return &wordlist[key]; 1664 return &wordlist[key];
1605 } 1665 }
1606 } 1666 }
1607 return 0; 1667 return 0;
1608 } 1668 }
1609 /*%>*/ 1669 /*%>*/
1610 1670
1611 static enum sym_type 1671 enum sym_type
1612 C_symtype (char *str, int len, int c_ext) 1672 C_symtype (str, len, c_ext)
1613 { 1673 char *str;
1614 register struct C_stab_entry *se = in_word_set(str, len); 1674 int len;
1675 int c_ext;
1676 {
1677 register struct C_stab_entry *se = in_word_set (str, len);
1615 1678
1616 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext))) 1679 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
1617 return st_none; 1680 return st_none;
1618 return se->type; 1681 return se->type;
1619 } 1682 }
1620 1683
1621 /* 1684 /*
1622 * C functions are recognized using a simple finite automaton. 1685 * C functions are recognized using a simple finite automaton.
1623 * funcdef is its state variable. 1686 * funcdef is its state variable.
1624 */ 1687 */
1625 typedef enum 1688 enum
1626 { 1689 {
1627 fnone, /* nothing seen */ 1690 fnone, /* nothing seen */
1628 ftagseen, /* function-like tag seen */ 1691 ftagseen, /* function-like tag seen */
1629 fstartlist, /* just after open parenthesis */ 1692 fstartlist, /* just after open parenthesis */
1630 finlist, /* in parameter list */ 1693 finlist, /* in parameter list */
1631 flistseen, /* after parameter list */ 1694 flistseen, /* after parameter list */
1632 fignore /* before open brace */ 1695 fignore /* before open brace */
1633 } FUNCST; 1696 } funcdef;
1634 FUNCST funcdef;
1635 1697
1636 1698
1637 /* 1699 /*
1638 * typedefs are recognized using a simple finite automaton. 1700 * typedefs are recognized using a simple finite automaton.
1639 * typeddef is its state variable. 1701 * typdef is its state variable.
1640 */ 1702 */
1641 typedef enum 1703 enum
1642 { 1704 {
1643 tnone, /* nothing seen */ 1705 tnone, /* nothing seen */
1644 ttypedseen, /* typedef keyword seen */ 1706 ttypedseen, /* typedef keyword seen */
1645 tinbody, /* inside typedef body */ 1707 tinbody, /* inside typedef body */
1646 tend, /* just before typedef tag */ 1708 tend, /* just before typedef tag */
1647 tignore /* junk after typedef tag */ 1709 tignore /* junk after typedef tag */
1648 } TYPEDST; 1710 } typdef;
1649 TYPEDST typdef;
1650 1711
1651 1712
1652 /* 1713 /*
1653 * struct-like structures (enum, struct and union) are recognized 1714 * struct-like structures (enum, struct and union) are recognized
1654 * using another simple finite automaton. `structdef' is its state 1715 * using another simple finite automaton. `structdef' is its state
1655 * variable. 1716 * variable.
1656 */ 1717 */
1657 typedef enum 1718 enum
1658 { 1719 {
1659 snone, /* nothing seen yet */ 1720 snone, /* nothing seen yet */
1660 skeyseen, /* struct-like keyword seen */ 1721 skeyseen, /* struct-like keyword seen */
1661 stagseen, /* struct-like tag seen */ 1722 stagseen, /* struct-like tag seen */
1662 scolonseen, /* colon seen after struct-like tag */ 1723 scolonseen, /* colon seen after struct-like tag */
1663 sinbody /* in struct body: recognize member func defs*/ 1724 sinbody /* in struct body: recognize member func defs*/
1664 } STRUCTST; 1725 } structdef;
1665 STRUCTST structdef;
1666 1726
1667 /* 1727 /*
1668 * When structdef is stagseen, scolonseen, or sinbody, structtag is the 1728 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
1669 * struct tag, and structtype is the type of the preceding struct-like 1729 * struct tag, and structtype is the type of the preceding struct-like
1670 * keyword. 1730 * keyword.
1671 */ 1731 */
1672 CONST char *structtag = "<uninited>"; 1732 char *structtag = "<uninited>";
1673 enum sym_type structtype; 1733 enum sym_type structtype;
1734
1735 /*
1736 * When objdef is different from onone, objtag is the name of the class.
1737 */
1738 char *objtag = "<uninited>";
1674 1739
1675 /* 1740 /*
1676 * Yet another little state machine to deal with preprocessor lines. 1741 * Yet another little state machine to deal with preprocessor lines.
1677 */ 1742 */
1678 typedef enum 1743 enum
1679 { 1744 {
1680 dnone, /* nothing seen */ 1745 dnone, /* nothing seen */
1681 dsharpseen, /* '#' seen as first char on line */ 1746 dsharpseen, /* '#' seen as first char on line */
1682 ddefineseen, /* '#' and 'define' seen */ 1747 ddefineseen, /* '#' and 'define' seen */
1683 dignorerest /* ignore rest of line */ 1748 dignorerest /* ignore rest of line */
1684 } DEFINEST; 1749 } definedef;
1685 DEFINEST definedef; 1750
1751 /*
1752 * State machine for Objective C protocols and implementations.
1753 */
1754 enum
1755 {
1756 onone, /* nothing seen */
1757 oprotocol, /* @interface or @protocol seen */
1758 oimplementation, /* @implementations seen */
1759 otagseen, /* class name seen */
1760 oparenseen, /* parenthesis before category seen */
1761 ocatseen, /* category name seen */
1762 oinbody, /* in @implementation body */
1763 omethodsign, /* in @implementation body, after +/- */
1764 omethodtag, /* after method name */
1765 omethodcolon, /* after method colon */
1766 omethodparm, /* after method parameter */
1767 oignore /* wait for @end */
1768 } objdef;
1686 1769
1687 /* 1770 /*
1688 * Set this to TRUE, and the next token considered is called a function. 1771 * Set this to TRUE, and the next token considered is called a function.
1689 * Used only for GNU emacs's function-defining macros. 1772 * Used only for GNU emacs's function-defining macros.
1690 */ 1773 */
1694 * TRUE in the rules part of a yacc file, FALSE outside (parse as C). 1777 * TRUE in the rules part of a yacc file, FALSE outside (parse as C).
1695 */ 1778 */
1696 logical yacc_rules; 1779 logical yacc_rules;
1697 1780
1698 /* 1781 /*
1782 * methodlen is the length of the method name stored in token_name.
1783 */
1784 int methodlen;
1785
1786 /*
1699 * consider_token () 1787 * consider_token ()
1700 * checks to see if the current token is at the start of a 1788 * checks to see if the current token is at the start of a
1701 * function, or corresponds to a typedef, or is a struct/union/enum 1789 * function, or corresponds to a typedef, or is a struct/union/enum
1702 * tag. 1790 * tag, or #define, or an enum constant.
1703 * 1791 *
1704 * *IS_FUNC gets TRUE iff the token is a function or macro with args. 1792 * *IS_FUNC gets TRUE iff the token is a function or #define macro
1705 * C_EXT is which language we are looking at. 1793 * with args. C_EXT is which language we are looking at.
1706 * 1794 *
1707 * In the future we will need some way to adjust where the end of 1795 * In the future we will need some way to adjust where the end of
1708 * the token is; for instance, implementing the C++ keyword 1796 * the token is; for instance, implementing the C++ keyword
1709 * `operator' properly will adjust the end of the token to be after 1797 * `operator' properly will adjust the end of the token to be after
1710 * whatever follows `operator'. 1798 * whatever follows `operator'.
1712 * Globals 1800 * Globals
1713 * funcdef IN OUT 1801 * funcdef IN OUT
1714 * structdef IN OUT 1802 * structdef IN OUT
1715 * definedef IN OUT 1803 * definedef IN OUT
1716 * typdef IN OUT 1804 * typdef IN OUT
1805 * objdef IN OUT
1717 * next_token_is_func IN OUT 1806 * next_token_is_func IN OUT
1718 */ 1807 */
1719 1808
1720 #if 0 1809 logical
1810 consider_token (str, len, c, c_ext, cblev, parlev, is_func)
1721 register char *str; /* IN: token pointer */ 1811 register char *str; /* IN: token pointer */
1722 register int len; /* IN: token length */ 1812 register int len; /* IN: token length */
1723 register char c; /* IN: first char after the token */ 1813 register char c; /* IN: first char after the token */
1724 int c_ext; /* IN: C extensions mask */ 1814 int c_ext; /* IN: C extensions mask */
1725 int cblev; /* IN: curly brace level */ 1815 int cblev; /* IN: curly brace level */
1816 int parlev; /* IN: parenthesis level */
1726 logical *is_func; /* OUT: function found */ 1817 logical *is_func; /* OUT: function found */
1727 #endif
1728 static logical
1729 consider_token (char *str, int len, char c, int c_ext, int cblev,
1730 logical *is_func)
1731 { 1818 {
1732 enum sym_type toktype = C_symtype (str, len, c_ext); 1819 enum sym_type toktype = C_symtype (str, len, c_ext);
1733 1820
1734 /* 1821 /*
1735 * Advance the definedef state machine. 1822 * Advance the definedef state machine.
1761 else 1848 else
1762 return TRUE; 1849 return TRUE;
1763 case dignorerest: 1850 case dignorerest:
1764 return FALSE; 1851 return FALSE;
1765 default: 1852 default:
1766 error ("internal error: definedef value.", 0); 1853 error ("internal error: definedef value.", (char *)NULL);
1767 } 1854 }
1768 1855
1769 /* 1856 /*
1770 * Now typedefs 1857 * Now typedefs
1771 */ 1858 */
1788 typdef = tend; 1875 typdef = tend;
1789 break; 1876 break;
1790 case st_C_struct: 1877 case st_C_struct:
1791 case st_C_enum: 1878 case st_C_enum:
1792 break; 1879 break;
1793 default:
1794 break;
1795 } 1880 }
1796 /* Do not return here, so the structdef stuff has a chance. */ 1881 /* Do not return here, so the structdef stuff has a chance. */
1797 break; 1882 break;
1798 case tend: 1883 case tend:
1799 switch (toktype) 1884 switch (toktype)
1800 { 1885 {
1801 case st_C_typespec: 1886 case st_C_typespec:
1802 case st_C_struct: 1887 case st_C_struct:
1803 case st_C_enum: 1888 case st_C_enum:
1804 return FALSE; 1889 return FALSE;
1805 default:
1806 break;
1807 } 1890 }
1808 return TRUE; 1891 return TRUE;
1809 default:
1810 break;
1811 } 1892 }
1812 1893
1813 /* 1894 /*
1814 * This structdef business is currently only invoked when cblev==0. 1895 * This structdef business is currently only invoked when cblev==0.
1815 * It should be recursively invoked whatever the curly brace level, 1896 * It should be recursively invoked whatever the curly brace level,
1817 * within structs. 1898 * within structs.
1818 * 1899 *
1819 * This structdef business is NOT invoked when we are ctags and the 1900 * This structdef business is NOT invoked when we are ctags and the
1820 * file is plain C. This is because a struct tag may have the same 1901 * file is plain C. This is because a struct tag may have the same
1821 * name as another tag, and this loses with ctags. 1902 * name as another tag, and this loses with ctags.
1822 *
1823 * This if statement deals with the typdef state machine as
1824 * follows: if typdef==ttypedseen and token is struct/union/class/enum,
1825 * return FALSE. All the other code here is for the structdef
1826 * state machine.
1827 */ 1903 */
1828 switch (toktype) 1904 switch (toktype)
1829 { 1905 {
1830 case st_C_struct: 1906 case st_C_struct:
1831 case st_C_enum: 1907 case st_C_enum:
1834 { 1910 {
1835 structdef = skeyseen; 1911 structdef = skeyseen;
1836 structtype = toktype; 1912 structtype = toktype;
1837 } 1913 }
1838 return FALSE; 1914 return FALSE;
1839 default: 1915 }
1840 break; 1916
1841 }
1842 if (structdef == skeyseen) 1917 if (structdef == skeyseen)
1843 { 1918 {
1844 /* Save the tag for struct/union/class, for functions that may be 1919 /* Save the tag for struct/union/class, for functions that may be
1845 defined inside. */ 1920 defined inside. */
1846 if (structtype == st_C_struct) 1921 if (structtype == st_C_struct)
1856 { 1931 {
1857 definedef = dnone; 1932 definedef = dnone;
1858 return FALSE; 1933 return FALSE;
1859 } 1934 }
1860 1935
1861 /* Detect GNU macros. */ 1936 /* Detect GNU macros.
1862 if (definedef == dnone) 1937
1863 if (strneq (str, "DEFUN", len) /* Used in emacs */ 1938 DEFUN note for writers of emacs C code:
1864 #if FALSE 1939 The DEFUN macro, used in emacs C source code, has a first arg
1865 These are defined inside C functions, so currently they 1940 that is a string (the lisp function name), and a second arg that
1866 are not met anyway. 1941 is a C function name. Since etags skips strings, the second arg
1867 || strneq (str, "EXFUN", len) /* Used in glibc */ 1942 is tagged. This is unfortunate, as it would be better to tag the
1868 || strneq (str, "DEFVAR_", 7) /* Used in emacs */ 1943 first arg. The simplest way to deal with this problem would be
1869 #endif 1944 to name the tag with a name built from the function name, by
1870 || strneq (str, "SYSCALL", len) /* Used in glibc (mach) */ 1945 removing the initial 'F' character and substituting '-' for '_'.
1871 || strneq (str, "ENTRY", len) /* Used in glibc */ 1946 Anyway, this assumes that the conventions of naming lisp
1872 || strneq (str, "PSEUDO", len)) /* Used in glibc */ 1947 functions will never change. Currently, this method is not
1873 1948 implemented, so writers of emacs code are recommended to put the
1874 { 1949 first two args of a DEFUN on the same line. */
1875 next_token_is_func = TRUE; 1950 if (definedef == dnone && toktype == st_C_gnumacro)
1876 return FALSE; 1951 {
1877 } 1952 next_token_is_func = TRUE;
1953 return FALSE;
1954 }
1878 if (next_token_is_func) 1955 if (next_token_is_func)
1879 { 1956 {
1880 next_token_is_func = FALSE; 1957 next_token_is_func = FALSE;
1881 funcdef = fignore; 1958 funcdef = fignore;
1882 *is_func = TRUE; 1959 *is_func = TRUE;
1883 return TRUE; 1960 return TRUE;
1884 } 1961 }
1885 1962
1886 /* A function? */ 1963 /* Detect Objective C constructs. */
1964 switch (objdef)
1965 {
1966 case onone:
1967 switch (toktype)
1968 {
1969 case st_C_objprot:
1970 objdef = oprotocol;
1971 return FALSE;
1972 case st_C_objimpl:
1973 objdef = oimplementation;
1974 return FALSE;
1975 }
1976 break;
1977 case oimplementation:
1978 /* Save the class tag for functions that may be defined inside. */
1979 objtag = savenstr (str, len);
1980 objdef = oinbody;
1981 return FALSE;
1982 case oprotocol:
1983 /* Save the class tag for categories. */
1984 objtag = savenstr (str, len);
1985 objdef = otagseen;
1986 *is_func = TRUE;
1987 return TRUE;
1988 case oparenseen:
1989 objdef = ocatseen;
1990 *is_func = TRUE;
1991 return TRUE;
1992 case oinbody:
1993 break;
1994 case omethodsign:
1995 if (parlev == 0)
1996 {
1997 objdef = omethodtag;
1998 methodlen = len;
1999 grow_linebuffer (&token_name, methodlen+1);
2000 strncpy (token_name.buffer, str, len);
2001 token_name.buffer[methodlen] = '\0';
2002 return TRUE;
2003 }
2004 return FALSE;
2005 case omethodcolon:
2006 if (parlev == 0)
2007 objdef = omethodparm;
2008 return FALSE;
2009 case omethodparm:
2010 if (parlev == 0)
2011 {
2012 objdef = omethodtag;
2013 methodlen += len;
2014 grow_linebuffer (&token_name, methodlen+1);
2015 strncat (token_name.buffer, str, len);
2016 return TRUE;
2017 }
2018 return FALSE;
2019 case oignore:
2020 if (toktype == st_C_objend)
2021 {
2022 /* Memory leakage here: the string pointed by objtag is
2023 never released, because many tests would be needed to
2024 avoid breaking on incorrect input code. The amount of
2025 memory leaked here is the sum of the lengths of the
2026 class tags.
2027 free (objtag); */
2028 objdef = onone;
2029 }
2030 return FALSE;
2031 }
2032
2033 /* A function or enum constant? */
1887 switch (toktype) 2034 switch (toktype)
1888 { 2035 {
1889 case st_C_typespec: 2036 case st_C_typespec:
1890 if (funcdef != finlist && funcdef != fignore) 2037 if (funcdef != finlist && funcdef != fignore)
1891 funcdef = fnone; /* should be useless */ 2038 funcdef = fnone; /* should be useless */
1892 return FALSE; 2039 return FALSE;
1893 default: 2040 case st_none:
2041 if (constantypedefs && structdef == sinbody && structtype == st_C_enum)
2042 return TRUE;
1894 if (funcdef == fnone) 2043 if (funcdef == fnone)
1895 { 2044 {
1896 funcdef = ftagseen; 2045 funcdef = ftagseen;
1897 *is_func = TRUE; 2046 *is_func = TRUE;
1898 return TRUE; 2047 return TRUE;
1902 return FALSE; 2051 return FALSE;
1903 } 2052 }
1904 2053
1905 /* 2054 /*
1906 * C_entries () 2055 * C_entries ()
1907 * This routine finds functions, typedefs, #define's and 2056 * This routine finds functions, typedefs, #define's, enum
1908 * struct/union/enum definitions in C syntax and adds them 2057 * constants and struct/union/enum definitions in C syntax
1909 * to the list. 2058 * and adds them to the list.
1910 */ 2059 */
1911 typedef struct 2060 typedef struct
1912 { 2061 {
1913 logical valid; 2062 logical valid;
1914 char *str; 2063 char *str;
1931 2080
1932 #define CNL_SAVE_DEFINEDEF \ 2081 #define CNL_SAVE_DEFINEDEF \
1933 do { \ 2082 do { \
1934 curlinepos = charno; \ 2083 curlinepos = charno; \
1935 lineno++; \ 2084 lineno++; \
2085 linecharno = charno; \
1936 charno += readline (&curlb, inf); \ 2086 charno += readline (&curlb, inf); \
1937 lp = curlb.buffer; \ 2087 lp = curlb.buffer; \
1938 quotednl = FALSE; \ 2088 quotednl = FALSE; \
1939 newndx = curndx; \ 2089 newndx = curndx; \
1940 } while (0) 2090 } while (0)
1948 savetok.valid = FALSE; \ 2098 savetok.valid = FALSE; \
1949 } \ 2099 } \
1950 definedef = dnone; \ 2100 definedef = dnone; \
1951 } while (0) 2101 } while (0)
1952 2102
1953 #define make_tag(isfun) do \ 2103 /* This macro should never be called when tok.valid is FALSE, but
1954 { \ 2104 we must protect about both invalid input and internal errors. */
1955 if (tok.valid) \ 2105 #define make_C_tag(isfun) do \
1956 { \ 2106 if (tok.valid) { \
1957 char *name = NULL; \ 2107 char *name = NULL; \
1958 if (tok.named) \ 2108 if (CTAGS || tok.named) \
1959 name = savestr (token_name.buffer); \ 2109 name = savestr (token_name.buffer); \
1960 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \ 2110 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1961 } \
1962 else if (DEBUG) abort (); \
1963 tok.valid = FALSE; \ 2111 tok.valid = FALSE; \
1964 } while (0) 2112 } /* else if (DEBUG) abort (); */ while (0)
1965 2113
1966 #if 0 2114 void
2115 C_entries (c_ext, inf)
1967 int c_ext; /* extension of C */ 2116 int c_ext; /* extension of C */
1968 FILE *inf; /* input file */ 2117 FILE *inf; /* input file */
1969 #endif
1970 void
1971 C_entries (int c_ext, FILE *inf)
1972 { 2118 {
1973 register char c; /* latest char read; '\0' for end of line */ 2119 register char c; /* latest char read; '\0' for end of line */
1974 register char *lp; /* pointer one beyond the character `c' */ 2120 register char *lp; /* pointer one beyond the character `c' */
1975 int curndx, newndx; /* indices for current and new lb */ 2121 int curndx, newndx; /* indices for current and new lb */
1976 TOKEN tok; /* latest token read */ 2122 TOKEN tok; /* latest token read */
1977 register int tokoff = 0; /* offset in line of start of current token */ 2123 register int tokoff; /* offset in line of start of current token */
1978 register int toklen = 0; /* length of current token */ 2124 register int toklen; /* length of current token */
1979 int cblev; /* current curly brace level */ 2125 int cblev; /* current curly brace level */
1980 int parlev; /* current parenthesis level */ 2126 int parlev; /* current parenthesis level */
1981 logical incomm, inquote, inchar, quotednl, midtoken; 2127 logical incomm, inquote, inchar, quotednl, midtoken;
1982 logical cplpl; 2128 logical cplpl;
1983 TOKEN savetok; /* token saved during preprocessor handling */ 2129 TOKEN savetok; /* token saved during preprocessor handling */
1987 lineno = 0; 2133 lineno = 0;
1988 charno = 0; 2134 charno = 0;
1989 lp = curlb.buffer; 2135 lp = curlb.buffer;
1990 *lp = 0; 2136 *lp = 0;
1991 2137
1992 definedef = dnone; funcdef = fnone; typdef = tnone; structdef = snone; 2138 funcdef = fnone; typdef = tnone; structdef = snone;
2139 definedef = dnone; objdef = onone;
1993 next_token_is_func = yacc_rules = FALSE; 2140 next_token_is_func = yacc_rules = FALSE;
1994 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2141 midtoken = inquote = inchar = incomm = quotednl = FALSE;
1995 tok.valid = savetok.valid = FALSE; 2142 tok.valid = savetok.valid = FALSE;
1996 cblev = 0; 2143 cblev = 0;
1997 parlev = 0; 2144 parlev = 0;
2080 { 2227 {
2081 lp++; 2228 lp++;
2082 incomm = TRUE; 2229 incomm = TRUE;
2083 continue; 2230 continue;
2084 } 2231 }
2085 else if (cplpl && *lp == '/') 2232 else if (/* cplpl && */ *lp == '/')
2086 { 2233 {
2087 c = 0; 2234 c = '\0';
2088 break; 2235 break;
2089 } 2236 }
2090 else 2237 else
2091 break; 2238 break;
2092 case '%': 2239 case '%':
2133 2280
2134 2281
2135 /* Consider token only if some complicated conditions are satisfied. */ 2282 /* Consider token only if some complicated conditions are satisfied. */
2136 if ((definedef != dnone 2283 if ((definedef != dnone
2137 || (cblev == 0 && structdef != scolonseen) 2284 || (cblev == 0 && structdef != scolonseen)
2138 || (cblev == 1 && cplpl && structdef == sinbody)) 2285 || (cblev == 1 && cplpl && structdef == sinbody)
2286 || (structdef == sinbody && structtype == st_C_enum))
2139 && typdef != tignore 2287 && typdef != tignore
2140 && definedef != dignorerest 2288 && definedef != dignorerest
2141 && funcdef != finlist) 2289 && funcdef != finlist)
2142 { 2290 {
2143 if (midtoken) 2291 if (midtoken)
2144 { 2292 {
2145 if (endtoken (c)) 2293 if (endtoken (c))
2146 { 2294 {
2147 if (cplpl && c == ':' && *lp == ':' && begtoken(*(lp + 1))) 2295 if (c == ':' && cplpl && *lp == ':' && begtoken(*(lp + 1)))
2148 { 2296 {
2149 /* 2297 /*
2150 * This handles :: in the middle, but not at the 2298 * This handles :: in the middle, but not at the
2151 * beginning of an identifier. 2299 * beginning of an identifier.
2152 */ 2300 */
2156 else 2304 else
2157 { 2305 {
2158 logical is_func = FALSE; 2306 logical is_func = FALSE;
2159 2307
2160 if (yacc_rules 2308 if (yacc_rules
2161 || consider_token (newlb.buffer + tokoff, toklen, 2309 || consider_token (newlb.buffer + tokoff, toklen, c,
2162 c, c_ext, cblev, &is_func)) 2310 c_ext, cblev, parlev, &is_func))
2163 { 2311 {
2164 if (structdef == sinbody 2312 if (structdef == sinbody
2165 && definedef == dnone 2313 && definedef == dnone
2166 && is_func) 2314 && is_func)
2167 /* function defined in C++ class body */ 2315 /* function defined in C++ class body */
2168 { 2316 {
2169 int strsize = strlen(structtag) + 2 + toklen + 1; 2317 grow_linebuffer (&token_name,
2170 while (token_name.size < strsize) 2318 strlen(structtag)+2+toklen+1);
2171 {
2172 token_name.size *= 2;
2173 token_name.buffer
2174 = (char *) xrealloc (token_name.buffer,
2175 token_name.size);
2176 }
2177 strcpy (token_name.buffer, structtag); 2319 strcpy (token_name.buffer, structtag);
2178 strcat (token_name.buffer, "::"); 2320 strcat (token_name.buffer, "::");
2179 strncat (token_name.buffer, 2321 strncat (token_name.buffer,
2180 newlb.buffer+tokoff, toklen); 2322 newlb.buffer+tokoff, toklen);
2181 tok.named = TRUE; 2323 tok.named = TRUE;
2182 } 2324 }
2325 else if (objdef == ocatseen)
2326 /* Objective C category */
2327 {
2328 grow_linebuffer (&token_name,
2329 strlen(objtag)+2+toklen+1);
2330 strcpy (token_name.buffer, objtag);
2331 strcat (token_name.buffer, "(");
2332 strncat (token_name.buffer,
2333 newlb.buffer+tokoff, toklen);
2334 strcat (token_name.buffer, ")");
2335 tok.named = TRUE;
2336 }
2337 else if (objdef == omethodtag
2338 || objdef == omethodparm)
2339 /* Objective C method */
2340 {
2341 tok.named = TRUE;
2342 }
2183 else 2343 else
2184 { 2344 {
2185 while (token_name.size < toklen + 1) 2345 grow_linebuffer (&token_name, toklen+1);
2186 {
2187 token_name.size *= 2;
2188 token_name.buffer
2189 = (char *) xrealloc (token_name.buffer,
2190 token_name.size);
2191 }
2192 strncpy (token_name.buffer, 2346 strncpy (token_name.buffer,
2193 newlb.buffer+tokoff, toklen); 2347 newlb.buffer+tokoff, toklen);
2194 token_name.buffer[toklen] = '\0'; 2348 token_name.buffer[toklen] = '\0';
2195 if (structdef == stagseen 2349 if (structdef == stagseen
2196 || typdef == tend 2350 || typdef == tend
2207 tok.valid = TRUE; 2361 tok.valid = TRUE;
2208 2362
2209 if (definedef == dnone 2363 if (definedef == dnone
2210 && (funcdef == ftagseen 2364 && (funcdef == ftagseen
2211 || structdef == stagseen 2365 || structdef == stagseen
2212 || typdef == tend)) 2366 || typdef == tend
2367 || objdef != onone))
2213 { 2368 {
2214 if (current_lb_is_new) 2369 if (current_lb_is_new)
2215 switch_line_buffers (); 2370 switch_line_buffers ();
2216 } 2371 }
2217 else 2372 else
2218 make_tag (is_func); 2373 make_C_tag (is_func);
2219 } 2374 }
2220 midtoken = FALSE; 2375 midtoken = FALSE;
2221 } 2376 }
2222 } /* if (endtoken (c)) */ 2377 } /* if (endtoken (c)) */
2223 else if (intoken (c)) 2378 else if (intoken (c))
2235 { 2390 {
2236 case fstartlist: 2391 case fstartlist:
2237 funcdef = finlist; 2392 funcdef = finlist;
2238 continue; 2393 continue;
2239 case flistseen: 2394 case flistseen:
2240 make_tag (TRUE); 2395 make_C_tag (TRUE);
2241 funcdef = fignore; 2396 funcdef = fignore;
2242 break; 2397 break;
2243 case ftagseen: 2398 case ftagseen:
2244 funcdef = fnone; 2399 funcdef = fnone;
2245 break;
2246 default:
2247 break; 2400 break;
2248 } 2401 }
2249 if (structdef == stagseen) 2402 if (structdef == stagseen)
2250 structdef = snone; 2403 structdef = snone;
2251 break; 2404 break;
2252 case dsharpseen: 2405 case dsharpseen:
2253 savetok = tok; 2406 savetok = tok;
2254 default:
2255 break;
2256 } 2407 }
2257 if (!yacc_rules || lp == newlb.buffer + 1) 2408 if (!yacc_rules || lp == newlb.buffer + 1)
2258 { 2409 {
2259 tokoff = lp - 1 - newlb.buffer; 2410 tokoff = lp - 1 - newlb.buffer;
2260 toklen = 1; 2411 toklen = 1;
2270 switch (c) 2421 switch (c)
2271 { 2422 {
2272 case ':': 2423 case ':':
2273 if (definedef != dnone) 2424 if (definedef != dnone)
2274 break; 2425 break;
2426 switch (objdef)
2427 {
2428 case otagseen:
2429 objdef = oignore;
2430 make_C_tag (TRUE);
2431 break;
2432 case omethodtag:
2433 case omethodparm:
2434 objdef = omethodcolon;
2435 methodlen += 1;
2436 grow_linebuffer (&token_name, methodlen+1);
2437 strcat (token_name.buffer, ":");
2438 break;
2439 }
2275 if (structdef == stagseen) 2440 if (structdef == stagseen)
2276 structdef = scolonseen; 2441 structdef = scolonseen;
2277 else 2442 else
2278 switch (funcdef) 2443 switch (funcdef)
2279 { 2444 {
2280 case ftagseen: 2445 case ftagseen:
2281 if (yacc_rules) 2446 if (yacc_rules)
2282 { 2447 {
2283 make_tag (FALSE); 2448 make_C_tag (FALSE);
2284 funcdef = fignore; 2449 funcdef = fignore;
2285 } 2450 }
2286 break; 2451 break;
2287 case fstartlist: 2452 case fstartlist:
2288 funcdef = fnone; 2453 funcdef = fnone;
2289 break;
2290 default:
2291 break; 2454 break;
2292 } 2455 }
2293 break; 2456 break;
2294 case ';': 2457 case ';':
2295 if (definedef != dnone) 2458 if (definedef != dnone)
2296 break; 2459 break;
2297 if (cblev == 0) 2460 if (cblev == 0)
2298 switch (typdef) 2461 switch (typdef)
2299 { 2462 {
2300 case tend: 2463 case tend:
2301 make_tag (FALSE); 2464 make_C_tag (FALSE);
2302 /* FALLTHRU */ 2465 /* FALLTHRU */
2303 default: 2466 default:
2304 typdef = tnone; 2467 typdef = tnone;
2305 } 2468 }
2306 if (funcdef != fignore) 2469 if (funcdef != fignore)
2315 structdef = snone; 2478 structdef = snone;
2316 break; 2479 break;
2317 case ',': 2480 case ',':
2318 if (definedef != dnone) 2481 if (definedef != dnone)
2319 break; 2482 break;
2483 switch (objdef)
2484 {
2485 case omethodtag:
2486 case omethodparm:
2487 make_C_tag (TRUE);
2488 objdef = oinbody;
2489 break;
2490 }
2320 if (funcdef != finlist && funcdef != fignore) 2491 if (funcdef != finlist && funcdef != fignore)
2321 funcdef = fnone; 2492 funcdef = fnone;
2322 if (structdef == stagseen) 2493 if (structdef == stagseen)
2323 structdef = snone; 2494 structdef = snone;
2324 break; 2495 break;
2326 if (definedef != dnone) 2497 if (definedef != dnone)
2327 break; 2498 break;
2328 if (cblev == 0 && typdef == tend) 2499 if (cblev == 0 && typdef == tend)
2329 { 2500 {
2330 typdef = tignore; 2501 typdef = tignore;
2331 make_tag (FALSE); 2502 make_C_tag (FALSE);
2332 break; 2503 break;
2333 } 2504 }
2334 if (funcdef != finlist && funcdef != fignore) 2505 if (funcdef != finlist && funcdef != fignore)
2335 funcdef = fnone; 2506 funcdef = fnone;
2336 if (structdef == stagseen) 2507 if (structdef == stagseen)
2337 structdef = snone; 2508 structdef = snone;
2338 break; 2509 break;
2339 case '(': 2510 case '(':
2340 if (definedef != dnone) 2511 if (definedef != dnone)
2341 break; 2512 break;
2513 if (objdef == otagseen && parlev == 0)
2514 objdef = oparenseen;
2342 switch (funcdef) 2515 switch (funcdef)
2343 { 2516 {
2344 case fnone: 2517 case fnone:
2345 switch (typdef) 2518 switch (typdef)
2346 { 2519 {
2350 This handles constructs like: 2523 This handles constructs like:
2351 typedef void OperatorFun (int fun); */ 2524 typedef void OperatorFun (int fun); */
2352 if (*lp != '*') 2525 if (*lp != '*')
2353 { 2526 {
2354 typdef = tignore; 2527 typdef = tignore;
2355 make_tag (FALSE); 2528 make_C_tag (FALSE);
2356 } 2529 }
2357 break;
2358 default:
2359 break; 2530 break;
2360 } /* switch (typdef) */ 2531 } /* switch (typdef) */
2361 break; 2532 break;
2362 case ftagseen: 2533 case ftagseen:
2363 funcdef = fstartlist; 2534 funcdef = fstartlist;
2364 break; 2535 break;
2365 case flistseen: 2536 case flistseen:
2366 funcdef = finlist; 2537 funcdef = finlist;
2367 break; 2538 break;
2368 default:
2369 break;
2370 } 2539 }
2371 parlev++; 2540 parlev++;
2372 break; 2541 break;
2373 case ')': 2542 case ')':
2374 if (definedef != dnone) 2543 if (definedef != dnone)
2375 break; 2544 break;
2545 if (objdef == ocatseen && parlev == 1)
2546 {
2547 make_C_tag (TRUE);
2548 objdef = oignore;
2549 }
2376 if (--parlev == 0) 2550 if (--parlev == 0)
2377 { 2551 {
2378 switch (funcdef) 2552 switch (funcdef)
2379 { 2553 {
2380 case fstartlist: 2554 case fstartlist:
2381 case finlist: 2555 case finlist:
2382 funcdef = flistseen; 2556 funcdef = flistseen;
2383 break; 2557 break;
2384 default:
2385 break;
2386 } 2558 }
2387 if (cblev == 0 && typdef == tend) 2559 if (cblev == 0 && typdef == tend)
2388 { 2560 {
2389 typdef = tignore; 2561 typdef = tignore;
2390 make_tag (FALSE); 2562 make_C_tag (FALSE);
2391 } 2563 }
2392 } 2564 }
2393 else if (parlev < 0) /* can happen due to ill-conceived #if's. */ 2565 else if (parlev < 0) /* can happen due to ill-conceived #if's. */
2394 parlev = 0; 2566 parlev = 0;
2395 break; 2567 break;
2399 if (typdef == ttypedseen) 2571 if (typdef == ttypedseen)
2400 typdef = tinbody; 2572 typdef = tinbody;
2401 switch (structdef) 2573 switch (structdef)
2402 { 2574 {
2403 case skeyseen: /* unnamed struct */ 2575 case skeyseen: /* unnamed struct */
2576 structdef = sinbody;
2404 structtag = "_anonymous_"; 2577 structtag = "_anonymous_";
2405 structdef = sinbody;
2406 break; 2578 break;
2407 case stagseen: 2579 case stagseen:
2408 case scolonseen: /* named struct */ 2580 case scolonseen: /* named struct */
2409 structdef = sinbody; 2581 structdef = sinbody;
2410 make_tag (FALSE); 2582 make_C_tag (FALSE);
2411 break; 2583 break;
2412 default:
2413 break;
2414 } 2584 }
2415 switch (funcdef) 2585 switch (funcdef)
2416 { 2586 {
2417 case flistseen: 2587 case flistseen:
2418 make_tag (TRUE); 2588 make_C_tag (TRUE);
2419 /* FALLTHRU */ 2589 /* FALLTHRU */
2420 case fignore: 2590 case fignore:
2421 funcdef = fnone; 2591 funcdef = fnone;
2422 break; 2592 break;
2423 case fnone: 2593 case fnone:
2424 /* Neutralize `extern "C" {' grot and look inside structs. */ 2594 switch (objdef)
2425 if (cblev == 0 && structdef == snone && typdef == tnone) 2595 {
2426 cblev = -1; 2596 case otagseen:
2427 default: 2597 make_C_tag (TRUE);
2428 break; 2598 objdef = oignore;
2599 break;
2600 case omethodtag:
2601 case omethodparm:
2602 make_C_tag (TRUE);
2603 objdef = oinbody;
2604 break;
2605 default:
2606 /* Neutralize `extern "C" {' grot. */
2607 if (cblev == 0 && structdef == snone && typdef == tnone)
2608 cblev = -1;
2609 }
2429 } 2610 }
2430 cblev++; 2611 cblev++;
2431 break; 2612 break;
2432 case '*': 2613 case '*':
2433 if (definedef != dnone) 2614 if (definedef != dnone)
2450 if (typdef == tinbody) 2631 if (typdef == tinbody)
2451 typdef = tend; 2632 typdef = tend;
2452 /* Memory leakage here: the string pointed by structtag is 2633 /* Memory leakage here: the string pointed by structtag is
2453 never released, because I fear to miss something and 2634 never released, because I fear to miss something and
2454 break things while freeing the area. The amount of 2635 break things while freeing the area. The amount of
2455 memory leaked here is the sum of the lenghts of the 2636 memory leaked here is the sum of the lengths of the
2456 struct tags. 2637 struct tags.
2457 if (structdef == sinbody) 2638 if (structdef == sinbody)
2458 free (structtag); */ 2639 free (structtag); */
2459 2640
2460 structdef = snone; 2641 structdef = snone;
2461 structtag = "<error>"; 2642 structtag = "<error>";
2462 } 2643 }
2463 break; 2644 break;
2464 case '=': 2645 case '+':
2465 case '#': case '+': case '-': case '~': case '&': case '%': case '/': 2646 case '-':
2647 if (objdef == oinbody && cblev == 0)
2648 {
2649 objdef = omethodsign;
2650 break;
2651 }
2652 /* FALLTHRU */
2653 case '=': case '#': case '~': case '&': case '%': case '/':
2466 case '|': case '^': case '!': case '<': case '>': case '.': case '?': 2654 case '|': case '^': case '!': case '<': case '>': case '.': case '?':
2467 if (definedef != dnone) 2655 if (definedef != dnone)
2468 break; 2656 break;
2469 /* These surely cannot follow a function tag. */ 2657 /* These surely cannot follow a function tag. */
2470 if (funcdef != finlist && funcdef != fignore) 2658 if (funcdef != finlist && funcdef != fignore)
2471 funcdef = fnone; 2659 funcdef = fnone;
2472 break; 2660 break;
2473 case '\0': 2661 case '\0':
2662 if (objdef == otagseen)
2663 {
2664 make_C_tag (TRUE);
2665 objdef = oignore;
2666 }
2474 /* If a macro spans multiple lines don't reset its state. */ 2667 /* If a macro spans multiple lines don't reset its state. */
2475 if (quotednl) 2668 if (quotednl)
2476 CNL_SAVE_DEFINEDEF; 2669 CNL_SAVE_DEFINEDEF;
2477 else 2670 else
2478 CNL; 2671 CNL;
2485 /* 2678 /*
2486 * Process either a C++ file or a C file depending on the setting 2679 * Process either a C++ file or a C file depending on the setting
2487 * of a global flag. 2680 * of a global flag.
2488 */ 2681 */
2489 void 2682 void
2490 default_C_entries (FILE *inf) 2683 default_C_entries (inf)
2684 FILE *inf;
2491 { 2685 {
2492 C_entries (cplusplus ? C_PLPL : 0, inf); 2686 C_entries (cplusplus ? C_PLPL : 0, inf);
2493 } 2687 }
2494 2688
2495 /* Always do plain ANSI C. */ 2689 /* Always do plain ANSI C. */
2500 C_entries (0, inf); 2694 C_entries (0, inf);
2501 } 2695 }
2502 2696
2503 /* Always do C++. */ 2697 /* Always do C++. */
2504 void 2698 void
2505 Cplusplus_entries (FILE *inf) 2699 Cplusplus_entries (inf)
2700 FILE *inf;
2506 { 2701 {
2507 C_entries (C_PLPL, inf); 2702 C_entries (C_PLPL, inf);
2508 } 2703 }
2509 2704
2510 /* Always do C*. */ 2705 /* Always do C*. */
2511 void 2706 void
2512 Cstar_entries (FILE *inf) 2707 Cstar_entries (inf)
2708 FILE *inf;
2513 { 2709 {
2514 C_entries (C_STAR, inf); 2710 C_entries (C_STAR, inf);
2515 } 2711 }
2516 2712
2517 /* Always do Yacc. */ 2713 /* Always do Yacc. */
2518 void 2714 void
2519 Yacc_entries (FILE *inf) 2715 Yacc_entries (inf)
2716 FILE *inf;
2520 { 2717 {
2521 C_entries (YACC, inf); 2718 C_entries (YACC, inf);
2522 } 2719 }
2523 2720
2524 /* Fortran parsing */ 2721 /* Fortran parsing */
2525 2722
2526 char *dbp; 2723 char *dbp;
2527 2724
2528 static logical 2725 logical
2529 tail (CONST char *cp) 2726 tail (cp)
2727 char *cp;
2530 { 2728 {
2531 register int len = 0; 2729 register int len = 0;
2532 2730
2533 while (*cp && lowcase(*cp) == lowcase(dbp[len])) 2731 while (*cp && lowcase(*cp) == lowcase(dbp[len]))
2534 cp++, len++; 2732 cp++, len++;
2539 } 2737 }
2540 return FALSE; 2738 return FALSE;
2541 } 2739 }
2542 2740
2543 void 2741 void
2544 takeprec (void) 2742 takeprec ()
2545 { 2743 {
2546 while (isspace (*dbp)) 2744 while (isspace (*dbp))
2547 dbp++; 2745 dbp++;
2548 if (*dbp != '*') 2746 if (*dbp != '*')
2549 return; 2747 return;
2564 dbp++; 2762 dbp++;
2565 while (isdigit (*dbp)); 2763 while (isdigit (*dbp));
2566 } 2764 }
2567 2765
2568 void 2766 void
2569 getit (FILE *inf) 2767 getit (inf)
2768 FILE *inf;
2570 { 2769 {
2571 register char *cp; 2770 register char *cp;
2572 2771
2573 while (isspace (*dbp)) 2772 while (isspace (*dbp))
2574 dbp++; 2773 dbp++;
2591 for (cp = dbp + 1; 2790 for (cp = dbp + 1;
2592 (*cp 2791 (*cp
2593 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); 2792 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$')));
2594 cp++) 2793 cp++)
2595 continue; 2794 continue;
2596 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2795 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
2796 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2597 } 2797 }
2598 2798
2599 void 2799 void
2600 Fortran_functions (FILE *inf) 2800 Fortran_functions (inf)
2801 FILE *inf;
2601 { 2802 {
2602 lineno = 0; 2803 lineno = 0;
2603 charno = 0; 2804 charno = 0;
2604 2805
2605 while (!feof (inf)) 2806 while (!feof (inf))
2680 * Bob Weiner, Motorola Inc., 4/3/94 2881 * Bob Weiner, Motorola Inc., 4/3/94
2681 * Unix and microcontroller assembly tag handling 2882 * Unix and microcontroller assembly tag handling
2682 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]' 2883 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
2683 */ 2884 */
2684 void 2885 void
2685 Asm_labels (FILE *inf) 2886 Asm_labels (inf)
2887 FILE *inf;
2686 { 2888 {
2687 register char *cp; 2889 register char *cp;
2688 2890
2689 lineno = 0; 2891 lineno = 0;
2690 charno = 0; 2892 charno = 0;
2705 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$') 2907 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
2706 cp++; 2908 cp++;
2707 if (*cp == ':' || isspace (*cp)) 2909 if (*cp == ':' || isspace (*cp))
2708 { 2910 {
2709 /* Found end of label, so copy it and add it to the table. */ 2911 /* Found end of label, so copy it and add it to the table. */
2710 pfnote (NULL, TRUE, 2912 pfnote ((CTAGS) ? savenstr(lb.buffer, cp-lb.buffer) : NULL, TRUE,
2711 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2913 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2712 } 2914 }
2713 } 2915 }
2714 } 2916 }
2715 } 2917 }
2738 { 2940 {
2739 while (*cp && isspace(*cp)) 2941 while (*cp && isspace(*cp))
2740 cp++; 2942 cp++;
2741 while (*cp && ! isspace(*cp) && *cp != '{') 2943 while (*cp && ! isspace(*cp) && *cp != '{')
2742 cp++; 2944 cp++;
2743 pfnote (NULL, TRUE, 2945 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : NULL, TRUE,
2744 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2946 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2745 } 2947 }
2746 } 2948 }
2747 } 2949 }
2748 2950
2749 /* Added by Mosur Mohan, 4/22/88 */ 2951 /* Added by Mosur Mohan, 4/22/88 */
2750 /* Pascal parsing */ 2952 /* Pascal parsing */
2751
2752 #define GET_NEW_LINE \
2753 { \
2754 linecharno = charno; lineno++; \
2755 charno += 1 + readline (&lb, inf); \
2756 dbp = lb.buffer; \
2757 }
2758 2953
2759 /* 2954 /*
2760 * Locates tags for procedures & functions. Doesn't do any type- or 2955 * Locates tags for procedures & functions. Doesn't do any type- or
2761 * var-definitions. It does look for the keyword "extern" or 2956 * var-definitions. It does look for the keyword "extern" or
2762 * "forward" immediately following the procedure statement; if found, 2957 * "forward" immediately following the procedure statement; if found,
2763 * the tag is skipped. 2958 * the tag is skipped.
2764 */ 2959 */
2765 void 2960 void
2766 Pascal_functions (FILE *inf) 2961 Pascal_functions (inf)
2962 FILE *inf;
2767 { 2963 {
2768 struct linebuffer tline; /* mostly copied from C_entries */ 2964 struct linebuffer tline; /* mostly copied from C_entries */
2769 long save_lcno = 0; 2965 long save_lcno;
2770 int save_lineno = 0, save_len = 0; 2966 int save_lineno, save_len;
2771 char c; 2967 char c, *cp, *namebuf;
2772 2968
2773 logical /* each of these flags is TRUE iff: */ 2969 logical /* each of these flags is TRUE iff: */
2774 incomment, /* point is inside a comment */ 2970 incomment, /* point is inside a comment */
2775 inquote, /* point is inside '..' string */ 2971 inquote, /* point is inside '..' string */
2776 get_tagname, /* point is after PROCEDURE/FUNCTION 2972 get_tagname, /* point is after PROCEDURE/FUNCTION
2799 while (!feof (inf)) 2995 while (!feof (inf))
2800 { 2996 {
2801 c = *dbp++; 2997 c = *dbp++;
2802 if (c == '\0') /* if end of line */ 2998 if (c == '\0') /* if end of line */
2803 { 2999 {
2804 GET_NEW_LINE; 3000 lineno++;
3001 linecharno = charno;
3002 charno += readline (&lb, inf);
3003 dbp = lb.buffer;
2805 if (*dbp == '\0') 3004 if (*dbp == '\0')
2806 continue; 3005 continue;
2807 if (!((found_tag && verify_tag) || 3006 if (!((found_tag && verify_tag) ||
2808 get_tagname)) 3007 get_tagname))
2809 c = *dbp++; /* only if don't need *dbp pointing 3008 c = *dbp++; /* only if don't need *dbp pointing
2880 } 3079 }
2881 if (found_tag && verify_tag) /* not external proc, so make tag */ 3080 if (found_tag && verify_tag) /* not external proc, so make tag */
2882 { 3081 {
2883 found_tag = FALSE; 3082 found_tag = FALSE;
2884 verify_tag = FALSE; 3083 verify_tag = FALSE;
2885 pfnote (NULL, TRUE, 3084 pfnote (namebuf, TRUE,
2886 tline.buffer, save_len, save_lineno, save_lcno); 3085 tline.buffer, save_len, save_lineno, save_lcno);
2887 continue; 3086 continue;
2888 } 3087 }
2889 } 3088 }
2890 if (get_tagname) /* grab name of proc or fn */ 3089 if (get_tagname) /* grab name of proc or fn */
2891 { 3090 {
2892 int size;
2893
2894 if (*dbp == '\0') 3091 if (*dbp == '\0')
2895 continue; 3092 continue;
2896 3093
2897 /* save all values for later tagging */ 3094 /* save all values for later tagging */
2898 size = strlen (lb.buffer) + 1; 3095 grow_linebuffer (&tline, strlen (lb.buffer) + 1);
2899 while (size > tline.size)
2900 {
2901 tline.size *= 2;
2902 tline.buffer = (char *) xrealloc (tline.buffer, tline.size);
2903 }
2904 strcpy (tline.buffer, lb.buffer); 3096 strcpy (tline.buffer, lb.buffer);
2905 save_lineno = lineno; 3097 save_lineno = lineno;
2906 save_lcno = linecharno; 3098 save_lcno = linecharno;
2907 3099
2908 /* grab block name */ 3100 /* grab block name */
2909 for (dbp++; *dbp && (!endtoken (*dbp)); dbp++) 3101 for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++)
2910 continue; 3102 continue;
3103 namebuf = (CTAGS) ? savenstr (dbp, cp-dbp) : NULL;
3104 dbp = cp; /* set dbp to e-o-token */
2911 save_len = dbp - lb.buffer + 1; 3105 save_len = dbp - lb.buffer + 1;
2912 get_tagname = FALSE; 3106 get_tagname = FALSE;
2913 found_tag = TRUE; 3107 found_tag = TRUE;
2914 continue; 3108 continue;
2915 3109
2937 3131
2938 /* 3132 /*
2939 * lisp tag functions 3133 * lisp tag functions
2940 * look for (def or (DEF, quote or QUOTE 3134 * look for (def or (DEF, quote or QUOTE
2941 */ 3135 */
2942 static int 3136 int
2943 L_isdef (char *strp) 3137 L_isdef (strp)
3138 register char *strp;
2944 { 3139 {
2945 return ((strp[1] == 'd' || strp[1] == 'D') 3140 return ((strp[1] == 'd' || strp[1] == 'D')
2946 && (strp[2] == 'e' || strp[2] == 'E') 3141 && (strp[2] == 'e' || strp[2] == 'E')
2947 && (strp[3] == 'f' || strp[3] == 'F')); 3142 && (strp[3] == 'f' || strp[3] == 'F'));
2948 } 3143 }
2949 3144
2950 static int 3145 int
2951 L_isquote (char *strp) 3146 L_isquote (strp)
3147 register char *strp;
2952 { 3148 {
2953 return ((*(++strp) == 'q' || *strp == 'Q') 3149 return ((*(++strp) == 'q' || *strp == 'Q')
2954 && (*(++strp) == 'u' || *strp == 'U') 3150 && (*(++strp) == 'u' || *strp == 'U')
2955 && (*(++strp) == 'o' || *strp == 'O') 3151 && (*(++strp) == 'o' || *strp == 'O')
2956 && (*(++strp) == 't' || *strp == 'T') 3152 && (*(++strp) == 't' || *strp == 'T')
2957 && (*(++strp) == 'e' || *strp == 'E') 3153 && (*(++strp) == 'e' || *strp == 'E')
2958 && isspace(*(++strp))); 3154 && isspace(*(++strp)));
2959 } 3155 }
2960 3156
2961 static void 3157 void
2962 L_getit (void) 3158 L_getit ()
2963 { 3159 {
2964 register char *cp; 3160 register char *cp;
2965 3161
2966 if (*dbp == '\'') /* Skip prefix quote */ 3162 if (*dbp == '\'') /* Skip prefix quote */
2967 dbp++; 3163 dbp++;
2976 cp++) 3172 cp++)
2977 continue; 3173 continue;
2978 if (cp == dbp) 3174 if (cp == dbp)
2979 return; 3175 return;
2980 3176
2981 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3177 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
3178 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2982 } 3179 }
2983 3180
2984 void 3181 void
2985 Lisp_functions (FILE *inf) 3182 Lisp_functions (inf)
3183 FILE *inf;
2986 { 3184 {
2987 lineno = 0; 3185 lineno = 0;
2988 charno = 0; 3186 charno = 0;
2989 3187
2990 while (!feof (inf)) 3188 while (!feof (inf))
3028 } 3226 }
3029 } 3227 }
3030 } 3228 }
3031 } 3229 }
3032 3230
3033 /* XEmacs addition: */
3034
3035 /*
3036 * Postscript tag functions
3037 * Just look for lines where the first character is '/'
3038 */
3039
3040 static void
3041 PS_getit (void)
3042 {
3043 register char *cp;
3044 char c;
3045 char nambuf[BUFSIZ];
3046
3047 if (*dbp == 0) return;
3048 for (cp = dbp+1; *cp && *cp != ' ' && *cp != '{'; cp++)
3049 continue;
3050 c = cp[0];
3051 cp[0] = 0;
3052 strcpy(nambuf, dbp);
3053 cp[0] = c;
3054 pfnote (nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3055 }
3056
3057 void
3058 Postscript_functions (FILE *fi)
3059 {
3060 lineno = 0;
3061 charno = 0;
3062
3063 while (!feof (fi))
3064 {
3065 lineno++;
3066 linecharno = charno;
3067 charno += readline (&lb, fi) + 1;
3068 dbp = lb.buffer;
3069 if (dbp[0] == '/')
3070 {
3071 PS_getit();
3072 }
3073 }
3074 }
3075
3076
3077 /* 3231 /*
3078 * Scheme tag functions 3232 * Scheme tag functions
3079 * look for (def... xyzzy 3233 * look for (def... xyzzy
3080 * look for (def... (xyzzy 3234 * look for (def... (xyzzy
3081 * look for (def ... ((...(xyzzy .... 3235 * look for (def ... ((...(xyzzy ....
3082 * look for (set! xyzzy 3236 * look for (set! xyzzy
3083 */ 3237 */
3084 3238
3085 void get_scheme (void); 3239 void get_scheme ();
3086 3240
3087 void 3241 void
3088 Scheme_functions (FILE *inf) 3242 Scheme_functions (inf)
3243 FILE *inf;
3089 { 3244 {
3090 lineno = 0; 3245 lineno = 0;
3091 charno = 0; 3246 charno = 0;
3092 3247
3093 while (!feof (inf)) 3248 while (!feof (inf))
3124 } 3279 }
3125 } 3280 }
3126 } 3281 }
3127 3282
3128 void 3283 void
3129 get_scheme (void) 3284 get_scheme ()
3130 { 3285 {
3131 register char *cp; 3286 register char *cp;
3132 3287
3133 if (*dbp == '\0') 3288 if (*dbp == '\0')
3134 return; 3289 return;
3135 /* Go till you get to white space or a syntactic break */ 3290 /* Go till you get to white space or a syntactic break */
3136 for (cp = dbp + 1; 3291 for (cp = dbp + 1;
3137 *cp && *cp != '(' && *cp != ')' && !isspace (*cp); 3292 *cp && *cp != '(' && *cp != ')' && !isspace (*cp);
3138 cp++) 3293 cp++)
3139 continue; 3294 continue;
3140 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3295 pfnote ((CTAGS) ? savenstr (dbp, cp-dbp) : NULL, TRUE,
3296 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3141 } 3297 }
3142 3298
3143 /* Find tags in TeX and LaTeX input files. */ 3299 /* Find tags in TeX and LaTeX input files. */
3144 3300
3145 /* TEX_toktab is a table of TeX control sequences that define tags. 3301 /* TEX_toktab is a table of TeX control sequences that define tags.
3146 Each TEX_tabent records one such control sequence. 3302 Each TEX_tabent records one such control sequence.
3147 CONVERT THIS TO USE THE Stab TYPE!! */ 3303 CONVERT THIS TO USE THE Stab TYPE!! */
3148 struct TEX_tabent 3304 struct TEX_tabent
3149 { 3305 {
3150 CONST char *name; 3306 char *name;
3151 int len; 3307 int len;
3152 }; 3308 };
3153 3309
3154 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */ 3310 struct TEX_tabent *TEX_toktab = NULL; /* Table with tag tokens */
3155 3311
3156 /* Default set of control sequences to put into TEX_toktab. 3312 /* Default set of control sequences to put into TEX_toktab.
3157 The value of environment var TEXTAGS is prepended to this. */ 3313 The value of environment var TEXTAGS is prepended to this. */
3158 3314
3159 CONST char *TEX_defenv = "\ 3315 char *TEX_defenv = "\
3160 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ 3316 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\
3161 :part:appendix:entry:index"; 3317 :part:appendix:entry:index";
3162 3318
3163 void TEX_mode (FILE *inf); 3319 void TEX_mode ();
3164 struct TEX_tabent *TEX_decode_env (CONST char *evarname, CONST char *defenv); 3320 struct TEX_tabent *TEX_decode_env ();
3165 int TEX_Token (char *cp); 3321 int TEX_Token ();
3166 #if TeX_named_tokens 3322 #if TeX_named_tokens
3167 void TEX_getit (char *name, int len); 3323 void TEX_getit ();
3168 #endif 3324 #endif
3169 3325
3170 char TEX_esc = '\\'; 3326 char TEX_esc = '\\';
3171 char TEX_opgrp = '{'; 3327 char TEX_opgrp = '{';
3172 char TEX_clgrp = '}'; 3328 char TEX_clgrp = '}';
3173 3329
3174 /* 3330 /*
3175 * TeX/LaTeX scanning loop. 3331 * TeX/LaTeX scanning loop.
3176 */ 3332 */
3177 void 3333 void
3178 TeX_functions (FILE *inf) 3334 TeX_functions (inf)
3335 FILE *inf;
3179 { 3336 {
3180 char *lasthit; 3337 char *lasthit;
3181 3338
3182 lineno = 0; 3339 lineno = 0;
3183 charno = 0; 3340 charno = 0;
3194 lineno++; 3351 lineno++;
3195 linecharno = charno; 3352 linecharno = charno;
3196 charno += readline (&lb, inf); 3353 charno += readline (&lb, inf);
3197 dbp = lb.buffer; 3354 dbp = lb.buffer;
3198 lasthit = dbp; 3355 lasthit = dbp;
3199 while ((dbp = etags_strchr (dbp, TEX_esc)))/* Look at each esc in line */ 3356 while (dbp = etags_strchr (dbp, TEX_esc)) /* Look at each esc in line */
3200 { 3357 {
3201 register int i; 3358 register int i;
3202 3359
3203 if (!*(++dbp)) 3360 if (!*(++dbp))
3204 break; 3361 break;
3205 linecharno += dbp - lasthit; 3362 linecharno += dbp - lasthit;
3206 lasthit = dbp; 3363 lasthit = dbp;
3207 i = TEX_Token (lasthit); 3364 i = TEX_Token (lasthit);
3208 if (0 <= i) 3365 if (0 <= i)
3209 { 3366 {
3210 pfnote (NULL, TRUE, 3367 pfnote ((char *)NULL, TRUE,
3211 lb.buffer, strlen (lb.buffer), lineno, linecharno); 3368 lb.buffer, strlen (lb.buffer), lineno, linecharno);
3212 #if TeX_named_tokens 3369 #if TeX_named_tokens
3213 TEX_getit (lasthit, TEX_toktab[i].len); 3370 TEX_getit (lasthit, TEX_toktab[i].len);
3214 #endif 3371 #endif
3215 break; /* We only save a line once */ 3372 break; /* We only save a line once */
3223 #define TEX_cmt '%' 3380 #define TEX_cmt '%'
3224 3381
3225 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping 3382 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping
3226 chars accordingly. */ 3383 chars accordingly. */
3227 void 3384 void
3228 TEX_mode (FILE *inf) 3385 TEX_mode (inf)
3386 FILE *inf;
3229 { 3387 {
3230 int c; 3388 int c;
3231 3389
3232 while ((c = getc (inf)) != EOF) 3390 while ((c = getc (inf)) != EOF)
3233 { 3391 {
3255 } 3413 }
3256 3414
3257 /* Read environment and prepend it to the default string. 3415 /* Read environment and prepend it to the default string.
3258 Build token table. */ 3416 Build token table. */
3259 struct TEX_tabent * 3417 struct TEX_tabent *
3260 TEX_decode_env (CONST char *evarname, CONST char *defenv) 3418 TEX_decode_env (evarname, defenv)
3261 { 3419 char *evarname;
3262 register CONST char *env, *p; 3420 char *defenv;
3421 {
3422 register char *env, *p;
3263 3423
3264 struct TEX_tabent *tab; 3424 struct TEX_tabent *tab;
3265 int size, i; 3425 int size, i;
3266 3426
3267 /* Append default string to environment. */ 3427 /* Append default string to environment. */
3268 env = getenv (evarname); 3428 env = getenv (evarname);
3269 if (!env) 3429 if (!env)
3270 env = defenv; 3430 env = defenv;
3271 else 3431 else
3272 env = concat (env, defenv, ""); /* never freed! */ 3432 env = concat (env, defenv, "");
3273 3433
3274 /* Allocate a token table */ 3434 /* Allocate a token table */
3275 for (size = 1, p = env; p;) 3435 for (size = 1, p = env; p;)
3276 if ((p = etags_strchr (p, ':')) && *(++p)) 3436 if ((p = etags_strchr (p, ':')) && *(++p))
3277 size++; 3437 size++;
3306 #if TeX_named_tokens 3466 #if TeX_named_tokens
3307 /* Record a tag defined by a TeX command of length LEN and starting at NAME. 3467 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
3308 The name being defined actually starts at (NAME + LEN + 1). 3468 The name being defined actually starts at (NAME + LEN + 1).
3309 But we seem to include the TeX command in the tag name. */ 3469 But we seem to include the TeX command in the tag name. */
3310 void 3470 void
3311 TEX_getit (char *name, int len) 3471 TEX_getit (name, len)
3472 char *name;
3473 int len;
3312 { 3474 {
3313 char *p = name + len; 3475 char *p = name + len;
3314 3476
3315 if (*name == '\0') 3477 if (*name == '\0')
3316 return; 3478 return;
3327 return the pointer to the first occurrence of that command in TEX_toktab. 3489 return the pointer to the first occurrence of that command in TEX_toktab.
3328 Otherwise return -1. 3490 Otherwise return -1.
3329 Keep the capital `T' in `Token' for dumb truncating compilers 3491 Keep the capital `T' in `Token' for dumb truncating compilers
3330 (this distinguishes it from `TEX_toktab' */ 3492 (this distinguishes it from `TEX_toktab' */
3331 int 3493 int
3332 TEX_Token (char *cp) 3494 TEX_Token (cp)
3495 char *cp;
3333 { 3496 {
3334 int i; 3497 int i;
3335 3498
3336 for (i = 0; TEX_toktab[i].len > 0; i++) 3499 for (i = 0; TEX_toktab[i].len > 0; i++)
3337 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len)) 3500 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
3338 return i; 3501 return i;
3339 return -1; 3502 return -1;
3340 } 3503 }
3341 3504
3342 /* Support for Prolog. */ 3505 /*
3343 3506 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
3344 /* Whole head (not only functor, but also arguments) 3507 *
3345 is gotten in compound term. */ 3508 * Assumes that the predicate starts at column 0.
3346 static void 3509 * Only the first clause of a predicate is added.
3347 prolog_getit (char *s) 3510 */
3348 {
3349 char *save_s;
3350 int insquote, npar;
3351
3352 save_s = s;
3353 insquote = FALSE;
3354 npar = 0;
3355 while (1)
3356 {
3357 if (s[0] == '\0') /* syntax error. */
3358 return;
3359 else if (insquote && s[0] == '\'' && s[1] == '\'')
3360 s += 2;
3361 else if (s[0] == '\'')
3362 {
3363 insquote = !insquote;
3364 s++;
3365 }
3366 else if (!insquote && s[0] == '(')
3367 {
3368 npar++;
3369 s++;
3370 }
3371 else if (!insquote && s[0] == ')')
3372 {
3373 npar--;
3374 s++;
3375 if (npar == 0)
3376 break;
3377 else if (npar < 0) /* syntax error. */
3378 return;
3379 }
3380 else if (!insquote && s[0] == '.'
3381 && (isspace (s[1]) || s[1] == '\0'))
3382 { /* fullstop. */
3383 if (npar != 0) /* syntax error. */
3384 return;
3385 s++;
3386 break;
3387 }
3388 else
3389 s++;
3390 }
3391 pfnote (NULL, TRUE, save_s, s-save_s, lineno, linecharno);
3392 }
3393
3394 void skip_comment (struct linebuffer *plb, FILE *inf, int *plineno,
3395 long *plinecharno);
3396
3397 /* It is assumed that prolog predicate starts from column 0. */
3398 void 3511 void
3399 Prolog_functions (FILE *inf) 3512 Prolog_functions (inf)
3400 { 3513 FILE *inf;
3401 lineno = linecharno = charno = 0; 3514 {
3515 int prolog_pred ();
3516 void prolog_skip_comment ();
3517
3518 char * last;
3519 int len;
3520 int allocated;
3521
3522 allocated = 0;
3523 len = 0;
3524 last = NULL;
3525
3526 lineno = 0;
3527 linecharno = 0;
3528 charno = 0;
3529
3402 while (!feof (inf)) 3530 while (!feof (inf))
3403 { 3531 {
3404 lineno++; 3532 lineno++;
3405 linecharno += charno; 3533 linecharno += charno;
3406 charno = readline (&lb, inf) + 1; /* 1 for newline. */ 3534 charno = readline (&lb, inf);
3407 dbp = lb.buffer; 3535 dbp = lb.buffer;
3408 if (isspace (dbp[0])) /* not predicate header. */ 3536 if (dbp[0] == '\0') /* Empty line */
3409 continue; 3537 continue;
3410 else if (dbp[0] == '%') /* comment. */ 3538 else if (isspace (dbp[0])) /* Not a predicate */
3411 continue; 3539 continue;
3412 else if (dbp[0] == '/' && dbp[1] == '*') /* comment. */ 3540 else if (dbp[0] == '/' && dbp[1] == '*') /* comment. */
3413 skip_comment (&lb, inf, &lineno, &linecharno); 3541 prolog_skip_comment (&lb, inf);
3414 else /* found. */ 3542 else if (len = prolog_pred (dbp, last))
3415 prolog_getit (dbp); 3543 {
3416 } 3544 /* Predicate. Store the function name so that we only
3417 } 3545 * generates a tag for the first clause. */
3546 if (last == NULL)
3547 last = xnew(len + 1, char);
3548 else if (len + 1 > allocated)
3549 last = (char *) xrealloc(last, len + 1);
3550 allocated = len + 1;
3551 strncpy (last, dbp, len);
3552 last[len] = '\0';
3553 }
3554 }
3555 }
3556
3418 3557
3419 void 3558 void
3420 skip_comment (struct linebuffer *plb, FILE *inf, int *plineno, 3559 prolog_skip_comment (plb, inf)
3421 long *plinecharno) 3560 struct linebuffer *plb;
3561 FILE *inf;
3422 { 3562 {
3423 char *cp; 3563 char *cp;
3424 3564
3425 do 3565 do
3426 { 3566 {
3427 for (cp = plb->buffer; *cp != '\0'; cp++) 3567 for (cp = plb->buffer; *cp != '\0'; cp++)
3428 if (cp[0] == '*' && cp[1] == '/') 3568 if (cp[0] == '*' && cp[1] == '/')
3429 return; 3569 return;
3430 (*plineno)++; 3570 lineno++;
3431 *plinecharno += readline (plb, inf) + 1; /* 1 for newline. */ 3571 linecharno += readline (plb, inf);
3432 } 3572 }
3433 while (!feof(inf)); 3573 while (!feof(inf));
3574 }
3575
3576 /*
3577 * A predicate definition is added if it matches:
3578 * <beginning of line><Prolog Atom><whitespace>(
3579 *
3580 * It is added to the tags database if it doesn't match the
3581 * name of the previous clause header.
3582 *
3583 * Return the size of the name of the predicate, or 0 if no header
3584 * was found.
3585 */
3586 int
3587 prolog_pred (s, last)
3588 char *s;
3589 char *last; /* Name of last clause. */
3590 {
3591 int prolog_atom();
3592 int prolog_white();
3593
3594 int pos;
3595 int len;
3596
3597 pos = prolog_atom(s, 0);
3598 if (pos < 1)
3599 return 0;
3600
3601 len = pos;
3602 pos += prolog_white(s, pos);
3603
3604 if ((s[pos] == '(') || (s[pos] == '.'))
3605 {
3606 if (s[pos] == '(')
3607 pos++;
3608
3609 /* Save only the first clause. */
3610 if ((last == NULL) ||
3611 (len != strlen(last)) ||
3612 (strncmp(s, last, len) != 0))
3613 {
3614 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE,
3615 s, pos, lineno, linecharno);
3616 return len;
3617 }
3618 }
3619 return 0;
3620 }
3621
3622 /*
3623 * Consume a Prolog atom.
3624 * Return the number of bytes consumed, or -1 if there was an error.
3625 *
3626 * A prolog atom, in this context, could be one of:
3627 * - An alphanumeric sequence, starting with a lower case letter.
3628 * - A quoted arbitrary string. Single quotes can escape themselves.
3629 * Backslash quotes everything.
3630 */
3631 int
3632 prolog_atom (s, pos)
3633 char *s;
3634 int pos;
3635 {
3636 int origpos;
3637
3638 origpos = pos;
3639
3640 if (islower(s[pos]) || (s[pos] == '_'))
3641 {
3642 /* The atom is unquoted. */
3643 pos++;
3644 while (isalnum(s[pos]) || (s[pos] == '_'))
3645 {
3646 pos++;
3647 }
3648 return pos - origpos;
3649 }
3650 else if (s[pos] == '\'')
3651 {
3652 pos++;
3653
3654 while (1)
3655 {
3656 if (s[pos] == '\'')
3657 {
3658 pos++;
3659 if (s[pos] != '\'')
3660 break;
3661 pos++; /* A double quote */
3662 }
3663 else if (s[pos] == '\0')
3664 /* Multiline quoted atoms are ignored. */
3665 return -1;
3666 else if (s[pos] == '\\')
3667 {
3668 if (s[pos+1] == '\0')
3669 return -1;
3670 pos += 2;
3671 }
3672 else
3673 pos++;
3674 }
3675 return pos - origpos;
3676 }
3677 else
3678 return -1;
3679 }
3680
3681 /* Consume whitespace. Return the number of bytes eaten. */
3682 int
3683 prolog_white (s, pos)
3684 char *s;
3685 int pos;
3686 {
3687 int origpos;
3688
3689 origpos = pos;
3690
3691 while (isspace(s[pos]))
3692 pos++;
3693
3694 return pos - origpos;
3695 }
3696
3697 /*
3698 * Support for Erlang -- Anders Lindgren, Feb 1996.
3699 *
3700 * Generates tags for functions, defines, and records.
3701 *
3702 * Assumes that Erlang functions start at column 0.
3703 */
3704 void
3705 Erlang_functions (inf)
3706 FILE *inf;
3707 {
3708 int erlang_func ();
3709 void erlang_attribute ();
3710
3711 char * last;
3712 int len;
3713 int allocated;
3714
3715 allocated = 0;
3716 len = 0;
3717 last = NULL;
3718
3719 lineno = 0;
3720 linecharno = 0;
3721 charno = 0;
3722
3723 while (!feof (inf))
3724 {
3725 lineno++;
3726 linecharno += charno;
3727 charno = readline (&lb, inf);
3728 dbp = lb.buffer;
3729 if (dbp[0] == '\0') /* Empty line */
3730 continue;
3731 else if (isspace (dbp[0])) /* Not function nor attribute */
3732 continue;
3733 else if (dbp[0] == '%') /* comment */
3734 continue;
3735 else if (dbp[0] == '"') /* Sometimes, strings start in column one */
3736 continue;
3737 else if (dbp[0] == '-') /* attribute, e.g. "-define" */
3738 {
3739 erlang_attribute(dbp);
3740 last = NULL;
3741 }
3742 else if (len = erlang_func (dbp, last))
3743 {
3744 /*
3745 * Function. Store the function name so that we only
3746 * generates a tag for the first clause.
3747 */
3748 if (last == NULL)
3749 last = xnew(len + 1, char);
3750 else if (len + 1 > allocated)
3751 last = (char *) xrealloc(last, len + 1);
3752 allocated = len + 1;
3753 strncpy (last, dbp, len);
3754 last[len] = '\0';
3755 }
3756 }
3757 }
3758
3759
3760 /*
3761 * A function definition is added if it matches:
3762 * <beginning of line><Erlang Atom><whitespace>(
3763 *
3764 * It is added to the tags database if it doesn't match the
3765 * name of the previous clause header.
3766 *
3767 * Return the size of the name of the function, or 0 if no function
3768 * was found.
3769 */
3770 int
3771 erlang_func (s, last)
3772 char *s;
3773 char *last; /* Name of last clause. */
3774 {
3775 int erlang_atom ();
3776 int erlang_white ();
3777
3778 int pos;
3779 int len;
3780
3781 pos = erlang_atom(s, 0);
3782 if (pos < 1)
3783 return 0;
3784
3785 len = pos;
3786 pos += erlang_white(s, pos);
3787
3788 if (s[pos++] == '(')
3789 {
3790 /* Save only the first clause. */
3791 if ((last == NULL) ||
3792 (len != strlen(last)) ||
3793 (strncmp(s, last, len) != 0))
3794 {
3795 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE,
3796 s, pos, lineno, linecharno);
3797 return len;
3798 }
3799 }
3800 return 0;
3801 }
3802
3803
3804 /*
3805 * Handle attributes. Currently, tags are generated for defines
3806 * and records.
3807 *
3808 * They are on the form:
3809 * -define(foo, bar).
3810 * -define(Foo(M, N), M+N).
3811 * -record(graph, {vtab = notable, cyclic = true}).
3812 */
3813 void
3814 erlang_attribute (s)
3815 char *s;
3816 {
3817 int erlang_atom ();
3818 int erlang_white ();
3819
3820 int pos;
3821 int len;
3822
3823 if ((strncmp(s, "-define", 7) == 0) ||
3824 (strncmp(s, "-record", 7) == 0))
3825 {
3826 pos = 7;
3827 pos += erlang_white(s, pos);
3828
3829 if (s[pos++] == '(')
3830 {
3831 pos += erlang_white(s, pos);
3832
3833 if (len = erlang_atom(s, pos))
3834 {
3835 pfnote ((CTAGS) ? savenstr (& s[pos], len) : NULL, TRUE,
3836 s, pos + len, lineno, linecharno);
3837 }
3838 }
3839 }
3840 return;
3841 }
3842
3843
3844 /*
3845 * Consume an Erlang atom (or variable).
3846 * Return the number of bytes consumed, or -1 if there was an error.
3847 */
3848 int
3849 erlang_atom (s, pos)
3850 char *s;
3851 int pos;
3852 {
3853 int origpos;
3854
3855 origpos = pos;
3856
3857 if (isalpha (s[pos]) || s[pos] == '_')
3858 {
3859 /* The atom is unquoted. */
3860 pos++;
3861 while (isalnum (s[pos]) || s[pos] == '_')
3862 pos++;
3863 return pos - origpos;
3864 }
3865 else if (s[pos] == '\'')
3866 {
3867 pos++;
3868
3869 while (1)
3870 {
3871 if (s[pos] == '\'')
3872 {
3873 pos++;
3874 break;
3875 }
3876 else if (s[pos] == '\0')
3877 /* Multiline quoted atoms are ignored. */
3878 return -1;
3879 else if (s[pos] == '\\')
3880 {
3881 if (s[pos+1] == '\0')
3882 return -1;
3883 pos += 2;
3884 }
3885 else
3886 pos++;
3887 }
3888 return pos - origpos;
3889 }
3890 else
3891 return -1;
3892 }
3893
3894 /* Consume whitespace. Return the number of bytes eaten */
3895 int
3896 erlang_white (s, pos)
3897 char *s;
3898 int pos;
3899 {
3900 int origpos;
3901
3902 origpos = pos;
3903
3904 while (isspace (s[pos]))
3905 pos++;
3906
3907 return pos - origpos;
3434 } 3908 }
3435 3909
3436 #ifdef ETAGS_REGEXPS 3910 #ifdef ETAGS_REGEXPS
3437 /* Take a string like "/blah/" and turn it into "blah", making sure 3911 /* Take a string like "/blah/" and turn it into "blah", making sure
3438 that the first and last characters are the same, and handling 3912 that the first and last characters are the same, and handling
3439 quoted separator characters. Actually, stops on the occurrence of 3913 quoted separator characters. Actually, stops on the occurrence of
3440 an unquoted separator. Also turns "\t" into a Tab character. 3914 an unquoted separator. Also turns "\t" into a Tab character.
3441 Returns pointer to terminating separator. Works in place. Null 3915 Returns pointer to terminating separator. Works in place. Null
3442 terminates name string. */ 3916 terminates name string. */
3443 static char * 3917 char *
3444 scan_separators (char *name) 3918 scan_separators (name)
3919 char *name;
3445 { 3920 {
3446 char sep = name[0]; 3921 char sep = name[0];
3447 char *copyto = name; 3922 char *copyto = name;
3448 logical quoted = FALSE; 3923 logical quoted = FALSE;
3449 3924
3477 } 3952 }
3478 3953
3479 /* Turn a name, which is an ed-style (but Emacs syntax) regular 3954 /* Turn a name, which is an ed-style (but Emacs syntax) regular
3480 expression, into a real regular expression by compiling it. */ 3955 expression, into a real regular expression by compiling it. */
3481 void 3956 void
3482 add_regex (char *regexp_pattern) 3957 add_regex (regexp_pattern)
3958 char *regexp_pattern;
3483 { 3959 {
3484 char *name; 3960 char *name;
3485 const char *err; 3961 const char *err;
3486 struct re_pattern_buffer *patbuf; 3962 struct re_pattern_buffer *patbuf;
3487 3963
3493 return; 3969 return;
3494 } 3970 }
3495 3971
3496 if (regexp_pattern[0] == '\0') 3972 if (regexp_pattern[0] == '\0')
3497 { 3973 {
3498 error ("missing regexp", 0); 3974 error ("missing regexp", (char *)NULL);
3499 return; 3975 return;
3500 } 3976 }
3501 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0]) 3977 if (regexp_pattern[strlen(regexp_pattern)-1] != regexp_pattern[0])
3502 { 3978 {
3503 error ("%s: unterminated regexp", regexp_pattern); 3979 error ("%s: unterminated regexp", regexp_pattern);
3504 return; 3980 return;
3505 } 3981 }
3506 name = scan_separators (regexp_pattern); 3982 name = scan_separators (regexp_pattern);
3507 if (regexp_pattern[0] == '\0') 3983 if (regexp_pattern[0] == '\0')
3508 { 3984 {
3509 error ("null regexp", 0); 3985 error ("null regexp", (char *)NULL);
3510 return; 3986 return;
3511 } 3987 }
3512 (void) scan_separators (name); 3988 (void) scan_separators (name);
3513 3989
3514 patbuf = xnew (1, struct re_pattern_buffer); 3990 patbuf = xnew (1, struct re_pattern_buffer);
3518 patbuf->allocated = 0; 3994 patbuf->allocated = 0;
3519 3995
3520 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); 3996 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
3521 if (err != NULL) 3997 if (err != NULL)
3522 { 3998 {
3523 error ("%s while compiling pattern", (void *) err); 3999 error ("%s while compiling pattern", err);
3524 return; 4000 return;
3525 } 4001 }
3526 4002
3527 num_patterns += 1; 4003 num_patterns += 1;
3528 if (num_patterns == 1) 4004 if (num_patterns == 1)
3538 4014
3539 /* 4015 /*
3540 * Do the substitutions indicated by the regular expression and 4016 * Do the substitutions indicated by the regular expression and
3541 * arguments. 4017 * arguments.
3542 */ 4018 */
3543 static char * 4019 char *
3544 substitute (char *in, char *out, struct re_registers *regs) 4020 substitute (in, out, regs)
4021 char *in, *out;
4022 struct re_registers *regs;
3545 { 4023 {
3546 char *result = NULL, *t; 4024 char *result = NULL, *t;
3547 int size = 0; 4025 int size = 0;
3548 4026
3549 /* Pass 1: figure out how much size to allocate. */ 4027 /* Pass 1: figure out how much size to allocate. */
3552 if (*t == '\\') 4030 if (*t == '\\')
3553 { 4031 {
3554 ++t; 4032 ++t;
3555 if (!*t) 4033 if (!*t)
3556 { 4034 {
3557 fprintf (stderr, "%s: pattern subtitution ends prematurely\n", 4035 fprintf (stderr, "%s: pattern substitution ends prematurely\n",
3558 progname); 4036 progname);
3559 return NULL; 4037 return NULL;
3560 } 4038 }
3561 if (isdigit (*t)) 4039 if (isdigit (*t))
3562 { 4040 {
3594 } 4072 }
3595 4073
3596 #endif /* ETAGS_REGEXPS */ 4074 #endif /* ETAGS_REGEXPS */
3597 /* Initialize a linebuffer for use */ 4075 /* Initialize a linebuffer for use */
3598 void 4076 void
3599 initbuffer (struct linebuffer *linebuffer) 4077 initbuffer (linebuffer)
4078 struct linebuffer *linebuffer;
3600 { 4079 {
3601 linebuffer->size = 200; 4080 linebuffer->size = 200;
3602 linebuffer->buffer = xnew (200, char); 4081 linebuffer->buffer = xnew (200, char);
3603 } 4082 }
3604 4083
3606 * Read a line of text from `stream' into `linebuffer'. 4085 * Read a line of text from `stream' into `linebuffer'.
3607 * Return the number of characters read from `stream', 4086 * Return the number of characters read from `stream',
3608 * which is the length of the line including the newline, if any. 4087 * which is the length of the line including the newline, if any.
3609 */ 4088 */
3610 long 4089 long
3611 readline_internal (struct linebuffer *linebuffer, FILE *stream) 4090 readline_internal (linebuffer, stream)
4091 struct linebuffer *linebuffer;
4092 register FILE *stream;
3612 { 4093 {
3613 char *buffer = linebuffer->buffer; 4094 char *buffer = linebuffer->buffer;
3614 register char *p = linebuffer->buffer; 4095 register char *p = linebuffer->buffer;
3615 register char *pend; 4096 register char *pend;
3616 int chars_deleted; 4097 int chars_deleted;
3628 pend = buffer + linebuffer->size; 4109 pend = buffer + linebuffer->size;
3629 linebuffer->buffer = buffer; 4110 linebuffer->buffer = buffer;
3630 } 4111 }
3631 if (c == EOF) 4112 if (c == EOF)
3632 { 4113 {
4114 *p = '\0';
3633 chars_deleted = 0; 4115 chars_deleted = 0;
3634 break; 4116 break;
3635 } 4117 }
3636 if (c == '\n') 4118 if (c == '\n')
3637 { 4119 {
3638 if (p > buffer && p[-1] == '\r') 4120 if (p > buffer && p[-1] == '\r')
3639 { 4121 {
3640 *--p = '\0'; 4122 *--p = '\0';
4123 #ifdef DOS_NT
4124 /* Assume CRLF->LF translation will be performed by Emacs
4125 when loading this file, so CRs won't appear in the buffer.
4126 It would be cleaner to compensate within Emacs;
4127 however, Emacs does not know how many CRs were deleted
4128 before any given point in the file. */
4129 chars_deleted = 1;
4130 #else
3641 chars_deleted = 2; 4131 chars_deleted = 2;
4132 #endif
3642 } 4133 }
3643 else 4134 else
3644 { 4135 {
3645 *p = '\0'; 4136 *p = '\0';
3646 chars_deleted = 1; 4137 chars_deleted = 1;
3656 /* 4147 /*
3657 * Like readline_internal, above, but try to match the input 4148 * Like readline_internal, above, but try to match the input
3658 * line against any existing regular expressions. 4149 * line against any existing regular expressions.
3659 */ 4150 */
3660 long 4151 long
3661 readline (struct linebuffer *linebuffer, FILE *stream) 4152 readline (linebuffer, stream)
4153 struct linebuffer *linebuffer;
4154 FILE *stream;
3662 { 4155 {
3663 /* Read new line. */ 4156 /* Read new line. */
4157 long result = readline_internal (linebuffer, stream);
3664 #ifdef ETAGS_REGEXPS 4158 #ifdef ETAGS_REGEXPS
3665 int i; 4159 int i;
3666 #endif 4160
3667 long result = readline_internal (linebuffer, stream);
3668
3669 #ifdef ETAGS_REGEXPS
3670 /* Match against all listed patterns. */ 4161 /* Match against all listed patterns. */
3671 for (i = 0; i < num_patterns; ++i) 4162 for (i = 0; i < num_patterns; ++i)
3672 { 4163 {
3673 int match = re_match (patterns[i].pattern, linebuffer->buffer, 4164 int match = re_match (patterns[i].pattern, linebuffer->buffer,
3674 (int)result, 0, &patterns[i].regs); 4165 (int)result, 0, &patterns[i].regs);
3676 { 4167 {
3677 case -2: 4168 case -2:
3678 /* Some error. */ 4169 /* Some error. */
3679 if (!patterns[i].error_signaled) 4170 if (!patterns[i].error_signaled)
3680 { 4171 {
3681 /* To avoid casting an int to a pointer, format the string 4172 error ("error while matching pattern %d", i);
3682 * here, and pass the address of the string to `error'. */
3683 char int_string[12];
3684
3685 sprintf(int_string, "%d", i);
3686 error ("error while matching pattern %s", int_string);
3687 patterns[i].error_signaled = TRUE; 4173 patterns[i].error_signaled = TRUE;
3688 } 4174 }
3689 break; 4175 break;
3690 case -1: 4176 case -1:
3691 /* No match. */ 4177 /* No match. */
3703 linebuffer->buffer, match, lineno, linecharno); 4189 linebuffer->buffer, match, lineno, linecharno);
3704 } 4190 }
3705 else 4191 else
3706 { 4192 {
3707 /* Make an unnamed tag. */ 4193 /* Make an unnamed tag. */
3708 pfnote (NULL, TRUE, 4194 pfnote ((char *)NULL, TRUE,
3709 linebuffer->buffer, match, lineno, linecharno); 4195 linebuffer->buffer, match, lineno, linecharno);
3710 } 4196 }
3711 break; 4197 break;
3712 } 4198 }
3713 } 4199 }
3719 /* 4205 /*
3720 * Read a file, but do no processing. This is used to do regexp 4206 * Read a file, but do no processing. This is used to do regexp
3721 * matching on files that have no language defined. 4207 * matching on files that have no language defined.
3722 */ 4208 */
3723 void 4209 void
3724 just_read_file (FILE *inf) 4210 just_read_file (inf)
3725 { 4211 FILE *inf;
4212 {
4213 lineno = 0;
4214 charno = 0;
4215
3726 while (!feof (inf)) 4216 while (!feof (inf))
3727 { 4217 {
3728 ++lineno; 4218 ++lineno;
3729 linecharno = charno; 4219 linecharno = charno;
3730 charno += readline (&lb, inf) + 1; 4220 charno += readline (&lb, inf) + 1;
3735 /* 4225 /*
3736 * Return a pointer to a space of size strlen(cp)+1 allocated 4226 * Return a pointer to a space of size strlen(cp)+1 allocated
3737 * with xnew where the string CP has been copied. 4227 * with xnew where the string CP has been copied.
3738 */ 4228 */
3739 char * 4229 char *
3740 savestr (CONST char *cp) 4230 savestr (cp)
4231 char *cp;
3741 { 4232 {
3742 return savenstr (cp, strlen (cp)); 4233 return savenstr (cp, strlen (cp));
3743 } 4234 }
3744 4235
3745 /* 4236 /*
3746 * Return a pointer to a space of size LEN+1 allocated with xnew where 4237 * Return a pointer to a space of size LEN+1 allocated with xnew where
3747 * the string CP has been copied for at most the first LEN characters. 4238 * the string CP has been copied for at most the first LEN characters.
3748 */ 4239 */
3749 char * 4240 char *
3750 savenstr (CONST char *cp, int len) 4241 savenstr (cp, len)
4242 char *cp;
4243 int len;
3751 { 4244 {
3752 register char *dp; 4245 register char *dp;
3753 4246
3754 dp = xnew (len + 1, char); 4247 dp = xnew (len + 1, char);
3755 strncpy (dp, cp, len); 4248 strncpy (dp, cp, len);
3762 * appears; NULL if not found 4255 * appears; NULL if not found
3763 * 4256 *
3764 * Identical to System V strrchr, included for portability. 4257 * Identical to System V strrchr, included for portability.
3765 */ 4258 */
3766 char * 4259 char *
3767 etags_strrchr (CONST char *sp, char c) 4260 etags_strrchr (sp, c)
3768 { 4261 register char *sp, c;
3769 register CONST char *r; 4262 {
4263 register char *r;
3770 4264
3771 r = NULL; 4265 r = NULL;
3772 do 4266 do
3773 { 4267 {
3774 if (*sp == c) 4268 if (*sp == c)
3775 r = sp; 4269 r = sp;
3776 } while (*sp++); 4270 } while (*sp++);
3777 return (char *)r; 4271 return r;
3778 } 4272 }
3779 4273
3780 4274
3781 /* 4275 /*
3782 * Return the ptr in sp at which the character c first 4276 * Return the ptr in sp at which the character c first
3783 * appears; NULL if not found 4277 * appears; NULL if not found
3784 * 4278 *
3785 * Identical to System V strchr, included for portability. 4279 * Identical to System V strchr, included for portability.
3786 */ 4280 */
3787 char * 4281 char *
3788 etags_strchr (CONST char *sp, char c) 4282 etags_strchr (sp, c)
4283 register char *sp, c;
3789 { 4284 {
3790 do 4285 do
3791 { 4286 {
3792 if (*sp == c) 4287 if (*sp == c)
3793 return (char *)sp; 4288 return sp;
3794 } while (*sp++); 4289 } while (*sp++);
3795 return NULL; 4290 return NULL;
3796 } 4291 }
3797 4292
3798 /* Print error message and exit. */ 4293 /* Print error message and exit. */
3799 void 4294 void
3800 fatal (CONST char *s1, CONST char *s2) 4295 fatal (s1, s2)
4296 char *s1, *s2;
3801 { 4297 {
3802 error (s1, s2); 4298 error (s1, s2);
3803 exit (BAD); 4299 exit (BAD);
3804 } 4300 }
3805 4301
3806 void 4302 void
3807 pfatal (CONST char *s1) 4303 pfatal (s1)
4304 char *s1;
3808 { 4305 {
3809 perror (s1); 4306 perror (s1);
3810 exit (BAD); 4307 exit (BAD);
3811 } 4308 }
3812 4309
4310 void
4311 suggest_asking_for_help ()
4312 {
4313 fprintf (stderr, "\tTry `%s --help' for a complete list of options.\n",
4314 progname);
4315 exit (BAD);
4316 }
4317
3813 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ 4318 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
3814 void 4319 void
3815 error (CONST char *s1, CONST void *s2) 4320 error (s1, s2)
4321 char *s1, *s2;
3816 { 4322 {
3817 fprintf (stderr, "%s: ", progname); 4323 fprintf (stderr, "%s: ", progname);
3818 fprintf (stderr, s1, s2); 4324 fprintf (stderr, s1, s2);
3819 fprintf (stderr, "\n"); 4325 fprintf (stderr, "\n");
3820 } 4326 }
3821 4327
3822 /* Return a newly-allocated string whose contents 4328 /* Return a newly-allocated string whose contents
3823 concatenate those of s1, s2, s3. */ 4329 concatenate those of s1, s2, s3. */
3824 char * 4330 char *
3825 concat (CONST char *s1, CONST char *s2, CONST char *s3) 4331 concat (s1, s2, s3)
4332 char *s1, *s2, *s3;
3826 { 4333 {
3827 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); 4334 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
3828 char *result = xnew (len1 + len2 + len3 + 1, char); 4335 char *result = xnew (len1 + len2 + len3 + 1, char);
3829 4336
3830 strcpy (result, s1); 4337 strcpy (result, s1);
3835 return result; 4342 return result;
3836 } 4343 }
3837 4344
3838 /* Does the same work as the system V getcwd, but does not need to 4345 /* Does the same work as the system V getcwd, but does not need to
3839 guess the buffer size in advance. */ 4346 guess the buffer size in advance. */
3840 /* Does the same work as the system V getcwd, but does not need to
3841 guess the buffer size in advance. */
3842 char * 4347 char *
3843 etags_getcwd (void) 4348 etags_getcwd ()
3844 { 4349 {
3845 #ifdef DOS_NT 4350 #ifdef HAVE_GETCWD
3846 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
3847
3848 getwd (path);
3849 p = path;
3850 while (*p)
3851 if (*p == '\\')
3852 *p++ = '/';
3853 else
3854 *p++ = lowcase (*p);
3855
3856 return strdup (path);
3857 #else /* not DOS_NT */
3858 #if HAVE_GETCWD
3859 int bufsize = 200; 4351 int bufsize = 200;
3860 char *path = xnew (bufsize, char); 4352 char *path = xnew (bufsize, char);
3861 4353
3862 while (getcwd (path, bufsize) == NULL) 4354 while (getcwd (path, bufsize) == NULL)
3863 { 4355 {
3865 pfatal ("getcwd"); 4357 pfatal ("getcwd");
3866 bufsize *= 2; 4358 bufsize *= 2;
3867 path = xnew (bufsize, char); 4359 path = xnew (bufsize, char);
3868 } 4360 }
3869 4361
4362 #if WINDOWSNT
4363 {
4364 /* Convert backslashes to slashes. */
4365 char *p;
4366 for (p = path; *p != '\0'; p++)
4367 if (*p == '\\')
4368 *p = '/';
4369 }
4370 #endif
4371
3870 return path; 4372 return path;
3871 #else /* not DOS_NT and not HAVE_GETCWD */ 4373
4374 #else /* not HAVE_GETCWD */
4375 #ifdef MSDOS
4376 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
4377
4378 getwd (path);
4379
4380 for (p = path; *p != '\0'; p++)
4381 if (*p == '\\')
4382 *p = '/';
4383 else
4384 *p = lowcase (*p);
4385
4386 return strdup (path);
4387 #else /* not MSDOS */
3872 struct linebuffer path; 4388 struct linebuffer path;
3873 FILE *paype; 4389 FILE *pipe;
3874 4390
3875 initbuffer (&path); 4391 initbuffer (&path);
3876 paype = (FILE *) popen ("pwd 2>/dev/null", "r"); 4392 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
3877 if (paype == NULL || readline_internal (&path, paype) == 0) 4393 if (pipe == NULL || readline_internal (&path, pipe) == 0)
3878 pfatal ("pwd"); 4394 pfatal ("pwd");
3879 pclose (paype); 4395 pclose (pipe);
3880 4396
3881 return path.buffer; 4397 return path.buffer;
4398 #endif /* not MSDOS */
3882 #endif /* not HAVE_GETCWD */ 4399 #endif /* not HAVE_GETCWD */
3883 #endif /* not DOS_NT */
3884 } 4400 }
3885 4401
3886 /* Return a newly allocated string containing the filename 4402 /* Return a newly allocated string containing the filename
3887 of FILE relative to the absolute directory DIR (which 4403 of FILE relative to the absolute directory DIR (which
3888 should end with a slash). */ 4404 should end with a slash). */
3889 char * 4405 char *
3890 relative_filename (CONST char *file, CONST char *dir) 4406 relative_filename (file, dir)
3891 { 4407 char *file, *dir;
3892 char *fp; 4408 {
3893 CONST char *dp; 4409 char *fp, *dp, *abs, *res;
3894 char *abbs, *res; 4410
3895 4411 /* Find the common root of file and dir (with a trailing slash). */
3896 /* Find the common root of file and dir. */ 4412 abs = absolute_filename (file, cwd);
3897 abbs = absolute_filename (file, cwd); 4413 fp = abs;
3898 fp = abbs;
3899 dp = dir; 4414 dp = dir;
3900 while (*fp++ == *dp++) 4415 while (*fp++ == *dp++)
3901 continue; 4416 continue;
3902 do 4417 fp--, dp--; /* back to the first differing char */
3903 { 4418 do /* look at the equal chars until / */
3904 fp--; 4419 fp--, dp--;
3905 dp--;
3906 }
3907 while (*fp != '/'); 4420 while (*fp != '/');
3908 4421
3909 /* Build a sequence of "../" strings for the resulting relative filename. */ 4422 /* Build a sequence of "../" strings for the resulting relative filename. */
3910 for (dp = etags_strchr (dp + 1, '/'), res = (char *) ""; 4423 for (dp = etags_strchr (dp + 1, '/'), res = "";
3911 dp != NULL; 4424 dp != NULL;
3912 dp = etags_strchr (dp + 1, '/')) 4425 dp = etags_strchr (dp + 1, '/'))
3913 { 4426 {
3914 res = concat (res, "../", ""); 4427 res = concat (res, "../", "");
3915 } 4428 }
3916 4429
3917 /* Add the filename relative to the common root of file and dir. */ 4430 /* Add the filename relative to the common root of file and dir. */
3918 res = concat (res, fp + 1, ""); 4431 res = concat (res, fp + 1, "");
3919 free (abbs); 4432 free (abs);
3920 4433
3921 return res; 4434 return res;
3922 } 4435 }
3923 4436
3924 /* Return a newly allocated string containing the 4437 /* Return a newly allocated string containing the
3925 absolute filename of FILE given CWD (which should 4438 absolute filename of FILE given CWD (which should
3926 end with a slash). */ 4439 end with a slash). */
3927 char * 4440 char *
3928 absolute_filename (CONST char *file, CONST char *cwwd) 4441 absolute_filename (file, cwd)
4442 char *file, *cwd;
3929 { 4443 {
3930 char *slashp, *cp, *res; 4444 char *slashp, *cp, *res;
3931 4445
3932 if (absolutefn (file)) 4446 if (absolutefn (file))
3933 res = concat (file, "", ""); 4447 res = concat (file, "", "");
4448 #ifdef DOS_NT
4449 /* We don't support non-absolute filenames with a drive
4450 letter, like `d:NAME' (it's too much hassle). */
4451 else if (file[1] == ':')
4452 fatal ("%s: relative filenames with drive letters not supported", file);
4453 #endif
3934 else 4454 else
3935 res = concat (cwwd, file, ""); 4455 res = concat (cwd, file, "");
3936 4456
3937 /* Delete the "/dirname/.." and "/." substrings. */ 4457 /* Delete the "/dirname/.." and "/." substrings. */
3938 slashp = etags_strchr (res, '/'); 4458 slashp = etags_strchr (res, '/');
3939 while (slashp != NULL && slashp[0] != '\0') 4459 while (slashp != NULL && slashp[0] != '\0')
3940 { 4460 {
3944 && (slashp[3] == '/' || slashp[3] == '\0')) 4464 && (slashp[3] == '/' || slashp[3] == '\0'))
3945 { 4465 {
3946 cp = slashp; 4466 cp = slashp;
3947 do 4467 do
3948 cp--; 4468 cp--;
3949 while (cp >= res && *cp != '/'); 4469 while (cp >= res && !absolutefn (cp));
3950 if (*cp == '/') 4470 if (*cp == '/')
3951 { 4471 {
3952 strcpy (cp, slashp + 3); 4472 strcpy (cp, slashp + 3);
3953 } 4473 }
4474 #ifdef DOS_NT
4475 /* Under MSDOS and NT we get `d:/NAME' as absolute
4476 filename, so the luser could say `d:/../NAME'.
4477 We silently treat this as `d:/NAME'. */
4478 else if (cp[1] == ':')
4479 strcpy (cp + 3, slashp + 4);
4480 #endif
3954 else /* else (cp == res) */ 4481 else /* else (cp == res) */
3955 { 4482 {
3956 if (slashp[3] != '\0') 4483 if (slashp[3] != '\0')
3957 strcpy (cp, slashp + 4); 4484 strcpy (cp, slashp + 4);
3958 else 4485 else
3959 return (char *) "."; 4486 return ".";
3960 } 4487 }
3961 slashp = cp; 4488 slashp = cp;
3962 continue; 4489 continue;
3963 } 4490 }
3964 else if (slashp[2] == '/' || slashp[2] == '\0') 4491 else if (slashp[2] == '/' || slashp[2] == '\0')
3976 4503
3977 /* Return a newly allocated string containing the absolute 4504 /* Return a newly allocated string containing the absolute
3978 filename of dir where FILE resides given CWD (which should 4505 filename of dir where FILE resides given CWD (which should
3979 end with a slash). */ 4506 end with a slash). */
3980 char * 4507 char *
3981 absolute_dirname (char *file, CONST char *cwwd) 4508 absolute_dirname (file, cwd)
4509 char *file, *cwd;
3982 { 4510 {
3983 char *slashp, *res; 4511 char *slashp, *res;
3984 char save; 4512 char save;
4513 #ifdef DOS_NT
4514 char *p;
4515
4516 for (p = file; *p != '\0'; p++)
4517 if (*p == '\\')
4518 *p = '/';
4519 #endif
3985 4520
3986 slashp = etags_strrchr (file, '/'); 4521 slashp = etags_strrchr (file, '/');
3987 if (slashp == NULL) 4522 if (slashp == NULL)
3988 return (char *) cwwd; 4523 return cwd;
3989 save = slashp[1]; 4524 save = slashp[1];
3990 slashp[1] = '\0'; 4525 slashp[1] = '\0';
3991 res = absolute_filename (file, cwwd); 4526 res = absolute_filename (file, cwd);
3992 slashp[1] = save; 4527 slashp[1] = save;
3993 4528
3994 return res; 4529 return res;
3995 } 4530 }
3996 4531
4532 /* Increase the size of a linebuffer. */
4533 void
4534 grow_linebuffer (bufp, toksize)
4535 struct linebuffer *bufp;
4536 int toksize;
4537 {
4538 while (bufp->size < toksize)
4539 bufp->size *= 2;
4540 bufp->buffer = (char *) xrealloc (bufp->buffer, bufp->size);
4541 }
4542
3997 /* Like malloc but get fatal error if memory is exhausted. */ 4543 /* Like malloc but get fatal error if memory is exhausted. */
3998 void * 4544 long *
3999 xmalloc (unsigned int size) 4545 xmalloc (size)
4000 { 4546 unsigned int size;
4001 void *result = malloc (size); 4547 {
4548 long *result = (long *) malloc (size);
4002 if (result == NULL) 4549 if (result == NULL)
4003 fatal ("virtual memory exhausted", 0); 4550 fatal ("virtual memory exhausted", (char *)NULL);
4004 return result; 4551 return result;
4005 } 4552 }
4006 4553
4007 void * 4554 long *
4008 xrealloc (void *ptr, unsigned int size) 4555 xrealloc (ptr, size)
4009 { 4556 char *ptr;
4010 void *result = realloc (ptr, size); 4557 unsigned int size;
4558 {
4559 long *result = (long *) realloc (ptr, size);
4011 if (result == NULL) 4560 if (result == NULL)
4012 fatal ("virtual memory exhausted", 0); 4561 fatal ("virtual memory exhausted", (char *)NULL);
4013 return result; 4562 return result;
4014 } 4563 }