comparison lib-src/etags.c @ 458:c33ae14dd6d0 r21-2-44

Import from CVS: tag r21-2-44
author cvs
date Mon, 13 Aug 2007 11:42:25 +0200
parents abe6d1db359e
children cd662ad69f40
comparison
equal deleted inserted replaced
457:4b9290a33024 458:c33ae14dd6d0
1 /* Tags file maker to go with GNU Emacs 1 /* Tags file maker to go with GNU Emacs -*- coding: latin-1 -*-
2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98, 99 2 Copyright (C) 1984, 87, 88, 89, 93, 94, 95, 98, 99, 2000, 2001
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
22 * Authors: 22 * Authors:
23 * Ctags originally by Ken Arnold. 23 * Ctags originally by Ken Arnold.
24 * Fortran added by Jim Kleckner. 24 * Fortran added by Jim Kleckner.
25 * Ed Pelegri-Llopart added C typedefs. 25 * Ed Pelegri-Llopart added C typedefs.
26 * Gnu Emacs TAGS format and modifications by RMS? 26 * Gnu Emacs TAGS format and modifications by RMS?
27 * Sam Kendall added C++. 27 * 1989 Sam Kendall added C++.
28 * Francesco Potorti` reorganised C and C++ based on work by Joe Wells. 28 * 1993 Francesco Potort́ reorganised C and C++ based on work by Joe Wells.
29 * Regexp tags by Tom Tromey. 29 * 1994 Regexp tags by Tom Tromey.
30 * 2001 Nested classes by Francesco Potort́ based on work by Mykola Dzyuba.
30 * 31 *
31 * Francesco Potorti` (pot@gnu.org) is the current maintainer. 32 * Francesco Potort́ <pot@gnu.org> has maintained it since 1993.
32 */ 33 */
33 34
34 char pot_etags_version[] = "@(#) pot revision number is 13.44"; 35 char pot_etags_version[] = "@(#) pot revision number is 14.15";
35 36
36 #define TRUE 1 37 #define TRUE 1
37 #define FALSE 0 38 #define FALSE 0
38 39
39 #ifndef DEBUG 40 #ifdef DEBUG
40 # define DEBUG FALSE 41 # undef DEBUG
42 # define DEBUG TRUE
43 #else
44 # define DEBUG FALSE
45 # define NDEBUG /* disable assert */
41 #endif 46 #endif
42 47
43 #if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C)) 48 #if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
44 # define P_(proto) proto 49 # define P_(proto) proto
45 #else 50 #else
57 62
58 #ifndef _GNU_SOURCE 63 #ifndef _GNU_SOURCE
59 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */ 64 # define _GNU_SOURCE 1 /* enables some compiler checks on GNU */
60 #endif 65 #endif
61 66
67 /* WIN32_NATIVE is for Xemacs.
68 MSDOS, WINDOWSNT, DOS_NT are for Emacs. */
62 #ifdef WIN32_NATIVE 69 #ifdef WIN32_NATIVE
70 # undef MSDOS
71 # undef WINDOWSNT
72 # define WINDOWSNT
73 #endif /* WIN32_NATIVE */
74
75 #ifdef MSDOS
76 # undef MSDOS
77 # define MSDOS TRUE
78 # include <fcntl.h>
79 # include <sys/param.h>
80 # include <io.h>
81 # ifndef HAVE_CONFIG_H
82 # define DOS_NT
83 # include <sys/config.h>
84 # endif
85 #else
86 # define MSDOS FALSE
87 #endif /* MSDOS */
88
89 #ifdef WINDOWSNT
63 # include <stdlib.h> 90 # include <stdlib.h>
64 # include <fcntl.h> 91 # include <fcntl.h>
65 # include <string.h> 92 # include <string.h>
66 # include <direct.h> 93 # include <direct.h>
67 # include <io.h> 94 # include <io.h>
68 # define MAXPATHLEN _MAX_PATH 95 # define MAXPATHLEN _MAX_PATH
96 # undef HAVE_NTGUI
97 # undef DOS_NT
98 # define DOS_NT
69 # ifndef HAVE_GETCWD 99 # ifndef HAVE_GETCWD
70 # define HAVE_GETCWD 100 # define HAVE_GETCWD
71 # endif /* undef HAVE_GETCWD */ 101 # endif /* undef HAVE_GETCWD */
72 #else /* !WIN32_NATIVE */ 102 #else /* !WINDOWSNT */
73 # ifdef STDC_HEADERS 103 # ifdef STDC_HEADERS
74 # include <stdlib.h> 104 # include <stdlib.h>
75 # include <string.h> 105 # include <string.h>
76 # else 106 # else
77 extern char *getenv (); 107 extern char *getenv ();
78 # endif 108 # endif
79 #endif /* !WIN32_NATIVE */ 109 #endif /* !WINDOWSNT */
80 110
81 #ifdef HAVE_UNISTD_H 111 #ifdef HAVE_UNISTD_H
82 # include <unistd.h> 112 # include <unistd.h>
83 #else 113 #else
84 # if defined (HAVE_GETCWD) && !defined (WIN32_NATIVE) 114 # if defined (HAVE_GETCWD) && !defined (WINDOWSNT)
85 extern char *getcwd (char *buf, size_t size); 115 extern char *getcwd (char *buf, size_t size);
86 # endif 116 # endif
87 #endif /* HAVE_UNISTD_H */ 117 #endif /* HAVE_UNISTD_H */
88 118
89 #include <stdio.h> 119 #include <stdio.h>
92 #ifndef errno 122 #ifndef errno
93 extern int errno; 123 extern int errno;
94 #endif 124 #endif
95 #include <sys/types.h> 125 #include <sys/types.h>
96 #include <sys/stat.h> 126 #include <sys/stat.h>
127
128 #include <assert.h>
129 #ifdef NDEBUG
130 # undef assert /* some systems have a buggy assert.h */
131 # define assert(x) ((void) 0)
132 #endif
97 133
98 #if !defined (S_ISREG) && defined (S_IFREG) 134 #if !defined (S_ISREG) && defined (S_IFREG)
99 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 135 # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
100 #endif 136 #endif
101 137
128 #else 164 #else
129 # define GOOD 0 165 # define GOOD 0
130 # define BAD 1 166 # define BAD 1
131 #endif 167 #endif
132 168
133 /* C extensions. */ 169 #define streq(s,t) (assert((s)!=NULL || (t)!=NULL), !strcmp (s, t))
134 #define C_PLPL 0x00001 /* C++ */ 170 #define strneq(s,t,n) (assert((s)!=NULL || (t)!=NULL), !strncmp (s, t, n))
135 #define C_STAR 0x00003 /* C* */
136 #define C_JAVA 0x00005 /* JAVA */
137 #define YACC 0x10000 /* yacc file */
138
139 #define streq(s,t) ((DEBUG && (s) == NULL && (t) == NULL \
140 && (abort (), 1)) || !strcmp (s, t))
141 #define strneq(s,t,n) ((DEBUG && (s) == NULL && (t) == NULL \
142 && (abort (), 1)) || !strncmp (s, t, n))
143
144 #define lowcase(c) tolower ((char)c)
145 171
146 #define CHARS 256 /* 2^sizeof(char) */ 172 #define CHARS 256 /* 2^sizeof(char) */
147 #define CHAR(x) ((unsigned int)x & (CHARS - 1)) 173 #define CHAR(x) ((unsigned int)(x) & (CHARS - 1))
148 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */ 174 #define iswhite(c) (_wht[CHAR(c)]) /* c is white */
149 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */ 175 #define notinname(c) (_nin[CHAR(c)]) /* c is not in a name */
150 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */ 176 #define begtoken(c) (_btk[CHAR(c)]) /* c can start token */
151 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */ 177 #define intoken(c) (_itk[CHAR(c)]) /* c can be in token */
152 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */ 178 #define endtoken(c) (_etk[CHAR(c)]) /* c ends tokens */
153 179
180 #define ISALNUM(c) isalnum (CHAR(c))
181 #define ISALPHA(c) isalpha (CHAR(c))
182 #define ISDIGIT(c) isdigit (CHAR(c))
183 #define ISLOWER(c) islower (CHAR(c))
184
185 #define lowcase(c) tolower (CHAR(c))
186 #define upcase(c) toupper (CHAR(c))
187
154 188
155 /* 189 /*
156 * xnew, xrnew -- allocate, reallocate storage 190 * xnew, xrnew -- allocate, reallocate storage
157 * 191 *
158 * SYNOPSIS: Type *xnew (int n, Type); 192 * SYNOPSIS: Type *xnew (int n, Type);
159 * Type *xrnew (OldPointer, int n, Type); 193 * void xrnew (OldPointer, int n, Type);
160 */ 194 */
161 #ifdef chkmalloc 195 #if DEBUG
162 # include "chkmalloc.h" 196 # include "chkmalloc.h"
163 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \ 197 # define xnew(n,Type) ((Type *) trace_malloc (__FILE__, __LINE__, \
164 (n) * sizeof (Type))) 198 (n) * sizeof (Type)))
165 # define xrnew(op,n,Type) ((Type *) trace_realloc (__FILE__, __LINE__, \ 199 # define xrnew(op,n,Type) ((op) = (Type *) trace_realloc (__FILE__, __LINE__, \
166 (op), (n) * sizeof (Type))) 200 (char *) (op), (n) * sizeof (Type)))
167 #else 201 #else
168 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type))) 202 # define xnew(n,Type) ((Type *) xmalloc ((n) * sizeof (Type)))
169 # define xrnew(op,n,Type) ((Type *) xrealloc ((op), (n) * sizeof (Type))) 203 # define xrnew(op,n,Type) ((op) = (Type *) xrealloc ( \
204 (char *) (op), (n) * sizeof (Type)))
170 #endif 205 #endif
171 206
172 typedef int bool; 207 typedef int bool;
173 208
174 typedef void Lang_function P_((FILE *)); 209 typedef void Lang_function P_((FILE *));
181 216
182 typedef struct 217 typedef struct
183 { 218 {
184 char *name; 219 char *name;
185 Lang_function *function; 220 Lang_function *function;
221 char **filenames;
186 char **suffixes; 222 char **suffixes;
187 char **interpreters; 223 char **interpreters;
188 } language; 224 } language;
189 225
190 typedef struct node_st 226 typedef struct node_st
227 static void Cstar_entries P_((FILE *)); 263 static void Cstar_entries P_((FILE *));
228 static void Erlang_functions P_((FILE *)); 264 static void Erlang_functions P_((FILE *));
229 static void Fortran_functions P_((FILE *)); 265 static void Fortran_functions P_((FILE *));
230 static void Yacc_entries P_((FILE *)); 266 static void Yacc_entries P_((FILE *));
231 static void Lisp_functions P_((FILE *)); 267 static void Lisp_functions P_((FILE *));
268 static void Makefile_targets P_((FILE *));
232 static void Pascal_functions P_((FILE *)); 269 static void Pascal_functions P_((FILE *));
233 static void Perl_functions P_((FILE *)); 270 static void Perl_functions P_((FILE *));
234 static void Postscript_functions P_((FILE *)); 271 static void Postscript_functions P_((FILE *));
235 static void Prolog_functions P_((FILE *)); 272 static void Prolog_functions P_((FILE *));
236 static void Python_functions P_((FILE *)); 273 static void Python_functions P_((FILE *));
237 static void Scheme_functions P_((FILE *)); 274 static void Scheme_functions P_((FILE *));
238 static void TeX_functions P_((FILE *)); 275 static void TeX_commands P_((FILE *));
276 static void Texinfo_nodes P_((FILE *));
239 static void just_read_file P_((FILE *)); 277 static void just_read_file P_((FILE *));
240 278
241 static void print_language_names P_((void)); 279 static void print_language_names P_((void));
242 static void print_version P_((void)); 280 static void print_version P_((void));
243 static void print_help P_((void)); 281 static void print_help P_((void));
244 int main P_((int, char **)); 282 int main P_((int, char **));
245 static int number_len P_((long)); 283 static int number_len P_((long));
246 284
247 static compressor *get_compressor_from_suffix P_((char *, char **)); 285 static compressor *get_compressor_from_suffix P_((char *, char **));
248 static language *get_language_from_name P_((char *)); 286 static language *get_language_from_langname P_((char *));
249 static language *get_language_from_interpreter P_((char *)); 287 static language *get_language_from_interpreter P_((char *));
250 static language *get_language_from_suffix P_((char *)); 288 static language *get_language_from_filename P_((char *));
251 static int total_size_of_entries P_((node *)); 289 static int total_size_of_entries P_((node *));
252 static long readline P_((linebuffer *, FILE *)); 290 static long readline P_((linebuffer *, FILE *));
253 static long readline_internal P_((linebuffer *, FILE *)); 291 static long readline_internal P_((linebuffer *, FILE *));
254 static void get_tag P_((char *)); 292 static void get_tag P_((char *));
255 293
258 static void add_regex P_((char *, bool, language *)); 296 static void add_regex P_((char *, bool, language *));
259 static void free_patterns P_((void)); 297 static void free_patterns P_((void));
260 #endif /* ETAGS_REGEXPS */ 298 #endif /* ETAGS_REGEXPS */
261 static void error P_((const char *, const char *)); 299 static void error P_((const char *, const char *));
262 static void suggest_asking_for_help P_((void)); 300 static void suggest_asking_for_help P_((void));
263 static void fatal P_((char *, char *)); 301 void fatal P_((char *, char *));
264 static void pfatal P_((char *)); 302 static void pfatal P_((char *));
265 static void add_node P_((node *, node **)); 303 static void add_node P_((node *, node **));
266 304
267 static void init P_((void)); 305 static void init P_((void));
268 static void initbuffer P_((linebuffer *)); 306 static void initbuffer P_((linebuffer *));
285 static char *relative_filename P_((char *, char *)); 323 static char *relative_filename P_((char *, char *));
286 static char *absolute_filename P_((char *, char *)); 324 static char *absolute_filename P_((char *, char *));
287 static char *absolute_dirname P_((char *, char *)); 325 static char *absolute_dirname P_((char *, char *));
288 static bool filename_is_absolute P_((char *f)); 326 static bool filename_is_absolute P_((char *f));
289 static void canonicalize_filename P_((char *)); 327 static void canonicalize_filename P_((char *));
290 static void grow_linebuffer P_((linebuffer *, int)); 328 static void linebuffer_setlen P_((linebuffer *, int));
291 static long *xmalloc P_((unsigned int)); 329 long *xmalloc P_((unsigned int));
292 static long *xrealloc P_((char *, unsigned int)); 330 long *xrealloc P_((char *, unsigned int));
293 331
294 332
295 char searchar = '/'; /* use /.../ searches */ 333 char searchar = '/'; /* use /.../ searches */
296 334
297 char *tagfile; /* output file */ 335 char *tagfile; /* output file */
309 char *dbp; /* pointer to start of current tag */ 347 char *dbp; /* pointer to start of current tag */
310 348
311 node *head; /* the head of the binary tree of tags */ 349 node *head; /* the head of the binary tree of tags */
312 350
313 linebuffer lb; /* the current line */ 351 linebuffer lb; /* the current line */
314 linebuffer token_name; /* used by C_entries as a temporary area */
315 struct
316 {
317 long linepos;
318 linebuffer lb; /* used by C_entries instead of lb */
319 } lbs[2];
320 352
321 /* boolean "functions" (see init) */ 353 /* boolean "functions" (see init) */
322 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS]; 354 bool _wht[CHARS], _nin[CHARS], _itk[CHARS], _btk[CHARS], _etk[CHARS];
323 char 355 char
324 /* white chars */ 356 /* white chars */
333 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789"; 365 *midtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789";
334 366
335 bool append_to_tagfile; /* -a: append to tags */ 367 bool append_to_tagfile; /* -a: append to tags */
336 /* The following four default to TRUE for etags, but to FALSE for ctags. */ 368 /* The following four default to TRUE for etags, but to FALSE for ctags. */
337 bool typedefs; /* -t: create tags for C and Ada typedefs */ 369 bool typedefs; /* -t: create tags for C and Ada typedefs */
338 bool typedefs_and_cplusplus; /* -T: create tags for C typedefs, level */ 370 bool typedefs_or_cplusplus; /* -T: create tags for C typedefs, level */
339 /* 0 struct/enum/union decls, and C++ */ 371 /* 0 struct/enum/union decls, and C++ */
340 /* member functions. */ 372 /* member functions. */
341 bool constantypedefs; /* -d: create tags for C #define, enum */ 373 bool constantypedefs; /* -d: create tags for C #define, enum */
342 /* constants and variables. */ 374 /* constants and variables. */
343 /* -D: opposite of -d. Default under ctags. */ 375 /* -D: opposite of -d. Default under ctags. */
443 "src", /* BSO/Tasking C compiler output */ 475 "src", /* BSO/Tasking C compiler output */
444 NULL 476 NULL
445 }; 477 };
446 478
447 /* Note that .c and .h can be considered C++, if the --c++ flag was 479 /* Note that .c and .h can be considered C++, if the --c++ flag was
448 given. That is why default_C_entries is called here. */ 480 given, or if the `class' keyowrd is met inside the file.
481 That is why default_C_entries is called for these. */
449 char *default_C_suffixes [] = 482 char *default_C_suffixes [] =
450 { "c", "h", NULL }; 483 { "c", "h", NULL };
451 484
452 char *Cplusplus_suffixes [] = 485 char *Cplusplus_suffixes [] =
453 { "C", "H", "c++", "cc", "cpp", "cxx", "h++", "hh", "hpp", "hxx", 486 { "C", "c++", "cc", "cpp", "cxx", "H", "h++", "hh", "hpp", "hxx",
454 "M", /* Objective C++ */ 487 "M", /* Objective C++ */
455 "pdb", /* Postscript with C syntax */ 488 "pdb", /* Postscript with C syntax */
456 NULL }; 489 NULL };
457 490
458 char *Cjava_suffixes [] = 491 char *Cjava_suffixes [] =
469 502
470 char *Fortran_suffixes [] = 503 char *Fortran_suffixes [] =
471 { "F", "f", "f90", "for", NULL }; 504 { "F", "f", "f90", "for", NULL };
472 505
473 char *Lisp_suffixes [] = 506 char *Lisp_suffixes [] =
474 { "cl", "clisp", "el", "l", "lisp", "lsp", "ml", NULL }; 507 { "cl", "clisp", "el", "l", "lisp", "LSP", "lsp", "ml", NULL };
508
509 char *Makefile_filenames [] =
510 { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};
475 511
476 char *Pascal_suffixes [] = 512 char *Pascal_suffixes [] =
477 { "p", "pas", NULL }; 513 { "p", "pas", NULL };
478 514
479 char *Perl_suffixes [] = 515 char *Perl_suffixes [] =
480 { "pl", "pm", NULL }; 516 { "pl", "pm", NULL };
481 char *Perl_interpreters [] = 517 char *Perl_interpreters [] =
482 { "perl", "@PERL@", NULL }; 518 { "perl", "@PERL@", NULL };
483 519
484 char *plain_C_suffixes [] = 520 char *plain_C_suffixes [] =
485 { "pc", /* Pro*C file */ 521 { "lm", /* Objective lex file */
486 "m", /* Objective C file */ 522 "m", /* Objective C file */
487 "lm", /* Objective lex file */ 523 "pc", /* Pro*C file */
488 NULL }; 524 NULL };
489 525
490 char *Postscript_suffixes [] = 526 char *Postscript_suffixes [] =
491 { "ps", "psw", NULL }; /* .psw is for PSWrap */ 527 { "ps", "psw", NULL }; /* .psw is for PSWrap */
492 528
496 char *Python_suffixes [] = 532 char *Python_suffixes [] =
497 { "py", NULL }; 533 { "py", NULL };
498 534
499 /* Can't do the `SCM' or `scm' prefix with a version number. */ 535 /* Can't do the `SCM' or `scm' prefix with a version number. */
500 char *Scheme_suffixes [] = 536 char *Scheme_suffixes [] =
501 { "SCM", "SM", "oak", "sch", "scheme", "scm", "sm", "ss", "t", NULL }; 537 { "oak", "sch", "scheme", "SCM", "scm", "SM", "sm", "ss", "t", NULL };
502 538
503 char *TeX_suffixes [] = 539 char *TeX_suffixes [] =
504 { "TeX", "bib", "clo", "cls", "ltx", "sty", "tex", NULL }; 540 { "bib", "clo", "cls", "ltx", "sty", "TeX", "tex", NULL };
541
542 char *Texinfo_suffixes [] =
543 { "texi", "texinfo", "txi", NULL };
505 544
506 char *Yacc_suffixes [] = 545 char *Yacc_suffixes [] =
507 { "y", "ym", "yy", "yxx", "y++", NULL }; /* .ym is Objective yacc file */ 546 { "y", "y++", "ym", "yxx", "yy", NULL }; /* .ym is Objective yacc file */
508 547
509 /* 548 /*
510 * Table of languages. 549 * Table of languages.
511 * 550 *
512 * It is ok for a given function to be listed under more than one 551 * It is ok for a given function to be listed under more than one
513 * name. I just didn't. 552 * name. I just didn't.
514 */ 553 */
515 554
516 language lang_names [] = 555 language lang_names [] =
517 { 556 {
518 { "ada", Ada_funcs, Ada_suffixes, NULL }, 557 { "ada", Ada_funcs, NULL, Ada_suffixes, NULL },
519 { "asm", Asm_labels, Asm_suffixes, NULL }, 558 { "asm", Asm_labels, NULL, Asm_suffixes, NULL },
520 { "c", default_C_entries, default_C_suffixes, NULL }, 559 { "c", default_C_entries, NULL, default_C_suffixes, NULL },
521 { "c++", Cplusplus_entries, Cplusplus_suffixes, NULL }, 560 { "c++", Cplusplus_entries, NULL, Cplusplus_suffixes, NULL },
522 { "c*", Cstar_entries, Cstar_suffixes, NULL }, 561 { "c*", Cstar_entries, NULL, Cstar_suffixes, NULL },
523 { "cobol", Cobol_paragraphs, Cobol_suffixes, NULL }, 562 { "cobol", Cobol_paragraphs, NULL, Cobol_suffixes, NULL },
524 { "erlang", Erlang_functions, Erlang_suffixes, NULL }, 563 { "erlang", Erlang_functions, NULL, Erlang_suffixes, NULL },
525 { "fortran", Fortran_functions, Fortran_suffixes, NULL }, 564 { "fortran", Fortran_functions, NULL, Fortran_suffixes, NULL },
526 { "java", Cjava_entries, Cjava_suffixes, NULL }, 565 { "java", Cjava_entries, NULL, Cjava_suffixes, NULL },
527 { "lisp", Lisp_functions, Lisp_suffixes, NULL }, 566 { "lisp", Lisp_functions, NULL, Lisp_suffixes, NULL },
528 { "pascal", Pascal_functions, Pascal_suffixes, NULL }, 567 { "makefile", Makefile_targets, Makefile_filenames, NULL, NULL },
529 { "perl", Perl_functions, Perl_suffixes, Perl_interpreters }, 568 { "pascal", Pascal_functions, NULL, Pascal_suffixes, NULL },
530 { "postscript", Postscript_functions, Postscript_suffixes, NULL }, 569 { "perl", Perl_functions, NULL, Perl_suffixes, Perl_interpreters },
531 { "proc", plain_C_entries, plain_C_suffixes, NULL }, 570 { "postscript", Postscript_functions, NULL, Postscript_suffixes, NULL },
532 { "prolog", Prolog_functions, Prolog_suffixes, NULL }, 571 { "proc", plain_C_entries, NULL, plain_C_suffixes, NULL },
533 { "python", Python_functions, Python_suffixes, NULL }, 572 { "prolog", Prolog_functions, NULL, Prolog_suffixes, NULL },
534 { "scheme", Scheme_functions, Scheme_suffixes, NULL }, 573 { "python", Python_functions, NULL, Python_suffixes, NULL },
535 { "tex", TeX_functions, TeX_suffixes, NULL }, 574 { "scheme", Scheme_functions, NULL, Scheme_suffixes, NULL },
536 { "yacc", Yacc_entries, Yacc_suffixes, NULL }, 575 { "tex", TeX_commands, NULL, TeX_suffixes, NULL },
576 { "texinfo", Texinfo_nodes, NULL, Texinfo_suffixes, NULL },
577 { "yacc", Yacc_entries, NULL, Yacc_suffixes, NULL },
537 { "auto", NULL }, /* default guessing scheme */ 578 { "auto", NULL }, /* default guessing scheme */
538 { "none", just_read_file }, /* regexp matching only */ 579 { "none", just_read_file }, /* regexp matching only */
539 { NULL, NULL } /* end of list */ 580 { NULL, NULL } /* end of list */
540 }; 581 };
582
541 583
542 static void 584 static void
543 print_language_names () 585 print_language_names ()
544 { 586 {
545 language *lang; 587 language *lang;
546 char **ext; 588 char **name, **ext;
547 589
548 puts ("\nThese are the currently supported languages, along with the\n\ 590 puts ("\nThese are the currently supported languages, along with the\n\
549 default file name suffixes:"); 591 default file names and dot suffixes:");
550 for (lang = lang_names; lang->name != NULL; lang++) 592 for (lang = lang_names; lang->name != NULL; lang++)
551 { 593 {
552 printf ("\t%s\t", lang->name); 594 printf (" %-*s", 10, lang->name);
595 if (lang->filenames != NULL)
596 for (name = lang->filenames; *name != NULL; name++)
597 printf (" %s", *name);
553 if (lang->suffixes != NULL) 598 if (lang->suffixes != NULL)
554 for (ext = lang->suffixes; *ext != NULL; ext++) 599 for (ext = lang->suffixes; *ext != NULL; ext++)
555 printf (" .%s", *ext); 600 printf (" .%s", *ext);
556 puts (""); 601 puts ("");
557 } 602 }
559 name suffix, and `none' means only do regexp processing on files.\n\ 604 name suffix, and `none' means only do regexp processing on files.\n\
560 If no language is specified and no matching suffix is found,\n\ 605 If no language is specified and no matching suffix is found,\n\
561 the first line of the file is read for a sharp-bang (#!) sequence\n\ 606 the first line of the file is read for a sharp-bang (#!) sequence\n\
562 followed by the name of an interpreter. If no such sequence is found,\n\ 607 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\ 608 Fortran is tried first; if no tags are found, C is tried next.\n\
609 When parsing any C file, a \"class\" keyword switches to C++.\n\
564 Compressed files are supported using gzip and bzip2."); 610 Compressed files are supported using gzip and bzip2.");
565 } 611 }
566 612
567 #ifndef EMACS_NAME 613 #ifndef EMACS_NAME
568 # define EMACS_NAME "GNU Emacs" 614 # define EMACS_NAME "GNU Emacs"
607 if (CTAGS) 653 if (CTAGS)
608 puts ("-B, --backward-search\n\ 654 puts ("-B, --backward-search\n\
609 Write the search commands for the tag entries using '?', the\n\ 655 Write the search commands for the tag entries using '?', the\n\
610 backward-search command instead of '/', the forward-search command."); 656 backward-search command instead of '/', the forward-search command.");
611 657
658 /* This option is mostly obsolete, because etags can now automatically
659 detect C++. Retained for backward compatibility and for debugging and
660 experimentation. In principle, we could want to tag as C++ even
661 before any "class" keyword.
612 puts ("-C, --c++\n\ 662 puts ("-C, --c++\n\
613 Treat files whose name suffix defaults to C language as C++ files."); 663 Treat files whose name suffix defaults to C language as C++ files.");
664 */
614 665
615 puts ("--declarations\n\ 666 puts ("--declarations\n\
616 In C and derived languages, create tags for function declarations,"); 667 In C and derived languages, create tags for function declarations,");
617 if (CTAGS) 668 if (CTAGS)
618 puts ("\tand create tags for extern variables if --globals is used."); 669 puts ("\tand create tags for extern variables if --globals is used.");
868 linebuffer filename_lb; 919 linebuffer filename_lb;
869 #ifdef VMS 920 #ifdef VMS
870 bool got_err; 921 bool got_err;
871 #endif 922 #endif
872 923
873 #ifdef WIN32_NATIVE 924 #ifdef DOS_NT
874 _fmode = O_BINARY; /* all of files are treated as binary files */ 925 _fmode = O_BINARY; /* all of files are treated as binary files */
875 #endif /* WIN32_NATIVE */ 926 #endif /* DOS_NT */
876 927
877 progname = argv[0]; 928 progname = argv[0];
878 nincluded_files = 0; 929 nincluded_files = 0;
879 included_files = xnew (argc, char *); 930 included_files = xnew (argc, char *);
880 current_arg = 0; 931 current_arg = 0;
892 lc_trans[i] = lowcase (i); 943 lc_trans[i] = lowcase (i);
893 #endif /* ETAGS_REGEXPS */ 944 #endif /* ETAGS_REGEXPS */
894 945
895 /* 946 /*
896 * If etags, always find typedefs and structure tags. Why not? 947 * If etags, always find typedefs and structure tags. Why not?
897 * Also default is to find macro constants, enum constants and 948 * Also default to find macro constants, enum constants and
898 * global variables. 949 * global variables.
899 */ 950 */
900 if (!CTAGS) 951 if (!CTAGS)
901 { 952 {
902 typedefs = typedefs_and_cplusplus = constantypedefs = TRUE; 953 typedefs = typedefs_or_cplusplus = constantypedefs = TRUE;
903 globals = TRUE; 954 globals = TRUE;
955 declarations = FALSE;
904 members = FALSE; 956 members = FALSE;
905 } 957 }
906 958
907 while (1) 959 while (1)
908 { 960 {
956 case 'S': /* for backward compatibility */ 1008 case 'S': /* for backward compatibility */
957 noindentypedefs = TRUE; 1009 noindentypedefs = TRUE;
958 break; 1010 break;
959 case 'l': 1011 case 'l':
960 { 1012 {
961 language *lang = get_language_from_name (optarg); 1013 language *lang = get_language_from_langname (optarg);
962 if (lang != NULL) 1014 if (lang != NULL)
963 { 1015 {
964 argbuffer[current_arg].lang = lang; 1016 argbuffer[current_arg].lang = lang;
965 argbuffer[current_arg].arg_type = at_language; 1017 argbuffer[current_arg].arg_type = at_language;
966 ++current_arg; 1018 ++current_arg;
993 break; 1045 break;
994 case 't': 1046 case 't':
995 typedefs = TRUE; 1047 typedefs = TRUE;
996 break; 1048 break;
997 case 'T': 1049 case 'T':
998 typedefs = typedefs_and_cplusplus = TRUE; 1050 typedefs = typedefs_or_cplusplus = TRUE;
999 break; 1051 break;
1000 #if (!CTAGS) 1052 #if (!CTAGS)
1001 /* Etags options */ 1053 /* Etags options */
1002 case 'i': 1054 case 'i':
1003 included_files[nincluded_files++] = optarg; 1055 included_files[nincluded_files++] = optarg;
1044 tagfiledir = absolute_dirname (tagfile, cwd); 1096 tagfiledir = absolute_dirname (tagfile, cwd);
1045 1097
1046 init (); /* set up boolean "functions" */ 1098 init (); /* set up boolean "functions" */
1047 1099
1048 initbuffer (&lb); 1100 initbuffer (&lb);
1049 initbuffer (&token_name);
1050 initbuffer (&lbs[0].lb);
1051 initbuffer (&lbs[1].lb);
1052 initbuffer (&filename_lb); 1101 initbuffer (&filename_lb);
1053 1102
1054 if (!CTAGS) 1103 if (!CTAGS)
1055 { 1104 {
1056 if (streq (tagfile, "-")) 1105 if (streq (tagfile, "-"))
1057 { 1106 {
1058 tagf = stdout; 1107 tagf = stdout;
1059 #ifdef WIN32_NATIVE 1108 #ifdef DOS_NT
1060 /* Switch redirected `stdout' to binary mode (setting `_fmode' 1109 /* Switch redirected `stdout' to binary mode (setting `_fmode'
1061 doesn't take effect until after `stdout' is already open). */ 1110 doesn't take effect until after `stdout' is already open). */
1062 if (!isatty (fileno (stdout))) 1111 if (!isatty (fileno (stdout)))
1063 setmode (fileno (stdout), O_BINARY); 1112 setmode (fileno (stdout), O_BINARY);
1064 #endif /* WIN32_NATIVE */ 1113 #endif /* DOS_NT */
1065 } 1114 }
1066 else 1115 else
1067 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w"); 1116 tagf = fopen (tagfile, append_to_tagfile ? "a" : "w");
1068 if (tagf == NULL) 1117 if (tagf == NULL)
1069 pfatal (tagfile); 1118 pfatal (tagfile);
1178 /* 1227 /*
1179 * Return a compressor given the file name. If EXTPTR is non-zero, 1228 * Return a compressor given the file name. If EXTPTR is non-zero,
1180 * return a pointer into FILE where the compressor-specific 1229 * return a pointer into FILE where the compressor-specific
1181 * extension begins. If no compressor is found, NULL is returned 1230 * extension begins. If no compressor is found, NULL is returned
1182 * and EXTPTR is not significant. 1231 * and EXTPTR is not significant.
1183 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> 1232 * Idea by Vladimir Alexiev <vladimir@cs.ualberta.ca> (1998)
1184 */ 1233 */
1185 static compressor * 1234 static compressor *
1186 get_compressor_from_suffix (file, extptr) 1235 get_compressor_from_suffix (file, extptr)
1187 char *file; 1236 char *file;
1188 char **extptr; 1237 char **extptr;
1189 { 1238 {
1190 compressor *compr; 1239 compressor *compr;
1191 char *slash, *suffix; 1240 char *slash, *suffix;
1192 1241
1193 /* This relies on FN to be after canonicalize_filename, 1242 /* This relies on FN to be after canonicalize_filename,
1194 so we don't need to consider backslashes on WIN32_NATIVE. */ 1243 so we don't need to consider backslashes on DOS_NT. */
1195 slash = etags_strrchr (file, '/'); 1244 slash = etags_strrchr (file, '/');
1196 suffix = etags_strrchr (file, '.'); 1245 suffix = etags_strrchr (file, '.');
1197 if (suffix == NULL || suffix < slash) 1246 if (suffix == NULL || suffix < slash)
1198 return NULL; 1247 return NULL;
1199 if (extptr != NULL) 1248 if (extptr != NULL)
1200 *extptr = suffix; 1249 *extptr = suffix;
1201 suffix += 1; 1250 suffix += 1;
1202 /* Let those poor souls who live with DOS 8+3 file name limits get 1251 /* Let those poor souls who live with DOS 8+3 file name limits get
1203 some solace by treating foo.cgz as if it were foo.c.gz, etc. 1252 some solace by treating foo.cgz as if it were foo.c.gz, etc.
1204 */ 1253 Only the first do loop is run if not MSDOS */
1205 do 1254 do
1206 { 1255 {
1207 for (compr = compressors; compr->suffix != NULL; compr++) 1256 for (compr = compressors; compr->suffix != NULL; compr++)
1208 if (streq (compr->suffix, suffix)) 1257 if (streq (compr->suffix, suffix))
1209 return compr; 1258 return compr;
1210 if (1) /* !MSDOS */ 1259 if (!MSDOS)
1211 break; /* do it only once: not really a loop */ 1260 break; /* do it only once: not really a loop */
1212 if (extptr != NULL) 1261 if (extptr != NULL)
1213 *extptr = ++suffix; 1262 *extptr = ++suffix;
1214 } while (*suffix != '\0'); 1263 } while (*suffix != '\0');
1215 return NULL; 1264 return NULL;
1219 1268
1220 /* 1269 /*
1221 * Return a language given the name. 1270 * Return a language given the name.
1222 */ 1271 */
1223 static language * 1272 static language *
1224 get_language_from_name (name) 1273 get_language_from_langname (name)
1225 char *name; 1274 char *name;
1226 { 1275 {
1227 language *lang; 1276 language *lang;
1228 1277
1229 if (name == NULL) 1278 if (name == NULL)
1265 1314
1266 /* 1315 /*
1267 * Return a language given the file name. 1316 * Return a language given the file name.
1268 */ 1317 */
1269 static language * 1318 static language *
1270 get_language_from_suffix (file) 1319 get_language_from_filename (file)
1271 char *file; 1320 char *file;
1272 { 1321 {
1273 language *lang; 1322 language *lang;
1274 char **ext, *suffix; 1323 char **name, **ext, *suffix;
1275 1324
1325 /* Try whole file name first. */
1326 for (lang = lang_names; lang->name != NULL; lang++)
1327 if (lang->filenames != NULL)
1328 for (name = lang->filenames; *name != NULL; name++)
1329 if (streq (*name, file))
1330 return lang;
1331
1332 /* If not found, try suffix after last dot. */
1276 suffix = etags_strrchr (file, '.'); 1333 suffix = etags_strrchr (file, '.');
1277 if (suffix == NULL) 1334 if (suffix == NULL)
1278 return NULL; 1335 return NULL;
1279 suffix += 1; 1336 suffix += 1;
1280 for (lang = lang_names; lang->name != NULL; lang++) 1337 for (lang = lang_names; lang->name != NULL; lang++)
1352 for (compr = compressors; compr->suffix != NULL; compr++) 1409 for (compr = compressors; compr->suffix != NULL; compr++)
1353 { 1410 {
1354 compressed_name = concat (file, ".", compr->suffix); 1411 compressed_name = concat (file, ".", compr->suffix);
1355 if (stat (compressed_name, &stat_buf) != 0) 1412 if (stat (compressed_name, &stat_buf) != 0)
1356 { 1413 {
1357 /* XEmacs: delete MSDOS code */ 1414 if (MSDOS)
1415 {
1416 char *suf = compressed_name + strlen (file);
1417 size_t suflen = strlen (compr->suffix) + 1;
1418 for ( ; suf[1]; suf++, suflen--)
1419 {
1420 memmove (suf, suf + 1, suflen);
1421 if (stat (compressed_name, &stat_buf) == 0)
1422 {
1423 real_name = compressed_name;
1424 break;
1425 }
1426 }
1427 if (real_name != NULL)
1428 break;
1429 } /* MSDOS */
1358 free (compressed_name); 1430 free (compressed_name);
1359 compressed_name = NULL; 1431 compressed_name = NULL;
1360 } 1432 }
1361 else 1433 else
1362 { 1434 {
1378 goto exit; 1450 goto exit;
1379 } 1451 }
1380 if (real_name == compressed_name) 1452 if (real_name == compressed_name)
1381 { 1453 {
1382 char *cmd = concat (compr->command, " ", real_name); 1454 char *cmd = concat (compr->command, " ", real_name);
1383 inf = popen (cmd, "r"); 1455 inf = (FILE *) popen (cmd, "r");
1384 free (cmd); 1456 free (cmd);
1385 } 1457 }
1386 else 1458 else
1387 inf = fopen (real_name, "r"); 1459 inf = fopen (real_name, "r");
1388 if (inf == NULL) 1460 if (inf == NULL)
1483 lang->function (inf); 1555 lang->function (inf);
1484 return; 1556 return;
1485 } 1557 }
1486 1558
1487 /* Try to guess the language given the file name. */ 1559 /* Try to guess the language given the file name. */
1488 lang = get_language_from_suffix (file); 1560 lang = get_language_from_filename (file);
1489 if (lang != NULL && lang->function != NULL) 1561 if (lang != NULL && lang->function != NULL)
1490 { 1562 {
1491 curlang = lang; 1563 curlang = lang;
1492 lang->function (inf); 1564 lang->function (inf);
1493 return; 1565 return;
1528 which is unlikely. */ 1600 which is unlikely. */
1529 rewind (inf); 1601 rewind (inf);
1530 1602
1531 /* Try Fortran. */ 1603 /* Try Fortran. */
1532 old_last_node = last_node; 1604 old_last_node = last_node;
1533 curlang = get_language_from_name ("fortran"); 1605 curlang = get_language_from_langname ("fortran");
1534 Fortran_functions (inf); 1606 Fortran_functions (inf);
1535 1607
1536 /* No Fortran entries found. Try C. */ 1608 /* No Fortran entries found. Try C. */
1537 if (old_last_node == last_node) 1609 if (old_last_node == last_node)
1538 { 1610 {
1539 /* We do not tag if rewind fails. 1611 /* We do not tag if rewind fails.
1540 Only the file name will be recorded in the tags file. */ 1612 Only the file name will be recorded in the tags file. */
1541 rewind (inf); 1613 rewind (inf);
1542 curlang = get_language_from_name (cplusplus ? "c++" : "c"); 1614 curlang = get_language_from_langname (cplusplus ? "c++" : "c");
1543 default_C_entries (inf); 1615 default_C_entries (inf);
1544 } 1616 }
1545 return; 1617 return;
1546 } 1618 }
1619
1547 1620
1548 /* Record a tag. */ 1621 /* Record a tag. */
1549 static void 1622 static void
1550 pfnote (name, is_func, linestart, linelen, lno, cno) 1623 pfnote (name, is_func, linestart, linelen, lno, cno)
1551 char *name; /* tag name, or NULL if unnamed */ 1624 char *name; /* tag name, or NULL if unnamed */
1595 np->pat = savenstr (linestart, linelen); 1668 np->pat = savenstr (linestart, linelen);
1596 1669
1597 add_node (np, &head); 1670 add_node (np, &head);
1598 } 1671 }
1599 1672
1600 /* Date: Wed, 22 Jan 1997 02:56:31 -0500 [last amended 18 Sep 1997] 1673 /*
1601 * From: Sam Kendall <kendall@mv.mv.com> 1674 * TAGS format specification
1602 * Subject: Proposal for firming up the TAGS format specification 1675 * Idea by Sam Kendall <kendall@mv.mv.com> (1997)
1603 * To: F.Potorti@cnuce.cnr.it
1604 * 1676 *
1605 * pfnote should emit the optimized form [unnamed tag] only if: 1677 * pfnote should emit the optimized form [unnamed tag] only if:
1606 * 1. name does not contain any of the characters " \t\r\n(),;"; 1678 * 1. name does not contain any of the characters " \t\r\n(),;";
1607 * 2. linestart contains name as either a rightmost, or rightmost but 1679 * 2. linestart contains name as either a rightmost, or rightmost but
1608 * one character, substring; 1680 * one character, substring;
1738 1810
1739 /* Actually add the node */ 1811 /* Actually add the node */
1740 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right); 1812 add_node (np, dif < 0 ? &cur_node->left : &cur_node->right);
1741 } 1813 }
1742 } 1814 }
1815
1743 1816
1744 static void 1817 static void
1745 put_entries (np) 1818 put_entries (np)
1746 register node *np; 1819 register node *np;
1747 { 1820 {
1846 total += 1 + strlen (np->name); /* \001name */ 1919 total += 1 + strlen (np->name); /* \001name */
1847 } 1920 }
1848 1921
1849 return total; 1922 return total;
1850 } 1923 }
1924
1851 1925
1926 /* C extensions. */
1927 #define C_EXT 0x00fff /* C extensions */
1928 #define C_PLAIN 0x00000 /* C */
1929 #define C_PLPL 0x00001 /* C++ */
1930 #define C_STAR 0x00003 /* C* */
1931 #define C_JAVA 0x00005 /* JAVA */
1932 #define C_AUTO 0x01000 /* C, but switch to C++ if `class' is met */
1933 #define YACC 0x10000 /* yacc file */
1934
1852 /* 1935 /*
1853 * The C symbol tables. 1936 * The C symbol tables.
1854 */ 1937 */
1855 enum sym_type 1938 enum sym_type
1856 { 1939 {
1858 st_C_objprot, st_C_objimpl, st_C_objend, 1941 st_C_objprot, st_C_objimpl, st_C_objend,
1859 st_C_gnumacro, 1942 st_C_gnumacro,
1860 st_C_ignore, 1943 st_C_ignore,
1861 st_C_javastruct, 1944 st_C_javastruct,
1862 st_C_operator, 1945 st_C_operator,
1946 st_C_class,
1863 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec 1947 st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
1864 }; 1948 };
1865 1949
1866 static unsigned int hash P_((const char *, unsigned int)); 1950 static unsigned int hash P_((const char *, unsigned int));
1867 static struct C_stab_entry * in_word_set P_((const char *, unsigned int)); 1951 static struct C_stab_entry * in_word_set P_((const char *, unsigned int));
1868 static enum sym_type C_symtype P_((char *, int, int)); 1952 static enum sym_type C_symtype P_((char *, int, int));
1869 1953
1870 /* Feed stuff between (but not including) %[ and %] lines to: 1954 /* Feed stuff between (but not including) %[ and %] lines to:
1871 gperf -c -k 1,3 -o -p -r -t 1955 gperf -c -k 1,3 -o -p -r -t
1956 then put a `static' keyword in front of the in_word_set function.
1872 %[ 1957 %[
1873 struct C_stab_entry { char *name; int c_ext; enum sym_type type; } 1958 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
1874 %% 1959 %%
1875 if, 0, st_C_ignore 1960 if, 0, st_C_ignore
1876 for, 0, st_C_ignore 1961 for, 0, st_C_ignore
1885 package, C_JAVA, st_C_ignore 1970 package, C_JAVA, st_C_ignore
1886 friend, C_PLPL, st_C_ignore 1971 friend, C_PLPL, st_C_ignore
1887 extends, C_JAVA, st_C_javastruct 1972 extends, C_JAVA, st_C_javastruct
1888 implements, C_JAVA, st_C_javastruct 1973 implements, C_JAVA, st_C_javastruct
1889 interface, C_JAVA, st_C_struct 1974 interface, C_JAVA, st_C_struct
1890 class, C_PLPL, st_C_struct 1975 class, 0, st_C_class
1891 namespace, C_PLPL, st_C_struct 1976 namespace, C_PLPL, st_C_struct
1892 domain, C_STAR, st_C_struct 1977 domain, C_STAR, st_C_struct
1893 union, 0, st_C_struct 1978 union, 0, st_C_struct
1894 struct, 0, st_C_struct 1979 struct, 0, st_C_struct
1895 extern, 0, st_C_extern 1980 extern, 0, st_C_extern
1922 # These are defined inside C functions, so currently they are not met. 2007 # These are defined inside C functions, so currently they are not met.
1923 # EXFUN used in glibc, DEFVAR_* in emacs. 2008 # EXFUN used in glibc, DEFVAR_* in emacs.
1924 #EXFUN, 0, st_C_gnumacro 2009 #EXFUN, 0, st_C_gnumacro
1925 #DEFVAR_, 0, st_C_gnumacro 2010 #DEFVAR_, 0, st_C_gnumacro
1926 %] 2011 %]
1927 and replace lines between %< and %> with its output. */ 2012 and replace lines between %< and %> with its output,
2013 then make in_word_set static. */
1928 /*%<*/ 2014 /*%<*/
1929 /* C code produced by gperf version 2.7.1 (19981006 egcs) */ 2015 /* C code produced by gperf version 2.7.1 (19981006 egcs) */
1930 /* Command-line: gperf -c -k 1,3 -o -p -r -t */ 2016 /* 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; }; 2017 struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
1932 2018
1933 #define TOTAL_KEYWORDS 46 2019 #define TOTAL_KEYWORDS 46
1934 #define MIN_WORD_LENGTH 2 2020 #define MIN_WORD_LENGTH 2
1935 #define MAX_WORD_LENGTH 15 2021 #define MAX_WORD_LENGTH 15
1936 #define MIN_HASH_VALUE 13 2022 #define MIN_HASH_VALUE 13
1937 #define MAX_HASH_VALUE 123 2023 #define MAX_HASH_VALUE 121
1938 /* maximum key range = 111, duplicates = 0 */ 2024 /* maximum key range = 109, duplicates = 0 */
1939 2025
1940 #ifdef __GNUC__ 2026 #ifdef __GNUC__
1941 __inline 2027 __inline
1942 #endif 2028 #endif
1943 static unsigned int 2029 static unsigned int
1945 register const char *str; 2031 register const char *str;
1946 register unsigned int len; 2032 register unsigned int len;
1947 { 2033 {
1948 static unsigned char asso_values[] = 2034 static unsigned char asso_values[] =
1949 { 2035 {
1950 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2036 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1951 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2037 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1952 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2038 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1953 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2039 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1954 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2040 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1955 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2041 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1956 124, 124, 124, 124, 3, 124, 124, 124, 43, 6, 2042 122, 122, 122, 122, 57, 122, 122, 122, 55, 6,
1957 11, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2043 60, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1958 11, 124, 124, 58, 7, 124, 124, 124, 124, 124, 2044 51, 122, 122, 10, 2, 122, 122, 122, 122, 122,
1959 124, 124, 124, 124, 124, 124, 124, 57, 7, 42, 2045 122, 122, 122, 122, 122, 122, 122, 2, 52, 59,
1960 4, 14, 52, 0, 124, 53, 124, 124, 29, 11, 2046 49, 38, 56, 41, 122, 22, 122, 122, 9, 32,
1961 6, 35, 32, 124, 29, 34, 59, 58, 51, 24, 2047 33, 60, 26, 122, 1, 28, 46, 59, 44, 51,
1962 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2048 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1963 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2049 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1964 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2050 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1965 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2051 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1966 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2052 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1967 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2053 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1968 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2054 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1969 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2055 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1970 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2056 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1971 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2057 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1972 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2058 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1973 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2059 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1974 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 2060 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
1975 124, 124, 124, 124, 124, 124 2061 122, 122, 122, 122, 122, 122
1976 }; 2062 };
1977 register int hval = len; 2063 register int hval = len;
1978 2064
1979 switch (hval) 2065 switch (hval)
1980 { 2066 {
1999 { 2085 {
2000 static struct C_stab_entry wordlist[] = 2086 static struct C_stab_entry wordlist[] =
2001 { 2087 {
2002 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, 2088 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2003 {""}, {""}, {""}, {""}, 2089 {""}, {""}, {""}, {""},
2004 {"@end", 0, st_C_objend},
2005 {""}, {""}, {""}, {""},
2006 {"ENTRY", 0, st_C_gnumacro}, 2090 {"ENTRY", 0, st_C_gnumacro},
2007 {"@interface", 0, st_C_objprot}, 2091 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2008 {""}, 2092 {""},
2009 {"domain", C_STAR, st_C_struct}, 2093 {"if", 0, st_C_ignore},
2094 {""}, {""},
2095 {"SYSCALL", 0, st_C_gnumacro},
2096 {""}, {""}, {""}, {""}, {""}, {""}, {""},
2097 {"struct", 0, st_C_struct},
2098 {"static", 0, st_C_typespec},
2099 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2100 {"long", 0, st_C_typespec},
2101 {""}, {""}, {""}, {""}, {""},
2102 {"auto", 0, st_C_typespec},
2103 {"return", 0, st_C_ignore},
2104 {"import", C_JAVA, st_C_ignore},
2105 {""},
2106 {"switch", 0, st_C_ignore},
2107 {""},
2108 {"implements", C_JAVA, st_C_javastruct},
2109 {""},
2110 {"for", 0, st_C_ignore},
2111 {"volatile", 0, st_C_typespec},
2010 {""}, 2112 {""},
2011 {"PSEUDO", 0, st_C_gnumacro}, 2113 {"PSEUDO", 0, st_C_gnumacro},
2114 {""},
2115 {"char", 0, st_C_typespec},
2116 {"class", 0, st_C_class},
2117 {"@protocol", 0, st_C_objprot},
2012 {""}, {""}, 2118 {""}, {""},
2119 {"void", 0, st_C_typespec},
2120 {"int", 0, st_C_typespec},
2121 {"explicit", C_PLPL, st_C_typespec},
2122 {""},
2013 {"namespace", C_PLPL, st_C_struct}, 2123 {"namespace", C_PLPL, st_C_struct},
2124 {"signed", 0, st_C_typespec},
2125 {""},
2126 {"interface", C_JAVA, st_C_struct},
2127 {"while", 0, st_C_ignore},
2128 {"typedef", 0, st_C_typedef},
2129 {"typename", C_PLPL, st_C_typespec},
2130 {""}, {""}, {""},
2131 {"friend", C_PLPL, st_C_ignore},
2132 {"mutable", C_PLPL, st_C_typespec},
2133 {"union", 0, st_C_struct},
2134 {"domain", C_STAR, st_C_struct},
2014 {""}, {""}, 2135 {""}, {""},
2015 {"@implementation",0, st_C_objimpl},
2016 {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
2017 {"long", 0, st_C_typespec},
2018 {"signed", 0, st_C_typespec},
2019 {"@protocol", 0, st_C_objprot},
2020 {""}, {""}, {""}, {""},
2021 {"bool", C_PLPL, st_C_typespec},
2022 {""}, {""}, {""}, {""}, {""}, {""},
2023 {"const", 0, st_C_typespec},
2024 {"explicit", C_PLPL, st_C_typespec},
2025 {"if", 0, st_C_ignore},
2026 {""},
2027 {"operator", C_PLPL, st_C_operator},
2028 {""},
2029 {"DEFUN", 0, st_C_gnumacro},
2030 {""}, {""},
2031 {"define", 0, st_C_define},
2032 {""}, {""}, {""}, {""}, {""},
2033 {"double", 0, st_C_typespec},
2034 {"struct", 0, st_C_struct},
2035 {""}, {""}, {""}, {""},
2036 {"short", 0, st_C_typespec},
2037 {""},
2038 {"enum", 0, st_C_enum},
2039 {"mutable", C_PLPL, st_C_typespec},
2040 {""},
2041 {"extern", 0, st_C_extern}, 2136 {"extern", 0, st_C_extern},
2042 {"extends", C_JAVA, st_C_javastruct}, 2137 {"extends", C_JAVA, st_C_javastruct},
2043 {"package", C_JAVA, st_C_ignore}, 2138 {"package", C_JAVA, st_C_ignore},
2044 {"while", 0, st_C_ignore}, 2139 {"short", 0, st_C_typespec},
2140 {"@end", 0, st_C_objend},
2141 {"unsigned", 0, st_C_typespec},
2045 {""}, 2142 {""},
2046 {"for", 0, st_C_ignore}, 2143 {"const", 0, st_C_typespec},
2144 {""}, {""},
2145 {"@interface", 0, st_C_objprot},
2146 {"enum", 0, st_C_enum},
2147 {""}, {""},
2148 {"@implementation",0, st_C_objimpl},
2149 {""},
2150 {"operator", C_PLPL, st_C_operator},
2151 {""}, {""}, {""}, {""},
2152 {"define", 0, st_C_define},
2153 {""}, {""},
2154 {"double", 0, st_C_typespec},
2155 {""},
2156 {"bool", C_PLPL, st_C_typespec},
2047 {""}, {""}, {""}, 2157 {""}, {""}, {""},
2048 {"volatile", 0, st_C_typespec}, 2158 {"DEFUN", 0, st_C_gnumacro},
2049 {""}, {""}, 2159 {"float", 0, st_C_typespec}
2050 {"import", C_JAVA, st_C_ignore},
2051 {"float", 0, st_C_typespec},
2052 {"switch", 0, st_C_ignore},
2053 {"return", 0, st_C_ignore},
2054 {"implements", C_JAVA, st_C_javastruct},
2055 {""},
2056 {"static", 0, st_C_typespec},
2057 {"typedef", 0, st_C_typedef},
2058 {"typename", C_PLPL, st_C_typespec},
2059 {"unsigned", 0, st_C_typespec},
2060 {""}, {""},
2061 {"char", 0, st_C_typespec},
2062 {"class", C_PLPL, st_C_struct},
2063 {""}, {""}, {""},
2064 {"void", 0, st_C_typespec},
2065 {""}, {""},
2066 {"friend", C_PLPL, st_C_ignore},
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 }; 2160 };
2076 2161
2077 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 2162 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
2078 { 2163 {
2079 register int key = hash (str, len); 2164 register int key = hash (str, len);
2100 2185
2101 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext))) 2186 if (se == NULL || (se->c_ext && !(c_ext & se->c_ext)))
2102 return st_none; 2187 return st_none;
2103 return se->type; 2188 return se->type;
2104 } 2189 }
2190
2105 2191
2106 /* 2192 /*
2107 * C functions and variables are recognized using a simple 2193 * C functions and variables are recognized using a simple
2108 * finite automaton. fvdef is its state variable. 2194 * finite automaton. fvdef is its state variable.
2109 */ 2195 */
2110 enum 2196 enum
2111 { 2197 {
2112 fvnone, /* nothing seen */ 2198 fvnone, /* nothing seen */
2199 fdefunkey, /* Emacs DEFUN keyword seen */
2200 fdefunname, /* Emacs DEFUN name seen */
2113 foperator, /* func: operator keyword seen (cplpl) */ 2201 foperator, /* func: operator keyword seen (cplpl) */
2114 fvnameseen, /* function or variable name seen */ 2202 fvnameseen, /* function or variable name seen */
2115 fstartlist, /* func: just after open parenthesis */ 2203 fstartlist, /* func: just after open parenthesis */
2116 finlist, /* func: in parameter list */ 2204 finlist, /* func: in parameter list */
2117 flistseen, /* func: after parameter list */ 2205 flistseen, /* func: after parameter list */
2119 vignore /* var-like: ignore until ';' */ 2207 vignore /* var-like: ignore until ';' */
2120 } fvdef; 2208 } fvdef;
2121 2209
2122 bool fvextern; /* func or var: extern keyword seen; */ 2210 bool fvextern; /* func or var: extern keyword seen; */
2123 2211
2124 /* 2212 /*
2125 * typedefs are recognized using a simple finite automaton. 2213 * typedefs are recognized using a simple finite automaton.
2126 * typdef is its state variable. 2214 * typdef is its state variable.
2127 */ 2215 */
2128 enum 2216 enum
2129 { 2217 {
2130 tnone, /* nothing seen */ 2218 tnone, /* nothing seen */
2131 tkeyseen, /* typedef keyword seen */ 2219 tkeyseen, /* typedef keyword seen */
2132 ttypeseen, /* defined type seen */ 2220 ttypeseen, /* defined type seen */
2133 tinbody, /* inside typedef body */ 2221 tinbody, /* inside typedef body */
2134 tend, /* just before typedef tag */ 2222 tend, /* just before typedef tag */
2135 tignore /* junk after typedef tag */ 2223 tignore /* junk after typedef tag */
2136 } typdef; 2224 } typdef;
2137 2225
2138 2226 /*
2139 /* 2227 * struct-like structures (enum, struct and union) are recognized
2140 * struct-like structures (enum, struct and union) are recognized 2228 * using another simple finite automaton. `structdef' is its state
2141 * using another simple finite automaton. `structdef' is its state 2229 * variable.
2142 * variable. 2230 */
2143 */
2144 enum 2231 enum
2145 { 2232 {
2146 snone, /* nothing seen yet */ 2233 snone, /* nothing seen yet,
2234 or in struct body if cblev > 0 */
2147 skeyseen, /* struct-like keyword seen */ 2235 skeyseen, /* struct-like keyword seen */
2148 stagseen, /* struct-like tag seen */ 2236 stagseen, /* struct-like tag seen */
2149 scolonseen, /* colon seen after struct-like tag */ 2237 sintemplate, /* inside template (ignore) */
2150 sinbody /* in struct body: recognize member func defs*/ 2238 scolonseen /* colon seen after struct-like tag */
2151 } structdef; 2239 } structdef;
2152
2153 /*
2154 * When structdef is stagseen, scolonseen, or sinbody, structtag is the
2155 * struct tag, and structtype is the type of the preceding struct-like
2156 * keyword.
2157 */
2158 char *structtag = "<uninited>";
2159 enum sym_type structtype;
2160 2240
2161 /* 2241 /*
2162 * When objdef is different from onone, objtag is the name of the class. 2242 * When objdef is different from onone, objtag is the name of the class.
2163 */ 2243 */
2164 char *objtag = "<uninited>"; 2244 char *objtag = "<uninited>";
2174 dignorerest /* ignore rest of line */ 2254 dignorerest /* ignore rest of line */
2175 } definedef; 2255 } definedef;
2176 2256
2177 /* 2257 /*
2178 * State machine for Objective C protocols and implementations. 2258 * State machine for Objective C protocols and implementations.
2179 * Tom R.Hageman <tom@basil.icce.rug.nl> 2259 * Idea by Tom R.Hageman <tom@basil.icce.rug.nl> (1995)
2180 */ 2260 */
2181 enum 2261 enum
2182 { 2262 {
2183 onone, /* nothing seen */ 2263 onone, /* nothing seen */
2184 oprotocol, /* @interface or @protocol seen */ 2264 oprotocol, /* @interface or @protocol seen */
2197 2277
2198 /* 2278 /*
2199 * Use this structure to keep info about the token read, and how it 2279 * Use this structure to keep info about the token read, and how it
2200 * should be tagged. Used by the make_C_tag function to build a tag. 2280 * should be tagged. Used by the make_C_tag function to build a tag.
2201 */ 2281 */
2202 typedef struct 2282 struct tok
2203 { 2283 {
2204 bool valid; 2284 bool valid;
2205 char *str;
2206 bool named; 2285 bool named;
2207 int linelen; 2286 int offset;
2287 int length;
2208 int lineno; 2288 int lineno;
2209 long linepos; 2289 long linepos;
2210 char *buffer; 2290 char *line;
2211 } token; 2291 } token; /* latest token read */
2212 2292 linebuffer token_name; /* its name */
2213 token tok; /* latest token read */
2214 2293
2215 /* 2294 /*
2216 * Set this to TRUE, and the next token considered is called a function. 2295 * Variables and functions for dealing with nested structures.
2217 * Used only for GNU emacs's function-defining macros. 2296 * Idea by Mykola Dzyuba <mdzyuba@yahoo.com> (2001)
2218 */ 2297 */
2219 bool next_token_is_func; 2298 static void pushclass_above P_((int, char *, int));
2220 2299 static void popclass_above P_((int));
2221 /* 2300 static void write_classname P_((linebuffer *, char *qualifier));
2222 * TRUE in the rules part of a yacc file, FALSE outside (parse as C). 2301
2223 */ 2302 struct {
2224 bool yacc_rules; 2303 char **cname; /* nested class names */
2225 2304 int *cblev; /* nested class curly brace level */
2226 /* 2305 int nl; /* class nesting level (elements used) */
2227 * methodlen is the length of the method name stored in token_name. 2306 int size; /* length of the array */
2228 */ 2307 } cstack; /* stack for nested declaration tags */
2229 int methodlen; 2308 /* Current struct nesting depth (namespace, class, struct, union, enum). */
2230 2309 #define nestlev (cstack.nl)
2231 static bool consider_token P_((char *, int, int, int, int, int, bool *)); 2310 /* After struct keyword or in struct body, not inside an nested function. */
2311 #define instruct (structdef == snone && nestlev > 0 \
2312 && cblev == cstack.cblev[nestlev-1] + 1)
2313
2314 static void
2315 pushclass_above (cblev, str, len)
2316 int cblev;
2317 char *str;
2318 int len;
2319 {
2320 int nl;
2321
2322 popclass_above (cblev);
2323 nl = cstack.nl;
2324 if (nl >= cstack.size)
2325 {
2326 int size = cstack.size *= 2;
2327 xrnew (cstack.cname, size, char *);
2328 xrnew (cstack.cblev, size, int);
2329 }
2330 assert (nl == 0 || cstack.cblev[nl-1] < cblev);
2331 cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
2332 cstack.cblev[nl] = cblev;
2333 cstack.nl = nl + 1;
2334 }
2335
2336 static void
2337 popclass_above (cblev)
2338 int cblev;
2339 {
2340 int nl;
2341
2342 for (nl = cstack.nl - 1;
2343 nl >= 0 && cstack.cblev[nl] >= cblev;
2344 nl--)
2345 {
2346 if (cstack.cname[nl] != NULL)
2347 free (cstack.cname[nl]);
2348 cstack.nl = nl;
2349 }
2350 }
2351
2352 static void
2353 write_classname (cn, qualifier)
2354 linebuffer *cn;
2355 char *qualifier;
2356 {
2357 int i, len;
2358 int qlen = strlen (qualifier);
2359
2360 if (cstack.nl == 0 || cstack.cname[0] == NULL)
2361 {
2362 len = 0;
2363 cn->len = 0;
2364 cn->buffer[0] = '\0';
2365 }
2366 else
2367 {
2368 len = strlen (cstack.cname[0]);
2369 linebuffer_setlen (cn, len);
2370 strcpy (cn->buffer, cstack.cname[0]);
2371 }
2372 for (i = 1; i < cstack.nl; i++)
2373 {
2374 char *s;
2375 int slen;
2376
2377 s = cstack.cname[i];
2378 if (s == NULL)
2379 continue;
2380 slen = strlen (s);
2381 len += slen + qlen;
2382 linebuffer_setlen (cn, len);
2383 strncat (cn->buffer, qualifier, qlen);
2384 strncat (cn->buffer, s, slen);
2385 }
2386 }
2387
2388
2389 static bool consider_token P_((char *, int, int, int *, int, int, bool *));
2232 static void make_C_tag P_((bool)); 2390 static void make_C_tag P_((bool));
2233 2391
2234 /* 2392 /*
2235 * consider_token () 2393 * consider_token ()
2236 * checks to see if the current token is at the start of a 2394 * checks to see if the current token is at the start of a
2237 * function or variable, or corresponds to a typedef, or 2395 * function or variable, or corresponds to a typedef, or
2238 * is a struct/union/enum tag, or #define, or an enum constant. 2396 * is a struct/union/enum tag, or #define, or an enum constant.
2239 * 2397 *
2240 * *IS_FUNC gets TRUE iff the token is a function or #define macro 2398 * *IS_FUNC gets TRUE iff the token is a function or #define macro
2241 * with args. C_EXT is which language we are looking at. 2399 * with args. C_EXTP points to which language we are looking at.
2242 * 2400 *
2243 * Globals 2401 * Globals
2244 * fvdef IN OUT 2402 * fvdef IN OUT
2245 * structdef IN OUT 2403 * structdef IN OUT
2246 * definedef IN OUT 2404 * definedef IN OUT
2247 * typdef IN OUT 2405 * typdef IN OUT
2248 * objdef IN OUT 2406 * objdef IN OUT
2249 * next_token_is_func IN OUT
2250 */ 2407 */
2251 2408
2252 static bool 2409 static bool
2253 consider_token (str, len, c, c_ext, cblev, parlev, is_func_or_var) 2410 consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var)
2254 register char *str; /* IN: token pointer */ 2411 register char *str; /* IN: token pointer */
2255 register int len; /* IN: token length */ 2412 register int len; /* IN: token length */
2256 register int c; /* IN: first char after the token */ 2413 register int c; /* IN: first char after the token */
2257 int c_ext; /* IN: C extensions mask */ 2414 int *c_extp; /* IN, OUT: C extensions mask */
2258 int cblev; /* IN: curly brace level */ 2415 int cblev; /* IN: curly brace level */
2259 int parlev; /* IN: parenthesis level */ 2416 int parlev; /* IN: parenthesis level */
2260 bool *is_func_or_var; /* OUT: function or variable found */ 2417 bool *is_func_or_var; /* OUT: function or variable found */
2261 { 2418 {
2262 enum sym_type toktype = C_symtype (str, len, c_ext); 2419 /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
2420 structtype is the type of the preceding struct-like keyword, and
2421 structcblev is the curly brace level where it has been seen. */
2422 static enum sym_type structtype;
2423 static int structcblev;
2424 static enum sym_type toktype;
2425
2426
2427 toktype = C_symtype (str, len, *c_extp);
2263 2428
2264 /* 2429 /*
2265 * Advance the definedef state machine. 2430 * Advance the definedef state machine.
2266 */ 2431 */
2267 switch (definedef) 2432 switch (definedef)
2268 { 2433 {
2269 case dnone: 2434 case dnone:
2270 /* We're not on a preprocessor line. */ 2435 /* We're not on a preprocessor line. */
2436 if (toktype == st_C_gnumacro)
2437 {
2438 fvdef = fdefunkey;
2439 return FALSE;
2440 }
2271 break; 2441 break;
2272 case dsharpseen: 2442 case dsharpseen:
2273 if (toktype == st_C_define) 2443 if (toktype == st_C_define)
2274 { 2444 {
2275 definedef = ddefineseen; 2445 definedef = ddefineseen;
2314 case tkeyseen: 2484 case tkeyseen:
2315 switch (toktype) 2485 switch (toktype)
2316 { 2486 {
2317 case st_none: 2487 case st_none:
2318 case st_C_typespec: 2488 case st_C_typespec:
2489 case st_C_class:
2319 case st_C_struct: 2490 case st_C_struct:
2320 case st_C_enum: 2491 case st_C_enum:
2321 typdef = ttypeseen; 2492 typdef = ttypeseen;
2322 break; 2493 break;
2323 } 2494 }
2324 /* Do not return here, so the structdef stuff has a chance. */ 2495 break;
2496 case ttypeseen:
2497 if (structdef == snone && fvdef == fvnone)
2498 {
2499 fvdef = fvnameseen;
2500 return TRUE;
2501 }
2325 break; 2502 break;
2326 case tend: 2503 case tend:
2327 switch (toktype) 2504 switch (toktype)
2328 { 2505 {
2329 case st_C_typespec: 2506 case st_C_typespec:
2507 case st_C_class:
2330 case st_C_struct: 2508 case st_C_struct:
2331 case st_C_enum: 2509 case st_C_enum:
2332 return FALSE; 2510 return FALSE;
2333 } 2511 }
2334 return TRUE; 2512 return TRUE;
2335 } 2513 }
2336 2514
2337 /* 2515 /*
2338 * This structdef business is currently only invoked when cblev==0.
2339 * It should be recursively invoked whatever the curly brace level,
2340 * and a stack of states kept, to allow for definitions of structs
2341 * within structs.
2342 *
2343 * This structdef business is NOT invoked when we are ctags and the 2516 * This structdef business is NOT invoked when we are ctags and the
2344 * file is plain C. This is because a struct tag may have the same 2517 * file is plain C. This is because a struct tag may have the same
2345 * name as another tag, and this loses with ctags. 2518 * name as another tag, and this loses with ctags.
2346 */ 2519 */
2347 switch (toktype) 2520 switch (toktype)
2348 { 2521 {
2349 case st_C_javastruct: 2522 case st_C_javastruct:
2350 if (structdef == stagseen) 2523 if (structdef == stagseen)
2351 structdef = scolonseen; 2524 structdef = scolonseen;
2352 return FALSE; 2525 return FALSE;
2526 case st_C_class:
2527 if (cblev == 0
2528 && (*c_extp & C_AUTO) /* automatic detection of C++ language */
2529 && definedef == dnone && structdef == snone
2530 && typdef == tnone && fvdef == fvnone)
2531 *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
2532 /* FALLTHRU */
2353 case st_C_struct: 2533 case st_C_struct:
2354 case st_C_enum: 2534 case st_C_enum:
2355 if (typdef == tkeyseen 2535 if (parlev == 0
2356 || (typedefs_and_cplusplus && cblev == 0 && structdef == snone)) 2536 && fvdef != vignore
2537 && (typdef == tkeyseen
2538 || (typedefs_or_cplusplus && structdef == snone)))
2357 { 2539 {
2358 structdef = skeyseen; 2540 structdef = skeyseen;
2359 structtype = toktype; 2541 structtype = toktype;
2542 structcblev = cblev;
2360 } 2543 }
2361 return FALSE; 2544 return FALSE;
2362 } 2545 }
2363 2546
2364 if (structdef == skeyseen) 2547 if (structdef == skeyseen)
2365 { 2548 {
2366 /* Save the tag for struct/union/class, for functions and variables
2367 that may be defined inside. */
2368 if (structtype == st_C_struct)
2369 structtag = savenstr (str, len);
2370 else
2371 structtag = "<enum>";
2372 structdef = stagseen; 2549 structdef = stagseen;
2373 return TRUE; 2550 return TRUE;
2374 } 2551 }
2375 2552
2376 if (typdef != tnone) 2553 if (typdef != tnone)
2377 definedef = dnone; 2554 definedef = dnone;
2378
2379 /* Detect GNU macros.
2380
2381 Writers of emacs code are recommended to put the
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
2385 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
2387 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
2389 to name the tag with a name built from the function name, by
2390 removing the initial 'F' character and substituting '-' for '_'.
2391 Anyway, this assumes that the conventions of naming lisp
2392 functions will never change. Currently, this method is not
2393 implemented. */
2394 if (definedef == dnone && toktype == st_C_gnumacro)
2395 {
2396 next_token_is_func = TRUE;
2397 return FALSE;
2398 }
2399 if (next_token_is_func)
2400 {
2401 next_token_is_func = FALSE;
2402 fvdef = fignore;
2403 *is_func_or_var = TRUE;
2404 return TRUE;
2405 }
2406 2555
2407 /* Detect Objective C constructs. */ 2556 /* Detect Objective C constructs. */
2408 switch (objdef) 2557 switch (objdef)
2409 { 2558 {
2410 case onone: 2559 case onone:
2437 break; 2586 break;
2438 case omethodsign: 2587 case omethodsign:
2439 if (parlev == 0) 2588 if (parlev == 0)
2440 { 2589 {
2441 objdef = omethodtag; 2590 objdef = omethodtag;
2442 methodlen = len; 2591 linebuffer_setlen (&token_name, len);
2443 grow_linebuffer (&token_name, methodlen + 1);
2444 strncpy (token_name.buffer, str, len); 2592 strncpy (token_name.buffer, str, len);
2445 token_name.buffer[methodlen] = '\0'; 2593 token_name.buffer[len] = '\0';
2446 token_name.len = methodlen;
2447 return TRUE; 2594 return TRUE;
2448 } 2595 }
2449 return FALSE; 2596 return FALSE;
2450 case omethodcolon: 2597 case omethodcolon:
2451 if (parlev == 0) 2598 if (parlev == 0)
2453 return FALSE; 2600 return FALSE;
2454 case omethodparm: 2601 case omethodparm:
2455 if (parlev == 0) 2602 if (parlev == 0)
2456 { 2603 {
2457 objdef = omethodtag; 2604 objdef = omethodtag;
2458 methodlen += len; 2605 linebuffer_setlen (&token_name, token_name.len + len);
2459 grow_linebuffer (&token_name, methodlen + 1);
2460 strncat (token_name.buffer, str, len); 2606 strncat (token_name.buffer, str, len);
2461 token_name.len = methodlen;
2462 return TRUE; 2607 return TRUE;
2463 } 2608 }
2464 return FALSE; 2609 return FALSE;
2465 case oignore: 2610 case oignore:
2466 if (toktype == st_C_objend) 2611 if (toktype == st_C_objend)
2493 case st_C_operator: 2638 case st_C_operator:
2494 fvdef = foperator; 2639 fvdef = foperator;
2495 *is_func_or_var = TRUE; 2640 *is_func_or_var = TRUE;
2496 return TRUE; 2641 return TRUE;
2497 case st_none: 2642 case st_none:
2498 if ((c_ext & C_PLPL) && strneq (str+len-10, "::operator", 10)) 2643 if (constantypedefs
2499 { 2644 && structdef == snone
2500 fvdef = foperator; 2645 && structtype == st_C_enum && cblev > structcblev)
2646 return TRUE; /* enum constant */
2647 switch (fvdef)
2648 {
2649 case fdefunkey:
2650 if (cblev > 0)
2651 break;
2652 fvdef = fdefunname; /* GNU macro */
2501 *is_func_or_var = TRUE; 2653 *is_func_or_var = TRUE;
2502 return TRUE; 2654 return TRUE;
2503 } 2655 case fvnone:
2504 if (constantypedefs && structdef == sinbody && structtype == st_C_enum) 2656 if ((strneq (str, "asm", 3) && endtoken (str[3]))
2505 return TRUE; 2657 || (strneq (str, "__asm__", 7) && endtoken (str[7])))
2506 if (fvdef == fvnone) 2658 {
2507 { 2659 fvdef = vignore;
2660 return FALSE;
2661 }
2662 if ((*c_extp & C_PLPL) && strneq (str+len-10, "::operator", 10))
2663 {
2664 fvdef = foperator;
2665 *is_func_or_var = TRUE;
2666 return TRUE;
2667 }
2668 if (cblev > 0 && !instruct)
2669 break;
2508 fvdef = fvnameseen; /* function or variable */ 2670 fvdef = fvnameseen; /* function or variable */
2509 *is_func_or_var = TRUE; 2671 *is_func_or_var = TRUE;
2510 return TRUE; 2672 return TRUE;
2511 } 2673 }
2512 break; 2674 break;
2513 } 2675 }
2514 2676
2515 return FALSE; 2677 return FALSE;
2516 } 2678 }
2517 2679
2680
2518 /* 2681 /*
2519 * C_entries () 2682 * C_entries often keeps pointers to tokens or lines which are older than
2520 * This routine finds functions, variables, typedefs, 2683 * the line currently read. By keeping two line buffers, and switching
2521 * #define's, enum constants and struct/union/enum definitions in 2684 * them at end of line, it is possible to use those pointers.
2522 * C syntax and adds them to the list.
2523 */ 2685 */
2686 struct
2687 {
2688 long linepos;
2689 linebuffer lb;
2690 } lbs[2];
2691
2524 #define current_lb_is_new (newndx == curndx) 2692 #define current_lb_is_new (newndx == curndx)
2525 #define switch_line_buffers() (curndx = 1 - curndx) 2693 #define switch_line_buffers() (curndx = 1 - curndx)
2526 2694
2527 #define curlb (lbs[curndx].lb) 2695 #define curlb (lbs[curndx].lb)
2528 #define othlb (lbs[1-curndx].lb)
2529 #define newlb (lbs[newndx].lb) 2696 #define newlb (lbs[newndx].lb)
2530 #define curlinepos (lbs[curndx].linepos) 2697 #define curlinepos (lbs[curndx].linepos)
2531 #define othlinepos (lbs[1-curndx].linepos)
2532 #define newlinepos (lbs[newndx].linepos) 2698 #define newlinepos (lbs[newndx].linepos)
2533 2699
2534 #define CNL_SAVE_DEFINEDEF() \ 2700 #define CNL_SAVE_DEFINEDEF() \
2535 do { \ 2701 do { \
2536 curlinepos = charno; \ 2702 curlinepos = charno; \
2543 } while (0) 2709 } while (0)
2544 2710
2545 #define CNL() \ 2711 #define CNL() \
2546 do { \ 2712 do { \
2547 CNL_SAVE_DEFINEDEF(); \ 2713 CNL_SAVE_DEFINEDEF(); \
2548 if (savetok.valid) \ 2714 if (savetoken.valid) \
2549 { \ 2715 { \
2550 tok = savetok; \ 2716 token = savetoken; \
2551 savetok.valid = FALSE; \ 2717 savetoken.valid = FALSE; \
2552 } \ 2718 } \
2553 definedef = dnone; \ 2719 definedef = dnone; \
2554 } while (0) 2720 } while (0)
2555 2721
2556 2722
2557 static void 2723 static void
2558 make_C_tag (isfun) 2724 make_C_tag (isfun)
2559 bool isfun; 2725 bool isfun;
2560 { 2726 {
2561 /* This function should never be called when tok.valid is FALSE, but 2727 /* This function should never be called when token.valid is FALSE, but
2562 we must protect against invalid input or internal errors. */ 2728 we must protect against invalid input or internal errors. */
2563 if (tok.valid) 2729 if (DEBUG || token.valid)
2564 { 2730 {
2565 if (traditional_tag_style) 2731 if (traditional_tag_style)
2566 { 2732 {
2567 /* This was the original code. Now we call new_pfnote instead, 2733 /* This was the original code. Now we call new_pfnote instead,
2568 which uses the new method for naming tags (see new_pfnote). */ 2734 which uses the new method for naming tags (see new_pfnote). */
2569 char *name = NULL; 2735 char *name = NULL;
2570 2736
2571 if (CTAGS || tok.named) 2737 if (CTAGS || token.named)
2572 name = savestr (token_name.buffer); 2738 name = savestr (token_name.buffer);
2573 pfnote (name, isfun, 2739 if (DEBUG && !token.valid)
2574 tok.buffer, tok.linelen, tok.lineno, tok.linepos); 2740 {
2741 if (token.named)
2742 name = concat (name, "##invalid##", "");
2743 else
2744 name = savestr ("##invalid##");
2745 }
2746 pfnote (name, isfun, token.line,
2747 token.offset+token.length+1, token.lineno, token.linepos);
2575 } 2748 }
2576 else 2749 else
2577 new_pfnote (token_name.buffer, token_name.len, isfun, 2750 new_pfnote (token_name.buffer, token_name.len, isfun, token.line,
2578 tok.buffer, tok.linelen, tok.lineno, tok.linepos); 2751 token.offset+token.length+1, token.lineno, token.linepos);
2579 tok.valid = FALSE; 2752 token.valid = FALSE;
2580 } 2753 }
2581 else if (DEBUG) 2754 }
2582 abort (); 2755
2583 } 2756
2584 2757 /*
2585 2758 * C_entries ()
2759 * This routine finds functions, variables, typedefs,
2760 * #define's, enum constants and struct/union/enum definitions in
2761 * C syntax and adds them to the list.
2762 */
2586 static void 2763 static void
2587 C_entries (c_ext, inf) 2764 C_entries (c_ext, inf)
2588 int c_ext; /* extension of C */ 2765 int c_ext; /* extension of C */
2589 FILE *inf; /* input file */ 2766 FILE *inf; /* input file */
2590 { 2767 {
2595 register int toklen; /* length of current token */ 2772 register int toklen; /* length of current token */
2596 char *qualifier; /* string used to qualify names */ 2773 char *qualifier; /* string used to qualify names */
2597 int qlen; /* length of qualifier */ 2774 int qlen; /* length of qualifier */
2598 int cblev; /* current curly brace level */ 2775 int cblev; /* current curly brace level */
2599 int parlev; /* current parenthesis level */ 2776 int parlev; /* current parenthesis level */
2777 int typdefcblev; /* cblev where a typedef struct body begun */
2600 bool incomm, inquote, inchar, quotednl, midtoken; 2778 bool incomm, inquote, inchar, quotednl, midtoken;
2601 bool purec, cplpl, cjava; 2779 bool cplpl, cjava;
2602 token savetok; /* token saved during preprocessor handling */ 2780 bool yacc_rules; /* in the rules part of a yacc file */
2603 2781 struct tok savetoken; /* token saved during preprocessor handling */
2782
2783
2784 initbuffer (&token_name);
2785 initbuffer (&lbs[0].lb);
2786 initbuffer (&lbs[1].lb);
2787 if (cstack.size == 0)
2788 {
2789 cstack.size = (DEBUG) ? 1 : 4;
2790 cstack.nl = 0;
2791 cstack.cname = xnew (cstack.size, char *);
2792 cstack.cblev = xnew (cstack.size, int);
2793 }
2604 2794
2605 tokoff = toklen = 0; /* keep compiler quiet */ 2795 tokoff = toklen = 0; /* keep compiler quiet */
2606 curndx = newndx = 0; 2796 curndx = newndx = 0;
2607 lineno = 0; 2797 lineno = 0;
2608 charno = 0; 2798 charno = 0;
2609 lp = curlb.buffer; 2799 lp = curlb.buffer;
2610 *lp = 0; 2800 *lp = 0;
2611 2801
2612 fvdef = fvnone; fvextern = FALSE; typdef = tnone; 2802 fvdef = fvnone; fvextern = FALSE; typdef = tnone;
2613 structdef = snone; definedef = dnone; objdef = onone; 2803 structdef = snone; definedef = dnone; objdef = onone;
2614 next_token_is_func = yacc_rules = FALSE; 2804 yacc_rules = FALSE;
2615 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2805 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2616 tok.valid = savetok.valid = FALSE; 2806 token.valid = savetoken.valid = FALSE;
2617 cblev = 0; 2807 cblev = 0;
2618 parlev = 0; 2808 parlev = 0;
2619 purec = !(c_ext & ~YACC); /* no extensions (apart from possibly yacc) */
2620 cplpl = (c_ext & C_PLPL) == C_PLPL; 2809 cplpl = (c_ext & C_PLPL) == C_PLPL;
2621 cjava = (c_ext & C_JAVA) == C_JAVA; 2810 cjava = (c_ext & C_JAVA) == C_JAVA;
2622 if (cjava) 2811 if (cjava)
2623 { qualifier = "."; qlen = 1; } 2812 { qualifier = "."; qlen = 1; }
2624 else 2813 else
2625 { qualifier = "::"; qlen = 2; } 2814 { qualifier = "::"; qlen = 2; }
2815
2626 2816
2627 while (!feof (inf)) 2817 while (!feof (inf))
2628 { 2818 {
2629 c = *lp++; 2819 c = *lp++;
2630 if (c == '\\') 2820 if (c == '\\')
2692 else 2882 else
2693 switch (c) 2883 switch (c)
2694 { 2884 {
2695 case '"': 2885 case '"':
2696 inquote = TRUE; 2886 inquote = TRUE;
2697 if (fvdef != finlist && fvdef != fignore && fvdef !=vignore) 2887 switch (fvdef)
2698 { 2888 {
2889 case fdefunkey:
2890 case fstartlist:
2891 case finlist:
2892 case fignore:
2893 case vignore:
2894 break;
2895 default:
2699 fvextern = FALSE; 2896 fvextern = FALSE;
2700 fvdef = fvnone; 2897 fvdef = fvnone;
2701 } 2898 }
2702 continue; 2899 continue;
2703 case '\'': 2900 case '\'':
2723 else 2920 else
2724 break; 2921 break;
2725 case '%': 2922 case '%':
2726 if ((c_ext & YACC) && *lp == '%') 2923 if ((c_ext & YACC) && *lp == '%')
2727 { 2924 {
2728 /* entering or exiting rules section in yacc file */ 2925 /* Entering or exiting rules section in yacc file. */
2729 lp++; 2926 lp++;
2730 definedef = dnone; fvdef = fvnone; fvextern = FALSE; 2927 definedef = dnone; fvdef = fvnone; fvextern = FALSE;
2731 typdef = tnone; structdef = snone; 2928 typdef = tnone; structdef = snone;
2732 next_token_is_func = FALSE;
2733 midtoken = inquote = inchar = incomm = quotednl = FALSE; 2929 midtoken = inquote = inchar = incomm = quotednl = FALSE;
2734 cblev = 0; 2930 cblev = 0;
2735 yacc_rules = !yacc_rules; 2931 yacc_rules = !yacc_rules;
2736 continue; 2932 continue;
2737 } 2933 }
2763 2959
2764 continue; 2960 continue;
2765 } /* switch (c) */ 2961 } /* switch (c) */
2766 2962
2767 2963
2768 /* Consider token only if some complicated conditions are satisfied. */ 2964 /* Consider token only if some involved conditions are satisfied. */
2769 if ((definedef != dnone 2965 if (typdef != tignore
2770 || (cblev == 0 && structdef != scolonseen)
2771 || (cblev == 1 && cplpl && structdef == sinbody)
2772 || (structdef == sinbody && purec))
2773 && typdef != tignore
2774 && definedef != dignorerest 2966 && definedef != dignorerest
2775 && fvdef != finlist) 2967 && fvdef != finlist
2968 && structdef != sintemplate
2969 && (definedef != dnone
2970 || structdef != scolonseen))
2776 { 2971 {
2777 if (midtoken) 2972 if (midtoken)
2778 { 2973 {
2779 if (endtoken (c)) 2974 if (endtoken (c))
2780 { 2975 {
2781 bool funorvar = FALSE;
2782
2783 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1])) 2976 if (c == ':' && cplpl && *lp == ':' && begtoken (lp[1]))
2784 { 2977 {
2785 /* 2978 /*
2786 * This handles :: in the middle, but not at the 2979 * This handles :: in the middle, but not at the
2787 * beginning of an identifier. Also, space-separated 2980 * beginning of an identifier. Also, space-separated
2788 * :: is not recognised. 2981 * :: is not recognised.
2789 */ 2982 */
2790 lp += 2; 2983 lp += 2;
2791 toklen += 2; 2984 toklen += 2;
2792 c = lp[-1]; 2985 c = lp[-1];
2793 goto intok; 2986 goto still_in_token;
2794 } 2987 }
2795 else 2988 else
2796 { 2989 {
2990 bool funorvar = FALSE;
2991
2797 if (yacc_rules 2992 if (yacc_rules
2798 || consider_token (newlb.buffer + tokoff, toklen, c, 2993 || consider_token (newlb.buffer + tokoff, toklen, c,
2799 c_ext, cblev, parlev, &funorvar)) 2994 &c_ext, cblev, parlev, &funorvar))
2800 { 2995 {
2801 if (fvdef == foperator) 2996 if (fvdef == foperator)
2802 { 2997 {
2803 char *oldlp = lp; 2998 char *oldlp = lp;
2804 lp = skip_spaces (lp-1); 2999 lp = skip_spaces (lp-1);
2808 && !iswhite (*lp) && *lp != '(') 3003 && !iswhite (*lp) && *lp != '(')
2809 lp += 1; 3004 lp += 1;
2810 c = *lp++; 3005 c = *lp++;
2811 toklen += lp - oldlp; 3006 toklen += lp - oldlp;
2812 } 3007 }
2813 tok.named = FALSE; 3008 token.named = FALSE;
2814 if (!purec 3009 if ((c_ext & C_EXT) /* not pure C */
2815 && funorvar 3010 && nestlev > 0 && definedef == dnone)
2816 && definedef == dnone 3011 /* in struct body */
2817 && structdef == sinbody)
2818 /* function or var defined in C++ class body */
2819 { 3012 {
2820 int len = strlen (structtag) + qlen + toklen; 3013 write_classname (&token_name, qualifier);
2821 grow_linebuffer (&token_name, len + 1); 3014 linebuffer_setlen (&token_name,
2822 strcpy (token_name.buffer, structtag); 3015 token_name.len+qlen+toklen);
2823 strcat (token_name.buffer, qualifier); 3016 strcat (token_name.buffer, qualifier);
2824 strncat (token_name.buffer, 3017 strncat (token_name.buffer,
2825 newlb.buffer + tokoff, toklen); 3018 newlb.buffer + tokoff, toklen);
2826 token_name.len = len; 3019 token.named = TRUE;
2827 tok.named = TRUE;
2828 } 3020 }
2829 else if (objdef == ocatseen) 3021 else if (objdef == ocatseen)
2830 /* Objective C category */ 3022 /* Objective C category */
2831 { 3023 {
2832 int len = strlen (objtag) + 2 + toklen; 3024 int len = strlen (objtag) + 2 + toklen;
2833 grow_linebuffer (&token_name, len + 1); 3025 linebuffer_setlen (&token_name, len);
2834 strcpy (token_name.buffer, objtag); 3026 strcpy (token_name.buffer, objtag);
2835 strcat (token_name.buffer, "("); 3027 strcat (token_name.buffer, "(");
2836 strncat (token_name.buffer, 3028 strncat (token_name.buffer,
2837 newlb.buffer + tokoff, toklen); 3029 newlb.buffer + tokoff, toklen);
2838 strcat (token_name.buffer, ")"); 3030 strcat (token_name.buffer, ")");
2839 token_name.len = len; 3031 token.named = TRUE;
2840 tok.named = TRUE;
2841 } 3032 }
2842 else if (objdef == omethodtag 3033 else if (objdef == omethodtag
2843 || objdef == omethodparm) 3034 || objdef == omethodparm)
2844 /* Objective C method */ 3035 /* Objective C method */
2845 { 3036 {
2846 tok.named = TRUE; 3037 token.named = TRUE;
3038 }
3039 else if (fvdef == fdefunname)
3040 /* GNU DEFUN and similar macros */
3041 {
3042 bool defun = (newlb.buffer[tokoff] == 'F');
3043 int off = tokoff;
3044 int len = toklen;
3045
3046 /* Rewrite the tag so that emacs lisp DEFUNs
3047 can be found by their elisp name */
3048 if (defun)
3049 {
3050 off += 1;
3051 len -= 1;
3052 }
3053 len = toklen;
3054 linebuffer_setlen (&token_name, len);
3055 strncpy (token_name.buffer,
3056 newlb.buffer + off, len);
3057 token_name.buffer[len] = '\0';
3058 if (defun)
3059 while (--len >= 0)
3060 if (token_name.buffer[len] == '_')
3061 token_name.buffer[len] = '-';
3062 token.named = defun;
2847 } 3063 }
2848 else 3064 else
2849 { 3065 {
2850 grow_linebuffer (&token_name, toklen + 1); 3066 linebuffer_setlen (&token_name, toklen);
2851 strncpy (token_name.buffer, 3067 strncpy (token_name.buffer,
2852 newlb.buffer + tokoff, toklen); 3068 newlb.buffer + tokoff, toklen);
2853 token_name.buffer[toklen] = '\0'; 3069 token_name.buffer[toklen] = '\0';
2854 token_name.len = toklen;
2855 /* Name macros and members. */ 3070 /* Name macros and members. */
2856 tok.named = (structdef == stagseen 3071 token.named = (structdef == stagseen
2857 || typdef == ttypeseen 3072 || typdef == ttypeseen
2858 || typdef == tend 3073 || typdef == tend
2859 || (funorvar 3074 || (funorvar
2860 && definedef == dignorerest) 3075 && definedef == dignorerest)
2861 || (funorvar 3076 || (funorvar
2862 && definedef == dnone 3077 && definedef == dnone
2863 && structdef == sinbody)); 3078 && structdef == snone
3079 && cblev > 0));
2864 } 3080 }
2865 tok.lineno = lineno; 3081 token.lineno = lineno;
2866 tok.linelen = tokoff + toklen + 1; 3082 token.offset = tokoff;
2867 tok.buffer = newlb.buffer; 3083 token.length = toklen;
2868 tok.linepos = newlinepos; 3084 token.line = newlb.buffer;
2869 tok.valid = TRUE; 3085 token.linepos = newlinepos;
3086 token.valid = TRUE;
2870 3087
2871 if (definedef == dnone 3088 if (definedef == dnone
2872 && (fvdef == fvnameseen 3089 && (fvdef == fvnameseen
2873 || fvdef == foperator 3090 || fvdef == foperator
2874 || structdef == stagseen 3091 || structdef == stagseen
2875 || typdef == tend 3092 || typdef == tend
3093 || typdef == ttypeseen
2876 || objdef != onone)) 3094 || objdef != onone))
2877 { 3095 {
2878 if (current_lb_is_new) 3096 if (current_lb_is_new)
2879 switch_line_buffers (); 3097 switch_line_buffers ();
2880 } 3098 }
2881 else 3099 else if (definedef != dnone
3100 || fvdef == fdefunname
3101 || instruct)
2882 make_C_tag (funorvar); 3102 make_C_tag (funorvar);
2883 } 3103 }
2884 midtoken = FALSE; 3104 midtoken = FALSE;
2885 } 3105 }
2886 } /* if (endtoken (c)) */ 3106 } /* if (endtoken (c)) */
2887 else if (intoken (c)) 3107 else if (intoken (c))
2888 intok: 3108 still_in_token:
2889 { 3109 {
2890 toklen++; 3110 toklen++;
2891 continue; 3111 continue;
2892 } 3112 }
2893 } /* if (midtoken) */ 3113 } /* if (midtoken) */
2908 case fvnameseen: 3128 case fvnameseen:
2909 fvdef = fvnone; 3129 fvdef = fvnone;
2910 break; 3130 break;
2911 } 3131 }
2912 if (structdef == stagseen && !cjava) 3132 if (structdef == stagseen && !cjava)
2913 structdef = snone; 3133 {
3134 popclass_above (cblev);
3135 structdef = snone;
3136 }
2914 break; 3137 break;
2915 case dsharpseen: 3138 case dsharpseen:
2916 savetok = tok; 3139 savetoken = token;
2917 } 3140 }
2918 if (!yacc_rules || lp == newlb.buffer + 1) 3141 if (!yacc_rules || lp == newlb.buffer + 1)
2919 { 3142 {
2920 tokoff = lp - 1 - newlb.buffer; 3143 tokoff = lp - 1 - newlb.buffer;
2921 toklen = 1; 3144 toklen = 1;
2929 /* Detect end of line, colon, comma, semicolon and various braces 3152 /* Detect end of line, colon, comma, semicolon and various braces
2930 after having handled a token.*/ 3153 after having handled a token.*/
2931 switch (c) 3154 switch (c)
2932 { 3155 {
2933 case ':': 3156 case ':':
3157 if (yacc_rules && token.offset == 0 && token.valid)
3158 {
3159 make_C_tag (FALSE); /* a yacc function */
3160 break;
3161 }
2934 if (definedef != dnone) 3162 if (definedef != dnone)
2935 break; 3163 break;
2936 switch (objdef) 3164 switch (objdef)
2937 { 3165 {
2938 case otagseen: 3166 case otagseen:
2940 make_C_tag (TRUE); /* an Objective C class */ 3168 make_C_tag (TRUE); /* an Objective C class */
2941 break; 3169 break;
2942 case omethodtag: 3170 case omethodtag:
2943 case omethodparm: 3171 case omethodparm:
2944 objdef = omethodcolon; 3172 objdef = omethodcolon;
2945 methodlen += 1; 3173 linebuffer_setlen (&token_name, token_name.len + 1);
2946 grow_linebuffer (&token_name, methodlen + 1);
2947 strcat (token_name.buffer, ":"); 3174 strcat (token_name.buffer, ":");
2948 token_name.len = methodlen;
2949 break; 3175 break;
2950 } 3176 }
2951 if (structdef == stagseen) 3177 if (structdef == stagseen)
2952 structdef = scolonseen; 3178 structdef = scolonseen;
2953 else
2954 switch (fvdef)
2955 {
2956 case fvnameseen:
2957 if (yacc_rules)
2958 {
2959 make_C_tag (FALSE); /* a yacc function */
2960 fvdef = fignore;
2961 }
2962 break;
2963 case fstartlist:
2964 fvextern = FALSE;
2965 fvdef = fvnone;
2966 break;
2967 }
2968 break; 3179 break;
2969 case ';': 3180 case ';':
2970 if (definedef != dnone) 3181 if (definedef != dnone)
2971 break; 3182 break;
2972 if (cblev == 0) 3183 switch (typdef)
2973 switch (typdef)
2974 {
2975 case tend:
2976 make_C_tag (FALSE); /* a typedef */
2977 /* FALLTHRU */
2978 default:
2979 typdef = tnone;
2980 }
2981 switch (fvdef)
2982 { 3184 {
2983 case fignore: 3185 case tend:
3186 case ttypeseen:
3187 make_C_tag (FALSE); /* a typedef */
3188 typdef = tnone;
3189 fvdef = fvnone;
2984 break; 3190 break;
2985 case fvnameseen: 3191 case tnone:
2986 if ((members && cblev == 1) 3192 case tinbody:
2987 || (globals && cblev == 0 && (!fvextern || declarations))) 3193 case tignore:
2988 make_C_tag (FALSE); /* a variable */ 3194 switch (fvdef)
2989 fvextern = FALSE; 3195 {
2990 fvdef = fvnone; 3196 case fignore:
2991 tok.valid = FALSE; 3197 if (typdef == tignore)
2992 break; 3198 fvdef = fvnone;
2993 case flistseen: 3199 break;
2994 if (declarations && (cblev == 0 || cblev == 1)) 3200 case fvnameseen:
2995 make_C_tag (TRUE); /* a function declaration */ 3201 if ((globals && cblev == 0 && (!fvextern || declarations))
3202 || (members && instruct))
3203 make_C_tag (FALSE); /* a variable */
3204 fvextern = FALSE;
3205 fvdef = fvnone;
3206 token.valid = FALSE;
3207 break;
3208 case flistseen:
3209 if ((declarations && typdef == tnone && !instruct)
3210 || (members && typdef != tignore && instruct))
3211 make_C_tag (TRUE); /* a function declaration */
3212 /* FALLTHRU */
3213 default:
3214 fvextern = FALSE;
3215 fvdef = fvnone;
3216 if (declarations
3217 && structdef == stagseen && (c_ext & C_PLPL))
3218 make_C_tag (FALSE); /* forward declaration */
3219 else
3220 /* The following instruction invalidates the token.
3221 Probably the token should be invalidated in all other
3222 cases where some state machine is reset prematurely. */
3223 token.valid = FALSE;
3224 } /* switch (fvdef) */
2996 /* FALLTHRU */ 3225 /* FALLTHRU */
2997 default: 3226 default:
2998 fvextern = FALSE; 3227 if (!instruct)
2999 fvdef = fvnone; 3228 typdef = tnone;
3000 /* The following instruction invalidates the token.
3001 Probably the token should be invalidated in all
3002 other cases where some state machine is reset. */
3003 tok.valid = FALSE;
3004 } 3229 }
3005 if (structdef == stagseen) 3230 if (structdef == stagseen)
3006 structdef = snone; 3231 structdef = snone;
3007 break; 3232 break;
3008 case ',': 3233 case ',':
3016 objdef = oinbody; 3241 objdef = oinbody;
3017 break; 3242 break;
3018 } 3243 }
3019 switch (fvdef) 3244 switch (fvdef)
3020 { 3245 {
3246 case fdefunkey:
3021 case foperator: 3247 case foperator:
3248 case fstartlist:
3022 case finlist: 3249 case finlist:
3023 case fignore: 3250 case fignore:
3024 case vignore: 3251 case vignore:
3025 break; 3252 break;
3026 case fvnameseen: 3253 case fdefunname:
3027 if ((members && cblev == 1) 3254 fvdef = fignore;
3028 || (globals && cblev == 0 && (!fvextern || declarations))) 3255 break;
3029 make_C_tag (FALSE); /* a variable */ 3256 case fvnameseen: /* a variable */
3257 if ((globals && cblev == 0 && (!fvextern || declarations))
3258 || (members && instruct))
3259 make_C_tag (FALSE);
3260 break;
3261 case flistseen: /* a function */
3262 if ((declarations && typdef == tnone && !instruct)
3263 || (members && typdef != tignore && instruct))
3264 {
3265 make_C_tag (TRUE); /* a function declaration */
3266 fvdef = fvnameseen;
3267 }
3268 else if (!declarations)
3269 fvdef = fvnone;
3270 token.valid = FALSE;
3030 break; 3271 break;
3031 default: 3272 default:
3032 fvdef = fvnone; 3273 fvdef = fvnone;
3033 } 3274 }
3034 if (structdef == stagseen) 3275 if (structdef == stagseen)
3035 structdef = snone; 3276 structdef = snone;
3036 break; 3277 break;
3037 case '[': 3278 case '[':
3038 if (definedef != dnone) 3279 if (definedef != dnone)
3039 break; 3280 break;
3040 if (cblev == 0 && typdef == tend) 3281 if (structdef == stagseen)
3282 structdef = snone;
3283 switch (typdef)
3041 { 3284 {
3285 case ttypeseen:
3286 case tend:
3042 typdef = tignore; 3287 typdef = tignore;
3043 make_C_tag (FALSE); /* a typedef */ 3288 make_C_tag (FALSE); /* a typedef */
3044 break; 3289 break;
3290 case tnone:
3291 case tinbody:
3292 switch (fvdef)
3293 {
3294 case foperator:
3295 case finlist:
3296 case fignore:
3297 case vignore:
3298 break;
3299 case fvnameseen:
3300 if ((members && cblev == 1)
3301 || (globals && cblev == 0
3302 && (!fvextern || declarations)))
3303 make_C_tag (FALSE); /* a variable */
3304 /* FALLTHRU */
3305 default:
3306 fvdef = fvnone;
3307 }
3308 break;
3045 } 3309 }
3046 switch (fvdef)
3047 {
3048 case foperator:
3049 case finlist:
3050 case fignore:
3051 case vignore:
3052 break;
3053 case fvnameseen:
3054 if ((members && cblev == 1)
3055 || (globals && cblev == 0 && (!fvextern || declarations)))
3056 make_C_tag (FALSE); /* a variable */
3057 /* FALLTHRU */
3058 default:
3059 fvdef = fvnone;
3060 }
3061 if (structdef == stagseen)
3062 structdef = snone;
3063 break; 3310 break;
3064 case '(': 3311 case '(':
3065 if (definedef != dnone) 3312 if (definedef != dnone)
3066 break; 3313 break;
3067 if (objdef == otagseen && parlev == 0) 3314 if (objdef == otagseen && parlev == 0)
3068 objdef = oparenseen; 3315 objdef = oparenseen;
3069 switch (fvdef) 3316 switch (fvdef)
3070 { 3317 {
3071 case fvnameseen: 3318 case fvnameseen:
3072 if (typdef == ttypeseen 3319 if (typdef == ttypeseen
3073 && tok.valid
3074 && *lp != '*' 3320 && *lp != '*'
3075 && structdef != sinbody) 3321 && !instruct)
3076 { 3322 {
3077 /* This handles constructs like: 3323 /* This handles constructs like:
3078 typedef void OperatorFun (int fun); */ 3324 typedef void OperatorFun (int fun); */
3079 make_C_tag (FALSE); 3325 make_C_tag (FALSE);
3080 typdef = tignore; 3326 typdef = tignore;
3327 fvdef = fignore;
3328 break;
3081 } 3329 }
3082 /* FALLTHRU */ 3330 /* FALLTHRU */
3083 case foperator: 3331 case foperator:
3084 fvdef = fstartlist; 3332 fvdef = fstartlist;
3085 break; 3333 break;
3104 case fstartlist: 3352 case fstartlist:
3105 case finlist: 3353 case finlist:
3106 fvdef = flistseen; 3354 fvdef = flistseen;
3107 break; 3355 break;
3108 } 3356 }
3109 if (cblev == 0 && (typdef == tend)) 3357 if (!instruct
3358 && (typdef == tend
3359 || typdef == ttypeseen))
3110 { 3360 {
3111 typdef = tignore; 3361 typdef = tignore;
3112 make_C_tag (FALSE); /* a typedef */ 3362 make_C_tag (FALSE); /* a typedef */
3113 } 3363 }
3114 } 3364 }
3117 break; 3367 break;
3118 case '{': 3368 case '{':
3119 if (definedef != dnone) 3369 if (definedef != dnone)
3120 break; 3370 break;
3121 if (typdef == ttypeseen) 3371 if (typdef == ttypeseen)
3122 typdef = tinbody;
3123 switch (structdef)
3124 { 3372 {
3125 case skeyseen: /* unnamed struct */ 3373 typdefcblev = cblev;
3126 structdef = sinbody; 3374 typdef = tinbody;
3127 structtag = "_anonymous_";
3128 break;
3129 case stagseen:
3130 case scolonseen: /* named struct */
3131 structdef = sinbody;
3132 make_C_tag (FALSE); /* a struct */
3133 break;
3134 } 3375 }
3135 switch (fvdef) 3376 switch (fvdef)
3136 { 3377 {
3137 case flistseen: 3378 case flistseen:
3138 make_C_tag (TRUE); /* a function */ 3379 make_C_tag (TRUE); /* a function */
3139 /* FALLTHRU */ 3380 /* FALLTHRU */
3140 case fignore: 3381 case fignore:
3141 fvdef = fvnone; 3382 fvdef = fvnone;
3142 break; 3383 break;
3143 case fvnone: 3384 case fvnone:
3152 make_C_tag (TRUE); /* an Objective C method */ 3393 make_C_tag (TRUE); /* an Objective C method */
3153 objdef = oinbody; 3394 objdef = oinbody;
3154 break; 3395 break;
3155 default: 3396 default:
3156 /* Neutralize `extern "C" {' grot. */ 3397 /* Neutralize `extern "C" {' grot. */
3157 if (cblev == 0 && structdef == snone && typdef == tnone) 3398 if (cblev == 0 && structdef == snone && nestlev == 0
3399 && typdef == tnone)
3158 cblev = -1; 3400 cblev = -1;
3159 } 3401 }
3402 }
3403 switch (structdef)
3404 {
3405 case skeyseen: /* unnamed struct */
3406 pushclass_above (cblev, NULL, 0);
3407 structdef = snone;
3408 break;
3409 case stagseen: /* named struct or enum */
3410 case scolonseen: /* a class */
3411 pushclass_above (cblev, token.line+token.offset, token.length);
3412 structdef = snone;
3413 make_C_tag (FALSE); /* a struct or enum */
3414 break;
3160 } 3415 }
3161 cblev++; 3416 cblev++;
3162 break; 3417 break;
3163 case '*': 3418 case '*':
3164 if (definedef != dnone) 3419 if (definedef != dnone)
3174 cblev = 0; /* reset curly brace level if first column */ 3429 cblev = 0; /* reset curly brace level if first column */
3175 parlev = 0; /* also reset paren level, just in case... */ 3430 parlev = 0; /* also reset paren level, just in case... */
3176 } 3431 }
3177 else if (cblev > 0) 3432 else if (cblev > 0)
3178 cblev--; 3433 cblev--;
3179 if (cblev == 0) 3434 popclass_above (cblev);
3435 structdef = snone;
3436 if (typdef == tinbody && cblev <= typdefcblev)
3180 { 3437 {
3181 if (typdef == tinbody) 3438 assert (cblev == typdefcblev);
3182 typdef = tend; 3439 typdef = tend;
3183 /* Memory leakage here: the string pointed by structtag is
3184 never released, because I fear to miss something and
3185 break things while freeing the area. The amount of
3186 memory leaked here is the sum of the lengths of the
3187 struct tags.
3188 if (structdef == sinbody)
3189 free (structtag); */
3190
3191 structdef = snone;
3192 structtag = "<error>";
3193 } 3440 }
3194 break; 3441 break;
3195 case '=': 3442 case '=':
3196 if (definedef != dnone) 3443 if (definedef != dnone)
3197 break; 3444 break;
3209 /* FALLTHRU */ 3456 /* FALLTHRU */
3210 default: 3457 default:
3211 fvdef = vignore; 3458 fvdef = vignore;
3212 } 3459 }
3213 break; 3460 break;
3461 case '<':
3462 if (cplpl && structdef == stagseen)
3463 {
3464 structdef = sintemplate;
3465 break;
3466 }
3467 goto resetfvdef;
3468 case '>':
3469 if (structdef == sintemplate)
3470 {
3471 structdef = stagseen;
3472 break;
3473 }
3474 goto resetfvdef;
3214 case '+': 3475 case '+':
3215 case '-': 3476 case '-':
3216 if (objdef == oinbody && cblev == 0) 3477 if (objdef == oinbody && cblev == 0)
3217 { 3478 {
3218 objdef = omethodsign; 3479 objdef = omethodsign;
3219 break; 3480 break;
3220 } 3481 }
3221 /* FALLTHRU */ 3482 /* FALLTHRU */
3483 resetfvdef:
3222 case '#': case '~': case '&': case '%': case '/': case '|': 3484 case '#': case '~': case '&': case '%': case '/': case '|':
3223 case '^': case '!': case '<': case '>': case '.': case '?': case ']': 3485 case '^': case '!': case '.': case '?': case ']':
3224 if (definedef != dnone) 3486 if (definedef != dnone)
3225 break; 3487 break;
3226 /* These surely cannot follow a function tag in C. */ 3488 /* These surely cannot follow a function tag in C. */
3227 switch (fvdef) 3489 switch (fvdef)
3228 { 3490 {
3248 CNL (); 3510 CNL ();
3249 break; 3511 break;
3250 } /* switch (c) */ 3512 } /* switch (c) */
3251 3513
3252 } /* while not eof */ 3514 } /* while not eof */
3515
3516 free (token_name.buffer);
3517 free (lbs[0].lb.buffer);
3518 free (lbs[1].lb.buffer);
3253 } 3519 }
3254 3520
3255 /* 3521 /*
3256 * Process either a C++ file or a C file depending on the setting 3522 * Process either a C++ file or a C file depending on the setting
3257 * of a global flag. 3523 * of a global flag.
3258 */ 3524 */
3259 static void 3525 static void
3260 default_C_entries (inf) 3526 default_C_entries (inf)
3261 FILE *inf; 3527 FILE *inf;
3262 { 3528 {
3263 C_entries (cplusplus ? C_PLPL : 0, inf); 3529 C_entries (cplusplus ? C_PLPL : C_AUTO, inf);
3264 } 3530 }
3265 3531
3266 /* Always do plain ANSI C. */ 3532 /* Always do plain C. */
3267 static void 3533 static void
3268 plain_C_entries (inf) 3534 plain_C_entries (inf)
3269 FILE *inf; 3535 FILE *inf;
3270 { 3536 {
3271 C_entries (0, inf); 3537 C_entries (0, inf);
3300 Yacc_entries (inf) 3566 Yacc_entries (inf)
3301 FILE *inf; 3567 FILE *inf;
3302 { 3568 {
3303 C_entries (YACC, inf); 3569 C_entries (YACC, inf);
3304 } 3570 }
3571
3305 3572
3306 /* A useful macro. */ 3573 /* A useful macro. */
3307 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ 3574 #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \
3308 for (lineno = charno = 0; /* loop initialization */ \ 3575 for (lineno = charno = 0; /* loop initialization */ \
3309 !feof (file_pointer) /* loop test */ \ 3576 !feof (file_pointer) /* loop test */ \
3326 register char *dummy; 3593 register char *dummy;
3327 3594
3328 LOOP_ON_INPUT_LINES (inf, lb, dummy) 3595 LOOP_ON_INPUT_LINES (inf, lb, dummy)
3329 continue; 3596 continue;
3330 } 3597 }
3598
3331 3599
3332 /* Fortran parsing */ 3600 /* Fortran parsing */
3333 3601
3334 static bool tail P_((char *)); 3602 static bool tail P_((char *));
3335 static void takeprec P_((void)); 3603 static void takeprec P_((void));
3362 if (strneq (dbp, "(*)", 3)) 3630 if (strneq (dbp, "(*)", 3))
3363 { 3631 {
3364 dbp += 3; 3632 dbp += 3;
3365 return; 3633 return;
3366 } 3634 }
3367 if (!isdigit ((unsigned char) *dbp)) 3635 if (!ISDIGIT (*dbp))
3368 { 3636 {
3369 --dbp; /* force failure */ 3637 --dbp; /* force failure */
3370 return; 3638 return;
3371 } 3639 }
3372 do 3640 do
3373 dbp++; 3641 dbp++;
3374 while (isdigit ((unsigned char) *dbp)); 3642 while (ISDIGIT (*dbp));
3375 } 3643 }
3376 3644
3377 static void 3645 static void
3378 getit (inf) 3646 getit (inf)
3379 FILE *inf; 3647 FILE *inf;
3390 if (dbp[5] != '&') 3658 if (dbp[5] != '&')
3391 return; 3659 return;
3392 dbp += 6; 3660 dbp += 6;
3393 dbp = skip_spaces (dbp); 3661 dbp = skip_spaces (dbp);
3394 } 3662 }
3395 if (!isalpha ((unsigned char) *dbp) && *dbp != '_' && *dbp != '$') 3663 if (!ISALPHA (*dbp) && *dbp != '_' && *dbp != '$')
3396 return; 3664 return;
3397 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++) 3665 for (cp = dbp + 1; *cp != '\0' && intoken (*cp); cp++)
3398 continue; 3666 continue;
3399 pfnote (savenstr (dbp, cp-dbp), TRUE, 3667 pfnote (savenstr (dbp, cp-dbp), TRUE,
3400 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3668 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3471 } 3739 }
3472 continue; 3740 continue;
3473 } 3741 }
3474 } 3742 }
3475 } 3743 }
3744
3476 3745
3477 /* 3746 /*
3478 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be>, 1998-04-24
3479 * Ada parsing 3747 * Ada parsing
3748 * Philippe Waroquiers <philippe.waroquiers@eurocontrol.be> (1998)
3480 */ 3749 */
3481 3750
3482 static void adagetit P_((FILE *, char *)); 3751 static void adagetit P_((FILE *, char *));
3483 3752
3484 /* Once we are positioned after an "interesting" keyword, let's get 3753 /* Once we are positioned after an "interesting" keyword, let's get
3531 else 3800 else
3532 { 3801 {
3533 dbp = skip_spaces (dbp); 3802 dbp = skip_spaces (dbp);
3534 for (cp = dbp; 3803 for (cp = dbp;
3535 (*cp != '\0' 3804 (*cp != '\0'
3536 && (isalpha ((unsigned char) *cp) || isdigit ((unsigned char) *cp) || *cp == '_' || *cp == '.')); 3805 && (ISALPHA (*cp) || ISDIGIT (*cp) || *cp == '_' || *cp == '.'));
3537 cp++) 3806 cp++)
3538 continue; 3807 continue;
3539 if (cp == dbp) 3808 if (cp == dbp)
3540 return; 3809 return;
3541 } 3810 }
3639 dbp++; 3908 dbp++;
3640 3909
3641 } /* advance char */ 3910 } /* advance char */
3642 } /* advance line */ 3911 } /* advance line */
3643 } 3912 }
3913
3644 3914
3645 /* 3915 /*
3646 * Bob Weiner, Motorola Inc., 4/3/94 3916 * Bob Weiner, Motorola Inc., 4/3/94
3647 * Unix and microcontroller assembly tag handling 3917 * Unix and microcontroller assembly tag handling
3648 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]' 3918 * look for '^[a-zA-Z_.$][a-zA_Z0-9_.$]*[: ^I^J]'
3655 3925
3656 LOOP_ON_INPUT_LINES (inf, lb, cp) 3926 LOOP_ON_INPUT_LINES (inf, lb, cp)
3657 { 3927 {
3658 /* If first char is alphabetic or one of [_.$], test for colon 3928 /* If first char is alphabetic or one of [_.$], test for colon
3659 following identifier. */ 3929 following identifier. */
3660 if (isalpha ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$') 3930 if (ISALPHA (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3661 { 3931 {
3662 /* Read past label. */ 3932 /* Read past label. */
3663 cp++; 3933 cp++;
3664 while (isalnum ((unsigned char) *cp) || *cp == '_' || *cp == '.' || *cp == '$') 3934 while (ISALNUM (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
3665 cp++; 3935 cp++;
3666 if (*cp == ':' || iswhite (*cp)) 3936 if (*cp == ':' || iswhite (*cp))
3667 { 3937 {
3668 /* Found end of label, so copy it and add it to the table. */ 3938 /* Found end of label, so copy it and add it to the table. */
3669 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE, 3939 pfnote (savenstr(lb.buffer, cp-lb.buffer), TRUE,
3670 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 3940 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3671 } 3941 }
3672 } 3942 }
3673 } 3943 }
3674 } 3944 }
3945
3675 3946
3676 /* 3947 /*
3677 * Perl support by Bart Robinson <lomew@cs.utah.edu> 3948 * Perl support
3678 * enhanced by Michael Ernst <mernst@alum.mit.edu>
3679 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/ 3949 * Perl sub names: look for /^sub[ \t\n]+[^ \t\n{]+/
3680 * Perl variable names: /^(my|local).../ 3950 * Perl variable names: /^(my|local).../
3951 * Bart Robinson <lomew@cs.utah.edu> (1995)
3952 * Michael Ernst <mernst@alum.mit.edu> (1997)
3681 */ 3953 */
3682 static void 3954 static void
3683 Perl_functions (inf) 3955 Perl_functions (inf)
3684 FILE *inf; 3956 FILE *inf;
3685 { 3957 {
3719 3991
3720 cp = skip_spaces (cp); 3992 cp = skip_spaces (cp);
3721 if (*cp == '$' || *cp == '@' || *cp == '%') 3993 if (*cp == '$' || *cp == '@' || *cp == '%')
3722 { 3994 {
3723 char* varstart = ++cp; 3995 char* varstart = ++cp;
3724 while (isalnum ((unsigned char) *cp) || *cp == '_') 3996 while (ISALNUM (*cp) || *cp == '_')
3725 cp++; 3997 cp++;
3726 varname = savenstr (varstart, cp-varstart); 3998 varname = savenstr (varstart, cp-varstart);
3727 } 3999 }
3728 else 4000 else
3729 { 4001 {
3738 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname, 4010 pfnote ((CTAGS) ? savenstr (lb.buffer, cp-lb.buffer) : varname,
3739 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4011 FALSE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3740 } 4012 }
3741 } 4013 }
3742 } 4014 }
4015
3743 4016
3744 /* 4017 /*
3745 * Python support by Eric S. Raymond <esr@thyrsus.com> 4018 * Python support
3746 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/ 4019 * Look for /^def[ \t\n]+[^ \t\n(:]+/ or /^class[ \t\n]+[^ \t\n(:]+/
4020 * Eric S. Raymond <esr@thyrsus.com> (1997)
3747 */ 4021 */
3748 static void 4022 static void
3749 Python_functions (inf) 4023 Python_functions (inf)
3750 FILE *inf; 4024 FILE *inf;
3751 { 4025 {
3777 pfnote (NULL, TRUE, 4051 pfnote (NULL, TRUE,
3778 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 4052 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
3779 } 4053 }
3780 } 4054 }
3781 } 4055 }
4056
3782 4057
3783 /* Idea by Corny de Souza 4058 /* Idea by Corny de Souza
3784 * Cobol tag functions 4059 * Cobol tag functions
3785 * We could look for anything that could be a paragraph name. 4060 * 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. 4061 * i.e. anything that starts in column 8 is one word and ends in a full stop.
3796 if (lb.len < 9) 4071 if (lb.len < 9)
3797 continue; 4072 continue;
3798 bp += 8; 4073 bp += 8;
3799 4074
3800 /* If eoln, compiler option or comment ignore whole line. */ 4075 /* If eoln, compiler option or comment ignore whole line. */
3801 if (bp[-1] != ' ' || !isalnum ((unsigned char) bp[0])) 4076 if (bp[-1] != ' ' || !ISALNUM (bp[0]))
3802 continue; 4077 continue;
3803 4078
3804 for (ep = bp; isalnum ((unsigned char) *ep) || *ep == '-'; ep++) 4079 for (ep = bp; ISALNUM (*ep) || *ep == '-'; ep++)
3805 continue; 4080 continue;
3806 if (*ep++ == '.') 4081 if (*ep++ == '.')
3807 pfnote (savenstr (bp, ep-bp), TRUE, 4082 pfnote (savenstr (bp, ep-bp), TRUE,
3808 lb.buffer, ep - lb.buffer + 1, lineno, linecharno); 4083 lb.buffer, ep - lb.buffer + 1, lineno, linecharno);
3809 } 4084 }
3810 } 4085 }
4086
4087
4088 /*
4089 * Makefile support
4090 * Idea by Assar Westerlund <assar@sics.se> (2001)
4091 */
4092 static void
4093 Makefile_targets (inf)
4094 FILE *inf;
4095 {
4096 register char *bp;
4097
4098 LOOP_ON_INPUT_LINES (inf, lb, bp)
4099 {
4100 if (*bp == '\t' || *bp == '#')
4101 continue;
4102 while (*bp != '\0' && *bp != '=' && *bp != ':')
4103 bp++;
4104 if (*bp == ':')
4105 pfnote (savenstr (lb.buffer, bp - lb.buffer), TRUE,
4106 lb.buffer, bp - lb.buffer + 1, lineno, linecharno);
4107 }
4108 }
4109
3811 4110
3812 /* Added by Mosur Mohan, 4/22/88 */ 4111 /* Added by Mosur Mohan, 4/22/88 */
3813 /* Pascal parsing */ 4112 /* Pascal parsing */
3814 4113
3815 /* 4114 /*
3952 { 4251 {
3953 if (*dbp == '\0') 4252 if (*dbp == '\0')
3954 continue; 4253 continue;
3955 4254
3956 /* save all values for later tagging */ 4255 /* save all values for later tagging */
3957 grow_linebuffer (&tline, lb.len + 1); 4256 linebuffer_setlen (&tline, lb.len);
3958 strcpy (tline.buffer, lb.buffer); 4257 strcpy (tline.buffer, lb.buffer);
3959 save_lineno = lineno; 4258 save_lineno = lineno;
3960 save_lcno = linecharno; 4259 save_lcno = linecharno;
3961 4260
3962 /* grab block name */ 4261 /* grab block name */
3988 } 4287 }
3989 } /* while not eof */ 4288 } /* while not eof */
3990 4289
3991 free (tline.buffer); 4290 free (tline.buffer);
3992 } 4291 }
4292
3993 4293
3994 /* 4294 /*
3995 * lisp tag functions 4295 * Lisp tag functions
3996 * look for (def or (DEF, quote or QUOTE 4296 * look for (def or (DEF, quote or QUOTE
3997 */ 4297 */
3998 4298
3999 static int L_isdef P_((char *)); 4299 static int L_isdef P_((char *));
4000 static int L_isquote P_((char *)); 4300 static int L_isquote P_((char *));
4084 } 4384 }
4085 } 4385 }
4086 } 4386 }
4087 } 4387 }
4088 } 4388 }
4389
4089 4390
4090 /* 4391 /*
4091 * Postscript tag functions 4392 * Postscript tag functions
4092 * Just look for lines where the first character is '/' 4393 * Just look for lines where the first character is '/'
4093 * Richard Mlynarik <mly@adoc.xerox.com>
4094 * Also look at "defineps" for PSWrap 4394 * Also look at "defineps" for PSWrap
4095 * suggested by Masatake YAMATO <masata-y@is.aist-nara.ac.jp> 4395 * Richard Mlynarik <mly@adoc.xerox.com> (1997)
4396 * Ideas by Masatake Yamato <masata-y@is.aist-nara.ac.jp> (1999)
4096 */ 4397 */
4097 static void 4398 static void
4098 Postscript_functions (inf) 4399 Postscript_functions (inf)
4099 FILE *inf; 4400 FILE *inf;
4100 { 4401 {
4159 bp = skip_spaces (bp); 4460 bp = skip_spaces (bp);
4160 get_tag (bp); 4461 get_tag (bp);
4161 } 4462 }
4162 } 4463 }
4163 } 4464 }
4465
4164 4466
4165 /* Find tags in TeX and LaTeX input files. */ 4467 /* Find tags in TeX and LaTeX input files. */
4166 4468
4167 /* TEX_toktab is a table of TeX control sequences that define tags. 4469 /* TEX_toktab is a table of TeX control sequences that define tags.
4168 Each TEX_tabent records one such control sequence. 4470 Each TEX_tabent records one such control sequence.
4192 4494
4193 /* 4495 /*
4194 * TeX/LaTeX scanning loop. 4496 * TeX/LaTeX scanning loop.
4195 */ 4497 */
4196 static void 4498 static void
4197 TeX_functions (inf) 4499 TeX_commands (inf)
4198 FILE *inf; 4500 FILE *inf;
4199 { 4501 {
4200 char *cp, *lasthit; 4502 char *cp, *lasthit;
4201 register int i; 4503 register int i;
4202 4504
4341 for (i = 0; TEX_toktab[i].len > 0; i++) 4643 for (i = 0; TEX_toktab[i].len > 0; i++)
4342 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len)) 4644 if (strneq (TEX_toktab[i].name, cp, TEX_toktab[i].len))
4343 return i; 4645 return i;
4344 return -1; 4646 return -1;
4345 } 4647 }
4648
4649
4650 /* Texinfo support. Dave Love, Mar. 2000. */
4651 static void
4652 Texinfo_nodes (inf)
4653 FILE * inf;
4654 {
4655 char *cp, *start;
4656 LOOP_ON_INPUT_LINES (inf, lb, cp)
4657 {
4658 if ((*cp++ == '@'
4659 && *cp++ == 'n'
4660 && *cp++ == 'o'
4661 && *cp++ == 'd'
4662 && *cp++ == 'e' && iswhite (*cp++)))
4663 {
4664 start = cp = skip_spaces(cp);
4665 while (*cp != '\0' && *cp != ',')
4666 cp++;
4667 pfnote (savenstr (start, cp - start), TRUE,
4668 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4669 }
4670 }
4671 }
4672
4346 4673
4347 /* 4674 /*
4348 * Prolog support (rewritten) by Anders Lindgren, Mar. 96 4675 * Prolog support (rewritten) by Anders Lindgren, Mar. 96
4349 * 4676 *
4350 * Assumes that the predicate starts at column 0. 4677 * Assumes that the predicate starts at column 0.
4379 /* Predicate. Store the function name so that we only 4706 /* Predicate. Store the function name so that we only
4380 generate a tag for the first clause. */ 4707 generate a tag for the first clause. */
4381 if (last == NULL) 4708 if (last == NULL)
4382 last = xnew(len + 1, char); 4709 last = xnew(len + 1, char);
4383 else if (len + 1 > allocated) 4710 else if (len + 1 > allocated)
4384 last = xrnew (last, len + 1, char); 4711 xrnew (last, len + 1, char);
4385 allocated = len + 1; 4712 allocated = len + 1;
4386 strncpy (last, cp, len); 4713 strncpy (last, cp, len);
4387 last[len] = '\0'; 4714 last[len] = '\0';
4388 } 4715 }
4389 } 4716 }
4466 { 4793 {
4467 int origpos; 4794 int origpos;
4468 4795
4469 origpos = pos; 4796 origpos = pos;
4470 4797
4471 if (islower((unsigned char) s[pos]) || (s[pos] == '_')) 4798 if (ISLOWER(s[pos]) || (s[pos] == '_'))
4472 { 4799 {
4473 /* The atom is unquoted. */ 4800 /* The atom is unquoted. */
4474 pos++; 4801 pos++;
4475 while (isalnum((unsigned char) s[pos]) || (s[pos] == '_')) 4802 while (ISALNUM(s[pos]) || (s[pos] == '_'))
4476 { 4803 {
4477 pos++; 4804 pos++;
4478 } 4805 }
4479 return pos - origpos; 4806 return pos - origpos;
4480 } 4807 }
4506 return pos - origpos; 4833 return pos - origpos;
4507 } 4834 }
4508 else 4835 else
4509 return -1; 4836 return -1;
4510 } 4837 }
4838
4511 4839
4512 /* 4840 /*
4513 * Support for Erlang -- Anders Lindgren, Feb 1996. 4841 * Support for Erlang -- Anders Lindgren, Feb 1996.
4514 * 4842 *
4515 * Generates tags for functions, defines, and records. 4843 * Generates tags for functions, defines, and records.
4554 * generates a tag for the first clause. 4882 * generates a tag for the first clause.
4555 */ 4883 */
4556 if (last == NULL) 4884 if (last == NULL)
4557 last = xnew (len + 1, char); 4885 last = xnew (len + 1, char);
4558 else if (len + 1 > allocated) 4886 else if (len + 1 > allocated)
4559 last = xrnew (last, len + 1, char); 4887 xrnew (last, len + 1, char);
4560 allocated = len + 1; 4888 allocated = len + 1;
4561 strncpy (last, cp, len); 4889 strncpy (last, cp, len);
4562 last[len] = '\0'; 4890 last[len] = '\0';
4563 } 4891 }
4564 } 4892 }
4647 { 4975 {
4648 int origpos; 4976 int origpos;
4649 4977
4650 origpos = pos; 4978 origpos = pos;
4651 4979
4652 if (isalpha ((unsigned char) s[pos]) || s[pos] == '_') 4980 if (ISALPHA (s[pos]) || s[pos] == '_')
4653 { 4981 {
4654 /* The atom is unquoted. */ 4982 /* The atom is unquoted. */
4655 pos++; 4983 pos++;
4656 while (isalnum ((unsigned char) s[pos]) || s[pos] == '_') 4984 while (ISALNUM (s[pos]) || s[pos] == '_')
4657 pos++; 4985 pos++;
4658 return pos - origpos; 4986 return pos - origpos;
4659 } 4987 }
4660 else if (s[pos] == '\'') 4988 else if (s[pos] == '\'')
4661 { 4989 {
4683 return pos - origpos; 5011 return pos - origpos;
4684 } 5012 }
4685 else 5013 else
4686 return -1; 5014 return -1;
4687 } 5015 }
5016
4688 5017
4689 #ifdef ETAGS_REGEXPS 5018 #ifdef ETAGS_REGEXPS
4690 5019
4691 static char *scan_separators P_((char *)); 5020 static char *scan_separators P_((char *));
4692 static void analyse_regex P_((char *, bool)); 5021 static void analyse_regex P_((char *, bool));
4790 { 5119 {
4791 error ("unterminated language name in regex: %s", regex_arg); 5120 error ("unterminated language name in regex: %s", regex_arg);
4792 return; 5121 return;
4793 } 5122 }
4794 *cp = '\0'; 5123 *cp = '\0';
4795 lang = get_language_from_name (lang_name); 5124 lang = get_language_from_langname (lang_name);
4796 if (lang == NULL) 5125 if (lang == NULL)
4797 return; 5126 return;
4798 add_regex (cp + 1, ignore_case, lang); 5127 add_regex (cp + 1, ignore_case, lang);
4799 } 5128 }
4800 break; 5129 break;
4837 /* Translation table to fold case if appropriate. */ 5166 /* Translation table to fold case if appropriate. */
4838 patbuf->translate = (ignore_case) ? lc_trans : NULL; 5167 patbuf->translate = (ignore_case) ? lc_trans : NULL;
4839 patbuf->fastmap = NULL; 5168 patbuf->fastmap = NULL;
4840 patbuf->buffer = NULL; 5169 patbuf->buffer = NULL;
4841 patbuf->allocated = 0; 5170 patbuf->allocated = 0;
4842
4843 #if 0 /* useful when debugging windows quoting convention problems */
4844 printf ("Compiling regex pattern: %s\n", regexp_pattern);
4845 #endif
4846 5171
4847 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf); 5172 err = re_compile_pattern (regexp_pattern, strlen (regexp_pattern), patbuf);
4848 if (err != NULL) 5173 if (err != NULL)
4849 { 5174 {
4850 error ("%s while compiling pattern", err); 5175 error ("%s while compiling pattern", err);
4880 if (out[size - 1] == '\\') 5205 if (out[size - 1] == '\\')
4881 fatal ("pattern error in \"%s\"", out); 5206 fatal ("pattern error in \"%s\"", out);
4882 for (t = etags_strchr (out, '\\'); 5207 for (t = etags_strchr (out, '\\');
4883 t != NULL; 5208 t != NULL;
4884 t = etags_strchr (t + 2, '\\')) 5209 t = etags_strchr (t + 2, '\\'))
4885 if (isdigit ((unsigned char) t[1])) 5210 if (ISDIGIT (t[1]))
4886 { 5211 {
4887 dig = t[1] - '0'; 5212 dig = t[1] - '0';
4888 diglen = regs->end[dig] - regs->start[dig]; 5213 diglen = regs->end[dig] - regs->start[dig];
4889 size += diglen - 2; 5214 size += diglen - 2;
4890 } 5215 }
4893 5218
4894 /* Allocate space and do the substitutions. */ 5219 /* Allocate space and do the substitutions. */
4895 result = xnew (size + 1, char); 5220 result = xnew (size + 1, char);
4896 5221
4897 for (t = result; *out != '\0'; out++) 5222 for (t = result; *out != '\0'; out++)
4898 if (*out == '\\' && isdigit ((unsigned char) *++out)) 5223 if (*out == '\\' && ISDIGIT (*++out))
4899 { 5224 {
4900 /* Using "dig2" satisfies my debugger. Bleah. */
4901 dig = *out - '0'; 5225 dig = *out - '0';
4902 diglen = regs->end[dig] - regs->start[dig]; 5226 diglen = regs->end[dig] - regs->start[dig];
4903 strncpy (t, in + regs->start[dig], diglen); 5227 strncpy (t, in + regs->start[dig], diglen);
4904 t += diglen; 5228 t += diglen;
4905 } 5229 }
4906 else 5230 else
4907 *t++ = *out; 5231 *t++ = *out;
4908 *t = '\0'; 5232 *t = '\0';
4909 5233
4910 if (DEBUG && (t > result + size || t - result != (int)strlen (result))) 5234 assert (t <= result + size && t - result == (int)strlen (result));
4911 abort ();
4912 5235
4913 return result; 5236 return result;
4914 } 5237 }
4915 5238
4916 /* Deallocate all patterns. */ 5239 /* Deallocate all patterns. */
4926 free (p_head); 5249 free (p_head);
4927 p_head = pp; 5250 p_head = pp;
4928 } 5251 }
4929 return; 5252 return;
4930 } 5253 }
5254 #endif /* ETAGS_REGEXPS */
5255
4931 5256
4932 static void 5257 static void
4933 get_tag (bp) 5258 get_tag (bp)
4934 register char *bp; 5259 register char *bp;
4935 { 5260 {
4944 continue; 5269 continue;
4945 pfnote (savenstr (bp, cp-bp), TRUE, 5270 pfnote (savenstr (bp, cp-bp), TRUE,
4946 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 5271 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
4947 } 5272 }
4948 5273
4949 #endif /* ETAGS_REGEXPS */
4950 /* Initialize a linebuffer for use */ 5274 /* Initialize a linebuffer for use */
4951 static void 5275 static void
4952 initbuffer (lbp) 5276 initbuffer (lbp)
4953 linebuffer *lbp; 5277 linebuffer *lbp;
4954 { 5278 {
4955 lbp->size = 200; 5279 lbp->size = (DEBUG) ? 3 : 200;
4956 lbp->buffer = xnew (200, char); 5280 lbp->buffer = xnew (lbp->size, char);
5281 lbp->buffer[0] = '\0';
5282 lbp->len = 0;
4957 } 5283 }
4958 5284
4959 /* 5285 /*
4960 * Read a line of text from `stream' into `lbp', excluding the 5286 * Read a line of text from `stream' into `lbp', excluding the
4961 * newline or CR-NL, if any. Return the number of characters read from 5287 * newline or CR-NL, if any. Return the number of characters read from
4983 register int c = getc (stream); 5309 register int c = getc (stream);
4984 if (p == pend) 5310 if (p == pend)
4985 { 5311 {
4986 /* We're at the end of linebuffer: expand it. */ 5312 /* We're at the end of linebuffer: expand it. */
4987 lbp->size *= 2; 5313 lbp->size *= 2;
4988 buffer = xrnew (buffer, lbp->size, char); 5314 xrnew (buffer, lbp->size, char);
4989 p += buffer - lbp->buffer; 5315 p += buffer - lbp->buffer;
4990 pend = buffer + lbp->size; 5316 pend = buffer + lbp->size;
4991 lbp->buffer = buffer; 5317 lbp->buffer = buffer;
4992 } 5318 }
4993 if (c == EOF) 5319 if (c == EOF)
4999 if (c == '\n') 5325 if (c == '\n')
5000 { 5326 {
5001 if (p > buffer && p[-1] == '\r') 5327 if (p > buffer && p[-1] == '\r')
5002 { 5328 {
5003 p -= 1; 5329 p -= 1;
5004 #ifdef WIN32_NATIVE 5330 #ifdef DOS_NT
5005 /* Assume CRLF->LF translation will be performed by Emacs 5331 /* Assume CRLF->LF translation will be performed by Emacs
5006 when loading this file, so CRs won't appear in the buffer. 5332 when loading this file, so CRs won't appear in the buffer.
5007 It would be cleaner to compensate within Emacs; 5333 It would be cleaner to compensate within Emacs;
5008 however, Emacs does not know how many CRs were deleted 5334 however, Emacs does not know how many CRs were deleted
5009 before any given point in the file. */ 5335 before any given point in the file. */
5084 } 5410 }
5085 #endif /* ETAGS_REGEXPS */ 5411 #endif /* ETAGS_REGEXPS */
5086 5412
5087 return result; 5413 return result;
5088 } 5414 }
5415
5089 5416
5090 /* 5417 /*
5091 * Return a pointer to a space of size strlen(cp)+1 allocated 5418 * Return a pointer to a space of size strlen(cp)+1 allocated
5092 * with xnew where the string CP has been copied. 5419 * with xnew where the string CP has been copied.
5093 */ 5420 */
5176 cp++; 5503 cp++;
5177 return cp; 5504 return cp;
5178 } 5505 }
5179 5506
5180 /* Print error message and exit. */ 5507 /* Print error message and exit. */
5181 static void 5508 void
5182 fatal (s1, s2) 5509 fatal (s1, s2)
5183 char *s1, *s2; 5510 char *s1, *s2;
5184 { 5511 {
5185 error (s1, s2); 5512 error (s1, s2);
5186 exit (BAD); 5513 exit (BAD);
5232 strcpy (result + len1 + len2, s3); 5559 strcpy (result + len1 + len2, s3);
5233 result[len1 + len2 + len3] = '\0'; 5560 result[len1 + len2 + len3] = '\0';
5234 5561
5235 return result; 5562 return result;
5236 } 5563 }
5564
5237 5565
5238 /* Does the same work as the system V getcwd, but does not need to 5566 /* Does the same work as the system V getcwd, but does not need to
5239 guess the buffer size in advance. */ 5567 guess the buffer size in advance. */
5240 static char * 5568 static char *
5241 etags_getcwd () 5569 etags_getcwd ()
5255 5583
5256 canonicalize_filename (path); 5584 canonicalize_filename (path);
5257 return path; 5585 return path;
5258 5586
5259 #else /* not HAVE_GETCWD */ 5587 #else /* not HAVE_GETCWD */
5588 #if MSDOS
5589
5590 char *p, path[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */
5591
5592 getwd (path);
5593
5594 for (p = path; *p != '\0'; p++)
5595 if (*p == '\\')
5596 *p = '/';
5597 else
5598 *p = lowcase (*p);
5599
5600 return strdup (path);
5601 #else /* not MSDOS */
5260 linebuffer path; 5602 linebuffer path;
5261 FILE *pipe; 5603 FILE *pipe;
5262 5604
5263 initbuffer (&path); 5605 initbuffer (&path);
5264 pipe = (FILE *) popen ("pwd 2>/dev/null", "r"); 5606 pipe = (FILE *) popen ("pwd 2>/dev/null", "r");
5265 if (pipe == NULL || readline_internal (&path, pipe) == 0) 5607 if (pipe == NULL || readline_internal (&path, pipe) == 0)
5266 pfatal ("pwd"); 5608 pfatal ("pwd");
5267 pclose (pipe); 5609 pclose (pipe);
5268 5610
5269 return path.buffer; 5611 return path.buffer;
5612 #endif /* not MSDOS */
5270 #endif /* not HAVE_GETCWD */ 5613 #endif /* not HAVE_GETCWD */
5271 } 5614 }
5272 5615
5273 /* Return a newly allocated string containing the file name of FILE 5616 /* Return a newly allocated string containing the file name of FILE
5274 relative to the absolute directory DIR (which should end with a slash). */ 5617 relative to the absolute directory DIR (which should end with a slash). */
5284 fp = afn; 5627 fp = afn;
5285 dp = dir; 5628 dp = dir;
5286 while (*fp++ == *dp++) 5629 while (*fp++ == *dp++)
5287 continue; 5630 continue;
5288 fp--, dp--; /* back to the first differing char */ 5631 fp--, dp--; /* back to the first differing char */
5289 #ifdef WIN32_NATIVE 5632 #ifdef DOS_NT
5290 if (fp == afn && afn[0] != '/') /* cannot build a relative name */ 5633 if (fp == afn && afn[0] != '/') /* cannot build a relative name */
5291 return afn; 5634 return afn;
5292 #endif 5635 #endif
5293 do /* look at the equal chars until '/' */ 5636 do /* look at the equal chars until '/' */
5294 fp--, dp--; 5637 fp--, dp--;
5318 { 5661 {
5319 char *slashp, *cp, *res; 5662 char *slashp, *cp, *res;
5320 5663
5321 if (filename_is_absolute (file)) 5664 if (filename_is_absolute (file))
5322 res = savestr (file); 5665 res = savestr (file);
5323 #ifdef WIN32_NATIVE 5666 #ifdef DOS_NT
5324 /* We don't support non-absolute file names with a drive 5667 /* We don't support non-absolute file names with a drive
5325 letter, like `d:NAME' (it's too much hassle). */ 5668 letter, like `d:NAME' (it's too much hassle). */
5326 else if (file[1] == ':') 5669 else if (file[1] == ':')
5327 fatal ("%s: relative file names with drive letters not supported", file); 5670 fatal ("%s: relative file names with drive letters not supported", file);
5328 #endif 5671 #endif
5342 do 5685 do
5343 cp--; 5686 cp--;
5344 while (cp >= res && !filename_is_absolute (cp)); 5687 while (cp >= res && !filename_is_absolute (cp));
5345 if (cp < res) 5688 if (cp < res)
5346 cp = slashp; /* the absolute name begins with "/.." */ 5689 cp = slashp; /* the absolute name begins with "/.." */
5347 #ifdef WIN32_NATIVE 5690 #ifdef DOS_NT
5348 /* Under Windows we get `d:/NAME' as absolute 5691 /* Under MSDOS and NT we get `d:/NAME' as absolute
5349 file name, so the luser could say `d:/../NAME'. 5692 file name, so the luser could say `d:/../NAME'.
5350 We silently treat this as `d:/NAME'. */ 5693 We silently treat this as `d:/NAME'. */
5351 else if (cp[0] != '/') 5694 else if (cp[0] != '/')
5352 cp = slashp; 5695 cp = slashp;
5353 #endif 5696 #endif
5398 static bool 5741 static bool
5399 filename_is_absolute (fn) 5742 filename_is_absolute (fn)
5400 char *fn; 5743 char *fn;
5401 { 5744 {
5402 return (fn[0] == '/' 5745 return (fn[0] == '/'
5403 #ifdef WIN32_NATIVE 5746 #ifdef DOS_NT
5404 || (isalpha(fn[0]) && fn[1] == ':' && fn[2] == '/') 5747 || (ISALPHA(fn[0]) && fn[1] == ':' && fn[2] == '/')
5405 #endif 5748 #endif
5406 ); 5749 );
5407 } 5750 }
5408 5751
5409 /* Translate backslashes into slashes. Works in place. */ 5752 /* Translate backslashes into slashes. Works in place. */
5410 static void 5753 static void
5411 canonicalize_filename (fn) 5754 canonicalize_filename (fn)
5412 register char *fn; 5755 register char *fn;
5413 { 5756 {
5414 #ifdef WIN32_NATIVE 5757 #ifdef DOS_NT
5415 /* Canonicalize drive letter case. */ 5758 /* Canonicalize drive letter case. */
5416 if (islower (fn[0]) && fn[1] == ':') 5759 if (fn[0] != '\0' && fn[1] == ':' && ISLOWER (fn[0]))
5417 fn[0] = toupper (fn[0]); 5760 fn[0] = upcase (fn[0]);
5418 /* Convert backslashes to slashes. */ 5761 /* Convert backslashes to slashes. */
5419 for (; *fn != '\0'; fn++) 5762 for (; *fn != '\0'; fn++)
5420 if (*fn == '\\') 5763 if (*fn == '\\')
5421 *fn = '/'; 5764 *fn = '/';
5422 #else 5765 #else
5423 /* No action. */ 5766 /* No action. */
5424 fn = NULL; /* shut up the compiler */ 5767 fn = NULL; /* shut up the compiler */
5425 #endif 5768 #endif
5426 } 5769 }
5427 5770
5428 /* Increase the size of a linebuffer. */ 5771 /* Set the minimum size of a string contained in a linebuffer. */
5429 static void 5772 static void
5430 grow_linebuffer (lbp, toksize) 5773 linebuffer_setlen (lbp, toksize)
5431 linebuffer *lbp; 5774 linebuffer *lbp;
5432 int toksize; 5775 int toksize;
5433 { 5776 {
5434 while (lbp->size < toksize) 5777 while (lbp->size <= toksize)
5435 lbp->size *= 2; 5778 {
5436 lbp->buffer = xrnew (lbp->buffer, lbp->size, char); 5779 lbp->size *= 2;
5780 xrnew (lbp->buffer, lbp->size, char);
5781 }
5782 lbp->len = toksize;
5437 } 5783 }
5438 5784
5439 /* Like malloc but get fatal error if memory is exhausted. */ 5785 /* Like malloc but get fatal error if memory is exhausted. */
5440 static long * 5786 long *
5441 xmalloc (size) 5787 xmalloc (size)
5442 unsigned int size; 5788 unsigned int size;
5443 { 5789 {
5444 long *result = (long *) malloc (size); 5790 long *result = (long *) malloc (size);
5445 if (result == NULL) 5791 if (result == NULL)
5446 fatal ("virtual memory exhausted", (char *)NULL); 5792 fatal ("virtual memory exhausted", (char *)NULL);
5447 return result; 5793 return result;
5448 } 5794 }
5449 5795
5450 static long * 5796 long *
5451 xrealloc (ptr, size) 5797 xrealloc (ptr, size)
5452 char *ptr; 5798 char *ptr;
5453 unsigned int size; 5799 unsigned int size;
5454 { 5800 {
5455 long *result = (long *) realloc (ptr, size); 5801 long *result = (long *) realloc (ptr, size);