Mercurial > hg > xemacs-beta
comparison lib-src/etags.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
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, 98, 99 | 2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98 |
3 Free Software Foundation, Inc. and Ken Arnold | 3 Free Software Foundation, Inc. and Ken Arnold |
4 | 4 |
5 This file is not considered part of GNU Emacs. | 5 This file is not considered part of GNU Emacs. |
6 | 6 |
7 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 |
26 * Gnu Emacs TAGS format and modifications by RMS? | 26 * Gnu Emacs TAGS format and modifications by RMS? |
27 * Sam Kendall added C++. | 27 * Sam Kendall added C++. |
28 * 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. |
29 * Regexp tags by Tom Tromey. | 29 * Regexp tags by Tom Tromey. |
30 * | 30 * |
31 * Francesco Potorti` (pot@gnu.org) is the current maintainer. | 31 * Francesco Potorti` (F.Potorti@cnuce.cnr.it) is the current maintainer. |
32 */ | 32 */ |
33 | 33 |
34 char pot_etags_version[] = "@(#) pot revision number is 13.44"; | 34 char pot_etags_version[] = "@(#) pot revision number is 13.7"; |
35 | 35 |
36 #define TRUE 1 | 36 #define TRUE 1 |
37 #define FALSE 0 | 37 #define FALSE 0 |
38 | 38 |
39 #ifndef DEBUG | 39 #ifndef DEBUG |
40 # define DEBUG FALSE | 40 # define DEBUG FALSE |
41 #endif | 41 #endif |
42 | 42 |
43 #if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C)) | 43 #ifdef MSDOS |
44 # define P_(proto) proto | 44 # include <fcntl.h> |
45 #else | 45 # include <sys/param.h> |
46 # define P_(proto) () | 46 # include <io.h> |
47 #endif | 47 # ifndef HAVE_CONFIG_H |
48 # define DOS_NT | |
49 # include <sys/config.h> | |
50 # endif | |
51 #endif /* MSDOS */ | |
52 | |
53 #ifdef WINDOWSNT | |
54 # include <stdlib.h> | |
55 # include <fcntl.h> | |
56 # include <string.h> | |
57 # include <io.h> | |
58 # define MAXPATHLEN _MAX_PATH | |
59 # ifdef HAVE_CONFIG_H | |
60 # undef HAVE_NTGUI | |
61 # else | |
62 # define DOS_NT | |
63 # define HAVE_GETCWD | |
64 # endif /* not HAVE_CONFIG_H */ | |
65 #endif /* WINDOWSNT */ | |
48 | 66 |
49 #ifdef HAVE_CONFIG_H | 67 #ifdef HAVE_CONFIG_H |
50 # include <config.h> | 68 # include <config.h> |
51 /* On some systems, Emacs defines static as nothing for the sake | 69 /* On some systems, Emacs defines static as nothing for the sake |
52 of unexec. We don't want that here since we don't use unexec. */ | 70 of unexec. We don't want that here since we don't use unexec. */ |
53 # undef static | 71 # undef static |
54 # define ETAGS_REGEXPS /* use the regexp features */ | 72 # define ETAGS_REGEXPS /* use the regexp features */ |
55 # define LONG_OPTIONS /* accept long options */ | 73 # define LONG_OPTIONS /* accept long options */ |
56 #endif /* HAVE_CONFIG_H */ | 74 #endif /* HAVE_CONFIG_H */ |
57 | 75 |
58 #ifndef _GNU_SOURCE | 76 #if !defined (WINDOWSNT) && defined (STDC_HEADERS) |
59 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */ | 77 #include <stdlib.h> |
78 #include <string.h> | |
60 #endif | 79 #endif |
61 | |
62 #ifdef WIN32_NATIVE | |
63 # include <stdlib.h> | |
64 # include <fcntl.h> | |
65 # include <string.h> | |
66 # include <direct.h> | |
67 # include <io.h> | |
68 # define MAXPATHLEN _MAX_PATH | |
69 # ifndef HAVE_GETCWD | |
70 # define HAVE_GETCWD | |
71 # endif /* undef HAVE_GETCWD */ | |
72 #else /* !WIN32_NATIVE */ | |
73 # ifdef STDC_HEADERS | |
74 # include <stdlib.h> | |
75 # include <string.h> | |
76 # else | |
77 extern char *getenv (); | |
78 # endif | |
79 #endif /* !WIN32_NATIVE */ | |
80 | 80 |
81 #ifdef HAVE_UNISTD_H | 81 #ifdef HAVE_UNISTD_H |
82 # include <unistd.h> | 82 # include <unistd.h> |
83 #else | 83 #else |
84 # if defined (HAVE_GETCWD) && !defined (WIN32_NATIVE) | 84 # ifdef HAVE_GETCWD |
85 extern char *getcwd (char *buf, size_t size); | 85 extern char *getcwd (); |
86 # endif | 86 # endif |
87 #endif /* HAVE_UNISTD_H */ | 87 #endif /* HAVE_UNISTD_H */ |
88 | 88 |
89 #include <stdio.h> | 89 #include <stdio.h> |
90 #include <ctype.h> | 90 #include <ctype.h> |
169 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) | 169 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) |
170 #endif | 170 #endif |
171 | 171 |
172 typedef int bool; | 172 typedef int bool; |
173 | 173 |
174 typedef void Lang_function P_((FILE *)); | 174 typedef void Lang_function (); |
175 | 175 |
176 typedef struct | 176 typedef struct |
177 { | 177 { |
178 char *suffix; | 178 char *suffix; |
179 int sufflen; | |
179 char *command; /* Takes one arg and decompresses to stdout */ | 180 char *command; /* Takes one arg and decompresses to stdout */ |
180 } compressor; | 181 } compressor; |
181 | 182 |
182 typedef struct | 183 typedef struct |
183 { | 184 { |
184 char *name; | 185 char *name; |
185 Lang_function *function; | 186 Lang_function *function; |
186 char **suffixes; | 187 char **suffixes; |
187 char **interpreters; | 188 char **interpreters; |
188 } language; | 189 } language; |
190 | |
191 extern char *getenv (); | |
192 | |
193 /* Many compilers barf on this: | |
194 Lang_function Asm_labels; | |
195 so let's write it this way */ | |
196 void Asm_labels (); | |
197 void C_entries (); | |
198 void default_C_entries (); | |
199 void plain_C_entries (); | |
200 void Cjava_entries (); | |
201 void Cobol_paragraphs (); | |
202 void Cplusplus_entries (); | |
203 void Cstar_entries (); | |
204 void Erlang_functions (); | |
205 void Fortran_functions (); | |
206 void Yacc_entries (); | |
207 void Lisp_functions (); | |
208 void Pascal_functions (); | |
209 void Perl_functions (); | |
210 void Postscript_functions (); | |
211 void Prolog_functions (); | |
212 void Python_functions (); | |
213 void Scheme_functions (); | |
214 void TeX_functions (); | |
215 void just_read_file (); | |
216 | |
217 compressor *get_compressor_from_suffix (); | |
218 language *get_language_from_name (); | |
219 language *get_language_from_interpreter (); | |
220 language *get_language_from_suffix (); | |
221 int total_size_of_entries (); | |
222 long readline (), readline_internal (); | |
223 #ifdef ETAGS_REGEXPS | |
224 void analyse_regex (); | |
225 void add_regex (); | |
226 void free_patterns (); | |
227 #endif /* ETAGS_REGEXPS */ | |
228 void error (); | |
229 void suggest_asking_for_help (); | |
230 void fatal (), pfatal (); | |
231 void add_node (); | |
232 | |
233 void init (); | |
234 void initbuffer (); | |
235 void find_entries (); | |
236 void free_tree (); | |
237 void pfnote (), new_pfnote (); | |
238 void process_file (); | |
239 void put_entries (); | |
240 void takeprec (); | |
241 | |
242 char *concat (); | |
243 char *skip_spaces (), *skip_non_spaces (); | |
244 char *savenstr (), *savestr (); | |
245 char *etags_strchr (), *etags_strrchr (); | |
246 char *etags_getcwd (); | |
247 char *relative_filename (), *absolute_filename (), *absolute_dirname (); | |
248 bool filename_is_absolute (); | |
249 void canonicalize_filename (); | |
250 void grow_linebuffer (); | |
251 long *xmalloc (), *xrealloc (); | |
252 | |
253 | |
254 char searchar = '/'; /* use /.../ searches */ | |
255 | |
256 char *tagfile; /* output file */ | |
257 char *progname; /* name this program was invoked with */ | |
258 char *cwd; /* current working directory */ | |
259 char *tagfiledir; /* directory of tagfile */ | |
260 FILE *tagf; /* ioptr for tags file */ | |
261 | |
262 char *curfile; /* current input file name */ | |
263 language *curlang; /* current language */ | |
264 | |
265 int lineno; /* line number of current line */ | |
266 long charno; /* current character number */ | |
267 long linecharno; /* charno of start of current line */ | |
268 char *dbp; /* pointer to start of current tag */ | |
189 | 269 |
190 typedef struct node_st | 270 typedef struct node_st |
191 { /* sorting structure */ | 271 { /* sorting structure */ |
192 char *name; /* function or type name */ | 272 char *name; /* function or type name */ |
193 char *file; /* file name */ | 273 char *file; /* file name */ |
197 long cno; /* character number line starts on */ | 277 long cno; /* character number line starts on */ |
198 char *pat; /* search pattern */ | 278 char *pat; /* search pattern */ |
199 struct node_st *left, *right; /* left and right sons */ | 279 struct node_st *left, *right; /* left and right sons */ |
200 } node; | 280 } node; |
201 | 281 |
282 node *head; /* the head of the binary tree of tags */ | |
283 | |
202 /* | 284 /* |
203 * A `linebuffer' is a structure which holds a line of text. | 285 * A `linebuffer' is a structure which holds a line of text. |
204 * `readline_internal' reads a line from a stream into a linebuffer | 286 * `readline_internal' reads a line from a stream into a linebuffer |
205 * and works regardless of the length of the line. | 287 * and works regardless of the length of the line. |
206 * SIZE is the size of BUFFER, LEN is the length of the string in | 288 * SIZE is the size of BUFFER, LEN is the length of the string in |
211 long size; | 293 long size; |
212 int len; | 294 int len; |
213 char *buffer; | 295 char *buffer; |
214 } linebuffer; | 296 } linebuffer; |
215 | 297 |
216 /* Many compilers barf on this: | |
217 Lang_function Ada_funcs; | |
218 so let's write it this way */ | |
219 static void Ada_funcs P_((FILE *)); | |
220 static void Asm_labels P_((FILE *)); | |
221 static void C_entries P_((int c_ext, FILE *)); | |
222 static void default_C_entries P_((FILE *)); | |
223 static void plain_C_entries P_((FILE *)); | |
224 static void Cjava_entries P_((FILE *)); | |
225 static void Cobol_paragraphs P_((FILE *)); | |
226 static void Cplusplus_entries P_((FILE *)); | |
227 static void Cstar_entries P_((FILE *)); | |
228 static void Erlang_functions P_((FILE *)); | |
229 static void Fortran_functions P_((FILE *)); | |
230 static void Yacc_entries P_((FILE *)); | |
231 static void Lisp_functions P_((FILE *)); | |
232 static void Pascal_functions P_((FILE *)); | |
233 static void Perl_functions P_((FILE *)); | |
234 static void Postscript_functions P_((FILE *)); | |
235 static void Prolog_functions P_((FILE *)); | |
236 static void Python_functions P_((FILE *)); | |
237 static void Scheme_functions P_((FILE *)); | |
238 static void TeX_functions P_((FILE *)); | |
239 static void just_read_file P_((FILE *)); | |
240 | |
241 static void print_language_names P_((void)); | |
242 static void print_version P_((void)); | |
243 static void print_help P_((void)); | |
244 int main P_((int, char **)); | |
245 static int number_len P_((long)); | |
246 | |
247 static compressor *get_compressor_from_suffix P_((char *, char **)); | |
248 static language *get_language_from_name P_((char *)); | |
249 static language *get_language_from_interpreter P_((char *)); | |
250 static language *get_language_from_suffix P_((char *)); | |
251 static int total_size_of_entries P_((node *)); | |
252 static long readline P_((linebuffer *, FILE *)); | |
253 static long readline_internal P_((linebuffer *, FILE *)); | |
254 static void get_tag P_((char *)); | |
255 | |
256 #ifdef ETAGS_REGEXPS | |
257 static void analyse_regex P_((char *, bool)); | |
258 static void add_regex P_((char *, bool, language *)); | |
259 static void free_patterns P_((void)); | |
260 #endif /* ETAGS_REGEXPS */ | |
261 static void error P_((const char *, const char *)); | |
262 static void suggest_asking_for_help P_((void)); | |
263 static void fatal P_((char *, char *)); | |
264 static void pfatal P_((char *)); | |
265 static void add_node P_((node *, node **)); | |
266 | |
267 static void init P_((void)); | |
268 static void initbuffer P_((linebuffer *)); | |
269 static void find_entries P_((char *, FILE *)); | |
270 static void free_tree P_((node *)); | |
271 static void pfnote P_((char *, bool, char *, int, int, long)); | |
272 static void new_pfnote P_((char *, int, bool, char *, int, int, long)); | |
273 static void process_file P_((char *)); | |
274 static void put_entries P_((node *)); | |
275 static void takeprec P_((void)); | |
276 | |
277 static char *concat P_((char *, char *, char *)); | |
278 static char *skip_spaces P_((char *)); | |
279 static char *skip_non_spaces P_((char *)); | |
280 static char *savenstr P_((char *, int)); | |
281 static char *savestr P_((char *)); | |
282 static char *etags_strchr P_((const char *, int)); | |
283 static char *etags_strrchr P_((const char *, int)); | |
284 static char *etags_getcwd P_((void)); | |
285 static char *relative_filename P_((char *, char *)); | |
286 static char *absolute_filename P_((char *, char *)); | |
287 static char *absolute_dirname P_((char *, char *)); | |
288 static bool filename_is_absolute P_((char *f)); | |
289 static void canonicalize_filename P_((char *)); | |
290 static void grow_linebuffer P_((linebuffer *, int)); | |
291 static long *xmalloc P_((unsigned int)); | |
292 static long *xrealloc P_((char *, unsigned int)); | |
293 | |
294 | |
295 char searchar = '/'; /* use /.../ searches */ | |
296 | |
297 char *tagfile; /* output file */ | |
298 char *progname; /* name this program was invoked with */ | |
299 char *cwd; /* current working directory */ | |
300 char *tagfiledir; /* directory of tagfile */ | |
301 FILE *tagf; /* ioptr for tags file */ | |
302 | |
303 char *curfile; /* current input file name */ | |
304 language *curlang; /* current language */ | |
305 | |
306 int lineno; /* line number of current line */ | |
307 long charno; /* current character number */ | |
308 long linecharno; /* charno of start of current line */ | |
309 char *dbp; /* pointer to start of current tag */ | |
310 | |
311 node *head; /* the head of the binary tree of tags */ | |
312 | |
313 linebuffer lb; /* the current line */ | 298 linebuffer lb; /* the current line */ |
314 linebuffer token_name; /* used by C_entries as a temporary area */ | 299 linebuffer token_name; /* used by C_entries as a temporary area */ |
315 struct | 300 struct |
316 { | 301 { |
317 long linepos; | 302 long linepos; |
320 | 305 |
321 /* boolean "functions" (see init) */ | 306 /* boolean "functions" (see init) */ |
322 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; | 307 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; |
323 char | 308 char |
324 /* white chars */ | 309 /* white chars */ |
325 *white = " \f\t\n\r\v", | 310 *white = " \f\t\n\r", |
326 /* not in a name */ | 311 /* not in a name */ |
327 *nonam = " \f\t\n\r(=,[;", | 312 *nonam = " \f\t\n\r(=,[;", |
328 /* token ending chars */ | 313 /* token ending chars */ |
329 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?", | 314 *endtk = " \t\n\r\"'#()[]{}=-+%*/&|^~!<>;,.:?", |
330 /* token starting chars */ | 315 /* token starting chars */ |
332 /* valid in-token chars */ | 317 /* valid in-token chars */ |
333 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; | 318 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; |
334 | 319 |
335 bool append_to_tagfile; /* -a: append to tags */ | 320 bool append_to_tagfile; /* -a: append to tags */ |
336 /* The following four default to TRUE for etags, but to FALSE for ctags. */ | 321 /* The following four default to TRUE for etags, but to FALSE for ctags. */ |
337 bool typedefs; /* -t: create tags for C and Ada typedefs */ | 322 bool typedefs; /* -t: create tags for C typedefs */ |
338 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */ | 323 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */ |
339 /* 0 struct/enum/union decls, and C++ */ | 324 /* 0 struct/enum/union decls, and C++ */ |
340 /* member functions. */ | 325 /* member functions. */ |
341 bool constantypedefs; /* -d: create tags for C #define, enum */ | 326 bool constantypedefs; /* -d: create tags for C #define, enum */ |
342 /* constants and variables. */ | 327 /* constants and variables. */ |
343 /* -D: opposite of -d. Default under ctags. */ | 328 /* -D: opposite of -d. Default under ctags. */ |
344 bool declarations; /* --declarations: tag them and extern in C&Co*/ | |
345 bool globals; /* create tags for global variables */ | 329 bool globals; /* create tags for global variables */ |
346 bool members; /* create tags for C member variables */ | 330 bool members; /* create tags for C member variables */ |
347 bool update; /* -u: update tags */ | 331 bool update; /* -u: update tags */ |
348 bool vgrind_style; /* -v: create vgrind style index output */ | 332 bool vgrind_style; /* -v: create vgrind style index output */ |
349 bool no_warnings; /* -w: suppress warnings */ | 333 bool no_warnings; /* -w: suppress warnings */ |
350 bool cxref_style; /* -x: create cxref style output */ | 334 bool cxref_style; /* -x: create cxref style output */ |
351 bool cplusplus; /* .[hc] means C++, not C */ | 335 bool cplusplus; /* .[hc] means C++, not C */ |
352 bool noindentypedefs; /* -I: ignore indentation in C */ | 336 bool noindentypedefs; /* -I: ignore indentation in C */ |
353 bool packages_only; /* --packages-only: in Ada, only tag packages*/ | |
354 | 337 |
355 #ifdef LONG_OPTIONS | 338 #ifdef LONG_OPTIONS |
356 struct option longopts[] = | 339 struct option longopts[] = |
357 { | 340 { |
358 { "packages-only", no_argument, &packages_only, TRUE }, | 341 { "append", no_argument, NULL, 'a' }, |
359 { "append", no_argument, NULL, 'a' }, | 342 { "backward-search", no_argument, NULL, 'B' }, |
360 { "backward-search", no_argument, NULL, 'B' }, | 343 { "c++", no_argument, NULL, 'C' }, |
361 { "c++", no_argument, NULL, 'C' }, | 344 { "cxref", no_argument, NULL, 'x' }, |
362 { "cxref", no_argument, NULL, 'x' }, | 345 { "defines", no_argument, NULL, 'd' }, |
363 { "defines", no_argument, NULL, 'd' }, | 346 { "no-defines", no_argument, NULL, 'D' }, |
364 { "declarations", no_argument, &declarations, TRUE }, | 347 { "globals", no_argument, &globals, TRUE }, |
365 { "no-defines", no_argument, NULL, 'D' }, | 348 { "no-globals", no_argument, &globals, FALSE }, |
366 { "globals", no_argument, &globals, TRUE }, | 349 { "help", no_argument, NULL, 'h' }, |
367 { "no-globals", no_argument, &globals, FALSE }, | 350 { "help", no_argument, NULL, 'H' }, |
368 { "help", no_argument, NULL, 'h' }, | 351 { "ignore-indentation", no_argument, NULL, 'I' }, |
369 { "help", no_argument, NULL, 'H' }, | 352 { "include", required_argument, NULL, 'i' }, |
370 { "ignore-indentation", no_argument, NULL, 'I' }, | 353 { "language", required_argument, NULL, 'l' }, |
371 { "include", required_argument, NULL, 'i' }, | 354 { "members", no_argument, &members, TRUE }, |
372 { "language", required_argument, NULL, 'l' }, | 355 { "no-members", no_argument, &members, FALSE }, |
373 { "members", no_argument, &members, TRUE }, | 356 { "no-warn", no_argument, NULL, 'w' }, |
374 { "no-members", no_argument, &members, FALSE }, | 357 { "output", required_argument, NULL, 'o' }, |
375 { "no-warn", no_argument, NULL, 'w' }, | 358 #ifdef ETAGS_REGEXPS |
376 { "output", required_argument, NULL, 'o' }, | 359 { "regex", required_argument, NULL, 'r' }, |
377 #ifdef ETAGS_REGEXPS | 360 { "no-regex", no_argument, NULL, 'R' }, |
378 { "regex", required_argument, NULL, 'r' }, | 361 #endif /* ETAGS_REGEXPS */ |
379 { "no-regex", no_argument, NULL, 'R' }, | 362 { "typedefs", no_argument, NULL, 't' }, |
380 { "ignore-case-regex", required_argument, NULL, 'c' }, | 363 { "typedefs-and-c++", no_argument, NULL, 'T' }, |
381 #endif /* ETAGS_REGEXPS */ | 364 { "update", no_argument, NULL, 'u' }, |
382 { "typedefs", no_argument, NULL, 't' }, | 365 { "version", no_argument, NULL, 'V' }, |
383 { "typedefs-and-c++", no_argument, NULL, 'T' }, | 366 { "vgrind", no_argument, NULL, 'v' }, |
384 { "update", no_argument, NULL, 'u' }, | 367 { 0 } |
385 { "version", no_argument, NULL, 'V' }, | |
386 { "vgrind", no_argument, NULL, 'v' }, | |
387 { NULL } | |
388 }; | 368 }; |
389 #endif /* LONG_OPTIONS */ | 369 #endif /* LONG_OPTIONS */ |
390 | 370 |
391 #ifdef ETAGS_REGEXPS | 371 #ifdef ETAGS_REGEXPS |
392 /* Structure defining a regular expression. Elements are | 372 /* Structure defining a regular expression. Elements are |
400 struct re_registers regs; | 380 struct re_registers regs; |
401 char *name_pattern; | 381 char *name_pattern; |
402 bool error_signaled; | 382 bool error_signaled; |
403 } pattern; | 383 } pattern; |
404 | 384 |
405 /* List of all regexps. */ | 385 /* Array of all regexps. */ |
406 pattern *p_head = NULL; | 386 pattern *p_head = NULL; |
407 | |
408 /* How many characters in the character set. (From regex.c.) */ | |
409 #define CHAR_SET_SIZE 256 | |
410 /* Translation table for case-insensitive matching. */ | |
411 char lc_trans[CHAR_SET_SIZE]; | |
412 #endif /* ETAGS_REGEXPS */ | 387 #endif /* ETAGS_REGEXPS */ |
413 | 388 |
414 compressor compressors[] = | 389 compressor compressors[] = |
415 { | 390 { |
416 { "z", "gzip -d -c"}, | 391 { "z", 1, "gzip -d -c"}, |
417 { "Z", "gzip -d -c"}, | 392 { "Z", 1, "gzip -d -c"}, |
418 { "gz", "gzip -d -c"}, | 393 { "gz", 2, "gzip -d -c"}, |
419 { "GZ", "gzip -d -c"}, | 394 { "GZ", 2, "gzip -d -c"}, |
420 { "bz2", "bzip2 -d -c" }, | 395 { "bz2", 3, "bzip2 -d -c" }, |
421 { NULL } | 396 { NULL } |
422 }; | 397 }; |
423 | 398 |
424 /* | 399 /* |
425 * Language stuff. | 400 * Language stuff. |
426 */ | 401 */ |
427 | 402 |
428 /* Non-NULL if language fixed. */ | 403 /* Non-NULL if language fixed. */ |
429 language *forced_lang = NULL; | 404 language *forced_lang = NULL; |
430 | |
431 /* Ada code */ | |
432 char *Ada_suffixes [] = | |
433 { "ads", "adb", "ada", NULL }; | |
434 | 405 |
435 /* Assembly code */ | 406 /* Assembly code */ |
436 char *Asm_suffixes [] = { "a", /* Unix assembler */ | 407 char *Asm_suffixes [] = { "a", /* Unix assembler */ |
437 "asm", /* Microcontroller assembly */ | 408 "asm", /* Microcontroller assembly */ |
438 "def", /* BSO/Tasking definition includes */ | 409 "def", /* BSO/Tasking definition includes */ |
486 "m", /* Objective C file */ | 457 "m", /* Objective C file */ |
487 "lm", /* Objective lex file */ | 458 "lm", /* Objective lex file */ |
488 NULL }; | 459 NULL }; |
489 | 460 |
490 char *Postscript_suffixes [] = | 461 char *Postscript_suffixes [] = |
491 { "ps", "psw", NULL }; /* .psw is for PSWrap */ | 462 { "ps", NULL }; |
492 | 463 |
493 char *Prolog_suffixes [] = | 464 char *Prolog_suffixes [] = |
494 { "prolog", NULL }; | 465 { "prolog", NULL }; |
495 | 466 |
496 char *Python_suffixes [] = | 467 char *Python_suffixes [] = |
513 * name. I just didn't. | 484 * name. I just didn't. |
514 */ | 485 */ |
515 | 486 |
516 language lang_names [] = | 487 language lang_names [] = |
517 { | 488 { |
518 { "ada", Ada_funcs, Ada_suffixes, NULL }, | |
519 { "asm", Asm_labels, Asm_suffixes, NULL }, | 489 { "asm", Asm_labels, Asm_suffixes, NULL }, |
520 { "c", default_C_entries, default_C_suffixes, NULL }, | 490 { "c", default_C_entries, default_C_suffixes, NULL }, |
521 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL }, | 491 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL }, |
522 { "c*", Cstar_entries, Cstar_suffixes, NULL }, | 492 { "c*", Cstar_entries, Cstar_suffixes, NULL }, |
523 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL }, | 493 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL }, |
537 { "auto", NULL }, /* default guessing scheme */ | 507 { "auto", NULL }, /* default guessing scheme */ |
538 { "none", just_read_file }, /* regexp matching only */ | 508 { "none", just_read_file }, /* regexp matching only */ |
539 { NULL, NULL } /* end of list */ | 509 { NULL, NULL } /* end of list */ |
540 }; | 510 }; |
541 | 511 |
542 static void | 512 void |
543 print_language_names () | 513 print_language_names () |
544 { | 514 { |
545 language *lang; | 515 language *lang; |
546 char **ext; | 516 char **ext; |
547 | 517 |
562 followed by the name of an interpreter. If no such sequence is found,\n\ | 532 followed by the name of an interpreter. If no such sequence is found,\n\ |
563 Fortran is tried first; if no tags are found, C is tried next.\n\ | 533 Fortran is tried first; if no tags are found, C is tried next.\n\ |
564 Compressed files are supported using gzip and bzip2."); | 534 Compressed files are supported using gzip and bzip2."); |
565 } | 535 } |
566 | 536 |
567 #ifndef EMACS_NAME | 537 #ifndef VERSION |
568 # define EMACS_NAME "GNU Emacs" | 538 # define VERSION "20" |
569 #endif | 539 #endif |
570 #ifndef VERSION | 540 void |
571 # define VERSION "21" | |
572 #endif | |
573 static void | |
574 print_version () | 541 print_version () |
575 { | 542 { |
576 printf ("%s (%s %s)\n", (CTAGS) ? "ctags" : "etags", EMACS_NAME, VERSION); | 543 printf ("%s (GNU Emacs %s)\n", (CTAGS) ? "ctags" : "etags", VERSION); |
577 puts ("Copyright (C) 1999 Free Software Foundation, Inc. and Ken Arnold"); | 544 puts ("Copyright (C) 1996 Free Software Foundation, Inc. and Ken Arnold"); |
578 puts ("This program is distributed under the same terms as Emacs"); | 545 puts ("This program is distributed under the same terms as Emacs"); |
579 | 546 |
580 exit (GOOD); | 547 exit (GOOD); |
581 } | 548 } |
582 | 549 |
583 static void | 550 void |
584 print_help () | 551 print_help () |
585 { | 552 { |
586 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\ | 553 printf ("Usage: %s [options] [[regex-option ...] file-name] ...\n\ |
587 \n\ | 554 \n\ |
588 These are the options accepted by %s.\n", progname, progname); | 555 These are the options accepted by %s.\n", progname, progname); |
599 puts ("\n"); | 566 puts ("\n"); |
600 | 567 |
601 puts ("-a, --append\n\ | 568 puts ("-a, --append\n\ |
602 Append tag entries to existing tags file."); | 569 Append tag entries to existing tags file."); |
603 | 570 |
604 puts ("--packages-only\n\ | |
605 For Ada files, only generate tags for packages ."); | |
606 | |
607 if (CTAGS) | 571 if (CTAGS) |
608 puts ("-B, --backward-search\n\ | 572 puts ("-B, --backward-search\n\ |
609 Write the search commands for the tag entries using '?', the\n\ | 573 Write the search commands for the tag entries using '?', the\n\ |
610 backward-search command instead of '/', the forward-search command."); | 574 backward-search command instead of '/', the forward-search command."); |
611 | 575 |
612 puts ("-C, --c++\n\ | 576 puts ("-C, --c++\n\ |
613 Treat files whose name suffix defaults to C language as C++ files."); | 577 Treat files whose name suffix defaults to C language as C++ files."); |
614 | |
615 puts ("--declarations\n\ | |
616 In C and derived languages, create tags for function declarations,"); | |
617 if (CTAGS) | |
618 puts ("\tand create tags for extern variables if --globals is used."); | |
619 else | |
620 puts | |
621 ("\tand create tags for extern variables unless --no-globals is used."); | |
622 | 578 |
623 if (CTAGS) | 579 if (CTAGS) |
624 puts ("-d, --defines\n\ | 580 puts ("-d, --defines\n\ |
625 Create tag entries for C #define constants and enum constants, too."); | 581 Create tag entries for C #define constants and enum constants, too."); |
626 else | 582 else |
649 puts ("--members\n\ | 605 puts ("--members\n\ |
650 Create tag entries for member variables in C and derived languages."); | 606 Create tag entries for member variables in C and derived languages."); |
651 | 607 |
652 #ifdef ETAGS_REGEXPS | 608 #ifdef ETAGS_REGEXPS |
653 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\ | 609 puts ("-r /REGEXP/, --regex=/REGEXP/ or --regex=@regexfile\n\ |
654 Make a tag for each line matching pattern REGEXP in the following\n\ | 610 Make a tag for each line matching pattern REGEXP in the\n\ |
655 files. {LANGUAGE}/REGEXP/ uses REGEXP for LANGUAGE files only.\n\ | 611 following files. regexfile is a file containing one REGEXP\n\ |
656 regexfile is a file containing one REGEXP per line.\n\ | 612 per line. REGEXP is anchored (as if preceded by ^).\n\ |
657 REGEXP is anchored (as if preceded by ^).\n\ | 613 The form /REGEXP/NAME/ creates a named tag. For example Tcl\n\ |
658 The form /REGEXP/NAME/ creates a named tag.\n\ | 614 named tags can be created with:\n\ |
659 For example Tcl named tags can be created with:\n\ | |
660 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/."); | 615 --regex=/proc[ \\t]+\\([^ \\t]+\\)/\\1/."); |
661 puts ("-c /REGEXP/, --ignore-case-regex=/REGEXP/ or --ignore-case-regex=@regexfile\n\ | |
662 Like -r, --regex but ignore case when matching expressions."); | |
663 puts ("-R, --no-regex\n\ | 616 puts ("-R, --no-regex\n\ |
664 Don't create tags from regexps for the following files."); | 617 Don't create tags from regexps for the following files."); |
665 #endif /* ETAGS_REGEXPS */ | 618 #endif /* ETAGS_REGEXPS */ |
666 puts ("-o FILE, --output=FILE\n\ | 619 puts ("-o FILE, --output=FILE\n\ |
667 Write the tags to FILE."); | 620 Write the tags to FILE."); |
672 definition in C and C++."); | 625 definition in C and C++."); |
673 | 626 |
674 if (CTAGS) | 627 if (CTAGS) |
675 { | 628 { |
676 puts ("-t, --typedefs\n\ | 629 puts ("-t, --typedefs\n\ |
677 Generate tag entries for C and Ada typedefs."); | 630 Generate tag entries for C typedefs."); |
678 puts ("-T, --typedefs-and-c++\n\ | 631 puts ("-T, --typedefs-and-c++\n\ |
679 Generate tag entries for C typedefs, C struct/enum/union tags,\n\ | 632 Generate tag entries for C typedefs, C struct/enum/union tags,\n\ |
680 and C++ member functions."); | 633 and C++ member functions."); |
681 puts ("-u, --update\n\ | 634 puts ("-u, --update\n\ |
682 Update the tag entries for the given files, leaving tag\n\ | 635 Update the tag entries for the given files, leaving tag\n\ |
705 Print this help message."); | 658 Print this help message."); |
706 | 659 |
707 print_language_names (); | 660 print_language_names (); |
708 | 661 |
709 puts (""); | 662 puts (""); |
710 puts ("Report bugs to bug-gnu-emacs@gnu.org"); | 663 puts ("Report bugs to bug-gnu-emacs@prep.ai.mit.edu"); |
711 | 664 |
712 exit (GOOD); | 665 exit (GOOD); |
713 } | 666 } |
714 | 667 |
715 | 668 |
716 enum argument_type | 669 enum argument_type |
717 { | 670 { |
718 at_language, | 671 at_language, |
719 at_regexp, | 672 at_regexp, |
720 at_filename, | 673 at_filename |
721 at_icregexp | |
722 }; | 674 }; |
723 | 675 |
724 /* This structure helps us allow mixing of --lang and file names. */ | 676 /* This structure helps us allow mixing of --lang and file names. */ |
725 typedef struct | 677 typedef struct |
726 { | 678 { |
759 */ | 711 */ |
760 | 712 |
761 #include <rmsdef.h> | 713 #include <rmsdef.h> |
762 #include <descrip.h> | 714 #include <descrip.h> |
763 #define OUTSIZE MAX_FILE_SPEC_LEN | 715 #define OUTSIZE MAX_FILE_SPEC_LEN |
764 static short | 716 short |
765 fn_exp (out, in) | 717 fn_exp (out, in) |
766 vspec *out; | 718 vspec *out; |
767 char *in; | 719 char *in; |
768 { | 720 { |
769 static long context = 0; | 721 static long context = 0; |
804 | 756 |
805 /* | 757 /* |
806 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the | 758 v1.01 nmm 19-Aug-85 gfnames - return in successive calls the |
807 name of each file specified by the provided arg expanding wildcards. | 759 name of each file specified by the provided arg expanding wildcards. |
808 */ | 760 */ |
809 static char * | 761 char * |
810 gfnames (arg, p_error) | 762 gfnames (arg, p_error) |
811 char *arg; | 763 char *arg; |
812 bool *p_error; | 764 bool *p_error; |
813 { | 765 { |
814 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"}; | 766 static vspec filename = {MAX_FILE_SPEC_LEN, "\0"}; |
868 linebuffer filename_lb; | 820 linebuffer filename_lb; |
869 #ifdef VMS | 821 #ifdef VMS |
870 bool got_err; | 822 bool got_err; |
871 #endif | 823 #endif |
872 | 824 |
873 #ifdef WIN32_NATIVE | 825 #ifdef DOS_NT |
874 _fmode = O_BINARY; /* all of files are treated as binary files */ | 826 _fmode = O_BINARY; /* all of files are treated as binary files */ |
875 #endif /* WIN32_NATIVE */ | 827 #endif /* DOS_NT */ |
876 | 828 |
877 progname = argv[0]; | 829 progname = argv[0]; |
878 nincluded_files = 0; | 830 nincluded_files = 0; |
879 included_files = xnew (argc, char *); | 831 included_files = xnew (argc, char *); |
880 current_arg = 0; | 832 current_arg = 0; |
885 argbuffer = xnew (argc, argument); | 837 argbuffer = xnew (argc, argument); |
886 | 838 |
887 #ifdef ETAGS_REGEXPS | 839 #ifdef ETAGS_REGEXPS |
888 /* Set syntax for regular expression routines. */ | 840 /* Set syntax for regular expression routines. */ |
889 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS); | 841 re_set_syntax (RE_SYNTAX_EMACS | RE_INTERVALS); |
890 /* Translation table for case-insensitive search. */ | |
891 for (i = 0; i < CHAR_SET_SIZE; i++) | |
892 lc_trans[i] = lowcase (i); | |
893 #endif /* ETAGS_REGEXPS */ | 842 #endif /* ETAGS_REGEXPS */ |
894 | 843 |
895 /* | 844 /* |
896 * If etags, always find typedefs and structure tags. Why not? | 845 * If etags, always find typedefs and structure tags. Why not? |
897 * Also default is to find macro constants, enum constants and | 846 * Also default is to find macro constants, enum constants and |
898 * global variables. | 847 * global variables. |
899 */ | 848 */ |
900 if (!CTAGS) | 849 if (!CTAGS) |
901 { | 850 { |
902 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; | 851 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; |
903 globals = TRUE; | 852 globals = TRUE; |
908 { | 857 { |
909 int opt; | 858 int opt; |
910 char *optstring; | 859 char *optstring; |
911 | 860 |
912 #ifdef ETAGS_REGEXPS | 861 #ifdef ETAGS_REGEXPS |
913 optstring = "-aCdDf:Il:o:r:c:RStTi:BuvxwVhH"; | 862 optstring = "-aCdDf:Il:o:r:RStTi:BuvxwVhH"; |
914 #else | 863 #else |
915 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH"; | 864 optstring = "-aCdDf:Il:o:StTi:BuvxwVhH"; |
916 #endif /* ETAGS_REGEXPS */ | 865 #endif /* ETAGS_REGEXPS */ |
917 | 866 |
918 #ifndef LONG_OPTIONS | 867 #ifndef LONG_OPTIONS |
945 case 'D': constantypedefs = FALSE; break; | 894 case 'D': constantypedefs = FALSE; break; |
946 case 'f': /* for compatibility with old makefiles */ | 895 case 'f': /* for compatibility with old makefiles */ |
947 case 'o': | 896 case 'o': |
948 if (tagfile) | 897 if (tagfile) |
949 { | 898 { |
950 error ("-o option may only be given once.", (char *)NULL); | 899 error ("-%c option may only be given once.", opt); |
951 suggest_asking_for_help (); | 900 suggest_asking_for_help (); |
952 } | 901 } |
953 tagfile = optarg; | 902 tagfile = optarg; |
954 break; | 903 break; |
955 case 'I': | 904 case 'I': |
974 ++current_arg; | 923 ++current_arg; |
975 break; | 924 break; |
976 case 'R': | 925 case 'R': |
977 argbuffer[current_arg].arg_type = at_regexp; | 926 argbuffer[current_arg].arg_type = at_regexp; |
978 argbuffer[current_arg].what = NULL; | 927 argbuffer[current_arg].what = NULL; |
979 ++current_arg; | |
980 break; | |
981 case 'c': | |
982 argbuffer[current_arg].arg_type = at_icregexp; | |
983 argbuffer[current_arg].what = optarg; | |
984 ++current_arg; | 928 ++current_arg; |
985 break; | 929 break; |
986 #endif /* ETAGS_REGEXPS */ | 930 #endif /* ETAGS_REGEXPS */ |
987 case 'V': | 931 case 'V': |
988 print_version (); | 932 print_version (); |
1023 ++file_count; | 967 ++file_count; |
1024 } | 968 } |
1025 | 969 |
1026 if (nincluded_files == 0 && file_count == 0) | 970 if (nincluded_files == 0 && file_count == 0) |
1027 { | 971 { |
1028 error ("no input files specified.", (char *)NULL); | 972 error ("no input files specified.", 0); |
1029 suggest_asking_for_help (); | 973 suggest_asking_for_help (); |
1030 } | 974 } |
1031 | 975 |
1032 if (tagfile == NULL) | 976 if (tagfile == NULL) |
1033 tagfile = CTAGS ? "tags" : "TAGS"; | 977 tagfile = CTAGS ? "tags" : "TAGS"; |
1054 if (!CTAGS) | 998 if (!CTAGS) |
1055 { | 999 { |
1056 if (streq (tagfile, "-")) | 1000 if (streq (tagfile, "-")) |
1057 { | 1001 { |
1058 tagf = stdout; | 1002 tagf = stdout; |
1059 #ifdef WIN32_NATIVE | 1003 #ifdef DOS_NT |
1060 /* Switch redirected `stdout' to binary mode (setting `_fmode' | 1004 /* Switch redirected `stdout' to binary mode (setting `_fmode' |
1061 doesn't take effect until after `stdout' is already open). */ | 1005 doesn't take effect until after `stdout' is already open). */ |
1062 if (!isatty (fileno (stdout))) | 1006 if (!isatty (fileno (stdout))) |
1063 setmode (fileno (stdout), O_BINARY); | 1007 setmode (fileno (stdout), O_BINARY); |
1064 #endif /* WIN32_NATIVE */ | 1008 #endif /* DOS_NT */ |
1065 } | 1009 } |
1066 else | 1010 else |
1067 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); | 1011 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); |
1068 if (tagf == NULL) | 1012 if (tagf == NULL) |
1069 pfatal (tagfile); | 1013 pfatal (tagfile); |
1079 case at_language: | 1023 case at_language: |
1080 forced_lang = argbuffer[i].lang; | 1024 forced_lang = argbuffer[i].lang; |
1081 break; | 1025 break; |
1082 #ifdef ETAGS_REGEXPS | 1026 #ifdef ETAGS_REGEXPS |
1083 case at_regexp: | 1027 case at_regexp: |
1084 analyse_regex (argbuffer[i].what, FALSE); | 1028 analyse_regex (argbuffer[i].what); |
1085 break; | |
1086 case at_icregexp: | |
1087 analyse_regex (argbuffer[i].what, TRUE); | |
1088 break; | 1029 break; |
1089 #endif | 1030 #endif |
1090 case at_filename: | 1031 case at_filename: |
1091 #ifdef VMS | 1032 #ifdef VMS |
1092 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL) | 1033 while ((this_file = gfnames (argbuffer[i].what, &got_err)) != NULL) |
1174 } | 1115 } |
1175 | 1116 |
1176 | 1117 |
1177 | 1118 |
1178 /* | 1119 /* |
1179 * Return a compressor given the file name. If EXTPTR is non-zero, | 1120 * Return a compressor given the file name. |
1180 * return a pointer into FILE where the compressor-specific | |
1181 * extension begins. If no compressor is found, NULL is returned | |
1182 * and EXTPTR is not significant. | |
1183 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> | 1121 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> |
1184 */ | 1122 */ |
1185 static compressor * | 1123 compressor * |
1186 get_compressor_from_suffix (file, extptr) | 1124 get_compressor_from_suffix (file) |
1187 char *file; | 1125 char *file; |
1188 char **extptr; | |
1189 { | 1126 { |
1190 compressor *compr; | 1127 compressor *compr; |
1191 char *slash, *suffix; | 1128 char *suffix; |
1192 | 1129 |
1193 /* This relies on FN to be after canonicalize_filename, | |
1194 so we don't need to consider backslashes on WIN32_NATIVE. */ | |
1195 slash = etags_strrchr (file, '/'); | |
1196 suffix = etags_strrchr (file, '.'); | 1130 suffix = etags_strrchr (file, '.'); |
1197 if (suffix == NULL || suffix < slash) | 1131 if (suffix == NULL) |
1198 return NULL; | 1132 return NULL; |
1199 if (extptr != NULL) | |
1200 *extptr = suffix; | |
1201 suffix += 1; | 1133 suffix += 1; |
1202 /* Let those poor souls who live with DOS 8+3 file name limits get | 1134 for (compr = compressors; compr->suffix != NULL; compr++) |
1203 some solace by treating foo.cgz as if it were foo.c.gz, etc. | 1135 if (streq (compr->suffix, suffix)) |
1204 */ | 1136 return compr; |
1205 do | |
1206 { | |
1207 for (compr = compressors; compr->suffix != NULL; compr++) | |
1208 if (streq (compr->suffix, suffix)) | |
1209 return compr; | |
1210 if (1) /* !MSDOS */ | |
1211 break; /* do it only once: not really a loop */ | |
1212 if (extptr != NULL) | |
1213 *extptr = ++suffix; | |
1214 } while (*suffix != '\0'); | |
1215 return NULL; | 1137 return NULL; |
1216 } | 1138 } |
1217 | 1139 |
1218 | 1140 |
1219 | 1141 |
1220 /* | 1142 /* |
1221 * Return a language given the name. | 1143 * Return a language given the name. |
1222 */ | 1144 */ |
1223 static language * | 1145 language * |
1224 get_language_from_name (name) | 1146 get_language_from_name (name) |
1225 char *name; | 1147 char *name; |
1226 { | 1148 { |
1227 language *lang; | 1149 language *lang; |
1228 | 1150 |
1241 | 1163 |
1242 | 1164 |
1243 /* | 1165 /* |
1244 * Return a language given the interpreter name. | 1166 * Return a language given the interpreter name. |
1245 */ | 1167 */ |
1246 static language * | 1168 language * |
1247 get_language_from_interpreter (interpreter) | 1169 get_language_from_interpreter (interpreter) |
1248 char *interpreter; | 1170 char *interpreter; |
1249 { | 1171 { |
1250 language *lang; | 1172 language *lang; |
1251 char **iname; | 1173 char **iname; |
1264 | 1186 |
1265 | 1187 |
1266 /* | 1188 /* |
1267 * Return a language given the file name. | 1189 * Return a language given the file name. |
1268 */ | 1190 */ |
1269 static language * | 1191 language * |
1270 get_language_from_suffix (file) | 1192 get_language_from_suffix (file) |
1271 char *file; | 1193 char *file; |
1272 { | 1194 { |
1273 language *lang; | 1195 language *lang; |
1274 char **ext, *suffix; | 1196 char **ext, *suffix; |
1288 | 1210 |
1289 | 1211 |
1290 /* | 1212 /* |
1291 * This routine is called on each file argument. | 1213 * This routine is called on each file argument. |
1292 */ | 1214 */ |
1293 static void | 1215 void |
1294 process_file (file) | 1216 process_file (file) |
1295 char *file; | 1217 char *file; |
1296 { | 1218 { |
1297 struct stat stat_buf; | 1219 struct stat stat_buf; |
1298 FILE *inf; | 1220 FILE *inf; |
1299 compressor *compr; | 1221 compressor *compr; |
1300 char *compressed_name, *uncompressed_name; | 1222 char *compressed_name, *uncompressed_name; |
1301 char *ext, *real_name; | 1223 char *real_name; |
1302 | |
1303 | 1224 |
1304 canonicalize_filename (file); | 1225 canonicalize_filename (file); |
1305 if (streq (file, tagfile) && !streq (tagfile, "-")) | 1226 if (streq (file, tagfile) && !streq (tagfile, "-")) |
1306 { | 1227 { |
1307 error ("skipping inclusion of %s in self.", file); | 1228 error ("skipping inclusion of %s in self.", file); |
1308 return; | 1229 return; |
1309 } | 1230 } |
1310 if ((compr = get_compressor_from_suffix (file, &ext)) == NULL) | 1231 if ((compr = get_compressor_from_suffix (file)) == NULL) |
1311 { | 1232 { |
1312 compressed_name = NULL; | 1233 compressed_name = NULL; |
1313 real_name = uncompressed_name = savestr (file); | 1234 real_name = uncompressed_name = savestr (file); |
1314 } | 1235 } |
1315 else | 1236 else |
1316 { | 1237 { |
1317 real_name = compressed_name = savestr (file); | 1238 real_name = compressed_name = savestr (file); |
1318 uncompressed_name = savenstr (file, ext - file); | 1239 uncompressed_name = savenstr (file, strlen(file) - compr->sufflen - 1); |
1319 } | 1240 } |
1320 | |
1321 /* If the canonicalised uncompressed name has already be dealt with, | |
1322 skip it silently, else add it to the list. */ | |
1323 { | |
1324 typedef struct processed_file | |
1325 { | |
1326 char *filename; | |
1327 struct processed_file *next; | |
1328 } processed_file; | |
1329 static processed_file *pf_head = NULL; | |
1330 register processed_file *fnp; | |
1331 | |
1332 for (fnp = pf_head; fnp != NULL; fnp = fnp->next) | |
1333 if (streq (uncompressed_name, fnp->filename)) | |
1334 goto exit; | |
1335 fnp = pf_head; | |
1336 pf_head = xnew (1, struct processed_file); | |
1337 pf_head->filename = savestr (uncompressed_name); | |
1338 pf_head->next = fnp; | |
1339 } | |
1340 | |
1341 if (stat (real_name, &stat_buf) != 0) | 1241 if (stat (real_name, &stat_buf) != 0) |
1342 { | 1242 { |
1343 /* Reset real_name and try with a different name. */ | 1243 /* Reset real_name and try with a different name. */ |
1344 real_name = NULL; | 1244 real_name = NULL; |
1345 if (compressed_name != NULL) /* try with the given suffix */ | 1245 if (compressed_name != NULL) /* try with the given suffix */ |
1351 { | 1251 { |
1352 for (compr = compressors; compr->suffix != NULL; compr++) | 1252 for (compr = compressors; compr->suffix != NULL; compr++) |
1353 { | 1253 { |
1354 compressed_name = concat (file, ".", compr->suffix); | 1254 compressed_name = concat (file, ".", compr->suffix); |
1355 if (stat (compressed_name, &stat_buf) != 0) | 1255 if (stat (compressed_name, &stat_buf) != 0) |
1356 { | 1256 free (compressed_name); |
1357 /* XEmacs: delete MSDOS code */ | |
1358 free (compressed_name); | |
1359 compressed_name = NULL; | |
1360 } | |
1361 else | 1257 else |
1362 { | 1258 { |
1363 real_name = compressed_name; | 1259 real_name = compressed_name; |
1364 break; | 1260 break; |
1365 } | 1261 } |
1381 { | 1277 { |
1382 char *cmd = concat (compr->command, " ", real_name); | 1278 char *cmd = concat (compr->command, " ", real_name); |
1383 inf = popen (cmd, "r"); | 1279 inf = popen (cmd, "r"); |
1384 free (cmd); | 1280 free (cmd); |
1385 } | 1281 } |
1386 else | 1282 else |
1387 inf = fopen (real_name, "r"); | 1283 inf = fopen (real_name, "r"); |
1388 if (inf == NULL) | 1284 if (inf == NULL) |
1389 { | 1285 { |
1390 perror (real_name); | 1286 perror (real_name); |
1391 goto exit; | 1287 goto exit; |
1432 * Every char which is NOT in that string is not a white char. Therefore, | 1328 * Every char which is NOT in that string is not a white char. Therefore, |
1433 * all of the array "_wht" is set to FALSE, and then the elements | 1329 * all of the array "_wht" is set to FALSE, and then the elements |
1434 * subscripted by the chars in "white" are set to TRUE. Thus "_wht" | 1330 * subscripted by the chars in "white" are set to TRUE. Thus "_wht" |
1435 * of a char is TRUE if it is the string "white", else FALSE. | 1331 * of a char is TRUE if it is the string "white", else FALSE. |
1436 */ | 1332 */ |
1437 static void | 1333 void |
1438 init () | 1334 init () |
1439 { | 1335 { |
1440 register char *sp; | 1336 register char *sp; |
1441 register int i; | 1337 register int i; |
1442 | 1338 |
1443 for (i = 0; i < CHARS; i++) | 1339 for (i = 0; i < CHARS; i++) |
1444 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE; | 1340 iswhite(i) = notinname(i) = begtoken(i) = intoken(i) = endtoken(i) = FALSE; |
1445 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE; | 1341 for (sp = white; *sp != '\0'; sp++) iswhite (*sp) = TRUE; |
1446 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE; | 1342 for (sp = nonam; *sp != '\0'; sp++) notinname (*sp) = TRUE; |
1343 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE; | |
1344 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE; | |
1345 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE; | |
1346 iswhite('\0') = iswhite('\n'); | |
1447 notinname('\0') = notinname('\n'); | 1347 notinname('\0') = notinname('\n'); |
1448 for (sp = begtk; *sp != '\0'; sp++) begtoken (*sp) = TRUE; | |
1449 begtoken('\0') = begtoken('\n'); | 1348 begtoken('\0') = begtoken('\n'); |
1450 for (sp = midtk; *sp != '\0'; sp++) intoken (*sp) = TRUE; | |
1451 intoken('\0') = intoken('\n'); | 1349 intoken('\0') = intoken('\n'); |
1452 for (sp = endtk; *sp != '\0'; sp++) endtoken (*sp) = TRUE; | |
1453 endtoken('\0') = endtoken('\n'); | 1350 endtoken('\0') = endtoken('\n'); |
1454 } | 1351 } |
1455 | 1352 |
1456 /* | 1353 /* |
1457 * This routine opens the specified file and calls the function | 1354 * This routine opens the specified file and calls the function |
1458 * which finds the function and type definitions. | 1355 * which finds the function and type definitions. |
1459 */ | 1356 */ |
1460 node *last_node = NULL; | 1357 node *last_node = NULL; |
1461 | 1358 |
1462 static void | 1359 void |
1463 find_entries (file, inf) | 1360 find_entries (file, inf) |
1464 char *file; | 1361 char *file; |
1465 FILE *inf; | 1362 FILE *inf; |
1466 { | 1363 { |
1467 char *cp; | 1364 char *cp; |
1544 } | 1441 } |
1545 return; | 1442 return; |
1546 } | 1443 } |
1547 | 1444 |
1548 /* Record a tag. */ | 1445 /* Record a tag. */ |
1549 static void | 1446 void |
1550 pfnote (name, is_func, linestart, linelen, lno, cno) | 1447 pfnote (name, is_func, linestart, linelen, lno, cno) |
1551 char *name; /* tag name, or NULL if unnamed */ | 1448 char *name; /* tag name, or NULL if unnamed */ |
1552 bool is_func; /* tag is a function */ | 1449 bool is_func; /* tag is a function */ |
1553 char *linestart; /* start of the line where tag is */ | 1450 char *linestart; /* start of the line where tag is */ |
1554 int linelen; /* length of the line where tag is */ | 1451 int linelen; /* length of the line where tag is */ |
1614 * The real implementation uses the notinname() macro, which recognises | 1511 * The real implementation uses the notinname() macro, which recognises |
1615 * characters slightly different form " \t\r\n(),;". See the variable | 1512 * characters slightly different form " \t\r\n(),;". See the variable |
1616 * `nonam'. | 1513 * `nonam'. |
1617 */ | 1514 */ |
1618 #define traditional_tag_style TRUE | 1515 #define traditional_tag_style TRUE |
1619 static void | 1516 void |
1620 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno) | 1517 new_pfnote (name, namelen, is_func, linestart, linelen, lno, cno) |
1621 char *name; /* tag name, or NULL if unnamed */ | 1518 char *name; /* tag name, or NULL if unnamed */ |
1622 int namelen; /* tag length */ | 1519 int namelen; /* tag length */ |
1623 bool is_func; /* tag is a function */ | 1520 bool is_func; /* tag is a function */ |
1624 char *linestart; /* start of the line where tag is */ | 1521 char *linestart; /* start of the line where tag is */ |
1644 || notinname (cp[-1])) /* rule #3 */ | 1541 || notinname (cp[-1])) /* rule #3 */ |
1645 && strneq (name, cp, namelen)) /* rule #2 */ | 1542 && strneq (name, cp, namelen)) /* rule #2 */ |
1646 named = FALSE; /* use unnamed tag */ | 1543 named = FALSE; /* use unnamed tag */ |
1647 } | 1544 } |
1648 } | 1545 } |
1649 | 1546 |
1650 if (named) | 1547 if (named) |
1651 name = savenstr (name, namelen); | 1548 name = savenstr (name, namelen); |
1652 else | 1549 else |
1653 name = NULL; | 1550 name = NULL; |
1654 pfnote (name, is_func, linestart, linelen, lno, cno); | 1551 pfnote (name, is_func, linestart, linelen, lno, cno); |
1656 | 1553 |
1657 /* | 1554 /* |
1658 * free_tree () | 1555 * free_tree () |
1659 * recurse on left children, iterate on right children. | 1556 * recurse on left children, iterate on right children. |
1660 */ | 1557 */ |
1661 static void | 1558 void |
1662 free_tree (np) | 1559 free_tree (np) |
1663 register node *np; | 1560 register node *np; |
1664 { | 1561 { |
1665 while (np) | 1562 while (np) |
1666 { | 1563 { |
1681 * an ordered tree, with no attempt at balancing. | 1578 * an ordered tree, with no attempt at balancing. |
1682 * | 1579 * |
1683 * add_node is the only function allowed to add nodes, so it can | 1580 * add_node is the only function allowed to add nodes, so it can |
1684 * maintain state. | 1581 * maintain state. |
1685 */ | 1582 */ |
1686 static void | 1583 void |
1687 add_node (np, cur_node_p) | 1584 add_node (np, cur_node_p) |
1688 node *np, **cur_node_p; | 1585 node *np, **cur_node_p; |
1689 { | 1586 { |
1690 register int dif; | 1587 register int dif; |
1691 register node *cur_node = *cur_node_p; | 1588 register node *cur_node = *cur_node_p; |
1739 /* Actually add the node */ | 1636 /* Actually add the node */ |
1740 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right); | 1637 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right); |
1741 } | 1638 } |
1742 } | 1639 } |
1743 | 1640 |
1744 static void | 1641 void |
1745 put_entries (np) | 1642 put_entries (np) |
1746 register node *np; | 1643 register node *np; |
1747 { | 1644 { |
1748 register char *sp; | 1645 register char *sp; |
1749 | 1646 |
1806 /* Output subentries that follow this one */ | 1703 /* Output subentries that follow this one */ |
1807 put_entries (np->right); | 1704 put_entries (np->right); |
1808 } | 1705 } |
1809 | 1706 |
1810 /* Length of a number's decimal representation. */ | 1707 /* Length of a number's decimal representation. */ |
1811 static int | 1708 int |
1812 number_len (num) | 1709 number_len (num) |
1813 long num; | 1710 long num; |
1814 { | 1711 { |
1815 int len = 1; | 1712 int len = 1; |
1816 while ((num /= 10) > 0) | 1713 while ((num /= 10) > 0) |
1823 * the nodes in the subtree of the specified node. Works only if | 1720 * the nodes in the subtree of the specified node. Works only if |
1824 * we are not ctags, but called only in that case. This count | 1721 * we are not ctags, but called only in that case. This count |
1825 * is irrelevant with the new tags.el, but is still supplied for | 1722 * is irrelevant with the new tags.el, but is still supplied for |
1826 * backward compatibility. | 1723 * backward compatibility. |
1827 */ | 1724 */ |
1828 static int | 1725 int |
1829 total_size_of_entries (np) | 1726 total_size_of_entries (np) |
1830 register node *np; | 1727 register node *np; |
1831 { | 1728 { |
1832 register int total; | 1729 register int total; |
1833 | 1730 |
1858 st_C_objprot, st_C_objimpl, st_C_objend, | 1755 st_C_objprot, st_C_objimpl, st_C_objend, |
1859 st_C_gnumacro, | 1756 st_C_gnumacro, |
1860 st_C_ignore, | 1757 st_C_ignore, |
1861 st_C_javastruct, | 1758 st_C_javastruct, |
1862 st_C_operator, | 1759 st_C_operator, |
1863 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec | 1760 st_C_struct, st_C_enum, st_C_define, st_C_typedef, st_C_typespec |
1864 }; | 1761 }; |
1865 | |
1866 static unsigned int hash P_((const char *, unsigned int)); | |
1867 static struct C_stab_entry * in_word_set P_((const char *, unsigned int)); | |
1868 static enum sym_type C_symtype P_((char *, int, int)); | |
1869 | 1762 |
1870 /* Feed stuff between (but not including) %[ and %] lines to: | 1763 /* Feed stuff between (but not including) %[ and %] lines to: |
1871 gperf -c -k 1,3 -o -p -r -t | 1764 gperf -c -k 1,3 -o -p -r -t |
1872 %[ | 1765 %[ |
1873 struct C_stab_entry { char *name; int c_ext; enum sym_type type; } | 1766 struct C_stab_entry { char *name; int c_ext; enum sym_type type; } |
1874 %% | 1767 %% |
1875 if, 0, st_C_ignore | |
1876 for, 0, st_C_ignore | |
1877 while, 0, st_C_ignore | |
1878 switch, 0, st_C_ignore | |
1879 return, 0, st_C_ignore | |
1880 @interface, 0, st_C_objprot | 1768 @interface, 0, st_C_objprot |
1881 @protocol, 0, st_C_objprot | 1769 @protocol, 0, st_C_objprot |
1882 @implementation,0, st_C_objimpl | 1770 @implementation,0, st_C_objimpl |
1883 @end, 0, st_C_objend | 1771 @end, 0, st_C_objend |
1884 import, C_JAVA, st_C_ignore | 1772 import, C_JAVA, st_C_ignore |
1890 class, C_PLPL, st_C_struct | 1778 class, C_PLPL, st_C_struct |
1891 namespace, C_PLPL, st_C_struct | 1779 namespace, C_PLPL, st_C_struct |
1892 domain, C_STAR, st_C_struct | 1780 domain, C_STAR, st_C_struct |
1893 union, 0, st_C_struct | 1781 union, 0, st_C_struct |
1894 struct, 0, st_C_struct | 1782 struct, 0, st_C_struct |
1895 extern, 0, st_C_extern | |
1896 enum, 0, st_C_enum | 1783 enum, 0, st_C_enum |
1897 typedef, 0, st_C_typedef | 1784 typedef, 0, st_C_typedef |
1898 define, 0, st_C_define | 1785 define, 0, st_C_define |
1899 operator, C_PLPL, st_C_operator | 1786 operator, C_PLPL, st_C_operator |
1900 bool, C_PLPL, st_C_typespec | 1787 bool, C_PLPL, st_C_typespec |
1906 double, 0, st_C_typespec | 1793 double, 0, st_C_typespec |
1907 signed, 0, st_C_typespec | 1794 signed, 0, st_C_typespec |
1908 unsigned, 0, st_C_typespec | 1795 unsigned, 0, st_C_typespec |
1909 auto, 0, st_C_typespec | 1796 auto, 0, st_C_typespec |
1910 void, 0, st_C_typespec | 1797 void, 0, st_C_typespec |
1798 extern, 0, st_C_typespec | |
1911 static, 0, st_C_typespec | 1799 static, 0, st_C_typespec |
1912 const, 0, st_C_typespec | 1800 const, 0, st_C_typespec |
1913 volatile, 0, st_C_typespec | 1801 volatile, 0, st_C_typespec |
1914 explicit, C_PLPL, st_C_typespec | 1802 explicit, C_PLPL, st_C_typespec |
1915 mutable, C_PLPL, st_C_typespec | 1803 mutable, C_PLPL, st_C_typespec |
1924 #EXFUN, 0, st_C_gnumacro | 1812 #EXFUN, 0, st_C_gnumacro |
1925 #DEFVAR_, 0, st_C_gnumacro | 1813 #DEFVAR_, 0, st_C_gnumacro |
1926 %] | 1814 %] |
1927 and replace lines between %< and %> with its output. */ | 1815 and replace lines between %< and %> with its output. */ |
1928 /*%<*/ | 1816 /*%<*/ |
1929 /* C code produced by gperf version 2.7.1 (19981006 egcs) */ | 1817 /* C code produced by gperf version 2.5 (GNU C++ version) */ |
1930 /* Command-line: gperf -c -k 1,3 -o -p -r -t */ | 1818 /* Command-line: gperf -c -k 1,3 -o -p -r -t */ |
1931 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }; | 1819 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }; |
1932 | 1820 |
1933 #define TOTAL_KEYWORDS 46 | 1821 #define TOTAL_KEYWORDS 41 |
1934 #define MIN_WORD_LENGTH 2 | 1822 #define MIN_WORD_LENGTH 3 |
1935 #define MAX_WORD_LENGTH 15 | 1823 #define MAX_WORD_LENGTH 15 |
1936 #define MIN_HASH_VALUE 13 | 1824 #define MIN_HASH_VALUE 20 |
1937 #define MAX_HASH_VALUE 123 | 1825 #define MAX_HASH_VALUE 136 |
1938 /* maximum key range = 111, duplicates = 0 */ | 1826 /* maximum key range = 117, duplicates = 0 */ |
1939 | 1827 |
1940 #ifdef __GNUC__ | |
1941 __inline | |
1942 #endif | |
1943 static unsigned int | 1828 static unsigned int |
1944 hash (str, len) | 1829 hash (str, len) |
1945 register const char *str; | 1830 register char *str; |
1831 register int unsigned len; | |
1832 { | |
1833 static unsigned char asso_values[] = | |
1834 { | |
1835 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1836 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1837 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1838 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1839 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1840 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1841 137, 137, 137, 137, 58, 137, 137, 137, 38, 37, | |
1842 45, 137, 137, 137, 137, 137, 137, 137, 137, 137, | |
1843 62, 137, 137, 14, 16, 137, 137, 137, 137, 137, | |
1844 137, 137, 137, 137, 137, 137, 137, 26, 16, 51, | |
1845 18, 61, 5, 19, 137, 23, 137, 137, 32, 63, | |
1846 54, 10, 26, 137, 24, 42, 30, 18, 46, 137, | |
1847 137, 137, 137, 137, 137, 137, 137, 137, | |
1848 }; | |
1849 return len + asso_values[str[2]] + asso_values[str[0]]; | |
1850 } | |
1851 | |
1852 struct C_stab_entry * | |
1853 in_word_set (str, len) | |
1854 register char *str; | |
1946 register unsigned int len; | 1855 register unsigned int len; |
1947 { | 1856 { |
1948 static unsigned char asso_values[] = | |
1949 { | |
1950 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1951 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1952 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1953 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1954 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1955 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1956 124, 124, 124, 124, 3, 124, 124, 124, 43, 6, | |
1957 11, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1958 11, 124, 124, 58, 7, 124, 124, 124, 124, 124, | |
1959 124, 124, 124, 124, 124, 124, 124, 57, 7, 42, | |
1960 4, 14, 52, 0, 124, 53, 124, 124, 29, 11, | |
1961 6, 35, 32, 124, 29, 34, 59, 58, 51, 24, | |
1962 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1963 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1964 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1965 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1966 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1967 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1968 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1969 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1970 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1971 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1972 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1973 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1974 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, | |
1975 124, 124, 124, 124, 124, 124 | |
1976 }; | |
1977 register int hval = len; | |
1978 | |
1979 switch (hval) | |
1980 { | |
1981 default: | |
1982 case 3: | |
1983 hval += asso_values[(unsigned char)str[2]]; | |
1984 case 2: | |
1985 case 1: | |
1986 hval += asso_values[(unsigned char)str[0]]; | |
1987 break; | |
1988 } | |
1989 return hval; | |
1990 } | |
1991 | |
1992 #ifdef __GNUC__ | |
1993 __inline | |
1994 #endif | |
1995 static struct C_stab_entry * | |
1996 in_word_set (str, len) | |
1997 register const char *str; | |
1998 register unsigned int len; | |
1999 { | |
2000 static struct C_stab_entry wordlist[] = | 1857 static struct C_stab_entry wordlist[] = |
2001 { | 1858 { |
2002 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, | 1859 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2003 {""}, {""}, {""}, {""}, | 1860 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2004 {"@end", 0, st_C_objend}, | 1861 {"",}, {"",}, |
2005 {""}, {""}, {""}, {""}, | 1862 {"float", 0, st_C_typespec}, |
2006 {"ENTRY", 0, st_C_gnumacro}, | 1863 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2007 {"@interface", 0, st_C_objprot}, | 1864 {"define", 0, st_C_define}, |
2008 {""}, | 1865 {"bool", C_PLPL, st_C_typespec}, |
2009 {"domain", C_STAR, st_C_struct}, | 1866 {"",}, {"",}, {"",}, |
2010 {""}, | 1867 {"friend", C_PLPL, st_C_ignore}, |
2011 {"PSEUDO", 0, st_C_gnumacro}, | 1868 {"SYSCALL", 0, st_C_gnumacro}, |
2012 {""}, {""}, | 1869 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2013 {"namespace", C_PLPL, st_C_struct}, | 1870 {"double", 0, st_C_typespec}, |
2014 {""}, {""}, | 1871 {"",}, {"",}, {"",}, |
2015 {"@implementation",0, st_C_objimpl}, | 1872 {"union", 0, st_C_struct}, |
2016 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, | 1873 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2017 {"long", 0, st_C_typespec}, | 1874 {"import", C_JAVA, st_C_ignore}, |
2018 {"signed", 0, st_C_typespec}, | 1875 {"int", 0, st_C_typespec}, |
2019 {"@protocol", 0, st_C_objprot}, | 1876 {"short", 0, st_C_typespec}, |
2020 {""}, {""}, {""}, {""}, | 1877 {"ENTRY", 0, st_C_gnumacro}, |
2021 {"bool", C_PLPL, st_C_typespec}, | 1878 {"implements", C_JAVA, st_C_javastruct}, |
2022 {""}, {""}, {""}, {""}, {""}, {""}, | 1879 {"auto", 0, st_C_typespec}, |
2023 {"const", 0, st_C_typespec}, | 1880 {"",}, |
2024 {"explicit", C_PLPL, st_C_typespec}, | 1881 {"interface", C_JAVA, st_C_struct}, |
2025 {"if", 0, st_C_ignore}, | 1882 {"typedef", 0, st_C_typedef}, |
2026 {""}, | 1883 {"typename", C_PLPL, st_C_typespec}, |
2027 {"operator", C_PLPL, st_C_operator}, | 1884 {"",}, {"",}, |
2028 {""}, | 1885 {"signed", 0, st_C_typespec}, |
2029 {"DEFUN", 0, st_C_gnumacro}, | 1886 {"unsigned", 0, st_C_typespec}, |
2030 {""}, {""}, | 1887 {"",}, {"",}, {"",}, |
2031 {"define", 0, st_C_define}, | 1888 {"struct", 0, st_C_struct}, |
2032 {""}, {""}, {""}, {""}, {""}, | 1889 {"void", 0, st_C_typespec}, |
2033 {"double", 0, st_C_typespec}, | 1890 {"static", 0, st_C_typespec}, |
2034 {"struct", 0, st_C_struct}, | 1891 {"",}, {"",}, {"",}, {"",}, |
2035 {""}, {""}, {""}, {""}, | 1892 {"operator", C_PLPL, st_C_operator}, |
2036 {"short", 0, st_C_typespec}, | 1893 {"",}, |
2037 {""}, | 1894 {"char", 0, st_C_typespec}, |
2038 {"enum", 0, st_C_enum}, | 1895 {"class", C_PLPL, st_C_struct}, |
2039 {"mutable", C_PLPL, st_C_typespec}, | 1896 {"enum", 0, st_C_enum}, |
2040 {""}, | 1897 {"package", C_JAVA, st_C_ignore}, |
2041 {"extern", 0, st_C_extern}, | 1898 {"",}, |
2042 {"extends", C_JAVA, st_C_javastruct}, | 1899 {"volatile", 0, st_C_typespec}, |
2043 {"package", C_JAVA, st_C_ignore}, | 1900 {"domain", C_STAR, st_C_struct}, |
2044 {"while", 0, st_C_ignore}, | 1901 {"DEFUN", 0, st_C_gnumacro}, |
2045 {""}, | 1902 {"",}, |
2046 {"for", 0, st_C_ignore}, | 1903 {"long", 0, st_C_typespec}, |
2047 {""}, {""}, {""}, | 1904 {"@protocol", 0, st_C_objprot}, |
2048 {"volatile", 0, st_C_typespec}, | 1905 {"",}, {"",}, {"",}, |
2049 {""}, {""}, | 1906 {"explicit", C_PLPL, st_C_typespec}, |
2050 {"import", C_JAVA, st_C_ignore}, | 1907 {"",}, |
2051 {"float", 0, st_C_typespec}, | 1908 {"extern", 0, st_C_typespec}, |
2052 {"switch", 0, st_C_ignore}, | 1909 {"extends", C_JAVA, st_C_javastruct}, |
2053 {"return", 0, st_C_ignore}, | 1910 {"",}, |
2054 {"implements", C_JAVA, st_C_javastruct}, | 1911 {"mutable", C_PLPL, st_C_typespec}, |
2055 {""}, | 1912 {"",}, {"",}, {"",}, {"",}, |
2056 {"static", 0, st_C_typespec}, | 1913 {"PSEUDO", 0, st_C_gnumacro}, |
2057 {"typedef", 0, st_C_typedef}, | 1914 {"",}, {"",}, {"",}, {"",}, |
2058 {"typename", C_PLPL, st_C_typespec}, | 1915 {"const", 0, st_C_typespec}, |
2059 {"unsigned", 0, st_C_typespec}, | 1916 {"",}, {"",}, {"",}, {"",}, {"",}, |
2060 {""}, {""}, | 1917 {"@end", 0, st_C_objend}, |
2061 {"char", 0, st_C_typespec}, | 1918 {"",}, {"",}, {"",}, {"",}, {"",}, |
2062 {"class", C_PLPL, st_C_struct}, | 1919 {"@interface", 0, st_C_objprot}, |
2063 {""}, {""}, {""}, | 1920 {"",}, {"",}, {"",}, |
2064 {"void", 0, st_C_typespec}, | 1921 {"namespace", C_PLPL, st_C_struct}, |
2065 {""}, {""}, | 1922 {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, |
2066 {"friend", C_PLPL, st_C_ignore}, | 1923 {"@implementation", 0, st_C_objimpl}, |
2067 {""}, {""}, {""}, | |
2068 {"int", 0, st_C_typespec}, | |
2069 {"union", 0, st_C_struct}, | |
2070 {""}, {""}, {""}, | |
2071 {"auto", 0, st_C_typespec}, | |
2072 {"interface", C_JAVA, st_C_struct}, | |
2073 {""}, | |
2074 {"SYSCALL", 0, st_C_gnumacro} | |
2075 }; | 1924 }; |
2076 | 1925 |
2077 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) | 1926 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) |
2078 { | 1927 { |
2079 register int key = hash (str, len); | 1928 register int key = hash (str, len); |
2080 | 1929 |
2081 if (key <= MAX_HASH_VALUE && key >= 0) | 1930 if (key <= MAX_HASH_VALUE && key >= 0) |
2082 { | 1931 { |
2083 register const char *s = wordlist[key].name; | 1932 register char *s = wordlist[key].name; |
2084 | 1933 |
2085 if (*str == *s && !strncmp (str + 1, s + 1, len - 1)) | 1934 if (*s == *str && !strncmp (str + 1, s + 1, len - 1)) |
2086 return &wordlist[key]; | 1935 return &wordlist[key]; |
2087 } | 1936 } |
2088 } | 1937 } |
2089 return 0; | 1938 return 0; |
2090 } | 1939 } |
2091 /*%>*/ | 1940 /*%>*/ |
2092 | 1941 |
2093 static enum sym_type | 1942 enum sym_type |
2094 C_symtype (str, len, c_ext) | 1943 C_symtype (str, len, c_ext) |
2095 char *str; | 1944 char *str; |
2096 int len; | 1945 int len; |
2097 int c_ext; | 1946 int c_ext; |
2098 { | 1947 { |
2117 flistseen, /* func: after parameter list */ | 1966 flistseen, /* func: after parameter list */ |
2118 fignore, /* func: before open brace */ | 1967 fignore, /* func: before open brace */ |
2119 vignore /* var-like: ignore until ';' */ | 1968 vignore /* var-like: ignore until ';' */ |
2120 } fvdef; | 1969 } fvdef; |
2121 | 1970 |
2122 bool fvextern; /* func or var: extern keyword seen; */ | |
2123 | 1971 |
2124 /* | 1972 /* |
2125 * typedefs are recognized using a simple finite automaton. | 1973 * typedefs are recognized using a simple finite automaton. |
2126 * typdef is its state variable. | 1974 * typdef is its state variable. |
2127 */ | 1975 */ |
2128 enum | 1976 enum |
2129 { | 1977 { |
2130 tnone, /* nothing seen */ | 1978 tnone, /* nothing seen */ |
2131 tkeyseen, /* typedef keyword seen */ | 1979 ttypedseen, /* typedef keyword seen */ |
2132 ttypeseen, /* defined type seen */ | |
2133 tinbody, /* inside typedef body */ | 1980 tinbody, /* inside typedef body */ |
2134 tend, /* just before typedef tag */ | 1981 tend, /* just before typedef tag */ |
2135 tignore /* junk after typedef tag */ | 1982 tignore /* junk after typedef tag */ |
2136 } typdef; | 1983 } typdef; |
2137 | 1984 |
2225 | 2072 |
2226 /* | 2073 /* |
2227 * methodlen is the length of the method name stored in token_name. | 2074 * methodlen is the length of the method name stored in token_name. |
2228 */ | 2075 */ |
2229 int methodlen; | 2076 int methodlen; |
2230 | |
2231 static bool consider_token P_((char *, int, int, int, int, int, bool *)); | |
2232 static void make_C_tag P_((bool)); | |
2233 | 2077 |
2234 /* | 2078 /* |
2235 * consider_token () | 2079 * consider_token () |
2236 * checks to see if the current token is at the start of a | 2080 * checks to see if the current token is at the start of a |
2237 * function or variable, or corresponds to a typedef, or | 2081 * function or variable, or corresponds to a typedef, or |
2247 * typdef IN OUT | 2091 * typdef IN OUT |
2248 * objdef IN OUT | 2092 * objdef IN OUT |
2249 * next_token_is_func IN OUT | 2093 * next_token_is_func IN OUT |
2250 */ | 2094 */ |
2251 | 2095 |
2252 static bool | 2096 bool |
2253 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) | 2097 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) |
2254 register char *str; /* IN: token pointer */ | 2098 register char *str; /* IN: token pointer */ |
2255 register int len; /* IN: token length */ | 2099 register int len; /* IN: token length */ |
2256 register int c; /* IN: first char after the token */ | 2100 register char c; /* IN: first char after the token */ |
2257 int c_ext; /* IN: C extensions mask */ | 2101 int c_ext; /* IN: C extensions mask */ |
2258 int cblev; /* IN: curly brace level */ | 2102 int cblev; /* IN: curly brace level */ |
2259 int parlev; /* IN: parenthesis level */ | 2103 int parlev; /* IN: parenthesis level */ |
2260 bool *is_func_or_var; /* OUT: function or variable found */ | 2104 bool *is_func_or_var; /* OUT: function or variable found */ |
2261 { | 2105 { |
2303 { | 2147 { |
2304 case tnone: | 2148 case tnone: |
2305 if (toktype == st_C_typedef) | 2149 if (toktype == st_C_typedef) |
2306 { | 2150 { |
2307 if (typedefs) | 2151 if (typedefs) |
2308 typdef = tkeyseen; | 2152 typdef = ttypedseen; |
2309 fvextern = FALSE; | |
2310 fvdef = fvnone; | 2153 fvdef = fvnone; |
2311 return FALSE; | 2154 return FALSE; |
2312 } | 2155 } |
2313 break; | 2156 break; |
2314 case tkeyseen: | 2157 case ttypedseen: |
2315 switch (toktype) | 2158 switch (toktype) |
2316 { | 2159 { |
2317 case st_none: | 2160 case st_none: |
2318 case st_C_typespec: | 2161 case st_C_typespec: |
2162 typdef = tend; | |
2163 break; | |
2319 case st_C_struct: | 2164 case st_C_struct: |
2320 case st_C_enum: | 2165 case st_C_enum: |
2321 typdef = ttypeseen; | |
2322 break; | 2166 break; |
2323 } | 2167 } |
2324 /* Do not return here, so the structdef stuff has a chance. */ | 2168 /* Do not return here, so the structdef stuff has a chance. */ |
2325 break; | 2169 break; |
2326 case tend: | 2170 case tend: |
2350 if (structdef == stagseen) | 2194 if (structdef == stagseen) |
2351 structdef = scolonseen; | 2195 structdef = scolonseen; |
2352 return FALSE; | 2196 return FALSE; |
2353 case st_C_struct: | 2197 case st_C_struct: |
2354 case st_C_enum: | 2198 case st_C_enum: |
2355 if (typdef == tkeyseen | 2199 if (typdef == ttypedseen |
2356 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone)) | 2200 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone)) |
2357 { | 2201 { |
2358 structdef = skeyseen; | 2202 structdef = skeyseen; |
2359 structtype = toktype; | 2203 structtype = toktype; |
2360 } | 2204 } |
2371 structtag = "<enum>"; | 2215 structtag = "<enum>"; |
2372 structdef = stagseen; | 2216 structdef = stagseen; |
2373 return TRUE; | 2217 return TRUE; |
2374 } | 2218 } |
2375 | 2219 |
2220 /* Avoid entering fvdef stuff if typdef is going on. */ | |
2376 if (typdef != tnone) | 2221 if (typdef != tnone) |
2377 definedef = dnone; | 2222 { |
2223 definedef = dnone; | |
2224 return FALSE; | |
2225 } | |
2378 | 2226 |
2379 /* Detect GNU macros. | 2227 /* Detect GNU macros. |
2380 | 2228 |
2381 Writers of emacs code are recommended to put the | 2229 DEFUN note for writers of emacs C code: |
2382 first two args of a DEFUN on the same line. | |
2383 | |
2384 The DEFUN macro, used in emacs C source code, has a first arg | 2230 The DEFUN macro, used in emacs C source code, has a first arg |
2385 that is a string (the lisp function name), and a second arg that | 2231 that is a string (the lisp function name), and a second arg that |
2386 is a C function name. Since etags skips strings, the second arg | 2232 is a C function name. Since etags skips strings, the second arg |
2387 is tagged. This is unfortunate, as it would be better to tag the | 2233 is tagged. This is unfortunate, as it would be better to tag the |
2388 first arg. The simplest way to deal with this problem would be | 2234 first arg. The simplest way to deal with this problem would be |
2389 to name the tag with a name built from the function name, by | 2235 to name the tag with a name built from the function name, by |
2390 removing the initial 'F' character and substituting '-' for '_'. | 2236 removing the initial 'F' character and substituting '-' for '_'. |
2391 Anyway, this assumes that the conventions of naming lisp | 2237 Anyway, this assumes that the conventions of naming lisp |
2392 functions will never change. Currently, this method is not | 2238 functions will never change. Currently, this method is not |
2393 implemented. */ | 2239 implemented, so writers of emacs code are recommended to put the |
2240 first two args of a DEFUN on the same line. */ | |
2394 if (definedef == dnone && toktype == st_C_gnumacro) | 2241 if (definedef == dnone && toktype == st_C_gnumacro) |
2395 { | 2242 { |
2396 next_token_is_func = TRUE; | 2243 next_token_is_func = TRUE; |
2397 return FALSE; | 2244 return FALSE; |
2398 } | 2245 } |
2477 } | 2324 } |
2478 | 2325 |
2479 /* A function, variable or enum constant? */ | 2326 /* A function, variable or enum constant? */ |
2480 switch (toktype) | 2327 switch (toktype) |
2481 { | 2328 { |
2482 case st_C_extern: | |
2483 fvextern = TRUE; | |
2484 /* FALLTHRU */ | |
2485 case st_C_typespec: | 2329 case st_C_typespec: |
2486 if (fvdef != finlist && fvdef != fignore && fvdef != vignore) | 2330 if (fvdef != finlist && fvdef != fignore && fvdef != vignore) |
2487 fvdef = fvnone; /* should be useless */ | 2331 fvdef = fvnone; /* should be useless */ |
2488 return FALSE; | 2332 return FALSE; |
2489 case st_C_ignore: | 2333 case st_C_ignore: |
2490 fvextern = FALSE; | |
2491 fvdef = vignore; | 2334 fvdef = vignore; |
2492 return FALSE; | 2335 return FALSE; |
2493 case st_C_operator: | 2336 case st_C_operator: |
2494 fvdef = foperator; | 2337 fvdef = foperator; |
2495 *is_func_or_var = TRUE; | 2338 *is_func_or_var = TRUE; |
2496 return TRUE; | 2339 return TRUE; |
2497 case st_none: | 2340 case st_none: |
2498 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10)) | |
2499 { | |
2500 fvdef = foperator; | |
2501 *is_func_or_var = TRUE; | |
2502 return TRUE; | |
2503 } | |
2504 if (constantypedefs && structdef == sinbody && structtype == st_C_enum) | 2341 if (constantypedefs && structdef == sinbody && structtype == st_C_enum) |
2505 return TRUE; | 2342 return TRUE; |
2506 if (fvdef == fvnone) | 2343 if (fvdef == fvnone) |
2507 { | 2344 { |
2508 fvdef = fvnameseen; /* function or variable */ | 2345 fvdef = fvnameseen; /* function or variable */ |
2509 *is_func_or_var = TRUE; | 2346 *is_func_or_var = TRUE; |
2510 return TRUE; | 2347 return TRUE; |
2511 } | 2348 } |
2512 break; | |
2513 } | 2349 } |
2514 | 2350 |
2515 return FALSE; | 2351 return FALSE; |
2516 } | 2352 } |
2517 | 2353 |
2518 /* | 2354 /* |
2519 * C_entries () | 2355 * C_entries () |
2520 * This routine finds functions, variables, typedefs, | 2356 * This routine finds functions, variables, typedefs, |
2521 * #define's, enum constants and struct/union/enum definitions in | 2357 * #define's, enum constants and struct/union/enum definitions in |
2522 * C syntax and adds them to the list. | 2358 * #C syntax and adds them to the list. |
2523 */ | 2359 */ |
2524 #define current_lb_is_new (newndx == curndx) | 2360 #define current_lb_is_new (newndx == curndx) |
2525 #define switch_line_buffers() (curndx = 1 - curndx) | 2361 #define switch_line_buffers() (curndx = 1 - curndx) |
2526 | 2362 |
2527 #define curlb (lbs[curndx].lb) | 2363 #define curlb (lbs[curndx].lb) |
2552 } \ | 2388 } \ |
2553 definedef = dnone; \ | 2389 definedef = dnone; \ |
2554 } while (0) | 2390 } while (0) |
2555 | 2391 |
2556 | 2392 |
2557 static void | 2393 void |
2558 make_C_tag (isfun) | 2394 make_C_tag (isfun) |
2559 bool isfun; | 2395 bool isfun; |
2560 { | 2396 { |
2561 /* This function should never be called when tok.valid is FALSE, but | 2397 /* This function should never be called when tok.valid is FALSE, but |
2562 we must protect against invalid input or internal errors. */ | 2398 we must protect against invalid input or internal errors. */ |
2581 else if (DEBUG) | 2417 else if (DEBUG) |
2582 abort (); | 2418 abort (); |
2583 } | 2419 } |
2584 | 2420 |
2585 | 2421 |
2586 static void | 2422 void |
2587 C_entries (c_ext, inf) | 2423 C_entries (c_ext, inf) |
2588 int c_ext; /* extension of C */ | 2424 int c_ext; /* extension of C */ |
2589 FILE *inf; /* input file */ | 2425 FILE *inf; /* input file */ |
2590 { | 2426 { |
2591 register char c; /* latest char read; '\0' for end of line */ | 2427 register char c; /* latest char read; '\0' for end of line */ |
2596 char *qualifier; /* string used to qualify names */ | 2432 char *qualifier; /* string used to qualify names */ |
2597 int qlen; /* length of qualifier */ | 2433 int qlen; /* length of qualifier */ |
2598 int cblev; /* current curly brace level */ | 2434 int cblev; /* current curly brace level */ |
2599 int parlev; /* current parenthesis level */ | 2435 int parlev; /* current parenthesis level */ |
2600 bool incomm, inquote, inchar, quotednl, midtoken; | 2436 bool incomm, inquote, inchar, quotednl, midtoken; |
2601 bool purec, cplpl, cjava; | 2437 bool cplpl, cjava; |
2602 token savetok; /* token saved during preprocessor handling */ | 2438 token savetok; /* token saved during preprocessor handling */ |
2603 | 2439 |
2604 | 2440 |
2605 tokoff = toklen = 0; /* keep compiler quiet */ | 2441 tokoff = toklen = 0; /* keep compiler quiet */ |
2606 curndx = newndx = 0; | 2442 curndx = newndx = 0; |
2607 lineno = 0; | 2443 lineno = 0; |
2608 charno = 0; | 2444 charno = 0; |
2609 lp = curlb.buffer; | 2445 lp = curlb.buffer; |
2610 *lp = 0; | 2446 *lp = 0; |
2611 | 2447 |
2612 fvdef = fvnone; fvextern = FALSE; typdef = tnone; | 2448 fvdef = fvnone; typdef = tnone; structdef = snone; |
2613 structdef = snone; definedef = dnone; objdef = onone; | 2449 definedef = dnone; objdef = onone; |
2614 next_token_is_func = yacc_rules = FALSE; | 2450 next_token_is_func = yacc_rules = FALSE; |
2615 midtoken = inquote = inchar = incomm = quotednl = FALSE; | 2451 midtoken = inquote = inchar = incomm = quotednl = FALSE; |
2616 tok.valid = savetok.valid = FALSE; | 2452 tok.valid = savetok.valid = FALSE; |
2617 cblev = 0; | 2453 cblev = 0; |
2618 parlev = 0; | 2454 parlev = 0; |
2619 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */ | |
2620 cplpl = (c_ext & C_PLPL) == C_PLPL; | 2455 cplpl = (c_ext & C_PLPL) == C_PLPL; |
2621 cjava = (c_ext & C_JAVA) == C_JAVA; | 2456 cjava = (c_ext & C_JAVA) == C_JAVA; |
2622 if (cjava) | 2457 if (cjava) |
2623 { qualifier = "."; qlen = 1; } | 2458 { qualifier = "."; qlen = 1; } |
2624 else | 2459 else |
2693 switch (c) | 2528 switch (c) |
2694 { | 2529 { |
2695 case '"': | 2530 case '"': |
2696 inquote = TRUE; | 2531 inquote = TRUE; |
2697 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) | 2532 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) |
2698 { | 2533 fvdef = fvnone; |
2699 fvextern = FALSE; | |
2700 fvdef = fvnone; | |
2701 } | |
2702 continue; | 2534 continue; |
2703 case '\'': | 2535 case '\'': |
2704 inchar = TRUE; | 2536 inchar = TRUE; |
2705 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) | 2537 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) |
2706 { | 2538 fvdef = fvnone; |
2707 fvextern = FALSE; | |
2708 fvdef = fvnone; | |
2709 } | |
2710 continue; | 2539 continue; |
2711 case '/': | 2540 case '/': |
2712 if (*lp == '*') | 2541 if (*lp == '*') |
2713 { | 2542 { |
2714 lp++; | 2543 lp++; |
2725 case '%': | 2554 case '%': |
2726 if ((c_ext & YACC) && *lp == '%') | 2555 if ((c_ext & YACC) && *lp == '%') |
2727 { | 2556 { |
2728 /* entering or exiting rules section in yacc file */ | 2557 /* entering or exiting rules section in yacc file */ |
2729 lp++; | 2558 lp++; |
2730 definedef = dnone; fvdef = fvnone; fvextern = FALSE; | 2559 definedef = dnone; fvdef = fvnone; |
2731 typdef = tnone; structdef = snone; | 2560 typdef = tnone; structdef = snone; |
2732 next_token_is_func = FALSE; | 2561 next_token_is_func = FALSE; |
2733 midtoken = inquote = inchar = incomm = quotednl = FALSE; | 2562 midtoken = inquote = inchar = incomm = quotednl = FALSE; |
2734 cblev = 0; | 2563 cblev = 0; |
2735 yacc_rules = !yacc_rules; | 2564 yacc_rules = !yacc_rules; |
2767 | 2596 |
2768 /* Consider token only if some complicated conditions are satisfied. */ | 2597 /* Consider token only if some complicated conditions are satisfied. */ |
2769 if ((definedef != dnone | 2598 if ((definedef != dnone |
2770 || (cblev == 0 && structdef != scolonseen) | 2599 || (cblev == 0 && structdef != scolonseen) |
2771 || (cblev == 1 && cplpl && structdef == sinbody) | 2600 || (cblev == 1 && cplpl && structdef == sinbody) |
2772 || (structdef == sinbody && purec)) | 2601 || (structdef == sinbody && structtype == st_C_enum)) |
2773 && typdef != tignore | 2602 && typdef != tignore |
2774 && definedef != dignorerest | 2603 && definedef != dignorerest |
2775 && fvdef != finlist) | 2604 && fvdef != finlist) |
2776 { | 2605 { |
2777 if (midtoken) | 2606 if (midtoken) |
2778 { | 2607 { |
2779 if (endtoken (c)) | 2608 if (endtoken (c)) |
2780 { | 2609 { |
2781 bool funorvar = FALSE; | 2610 if (c == ':' && cplpl && *lp == ':' && begtoken(*(lp + 1))) |
2782 | |
2783 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1])) | |
2784 { | 2611 { |
2785 /* | 2612 /* |
2786 * This handles :: in the middle, but not at the | 2613 * This handles :: in the middle, but not at the |
2787 * beginning of an identifier. Also, space-separated | 2614 * beginning of an identifier. |
2788 * :: is not recognised. | |
2789 */ | 2615 */ |
2790 lp += 2; | 2616 lp += 2; |
2791 toklen += 2; | 2617 toklen += 3; |
2792 c = lp[-1]; | |
2793 goto intok; | |
2794 } | 2618 } |
2795 else | 2619 else |
2796 { | 2620 { |
2621 bool funorvar = FALSE; | |
2622 | |
2797 if (yacc_rules | 2623 if (yacc_rules |
2798 || consider_token (newlb.buffer + tokoff, toklen, c, | 2624 || consider_token (newlb.buffer + tokoff, toklen, c, |
2799 c_ext, cblev, parlev, &funorvar)) | 2625 c_ext, cblev, parlev, &funorvar)) |
2800 { | 2626 { |
2801 if (fvdef == foperator) | |
2802 { | |
2803 char *oldlp = lp; | |
2804 lp = skip_spaces (lp-1); | |
2805 if (*lp != '\0') | |
2806 lp += 1; | |
2807 while (*lp != '\0' | |
2808 && !iswhite (*lp) && *lp != '(') | |
2809 lp += 1; | |
2810 c = *lp++; | |
2811 toklen += lp - oldlp; | |
2812 } | |
2813 tok.named = FALSE; | 2627 tok.named = FALSE; |
2814 if (!purec | 2628 if (structdef == sinbody |
2815 && funorvar | |
2816 && definedef == dnone | 2629 && definedef == dnone |
2817 && structdef == sinbody) | 2630 && funorvar) |
2818 /* function or var defined in C++ class body */ | 2631 /* function or var defined in C++ class body */ |
2819 { | 2632 { |
2820 int len = strlen (structtag) + qlen + toklen; | 2633 int len; |
2634 if (fvdef == foperator) | |
2635 { | |
2636 char *oldlp = lp; | |
2637 lp = skip_spaces (lp-1); | |
2638 while (*lp != '\0' | |
2639 && !isspace (*lp) && *lp != '(') | |
2640 lp += 1; | |
2641 c = *lp++; | |
2642 toklen += lp - oldlp; | |
2643 } | |
2644 | |
2645 len = strlen (structtag) + qlen + toklen; | |
2821 grow_linebuffer (&token_name, len + 1); | 2646 grow_linebuffer (&token_name, len + 1); |
2822 strcpy (token_name.buffer, structtag); | 2647 strcpy (token_name.buffer, structtag); |
2823 strcat (token_name.buffer, qualifier); | 2648 strcat (token_name.buffer, qualifier); |
2824 strncat (token_name.buffer, | 2649 strncat (token_name.buffer, |
2825 newlb.buffer + tokoff, toklen); | 2650 newlb.buffer + tokoff, toklen); |
2850 grow_linebuffer (&token_name, toklen + 1); | 2675 grow_linebuffer (&token_name, toklen + 1); |
2851 strncpy (token_name.buffer, | 2676 strncpy (token_name.buffer, |
2852 newlb.buffer + tokoff, toklen); | 2677 newlb.buffer + tokoff, toklen); |
2853 token_name.buffer[toklen] = '\0'; | 2678 token_name.buffer[toklen] = '\0'; |
2854 token_name.len = toklen; | 2679 token_name.len = toklen; |
2855 /* Name macros and members. */ | 2680 /* Name macros. */ |
2856 tok.named = (structdef == stagseen | 2681 tok.named = (structdef == stagseen |
2857 || typdef == ttypeseen | |
2858 || typdef == tend | 2682 || typdef == tend |
2859 || (funorvar | 2683 || (funorvar |
2860 && definedef == dignorerest) | 2684 && definedef == dignorerest)); |
2861 || (funorvar | |
2862 && definedef == dnone | |
2863 && structdef == sinbody)); | |
2864 } | 2685 } |
2865 tok.lineno = lineno; | 2686 tok.lineno = lineno; |
2866 tok.linelen = tokoff + toklen + 1; | 2687 tok.linelen = tokoff + toklen + 1; |
2867 tok.buffer = newlb.buffer; | 2688 tok.buffer = newlb.buffer; |
2868 tok.linepos = newlinepos; | 2689 tok.linepos = newlinepos; |
2883 } | 2704 } |
2884 midtoken = FALSE; | 2705 midtoken = FALSE; |
2885 } | 2706 } |
2886 } /* if (endtoken (c)) */ | 2707 } /* if (endtoken (c)) */ |
2887 else if (intoken (c)) | 2708 else if (intoken (c)) |
2888 intok: | |
2889 { | 2709 { |
2890 toklen++; | 2710 toklen++; |
2891 continue; | 2711 continue; |
2892 } | 2712 } |
2893 } /* if (midtoken) */ | 2713 } /* if (midtoken) */ |
2959 make_C_tag (FALSE); /* a yacc function */ | 2779 make_C_tag (FALSE); /* a yacc function */ |
2960 fvdef = fignore; | 2780 fvdef = fignore; |
2961 } | 2781 } |
2962 break; | 2782 break; |
2963 case fstartlist: | 2783 case fstartlist: |
2964 fvextern = FALSE; | |
2965 fvdef = fvnone; | 2784 fvdef = fvnone; |
2966 break; | 2785 break; |
2967 } | 2786 } |
2968 break; | 2787 break; |
2969 case ';': | 2788 case ';': |
2981 switch (fvdef) | 2800 switch (fvdef) |
2982 { | 2801 { |
2983 case fignore: | 2802 case fignore: |
2984 break; | 2803 break; |
2985 case fvnameseen: | 2804 case fvnameseen: |
2986 if ((members && cblev == 1) | 2805 if ((globals && cblev == 0) || (members && cblev == 1)) |
2987 || (globals && cblev == 0 && (!fvextern || declarations))) | |
2988 make_C_tag (FALSE); /* a variable */ | 2806 make_C_tag (FALSE); /* a variable */ |
2989 fvextern = FALSE; | |
2990 fvdef = fvnone; | |
2991 tok.valid = FALSE; | |
2992 break; | |
2993 case flistseen: | |
2994 if (declarations && (cblev == 0 || cblev == 1)) | |
2995 make_C_tag (TRUE); /* a function declaration */ | |
2996 /* FALLTHRU */ | 2807 /* FALLTHRU */ |
2997 default: | 2808 default: |
2998 fvextern = FALSE; | |
2999 fvdef = fvnone; | 2809 fvdef = fvnone; |
3000 /* The following instruction invalidates the token. | 2810 /* The following instruction invalidates the token. |
3001 Probably the token should be invalidated in all | 2811 Probably the token should be invalidated in all |
3002 other cases where some state machine is reset. */ | 2812 other cases where some state machine is reset. */ |
3003 tok.valid = FALSE; | 2813 tok.valid = FALSE; |
3022 case finlist: | 2832 case finlist: |
3023 case fignore: | 2833 case fignore: |
3024 case vignore: | 2834 case vignore: |
3025 break; | 2835 break; |
3026 case fvnameseen: | 2836 case fvnameseen: |
3027 if ((members && cblev == 1) | 2837 if ((globals && cblev == 0) || (members && cblev == 1)) |
3028 || (globals && cblev == 0 && (!fvextern || declarations))) | |
3029 make_C_tag (FALSE); /* a variable */ | 2838 make_C_tag (FALSE); /* a variable */ |
3030 break; | 2839 break; |
3031 default: | 2840 default: |
3032 fvdef = fvnone; | 2841 fvdef = fvnone; |
3033 } | 2842 } |
3049 case finlist: | 2858 case finlist: |
3050 case fignore: | 2859 case fignore: |
3051 case vignore: | 2860 case vignore: |
3052 break; | 2861 break; |
3053 case fvnameseen: | 2862 case fvnameseen: |
3054 if ((members && cblev == 1) | 2863 if ((globals && cblev == 0) || (members && cblev == 1)) |
3055 || (globals && cblev == 0 && (!fvextern || declarations))) | |
3056 make_C_tag (FALSE); /* a variable */ | 2864 make_C_tag (FALSE); /* a variable */ |
3057 /* FALLTHRU */ | 2865 /* FALLTHRU */ |
3058 default: | 2866 default: |
3059 fvdef = fvnone; | 2867 fvdef = fvnone; |
3060 } | 2868 } |
3066 break; | 2874 break; |
3067 if (objdef == otagseen && parlev == 0) | 2875 if (objdef == otagseen && parlev == 0) |
3068 objdef = oparenseen; | 2876 objdef = oparenseen; |
3069 switch (fvdef) | 2877 switch (fvdef) |
3070 { | 2878 { |
2879 case fvnone: | |
2880 switch (typdef) | |
2881 { | |
2882 case ttypedseen: | |
2883 case tend: | |
2884 if (tok.valid && *lp != '*') | |
2885 { | |
2886 /* This handles constructs like: | |
2887 typedef void OperatorFun (int fun); */ | |
2888 make_C_tag (FALSE); | |
2889 typdef = tignore; | |
2890 } | |
2891 break; | |
2892 } /* switch (typdef) */ | |
2893 break; | |
2894 case foperator: /* operator() is not handled */ | |
3071 case fvnameseen: | 2895 case fvnameseen: |
3072 if (typdef == ttypeseen | |
3073 && tok.valid | |
3074 && *lp != '*' | |
3075 && structdef != sinbody) | |
3076 { | |
3077 /* This handles constructs like: | |
3078 typedef void OperatorFun (int fun); */ | |
3079 make_C_tag (FALSE); | |
3080 typdef = tignore; | |
3081 } | |
3082 /* FALLTHRU */ | |
3083 case foperator: | |
3084 fvdef = fstartlist; | 2896 fvdef = fstartlist; |
3085 break; | 2897 break; |
3086 case flistseen: | 2898 case flistseen: |
3087 fvdef = finlist; | 2899 fvdef = finlist; |
3088 break; | 2900 break; |
3104 case fstartlist: | 2916 case fstartlist: |
3105 case finlist: | 2917 case finlist: |
3106 fvdef = flistseen; | 2918 fvdef = flistseen; |
3107 break; | 2919 break; |
3108 } | 2920 } |
3109 if (cblev == 0 && (typdef == tend)) | 2921 if (cblev == 0 && typdef == tend) |
3110 { | 2922 { |
3111 typdef = tignore; | 2923 typdef = tignore; |
3112 make_C_tag (FALSE); /* a typedef */ | 2924 make_C_tag (FALSE); /* a typedef */ |
3113 } | 2925 } |
3114 } | 2926 } |
3116 parlev = 0; | 2928 parlev = 0; |
3117 break; | 2929 break; |
3118 case '{': | 2930 case '{': |
3119 if (definedef != dnone) | 2931 if (definedef != dnone) |
3120 break; | 2932 break; |
3121 if (typdef == ttypeseen) | 2933 if (typdef == ttypedseen) |
3122 typdef = tinbody; | 2934 typdef = tinbody; |
3123 switch (structdef) | 2935 switch (structdef) |
3124 { | 2936 { |
3125 case skeyseen: /* unnamed struct */ | 2937 case skeyseen: /* unnamed struct */ |
3126 structdef = sinbody; | 2938 structdef = sinbody; |
3201 case finlist: | 3013 case finlist: |
3202 case fignore: | 3014 case fignore: |
3203 case vignore: | 3015 case vignore: |
3204 break; | 3016 break; |
3205 case fvnameseen: | 3017 case fvnameseen: |
3206 if ((members && cblev == 1) | 3018 if ((globals && cblev == 0) || (members && cblev == 1)) |
3207 || (globals && cblev == 0 && (!fvextern || declarations))) | |
3208 make_C_tag (FALSE); /* a variable */ | 3019 make_C_tag (FALSE); /* a variable */ |
3209 /* FALLTHRU */ | 3020 /* FALLTHRU */ |
3210 default: | 3021 default: |
3211 fvdef = vignore; | 3022 fvdef = vignore; |
3212 } | 3023 } |
3254 | 3065 |
3255 /* | 3066 /* |
3256 * Process either a C++ file or a C file depending on the setting | 3067 * Process either a C++ file or a C file depending on the setting |
3257 * of a global flag. | 3068 * of a global flag. |
3258 */ | 3069 */ |
3259 static void | 3070 void |
3260 default_C_entries (inf) | 3071 default_C_entries (inf) |
3261 FILE *inf; | 3072 FILE *inf; |
3262 { | 3073 { |
3263 C_entries (cplusplus ? C_PLPL : 0, inf); | 3074 C_entries (cplusplus ? C_PLPL : 0, inf); |
3264 } | 3075 } |
3265 | 3076 |
3266 /* Always do plain ANSI C. */ | 3077 /* Always do plain ANSI C. */ |
3267 static void | 3078 void |
3268 plain_C_entries (inf) | 3079 plain_C_entries (inf) |
3269 FILE *inf; | 3080 FILE *inf; |
3270 { | 3081 { |
3271 C_entries (0, inf); | 3082 C_entries (0, inf); |
3272 } | 3083 } |
3273 | 3084 |
3274 /* Always do C++. */ | 3085 /* Always do C++. */ |
3275 static void | 3086 void |
3276 Cplusplus_entries (inf) | 3087 Cplusplus_entries (inf) |
3277 FILE *inf; | 3088 FILE *inf; |
3278 { | 3089 { |
3279 C_entries (C_PLPL, inf); | 3090 C_entries (C_PLPL, inf); |
3280 } | 3091 } |
3281 | 3092 |
3282 /* Always do Java. */ | 3093 /* Always do Java. */ |
3283 static void | 3094 void |
3284 Cjava_entries (inf) | 3095 Cjava_entries (inf) |
3285 FILE *inf; | 3096 FILE *inf; |
3286 { | 3097 { |
3287 C_entries (C_JAVA, inf); | 3098 C_entries (C_JAVA, inf); |
3288 } | 3099 } |
3289 | 3100 |
3290 /* Always do C*. */ | 3101 /* Always do C*. */ |
3291 static void | 3102 void |
3292 Cstar_entries (inf) | 3103 Cstar_entries (inf) |
3293 FILE *inf; | 3104 FILE *inf; |
3294 { | 3105 { |
3295 C_entries (C_STAR, inf); | 3106 C_entries (C_STAR, inf); |
3296 } | 3107 } |
3297 | 3108 |
3298 /* Always do Yacc. */ | 3109 /* Always do Yacc. */ |
3299 static void | 3110 void |
3300 Yacc_entries (inf) | 3111 Yacc_entries (inf) |
3301 FILE *inf; | 3112 FILE *inf; |
3302 { | 3113 { |
3303 C_entries (YACC, inf); | 3114 C_entries (YACC, inf); |
3304 } | 3115 } |
3305 | 3116 |
3306 /* A useful macro. */ | 3117 /* A useful macro. */ |
3307 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ | 3118 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ |
3308 for (lineno = charno = 0; /* loop initialization */ \ | 3119 for (lineno = charno = 0; /* loop initialization */ \ |
3309 !feof (file_pointer) /* loop test */ \ | 3120 !feof (file_pointer) /* loop test */ \ |
3310 && (lineno++, /* instructions at start of loop */ \ | 3121 && (lineno++, /* instructions at start of loop */ \ |
3311 linecharno = charno, \ | 3122 linecharno = charno, \ |
3317 | 3128 |
3318 /* | 3129 /* |
3319 * Read a file, but do no processing. This is used to do regexp | 3130 * Read a file, but do no processing. This is used to do regexp |
3320 * matching on files that have no language defined. | 3131 * matching on files that have no language defined. |
3321 */ | 3132 */ |
3322 static void | 3133 void |
3323 just_read_file (inf) | 3134 just_read_file (inf) |
3324 FILE *inf; | 3135 FILE *inf; |
3325 { | 3136 { |
3326 register char *dummy; | 3137 register char *dummy; |
3327 | 3138 |
3329 continue; | 3140 continue; |
3330 } | 3141 } |
3331 | 3142 |
3332 /* Fortran parsing */ | 3143 /* Fortran parsing */ |
3333 | 3144 |
3334 static bool tail P_((char *)); | 3145 bool |
3335 static void takeprec P_((void)); | |
3336 static void getit P_((FILE *)); | |
3337 | |
3338 static bool | |
3339 tail (cp) | 3146 tail (cp) |
3340 char *cp; | 3147 char *cp; |
3341 { | 3148 { |
3342 register int len = 0; | 3149 register int len = 0; |
3343 | 3150 |
3344 while (*cp != '\0' && lowcase (*cp) == lowcase (dbp[len])) | 3151 while (*cp && lowcase(*cp) == lowcase(dbp[len])) |
3345 cp++, len++; | 3152 cp++, len++; |
3346 if (*cp == '\0' && !intoken (dbp[len])) | 3153 if (*cp == '\0' && !intoken(dbp[len])) |
3347 { | 3154 { |
3348 dbp += len; | 3155 dbp += len; |
3349 return TRUE; | 3156 return TRUE; |
3350 } | 3157 } |
3351 return FALSE; | 3158 return FALSE; |
3352 } | 3159 } |
3353 | 3160 |
3354 static void | 3161 void |
3355 takeprec () | 3162 takeprec () |
3356 { | 3163 { |
3357 dbp = skip_spaces (dbp); | 3164 dbp = skip_spaces (dbp); |
3358 if (*dbp != '*') | 3165 if (*dbp != '*') |
3359 return; | 3166 return; |
3362 if (strneq (dbp, "(*)", 3)) | 3169 if (strneq (dbp, "(*)", 3)) |
3363 { | 3170 { |
3364 dbp += 3; | 3171 dbp += 3; |
3365 return; | 3172 return; |
3366 } | 3173 } |
3367 if (!isdigit ((unsigned char) *dbp)) | 3174 if (!isdigit (*dbp)) |
3368 { | 3175 { |
3369 --dbp; /* force failure */ | 3176 --dbp; /* force failure */ |
3370 return; | 3177 return; |
3371 } | 3178 } |
3372 do | 3179 do |
3373 dbp++; | 3180 dbp++; |
3374 while (isdigit ((unsigned char) *dbp)); | 3181 while (isdigit (*dbp)); |
3375 } | 3182 } |
3376 | 3183 |
3377 static void | 3184 void |
3378 getit (inf) | 3185 getit (inf) |
3379 FILE *inf; | 3186 FILE *inf; |
3380 { | 3187 { |
3381 register char *cp; | 3188 register char *cp; |
3382 | 3189 |
3390 if (dbp[5] != '&') | 3197 if (dbp[5] != '&') |
3391 return; | 3198 return; |
3392 dbp += 6; | 3199 dbp += 6; |
3393 dbp = skip_spaces (dbp); | 3200 dbp = skip_spaces (dbp); |
3394 } | 3201 } |
3395 if (!isalpha ((unsigned char) *dbp) && *dbp != '_' && *dbp != '$') | 3202 if (!isalpha (*dbp) |
3203 && *dbp != '_' | |
3204 && *dbp != '$') | |
3396 return; | 3205 return; |
3397 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++) | 3206 for (cp = dbp + 1; *cp && intoken (*cp); cp++) |
3398 continue; | 3207 continue; |
3399 pfnote (savenstr (dbp, cp-dbp), TRUE, | 3208 pfnote (savenstr (dbp, cp-dbp), TRUE, |
3400 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3209 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3401 } | 3210 } |
3402 | 3211 |
3403 | 3212 |
3404 static void | 3213 void |
3405 Fortran_functions (inf) | 3214 Fortran_functions (inf) |
3406 FILE *inf; | 3215 FILE *inf; |
3407 { | 3216 { |
3408 LOOP_ON_INPUT_LINES (inf, lb, dbp) | 3217 LOOP_ON_INPUT_LINES (inf, lb, dbp) |
3409 { | 3218 { |
3457 continue; | 3266 continue; |
3458 case 'e': | 3267 case 'e': |
3459 if (tail ("entry")) | 3268 if (tail ("entry")) |
3460 getit (inf); | 3269 getit (inf); |
3461 continue; | 3270 continue; |
3271 case 'p': | |
3272 if (tail ("program") || tail ("procedure")) | |
3273 getit (inf); | |
3274 continue; | |
3462 case 'b': | 3275 case 'b': |
3463 if (tail ("blockdata") || tail ("block data")) | 3276 if (tail ("blockdata") || tail ("block data")) |
3464 { | 3277 { |
3465 dbp = skip_spaces (dbp); | 3278 dbp = skip_spaces (dbp); |
3466 if (*dbp == '\0') /* assume un-named */ | 3279 if (*dbp == '\0') /* assume un-named */ |
3473 } | 3286 } |
3474 } | 3287 } |
3475 } | 3288 } |
3476 | 3289 |
3477 /* | 3290 /* |
3478 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24 | |
3479 * Ada parsing | |
3480 */ | |
3481 | |
3482 static void adagetit P_((FILE *, char *)); | |
3483 | |
3484 /* Once we are positioned after an "interesting" keyword, let's get | |
3485 the real tag value necessary. */ | |
3486 static void | |
3487 adagetit (inf, name_qualifier) | |
3488 FILE *inf; | |
3489 char *name_qualifier; | |
3490 { | |
3491 register char *cp; | |
3492 char *name; | |
3493 char c; | |
3494 | |
3495 while (!feof (inf)) | |
3496 { | |
3497 dbp = skip_spaces (dbp); | |
3498 if (*dbp == '\0' | |
3499 || (dbp[0] == '-' && dbp[1] == '-')) | |
3500 { | |
3501 lineno++; | |
3502 linecharno = charno; | |
3503 charno += readline (&lb, inf); | |
3504 dbp = lb.buffer; | |
3505 } | |
3506 switch (*dbp) | |
3507 { | |
3508 case 'b': | |
3509 case 'B': | |
3510 if (tail ("body")) | |
3511 { | |
3512 /* Skipping body of procedure body or package body or .... | |
3513 resetting qualifier to body instead of spec. */ | |
3514 name_qualifier = "/b"; | |
3515 continue; | |
3516 } | |
3517 break; | |
3518 case 't': | |
3519 case 'T': | |
3520 /* Skipping type of task type or protected type ... */ | |
3521 if (tail ("type")) | |
3522 continue; | |
3523 break; | |
3524 } | |
3525 if (*dbp == '"') | |
3526 { | |
3527 dbp += 1; | |
3528 for (cp = dbp; *cp != '\0' && *cp != '"'; cp++) | |
3529 continue; | |
3530 } | |
3531 else | |
3532 { | |
3533 dbp = skip_spaces (dbp); | |
3534 for (cp = dbp; | |
3535 (*cp != '\0' | |
3536 && (isalpha ((unsigned char) *cp) || isdigit ((unsigned char) *cp) || *cp == '_' || *cp == '.')); | |
3537 cp++) | |
3538 continue; | |
3539 if (cp == dbp) | |
3540 return; | |
3541 } | |
3542 c = *cp; | |
3543 *cp = '\0'; | |
3544 name = concat (dbp, name_qualifier, ""); | |
3545 *cp = c; | |
3546 pfnote (name, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | |
3547 if (c == '"') | |
3548 dbp = cp + 1; | |
3549 return; | |
3550 } | |
3551 } | |
3552 | |
3553 static void | |
3554 Ada_funcs (inf) | |
3555 FILE *inf; | |
3556 { | |
3557 bool inquote = FALSE; | |
3558 | |
3559 LOOP_ON_INPUT_LINES (inf, lb, dbp) | |
3560 { | |
3561 while (*dbp != '\0') | |
3562 { | |
3563 /* Skip a string i.e. "abcd". */ | |
3564 if (inquote || (*dbp == '"')) | |
3565 { | |
3566 dbp = etags_strchr ((inquote) ? dbp : dbp+1, '"'); | |
3567 if (dbp != NULL) | |
3568 { | |
3569 inquote = FALSE; | |
3570 dbp += 1; | |
3571 continue; /* advance char */ | |
3572 } | |
3573 else | |
3574 { | |
3575 inquote = TRUE; | |
3576 break; /* advance line */ | |
3577 } | |
3578 } | |
3579 | |
3580 /* Skip comments. */ | |
3581 if (dbp[0] == '-' && dbp[1] == '-') | |
3582 break; /* advance line */ | |
3583 | |
3584 /* Skip character enclosed in single quote i.e. 'a' | |
3585 and skip single quote starting an attribute i.e. 'Image. */ | |
3586 if (*dbp == '\'') | |
3587 { | |
3588 dbp++ ; | |
3589 if (*dbp != '\0') | |
3590 dbp++; | |
3591 continue; | |
3592 } | |
3593 | |
3594 /* Search for beginning of a token. */ | |
3595 if (!begtoken (*dbp)) | |
3596 { | |
3597 dbp++; | |
3598 continue; /* advance char */ | |
3599 } | |
3600 | |
3601 /* We are at the beginning of a token. */ | |
3602 switch (*dbp) | |
3603 { | |
3604 case 'f': | |
3605 case 'F': | |
3606 if (!packages_only && tail ("function")) | |
3607 adagetit (inf, "/f"); | |
3608 else | |
3609 break; /* from switch */ | |
3610 continue; /* advance char */ | |
3611 case 'p': | |
3612 case 'P': | |
3613 if (!packages_only && tail ("procedure")) | |
3614 adagetit (inf, "/p"); | |
3615 else if (tail ("package")) | |
3616 adagetit (inf, "/s"); | |
3617 else if (tail ("protected")) /* protected type */ | |
3618 adagetit (inf, "/t"); | |
3619 else | |
3620 break; /* from switch */ | |
3621 continue; /* advance char */ | |
3622 case 't': | |
3623 case 'T': | |
3624 if (!packages_only && tail ("task")) | |
3625 adagetit (inf, "/k"); | |
3626 else if (typedefs && !packages_only && tail ("type")) | |
3627 { | |
3628 adagetit (inf, "/t"); | |
3629 while (*dbp != '\0') | |
3630 dbp += 1; | |
3631 } | |
3632 else | |
3633 break; /* from switch */ | |
3634 continue; /* advance char */ | |
3635 } | |
3636 | |
3637 /* Look for the end of the token. */ | |
3638 while (!endtoken (*dbp)) | |
3639 dbp++; | |
3640 | |
3641 } /* advance char */ | |
3642 } /* advance line */ | |
3643 } | |
3644 | |
3645 /* | |
3646 * Bob Weiner, Motorola Inc., 4/3/94 | 3291 * Bob Weiner, Motorola Inc., 4/3/94 |
3647 * Unix and microcontroller assembly tag handling | 3292 * Unix and microcontroller assembly tag handling |
3648 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]' | 3293 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]' |
3649 */ | 3294 */ |
3650 static void | 3295 void |
3651 Asm_labels (inf) | 3296 Asm_labels (inf) |
3652 FILE *inf; | 3297 FILE *inf; |
3653 { | 3298 { |
3654 register char *cp; | 3299 register char *cp; |
3655 | 3300 |
3656 LOOP_ON_INPUT_LINES (inf, lb, cp) | 3301 LOOP_ON_INPUT_LINES (inf, lb, cp) |
3657 { | 3302 { |
3658 /* If first char is alphabetic or one of [_.$], test for colon | 3303 /* If first char is alphabetic or one of [_.$], test for colon |
3659 following identifier. */ | 3304 following identifier. */ |
3660 if (isalpha ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$') | 3305 if (isalpha (*cp) || *cp == '_' || *cp == '.' || *cp == '$') |
3661 { | 3306 { |
3662 /* Read past label. */ | 3307 /* Read past label. */ |
3663 cp++; | 3308 cp++; |
3664 while (isalnum ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$') | 3309 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$') |
3665 cp++; | 3310 cp++; |
3666 if (*cp == ':' || iswhite (*cp)) | 3311 if (*cp == ':' || isspace (*cp)) |
3667 { | 3312 { |
3668 /* Found end of label, so copy it and add it to the table. */ | 3313 /* Found end of label, so copy it and add it to the table. */ |
3669 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE, | 3314 pfnote ((CTAGS) ? savenstr(lb.buffer, cp-lb.buffer) : NULL, TRUE, |
3670 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3315 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3671 } | 3316 } |
3672 } | 3317 } |
3673 } | 3318 } |
3674 } | 3319 } |
3677 * Perl support by Bart Robinson <lomew@cs.utah.edu> | 3322 * Perl support by Bart Robinson <lomew@cs.utah.edu> |
3678 * enhanced by Michael Ernst <mernst@alum.mit.edu> | 3323 * enhanced by Michael Ernst <mernst@alum.mit.edu> |
3679 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/ | 3324 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/ |
3680 * Perl variable names: /^(my|local).../ | 3325 * Perl variable names: /^(my|local).../ |
3681 */ | 3326 */ |
3682 static void | 3327 void |
3683 Perl_functions (inf) | 3328 Perl_functions (inf) |
3684 FILE *inf; | 3329 FILE *inf; |
3685 { | 3330 { |
3686 register char *cp; | 3331 register char *cp; |
3687 | 3332 |
3688 LOOP_ON_INPUT_LINES (inf, lb, cp) | 3333 LOOP_ON_INPUT_LINES (inf, lb, cp) |
3689 { | 3334 { |
3690 if (*cp++ == 's' | 3335 if (*cp++ == 's' |
3691 && *cp++ == 'u' | 3336 && *cp++ == 'u' |
3692 && *cp++ == 'b' && iswhite (*cp++)) | 3337 && *cp++ == 'b' && isspace (*cp++)) |
3693 { | 3338 { |
3694 cp = skip_spaces (cp); | 3339 cp = skip_spaces (cp); |
3695 if (*cp != '\0') | 3340 if (*cp != '\0') |
3696 { | 3341 { |
3697 char *sp = cp; | 3342 char *sp = cp; |
3698 while (*cp != '\0' | 3343 while (*cp != '\0' |
3699 && !iswhite (*cp) && *cp != '{' && *cp != '(') | 3344 && !isspace (*cp) && *cp != '{' && *cp != '(') |
3700 cp++; | 3345 cp++; |
3701 pfnote (savenstr (sp, cp-sp), TRUE, | 3346 pfnote (savenstr (sp, cp-sp), TRUE, |
3702 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3347 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3703 } | 3348 } |
3704 } | 3349 } |
3705 else if (globals /* only if tagging global vars is enabled */ | 3350 else if (globals /* only if tagging global vars is enabled */ |
3706 && ((cp = lb.buffer, | 3351 && ((cp = lb.buffer, |
3707 *cp++ == 'm' | 3352 *cp++ == 'm' |
3708 && *cp++ == 'y') | 3353 && *cp++ == 'y') |
3710 *cp++ == 'l' | 3355 *cp++ == 'l' |
3711 && *cp++ == 'o' | 3356 && *cp++ == 'o' |
3712 && *cp++ == 'c' | 3357 && *cp++ == 'c' |
3713 && *cp++ == 'a' | 3358 && *cp++ == 'a' |
3714 && *cp++ == 'l')) | 3359 && *cp++ == 'l')) |
3715 && (*cp == '(' || iswhite (*cp))) | 3360 && (*cp == '(' || isspace (*cp))) |
3716 { | 3361 { |
3717 /* After "my" or "local", but before any following paren or space. */ | 3362 /* After "my" or "local", but before any following paren or space. */ |
3718 char *varname = NULL; | 3363 char *varname = NULL; |
3719 | 3364 |
3720 cp = skip_spaces (cp); | 3365 cp = skip_spaces (cp); |
3721 if (*cp == '$' || *cp == '@' || *cp == '%') | 3366 if (*cp == '$' || *cp == '@' || *cp == '%') |
3722 { | 3367 { |
3723 char* varstart = ++cp; | 3368 char* varstart = ++cp; |
3724 while (isalnum ((unsigned char) *cp) || *cp == '_') | 3369 while (isalnum (*cp) || *cp == '_') |
3725 cp++; | 3370 cp++; |
3726 varname = savenstr (varstart, cp-varstart); | 3371 varname = savenstr (varstart, cp-varstart); |
3727 } | 3372 } |
3728 else | 3373 else |
3729 { | 3374 { |
3730 /* Should be examining a variable list at this point; | 3375 /* Should be examining a variable list at this point; |
3731 could insist on seeing an open parenthesis. */ | 3376 could insist on seeing an open parenthesis. */ |
3732 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')') | 3377 while (*cp != '\0' && *cp != ';' && *cp != '=' && *cp != ')') |
3733 cp++; | 3378 cp++; |
3734 } | 3379 } |
3735 | 3380 |
3736 /* Perhaps I should back cp up one character, so the TAGS table | 3381 /* Perhaps I should back cp up one character, so the TAGS table |
3737 doesn't mention (and so depend upon) the following char. */ | 3382 doesn't mention (and so depend upon) the following char. */ |
3738 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname, | 3383 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname, |
3739 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3384 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3740 } | 3385 } |
3743 | 3388 |
3744 /* | 3389 /* |
3745 * Python support by Eric S. Raymond <esr@thyrsus.com> | 3390 * Python support by Eric S. Raymond <esr@thyrsus.com> |
3746 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ | 3391 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ |
3747 */ | 3392 */ |
3748 static void | 3393 void |
3749 Python_functions (inf) | 3394 Python_functions (inf) |
3750 FILE *inf; | 3395 FILE *inf; |
3751 { | 3396 { |
3752 register char *cp; | 3397 register char *cp; |
3753 | 3398 |
3754 LOOP_ON_INPUT_LINES (inf, lb, cp) | 3399 LOOP_ON_INPUT_LINES (inf, lb, cp) |
3755 { | 3400 { |
3756 if (*cp++ == 'd' | 3401 if (*cp++ == 'd' |
3757 && *cp++ == 'e' | 3402 && *cp++ == 'e' |
3758 && *cp++ == 'f' && iswhite (*cp++)) | 3403 && *cp++ == 'f' && isspace (*cp++)) |
3759 { | 3404 { |
3760 cp = skip_spaces (cp); | 3405 cp = skip_spaces (cp); |
3761 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') | 3406 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':') |
3762 cp++; | 3407 cp++; |
3763 pfnote (NULL, TRUE, | 3408 pfnote (NULL, TRUE, |
3764 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3409 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3765 } | 3410 } |
3766 | 3411 |
3767 cp = lb.buffer; | 3412 cp = lb.buffer; |
3768 if (*cp++ == 'c' | 3413 if (*cp++ == 'c' |
3769 && *cp++ == 'l' | 3414 && *cp++ == 'l' |
3770 && *cp++ == 'a' | 3415 && *cp++ == 'a' |
3771 && *cp++ == 's' | 3416 && *cp++ == 's' |
3772 && *cp++ == 's' && iswhite (*cp++)) | 3417 && *cp++ == 's' && isspace (*cp++)) |
3773 { | 3418 { |
3774 cp = skip_spaces (cp); | 3419 cp = skip_spaces (cp); |
3775 while (*cp != '\0' && !iswhite (*cp) && *cp != '(' && *cp != ':') | 3420 while (*cp != '\0' && !isspace (*cp) && *cp != '(' && *cp != ':') |
3776 cp++; | 3421 cp++; |
3777 pfnote (NULL, TRUE, | 3422 pfnote (NULL, TRUE, |
3778 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3423 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
3779 } | 3424 } |
3780 } | 3425 } |
3783 /* Idea by Corny de Souza | 3428 /* Idea by Corny de Souza |
3784 * Cobol tag functions | 3429 * Cobol tag functions |
3785 * We could look for anything that could be a paragraph name. | 3430 * We could look for anything that could be a paragraph name. |
3786 * i.e. anything that starts in column 8 is one word and ends in a full stop. | 3431 * i.e. anything that starts in column 8 is one word and ends in a full stop. |
3787 */ | 3432 */ |
3788 static void | 3433 void |
3789 Cobol_paragraphs (inf) | 3434 Cobol_paragraphs (inf) |
3790 FILE *inf; | 3435 FILE *inf; |
3791 { | 3436 { |
3792 register char *bp, *ep; | 3437 register char *bp, *ep; |
3793 | 3438 |
3796 if (lb.len < 9) | 3441 if (lb.len < 9) |
3797 continue; | 3442 continue; |
3798 bp += 8; | 3443 bp += 8; |
3799 | 3444 |
3800 /* If eoln, compiler option or comment ignore whole line. */ | 3445 /* If eoln, compiler option or comment ignore whole line. */ |
3801 if (bp[-1] != ' ' || !isalnum ((unsigned char) bp[0])) | 3446 if (bp[-1] != ' ' || !isalnum (bp[0])) |
3802 continue; | 3447 continue; |
3803 | 3448 |
3804 for (ep = bp; isalnum ((unsigned char) *ep) || *ep == '-'; ep++) | 3449 for (ep = bp; isalnum (*ep) || *ep == '-'; ep++) |
3805 continue; | 3450 continue; |
3806 if (*ep++ == '.') | 3451 if (*ep++ == '.') |
3807 pfnote (savenstr (bp, ep-bp), TRUE, | 3452 pfnote (savenstr (bp, ep-bp), TRUE, |
3808 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); | 3453 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); |
3809 } | 3454 } |
3816 * Locates tags for procedures & functions. Doesn't do any type- or | 3461 * Locates tags for procedures & functions. Doesn't do any type- or |
3817 * var-definitions. It does look for the keyword "extern" or | 3462 * var-definitions. It does look for the keyword "extern" or |
3818 * "forward" immediately following the procedure statement; if found, | 3463 * "forward" immediately following the procedure statement; if found, |
3819 * the tag is skipped. | 3464 * the tag is skipped. |
3820 */ | 3465 */ |
3821 static void | 3466 void |
3822 Pascal_functions (inf) | 3467 Pascal_functions (inf) |
3823 FILE *inf; | 3468 FILE *inf; |
3824 { | 3469 { |
3825 linebuffer tline; /* mostly copied from C_entries */ | 3470 linebuffer tline; /* mostly copied from C_entries */ |
3826 long save_lcno; | 3471 long save_lcno; |
3851 found_tag = FALSE; /* have a proc name; check if extern */ | 3496 found_tag = FALSE; /* have a proc name; check if extern */ |
3852 get_tagname = FALSE; /* have found "procedure" keyword */ | 3497 get_tagname = FALSE; /* have found "procedure" keyword */ |
3853 inparms = FALSE; /* found '(' after "proc" */ | 3498 inparms = FALSE; /* found '(' after "proc" */ |
3854 verify_tag = FALSE; /* check if "extern" is ahead */ | 3499 verify_tag = FALSE; /* check if "extern" is ahead */ |
3855 | 3500 |
3856 | 3501 |
3857 while (!feof (inf)) /* long main loop to get next char */ | 3502 while (!feof (inf)) /* long main loop to get next char */ |
3858 { | 3503 { |
3859 c = *dbp++; | 3504 c = *dbp++; |
3860 if (c == '\0') /* if end of line */ | 3505 if (c == '\0') /* if end of line */ |
3861 { | 3506 { |
3862 lineno++; | 3507 lineno++; |
3993 | 3638 |
3994 /* | 3639 /* |
3995 * lisp tag functions | 3640 * lisp tag functions |
3996 * look for (def or (DEF, quote or QUOTE | 3641 * look for (def or (DEF, quote or QUOTE |
3997 */ | 3642 */ |
3998 | 3643 int |
3999 static int L_isdef P_((char *)); | |
4000 static int L_isquote P_((char *)); | |
4001 static void L_getit P_((void)); | |
4002 | |
4003 static int | |
4004 L_isdef (strp) | 3644 L_isdef (strp) |
4005 register char *strp; | 3645 register char *strp; |
4006 { | 3646 { |
4007 return ((strp[1] == 'd' || strp[1] == 'D') | 3647 return ((strp[1] == 'd' || strp[1] == 'D') |
4008 && (strp[2] == 'e' || strp[2] == 'E') | 3648 && (strp[2] == 'e' || strp[2] == 'E') |
4009 && (strp[3] == 'f' || strp[3] == 'F')); | 3649 && (strp[3] == 'f' || strp[3] == 'F')); |
4010 } | 3650 } |
4011 | 3651 |
4012 static int | 3652 int |
4013 L_isquote (strp) | 3653 L_isquote (strp) |
4014 register char *strp; | 3654 register char *strp; |
4015 { | 3655 { |
4016 return ((*++strp == 'q' || *strp == 'Q') | 3656 return ((*++strp == 'q' || *strp == 'Q') |
4017 && (*++strp == 'u' || *strp == 'U') | 3657 && (*++strp == 'u' || *strp == 'U') |
4018 && (*++strp == 'o' || *strp == 'O') | 3658 && (*++strp == 'o' || *strp == 'O') |
4019 && (*++strp == 't' || *strp == 'T') | 3659 && (*++strp == 't' || *strp == 'T') |
4020 && (*++strp == 'e' || *strp == 'E') | 3660 && (*++strp == 'e' || *strp == 'E') |
4021 && iswhite (*++strp)); | 3661 && isspace (*++strp)); |
4022 } | 3662 } |
4023 | 3663 |
4024 static void | 3664 void |
4025 L_getit () | 3665 L_getit () |
4026 { | 3666 { |
4027 register char *cp; | 3667 register char *cp; |
4028 | 3668 |
4029 if (*dbp == '\'') /* Skip prefix quote */ | 3669 if (*dbp == '\'') /* Skip prefix quote */ |
4036 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */ | 3676 dbp += 1; /* Skip "(" before name in (defstruct (foo)) */ |
4037 dbp = skip_spaces (dbp); | 3677 dbp = skip_spaces (dbp); |
4038 } | 3678 } |
4039 | 3679 |
4040 for (cp = dbp /*+1*/; | 3680 for (cp = dbp /*+1*/; |
4041 *cp != '\0' && *cp != '(' && !iswhite(*cp) && *cp != ')'; | 3681 *cp != '\0' && *cp != '(' && *cp != ' ' && *cp != ')'; |
4042 cp++) | 3682 cp++) |
4043 continue; | 3683 continue; |
4044 if (cp == dbp) | 3684 if (cp == dbp) |
4045 return; | 3685 return; |
4046 | 3686 |
4047 pfnote (savenstr (dbp, cp-dbp), TRUE, | 3687 pfnote (savenstr (dbp, cp-dbp), TRUE, |
4048 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | 3688 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); |
4049 } | 3689 } |
4050 | 3690 |
4051 static void | 3691 void |
4052 Lisp_functions (inf) | 3692 Lisp_functions (inf) |
4053 FILE *inf; | 3693 FILE *inf; |
4054 { | 3694 { |
4055 LOOP_ON_INPUT_LINES (inf, lb, dbp) | 3695 LOOP_ON_INPUT_LINES (inf, lb, dbp) |
4056 { | 3696 { |
4065 else | 3705 else |
4066 { | 3706 { |
4067 /* Check for (foo::defmumble name-defined ... */ | 3707 /* Check for (foo::defmumble name-defined ... */ |
4068 do | 3708 do |
4069 dbp++; | 3709 dbp++; |
4070 while (*dbp != '\0' && !iswhite (*dbp) | 3710 while (*dbp != '\0' && !isspace (*dbp) |
4071 && *dbp != ':' && *dbp != '(' && *dbp != ')'); | 3711 && *dbp != ':' && *dbp != '(' && *dbp != ')'); |
4072 if (*dbp == ':') | 3712 if (*dbp == ':') |
4073 { | 3713 { |
4074 do | 3714 do |
4075 dbp++; | 3715 dbp++; |
4089 | 3729 |
4090 /* | 3730 /* |
4091 * Postscript tag functions | 3731 * Postscript tag functions |
4092 * Just look for lines where the first character is '/' | 3732 * Just look for lines where the first character is '/' |
4093 * Richard Mlynarik <mly@adoc.xerox.com> | 3733 * Richard Mlynarik <mly@adoc.xerox.com> |
4094 * Also look at "defineps" for PSWrap | 3734 */ |
4095 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp> | 3735 void |
4096 */ | |
4097 static void | |
4098 Postscript_functions (inf) | 3736 Postscript_functions (inf) |
4099 FILE *inf; | 3737 FILE *inf; |
4100 { | 3738 { |
4101 register char *bp, *ep; | 3739 register char *bp, *ep; |
4102 | 3740 |
4106 { | 3744 { |
4107 for (ep = bp+1; | 3745 for (ep = bp+1; |
4108 *ep != '\0' && *ep != ' ' && *ep != '{'; | 3746 *ep != '\0' && *ep != ' ' && *ep != '{'; |
4109 ep++) | 3747 ep++) |
4110 continue; | 3748 continue; |
4111 pfnote (savenstr (bp, ep-bp), TRUE, | 3749 pfnote ((CTAGS) ? savenstr (bp, ep-bp) : NULL, TRUE, |
4112 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); | 3750 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); |
4113 } | |
4114 else if (strneq (bp, "defineps", 8)) | |
4115 { | |
4116 bp = skip_non_spaces (bp); | |
4117 bp = skip_spaces (bp); | |
4118 get_tag (bp); | |
4119 } | 3751 } |
4120 } | 3752 } |
4121 } | 3753 } |
4122 | 3754 |
4123 | 3755 |
4127 * look for (def... (xyzzy | 3759 * look for (def... (xyzzy |
4128 * look for (def ... ((...(xyzzy .... | 3760 * look for (def ... ((...(xyzzy .... |
4129 * look for (set! xyzzy | 3761 * look for (set! xyzzy |
4130 */ | 3762 */ |
4131 | 3763 |
4132 static void | 3764 void get_scheme (); |
3765 | |
3766 void | |
4133 Scheme_functions (inf) | 3767 Scheme_functions (inf) |
4134 FILE *inf; | 3768 FILE *inf; |
4135 { | 3769 { |
4136 register char *bp; | 3770 LOOP_ON_INPUT_LINES (inf, lb, dbp) |
4137 | 3771 { |
4138 LOOP_ON_INPUT_LINES (inf, lb, bp) | 3772 if (dbp[0] == '(' |
4139 { | 3773 && (dbp[1] == 'D' || dbp[1] == 'd') |
4140 if (bp[0] == '(' | 3774 && (dbp[2] == 'E' || dbp[2] == 'e') |
4141 && (bp[1] == 'D' || bp[1] == 'd') | 3775 && (dbp[3] == 'F' || dbp[3] == 'f')) |
4142 && (bp[2] == 'E' || bp[2] == 'e') | 3776 { |
4143 && (bp[3] == 'F' || bp[3] == 'f')) | 3777 dbp = skip_non_spaces (dbp); |
4144 { | |
4145 bp = skip_non_spaces (bp); | |
4146 /* Skip over open parens and white space */ | 3778 /* Skip over open parens and white space */ |
4147 while (iswhite (*bp) || *bp == '(') | 3779 while (isspace (*dbp) || *dbp == '(') |
4148 bp++; | 3780 dbp++; |
4149 get_tag (bp); | 3781 get_scheme (); |
4150 } | 3782 } |
4151 if (bp[0] == '(' | 3783 if (dbp[0] == '(' |
4152 && (bp[1] == 'S' || bp[1] == 's') | 3784 && (dbp[1] == 'S' || dbp[1] == 's') |
4153 && (bp[2] == 'E' || bp[2] == 'e') | 3785 && (dbp[2] == 'E' || dbp[2] == 'e') |
4154 && (bp[3] == 'T' || bp[3] == 't') | 3786 && (dbp[3] == 'T' || dbp[3] == 't') |
4155 && (bp[4] == '!' || bp[4] == '!') | 3787 && (dbp[4] == '!' || dbp[4] == '!') |
4156 && (iswhite (bp[5]))) | 3788 && (isspace (dbp[5]))) |
4157 { | 3789 { |
4158 bp = skip_non_spaces (bp); | 3790 dbp = skip_non_spaces (dbp); |
4159 bp = skip_spaces (bp); | 3791 dbp = skip_spaces (dbp); |
4160 get_tag (bp); | 3792 get_scheme (); |
4161 } | 3793 } |
4162 } | 3794 } |
3795 } | |
3796 | |
3797 void | |
3798 get_scheme () | |
3799 { | |
3800 register char *cp; | |
3801 | |
3802 if (*dbp == '\0') | |
3803 return; | |
3804 /* Go till you get to white space or a syntactic break */ | |
3805 for (cp = dbp + 1; | |
3806 *cp != '\0' && *cp != '(' && *cp != ')' && !isspace (*cp); | |
3807 cp++) | |
3808 continue; | |
3809 pfnote (savenstr (dbp, cp-dbp), TRUE, | |
3810 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | |
4163 } | 3811 } |
4164 | 3812 |
4165 /* Find tags in TeX and LaTeX input files. */ | 3813 /* Find tags in TeX and LaTeX input files. */ |
4166 | 3814 |
4167 /* TEX_toktab is a table of TeX control sequences that define tags. | 3815 /* TEX_toktab is a table of TeX control sequences that define tags. |
4180 | 3828 |
4181 char *TEX_defenv = "\ | 3829 char *TEX_defenv = "\ |
4182 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ | 3830 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem\ |
4183 :part:appendix:entry:index"; | 3831 :part:appendix:entry:index"; |
4184 | 3832 |
4185 static void TEX_mode P_((FILE *)); | 3833 void TEX_mode (); |
4186 static struct TEX_tabent *TEX_decode_env P_((char *, char *)); | 3834 struct TEX_tabent *TEX_decode_env (); |
4187 static int TEX_Token P_((char *)); | 3835 int TEX_Token (); |
4188 | 3836 |
4189 char TEX_esc = '\\'; | 3837 char TEX_esc = '\\'; |
4190 char TEX_opgrp = '{'; | 3838 char TEX_opgrp = '{'; |
4191 char TEX_clgrp = '}'; | 3839 char TEX_clgrp = '}'; |
4192 | 3840 |
4193 /* | 3841 /* |
4194 * TeX/LaTeX scanning loop. | 3842 * TeX/LaTeX scanning loop. |
4195 */ | 3843 */ |
4196 static void | 3844 void |
4197 TeX_functions (inf) | 3845 TeX_functions (inf) |
4198 FILE *inf; | 3846 FILE *inf; |
4199 { | 3847 { |
4200 char *cp, *lasthit; | 3848 char *cp, *lasthit; |
4201 register int i; | 3849 register int i; |
4238 #define TEX_SESC '!' | 3886 #define TEX_SESC '!' |
4239 #define TEX_cmt '%' | 3887 #define TEX_cmt '%' |
4240 | 3888 |
4241 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping | 3889 /* Figure out whether TeX's escapechar is '\\' or '!' and set grouping |
4242 chars accordingly. */ | 3890 chars accordingly. */ |
4243 static void | 3891 void |
4244 TEX_mode (inf) | 3892 TEX_mode (inf) |
4245 FILE *inf; | 3893 FILE *inf; |
4246 { | 3894 { |
4247 int c; | 3895 int c; |
4248 | 3896 |
4273 rewind (inf); | 3921 rewind (inf); |
4274 } | 3922 } |
4275 | 3923 |
4276 /* Read environment and prepend it to the default string. | 3924 /* Read environment and prepend it to the default string. |
4277 Build token table. */ | 3925 Build token table. */ |
4278 static struct TEX_tabent * | 3926 struct TEX_tabent * |
4279 TEX_decode_env (evarname, defenv) | 3927 TEX_decode_env (evarname, defenv) |
4280 char *evarname; | 3928 char *evarname; |
4281 char *defenv; | 3929 char *defenv; |
4282 { | 3930 { |
4283 register char *env, *p; | 3931 register char *env, *p; |
4330 /* If the text at CP matches one of the tag-defining TeX command names, | 3978 /* If the text at CP matches one of the tag-defining TeX command names, |
4331 return the pointer to the first occurrence of that command in TEX_toktab. | 3979 return the pointer to the first occurrence of that command in TEX_toktab. |
4332 Otherwise return -1. | 3980 Otherwise return -1. |
4333 Keep the capital `T' in `token' for dumb truncating compilers | 3981 Keep the capital `T' in `token' for dumb truncating compilers |
4334 (this distinguishes it from `TEX_toktab' */ | 3982 (this distinguishes it from `TEX_toktab' */ |
4335 static int | 3983 int |
4336 TEX_Token (cp) | 3984 TEX_Token (cp) |
4337 char *cp; | 3985 char *cp; |
4338 { | 3986 { |
4339 int i; | 3987 int i; |
4340 | 3988 |
4346 | 3994 |
4347 /* | 3995 /* |
4348 * Prolog support (rewritten) by Anders Lindgren, Mar. 96 | 3996 * Prolog support (rewritten) by Anders Lindgren, Mar. 96 |
4349 * | 3997 * |
4350 * Assumes that the predicate starts at column 0. | 3998 * Assumes that the predicate starts at column 0. |
4351 * Only the first clause of a predicate is added. | 3999 * Only the first clause of a predicate is added. |
4352 */ | 4000 */ |
4353 static int prolog_pred P_((char *, char *)); | 4001 int prolog_pred (); |
4354 static void prolog_skip_comment P_((linebuffer *, FILE *)); | 4002 void prolog_skip_comment (); |
4355 static int prolog_atom P_((char *, int)); | 4003 int prolog_atom (); |
4356 | 4004 |
4357 static void | 4005 void |
4358 Prolog_functions (inf) | 4006 Prolog_functions (inf) |
4359 FILE *inf; | 4007 FILE *inf; |
4360 { | 4008 { |
4361 char *cp, *last; | 4009 char *cp, *last; |
4362 int len; | 4010 int len; |
4368 | 4016 |
4369 LOOP_ON_INPUT_LINES (inf, lb, cp) | 4017 LOOP_ON_INPUT_LINES (inf, lb, cp) |
4370 { | 4018 { |
4371 if (cp[0] == '\0') /* Empty line */ | 4019 if (cp[0] == '\0') /* Empty line */ |
4372 continue; | 4020 continue; |
4373 else if (iswhite (cp[0])) /* Not a predicate */ | 4021 else if (isspace (cp[0])) /* Not a predicate */ |
4374 continue; | 4022 continue; |
4375 else if (cp[0] == '/' && cp[1] == '*') /* comment. */ | 4023 else if (cp[0] == '/' && cp[1] == '*') /* comment. */ |
4376 prolog_skip_comment (&lb, inf); | 4024 prolog_skip_comment (&lb, inf); |
4377 else if ((len = prolog_pred (cp, last)) > 0) | 4025 else if ((len = prolog_pred (cp, last)) > 0) |
4378 { | 4026 { |
4388 } | 4036 } |
4389 } | 4037 } |
4390 } | 4038 } |
4391 | 4039 |
4392 | 4040 |
4393 static void | 4041 void |
4394 prolog_skip_comment (plb, inf) | 4042 prolog_skip_comment (plb, inf) |
4395 linebuffer *plb; | 4043 linebuffer *plb; |
4396 FILE *inf; | 4044 FILE *inf; |
4397 { | 4045 { |
4398 char *cp; | 4046 char *cp; |
4416 * name of the previous clause header. | 4064 * name of the previous clause header. |
4417 * | 4065 * |
4418 * Return the size of the name of the predicate, or 0 if no header | 4066 * Return the size of the name of the predicate, or 0 if no header |
4419 * was found. | 4067 * was found. |
4420 */ | 4068 */ |
4421 static int | 4069 int |
4422 prolog_pred (s, last) | 4070 prolog_pred (s, last) |
4423 char *s; | 4071 char *s; |
4424 char *last; /* Name of last clause. */ | 4072 char *last; /* Name of last clause. */ |
4425 { | 4073 { |
4426 int pos; | 4074 int pos; |
4441 /* Save only the first clause. */ | 4089 /* Save only the first clause. */ |
4442 if (last == NULL | 4090 if (last == NULL |
4443 || len != (int)strlen (last) | 4091 || len != (int)strlen (last) |
4444 || !strneq (s, last, len)) | 4092 || !strneq (s, last, len)) |
4445 { | 4093 { |
4446 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); | 4094 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE, |
4095 s, pos, lineno, linecharno); | |
4447 return len; | 4096 return len; |
4448 } | 4097 } |
4449 } | 4098 } |
4450 return 0; | 4099 return 0; |
4451 } | 4100 } |
4457 * A prolog atom, in this context, could be one of: | 4106 * A prolog atom, in this context, could be one of: |
4458 * - An alphanumeric sequence, starting with a lower case letter. | 4107 * - An alphanumeric sequence, starting with a lower case letter. |
4459 * - A quoted arbitrary string. Single quotes can escape themselves. | 4108 * - A quoted arbitrary string. Single quotes can escape themselves. |
4460 * Backslash quotes everything. | 4109 * Backslash quotes everything. |
4461 */ | 4110 */ |
4462 static int | 4111 int |
4463 prolog_atom (s, pos) | 4112 prolog_atom (s, pos) |
4464 char *s; | 4113 char *s; |
4465 int pos; | 4114 int pos; |
4466 { | 4115 { |
4467 int origpos; | 4116 int origpos; |
4468 | 4117 |
4469 origpos = pos; | 4118 origpos = pos; |
4470 | 4119 |
4471 if (islower((unsigned char) s[pos]) || (s[pos] == '_')) | 4120 if (islower(s[pos]) || (s[pos] == '_')) |
4472 { | 4121 { |
4473 /* The atom is unquoted. */ | 4122 /* The atom is unquoted. */ |
4474 pos++; | 4123 pos++; |
4475 while (isalnum((unsigned char) s[pos]) || (s[pos] == '_')) | 4124 while (isalnum(s[pos]) || (s[pos] == '_')) |
4476 { | 4125 { |
4477 pos++; | 4126 pos++; |
4478 } | 4127 } |
4479 return pos - origpos; | 4128 return pos - origpos; |
4480 } | 4129 } |
4481 else if (s[pos] == '\'') | 4130 else if (s[pos] == '\'') |
4482 { | 4131 { |
4483 pos++; | 4132 pos++; |
4484 | 4133 |
4485 while (1) | 4134 while (1) |
4486 { | 4135 { |
4487 if (s[pos] == '\'') | 4136 if (s[pos] == '\'') |
4488 { | 4137 { |
4489 pos++; | 4138 pos++; |
4490 if (s[pos] != '\'') | 4139 if (s[pos] != '\'') |
4507 } | 4156 } |
4508 else | 4157 else |
4509 return -1; | 4158 return -1; |
4510 } | 4159 } |
4511 | 4160 |
4512 /* | 4161 /* |
4513 * Support for Erlang -- Anders Lindgren, Feb 1996. | 4162 * Support for Erlang -- Anders Lindgren, Feb 1996. |
4514 * | 4163 * |
4515 * Generates tags for functions, defines, and records. | 4164 * Generates tags for functions, defines, and records. |
4516 * | 4165 * |
4517 * Assumes that Erlang functions start at column 0. | 4166 * Assumes that Erlang functions start at column 0. |
4518 */ | 4167 */ |
4519 static int erlang_func P_((char *, char *)); | 4168 int erlang_func (); |
4520 static void erlang_attribute P_((char *)); | 4169 void erlang_attribute (); |
4521 static int erlang_atom P_((char *, int)); | 4170 int erlang_atom (); |
4522 | 4171 |
4523 static void | 4172 void |
4524 Erlang_functions (inf) | 4173 Erlang_functions (inf) |
4525 FILE *inf; | 4174 FILE *inf; |
4526 { | 4175 { |
4527 char *cp, *last; | 4176 char *cp, *last; |
4528 int len; | 4177 int len; |
4534 | 4183 |
4535 LOOP_ON_INPUT_LINES (inf, lb, cp) | 4184 LOOP_ON_INPUT_LINES (inf, lb, cp) |
4536 { | 4185 { |
4537 if (cp[0] == '\0') /* Empty line */ | 4186 if (cp[0] == '\0') /* Empty line */ |
4538 continue; | 4187 continue; |
4539 else if (iswhite (cp[0])) /* Not function nor attribute */ | 4188 else if (isspace (cp[0])) /* Not function nor attribute */ |
4540 continue; | 4189 continue; |
4541 else if (cp[0] == '%') /* comment */ | 4190 else if (cp[0] == '%') /* comment */ |
4542 continue; | 4191 continue; |
4543 else if (cp[0] == '"') /* Sometimes, strings start in column one */ | 4192 else if (cp[0] == '"') /* Sometimes, strings start in column one */ |
4544 continue; | 4193 continue; |
4547 erlang_attribute (cp); | 4196 erlang_attribute (cp); |
4548 last = NULL; | 4197 last = NULL; |
4549 } | 4198 } |
4550 else if ((len = erlang_func (cp, last)) > 0) | 4199 else if ((len = erlang_func (cp, last)) > 0) |
4551 { | 4200 { |
4552 /* | 4201 /* |
4553 * Function. Store the function name so that we only | 4202 * Function. Store the function name so that we only |
4554 * generates a tag for the first clause. | 4203 * generates a tag for the first clause. |
4555 */ | 4204 */ |
4556 if (last == NULL) | 4205 if (last == NULL) |
4557 last = xnew (len + 1, char); | 4206 last = xnew (len + 1, char); |
4573 * name of the previous clause header. | 4222 * name of the previous clause header. |
4574 * | 4223 * |
4575 * Return the size of the name of the function, or 0 if no function | 4224 * Return the size of the name of the function, or 0 if no function |
4576 * was found. | 4225 * was found. |
4577 */ | 4226 */ |
4578 static int | 4227 int |
4579 erlang_func (s, last) | 4228 erlang_func (s, last) |
4580 char *s; | 4229 char *s; |
4581 char *last; /* Name of last clause. */ | 4230 char *last; /* Name of last clause. */ |
4582 { | 4231 { |
4583 int pos; | 4232 int pos; |
4594 if (s[pos++] == '(' | 4243 if (s[pos++] == '(' |
4595 && (last == NULL | 4244 && (last == NULL |
4596 || len != (int)strlen (last) | 4245 || len != (int)strlen (last) |
4597 || !strneq (s, last, len))) | 4246 || !strneq (s, last, len))) |
4598 { | 4247 { |
4599 pfnote (savenstr (s, len), TRUE, s, pos, lineno, linecharno); | 4248 pfnote ((CTAGS) ? savenstr (s, len) : NULL, TRUE, |
4249 s, pos, lineno, linecharno); | |
4600 return len; | 4250 return len; |
4601 } | 4251 } |
4602 | 4252 |
4603 return 0; | 4253 return 0; |
4604 } | 4254 } |
4605 | 4255 |
4606 | 4256 |
4607 /* | 4257 /* |
4608 * Handle attributes. Currently, tags are generated for defines | 4258 * Handle attributes. Currently, tags are generated for defines |
4609 * and records. | 4259 * and records. |
4610 * | 4260 * |
4611 * They are on the form: | 4261 * They are on the form: |
4612 * -define(foo, bar). | 4262 * -define(foo, bar). |
4613 * -define(Foo(M, N), M+N). | 4263 * -define(Foo(M, N), M+N). |
4614 * -record(graph, {vtab = notable, cyclic = true}). | 4264 * -record(graph, {vtab = notable, cyclic = true}). |
4615 */ | 4265 */ |
4616 static void | 4266 void |
4617 erlang_attribute (s) | 4267 erlang_attribute (s) |
4618 char *s; | 4268 char *s; |
4619 { | 4269 { |
4620 int pos; | 4270 int pos; |
4621 int len; | 4271 int len; |
4622 | 4272 |
4623 if (strneq (s, "-define", 7) || strneq (s, "-record", 7)) | 4273 if (strneq (s, "-define", 7) || strneq (s, "-record", 7)) |
4624 { | 4274 { |
4625 pos = skip_spaces (s + 7) - s; | 4275 pos = skip_spaces (s + 7) - s; |
4626 if (s[pos++] == '(') | 4276 if (s[pos++] == '(') |
4627 { | 4277 { |
4628 pos = skip_spaces (s + pos) - s; | 4278 pos = skip_spaces (s + pos) - s; |
4629 len = erlang_atom (s, pos); | 4279 len = erlang_atom (s, pos); |
4630 if (len != 0) | 4280 if (len != 0) |
4631 pfnote (savenstr (& s[pos], len), TRUE, | 4281 pfnote ((CTAGS) ? savenstr (& s[pos], len) : NULL, TRUE, |
4632 s, pos + len, lineno, linecharno); | 4282 s, pos + len, lineno, linecharno); |
4633 } | 4283 } |
4634 } | 4284 } |
4635 return; | 4285 return; |
4636 } | 4286 } |
4638 | 4288 |
4639 /* | 4289 /* |
4640 * Consume an Erlang atom (or variable). | 4290 * Consume an Erlang atom (or variable). |
4641 * Return the number of bytes consumed, or -1 if there was an error. | 4291 * Return the number of bytes consumed, or -1 if there was an error. |
4642 */ | 4292 */ |
4643 static int | 4293 int |
4644 erlang_atom (s, pos) | 4294 erlang_atom (s, pos) |
4645 char *s; | 4295 char *s; |
4646 int pos; | 4296 int pos; |
4647 { | 4297 { |
4648 int origpos; | 4298 int origpos; |
4649 | 4299 |
4650 origpos = pos; | 4300 origpos = pos; |
4651 | 4301 |
4652 if (isalpha ((unsigned char) s[pos]) || s[pos] == '_') | 4302 if (isalpha (s[pos]) || s[pos] == '_') |
4653 { | 4303 { |
4654 /* The atom is unquoted. */ | 4304 /* The atom is unquoted. */ |
4655 pos++; | 4305 pos++; |
4656 while (isalnum ((unsigned char) s[pos]) || s[pos] == '_') | 4306 while (isalnum (s[pos]) || s[pos] == '_') |
4657 pos++; | 4307 pos++; |
4658 return pos - origpos; | 4308 return pos - origpos; |
4659 } | 4309 } |
4660 else if (s[pos] == '\'') | 4310 else if (s[pos] == '\'') |
4661 { | 4311 { |
4662 pos++; | 4312 pos++; |
4663 | 4313 |
4664 while (1) | 4314 while (1) |
4665 { | 4315 { |
4666 if (s[pos] == '\'') | 4316 if (s[pos] == '\'') |
4667 { | 4317 { |
4668 pos++; | 4318 pos++; |
4669 break; | 4319 break; |
4686 return -1; | 4336 return -1; |
4687 } | 4337 } |
4688 | 4338 |
4689 #ifdef ETAGS_REGEXPS | 4339 #ifdef ETAGS_REGEXPS |
4690 | 4340 |
4691 static char *scan_separators P_((char *)); | |
4692 static void analyse_regex P_((char *, bool)); | |
4693 static void add_regex P_((char *, bool, language *)); | |
4694 static char *substitute P_((char *, char *, struct re_registers *)); | |
4695 | |
4696 /* Take a string like "/blah/" and turn it into "blah", making sure | 4341 /* Take a string like "/blah/" and turn it into "blah", making sure |
4697 that the first and last characters are the same, and handling | 4342 that the first and last characters are the same, and handling |
4698 quoted separator characters. Actually, stops on the occurrence of | 4343 quoted separator characters. Actually, stops on the occurrence of |
4699 an unquoted separator. Also turns "\t" into a Tab character. | 4344 an unquoted separator. Also turns "\t" into a Tab character. |
4700 Returns pointer to terminating separator. Works in place. Null | 4345 Returns pointer to terminating separator. Works in place. Null |
4701 terminates name string. */ | 4346 terminates name string. */ |
4702 static char * | 4347 char * |
4703 scan_separators (name) | 4348 scan_separators (name) |
4704 char *name; | 4349 char *name; |
4705 { | 4350 { |
4706 char sep = name[0]; | 4351 char sep = name[0]; |
4707 char *copyto = name; | 4352 char *copyto = name; |
4736 return name; | 4381 return name; |
4737 } | 4382 } |
4738 | 4383 |
4739 /* Look at the argument of --regex or --no-regex and do the right | 4384 /* Look at the argument of --regex or --no-regex and do the right |
4740 thing. Same for each line of a regexp file. */ | 4385 thing. Same for each line of a regexp file. */ |
4741 static void | 4386 void |
4742 analyse_regex (regex_arg, ignore_case) | 4387 analyse_regex (regex_arg) |
4743 char *regex_arg; | 4388 char *regex_arg; |
4744 bool ignore_case; | |
4745 { | 4389 { |
4746 if (regex_arg == NULL) | 4390 if (regex_arg == NULL) |
4747 free_patterns (); /* --no-regex: remove existing regexps */ | 4391 free_patterns (); /* --no-regex: remove existing regexps */ |
4748 | 4392 |
4749 /* A real --regexp option or a line in a regexp file. */ | 4393 /* A real --regexp option or a line in a regexp file. */ |
4770 pfatal (regexfile); | 4414 pfatal (regexfile); |
4771 return; | 4415 return; |
4772 } | 4416 } |
4773 initbuffer (®exbuf); | 4417 initbuffer (®exbuf); |
4774 while (readline_internal (®exbuf, regexfp) > 0) | 4418 while (readline_internal (®exbuf, regexfp) > 0) |
4775 analyse_regex (regexbuf.buffer, ignore_case); | 4419 analyse_regex (regexbuf.buffer); |
4776 free (regexbuf.buffer); | 4420 free (regexbuf.buffer); |
4777 fclose (regexfp); | 4421 fclose (regexfp); |
4778 } | 4422 } |
4779 break; | 4423 break; |
4780 | 4424 |
4793 } | 4437 } |
4794 *cp = '\0'; | 4438 *cp = '\0'; |
4795 lang = get_language_from_name (lang_name); | 4439 lang = get_language_from_name (lang_name); |
4796 if (lang == NULL) | 4440 if (lang == NULL) |
4797 return; | 4441 return; |
4798 add_regex (cp + 1, ignore_case, lang); | 4442 add_regex (cp + 1, lang); |
4799 } | 4443 } |
4800 break; | 4444 break; |
4801 | 4445 |
4802 /* Regexp to be used for any language. */ | 4446 /* Regexp to be used for any language. */ |
4803 default: | 4447 default: |
4804 add_regex (regex_arg, ignore_case, NULL); | 4448 add_regex (regex_arg, NULL); |
4805 break; | 4449 break; |
4806 } | 4450 } |
4807 } | 4451 } |
4808 | 4452 |
4809 /* Turn a name, which is an ed-style (but Emacs syntax) regular | 4453 /* Turn a name, which is an ed-style (but Emacs syntax) regular |
4810 expression, into a real regular expression by compiling it. */ | 4454 expression, into a real regular expression by compiling it. */ |
4811 static void | 4455 void |
4812 add_regex (regexp_pattern, ignore_case, lang) | 4456 add_regex (regexp_pattern, lang) |
4813 char *regexp_pattern; | 4457 char *regexp_pattern; |
4814 bool ignore_case; | |
4815 language *lang; | 4458 language *lang; |
4816 { | 4459 { |
4817 char *name; | 4460 char *name; |
4818 const char *err; | 4461 const char *err; |
4819 struct re_pattern_buffer *patbuf; | 4462 struct re_pattern_buffer *patbuf; |
4832 return; | 4475 return; |
4833 } | 4476 } |
4834 (void) scan_separators (name); | 4477 (void) scan_separators (name); |
4835 | 4478 |
4836 patbuf = xnew (1, struct re_pattern_buffer); | 4479 patbuf = xnew (1, struct re_pattern_buffer); |
4837 /* Translation table to fold case if appropriate. */ | 4480 patbuf->translate = NULL; |
4838 patbuf->translate = (ignore_case) ? lc_trans : NULL; | |
4839 patbuf->fastmap = NULL; | 4481 patbuf->fastmap = NULL; |
4840 patbuf->buffer = NULL; | 4482 patbuf->buffer = NULL; |
4841 patbuf->allocated = 0; | 4483 patbuf->allocated = 0; |
4842 | 4484 |
4843 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); | 4485 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); |
4859 | 4501 |
4860 /* | 4502 /* |
4861 * Do the substitutions indicated by the regular expression and | 4503 * Do the substitutions indicated by the regular expression and |
4862 * arguments. | 4504 * arguments. |
4863 */ | 4505 */ |
4864 static char * | 4506 char * |
4865 substitute (in, out, regs) | 4507 substitute (in, out, regs) |
4866 char *in, *out; | 4508 char *in, *out; |
4867 struct re_registers *regs; | 4509 struct re_registers *regs; |
4868 { | 4510 { |
4869 char *result, *t; | 4511 char *result, *t; |
4876 if (out[size - 1] == '\\') | 4518 if (out[size - 1] == '\\') |
4877 fatal ("pattern error in \"%s\"", out); | 4519 fatal ("pattern error in \"%s\"", out); |
4878 for (t = etags_strchr (out, '\\'); | 4520 for (t = etags_strchr (out, '\\'); |
4879 t != NULL; | 4521 t != NULL; |
4880 t = etags_strchr (t + 2, '\\')) | 4522 t = etags_strchr (t + 2, '\\')) |
4881 if (isdigit ((unsigned char) t[1])) | 4523 if (isdigit (t[1])) |
4882 { | 4524 { |
4883 dig = t[1] - '0'; | 4525 dig = t[1] - '0'; |
4884 diglen = regs->end[dig] - regs->start[dig]; | 4526 diglen = regs->end[dig] - regs->start[dig]; |
4885 size += diglen - 2; | 4527 size += diglen - 2; |
4886 } | 4528 } |
4889 | 4531 |
4890 /* Allocate space and do the substitutions. */ | 4532 /* Allocate space and do the substitutions. */ |
4891 result = xnew (size + 1, char); | 4533 result = xnew (size + 1, char); |
4892 | 4534 |
4893 for (t = result; *out != '\0'; out++) | 4535 for (t = result; *out != '\0'; out++) |
4894 if (*out == '\\' && isdigit ((unsigned char) *++out)) | 4536 if (*out == '\\' && isdigit (*++out)) |
4895 { | 4537 { |
4896 /* Using "dig2" satisfies my debugger. Bleah. */ | 4538 /* Using "dig2" satisfies my debugger. Bleah. */ |
4897 dig = *out - '0'; | 4539 dig = *out - '0'; |
4898 diglen = regs->end[dig] - regs->start[dig]; | 4540 diglen = regs->end[dig] - regs->start[dig]; |
4899 strncpy (t, in + regs->start[dig], diglen); | 4541 strncpy (t, in + regs->start[dig], diglen); |
4908 | 4550 |
4909 return result; | 4551 return result; |
4910 } | 4552 } |
4911 | 4553 |
4912 /* Deallocate all patterns. */ | 4554 /* Deallocate all patterns. */ |
4913 static void | 4555 void |
4914 free_patterns () | 4556 free_patterns () |
4915 { | 4557 { |
4916 pattern *pp; | 4558 pattern *pp; |
4917 while (p_head != NULL) | 4559 while (p_head != NULL) |
4918 { | 4560 { |
4923 p_head = pp; | 4565 p_head = pp; |
4924 } | 4566 } |
4925 return; | 4567 return; |
4926 } | 4568 } |
4927 | 4569 |
4928 static void | |
4929 get_tag (bp) | |
4930 register char *bp; | |
4931 { | |
4932 register char *cp; | |
4933 | |
4934 if (*bp == '\0') | |
4935 return; | |
4936 /* Go till you get to white space or a syntactic break */ | |
4937 for (cp = bp + 1; | |
4938 *cp != '\0' && *cp != '(' && *cp != ')' && !iswhite (*cp); | |
4939 cp++) | |
4940 continue; | |
4941 pfnote (savenstr (bp, cp-bp), TRUE, | |
4942 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); | |
4943 } | |
4944 | |
4945 #endif /* ETAGS_REGEXPS */ | 4570 #endif /* ETAGS_REGEXPS */ |
4946 /* Initialize a linebuffer for use */ | 4571 /* Initialize a linebuffer for use */ |
4947 static void | 4572 void |
4948 initbuffer (lbp) | 4573 initbuffer (lbp) |
4949 linebuffer *lbp; | 4574 linebuffer *lbp; |
4950 { | 4575 { |
4951 lbp->size = 200; | 4576 lbp->size = 200; |
4952 lbp->buffer = xnew (200, char); | 4577 lbp->buffer = xnew (200, char); |
4960 * On DOS or Windows we do not count the CR character, if any, before the | 4585 * On DOS or Windows we do not count the CR character, if any, before the |
4961 * NL, in the returned length; this mirrors the behavior of emacs on those | 4586 * NL, in the returned length; this mirrors the behavior of emacs on those |
4962 * platforms (for text files, it translates CR-NL to NL as it reads in the | 4587 * platforms (for text files, it translates CR-NL to NL as it reads in the |
4963 * file). | 4588 * file). |
4964 */ | 4589 */ |
4965 static long | 4590 long |
4966 readline_internal (lbp, stream) | 4591 readline_internal (lbp, stream) |
4967 linebuffer *lbp; | 4592 linebuffer *lbp; |
4968 register FILE *stream; | 4593 register FILE *stream; |
4969 { | 4594 { |
4970 char *buffer = lbp->buffer; | 4595 char *buffer = lbp->buffer; |
4995 if (c == '\n') | 4620 if (c == '\n') |
4996 { | 4621 { |
4997 if (p > buffer && p[-1] == '\r') | 4622 if (p > buffer && p[-1] == '\r') |
4998 { | 4623 { |
4999 p -= 1; | 4624 p -= 1; |
5000 #ifdef WIN32_NATIVE | 4625 #ifdef DOS_NT |
5001 /* Assume CRLF->LF translation will be performed by Emacs | 4626 /* Assume CRLF->LF translation will be performed by Emacs |
5002 when loading this file, so CRs won't appear in the buffer. | 4627 when loading this file, so CRs won't appear in the buffer. |
5003 It would be cleaner to compensate within Emacs; | 4628 It would be cleaner to compensate within Emacs; |
5004 however, Emacs does not know how many CRs were deleted | 4629 however, Emacs does not know how many CRs were deleted |
5005 before any given point in the file. */ | 4630 before any given point in the file. */ |
5024 | 4649 |
5025 /* | 4650 /* |
5026 * Like readline_internal, above, but in addition try to match the | 4651 * Like readline_internal, above, but in addition try to match the |
5027 * input line against relevant regular expressions. | 4652 * input line against relevant regular expressions. |
5028 */ | 4653 */ |
5029 static long | 4654 long |
5030 readline (lbp, stream) | 4655 readline (lbp, stream) |
5031 linebuffer *lbp; | 4656 linebuffer *lbp; |
5032 FILE *stream; | 4657 FILE *stream; |
5033 { | 4658 { |
5034 /* Read new line. */ | 4659 /* Read new line. */ |
5077 } | 4702 } |
5078 break; | 4703 break; |
5079 } | 4704 } |
5080 } | 4705 } |
5081 #endif /* ETAGS_REGEXPS */ | 4706 #endif /* ETAGS_REGEXPS */ |
5082 | 4707 |
5083 return result; | 4708 return result; |
5084 } | 4709 } |
5085 | 4710 |
5086 /* | 4711 /* |
5087 * Return a pointer to a space of size strlen(cp)+1 allocated | 4712 * Return a pointer to a space of size strlen(cp)+1 allocated |
5088 * with xnew where the string CP has been copied. | 4713 * with xnew where the string CP has been copied. |
5089 */ | 4714 */ |
5090 static char * | 4715 char * |
5091 savestr (cp) | 4716 savestr (cp) |
5092 char *cp; | 4717 char *cp; |
5093 { | 4718 { |
5094 return savenstr (cp, strlen (cp)); | 4719 return savenstr (cp, strlen (cp)); |
5095 } | 4720 } |
5096 | 4721 |
5097 /* | 4722 /* |
5098 * Return a pointer to a space of size LEN+1 allocated with xnew where | 4723 * Return a pointer to a space of size LEN+1 allocated with xnew where |
5099 * the string CP has been copied for at most the first LEN characters. | 4724 * the string CP has been copied for at most the first LEN characters. |
5100 */ | 4725 */ |
5101 static char * | 4726 char * |
5102 savenstr (cp, len) | 4727 savenstr (cp, len) |
5103 char *cp; | 4728 char *cp; |
5104 int len; | 4729 int len; |
5105 { | 4730 { |
5106 register char *dp; | 4731 register char *dp; |
5113 | 4738 |
5114 /* | 4739 /* |
5115 * Return the ptr in sp at which the character c last | 4740 * Return the ptr in sp at which the character c last |
5116 * appears; NULL if not found | 4741 * appears; NULL if not found |
5117 * | 4742 * |
5118 * Identical to POSIX strrchr, included for portability. | 4743 * Identical to System V strrchr, included for portability. |
5119 */ | 4744 */ |
5120 static char * | 4745 char * |
5121 etags_strrchr (sp, c) | 4746 etags_strrchr (sp, c) |
5122 register const char *sp; | 4747 register char *sp, c; |
5123 register int c; | 4748 { |
5124 { | 4749 register char *r; |
5125 register const char *r; | |
5126 | 4750 |
5127 r = NULL; | 4751 r = NULL; |
5128 do | 4752 do |
5129 { | 4753 { |
5130 if (*sp == c) | 4754 if (*sp == c) |
5131 r = sp; | 4755 r = sp; |
5132 } while (*sp++); | 4756 } while (*sp++); |
5133 return (char *)r; | 4757 return r; |
5134 } | 4758 } |
5135 | 4759 |
5136 | 4760 |
5137 /* | 4761 /* |
5138 * Return the ptr in sp at which the character c first | 4762 * Return the ptr in sp at which the character c first |
5139 * appears; NULL if not found | 4763 * appears; NULL if not found |
5140 * | 4764 * |
5141 * Identical to POSIX strchr, included for portability. | 4765 * Identical to System V strchr, included for portability. |
5142 */ | 4766 */ |
5143 static char * | 4767 char * |
5144 etags_strchr (sp, c) | 4768 etags_strchr (sp, c) |
5145 register const char *sp; | 4769 register char *sp, c; |
5146 register int c; | |
5147 { | 4770 { |
5148 do | 4771 do |
5149 { | 4772 { |
5150 if (*sp == c) | 4773 if (*sp == c) |
5151 return (char *)sp; | 4774 return sp; |
5152 } while (*sp++); | 4775 } while (*sp++); |
5153 return NULL; | 4776 return NULL; |
5154 } | 4777 } |
5155 | 4778 |
5156 /* Skip spaces, return new pointer. */ | 4779 /* Skip spaces, return new pointer. */ |
5157 static char * | 4780 char * |
5158 skip_spaces (cp) | 4781 skip_spaces (cp) |
5159 char *cp; | 4782 char *cp; |
5160 { | 4783 { |
5161 while (iswhite (*cp)) | 4784 while (isspace (*cp)) /* isspace('\0')==FALSE */ |
5162 cp++; | 4785 cp++; |
5163 return cp; | 4786 return cp; |
5164 } | 4787 } |
5165 | 4788 |
5166 /* Skip non spaces, return new pointer. */ | 4789 /* Skip non spaces, return new pointer. */ |
5167 static char * | 4790 char * |
5168 skip_non_spaces (cp) | 4791 skip_non_spaces (cp) |
5169 char *cp; | 4792 char *cp; |
5170 { | 4793 { |
5171 while (*cp != '\0' && !iswhite (*cp)) | 4794 while (!iswhite (*cp)) /* iswhite('\0')==TRUE */ |
5172 cp++; | 4795 cp++; |
5173 return cp; | 4796 return cp; |
5174 } | 4797 } |
5175 | 4798 |
5176 /* Print error message and exit. */ | 4799 /* Print error message and exit. */ |
5177 static void | 4800 void |
5178 fatal (s1, s2) | 4801 fatal (s1, s2) |
5179 char *s1, *s2; | 4802 char *s1, *s2; |
5180 { | 4803 { |
5181 error (s1, s2); | 4804 error (s1, s2); |
5182 exit (BAD); | 4805 exit (BAD); |
5183 } | 4806 } |
5184 | 4807 |
5185 static void | 4808 void |
5186 pfatal (s1) | 4809 pfatal (s1) |
5187 char *s1; | 4810 char *s1; |
5188 { | 4811 { |
5189 perror (s1); | 4812 perror (s1); |
5190 exit (BAD); | 4813 exit (BAD); |
5191 } | 4814 } |
5192 | 4815 |
5193 static void | 4816 void |
5194 suggest_asking_for_help () | 4817 suggest_asking_for_help () |
5195 { | 4818 { |
5196 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n", | 4819 fprintf (stderr, "\tTry `%s %s' for a complete list of options.\n", |
5197 progname, | 4820 progname, |
5198 #ifdef LONG_OPTIONS | 4821 #ifdef LONG_OPTIONS |
5203 ); | 4826 ); |
5204 exit (BAD); | 4827 exit (BAD); |
5205 } | 4828 } |
5206 | 4829 |
5207 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ | 4830 /* Print error message. `s1' is printf control string, `s2' is arg for it. */ |
5208 static void | 4831 void |
5209 error (s1, s2) | 4832 error (s1, s2) |
5210 const char *s1, *s2; | 4833 char *s1, *s2; |
5211 { | 4834 { |
5212 fprintf (stderr, "%s: ", progname); | 4835 fprintf (stderr, "%s: ", progname); |
5213 fprintf (stderr, s1, s2); | 4836 fprintf (stderr, s1, s2); |
5214 fprintf (stderr, "\n"); | 4837 fprintf (stderr, "\n"); |
5215 } | 4838 } |
5216 | 4839 |
5217 /* Return a newly-allocated string whose contents | 4840 /* Return a newly-allocated string whose contents |
5218 concatenate those of s1, s2, s3. */ | 4841 concatenate those of s1, s2, s3. */ |
5219 static char * | 4842 char * |
5220 concat (s1, s2, s3) | 4843 concat (s1, s2, s3) |
5221 char *s1, *s2, *s3; | 4844 char *s1, *s2, *s3; |
5222 { | 4845 { |
5223 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); | 4846 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); |
5224 char *result = xnew (len1 + len2 + len3 + 1, char); | 4847 char *result = xnew (len1 + len2 + len3 + 1, char); |
5231 return result; | 4854 return result; |
5232 } | 4855 } |
5233 | 4856 |
5234 /* Does the same work as the system V getcwd, but does not need to | 4857 /* Does the same work as the system V getcwd, but does not need to |
5235 guess the buffer size in advance. */ | 4858 guess the buffer size in advance. */ |
5236 static char * | 4859 char * |
5237 etags_getcwd () | 4860 etags_getcwd () |
5238 { | 4861 { |
5239 #ifdef HAVE_GETCWD | 4862 #ifdef HAVE_GETCWD |
5240 int bufsize = 200; | 4863 int bufsize = 200; |
5241 char *path = xnew (bufsize, char); | 4864 char *path = xnew (bufsize, char); |
5251 | 4874 |
5252 canonicalize_filename (path); | 4875 canonicalize_filename (path); |
5253 return path; | 4876 return path; |
5254 | 4877 |
5255 #else /* not HAVE_GETCWD */ | 4878 #else /* not HAVE_GETCWD */ |
4879 #ifdef MSDOS | |
4880 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ | |
4881 | |
4882 getwd (path); | |
4883 | |
4884 for (p = path; *p != '\0'; p++) | |
4885 if (*p == '\\') | |
4886 *p = '/'; | |
4887 else | |
4888 *p = lowcase (*p); | |
4889 | |
4890 return strdup (path); | |
4891 #else /* not MSDOS */ | |
5256 linebuffer path; | 4892 linebuffer path; |
5257 FILE *pipe; | 4893 FILE *pipe; |
5258 | 4894 |
5259 initbuffer (&path); | 4895 initbuffer (&path); |
5260 pipe = (FILE *) popen ("pwd 2>/dev/null", "r"); | 4896 pipe = (FILE *) popen ("pwd 2>/dev/null", "r"); |
5261 if (pipe == NULL || readline_internal (&path, pipe) == 0) | 4897 if (pipe == NULL || readline_internal (&path, pipe) == 0) |
5262 pfatal ("pwd"); | 4898 pfatal ("pwd"); |
5263 pclose (pipe); | 4899 pclose (pipe); |
5264 | 4900 |
5265 return path.buffer; | 4901 return path.buffer; |
4902 #endif /* not MSDOS */ | |
5266 #endif /* not HAVE_GETCWD */ | 4903 #endif /* not HAVE_GETCWD */ |
5267 } | 4904 } |
5268 | 4905 |
5269 /* Return a newly allocated string containing the file name of FILE | 4906 /* Return a newly allocated string containing the file name of FILE |
5270 relative to the absolute directory DIR (which should end with a slash). */ | 4907 relative to the absolute directory DIR (which should end with a slash). */ |
5271 static char * | 4908 char * |
5272 relative_filename (file, dir) | 4909 relative_filename (file, dir) |
5273 char *file, *dir; | 4910 char *file, *dir; |
5274 { | 4911 { |
5275 char *fp, *dp, *afn, *res; | 4912 char *fp, *dp, *afn, *res; |
5276 int i; | 4913 int i; |
5280 fp = afn; | 4917 fp = afn; |
5281 dp = dir; | 4918 dp = dir; |
5282 while (*fp++ == *dp++) | 4919 while (*fp++ == *dp++) |
5283 continue; | 4920 continue; |
5284 fp--, dp--; /* back to the first differing char */ | 4921 fp--, dp--; /* back to the first differing char */ |
5285 #ifdef WIN32_NATIVE | |
5286 if (fp == afn && afn[0] != '/') /* cannot build a relative name */ | |
5287 return afn; | |
5288 #endif | |
5289 do /* look at the equal chars until '/' */ | 4922 do /* look at the equal chars until '/' */ |
5290 fp--, dp--; | 4923 fp--, dp--; |
5291 while (*fp != '/'); | 4924 while (*fp != '/'); |
5292 | 4925 |
5293 /* Build a sequence of "../" strings for the resulting relative file name. */ | 4926 /* Build a sequence of "../" strings for the resulting relative file name. */ |
5306 return res; | 4939 return res; |
5307 } | 4940 } |
5308 | 4941 |
5309 /* Return a newly allocated string containing the absolute file name | 4942 /* Return a newly allocated string containing the absolute file name |
5310 of FILE given DIR (which should end with a slash). */ | 4943 of FILE given DIR (which should end with a slash). */ |
5311 static char * | 4944 char * |
5312 absolute_filename (file, dir) | 4945 absolute_filename (file, dir) |
5313 char *file, *dir; | 4946 char *file, *dir; |
5314 { | 4947 { |
5315 char *slashp, *cp, *res; | 4948 char *slashp, *cp, *res; |
5316 | 4949 |
5317 if (filename_is_absolute (file)) | 4950 if (filename_is_absolute (file)) |
5318 res = savestr (file); | 4951 res = savestr (file); |
5319 #ifdef WIN32_NATIVE | 4952 #ifdef DOS_NT |
5320 /* We don't support non-absolute file names with a drive | 4953 /* We don't support non-absolute file names with a drive |
5321 letter, like `d:NAME' (it's too much hassle). */ | 4954 letter, like `d:NAME' (it's too much hassle). */ |
5322 else if (file[1] == ':') | 4955 else if (file[1] == ':') |
5323 fatal ("%s: relative file names with drive letters not supported", file); | 4956 fatal ("%s: relative file names with drive letters not supported", file); |
5324 #endif | 4957 #endif |
5338 do | 4971 do |
5339 cp--; | 4972 cp--; |
5340 while (cp >= res && !filename_is_absolute (cp)); | 4973 while (cp >= res && !filename_is_absolute (cp)); |
5341 if (cp < res) | 4974 if (cp < res) |
5342 cp = slashp; /* the absolute name begins with "/.." */ | 4975 cp = slashp; /* the absolute name begins with "/.." */ |
5343 #ifdef WIN32_NATIVE | 4976 #ifdef DOS_NT |
5344 /* Under Windows we get `d:/NAME' as absolute | 4977 /* Under MSDOS and NT we get `d:/NAME' as absolute |
5345 file name, so the luser could say `d:/../NAME'. | 4978 file name, so the luser could say `d:/../NAME'. |
5346 We silently treat this as `d:/NAME'. */ | 4979 We silently treat this as `d:/NAME'. */ |
5347 else if (cp[0] != '/') | 4980 else if (cp[0] != '/') |
5348 cp = slashp; | 4981 cp = slashp; |
5349 #endif | 4982 #endif |
5358 } | 4991 } |
5359 } | 4992 } |
5360 | 4993 |
5361 slashp = etags_strchr (slashp + 1, '/'); | 4994 slashp = etags_strchr (slashp + 1, '/'); |
5362 } | 4995 } |
5363 | 4996 |
5364 if (res[0] == '\0') | 4997 if (res[0] == '\0') |
5365 return savestr ("/"); | 4998 return savestr ("/"); |
5366 else | 4999 else |
5367 return res; | 5000 return res; |
5368 } | 5001 } |
5369 | 5002 |
5370 /* Return a newly allocated string containing the absolute | 5003 /* Return a newly allocated string containing the absolute |
5371 file name of dir where FILE resides given DIR (which should | 5004 file name of dir where FILE resides given DIR (which should |
5372 end with a slash). */ | 5005 end with a slash). */ |
5373 static char * | 5006 char * |
5374 absolute_dirname (file, dir) | 5007 absolute_dirname (file, dir) |
5375 char *file, *dir; | 5008 char *file, *dir; |
5376 { | 5009 { |
5377 char *slashp, *res; | 5010 char *slashp, *res; |
5378 char save; | 5011 char save; |
5389 return res; | 5022 return res; |
5390 } | 5023 } |
5391 | 5024 |
5392 /* Whether the argument string is an absolute file name. The argument | 5025 /* Whether the argument string is an absolute file name. The argument |
5393 string must have been canonicalized with canonicalize_filename. */ | 5026 string must have been canonicalized with canonicalize_filename. */ |
5394 static bool | 5027 bool |
5395 filename_is_absolute (fn) | 5028 filename_is_absolute (fn) |
5396 char *fn; | 5029 char *fn; |
5397 { | 5030 { |
5398 return (fn[0] == '/' | 5031 return (fn[0] == '/' |
5399 #ifdef WIN32_NATIVE | 5032 #ifdef DOS_NT |
5400 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/') | 5033 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/') |
5401 #endif | 5034 #endif |
5402 ); | 5035 ); |
5403 } | 5036 } |
5404 | 5037 |
5405 /* Translate backslashes into slashes. Works in place. */ | 5038 /* Translate backslashes into slashes. Works in place. */ |
5406 static void | 5039 void |
5407 canonicalize_filename (fn) | 5040 canonicalize_filename (fn) |
5408 register char *fn; | 5041 register char *fn; |
5409 { | 5042 { |
5410 #ifdef WIN32_NATIVE | 5043 #ifdef DOS_NT |
5411 /* Canonicalize drive letter case. */ | |
5412 if (islower (fn[0]) && fn[1] == ':') | |
5413 fn[0] = toupper (fn[0]); | |
5414 /* Convert backslashes to slashes. */ | |
5415 for (; *fn != '\0'; fn++) | 5044 for (; *fn != '\0'; fn++) |
5416 if (*fn == '\\') | 5045 if (*fn == '\\') |
5417 *fn = '/'; | 5046 *fn = '/'; |
5418 #else | 5047 #else |
5419 /* No action. */ | 5048 /* No action. */ |
5420 fn = NULL; /* shut up the compiler */ | 5049 fn = NULL; /* shut up the compiler */ |
5421 #endif | 5050 #endif |
5422 } | 5051 } |
5423 | 5052 |
5424 /* Increase the size of a linebuffer. */ | 5053 /* Increase the size of a linebuffer. */ |
5425 static void | 5054 void |
5426 grow_linebuffer (lbp, toksize) | 5055 grow_linebuffer (lbp, toksize) |
5427 linebuffer *lbp; | 5056 linebuffer *lbp; |
5428 int toksize; | 5057 int toksize; |
5429 { | 5058 { |
5430 while (lbp->size < toksize) | 5059 while (lbp->size < toksize) |
5431 lbp->size *= 2; | 5060 lbp->size *= 2; |
5432 lbp->buffer = xrnew (lbp->buffer, lbp->size, char); | 5061 lbp->buffer = xrnew (lbp->buffer, lbp->size, char); |
5433 } | 5062 } |
5434 | 5063 |
5435 /* Like malloc but get fatal error if memory is exhausted. */ | 5064 /* Like malloc but get fatal error if memory is exhausted. */ |
5436 static long * | 5065 long * |
5437 xmalloc (size) | 5066 xmalloc (size) |
5438 unsigned int size; | 5067 unsigned int size; |
5439 { | 5068 { |
5440 long *result = (long *) malloc (size); | 5069 long *result = (long *) malloc (size); |
5441 if (result == NULL) | 5070 if (result == NULL) |
5442 fatal ("virtual memory exhausted", (char *)NULL); | 5071 fatal ("virtual memory exhausted", (char *)NULL); |
5443 return result; | 5072 return result; |
5444 } | 5073 } |
5445 | 5074 |
5446 static long * | 5075 long * |
5447 xrealloc (ptr, size) | 5076 xrealloc (ptr, size) |
5448 char *ptr; | 5077 char *ptr; |
5449 unsigned int size; | 5078 unsigned int size; |
5450 { | 5079 { |
5451 long *result = (long *) realloc (ptr, size); | 5080 long *result = (long *) realloc (ptr, size); |