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