Mercurial > hg > xemacs-beta
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); |