Mercurial > emacs
annotate lib-src/ebrowse.c @ 66573:e65b759c6906
Revision: miles@gnu.org--gnu-2005/emacs--cvs-trunk--0--patch-630
Merge from gnus--rel--5.10
Patches applied:
* gnus--rel--5.10 (patch 149-151)
- Merge from emacs--cvs-trunk--0
- Update from CVS
2005-10-27 Reiner Steib <Reiner.Steib@gmx.de>
* lisp/gnus/flow-fill.el (fill-flowed-encode-tests): Restore trailing
whitespace removed in revision 7.8. Use concatenated string to
protect trailing whitespace.
2005-10-27 Jouni K Seppanen <jks@iki.fi> (tiny change)
* lisp/gnus/nnimap.el (nnimap-search-uids-not-since-is-evil): Add variable.
(nnimap-request-expire-articles): Use it to avoid sending 'UID
SEARCH UID ... NOT SINCE' queries, for inefficient servers like
Courier IMAP ("some version from 2004"). Mostly based on similar
code in the same function.
2005-10-26 Katsumi Yamaoka <yamaoka@jpl.org>
* lisp/gnus/message.el (message-display-completion-list): New function.
(message-expand-group): Use it; make sure the Completions buffer
is modifiable.
author | Miles Bader <miles@gnu.org> |
---|---|
date | Mon, 31 Oct 2005 07:07:28 +0000 |
parents | 69a9e146ef35 |
children | 3661e9b3c48f ee12d75eb214 |
rev | line source |
---|---|
28523 | 1 /* ebrowse.c --- parsing files for the ebrowse C++ browser |
2 | |
64769
6358e3c6075c
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64083
diff
changeset
|
3 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
6358e3c6075c
Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
64083
diff
changeset
|
4 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
5 |
28523 | 6 This file is part of GNU Emacs. |
7 | |
8 GNU Emacs is free software; you can redistribute it and/or modify | |
9 it under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 2, or (at your option) | |
11 any later version. | |
12 | |
13 GNU Emacs is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
42259
20ee6e9752ef
*** empty log message ***
Richard M. Stallman <rms@gnu.org>
parents:
42174
diff
changeset
|
19 along with GNU Emacs; see the file COPYING. If not, write to the |
64083 | 20 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
21 Boston, MA 02110-1301, USA. */ | |
28523 | 22 |
29889
565ecd919fca
Move config.h before other includes (which may use feature tests).
Dave Love <fx@gnu.org>
parents:
29561
diff
changeset
|
23 #ifdef HAVE_CONFIG_H |
565ecd919fca
Move config.h before other includes (which may use feature tests).
Dave Love <fx@gnu.org>
parents:
29561
diff
changeset
|
24 #include <config.h> |
565ecd919fca
Move config.h before other includes (which may use feature tests).
Dave Love <fx@gnu.org>
parents:
29561
diff
changeset
|
25 #endif |
565ecd919fca
Move config.h before other includes (which may use feature tests).
Dave Love <fx@gnu.org>
parents:
29561
diff
changeset
|
26 |
28523 | 27 #include <stdio.h> |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
28 |
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
29 #ifdef HAVE_STDLIB_H |
28523 | 30 #include <stdlib.h> |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
31 #endif |
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
32 |
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
33 #ifdef HAVE_STRING_H |
28523 | 34 #include <string.h> |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
35 #endif |
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
36 |
28523 | 37 #include <ctype.h> |
38 #include <assert.h> | |
39 #include "getopt.h" | |
40 | |
39076
fe37d7c5eae2
(SEEK_END): #define if not defined by system headers.
Eli Zaretskii <eliz@gnu.org>
parents:
38769
diff
changeset
|
41 /* The SunOS compiler doesn't have SEEK_END. */ |
fe37d7c5eae2
(SEEK_END): #define if not defined by system headers.
Eli Zaretskii <eliz@gnu.org>
parents:
38769
diff
changeset
|
42 #ifndef SEEK_END |
fe37d7c5eae2
(SEEK_END): #define if not defined by system headers.
Eli Zaretskii <eliz@gnu.org>
parents:
38769
diff
changeset
|
43 #define SEEK_END 2 |
fe37d7c5eae2
(SEEK_END): #define if not defined by system headers.
Eli Zaretskii <eliz@gnu.org>
parents:
38769
diff
changeset
|
44 #endif |
fe37d7c5eae2
(SEEK_END): #define if not defined by system headers.
Eli Zaretskii <eliz@gnu.org>
parents:
38769
diff
changeset
|
45 |
28523 | 46 /* Conditionalize function prototypes. */ |
47 | |
48 #ifdef PROTOTYPES /* From config.h. */ | |
49 #define P_(x) x | |
50 #else | |
51 #define P_(x) () | |
52 #endif | |
53 | |
54 /* Value is non-zero if strings X and Y compare equal. */ | |
55 | |
56 #define streq(X, Y) (*(X) == *(Y) && strcmp ((X) + 1, (Y) + 1) == 0) | |
57 | |
58 /* The ubiquitous `max' and `min' macros. */ | |
59 | |
60 #ifndef max | |
61 #define max(X, Y) ((X) > (Y) ? (X) : (Y)) | |
62 #define min(X, Y) ((X) < (Y) ? (X) : (Y)) | |
63 #endif | |
64 | |
65 /* Files are read in chunks of this number of bytes. */ | |
66 | |
67 #define READ_CHUNK_SIZE (100 * 1024) | |
68 | |
69 /* The character used as a separator in path lists (like $PATH). */ | |
70 | |
29561
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
71 #if defined(__MSDOS__) |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
72 #define PATH_LIST_SEPARATOR ';' |
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
73 #define FILENAME_EQ(X,Y) (strcasecmp(X,Y) == 0) |
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
74 #else |
29561
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
75 #if defined(WINDOWSNT) |
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
76 #define PATH_LIST_SEPARATOR ';' |
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
77 #define FILENAME_EQ(X,Y) (stricmp(X,Y) == 0) |
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
78 #else |
28523 | 79 #define PATH_LIST_SEPARATOR ':' |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
80 #define FILENAME_EQ(X,Y) (streq(X,Y)) |
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
81 #endif |
29561
235fb8ea80a2
[WINDOWS-NT]: Use stricmp rather than strcasecmp to compare filenames.
Jason Rumney <jasonr@gnu.org>
parents:
29459
diff
changeset
|
82 #endif |
28523 | 83 /* The default output file name. */ |
84 | |
28814
7bb3a2b7ff29
(DEFAULT_OUTFILE): Set to `BROWSE'.
Gerd Moellmann <gerd@gnu.org>
parents:
28773
diff
changeset
|
85 #define DEFAULT_OUTFILE "BROWSE" |
28523 | 86 |
87 /* A version string written to the output file. Change this whenever | |
88 the structure of the output file changes. */ | |
89 | |
90 #define EBROWSE_FILE_VERSION "ebrowse 5.0" | |
91 | |
92 /* The output file consists of a tree of Lisp objects, with major | |
93 nodes built out of Lisp structures. These are the heads of the | |
94 Lisp structs with symbols identifying their type. */ | |
95 | |
96 #define TREE_HEADER_STRUCT "[ebrowse-hs " | |
97 #define TREE_STRUCT "[ebrowse-ts " | |
98 #define MEMBER_STRUCT "[ebrowse-ms " | |
99 #define BROWSE_STRUCT "[ebrowse-bs " | |
100 #define CLASS_STRUCT "[ebrowse-cs " | |
101 | |
102 /* The name of the symbol table entry for global functions, variables, | |
103 defines etc. This name also appears in the browser display. */ | |
104 | |
105 #define GLOBALS_NAME "*Globals*" | |
106 | |
107 /* Token definitions. */ | |
108 | |
109 enum token | |
110 { | |
111 YYEOF = 0, /* end of file */ | |
112 CSTRING = 256, /* string constant */ | |
113 CCHAR, /* character constant */ | |
114 CINT, /* integral constant */ | |
115 CFLOAT, /* real constant */ | |
116 | |
117 ELLIPSIS, /* ... */ | |
118 LSHIFTASGN, /* <<= */ | |
119 RSHIFTASGN, /* >>= */ | |
120 ARROWSTAR, /* ->* */ | |
121 IDENT, /* identifier */ | |
122 DIVASGN, /* /= */ | |
123 INC, /* ++ */ | |
124 ADDASGN, /* += */ | |
125 DEC, /* -- */ | |
126 ARROW, /* -> */ | |
127 SUBASGN, /* -= */ | |
128 MULASGN, /* *= */ | |
129 MODASGN, /* %= */ | |
130 LOR, /* || */ | |
131 ORASGN, /* |= */ | |
132 LAND, /* && */ | |
133 ANDASGN, /* &= */ | |
134 XORASGN, /* ^= */ | |
135 POINTSTAR, /* .* */ | |
136 DCOLON, /* :: */ | |
137 EQ, /* == */ | |
138 NE, /* != */ | |
139 LE, /* <= */ | |
140 LSHIFT, /* << */ | |
141 GE, /* >= */ | |
142 RSHIFT, /* >> */ | |
143 | |
144 /* Keywords. The undef's are there because these | |
145 three symbols are very likely to be defined somewhere. */ | |
146 #undef BOOL | |
147 #undef TRUE | |
148 #undef FALSE | |
149 | |
150 ASM, /* asm */ | |
151 AUTO, /* auto */ | |
152 BREAK, /* break */ | |
153 CASE, /* case */ | |
154 CATCH, /* catch */ | |
155 CHAR, /* char */ | |
156 CLASS, /* class */ | |
157 CONST, /* const */ | |
158 CONTINUE, /* continue */ | |
159 DEFAULT, /* default */ | |
160 DELETE, /* delete */ | |
161 DO, /* do */ | |
162 DOUBLE, /* double */ | |
163 ELSE, /* else */ | |
164 ENUM, /* enum */ | |
165 EXTERN, /* extern */ | |
166 FLOAT, /* float */ | |
167 FOR, /* for */ | |
168 FRIEND, /* friend */ | |
169 GOTO, /* goto */ | |
170 IF, /* if */ | |
171 T_INLINE, /* inline */ | |
172 INT, /* int */ | |
173 LONG, /* long */ | |
174 NEW, /* new */ | |
175 OPERATOR, /* operator */ | |
176 PRIVATE, /* private */ | |
177 PROTECTED, /* protected */ | |
178 PUBLIC, /* public */ | |
179 REGISTER, /* register */ | |
180 RETURN, /* return */ | |
181 SHORT, /* short */ | |
182 SIGNED, /* signed */ | |
183 SIZEOF, /* sizeof */ | |
184 STATIC, /* static */ | |
185 STRUCT, /* struct */ | |
186 SWITCH, /* switch */ | |
187 TEMPLATE, /* template */ | |
188 THIS, /* this */ | |
189 THROW, /* throw */ | |
190 TRY, /* try */ | |
191 TYPEDEF, /* typedef */ | |
192 UNION, /* union */ | |
193 UNSIGNED, /* unsigned */ | |
194 VIRTUAL, /* virtual */ | |
195 VOID, /* void */ | |
196 VOLATILE, /* volatile */ | |
197 WHILE, /* while */ | |
198 MUTABLE, /* mutable */ | |
199 BOOL, /* bool */ | |
200 TRUE, /* true */ | |
201 FALSE, /* false */ | |
202 SIGNATURE, /* signature (GNU extension) */ | |
203 NAMESPACE, /* namespace */ | |
204 EXPLICIT, /* explicit */ | |
205 TYPENAME, /* typename */ | |
206 CONST_CAST, /* const_cast */ | |
207 DYNAMIC_CAST, /* dynamic_cast */ | |
208 REINTERPRET_CAST, /* reinterpret_cast */ | |
209 STATIC_CAST, /* static_cast */ | |
210 TYPEID, /* typeid */ | |
211 USING, /* using */ | |
212 WCHAR /* wchar_t */ | |
213 }; | |
214 | |
215 /* Storage classes, in a wider sense. */ | |
216 | |
217 enum sc | |
218 { | |
219 SC_UNKNOWN, | |
220 SC_MEMBER, /* Is an instance member. */ | |
221 SC_STATIC, /* Is static member. */ | |
222 SC_FRIEND, /* Is friend function. */ | |
223 SC_TYPE /* Is a type definition. */ | |
224 }; | |
225 | |
226 /* Member visibility. */ | |
227 | |
228 enum visibility | |
229 { | |
230 V_PUBLIC, | |
231 V_PROTECTED, | |
232 V_PRIVATE | |
233 }; | |
234 | |
235 /* Member flags. */ | |
236 | |
237 #define F_VIRTUAL 1 /* Is virtual function. */ | |
238 #define F_INLINE 2 /* Is inline function. */ | |
239 #define F_CONST 4 /* Is const. */ | |
240 #define F_PURE 8 /* Is pure virtual function. */ | |
241 #define F_MUTABLE 16 /* Is mutable. */ | |
242 #define F_TEMPLATE 32 /* Is a template. */ | |
243 #define F_EXPLICIT 64 /* Is explicit constructor. */ | |
244 #define F_THROW 128 /* Has a throw specification. */ | |
245 #define F_EXTERNC 256 /* Is declared extern "C". */ | |
246 #define F_DEFINE 512 /* Is a #define. */ | |
247 | |
248 /* Two macros to set and test a bit in an int. */ | |
249 | |
250 #define SET_FLAG(F, FLAG) ((F) |= (FLAG)) | |
251 #define HAS_FLAG(F, FLAG) (((F) & (FLAG)) != 0) | |
252 | |
253 /* Structure describing a class member. */ | |
254 | |
255 struct member | |
256 { | |
257 struct member *next; /* Next in list of members. */ | |
258 struct member *anext; /* Collision chain in member_table. */ | |
259 struct member **list; /* Pointer to list in class. */ | |
260 unsigned param_hash; /* Hash value for parameter types. */ | |
261 int vis; /* Visibility (public, ...). */ | |
262 int flags; /* See F_* above. */ | |
263 char *regexp; /* Matching regular expression. */ | |
264 char *filename; /* Don't free this shared string. */ | |
265 int pos; /* Buffer position of occurrence. */ | |
266 char *def_regexp; /* Regular expression matching definition. */ | |
267 char *def_filename; /* File name of definition. */ | |
268 int def_pos; /* Buffer position of definition. */ | |
269 char name[1]; /* Member name. */ | |
270 }; | |
271 | |
272 /* Structures of this type are used to connect class structures with | |
273 their super and subclasses. */ | |
274 | |
275 struct link | |
276 { | |
277 struct sym *sym; /* The super or subclass. */ | |
278 struct link *next; /* Next in list or NULL. */ | |
279 }; | |
280 | |
281 /* Structure used to record namespace aliases. */ | |
282 | |
283 struct alias | |
284 { | |
285 struct alias *next; /* Next in list. */ | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
286 struct sym *namesp; /* Namespace in which defined. */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
287 struct link *aliasee; /* List of aliased namespaces (A::B::C...). */ |
28523 | 288 char name[1]; /* Alias name. */ |
289 }; | |
290 | |
291 /* The structure used to describe a class in the symbol table, | |
292 or a namespace in all_namespaces. */ | |
293 | |
294 struct sym | |
295 { | |
296 int flags; /* Is class a template class?. */ | |
297 unsigned char visited; /* Used to find circles. */ | |
298 struct sym *next; /* Hash collision list. */ | |
299 struct link *subs; /* List of subclasses. */ | |
300 struct link *supers; /* List of superclasses. */ | |
301 struct member *vars; /* List of instance variables. */ | |
302 struct member *fns; /* List of instance functions. */ | |
303 struct member *static_vars; /* List of static variables. */ | |
304 struct member *static_fns; /* List of static functions. */ | |
305 struct member *friends; /* List of friend functions. */ | |
306 struct member *types; /* List of local types. */ | |
307 char *regexp; /* Matching regular expression. */ | |
308 int pos; /* Buffer position. */ | |
309 char *filename; /* File in which it can be found. */ | |
310 char *sfilename; /* File in which members can be found. */ | |
311 struct sym *namesp; /* Namespace in which defined. . */ | |
312 char name[1]; /* Name of the class. */ | |
313 }; | |
314 | |
315 /* Experimental: Print info for `--position-info'. We print | |
316 '(CLASS-NAME SCOPE MEMBER-NAME). */ | |
317 | |
318 #define P_DEFN 1 | |
319 #define P_DECL 2 | |
320 | |
321 int info_where; | |
322 struct sym *info_cls = NULL; | |
323 struct member *info_member = NULL; | |
324 | |
325 /* Experimental. For option `--position-info', the buffer position we | |
326 are interested in. When this position is reached, print out | |
327 information about what we know about that point. */ | |
328 | |
329 int info_position = -1; | |
330 | |
331 /* Command line options structure for getopt_long. */ | |
332 | |
333 struct option options[] = | |
334 { | |
335 {"append", no_argument, NULL, 'a'}, | |
336 {"files", required_argument, NULL, 'f'}, | |
337 {"help", no_argument, NULL, -2}, | |
338 {"min-regexp-length", required_argument, NULL, 'm'}, | |
339 {"max-regexp-length", required_argument, NULL, 'M'}, | |
340 {"no-nested-classes", no_argument, NULL, 'n'}, | |
341 {"no-regexps", no_argument, NULL, 'x'}, | |
342 {"no-structs-or-unions", no_argument, NULL, 's'}, | |
343 {"output-file", required_argument, NULL, 'o'}, | |
344 {"position-info", required_argument, NULL, 'p'}, | |
345 {"search-path", required_argument, NULL, 'I'}, | |
346 {"verbose", no_argument, NULL, 'v'}, | |
347 {"version", no_argument, NULL, -3}, | |
348 {"very-verbose", no_argument, NULL, 'V'}, | |
349 {NULL, 0, NULL, 0} | |
350 }; | |
351 | |
352 /* Semantic values of tokens. Set by yylex.. */ | |
353 | |
354 unsigned yyival; /* Set for token CINT. */ | |
355 char *yytext; /* Set for token IDENT. */ | |
356 char *yytext_end; | |
357 | |
358 /* Output file. */ | |
359 | |
360 FILE *yyout; | |
361 | |
362 /* Current line number. */ | |
363 | |
364 int yyline; | |
365 | |
366 /* The name of the current input file. */ | |
367 | |
368 char *filename; | |
369 | |
370 /* Three character class vectors, and macros to test membership | |
371 of characters. */ | |
372 | |
373 char is_ident[255]; | |
374 char is_digit[255]; | |
375 char is_white[255]; | |
376 | |
377 #define IDENTP(C) is_ident[(unsigned char) (C)] | |
378 #define DIGITP(C) is_digit[(unsigned char) (C)] | |
379 #define WHITEP(C) is_white[(unsigned char) (C)] | |
380 | |
381 /* Command line flags. */ | |
382 | |
383 int f_append; | |
384 int f_verbose; | |
385 int f_very_verbose; | |
386 int f_structs = 1; | |
387 int f_regexps = 1; | |
388 int f_nested_classes = 1; | |
389 | |
390 /* Maximum and minimum lengths of regular expressions matching a | |
391 member, class etc., for writing them to the output file. These are | |
392 overridable from the command line. */ | |
393 | |
394 int min_regexp = 5; | |
395 int max_regexp = 50; | |
396 | |
397 /* Input buffer. */ | |
398 | |
399 char *inbuffer; | |
400 char *in; | |
401 int inbuffer_size; | |
402 | |
403 /* Return the current buffer position in the input file. */ | |
404 | |
405 #define BUFFER_POS() (in - inbuffer) | |
406 | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
407 /* If current lookahead is CSTRING, the following points to the |
28523 | 408 first character in the string constant. Used for recognizing |
409 extern "C". */ | |
410 | |
411 char *string_start; | |
412 | |
413 /* The size of the hash tables for classes.and members. Should be | |
414 prime. */ | |
415 | |
416 #define TABLE_SIZE 1001 | |
417 | |
418 /* The hash table for class symbols. */ | |
419 | |
420 struct sym *class_table[TABLE_SIZE]; | |
421 | |
422 /* Hash table containing all member structures. This is generally | |
423 faster for member lookup than traversing the member lists of a | |
424 `struct sym'. */ | |
425 | |
426 struct member *member_table[TABLE_SIZE]; | |
427 | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
428 /* Hash table for namespace aliases */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
429 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
430 struct alias *namespace_alias_table[TABLE_SIZE]; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
431 |
28523 | 432 /* The special class symbol used to hold global functions, |
433 variables etc. */ | |
434 | |
435 struct sym *global_symbols; | |
436 | |
437 /* The current namespace. */ | |
438 | |
439 struct sym *current_namespace; | |
440 | |
441 /* The list of all known namespaces. */ | |
442 | |
443 struct sym *all_namespaces; | |
444 | |
445 /* Stack of namespaces we're currently nested in, during the parse. */ | |
446 | |
447 struct sym **namespace_stack; | |
448 int namespace_stack_size; | |
449 int namespace_sp; | |
450 | |
451 /* The current lookahead token. */ | |
452 | |
453 int tk = -1; | |
454 | |
455 /* Structure describing a keyword. */ | |
456 | |
457 struct kw | |
458 { | |
459 char *name; /* Spelling. */ | |
460 int tk; /* Token value. */ | |
461 struct kw *next; /* Next in collision chain. */ | |
462 }; | |
463 | |
464 /* Keywords are lookup up in a hash table of their own. */ | |
465 | |
466 #define KEYWORD_TABLE_SIZE 1001 | |
467 struct kw *keyword_table[KEYWORD_TABLE_SIZE]; | |
468 | |
469 /* Search path. */ | |
470 | |
471 struct search_path | |
472 { | |
473 char *path; | |
474 struct search_path *next; | |
475 }; | |
476 | |
477 struct search_path *search_path; | |
478 struct search_path *search_path_tail; | |
479 | |
480 /* Function prototypes. */ | |
481 | |
482 int yylex P_ ((void)); | |
483 void yyparse P_ ((void)); | |
484 void re_init_parser P_ ((void)); | |
485 char *token_string P_ ((int)); | |
486 char *matching_regexp P_ ((void)); | |
487 void init_sym P_ ((void)); | |
488 struct sym *add_sym P_ ((char *, struct sym *)); | |
489 void add_link P_ ((struct sym *, struct sym *)); | |
490 void add_member_defn P_ ((struct sym *, char *, char *, | |
491 int, unsigned, int, int, int)); | |
492 void add_member_decl P_ ((struct sym *, char *, char *, int, | |
493 unsigned, int, int, int, int)); | |
494 void dump_roots P_ ((FILE *)); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
495 void *xmalloc P_ ((int)); |
35459 | 496 void xfree P_ ((void *)); |
28523 | 497 void add_global_defn P_ ((char *, char *, int, unsigned, int, int, int)); |
498 void add_global_decl P_ ((char *, char *, int, unsigned, int, int, int)); | |
499 void add_define P_ ((char *, char *, int)); | |
500 void mark_inherited_virtual P_ ((void)); | |
501 void leave_namespace P_ ((void)); | |
502 void enter_namespace P_ ((char *)); | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
503 void register_namespace_alias P_ ((char *, struct link *)); |
28523 | 504 void insert_keyword P_ ((char *, int)); |
505 void re_init_scanner P_ ((void)); | |
506 void init_scanner P_ ((void)); | |
507 void usage P_ ((int)); | |
508 void version P_ ((void)); | |
509 void process_file P_ ((char *)); | |
510 void add_search_path P_ ((char *)); | |
511 FILE *open_file P_ ((char *)); | |
512 int process_pp_line P_ ((void)); | |
513 int dump_members P_ ((FILE *, struct member *)); | |
514 void dump_sym P_ ((FILE *, struct sym *)); | |
515 int dump_tree P_ ((FILE *, struct sym *)); | |
516 struct member *find_member P_ ((struct sym *, char *, int, int, unsigned)); | |
517 struct member *add_member P_ ((struct sym *, char *, int, int, unsigned)); | |
518 void mark_virtual P_ ((struct sym *)); | |
519 void mark_virtual P_ ((struct sym *)); | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
520 struct sym *make_namespace P_ ((char *, struct sym *)); |
28523 | 521 char *sym_scope P_ ((struct sym *)); |
522 char *sym_scope_1 P_ ((struct sym *)); | |
523 int skip_to P_ ((int)); | |
524 void skip_matching P_ ((void)); | |
525 void member P_ ((struct sym *, int)); | |
526 void class_body P_ ((struct sym *, int)); | |
527 void class_definition P_ ((struct sym *, int, int, int)); | |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
528 void declaration P_ ((int)); |
28523 | 529 unsigned parm_list P_ ((int *)); |
530 char *operator_name P_ ((int *)); | |
531 struct sym *parse_classname P_ ((void)); | |
532 struct sym *parse_qualified_ident_or_type P_ ((char **)); | |
533 void parse_qualified_param_ident_or_type P_ ((char **)); | |
534 int globals P_ ((int)); | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
535 void yyerror P_ ((char *, char *)); |
28523 | 536 |
537 | |
538 | |
539 /*********************************************************************** | |
540 Utilities | |
541 ***********************************************************************/ | |
542 | |
543 /* Print an error in a printf-like style with the current input file | |
544 name and line number. */ | |
545 | |
546 void | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
547 yyerror (format, s) |
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
548 char *format, *s; |
28523 | 549 { |
550 fprintf (stderr, "%s:%d: ", filename, yyline); | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
551 fprintf (stderr, format, s); |
28523 | 552 putc ('\n', stderr); |
553 } | |
554 | |
555 | |
556 /* Like malloc but print an error and exit if not enough memory is | |
33384 | 557 available. */ |
28523 | 558 |
559 void * | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
560 xmalloc (nbytes) |
28523 | 561 int nbytes; |
562 { | |
563 void *p = malloc (nbytes); | |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
564 if (p == NULL) |
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
565 { |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
566 yyerror ("out of memory", NULL); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
567 exit (EXIT_FAILURE); |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
568 } |
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
569 return p; |
28523 | 570 } |
571 | |
572 | |
573 /* Like realloc but print an error and exit if out of memory. */ | |
574 | |
575 void * | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
576 xrealloc (p, sz) |
28523 | 577 void *p; |
578 int sz; | |
579 { | |
580 p = realloc (p, sz); | |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
581 if (p == NULL) |
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
582 { |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
583 yyerror ("out of memory", NULL); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
584 exit (EXIT_FAILURE); |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
585 } |
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
586 return p; |
28523 | 587 } |
588 | |
589 | |
35459 | 590 /* Like free but always check for null pointers.. */ |
591 | |
592 void | |
593 xfree (p) | |
594 void *p; | |
595 { | |
596 if (p) | |
597 free (p); | |
598 } | |
599 | |
600 | |
28523 | 601 /* Like strdup, but print an error and exit if not enough memory is |
602 available.. If S is null, return null. */ | |
603 | |
604 char * | |
605 xstrdup (s) | |
606 char *s; | |
607 { | |
608 if (s) | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
609 s = strcpy (xmalloc (strlen (s) + 1), s); |
28523 | 610 return s; |
611 } | |
612 | |
613 | |
614 | |
615 /*********************************************************************** | |
616 Symbols | |
617 ***********************************************************************/ | |
618 | |
619 /* Initialize the symbol table. This currently only sets up the | |
620 special symbol for globals (`*Globals*'). */ | |
621 | |
622 void | |
623 init_sym () | |
624 { | |
625 global_symbols = add_sym (GLOBALS_NAME, NULL); | |
626 } | |
627 | |
628 | |
629 /* Add a symbol for class NAME to the symbol table. NESTED_IN_CLASS | |
630 is the class in which class NAME was found. If it is null, | |
631 this means the scope of NAME is the current namespace. | |
632 | |
633 If a symbol for NAME already exists, return that. Otherwise | |
634 create a new symbol and set it to default values. */ | |
635 | |
636 struct sym * | |
637 add_sym (name, nested_in_class) | |
638 char *name; | |
639 struct sym *nested_in_class; | |
640 { | |
641 struct sym *sym; | |
642 unsigned h; | |
643 char *s; | |
644 struct sym *scope = nested_in_class ? nested_in_class : current_namespace; | |
645 | |
646 for (s = name, h = 0; *s; ++s) | |
647 h = (h << 1) ^ *s; | |
648 h %= TABLE_SIZE; | |
649 | |
650 for (sym = class_table[h]; sym; sym = sym->next) | |
65626
69a9e146ef35
(add_sym): Compare namespace names instead of namespace objects. This
Chong Yidong <cyd@stupidchicken.com>
parents:
64769
diff
changeset
|
651 if (streq (name, sym->name) |
69a9e146ef35
(add_sym): Compare namespace names instead of namespace objects. This
Chong Yidong <cyd@stupidchicken.com>
parents:
64769
diff
changeset
|
652 && ((!sym->namesp && !scope) |
69a9e146ef35
(add_sym): Compare namespace names instead of namespace objects. This
Chong Yidong <cyd@stupidchicken.com>
parents:
64769
diff
changeset
|
653 || (sym->namesp && scope |
69a9e146ef35
(add_sym): Compare namespace names instead of namespace objects. This
Chong Yidong <cyd@stupidchicken.com>
parents:
64769
diff
changeset
|
654 && streq (sym->namesp->name, scope->name)))) |
28523 | 655 break; |
656 | |
657 if (sym == NULL) | |
658 { | |
659 if (f_very_verbose) | |
660 { | |
661 putchar ('\t'); | |
662 puts (name); | |
663 } | |
664 | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
665 sym = (struct sym *) xmalloc (sizeof *sym + strlen (name)); |
28523 | 666 bzero (sym, sizeof *sym); |
667 strcpy (sym->name, name); | |
668 sym->namesp = scope; | |
669 sym->next = class_table[h]; | |
670 class_table[h] = sym; | |
671 } | |
672 | |
673 return sym; | |
674 } | |
675 | |
676 | |
677 /* Add links between superclass SUPER and subclass SUB. */ | |
678 | |
679 void | |
680 add_link (super, sub) | |
681 struct sym *super, *sub; | |
682 { | |
683 struct link *lnk, *lnk2, *p, *prev; | |
684 | |
685 /* See if a link already exists. */ | |
686 for (p = super->subs, prev = NULL; | |
687 p && strcmp (sub->name, p->sym->name) > 0; | |
688 prev = p, p = p->next) | |
689 ; | |
690 | |
691 /* Avoid duplicates. */ | |
692 if (p == NULL || p->sym != sub) | |
693 { | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
694 lnk = (struct link *) xmalloc (sizeof *lnk); |
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
695 lnk2 = (struct link *) xmalloc (sizeof *lnk2); |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
696 |
28523 | 697 lnk->sym = sub; |
698 lnk->next = p; | |
699 | |
700 if (prev) | |
701 prev->next = lnk; | |
702 else | |
703 super->subs = lnk; | |
704 | |
705 lnk2->sym = super; | |
706 lnk2->next = sub->supers; | |
707 sub->supers = lnk2; | |
708 } | |
709 } | |
710 | |
711 | |
712 /* Find in class CLS member NAME. | |
713 | |
714 VAR non-zero means look for a member variable; otherwise a function | |
715 is searched. SC specifies what kind of member is searched---a | |
716 static, or per-instance member etc. HASH is a hash code for the | |
717 parameter types of functions. Value is a pointer to the member | |
718 found or null if not found. */ | |
719 | |
720 struct member * | |
721 find_member (cls, name, var, sc, hash) | |
722 struct sym *cls; | |
723 char *name; | |
724 int var, sc; | |
725 unsigned hash; | |
726 { | |
727 struct member **list; | |
728 struct member *p; | |
729 unsigned name_hash = 0; | |
730 char *s; | |
731 int i; | |
732 | |
733 switch (sc) | |
734 { | |
735 case SC_FRIEND: | |
736 list = &cls->friends; | |
737 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
738 |
28523 | 739 case SC_TYPE: |
740 list = &cls->types; | |
741 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
742 |
28523 | 743 case SC_STATIC: |
744 list = var ? &cls->static_vars : &cls->static_fns; | |
745 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
746 |
28523 | 747 default: |
748 list = var ? &cls->vars : &cls->fns; | |
749 break; | |
750 } | |
751 | |
752 for (s = name; *s; ++s) | |
753 name_hash = (name_hash << 1) ^ *s; | |
754 i = name_hash % TABLE_SIZE; | |
755 | |
756 for (p = member_table[i]; p; p = p->anext) | |
757 if (p->list == list && p->param_hash == hash && streq (name, p->name)) | |
758 break; | |
759 | |
760 return p; | |
761 } | |
762 | |
763 | |
764 /* Add to class CLS information for the declaration of member NAME. | |
765 REGEXP is a regexp matching the declaration, if non-null. POS is | |
766 the position in the source where the declaration is found. HASH is | |
767 a hash code for the parameter list of the member, if it's a | |
768 function. VAR non-zero means member is a variable or type. SC | |
769 specifies the type of member (instance member, static, ...). VIS | |
770 is the member's visibility (public, protected, private). FLAGS is | |
771 a bit set giving additional information about the member (see the | |
772 F_* defines). */ | |
773 | |
774 void | |
775 add_member_decl (cls, name, regexp, pos, hash, var, sc, vis, flags) | |
776 struct sym *cls; | |
777 char *name; | |
778 char *regexp; | |
779 int pos; | |
780 unsigned hash; | |
781 int var; | |
782 int sc; | |
783 int vis; | |
784 int flags; | |
785 { | |
786 struct member *m; | |
787 | |
788 m = find_member (cls, name, var, sc, hash); | |
789 if (m == NULL) | |
790 m = add_member (cls, name, var, sc, hash); | |
791 | |
792 /* Have we seen a new filename? If so record that. */ | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
793 if (!cls->filename || !FILENAME_EQ (cls->filename, filename)) |
28523 | 794 m->filename = filename; |
795 | |
796 m->regexp = regexp; | |
797 m->pos = pos; | |
798 m->flags = flags; | |
799 | |
800 switch (vis) | |
801 { | |
802 case PRIVATE: | |
803 m->vis = V_PRIVATE; | |
804 break; | |
805 | |
806 case PROTECTED: | |
807 m->vis = V_PROTECTED; | |
808 break; | |
809 | |
810 case PUBLIC: | |
811 m->vis = V_PUBLIC; | |
812 break; | |
813 } | |
814 | |
815 info_where = P_DECL; | |
816 info_cls = cls; | |
817 info_member = m; | |
818 } | |
819 | |
820 | |
821 /* Add to class CLS information for the definition of member NAME. | |
822 REGEXP is a regexp matching the declaration, if non-null. POS is | |
823 the position in the source where the declaration is found. HASH is | |
824 a hash code for the parameter list of the member, if it's a | |
825 function. VAR non-zero means member is a variable or type. SC | |
826 specifies the type of member (instance member, static, ...). VIS | |
827 is the member's visibility (public, protected, private). FLAGS is | |
828 a bit set giving additional information about the member (see the | |
829 F_* defines). */ | |
830 | |
831 void | |
832 add_member_defn (cls, name, regexp, pos, hash, var, sc, flags) | |
833 struct sym *cls; | |
834 char *name; | |
835 char *regexp; | |
836 int pos; | |
837 unsigned hash; | |
838 int var; | |
839 int sc; | |
840 int flags; | |
841 { | |
842 struct member *m; | |
843 | |
844 if (sc == SC_UNKNOWN) | |
845 { | |
846 m = find_member (cls, name, var, SC_MEMBER, hash); | |
847 if (m == NULL) | |
848 { | |
849 m = find_member (cls, name, var, SC_STATIC, hash); | |
850 if (m == NULL) | |
851 m = add_member (cls, name, var, sc, hash); | |
852 } | |
853 } | |
854 else | |
855 { | |
856 m = find_member (cls, name, var, sc, hash); | |
857 if (m == NULL) | |
858 m = add_member (cls, name, var, sc, hash); | |
859 } | |
860 | |
861 if (!cls->sfilename) | |
862 cls->sfilename = filename; | |
863 | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
864 if (!FILENAME_EQ (cls->sfilename, filename)) |
28523 | 865 m->def_filename = filename; |
866 | |
867 m->def_regexp = regexp; | |
868 m->def_pos = pos; | |
869 m->flags |= flags; | |
870 | |
871 info_where = P_DEFN; | |
872 info_cls = cls; | |
873 info_member = m; | |
874 } | |
875 | |
876 | |
877 /* Add a symbol for a define named NAME to the symbol table. | |
878 REGEXP is a regular expression matching the define in the source, | |
879 if it is non-null. POS is the position in the file. */ | |
880 | |
881 void | |
882 add_define (name, regexp, pos) | |
883 char *name, *regexp; | |
884 int pos; | |
885 { | |
886 add_global_defn (name, regexp, pos, 0, 1, SC_FRIEND, F_DEFINE); | |
887 add_global_decl (name, regexp, pos, 0, 1, SC_FRIEND, F_DEFINE); | |
888 } | |
889 | |
890 | |
891 /* Add information for the global definition of NAME. | |
892 REGEXP is a regexp matching the declaration, if non-null. POS is | |
893 the position in the source where the declaration is found. HASH is | |
894 a hash code for the parameter list of the member, if it's a | |
895 function. VAR non-zero means member is a variable or type. SC | |
896 specifies the type of member (instance member, static, ...). VIS | |
897 is the member's visibility (public, protected, private). FLAGS is | |
898 a bit set giving additional information about the member (see the | |
899 F_* defines). */ | |
900 | |
901 void | |
902 add_global_defn (name, regexp, pos, hash, var, sc, flags) | |
903 char *name, *regexp; | |
904 int pos; | |
905 unsigned hash; | |
906 int var; | |
907 int sc; | |
908 int flags; | |
909 { | |
910 int i; | |
911 struct sym *sym; | |
912 | |
913 /* Try to find out for which classes a function is a friend, and add | |
914 what we know about it to them. */ | |
915 if (!var) | |
916 for (i = 0; i < TABLE_SIZE; ++i) | |
917 for (sym = class_table[i]; sym; sym = sym->next) | |
918 if (sym != global_symbols && sym->friends) | |
919 if (find_member (sym, name, 0, SC_FRIEND, hash)) | |
920 add_member_defn (sym, name, regexp, pos, hash, 0, | |
921 SC_FRIEND, flags); | |
922 | |
923 /* Add to global symbols. */ | |
924 add_member_defn (global_symbols, name, regexp, pos, hash, var, sc, flags); | |
925 } | |
926 | |
927 | |
928 /* Add information for the global declaration of NAME. | |
929 REGEXP is a regexp matching the declaration, if non-null. POS is | |
930 the position in the source where the declaration is found. HASH is | |
931 a hash code for the parameter list of the member, if it's a | |
932 function. VAR non-zero means member is a variable or type. SC | |
933 specifies the type of member (instance member, static, ...). VIS | |
934 is the member's visibility (public, protected, private). FLAGS is | |
935 a bit set giving additional information about the member (see the | |
936 F_* defines). */ | |
937 | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
938 void |
28523 | 939 add_global_decl (name, regexp, pos, hash, var, sc, flags) |
940 char *name, *regexp; | |
941 int pos; | |
942 unsigned hash; | |
943 int var; | |
944 int sc; | |
945 int flags; | |
946 { | |
947 /* Add declaration only if not already declared. Header files must | |
948 be processed before source files for this to have the right effect. | |
949 I do not want to handle implicit declarations at the moment. */ | |
950 struct member *m; | |
951 struct member *found; | |
952 | |
953 m = found = find_member (global_symbols, name, var, sc, hash); | |
954 if (m == NULL) | |
955 m = add_member (global_symbols, name, var, sc, hash); | |
956 | |
957 /* Definition already seen => probably last declaration implicit. | |
958 Override. This means that declarations must always be added to | |
959 the symbol table before definitions. */ | |
960 if (!found) | |
961 { | |
962 if (!global_symbols->filename | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
963 || !FILENAME_EQ (global_symbols->filename, filename)) |
28523 | 964 m->filename = filename; |
965 | |
966 m->regexp = regexp; | |
967 m->pos = pos; | |
968 m->vis = V_PUBLIC; | |
969 m->flags = flags; | |
970 | |
971 info_where = P_DECL; | |
972 info_cls = global_symbols; | |
973 info_member = m; | |
974 } | |
975 } | |
976 | |
977 | |
978 /* Add a symbol for member NAME to class CLS. | |
979 VAR non-zero means it's a variable. SC specifies the kind of | |
980 member. HASH is a hash code for the parameter types of a function. | |
981 Value is a pointer to the member's structure. */ | |
982 | |
983 struct member * | |
984 add_member (cls, name, var, sc, hash) | |
985 struct sym *cls; | |
986 char *name; | |
987 int var; | |
988 int sc; | |
989 unsigned hash; | |
990 { | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
991 struct member *m = (struct member *) xmalloc (sizeof *m + strlen (name)); |
28523 | 992 struct member **list; |
993 struct member *p; | |
994 struct member *prev; | |
995 unsigned name_hash = 0; | |
996 int i; | |
997 char *s; | |
998 | |
999 strcpy (m->name, name); | |
1000 m->param_hash = hash; | |
1001 | |
1002 m->vis = 0; | |
1003 m->flags = 0; | |
1004 m->regexp = NULL; | |
1005 m->filename = NULL; | |
1006 m->pos = 0; | |
1007 m->def_regexp = NULL; | |
1008 m->def_filename = NULL; | |
1009 m->def_pos = 0; | |
1010 | |
1011 assert (cls != NULL); | |
1012 | |
1013 switch (sc) | |
1014 { | |
1015 case SC_FRIEND: | |
1016 list = &cls->friends; | |
1017 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1018 |
28523 | 1019 case SC_TYPE: |
1020 list = &cls->types; | |
1021 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1022 |
28523 | 1023 case SC_STATIC: |
1024 list = var ? &cls->static_vars : &cls->static_fns; | |
1025 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1026 |
28523 | 1027 default: |
1028 list = var ? &cls->vars : &cls->fns; | |
1029 break; | |
1030 } | |
1031 | |
1032 for (s = name; *s; ++s) | |
1033 name_hash = (name_hash << 1) ^ *s; | |
1034 i = name_hash % TABLE_SIZE; | |
1035 m->anext = member_table[i]; | |
1036 member_table[i] = m; | |
1037 m->list = list; | |
1038 | |
1039 /* Keep the member list sorted. It's cheaper to do it here than to | |
1040 sort them in Lisp. */ | |
1041 for (prev = NULL, p = *list; | |
1042 p && strcmp (name, p->name) > 0; | |
1043 prev = p, p = p->next) | |
1044 ; | |
1045 | |
1046 m->next = p; | |
1047 if (prev) | |
1048 prev->next = m; | |
1049 else | |
1050 *list = m; | |
1051 return m; | |
1052 } | |
1053 | |
1054 | |
1055 /* Given the root R of a class tree, step through all subclasses | |
1056 recursively, marking functions as virtual that are declared virtual | |
1057 in base classes. */ | |
1058 | |
1059 void | |
1060 mark_virtual (r) | |
1061 struct sym *r; | |
1062 { | |
1063 struct link *p; | |
1064 struct member *m, *m2; | |
1065 | |
1066 for (p = r->subs; p; p = p->next) | |
1067 { | |
1068 for (m = r->fns; m; m = m->next) | |
1069 if (HAS_FLAG (m->flags, F_VIRTUAL)) | |
1070 { | |
1071 for (m2 = p->sym->fns; m2; m2 = m2->next) | |
1072 if (m->param_hash == m2->param_hash && streq (m->name, m2->name)) | |
1073 SET_FLAG (m2->flags, F_VIRTUAL); | |
1074 } | |
1075 | |
1076 mark_virtual (p->sym); | |
1077 } | |
1078 } | |
1079 | |
1080 | |
1081 /* For all roots of the class tree, mark functions as virtual that | |
1082 are virtual because of a virtual declaration in a base class. */ | |
1083 | |
1084 void | |
1085 mark_inherited_virtual () | |
1086 { | |
1087 struct sym *r; | |
1088 int i; | |
1089 | |
1090 for (i = 0; i < TABLE_SIZE; ++i) | |
1091 for (r = class_table[i]; r; r = r->next) | |
1092 if (r->supers == NULL) | |
1093 mark_virtual (r); | |
1094 } | |
1095 | |
1096 | |
1097 /* Create and return a symbol for a namespace with name NAME. */ | |
1098 | |
1099 struct sym * | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1100 make_namespace (name, context) |
28523 | 1101 char *name; |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1102 struct sym *context; |
28523 | 1103 { |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
1104 struct sym *s = (struct sym *) xmalloc (sizeof *s + strlen (name)); |
28523 | 1105 bzero (s, sizeof *s); |
1106 strcpy (s->name, name); | |
1107 s->next = all_namespaces; | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1108 s->namesp = context; |
28523 | 1109 all_namespaces = s; |
1110 return s; | |
1111 } | |
1112 | |
1113 | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1114 /* Find the symbol for namespace NAME. If not found, retrun NULL */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1115 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1116 struct sym * |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1117 check_namespace (name, context) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1118 char *name; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1119 struct sym *context; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1120 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1121 struct sym *p = NULL; |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1122 |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1123 for (p = all_namespaces; p; p = p->next) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1124 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1125 if (streq (p->name, name) && (p->namesp == context)) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1126 break; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1127 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1128 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1129 return p; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1130 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1131 |
28523 | 1132 /* Find the symbol for namespace NAME. If not found, add a new symbol |
1133 for NAME to all_namespaces. */ | |
1134 | |
1135 struct sym * | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1136 find_namespace (name, context) |
28523 | 1137 char *name; |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1138 struct sym *context; |
28523 | 1139 { |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1140 struct sym *p = check_namespace (name, context); |
28523 | 1141 |
1142 if (p == NULL) | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1143 p = make_namespace (name, context); |
28523 | 1144 |
1145 return p; | |
1146 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1147 |
28523 | 1148 |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1149 /* Find namespace alias with name NAME. If not found return NULL. */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1150 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1151 struct link * |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1152 check_namespace_alias (name) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1153 char *name; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1154 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1155 struct link *p = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1156 struct alias *al; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1157 unsigned h; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1158 char *s; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1159 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1160 for (s = name, h = 0; *s; ++s) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1161 h = (h << 1) ^ *s; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1162 h %= TABLE_SIZE; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1163 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1164 for (al = namespace_alias_table[h]; al; al = al->next) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1165 if (streq (name, al->name) && (al->namesp == current_namespace)) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1166 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1167 p = al->aliasee; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1168 break; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1169 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1170 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1171 return p; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1172 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1173 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1174 /* Register the name NEW_NAME as an alias for namespace list OLD_NAME. */ |
28523 | 1175 |
1176 void | |
1177 register_namespace_alias (new_name, old_name) | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1178 char *new_name; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1179 struct link *old_name; |
28523 | 1180 { |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1181 unsigned h; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1182 char *s; |
28523 | 1183 struct alias *al; |
1184 | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1185 for (s = new_name, h = 0; *s; ++s) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1186 h = (h << 1) ^ *s; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1187 h %= TABLE_SIZE; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1188 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1189 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1190 /* Is it already in the table of aliases? */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1191 for (al = namespace_alias_table[h]; al; al = al->next) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1192 if (streq (new_name, al->name) && (al->namesp == current_namespace)) |
28523 | 1193 return; |
1194 | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
1195 al = (struct alias *) xmalloc (sizeof *al + strlen (new_name)); |
28523 | 1196 strcpy (al->name, new_name); |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1197 al->next = namespace_alias_table[h]; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1198 al->namesp = current_namespace; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1199 al->aliasee = old_name; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1200 namespace_alias_table[h] = al; |
28523 | 1201 } |
1202 | |
1203 | |
1204 /* Enter namespace with name NAME. */ | |
1205 | |
1206 void | |
1207 enter_namespace (name) | |
1208 char *name; | |
1209 { | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
1210 struct sym *p = find_namespace (name, current_namespace); |
28523 | 1211 |
1212 if (namespace_sp == namespace_stack_size) | |
1213 { | |
1214 int size = max (10, 2 * namespace_stack_size); | |
37615
ceb79feb93aa
(enter_namespace): Fix reallocation of
Gerd Moellmann <gerd@gnu.org>
parents:
37594
diff
changeset
|
1215 namespace_stack |
ceb79feb93aa
(enter_namespace): Fix reallocation of
Gerd Moellmann <gerd@gnu.org>
parents:
37594
diff
changeset
|
1216 = (struct sym **) xrealloc ((void *)namespace_stack, |
ceb79feb93aa
(enter_namespace): Fix reallocation of
Gerd Moellmann <gerd@gnu.org>
parents:
37594
diff
changeset
|
1217 size * sizeof *namespace_stack); |
28523 | 1218 namespace_stack_size = size; |
1219 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1220 |
28523 | 1221 namespace_stack[namespace_sp++] = current_namespace; |
1222 current_namespace = p; | |
1223 } | |
1224 | |
1225 | |
1226 /* Leave the current namespace. */ | |
1227 | |
1228 void | |
1229 leave_namespace () | |
1230 { | |
1231 assert (namespace_sp > 0); | |
1232 current_namespace = namespace_stack[--namespace_sp]; | |
1233 } | |
1234 | |
1235 | |
1236 | |
1237 /*********************************************************************** | |
1238 Writing the Output File | |
1239 ***********************************************************************/ | |
1240 | |
1241 /* Write string S to the output file FP in a Lisp-readable form. | |
1242 If S is null, write out `()'. */ | |
1243 | |
1244 #define PUTSTR(s, fp) \ | |
1245 do { \ | |
1246 if (!s) \ | |
1247 { \ | |
1248 putc ('(', fp); \ | |
1249 putc (')', fp); \ | |
1250 putc (' ', fp); \ | |
1251 } \ | |
1252 else \ | |
1253 { \ | |
1254 putc ('"', fp); \ | |
1255 fputs (s, fp); \ | |
1256 putc ('"', fp); \ | |
1257 putc (' ', fp); \ | |
1258 } \ | |
1259 } while (0) | |
1260 | |
1261 /* A dynamically allocated buffer for constructing a scope name. */ | |
1262 | |
1263 char *scope_buffer; | |
1264 int scope_buffer_size; | |
1265 int scope_buffer_len; | |
1266 | |
1267 | |
1268 /* Make sure scope_buffer has enough room to add LEN chars to it. */ | |
1269 | |
1270 void | |
1271 ensure_scope_buffer_room (len) | |
1272 int len; | |
1273 { | |
1274 if (scope_buffer_len + len >= scope_buffer_size) | |
1275 { | |
1276 int new_size = max (2 * scope_buffer_size, scope_buffer_len + len); | |
34522
db980c0e762d
(ensure_scope_buffer_room): Fix xrealloc call.
Dave Love <fx@gnu.org>
parents:
34304
diff
changeset
|
1277 scope_buffer = (char *) xrealloc (scope_buffer, new_size); |
28523 | 1278 scope_buffer_size = new_size; |
1279 } | |
1280 } | |
1281 | |
1282 | |
1283 /* Recursively add the scope names of symbol P and the scopes of its | |
1284 namespaces to scope_buffer. Value is a pointer to the complete | |
1285 scope name constructed. */ | |
1286 | |
1287 char * | |
1288 sym_scope_1 (p) | |
1289 struct sym *p; | |
1290 { | |
1291 int len; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1292 |
28523 | 1293 if (p->namesp) |
1294 sym_scope_1 (p->namesp); | |
1295 | |
1296 if (*scope_buffer) | |
1297 { | |
1298 ensure_scope_buffer_room (3); | |
1299 strcat (scope_buffer, "::"); | |
1300 scope_buffer_len += 2; | |
1301 } | |
1302 | |
1303 len = strlen (p->name); | |
1304 ensure_scope_buffer_room (len + 1); | |
1305 strcat (scope_buffer, p->name); | |
1306 scope_buffer_len += len; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1307 |
28523 | 1308 if (HAS_FLAG (p->flags, F_TEMPLATE)) |
1309 { | |
1310 ensure_scope_buffer_room (3); | |
1311 strcat (scope_buffer, "<>"); | |
1312 scope_buffer_len += 2; | |
1313 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1314 |
28523 | 1315 return scope_buffer; |
1316 } | |
1317 | |
1318 | |
1319 /* Return the scope of symbol P in printed representation, i.e. | |
1320 as it would appear in a C*+ source file. */ | |
1321 | |
1322 char * | |
1323 sym_scope (p) | |
1324 struct sym *p; | |
1325 { | |
1326 if (!scope_buffer) | |
1327 { | |
1328 scope_buffer_size = 1024; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
1329 scope_buffer = (char *) xmalloc (scope_buffer_size); |
28523 | 1330 } |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1331 |
28523 | 1332 *scope_buffer = '\0'; |
1333 scope_buffer_len = 0; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1334 |
28523 | 1335 if (p->namesp) |
1336 sym_scope_1 (p->namesp); | |
1337 | |
1338 return scope_buffer; | |
1339 } | |
1340 | |
1341 | |
1342 /* Dump the list of members M to file FP. Value is the length of the | |
1343 list. */ | |
1344 | |
1345 int | |
1346 dump_members (fp, m) | |
1347 FILE *fp; | |
1348 struct member *m; | |
1349 { | |
1350 int n; | |
1351 | |
1352 putc ('(', fp); | |
1353 | |
1354 for (n = 0; m; m = m->next, ++n) | |
1355 { | |
1356 fputs (MEMBER_STRUCT, fp); | |
1357 PUTSTR (m->name, fp); | |
1358 PUTSTR (NULL, fp); /* FIXME? scope for globals */ | |
1359 fprintf (fp, "%u ", (unsigned) m->flags); | |
1360 PUTSTR (m->filename, fp); | |
1361 PUTSTR (m->regexp, fp); | |
1362 fprintf (fp, "%u ", (unsigned) m->pos); | |
1363 fprintf (fp, "%u ", (unsigned) m->vis); | |
1364 putc (' ', fp); | |
1365 PUTSTR (m->def_filename, fp); | |
1366 PUTSTR (m->def_regexp, fp); | |
1367 fprintf (fp, "%u", (unsigned) m->def_pos); | |
1368 putc (']', fp); | |
1369 putc ('\n', fp); | |
1370 } | |
1371 | |
1372 putc (')', fp); | |
1373 putc ('\n', fp); | |
1374 return n; | |
1375 } | |
1376 | |
1377 | |
1378 /* Dump class ROOT to stream FP. */ | |
1379 | |
1380 void | |
1381 dump_sym (fp, root) | |
1382 FILE *fp; | |
1383 struct sym *root; | |
1384 { | |
1385 fputs (CLASS_STRUCT, fp); | |
1386 PUTSTR (root->name, fp); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1387 |
28523 | 1388 /* Print scope, if any. */ |
1389 if (root->namesp) | |
1390 PUTSTR (sym_scope (root), fp); | |
1391 else | |
1392 PUTSTR (NULL, fp); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1393 |
28523 | 1394 /* Print flags. */ |
1395 fprintf (fp, "%u", root->flags); | |
1396 PUTSTR (root->filename, fp); | |
1397 PUTSTR (root->regexp, fp); | |
1398 fprintf (fp, "%u", (unsigned) root->pos); | |
1399 PUTSTR (root->sfilename, fp); | |
1400 putc (']', fp); | |
1401 putc ('\n', fp); | |
1402 } | |
1403 | |
1404 | |
1405 /* Dump class ROOT and its subclasses to file FP. Value is the | |
1406 number of classes written. */ | |
1407 | |
1408 int | |
1409 dump_tree (fp, root) | |
1410 FILE *fp; | |
1411 struct sym *root; | |
1412 { | |
1413 struct link *lk; | |
1414 unsigned n = 0; | |
1415 | |
1416 dump_sym (fp, root); | |
1417 | |
1418 if (f_verbose) | |
1419 { | |
1420 putchar ('+'); | |
1421 fflush (stdout); | |
1422 } | |
1423 | |
1424 putc ('(', fp); | |
1425 | |
1426 for (lk = root->subs; lk; lk = lk->next) | |
1427 { | |
1428 fputs (TREE_STRUCT, fp); | |
1429 n += dump_tree (fp, lk->sym); | |
1430 putc (']', fp); | |
1431 } | |
1432 | |
1433 putc (')', fp); | |
1434 | |
1435 dump_members (fp, root->vars); | |
1436 n += dump_members (fp, root->fns); | |
1437 dump_members (fp, root->static_vars); | |
1438 n += dump_members (fp, root->static_fns); | |
1439 n += dump_members (fp, root->friends); | |
1440 dump_members (fp, root->types); | |
1441 | |
1442 /* Superclasses. */ | |
1443 putc ('(', fp); | |
1444 putc (')', fp); | |
1445 | |
1446 /* Mark slot. */ | |
1447 putc ('(', fp); | |
1448 putc (')', fp); | |
1449 | |
1450 putc ('\n', fp); | |
1451 return n; | |
1452 } | |
1453 | |
1454 | |
1455 /* Dump the entire class tree to file FP. */ | |
1456 | |
1457 void | |
1458 dump_roots (fp) | |
1459 FILE *fp; | |
1460 { | |
1461 int i, n = 0; | |
1462 struct sym *r; | |
1463 | |
1464 /* Output file header containing version string, command line | |
1465 options etc. */ | |
1466 if (!f_append) | |
1467 { | |
1468 fputs (TREE_HEADER_STRUCT, fp); | |
1469 PUTSTR (EBROWSE_FILE_VERSION, fp); | |
1470 | |
1471 putc ('\"', fp); | |
1472 if (!f_structs) | |
1473 fputs (" -s", fp); | |
1474 if (f_regexps) | |
1475 fputs (" -x", fp); | |
1476 putc ('\"', fp); | |
1477 fputs (" ()", fp); | |
1478 fputs (" ()", fp); | |
1479 putc (']', fp); | |
1480 } | |
1481 | |
1482 /* Mark functions as virtual that are so because of functions | |
1483 declared virtual in base classes. */ | |
1484 mark_inherited_virtual (); | |
1485 | |
1486 /* Dump the roots of the graph. */ | |
1487 for (i = 0; i < TABLE_SIZE; ++i) | |
1488 for (r = class_table[i]; r; r = r->next) | |
1489 if (!r->supers) | |
1490 { | |
1491 fputs (TREE_STRUCT, fp); | |
1492 n += dump_tree (fp, r); | |
1493 putc (']', fp); | |
1494 } | |
1495 | |
1496 if (f_verbose) | |
1497 putchar ('\n'); | |
1498 } | |
1499 | |
1500 | |
1501 | |
1502 /*********************************************************************** | |
1503 Scanner | |
1504 ***********************************************************************/ | |
1505 | |
1506 #ifdef DEBUG | |
1507 #define INCREMENT_LINENO \ | |
1508 do { \ | |
1509 if (f_very_verbose) \ | |
1510 { \ | |
1511 ++yyline; \ | |
1512 printf ("%d:\n", yyline); \ | |
1513 } \ | |
1514 else \ | |
1515 ++yyline; \ | |
1516 } while (0) | |
1517 #else | |
1518 #define INCREMENT_LINENO ++yyline | |
1519 #endif | |
1520 | |
1521 /* Define two macros for accessing the input buffer (current input | |
1522 file). GET(C) sets C to the next input character and advances the | |
1523 input pointer. UNGET retracts the input pointer. */ | |
1524 | |
1525 #define GET(C) ((C) = *in++) | |
1526 #define UNGET() (--in) | |
1527 | |
1528 | |
1529 /* Process a preprocessor line. Value is the next character from the | |
1530 input buffer not consumed. */ | |
1531 | |
1532 int | |
1533 process_pp_line () | |
1534 { | |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1535 int in_comment = 0, in_string = 0; |
28523 | 1536 int c; |
1537 char *p = yytext; | |
1538 | |
1539 /* Skip over white space. The `#' has been consumed already. */ | |
1540 while (WHITEP (GET (c))) | |
1541 ; | |
1542 | |
1543 /* Read the preprocessor command (if any). */ | |
1544 while (IDENTP (c)) | |
1545 { | |
1546 *p++ = c; | |
1547 GET (c); | |
1548 } | |
1549 | |
1550 /* Is it a `define'? */ | |
1551 *p = '\0'; | |
1552 | |
1553 if (*yytext && streq (yytext, "define")) | |
1554 { | |
1555 p = yytext; | |
1556 while (WHITEP (c)) | |
1557 GET (c); | |
1558 while (IDENTP (c)) | |
1559 { | |
1560 *p++ = c; | |
1561 GET (c); | |
1562 } | |
1563 | |
1564 *p = '\0'; | |
1565 | |
1566 if (*yytext) | |
1567 { | |
1568 char *regexp = matching_regexp (); | |
1569 int pos = BUFFER_POS (); | |
1570 add_define (yytext, regexp, pos); | |
1571 } | |
1572 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1573 |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1574 while (c && (c != '\n' || in_comment || in_string)) |
28523 | 1575 { |
1576 if (c == '\\') | |
1577 GET (c); | |
1578 else if (c == '/' && !in_comment) | |
1579 { | |
1580 if (GET (c) == '*') | |
1581 in_comment = 1; | |
1582 } | |
1583 else if (c == '*' && in_comment) | |
1584 { | |
1585 if (GET (c) == '/') | |
1586 in_comment = 0; | |
1587 } | |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1588 else if (c == '"') |
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1589 in_string = !in_string; |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
1590 |
28523 | 1591 if (c == '\n') |
1592 INCREMENT_LINENO; | |
1593 | |
1594 GET (c); | |
1595 } | |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1596 |
28523 | 1597 return c; |
1598 } | |
1599 | |
1600 | |
1601 /* Value is the next token from the input buffer. */ | |
1602 | |
1603 int | |
1604 yylex () | |
1605 { | |
1606 int c; | |
1607 char end_char; | |
1608 char *p; | |
1609 | |
1610 for (;;) | |
1611 { | |
1612 while (WHITEP (GET (c))) | |
1613 ; | |
1614 | |
1615 switch (c) | |
1616 { | |
1617 case '\n': | |
1618 INCREMENT_LINENO; | |
1619 break; | |
1620 | |
1621 case '\r': | |
1622 break; | |
1623 | |
1624 case 0: | |
1625 /* End of file. */ | |
1626 return YYEOF; | |
1627 | |
1628 case '\\': | |
1629 GET (c); | |
1630 break; | |
1631 | |
1632 case '"': | |
1633 case '\'': | |
1634 /* String and character constants. */ | |
1635 end_char = c; | |
1636 string_start = in; | |
1637 while (GET (c) && c != end_char) | |
1638 { | |
1639 switch (c) | |
1640 { | |
1641 case '\\': | |
1642 /* Escape sequences. */ | |
1643 if (!GET (c)) | |
1644 { | |
1645 if (end_char == '\'') | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
1646 yyerror ("EOF in character constant", NULL); |
28523 | 1647 else |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
1648 yyerror ("EOF in string constant", NULL); |
28523 | 1649 goto end_string; |
1650 } | |
1651 else switch (c) | |
1652 { | |
1653 case '\n': | |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1654 INCREMENT_LINENO; |
28523 | 1655 case 'a': |
1656 case 'b': | |
1657 case 'f': | |
1658 case 'n': | |
1659 case 'r': | |
1660 case 't': | |
1661 case 'v': | |
1662 break; | |
1663 | |
1664 case 'x': | |
1665 { | |
1666 /* Hexadecimal escape sequence. */ | |
1667 int i; | |
1668 for (i = 0; i < 2; ++i) | |
1669 { | |
1670 GET (c); | |
1671 | |
1672 if (c >= '0' && c <= '7') | |
1673 ; | |
1674 else if (c >= 'a' && c <= 'f') | |
1675 ; | |
1676 else if (c >= 'A' && c <= 'F') | |
1677 ; | |
1678 else | |
1679 { | |
1680 UNGET (); | |
1681 break; | |
1682 } | |
1683 } | |
1684 } | |
1685 break; | |
1686 | |
1687 case '0': | |
1688 { | |
1689 /* Octal escape sequence. */ | |
1690 int i; | |
1691 for (i = 0; i < 3; ++i) | |
1692 { | |
1693 GET (c); | |
1694 | |
1695 if (c >= '0' && c <= '7') | |
1696 ; | |
1697 else | |
1698 { | |
1699 UNGET (); | |
1700 break; | |
1701 } | |
1702 } | |
1703 } | |
1704 break; | |
1705 | |
1706 default: | |
1707 break; | |
1708 } | |
1709 break; | |
1710 | |
1711 case '\n': | |
1712 if (end_char == '\'') | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
1713 yyerror ("newline in character constant", NULL); |
28523 | 1714 else |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
1715 yyerror ("newline in string constant", NULL); |
28523 | 1716 INCREMENT_LINENO; |
30138
d00767029418
(yylex): Accept string literals with newlines in them.
Gerd Moellmann <gerd@gnu.org>
parents:
29994
diff
changeset
|
1717 break; |
28523 | 1718 |
1719 default: | |
1720 break; | |
1721 } | |
1722 } | |
1723 | |
1724 end_string: | |
1725 return end_char == '\'' ? CCHAR : CSTRING; | |
1726 | |
1727 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': | |
1728 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': | |
1729 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': | |
1730 case 'v': case 'w': case 'x': case 'y': case 'z': | |
1731 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': | |
1732 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': | |
1733 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': | |
1734 case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': | |
1735 { | |
1736 /* Identifier and keywords. */ | |
1737 unsigned hash; | |
1738 struct kw *k; | |
1739 | |
1740 p = yytext; | |
1741 *p++ = hash = c; | |
1742 | |
1743 while (IDENTP (GET (*p))) | |
1744 { | |
1745 hash = (hash << 1) ^ *p++; | |
1746 if (p == yytext_end - 1) | |
1747 { | |
1748 int size = yytext_end - yytext; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
1749 yytext = (char *) xrealloc (yytext, 2 * size); |
28523 | 1750 yytext_end = yytext + 2 * size; |
1751 p = yytext + size - 1; | |
1752 } | |
1753 } | |
1754 | |
1755 UNGET (); | |
1756 *p = 0; | |
1757 | |
1758 for (k = keyword_table[hash % KEYWORD_TABLE_SIZE]; k; k = k->next) | |
1759 if (streq (k->name, yytext)) | |
1760 return k->tk; | |
1761 | |
1762 return IDENT; | |
1763 } | |
1764 | |
1765 case '/': | |
1766 /* C and C++ comments, '/' and '/='. */ | |
1767 switch (GET (c)) | |
1768 { | |
1769 case '*': | |
1770 while (GET (c)) | |
1771 { | |
1772 switch (c) | |
1773 { | |
1774 case '*': | |
1775 if (GET (c) == '/') | |
1776 goto comment_end; | |
1777 UNGET (); | |
1778 break; | |
1779 case '\\': | |
1780 GET (c); | |
1781 break; | |
1782 case '\n': | |
1783 INCREMENT_LINENO; | |
1784 break; | |
1785 } | |
1786 } | |
1787 comment_end:; | |
1788 break; | |
1789 | |
1790 case '=': | |
1791 return DIVASGN; | |
1792 | |
1793 case '/': | |
1794 while (GET (c) && c != '\n') | |
1795 ; | |
1796 INCREMENT_LINENO; | |
1797 break; | |
1798 | |
1799 default: | |
1800 UNGET (); | |
1801 return '/'; | |
1802 } | |
1803 break; | |
1804 | |
1805 case '+': | |
1806 if (GET (c) == '+') | |
1807 return INC; | |
1808 else if (c == '=') | |
1809 return ADDASGN; | |
1810 UNGET (); | |
1811 return '+'; | |
1812 | |
1813 case '-': | |
1814 switch (GET (c)) | |
1815 { | |
1816 case '-': | |
1817 return DEC; | |
1818 case '>': | |
1819 if (GET (c) == '*') | |
1820 return ARROWSTAR; | |
1821 UNGET (); | |
1822 return ARROW; | |
1823 case '=': | |
1824 return SUBASGN; | |
1825 } | |
1826 UNGET (); | |
1827 return '-'; | |
1828 | |
1829 case '*': | |
1830 if (GET (c) == '=') | |
1831 return MULASGN; | |
1832 UNGET (); | |
1833 return '*'; | |
1834 | |
1835 case '%': | |
1836 if (GET (c) == '=') | |
1837 return MODASGN; | |
1838 UNGET (); | |
1839 return '%'; | |
1840 | |
1841 case '|': | |
1842 if (GET (c) == '|') | |
1843 return LOR; | |
1844 else if (c == '=') | |
1845 return ORASGN; | |
1846 UNGET (); | |
1847 return '|'; | |
1848 | |
1849 case '&': | |
1850 if (GET (c) == '&') | |
1851 return LAND; | |
1852 else if (c == '=') | |
1853 return ANDASGN; | |
1854 UNGET (); | |
1855 return '&'; | |
1856 | |
1857 case '^': | |
1858 if (GET (c) == '=') | |
1859 return XORASGN; | |
1860 UNGET (); | |
1861 return '^'; | |
1862 | |
1863 case '.': | |
1864 if (GET (c) == '*') | |
1865 return POINTSTAR; | |
1866 else if (c == '.') | |
1867 { | |
1868 if (GET (c) != '.') | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
1869 yyerror ("invalid token '..' ('...' assumed)", NULL); |
28523 | 1870 UNGET (); |
1871 return ELLIPSIS; | |
1872 } | |
1873 else if (!DIGITP (c)) | |
1874 { | |
1875 UNGET (); | |
1876 return '.'; | |
1877 } | |
1878 goto mantissa; | |
1879 | |
1880 case ':': | |
1881 if (GET (c) == ':') | |
1882 return DCOLON; | |
1883 UNGET (); | |
1884 return ':'; | |
1885 | |
1886 case '=': | |
1887 if (GET (c) == '=') | |
1888 return EQ; | |
1889 UNGET (); | |
1890 return '='; | |
1891 | |
1892 case '!': | |
1893 if (GET (c) == '=') | |
1894 return NE; | |
1895 UNGET (); | |
1896 return '!'; | |
1897 | |
1898 case '<': | |
1899 switch (GET (c)) | |
1900 { | |
1901 case '=': | |
1902 return LE; | |
1903 case '<': | |
1904 if (GET (c) == '=') | |
1905 return LSHIFTASGN; | |
1906 UNGET (); | |
1907 return LSHIFT; | |
1908 } | |
1909 UNGET (); | |
1910 return '<'; | |
1911 | |
1912 case '>': | |
1913 switch (GET (c)) | |
1914 { | |
1915 case '=': | |
1916 return GE; | |
1917 case '>': | |
1918 if (GET (c) == '=') | |
1919 return RSHIFTASGN; | |
1920 UNGET (); | |
1921 return RSHIFT; | |
1922 } | |
1923 UNGET (); | |
1924 return '>'; | |
1925 | |
1926 case '#': | |
1927 c = process_pp_line (); | |
1928 if (c == 0) | |
1929 return YYEOF; | |
1930 break; | |
1931 | |
1932 case '(': case ')': case '[': case ']': case '{': case '}': | |
1933 case ';': case ',': case '?': case '~': | |
1934 return c; | |
1935 | |
1936 case '0': | |
1937 yyival = 0; | |
1938 | |
1939 if (GET (c) == 'x' || c == 'X') | |
1940 { | |
1941 while (GET (c)) | |
1942 { | |
1943 if (DIGITP (c)) | |
1944 yyival = yyival * 16 + c - '0'; | |
1945 else if (c >= 'a' && c <= 'f') | |
1946 yyival = yyival * 16 + c - 'a' + 10; | |
1947 else if (c >= 'A' && c <= 'F') | |
1948 yyival = yyival * 16 + c - 'A' + 10; | |
1949 else | |
1950 break; | |
1951 } | |
1952 | |
1953 goto int_suffixes; | |
1954 } | |
1955 else if (c == '.') | |
1956 goto mantissa; | |
1957 | |
1958 while (c >= '0' && c <= '7') | |
1959 { | |
1960 yyival = (yyival << 3) + c - '0'; | |
1961 GET (c); | |
1962 } | |
1963 | |
1964 int_suffixes: | |
1965 /* Integer suffixes. */ | |
1966 while (isalpha (c)) | |
1967 GET (c); | |
1968 UNGET (); | |
1969 return CINT; | |
1970 | |
1971 case '1': case '2': case '3': case '4': case '5': case '6': | |
1972 case '7': case '8': case '9': | |
1973 /* Integer or floating constant, part before '.'. */ | |
1974 yyival = c - '0'; | |
1975 | |
1976 while (GET (c) && DIGITP (c)) | |
1977 yyival = 10 * yyival + c - '0'; | |
1978 | |
1979 if (c != '.') | |
1980 goto int_suffixes; | |
1981 | |
1982 mantissa: | |
1983 /* Digits following '.'. */ | |
1984 while (DIGITP (c)) | |
1985 GET (c); | |
1986 | |
1987 /* Optional exponent. */ | |
1988 if (c == 'E' || c == 'e') | |
1989 { | |
1990 if (GET (c) == '-' || c == '+') | |
1991 GET (c); | |
1992 | |
1993 while (DIGITP (c)) | |
1994 GET (c); | |
1995 } | |
1996 | |
1997 /* Optional type suffixes. */ | |
1998 while (isalpha (c)) | |
1999 GET (c); | |
2000 UNGET (); | |
2001 return CFLOAT; | |
2002 | |
2003 default: | |
2004 break; | |
2005 } | |
2006 } | |
2007 } | |
2008 | |
2009 | |
35591
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2010 /* Actually local to matching_regexp. These variables must be in |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2011 global scope for the case that `static' get's defined away. */ |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2012 |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2013 static char *matching_regexp_buffer, *matching_regexp_end_buf; |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2014 |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2015 |
28523 | 2016 /* Value is the string from the start of the line to the current |
2017 position in the input buffer, or maybe a bit more if that string is | |
2018 shorter than min_regexp. */ | |
2019 | |
2020 char * | |
2021 matching_regexp () | |
2022 { | |
2023 char *p; | |
2024 char *s; | |
2025 char *t; | |
2026 | |
2027 if (!f_regexps) | |
2028 return NULL; | |
2029 | |
35591
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2030 if (matching_regexp_buffer == NULL) |
28523 | 2031 { |
35591
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2032 matching_regexp_buffer = (char *) xmalloc (max_regexp); |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2033 matching_regexp_end_buf = &matching_regexp_buffer[max_regexp] - 1; |
28523 | 2034 } |
2035 | |
2036 /* Scan back to previous newline of buffer start. */ | |
2037 for (p = in - 1; p > inbuffer && *p != '\n'; --p) | |
2038 ; | |
2039 | |
2040 if (*p == '\n') | |
2041 { | |
2042 while (in - p < min_regexp && p > inbuffer) | |
2043 { | |
2044 /* Line probably not significant enough */ | |
2045 for (--p; p >= inbuffer && *p != '\n'; --p) | |
2046 ; | |
2047 } | |
2048 if (*p == '\n') | |
2049 ++p; | |
2050 } | |
2051 | |
2052 /* Copy from end to make sure significant portions are included. | |
2053 This implies that in the browser a regular expressing of the form | |
2054 `^.*{regexp}' has to be used. */ | |
35591
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2055 for (s = matching_regexp_end_buf - 1, t = in; |
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2056 s > matching_regexp_buffer && t > p;) |
28523 | 2057 { |
2058 *--s = *--t; | |
2059 | |
41112
1ba618f8fdb5
(matching_regexp): Escape '\\'.
Gerd Moellmann <gerd@gnu.org>
parents:
39514
diff
changeset
|
2060 if (*s == '"' || *s == '\\') |
28523 | 2061 *--s = '\\'; |
2062 } | |
2063 | |
35591
92a64125d228
(matching_regexp_buffer, matching_regexp_end_buf):
Gerd Moellmann <gerd@gnu.org>
parents:
35459
diff
changeset
|
2064 *(matching_regexp_end_buf - 1) = '\0'; |
28523 | 2065 return xstrdup (s); |
2066 } | |
2067 | |
2068 | |
2069 /* Return a printable representation of token T. */ | |
2070 | |
2071 char * | |
2072 token_string (t) | |
2073 int t; | |
2074 { | |
2075 static char b[3]; | |
2076 | |
2077 switch (t) | |
2078 { | |
2079 case CSTRING: return "string constant"; | |
2080 case CCHAR: return "char constant"; | |
2081 case CINT: return "int constant"; | |
2082 case CFLOAT: return "floating constant"; | |
2083 case ELLIPSIS: return "..."; | |
2084 case LSHIFTASGN: return "<<="; | |
2085 case RSHIFTASGN: return ">>="; | |
2086 case ARROWSTAR: return "->*"; | |
2087 case IDENT: return "identifier"; | |
2088 case DIVASGN: return "/="; | |
2089 case INC: return "++"; | |
2090 case ADDASGN: return "+="; | |
2091 case DEC: return "--"; | |
2092 case ARROW: return "->"; | |
2093 case SUBASGN: return "-="; | |
2094 case MULASGN: return "*="; | |
2095 case MODASGN: return "%="; | |
2096 case LOR: return "||"; | |
2097 case ORASGN: return "|="; | |
2098 case LAND: return "&&"; | |
2099 case ANDASGN: return "&="; | |
2100 case XORASGN: return "^="; | |
2101 case POINTSTAR: return ".*"; | |
2102 case DCOLON: return "::"; | |
2103 case EQ: return "=="; | |
2104 case NE: return "!="; | |
2105 case LE: return "<="; | |
2106 case LSHIFT: return "<<"; | |
2107 case GE: return ">="; | |
2108 case RSHIFT: return ">>"; | |
2109 case ASM: return "asm"; | |
2110 case AUTO: return "auto"; | |
2111 case BREAK: return "break"; | |
2112 case CASE: return "case"; | |
2113 case CATCH: return "catch"; | |
2114 case CHAR: return "char"; | |
2115 case CLASS: return "class"; | |
2116 case CONST: return "const"; | |
2117 case CONTINUE: return "continue"; | |
2118 case DEFAULT: return "default"; | |
2119 case DELETE: return "delete"; | |
2120 case DO: return "do"; | |
2121 case DOUBLE: return "double"; | |
2122 case ELSE: return "else"; | |
2123 case ENUM: return "enum"; | |
2124 case EXTERN: return "extern"; | |
2125 case FLOAT: return "float"; | |
2126 case FOR: return "for"; | |
2127 case FRIEND: return "friend"; | |
2128 case GOTO: return "goto"; | |
2129 case IF: return "if"; | |
2130 case T_INLINE: return "inline"; | |
2131 case INT: return "int"; | |
2132 case LONG: return "long"; | |
2133 case NEW: return "new"; | |
2134 case OPERATOR: return "operator"; | |
2135 case PRIVATE: return "private"; | |
2136 case PROTECTED: return "protected"; | |
2137 case PUBLIC: return "public"; | |
2138 case REGISTER: return "register"; | |
2139 case RETURN: return "return"; | |
2140 case SHORT: return "short"; | |
2141 case SIGNED: return "signed"; | |
2142 case SIZEOF: return "sizeof"; | |
2143 case STATIC: return "static"; | |
2144 case STRUCT: return "struct"; | |
2145 case SWITCH: return "switch"; | |
2146 case TEMPLATE: return "template"; | |
2147 case THIS: return "this"; | |
2148 case THROW: return "throw"; | |
2149 case TRY: return "try"; | |
2150 case TYPEDEF: return "typedef"; | |
2151 case UNION: return "union"; | |
2152 case UNSIGNED: return "unsigned"; | |
2153 case VIRTUAL: return "virtual"; | |
2154 case VOID: return "void"; | |
2155 case VOLATILE: return "volatile"; | |
2156 case WHILE: return "while"; | |
29994
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2157 case MUTABLE: return "mutable"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2158 case BOOL: return "bool"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2159 case TRUE: return "true"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2160 case FALSE: return "false"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2161 case SIGNATURE: return "signature"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2162 case NAMESPACE: return "namespace"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2163 case EXPLICIT: return "explicit"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2164 case TYPENAME: return "typename"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2165 case CONST_CAST: return "const_cast"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2166 case DYNAMIC_CAST: return "dynamic_cast"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2167 case REINTERPRET_CAST: return "reinterpret_cast"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2168 case STATIC_CAST: return "static_cast"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2169 case TYPEID: return "typeid"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2170 case USING: return "using"; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2171 case WCHAR: return "wchar_t"; |
28523 | 2172 case YYEOF: return "EOF"; |
29994
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2173 |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2174 default: |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2175 if (t < 255) |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2176 { |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2177 b[0] = t; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2178 b[1] = '\0'; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2179 return b; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2180 } |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2181 else |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2182 return "???"; |
28523 | 2183 } |
2184 } | |
2185 | |
2186 | |
2187 /* Reinitialize the scanner for a new input file. */ | |
2188 | |
2189 void | |
2190 re_init_scanner () | |
2191 { | |
2192 in = inbuffer; | |
2193 yyline = 1; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2194 |
28523 | 2195 if (yytext == NULL) |
2196 { | |
2197 int size = 256; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
2198 yytext = (char *) xmalloc (size * sizeof *yytext); |
28523 | 2199 yytext_end = yytext + size; |
2200 } | |
2201 } | |
2202 | |
2203 | |
2204 /* Insert a keyword NAME with token value TK into the keyword hash | |
2205 table. */ | |
2206 | |
2207 void | |
2208 insert_keyword (name, tk) | |
2209 char *name; | |
2210 int tk; | |
2211 { | |
2212 char *s; | |
2213 unsigned h = 0; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
2214 struct kw *k = (struct kw *) xmalloc (sizeof *k); |
28523 | 2215 |
2216 for (s = name; *s; ++s) | |
2217 h = (h << 1) ^ *s; | |
2218 | |
2219 h %= KEYWORD_TABLE_SIZE; | |
2220 k->name = name; | |
2221 k->tk = tk; | |
2222 k->next = keyword_table[h]; | |
2223 keyword_table[h] = k; | |
2224 } | |
2225 | |
2226 | |
2227 /* Initialize the scanner for the first file. This sets up the | |
2228 character class vectors and fills the keyword hash table. */ | |
2229 | |
2230 void | |
2231 init_scanner () | |
2232 { | |
2233 int i; | |
2234 | |
2235 /* Allocate the input buffer */ | |
2236 inbuffer_size = READ_CHUNK_SIZE + 1; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
2237 inbuffer = in = (char *) xmalloc (inbuffer_size); |
28523 | 2238 yyline = 1; |
2239 | |
2240 /* Set up character class vectors. */ | |
2241 for (i = 0; i < sizeof is_ident; ++i) | |
2242 { | |
2243 if (i == '_' || isalnum (i)) | |
2244 is_ident[i] = 1; | |
2245 | |
2246 if (i >= '0' && i <= '9') | |
2247 is_digit[i] = 1; | |
2248 | |
2249 if (i == ' ' || i == '\t' || i == '\f' || i == '\v') | |
2250 is_white[i] = 1; | |
2251 } | |
2252 | |
2253 /* Fill keyword hash table. */ | |
2254 insert_keyword ("and", LAND); | |
2255 insert_keyword ("and_eq", ANDASGN); | |
2256 insert_keyword ("asm", ASM); | |
2257 insert_keyword ("auto", AUTO); | |
2258 insert_keyword ("bitand", '&'); | |
2259 insert_keyword ("bitor", '|'); | |
2260 insert_keyword ("bool", BOOL); | |
2261 insert_keyword ("break", BREAK); | |
2262 insert_keyword ("case", CASE); | |
2263 insert_keyword ("catch", CATCH); | |
2264 insert_keyword ("char", CHAR); | |
2265 insert_keyword ("class", CLASS); | |
2266 insert_keyword ("compl", '~'); | |
2267 insert_keyword ("const", CONST); | |
2268 insert_keyword ("const_cast", CONST_CAST); | |
2269 insert_keyword ("continue", CONTINUE); | |
2270 insert_keyword ("default", DEFAULT); | |
2271 insert_keyword ("delete", DELETE); | |
2272 insert_keyword ("do", DO); | |
2273 insert_keyword ("double", DOUBLE); | |
2274 insert_keyword ("dynamic_cast", DYNAMIC_CAST); | |
2275 insert_keyword ("else", ELSE); | |
2276 insert_keyword ("enum", ENUM); | |
2277 insert_keyword ("explicit", EXPLICIT); | |
2278 insert_keyword ("extern", EXTERN); | |
2279 insert_keyword ("false", FALSE); | |
2280 insert_keyword ("float", FLOAT); | |
2281 insert_keyword ("for", FOR); | |
2282 insert_keyword ("friend", FRIEND); | |
2283 insert_keyword ("goto", GOTO); | |
2284 insert_keyword ("if", IF); | |
2285 insert_keyword ("inline", T_INLINE); | |
2286 insert_keyword ("int", INT); | |
2287 insert_keyword ("long", LONG); | |
2288 insert_keyword ("mutable", MUTABLE); | |
2289 insert_keyword ("namespace", NAMESPACE); | |
2290 insert_keyword ("new", NEW); | |
2291 insert_keyword ("not", '!'); | |
2292 insert_keyword ("not_eq", NE); | |
2293 insert_keyword ("operator", OPERATOR); | |
2294 insert_keyword ("or", LOR); | |
2295 insert_keyword ("or_eq", ORASGN); | |
2296 insert_keyword ("private", PRIVATE); | |
2297 insert_keyword ("protected", PROTECTED); | |
2298 insert_keyword ("public", PUBLIC); | |
2299 insert_keyword ("register", REGISTER); | |
2300 insert_keyword ("reinterpret_cast", REINTERPRET_CAST); | |
2301 insert_keyword ("return", RETURN); | |
2302 insert_keyword ("short", SHORT); | |
2303 insert_keyword ("signed", SIGNED); | |
2304 insert_keyword ("sizeof", SIZEOF); | |
2305 insert_keyword ("static", STATIC); | |
2306 insert_keyword ("static_cast", STATIC_CAST); | |
2307 insert_keyword ("struct", STRUCT); | |
2308 insert_keyword ("switch", SWITCH); | |
2309 insert_keyword ("template", TEMPLATE); | |
2310 insert_keyword ("this", THIS); | |
2311 insert_keyword ("throw", THROW); | |
2312 insert_keyword ("true", TRUE); | |
2313 insert_keyword ("try", TRY); | |
2314 insert_keyword ("typedef", TYPEDEF); | |
2315 insert_keyword ("typeid", TYPEID); | |
2316 insert_keyword ("typename", TYPENAME); | |
2317 insert_keyword ("union", UNION); | |
2318 insert_keyword ("unsigned", UNSIGNED); | |
2319 insert_keyword ("using", USING); | |
2320 insert_keyword ("virtual", VIRTUAL); | |
2321 insert_keyword ("void", VOID); | |
2322 insert_keyword ("volatile", VOLATILE); | |
2323 insert_keyword ("wchar_t", WCHAR); | |
2324 insert_keyword ("while", WHILE); | |
2325 insert_keyword ("xor", '^'); | |
2326 insert_keyword ("xor_eq", XORASGN); | |
2327 } | |
2328 | |
2329 | |
2330 | |
2331 /*********************************************************************** | |
2332 Parser | |
2333 ***********************************************************************/ | |
2334 | |
2335 /* Match the current lookahead token and set it to the next token. */ | |
2336 | |
2337 #define MATCH() (tk = yylex ()) | |
2338 | |
2339 /* Return the lookahead token. If current lookahead token is cleared, | |
2340 read a new token. */ | |
2341 | |
2342 #define LA1 (tk == -1 ? (tk = yylex ()) : tk) | |
2343 | |
2344 /* Is the current lookahead equal to the token T? */ | |
2345 | |
2346 #define LOOKING_AT(T) (tk == (T)) | |
2347 | |
2348 /* Is the current lookahead one of T1 or T2? */ | |
2349 | |
2350 #define LOOKING_AT2(T1, T2) (tk == (T1) || tk == (T2)) | |
2351 | |
2352 /* Is the current lookahead one of T1, T2 or T3? */ | |
2353 | |
2354 #define LOOKING_AT3(T1, T2, T3) (tk == (T1) || tk == (T2) || tk == (T3)) | |
2355 | |
2356 /* Is the current lookahead one of T1...T4? */ | |
2357 | |
2358 #define LOOKING_AT4(T1, T2, T3, T4) \ | |
2359 (tk == (T1) || tk == (T2) || tk == (T3) || tk == (T4)) | |
2360 | |
2361 /* Match token T if current lookahead is T. */ | |
2362 | |
2363 #define MATCH_IF(T) if (LOOKING_AT (T)) MATCH (); else ((void) 0) | |
2364 | |
2365 /* Skip to matching token if current token is T. */ | |
2366 | |
2367 #define SKIP_MATCHING_IF(T) \ | |
2368 if (LOOKING_AT (T)) skip_matching (); else ((void) 0) | |
2369 | |
2370 | |
2371 /* Skip forward until a given token TOKEN or YYEOF is seen and return | |
2372 the current lookahead token after skipping. */ | |
2373 | |
2374 int | |
2375 skip_to (token) | |
2376 int token; | |
2377 { | |
2378 while (!LOOKING_AT2 (YYEOF, token)) | |
2379 MATCH (); | |
2380 return tk; | |
2381 } | |
2382 | |
2383 /* Skip over pairs of tokens (parentheses, square brackets, | |
2384 angle brackets, curly brackets) matching the current lookahead. */ | |
2385 | |
2386 void | |
2387 skip_matching () | |
2388 { | |
2389 int open, close, n; | |
2390 | |
2391 switch (open = LA1) | |
2392 { | |
2393 case '{': | |
2394 close = '}'; | |
2395 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2396 |
28523 | 2397 case '(': |
2398 close = ')'; | |
2399 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2400 |
28523 | 2401 case '<': |
2402 close = '>'; | |
2403 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2404 |
28523 | 2405 case '[': |
2406 close = ']'; | |
2407 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2408 |
28523 | 2409 default: |
2410 abort (); | |
2411 } | |
2412 | |
2413 for (n = 0;;) | |
2414 { | |
2415 if (LOOKING_AT (open)) | |
2416 ++n; | |
2417 else if (LOOKING_AT (close)) | |
2418 --n; | |
2419 else if (LOOKING_AT (YYEOF)) | |
2420 break; | |
2421 | |
2422 MATCH (); | |
2423 | |
2424 if (n == 0) | |
2425 break; | |
2426 } | |
2427 } | |
2428 | |
44819
9ce753124d1b
(skip_initializer): Return void.
Pavel Janík <Pavel@Janik.cz>
parents:
44719
diff
changeset
|
2429 void |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2430 skip_initializer () |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2431 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2432 for (;;) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2433 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2434 switch (LA1) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2435 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2436 case ';': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2437 case ',': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2438 case YYEOF: |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2439 return; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2440 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2441 case '{': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2442 case '[': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2443 case '(': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2444 skip_matching (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2445 break; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2446 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2447 default: |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2448 MATCH (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2449 break; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2450 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2451 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
2452 } |
28523 | 2453 |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2454 /* Build qualified namespace alias (A::B::c) and return it. */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2455 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2456 struct link * |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2457 match_qualified_namespace_alias () |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2458 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2459 struct link *head = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2460 struct link *cur = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2461 struct link *tmp = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2462 |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2463 for (;;) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2464 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2465 MATCH (); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2466 switch (LA1) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2467 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2468 case IDENT: |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2469 tmp = (struct link *) xmalloc (sizeof *cur); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2470 tmp->sym = find_namespace (yytext, cur); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2471 tmp->next = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2472 if (head) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2473 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2474 cur = cur->next = tmp; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2475 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2476 else |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2477 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2478 head = cur = tmp; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2479 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2480 break; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2481 case DCOLON: |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2482 /* Just skip */ |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2483 break; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2484 default: |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2485 return head; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2486 break; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2487 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2488 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2489 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
2490 |
28523 | 2491 /* Re-initialize the parser by resetting the lookahead token. */ |
2492 | |
2493 void | |
2494 re_init_parser () | |
2495 { | |
2496 tk = -1; | |
2497 } | |
2498 | |
2499 | |
2500 /* Parse a parameter list, including the const-specifier, | |
2501 pure-specifier, and throw-list that may follow a parameter list. | |
2502 Return in FLAGS what was seen following the parameter list. | |
2503 Returns a hash code for the parameter types. This value is used to | |
2504 distinguish between overloaded functions. */ | |
2505 | |
2506 unsigned | |
2507 parm_list (flags) | |
2508 int *flags; | |
2509 { | |
2510 unsigned hash = 0; | |
2511 int type_seen = 0; | |
2512 | |
2513 while (!LOOKING_AT2 (YYEOF, ')')) | |
2514 { | |
2515 switch (LA1) | |
2516 { | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44819
diff
changeset
|
2517 /* Skip over grouping parens or parameter lists in parameter |
28523 | 2518 declarations. */ |
2519 case '(': | |
2520 skip_matching (); | |
2521 break; | |
2522 | |
2523 /* Next parameter. */ | |
2524 case ',': | |
2525 MATCH (); | |
2526 type_seen = 0; | |
2527 break; | |
2528 | |
2529 /* Ignore the scope part of types, if any. This is because | |
2530 some types need scopes when defined outside of a class body, | |
2531 and don't need them inside the class body. This means that | |
2532 we have to look for the last IDENT in a sequence of | |
2533 IDENT::IDENT::... */ | |
2534 case IDENT: | |
2535 if (!type_seen) | |
2536 { | |
29994
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2537 char *last_id; |
28523 | 2538 unsigned ident_type_hash = 0; |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2539 |
29994
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2540 parse_qualified_param_ident_or_type (&last_id); |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2541 if (last_id) |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2542 { |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2543 /* LAST_ID null means something like `X::*'. */ |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2544 for (; *last_id; ++last_id) |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2545 ident_type_hash = (ident_type_hash << 1) ^ *last_id; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2546 hash = (hash << 1) ^ ident_type_hash; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2547 type_seen = 1; |
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
2548 } |
28523 | 2549 } |
2550 else | |
2551 MATCH (); | |
2552 break; | |
2553 | |
2554 case VOID: | |
2555 /* This distinction is made to make `func (void)' equivalent | |
2556 to `func ()'. */ | |
2557 type_seen = 1; | |
2558 MATCH (); | |
2559 if (!LOOKING_AT (')')) | |
2560 hash = (hash << 1) ^ VOID; | |
2561 break; | |
2562 | |
2563 case BOOL: case CHAR: case CLASS: case CONST: | |
2564 case DOUBLE: case ENUM: case FLOAT: case INT: | |
2565 case LONG: case SHORT: case SIGNED: case STRUCT: | |
2566 case UNION: case UNSIGNED: case VOLATILE: case WCHAR: | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2567 case ELLIPSIS: |
28523 | 2568 type_seen = 1; |
2569 hash = (hash << 1) ^ LA1; | |
2570 MATCH (); | |
2571 break; | |
2572 | |
2573 case '*': case '&': case '[': case ']': | |
2574 hash = (hash << 1) ^ LA1; | |
2575 MATCH (); | |
2576 break; | |
2577 | |
2578 default: | |
2579 MATCH (); | |
2580 break; | |
2581 } | |
2582 } | |
2583 | |
2584 if (LOOKING_AT (')')) | |
2585 { | |
2586 MATCH (); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2587 |
28523 | 2588 if (LOOKING_AT (CONST)) |
2589 { | |
2590 /* We can overload the same function on `const' */ | |
2591 hash = (hash << 1) ^ CONST; | |
2592 SET_FLAG (*flags, F_CONST); | |
2593 MATCH (); | |
2594 } | |
2595 | |
2596 if (LOOKING_AT (THROW)) | |
2597 { | |
2598 MATCH (); | |
2599 SKIP_MATCHING_IF ('('); | |
2600 SET_FLAG (*flags, F_THROW); | |
2601 } | |
2602 | |
2603 if (LOOKING_AT ('=')) | |
2604 { | |
2605 MATCH (); | |
2606 if (LOOKING_AT (CINT) && yyival == 0) | |
2607 { | |
2608 MATCH (); | |
2609 SET_FLAG (*flags, F_PURE); | |
2610 } | |
2611 } | |
2612 } | |
2613 | |
2614 return hash; | |
2615 } | |
2616 | |
2617 | |
2618 /* Print position info to stdout. */ | |
2619 | |
2620 void | |
2621 print_info () | |
2622 { | |
2623 if (info_position >= 0 && BUFFER_POS () <= info_position) | |
2624 if (info_cls) | |
2625 printf ("(\"%s\" \"%s\" \"%s\" %d)\n", | |
2626 info_cls->name, sym_scope (info_cls), | |
2627 info_member->name, info_where); | |
2628 } | |
2629 | |
2630 | |
2631 /* Parse a member declaration within the class body of CLS. VIS is | |
2632 the access specifier for the member (private, protected, | |
2633 public). */ | |
2634 | |
2635 void | |
2636 member (cls, vis) | |
2637 struct sym *cls; | |
2638 int vis; | |
2639 { | |
2640 char *id = NULL; | |
2641 int sc = SC_MEMBER; | |
2642 char *regexp = NULL; | |
2643 int pos; | |
2644 int is_constructor; | |
2645 int anonymous = 0; | |
2646 int flags = 0; | |
2647 int class_tag; | |
2648 int type_seen = 0; | |
2649 int paren_seen = 0; | |
2650 unsigned hash = 0; | |
2651 int tilde = 0; | |
2652 | |
2653 while (!LOOKING_AT4 (';', '{', '}', YYEOF)) | |
2654 { | |
2655 switch (LA1) | |
2656 { | |
2657 default: | |
2658 MATCH (); | |
2659 break; | |
2660 | |
2661 /* A function or class may follow. */ | |
2662 case TEMPLATE: | |
2663 MATCH(); | |
2664 SET_FLAG (flags, F_TEMPLATE); | |
2665 /* Skip over template argument list */ | |
2666 SKIP_MATCHING_IF ('<'); | |
2667 break; | |
2668 | |
2669 case EXPLICIT: | |
2670 SET_FLAG (flags, F_EXPLICIT); | |
2671 goto typeseen; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2672 |
28523 | 2673 case MUTABLE: |
2674 SET_FLAG (flags, F_MUTABLE); | |
2675 goto typeseen; | |
2676 | |
2677 case T_INLINE: | |
2678 SET_FLAG (flags, F_INLINE); | |
2679 goto typeseen; | |
2680 | |
2681 case VIRTUAL: | |
2682 SET_FLAG (flags, F_VIRTUAL); | |
2683 goto typeseen; | |
2684 | |
2685 case '[': | |
2686 skip_matching (); | |
2687 break; | |
2688 | |
2689 case ENUM: | |
2690 sc = SC_TYPE; | |
2691 goto typeseen; | |
2692 | |
2693 case TYPEDEF: | |
2694 sc = SC_TYPE; | |
2695 goto typeseen; | |
2696 | |
2697 case FRIEND: | |
2698 sc = SC_FRIEND; | |
2699 goto typeseen; | |
2700 | |
2701 case STATIC: | |
2702 sc = SC_STATIC; | |
2703 goto typeseen; | |
2704 | |
2705 case '~': | |
2706 tilde = 1; | |
2707 MATCH (); | |
2708 break; | |
2709 | |
2710 case IDENT: | |
35459 | 2711 /* Remember IDENTS seen so far. Among these will be the member |
2712 name. */ | |
2713 id = (char *) xrealloc (id, strlen (yytext) + 2); | |
28523 | 2714 if (tilde) |
2715 { | |
2716 *id = '~'; | |
2717 strcpy (id + 1, yytext); | |
2718 } | |
2719 else | |
2720 strcpy (id, yytext); | |
2721 MATCH (); | |
2722 break; | |
2723 | |
2724 case OPERATOR: | |
35459 | 2725 { |
2726 char *s = operator_name (&sc); | |
2727 id = (char *) xrealloc (id, strlen (s) + 1); | |
2728 strcpy (id, s); | |
2729 } | |
28523 | 2730 break; |
2731 | |
2732 case '(': | |
2733 /* Most probably the beginning of a parameter list. */ | |
2734 MATCH (); | |
2735 paren_seen = 1; | |
2736 | |
2737 if (id && cls) | |
2738 { | |
2739 if (!(is_constructor = streq (id, cls->name))) | |
2740 regexp = matching_regexp (); | |
2741 } | |
2742 else | |
2743 is_constructor = 0; | |
2744 | |
2745 pos = BUFFER_POS (); | |
2746 hash = parm_list (&flags); | |
2747 | |
2748 if (is_constructor) | |
2749 regexp = matching_regexp (); | |
2750 | |
2751 if (id && cls != NULL) | |
2752 add_member_decl (cls, id, regexp, pos, hash, 0, sc, vis, flags); | |
2753 | |
2754 while (!LOOKING_AT3 (';', '{', YYEOF)) | |
2755 MATCH (); | |
2756 | |
2757 if (LOOKING_AT ('{') && id && cls) | |
2758 add_member_defn (cls, id, regexp, pos, hash, 0, sc, flags); | |
35459 | 2759 |
2760 xfree (id); | |
28523 | 2761 id = NULL; |
2762 sc = SC_MEMBER; | |
2763 break; | |
2764 | |
2765 case STRUCT: case UNION: case CLASS: | |
2766 /* Nested class */ | |
2767 class_tag = LA1; | |
2768 type_seen = 1; | |
2769 MATCH (); | |
2770 anonymous = 1; | |
2771 | |
2772 /* More than one ident here to allow for MS-DOS specialties | |
2773 like `_export class' etc. The last IDENT seen counts | |
2774 as the class name. */ | |
2775 while (!LOOKING_AT4 (YYEOF, ';', ':', '{')) | |
2776 { | |
2777 if (LOOKING_AT (IDENT)) | |
2778 anonymous = 0; | |
2779 MATCH (); | |
2780 } | |
2781 | |
2782 if (LOOKING_AT2 (':', '{')) | |
2783 class_definition (anonymous ? NULL : cls, class_tag, flags, 1); | |
2784 else | |
2785 skip_to (';'); | |
2786 break; | |
2787 | |
2788 case INT: case CHAR: case LONG: case UNSIGNED: | |
2789 case SIGNED: case CONST: case DOUBLE: case VOID: | |
2790 case SHORT: case VOLATILE: case BOOL: case WCHAR: | |
2791 case TYPENAME: | |
2792 typeseen: | |
2793 type_seen = 1; | |
2794 MATCH (); | |
2795 break; | |
2796 } | |
2797 } | |
2798 | |
2799 if (LOOKING_AT (';')) | |
2800 { | |
2801 /* The end of a member variable, a friend declaration or an access | |
2802 declaration. We don't want to add friend classes as members. */ | |
2803 if (id && sc != SC_FRIEND && cls) | |
2804 { | |
2805 regexp = matching_regexp (); | |
2806 pos = BUFFER_POS (); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2807 |
28523 | 2808 if (cls != NULL) |
2809 { | |
2810 if (type_seen || !paren_seen) | |
2811 add_member_decl (cls, id, regexp, pos, 0, 1, sc, vis, 0); | |
2812 else | |
2813 add_member_decl (cls, id, regexp, pos, hash, 0, sc, vis, 0); | |
2814 } | |
2815 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2816 |
28523 | 2817 MATCH (); |
2818 print_info (); | |
2819 } | |
2820 else if (LOOKING_AT ('{')) | |
2821 { | |
2822 /* A named enum. */ | |
2823 if (sc == SC_TYPE && id && cls) | |
2824 { | |
2825 regexp = matching_regexp (); | |
2826 pos = BUFFER_POS (); | |
2827 | |
2828 if (cls != NULL) | |
2829 { | |
2830 add_member_decl (cls, id, regexp, pos, 0, 1, sc, vis, 0); | |
2831 add_member_defn (cls, id, regexp, pos, 0, 1, sc, 0); | |
2832 } | |
2833 } | |
2834 | |
2835 skip_matching (); | |
2836 print_info (); | |
2837 } | |
35459 | 2838 |
2839 xfree (id); | |
28523 | 2840 } |
2841 | |
2842 | |
2843 /* Parse the body of class CLS. TAG is the tag of the class (struct, | |
2844 union, class). */ | |
2845 | |
2846 void | |
2847 class_body (cls, tag) | |
2848 struct sym *cls; | |
2849 int tag; | |
2850 { | |
2851 int vis = tag == CLASS ? PRIVATE : PUBLIC; | |
2852 int temp; | |
2853 | |
2854 while (!LOOKING_AT2 (YYEOF, '}')) | |
2855 { | |
2856 switch (LA1) | |
2857 { | |
2858 case PRIVATE: case PROTECTED: case PUBLIC: | |
2859 temp = LA1; | |
2860 MATCH (); | |
2861 | |
2862 if (LOOKING_AT (':')) | |
2863 { | |
2864 vis = temp; | |
2865 MATCH (); | |
2866 } | |
2867 else | |
2868 { | |
2869 /* Probably conditional compilation for inheritance list. | |
2870 We don't known whether there comes more of this. | |
2871 This is only a crude fix that works most of the time. */ | |
2872 do | |
2873 { | |
2874 MATCH (); | |
2875 } | |
2876 while (LOOKING_AT2 (IDENT, ',') | |
2877 || LOOKING_AT3 (PUBLIC, PROTECTED, PRIVATE)); | |
2878 } | |
2879 break; | |
2880 | |
2881 case TYPENAME: | |
2882 case USING: | |
2883 skip_to (';'); | |
2884 break; | |
2885 | |
2886 /* Try to synchronize */ | |
2887 case CHAR: case CLASS: case CONST: | |
2888 case DOUBLE: case ENUM: case FLOAT: case INT: | |
2889 case LONG: case SHORT: case SIGNED: case STRUCT: | |
2890 case UNION: case UNSIGNED: case VOID: case VOLATILE: | |
2891 case TYPEDEF: case STATIC: case T_INLINE: case FRIEND: | |
2892 case VIRTUAL: case TEMPLATE: case IDENT: case '~': | |
2893 case BOOL: case WCHAR: case EXPLICIT: case MUTABLE: | |
2894 member (cls, vis); | |
2895 break; | |
2896 | |
2897 default: | |
2898 MATCH (); | |
2899 break; | |
2900 } | |
2901 } | |
2902 } | |
2903 | |
2904 | |
2905 /* Parse a qualified identifier. Current lookahead is IDENT. A | |
2906 qualified ident has the form `X<..>::Y<...>::T<...>. Returns a | |
2907 symbol for that class. */ | |
2908 | |
2909 struct sym * | |
2910 parse_classname () | |
2911 { | |
2912 struct sym *last_class = NULL; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2913 |
28523 | 2914 while (LOOKING_AT (IDENT)) |
2915 { | |
2916 last_class = add_sym (yytext, last_class); | |
2917 MATCH (); | |
2918 | |
2919 if (LOOKING_AT ('<')) | |
2920 { | |
2921 skip_matching (); | |
2922 SET_FLAG (last_class->flags, F_TEMPLATE); | |
2923 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2924 |
28523 | 2925 if (!LOOKING_AT (DCOLON)) |
2926 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2927 |
28523 | 2928 MATCH (); |
2929 } | |
2930 | |
2931 return last_class; | |
2932 } | |
2933 | |
2934 | |
2935 /* Parse an operator name. Add the `static' flag to *SC if an | |
2936 implicitly static operator has been parsed. Value is a pointer to | |
2937 a static buffer holding the constructed operator name string. */ | |
2938 | |
2939 char * | |
2940 operator_name (sc) | |
2941 int *sc; | |
2942 { | |
2943 static int id_size = 0; | |
2944 static char *id = NULL; | |
2945 char *s; | |
2946 int len; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2947 |
28523 | 2948 MATCH (); |
2949 | |
2950 if (LOOKING_AT2 (NEW, DELETE)) | |
2951 { | |
2952 /* `new' and `delete' are implicitly static. */ | |
2953 if (*sc != SC_FRIEND) | |
2954 *sc = SC_STATIC; | |
2955 | |
2956 s = token_string (LA1); | |
2957 MATCH (); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2958 |
28523 | 2959 len = strlen (s) + 10; |
2960 if (len > id_size) | |
2961 { | |
2962 int new_size = max (len, 2 * id_size); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
2963 id = (char *) xrealloc (id, new_size); |
28523 | 2964 id_size = new_size; |
2965 } | |
2966 strcpy (id, s); | |
2967 | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2968 /* Vector new or delete? */ |
28523 | 2969 if (LOOKING_AT ('[')) |
2970 { | |
2971 strcat (id, "["); | |
2972 MATCH (); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
2973 |
28523 | 2974 if (LOOKING_AT (']')) |
2975 { | |
2976 strcat (id, "]"); | |
2977 MATCH (); | |
2978 } | |
2979 } | |
2980 } | |
2981 else | |
2982 { | |
2983 int tokens_matched = 0; | |
2984 | |
2985 len = 20; | |
2986 if (len > id_size) | |
2987 { | |
2988 int new_size = max (len, 2 * id_size); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
2989 id = (char *) xrealloc (id, new_size); |
28523 | 2990 id_size = new_size; |
2991 } | |
2992 strcpy (id, "operator"); | |
2993 | |
2994 /* Beware access declarations of the form "X::f;" Beware of | |
2995 `operator () ()'. Yet another difficulty is found in | |
2996 GCC 2.95's STL: `operator == __STL_NULL_TMPL_ARGS (...'. */ | |
2997 while (!(LOOKING_AT ('(') && tokens_matched) | |
2998 && !LOOKING_AT2 (';', YYEOF)) | |
2999 { | |
3000 s = token_string (LA1); | |
3001 len += strlen (s) + 2; | |
3002 if (len > id_size) | |
3003 { | |
3004 int new_size = max (len, 2 * id_size); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3005 id = (char *) xrealloc (id, new_size); |
28523 | 3006 id_size = new_size; |
3007 } | |
3008 | |
3009 if (*s != ')' && *s != ']') | |
3010 strcat (id, " "); | |
3011 strcat (id, s); | |
3012 MATCH (); | |
3013 | |
3014 /* If this is a simple operator like `+', stop now. */ | |
34610
beea10bab07e
(operator_name): Cast argument of isalpha to
Gerd Moellmann <gerd@gnu.org>
parents:
34522
diff
changeset
|
3015 if (!isalpha ((unsigned char) *s) && *s != '(' && *s != '[') |
28523 | 3016 break; |
3017 | |
3018 ++tokens_matched; | |
3019 } | |
3020 } | |
3021 | |
3022 return id; | |
3023 } | |
3024 | |
3025 | |
3026 /* This one consumes the last IDENT of a qualified member name like | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3027 `X::Y::z'. This IDENT is returned in LAST_ID. Value is the |
28523 | 3028 symbol structure for the ident. */ |
3029 | |
3030 struct sym * | |
3031 parse_qualified_ident_or_type (last_id) | |
3032 char **last_id; | |
3033 { | |
3034 struct sym *cls = NULL; | |
36478
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3035 char *id = NULL; |
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3036 size_t id_size = 0; |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3037 int enter = 0; |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3038 |
28523 | 3039 while (LOOKING_AT (IDENT)) |
3040 { | |
3041 int len = strlen (yytext) + 1; | |
3042 if (len > id_size) | |
3043 { | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3044 id = (char *) xrealloc (id, len); |
28523 | 3045 id_size = len; |
3046 } | |
3047 strcpy (id, yytext); | |
3048 *last_id = id; | |
3049 MATCH (); | |
3050 | |
3051 SKIP_MATCHING_IF ('<'); | |
3052 | |
3053 if (LOOKING_AT (DCOLON)) | |
3054 { | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3055 struct sym *pcn = NULL; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3056 struct link *pna = check_namespace_alias (id); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3057 if (pna) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3058 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3059 do |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3060 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3061 enter_namespace (pna->sym->name); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3062 enter++; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3063 pna = pna->next; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3064 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3065 while (pna); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3066 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3067 else if ((pcn = check_namespace (id, current_namespace))) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3068 { |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3069 enter_namespace (pcn->name); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3070 enter++; |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3071 } |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3072 else |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3073 cls = add_sym (id, cls); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3074 |
28523 | 3075 *last_id = NULL; |
36478
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3076 xfree (id); |
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3077 id = NULL; |
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3078 id_size = 0; |
28523 | 3079 MATCH (); |
3080 } | |
3081 else | |
3082 break; | |
3083 } | |
3084 | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3085 while (enter--) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3086 leave_namespace(); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3087 |
28523 | 3088 return cls; |
3089 } | |
3090 | |
3091 | |
3092 /* This one consumes the last IDENT of a qualified member name like | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3093 `X::Y::z'. This IDENT is returned in LAST_ID. Value is the |
28523 | 3094 symbol structure for the ident. */ |
3095 | |
3096 void | |
3097 parse_qualified_param_ident_or_type (last_id) | |
3098 char **last_id; | |
3099 { | |
3100 struct sym *cls = NULL; | |
3101 static char *id = NULL; | |
3102 static int id_size = 0; | |
29994
b5da88c41066
(token_string): Add missing tokens.
Gerd Moellmann <gerd@gnu.org>
parents:
29889
diff
changeset
|
3103 |
28523 | 3104 while (LOOKING_AT (IDENT)) |
3105 { | |
3106 int len = strlen (yytext) + 1; | |
3107 if (len > id_size) | |
3108 { | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3109 id = (char *) xrealloc (id, len); |
28523 | 3110 id_size = len; |
3111 } | |
3112 strcpy (id, yytext); | |
3113 *last_id = id; | |
3114 MATCH (); | |
3115 | |
3116 SKIP_MATCHING_IF ('<'); | |
3117 | |
3118 if (LOOKING_AT (DCOLON)) | |
3119 { | |
3120 cls = add_sym (id, cls); | |
3121 *last_id = NULL; | |
3122 MATCH (); | |
3123 } | |
3124 else | |
3125 break; | |
3126 } | |
3127 } | |
3128 | |
3129 | |
3130 /* Parse a class definition. | |
3131 | |
3132 CONTAINING is the class containing the class being parsed or null. | |
3133 This may also be null if NESTED != 0 if the containing class is | |
3134 anonymous. TAG is the tag of the class (struct, union, class). | |
3135 NESTED is non-zero if we are parsing a nested class. | |
3136 | |
3137 Current lookahead is the class name. */ | |
3138 | |
3139 void | |
3140 class_definition (containing, tag, flags, nested) | |
3141 struct sym *containing; | |
3142 int tag; | |
3143 int flags; | |
3144 int nested; | |
3145 { | |
3146 struct sym *current; | |
3147 struct sym *base_class; | |
3148 | |
3149 /* Set CURRENT to null if no entry has to be made for the class | |
3150 parsed. This is the case for certain command line flag | |
3151 settings. */ | |
3152 if ((tag != CLASS && !f_structs) || (nested && !f_nested_classes)) | |
3153 current = NULL; | |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44819
diff
changeset
|
3154 else |
28523 | 3155 { |
3156 current = add_sym (yytext, containing); | |
3157 current->pos = BUFFER_POS (); | |
3158 current->regexp = matching_regexp (); | |
3159 current->filename = filename; | |
3160 current->flags = flags; | |
3161 } | |
3162 | |
3163 /* If at ':', base class list follows. */ | |
3164 if (LOOKING_AT (':')) | |
3165 { | |
3166 int done = 0; | |
3167 MATCH (); | |
3168 | |
3169 while (!done) | |
3170 { | |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
3171 switch (LA1) |
28523 | 3172 { |
49600
23a1cea22d13
Trailing whitespace deleted.
Juanma Barranquero <lekktu@gmail.com>
parents:
44819
diff
changeset
|
3173 case VIRTUAL: case PUBLIC: case PROTECTED: case PRIVATE: |
28523 | 3174 MATCH (); |
3175 break; | |
3176 | |
3177 case IDENT: | |
3178 base_class = parse_classname (); | |
3179 if (base_class && current && base_class != current) | |
3180 add_link (base_class, current); | |
3181 break; | |
3182 | |
3183 /* The `,' between base classes or the end of the base | |
3184 class list. Add the previously found base class. | |
3185 It's done this way to skip over sequences of | |
3186 `A::B::C' until we reach the end. | |
3187 | |
3188 FIXME: it is now possible to handle `class X : public B::X' | |
3189 because we have enough information. */ | |
3190 case ',': | |
3191 MATCH (); | |
3192 break; | |
3193 | |
3194 default: | |
3195 /* A syntax error, possibly due to preprocessor constructs | |
3196 like | |
3197 | |
3198 #ifdef SOMETHING | |
3199 class A : public B | |
3200 #else | |
3201 class A : private B. | |
3202 | |
3203 MATCH until we see something like `;' or `{'. */ | |
3204 while (!LOOKING_AT3 (';', YYEOF, '{')) | |
3205 MATCH (); | |
3206 done = 1; | |
3207 | |
3208 case '{': | |
3209 done = 1; | |
3210 break; | |
3211 } | |
3212 } | |
3213 } | |
3214 | |
3215 /* Parse the class body if there is one. */ | |
3216 if (LOOKING_AT ('{')) | |
3217 { | |
3218 if (tag != CLASS && !f_structs) | |
3219 skip_matching (); | |
3220 else | |
3221 { | |
3222 MATCH (); | |
3223 class_body (current, tag); | |
3224 | |
3225 if (LOOKING_AT ('}')) | |
3226 { | |
3227 MATCH (); | |
3228 if (LOOKING_AT (';') && !nested) | |
3229 MATCH (); | |
3230 } | |
3231 } | |
3232 } | |
3233 } | |
3234 | |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3235 /* Add to class *CLS information for the declaration of variable or |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3236 type *ID. If *CLS is null, this means a global declaration. SC is |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3237 the storage class of *ID. FLAGS is a bit set giving additional |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3238 information about the member (see the F_* defines). */ |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3239 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3240 void |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3241 add_declarator (cls, id, flags, sc) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3242 struct sym **cls; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3243 char **id; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3244 int flags, sc; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3245 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3246 if (LOOKING_AT2 (';', ',')) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3247 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3248 /* The end of a member variable or of an access declaration |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3249 `X::f'. To distinguish between them we have to know whether |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3250 type information has been seen. */ |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3251 if (*id) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3252 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3253 char *regexp = matching_regexp (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3254 int pos = BUFFER_POS (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3255 |
44719
dfc7601deedf
(add_declarator): Test *CLS instead of CLS.
Gerd Moellmann <gerd@gnu.org>
parents:
44254
diff
changeset
|
3256 if (*cls) |
44254
2bc6f0ac1394
(add_declarator): Fix the first call to add_member_defn.
Eli Zaretskii <eliz@gnu.org>
parents:
44220
diff
changeset
|
3257 add_member_defn (*cls, *id, regexp, pos, 0, 1, SC_UNKNOWN, flags); |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3258 else |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3259 add_global_defn (*id, regexp, pos, 0, 1, sc, flags); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3260 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3261 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3262 MATCH (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3263 print_info (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3264 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3265 else if (LOOKING_AT ('{')) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3266 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3267 if (sc == SC_TYPE && *id) |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3268 { |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3269 /* A named enumeration. */ |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3270 char *regexp = matching_regexp (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3271 int pos = BUFFER_POS (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3272 add_global_defn (*id, regexp, pos, 0, 1, sc, flags); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3273 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3274 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3275 skip_matching (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3276 print_info (); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3277 } |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3278 |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3279 xfree (*id); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3280 *id = NULL; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3281 *cls = NULL; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3282 } |
28523 | 3283 |
3284 /* Parse a declaration. */ | |
3285 | |
3286 void | |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
3287 declaration (flags) |
28523 | 3288 int flags; |
3289 { | |
3290 char *id = NULL; | |
3291 struct sym *cls = NULL; | |
3292 char *regexp = NULL; | |
3293 int pos = 0; | |
3294 unsigned hash = 0; | |
3295 int is_constructor; | |
3296 int sc = 0; | |
3297 | |
3298 while (!LOOKING_AT3 (';', '{', YYEOF)) | |
3299 { | |
3300 switch (LA1) | |
3301 { | |
3302 default: | |
3303 MATCH (); | |
3304 break; | |
3305 | |
3306 case '[': | |
3307 skip_matching (); | |
3308 break; | |
3309 | |
3310 case ENUM: | |
3311 case TYPEDEF: | |
3312 sc = SC_TYPE; | |
3313 MATCH (); | |
3314 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3315 |
28523 | 3316 case STATIC: |
3317 sc = SC_STATIC; | |
3318 MATCH (); | |
3319 break; | |
3320 | |
3321 case INT: case CHAR: case LONG: case UNSIGNED: | |
3322 case SIGNED: case CONST: case DOUBLE: case VOID: | |
3323 case SHORT: case VOLATILE: case BOOL: case WCHAR: | |
3324 MATCH (); | |
3325 break; | |
3326 | |
3327 case CLASS: case STRUCT: case UNION: | |
3328 /* This is for the case `STARTWRAP class X : ...' or | |
3329 `declare (X, Y)\n class A : ...'. */ | |
3330 if (id) | |
35459 | 3331 { |
3332 xfree (id); | |
3333 return; | |
3334 } | |
28523 | 3335 |
3336 case '=': | |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3337 /* Assumed to be the start of an initialization in this |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3338 context. */ |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3339 skip_initializer (); |
28523 | 3340 break; |
3341 | |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3342 case ',': |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3343 add_declarator (&cls, &id, flags, sc); |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3344 break; |
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3345 |
28523 | 3346 case OPERATOR: |
35459 | 3347 { |
3348 char *s = operator_name (&sc); | |
3349 id = (char *) xrealloc (id, strlen (s) + 1); | |
3350 strcpy (id, s); | |
3351 } | |
28523 | 3352 break; |
3353 | |
3354 case T_INLINE: | |
3355 SET_FLAG (flags, F_INLINE); | |
3356 MATCH (); | |
3357 break; | |
3358 | |
3359 case '~': | |
3360 MATCH (); | |
3361 if (LOOKING_AT (IDENT)) | |
3362 { | |
35459 | 3363 id = (char *) xrealloc (id, strlen (yytext) + 2); |
28523 | 3364 *id = '~'; |
3365 strcpy (id + 1, yytext); | |
3366 MATCH (); | |
3367 } | |
3368 break; | |
3369 | |
3370 case IDENT: | |
3371 cls = parse_qualified_ident_or_type (&id); | |
3372 break; | |
3373 | |
3374 case '(': | |
3375 /* Most probably the beginning of a parameter list. */ | |
3376 if (cls) | |
3377 { | |
3378 MATCH (); | |
3379 | |
3380 if (id && cls) | |
3381 { | |
3382 if (!(is_constructor = streq (id, cls->name))) | |
3383 regexp = matching_regexp (); | |
3384 } | |
3385 else | |
3386 is_constructor = 0; | |
3387 | |
3388 pos = BUFFER_POS (); | |
3389 hash = parm_list (&flags); | |
3390 | |
3391 if (is_constructor) | |
3392 regexp = matching_regexp (); | |
3393 | |
3394 if (id && cls) | |
3395 add_member_defn (cls, id, regexp, pos, hash, 0, | |
3396 SC_UNKNOWN, flags); | |
3397 } | |
3398 else | |
3399 { | |
3400 /* This may be a C functions, but also a macro | |
3401 call of the form `declare (A, B)' --- such macros | |
3402 can be found in some class libraries. */ | |
3403 MATCH (); | |
3404 | |
3405 if (id) | |
3406 { | |
3407 regexp = matching_regexp (); | |
3408 pos = BUFFER_POS (); | |
3409 hash = parm_list (&flags); | |
3410 add_global_decl (id, regexp, pos, hash, 0, sc, flags); | |
3411 } | |
3412 | |
3413 /* This is for the case that the function really is | |
3414 a macro with no `;' following it. If a CLASS directly | |
3415 follows, we would miss it otherwise. */ | |
3416 if (LOOKING_AT3 (CLASS, STRUCT, UNION)) | |
3417 return; | |
3418 } | |
3419 | |
3420 while (!LOOKING_AT3 (';', '{', YYEOF)) | |
3421 MATCH (); | |
3422 | |
3423 if (!cls && id && LOOKING_AT ('{')) | |
3424 add_global_defn (id, regexp, pos, hash, 0, sc, flags); | |
35459 | 3425 |
3426 xfree (id); | |
28523 | 3427 id = NULL; |
3428 break; | |
3429 } | |
3430 } | |
3431 | |
44220
69735f5e2a07
(add_declarator, skip_initializer): New functions.
Gerd Moellmann <gerd@gnu.org>
parents:
42259
diff
changeset
|
3432 add_declarator (&cls, &id, flags, sc); |
28523 | 3433 } |
3434 | |
3435 | |
3436 /* Parse a list of top-level declarations/definitions. START_FLAGS | |
3437 says in which context we are parsing. If it is F_EXTERNC, we are | |
3438 parsing in an `extern "C"' block. Value is 1 if EOF is reached, 0 | |
3439 otherwise. */ | |
3440 | |
3441 int | |
3442 globals (start_flags) | |
3443 int start_flags; | |
3444 { | |
3445 int anonymous; | |
3446 int class_tk; | |
3447 int flags = start_flags; | |
3448 | |
3449 for (;;) | |
3450 { | |
3451 char *prev_in = in; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3452 |
28523 | 3453 switch (LA1) |
3454 { | |
3455 case NAMESPACE: | |
3456 { | |
3457 MATCH (); | |
3458 | |
3459 if (LOOKING_AT (IDENT)) | |
3460 { | |
35459 | 3461 char *namespace_name = xstrdup (yytext); |
28523 | 3462 MATCH (); |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3463 |
28523 | 3464 if (LOOKING_AT ('=')) |
3465 { | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3466 struct link *qna = match_qualified_namespace_alias (); |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3467 if (qna) |
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3468 register_namespace_alias (namespace_name, qna); |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3469 |
28523 | 3470 if (skip_to (';') == ';') |
3471 MATCH (); | |
3472 } | |
3473 else if (LOOKING_AT ('{')) | |
3474 { | |
3475 MATCH (); | |
3476 enter_namespace (namespace_name); | |
3477 globals (0); | |
3478 leave_namespace (); | |
3479 MATCH_IF ('}'); | |
3480 } | |
35459 | 3481 |
3482 xfree (namespace_name); | |
28523 | 3483 } |
3484 } | |
3485 break; | |
3486 | |
3487 case EXTERN: | |
3488 MATCH (); | |
3489 if (LOOKING_AT (CSTRING) && *string_start == 'C' | |
3490 && *(string_start + 1) == '"') | |
3491 { | |
3492 /* This is `extern "C"'. */ | |
3493 MATCH (); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3494 |
28523 | 3495 if (LOOKING_AT ('{')) |
3496 { | |
3497 MATCH (); | |
3498 globals (F_EXTERNC); | |
3499 MATCH_IF ('}'); | |
3500 } | |
3501 else | |
3502 SET_FLAG (flags, F_EXTERNC); | |
3503 } | |
3504 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3505 |
28523 | 3506 case TEMPLATE: |
3507 MATCH (); | |
3508 SKIP_MATCHING_IF ('<'); | |
3509 SET_FLAG (flags, F_TEMPLATE); | |
3510 break; | |
3511 | |
3512 case CLASS: case STRUCT: case UNION: | |
3513 class_tk = LA1; | |
3514 MATCH (); | |
3515 anonymous = 1; | |
3516 | |
3517 /* More than one ident here to allow for MS-DOS and OS/2 | |
3518 specialties like `far', `_Export' etc. Some C++ libs | |
3519 have constructs like `_OS_DLLIMPORT(_OS_CLIENT)' in front | |
3520 of the class name. */ | |
3521 while (!LOOKING_AT4 (YYEOF, ';', ':', '{')) | |
3522 { | |
3523 if (LOOKING_AT (IDENT)) | |
3524 anonymous = 0; | |
3525 MATCH (); | |
3526 } | |
3527 | |
3528 /* Don't add anonymous unions. */ | |
3529 if (LOOKING_AT2 (':', '{') && !anonymous) | |
3530 class_definition (NULL, class_tk, flags, 0); | |
3531 else | |
3532 { | |
3533 if (skip_to (';') == ';') | |
3534 MATCH (); | |
3535 } | |
3536 | |
3537 flags = start_flags; | |
3538 break; | |
3539 | |
3540 case YYEOF: | |
3541 return 1; | |
3542 | |
3543 case '}': | |
3544 return 0; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3545 |
28523 | 3546 default: |
28645
0813367c7810
(xmalloc, xrealloc): Rewritten.
Gerd Moellmann <gerd@gnu.org>
parents:
28523
diff
changeset
|
3547 declaration (flags); |
28523 | 3548 flags = start_flags; |
3549 break; | |
3550 } | |
3551 | |
3552 if (prev_in == in) | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
3553 yyerror ("parse error", NULL); |
28523 | 3554 } |
3555 } | |
3556 | |
3557 | |
3558 /* Parse the current input file. */ | |
3559 | |
3560 void | |
3561 yyparse () | |
3562 { | |
3563 while (globals (0) == 0) | |
3564 MATCH_IF ('}'); | |
3565 } | |
3566 | |
3567 | |
3568 | |
3569 /*********************************************************************** | |
3570 Main Program | |
3571 ***********************************************************************/ | |
3572 | |
3573 /* Add the list of paths PATH_LIST to the current search path for | |
3574 input files. */ | |
3575 | |
3576 void | |
3577 add_search_path (path_list) | |
3578 char *path_list; | |
3579 { | |
3580 while (*path_list) | |
3581 { | |
3582 char *start = path_list; | |
3583 struct search_path *p; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3584 |
28523 | 3585 while (*path_list && *path_list != PATH_LIST_SEPARATOR) |
3586 ++path_list; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3587 |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3588 p = (struct search_path *) xmalloc (sizeof *p); |
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3589 p->path = (char *) xmalloc (path_list - start + 1); |
28523 | 3590 memcpy (p->path, start, path_list - start); |
3591 p->path[path_list - start] = '\0'; | |
3592 p->next = NULL; | |
3593 | |
3594 if (search_path_tail) | |
3595 { | |
3596 search_path_tail->next = p; | |
3597 search_path_tail = p; | |
3598 } | |
3599 else | |
3600 search_path = search_path_tail = p; | |
3601 | |
3602 while (*path_list == PATH_LIST_SEPARATOR) | |
3603 ++path_list; | |
3604 } | |
3605 } | |
3606 | |
3607 | |
3608 /* Open FILE and return a file handle for it, or -1 if FILE cannot be | |
3609 opened. Try to find FILE in search_path first, then try the | |
3610 unchanged file name. */ | |
3611 | |
3612 FILE * | |
3613 open_file (file) | |
3614 char *file; | |
3615 { | |
3616 FILE *fp = NULL; | |
3617 static char *buffer; | |
3618 static int buffer_size; | |
3619 struct search_path *path; | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3620 int flen = strlen (file) + 1; /* +1 for the slash */ |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3621 |
28523 | 3622 filename = xstrdup (file); |
3623 | |
3624 for (path = search_path; path && fp == NULL; path = path->next) | |
3625 { | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3626 int len = strlen (path->path) + flen; |
28523 | 3627 |
3628 if (len + 1 >= buffer_size) | |
3629 { | |
3630 buffer_size = max (len + 1, 2 * buffer_size); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3631 buffer = (char *) xrealloc (buffer, buffer_size); |
28523 | 3632 } |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3633 |
28523 | 3634 strcpy (buffer, path->path); |
3635 strcat (buffer, "/"); | |
3636 strcat (buffer, file); | |
3637 fp = fopen (buffer, "r"); | |
3638 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3639 |
28523 | 3640 /* Try the original file name. */ |
3641 if (fp == NULL) | |
3642 fp = fopen (file, "r"); | |
3643 | |
3644 if (fp == NULL) | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
3645 yyerror ("cannot open", NULL); |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3646 |
28523 | 3647 return fp; |
3648 } | |
3649 | |
3650 | |
3651 /* Display usage information and exit program. */ | |
3652 | |
3653 #define USAGE "\ | |
3654 Usage: ebrowse [options] {files}\n\ | |
3655 \n\ | |
38429
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3656 -a, --append append output to existing file\n\ |
28523 | 3657 -f, --files=FILES read input file names from FILE\n\ |
3658 -I, --search-path=LIST set search path for input files\n\ | |
3659 -m, --min-regexp-length=N set minimum regexp length to N\n\ | |
3660 -M, --max-regexp-length=N set maximum regexp length to N\n\ | |
3661 -n, --no-nested-classes exclude nested classes\n\ | |
3662 -o, --output-file=FILE set output file name to FILE\n\ | |
3663 -p, --position-info print info about position in file\n\ | |
3664 -s, --no-structs-or-unions don't record structs or unions\n\ | |
3665 -v, --verbose be verbose\n\ | |
3666 -V, --very-verbose be very verbose\n\ | |
3667 -x, --no-regexps don't record regular expressions\n\ | |
3668 --help display this help\n\ | |
3669 --version display version info\n\ | |
3670 " | |
3671 | |
3672 void | |
3673 usage (error) | |
3674 int error; | |
3675 { | |
3676 puts (USAGE); | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3677 exit (error ? EXIT_FAILURE : EXIT_SUCCESS); |
28523 | 3678 } |
3679 | |
3680 | |
3681 /* Display version and copyright info. The VERSION macro is set | |
3682 from the Makefile and contains the Emacs version. */ | |
3683 | |
34258
6894bd47e0e0
(VERSION): Provide default definition, like etags.c
Andrew Innes <andrewi@gnu.org>
parents:
33384
diff
changeset
|
3684 #ifndef VERSION |
6894bd47e0e0
(VERSION): Provide default definition, like etags.c
Andrew Innes <andrewi@gnu.org>
parents:
33384
diff
changeset
|
3685 # define VERSION "21" |
6894bd47e0e0
(VERSION): Provide default definition, like etags.c
Andrew Innes <andrewi@gnu.org>
parents:
33384
diff
changeset
|
3686 #endif |
6894bd47e0e0
(VERSION): Provide default definition, like etags.c
Andrew Innes <andrewi@gnu.org>
parents:
33384
diff
changeset
|
3687 |
28523 | 3688 void |
3689 version () | |
3690 { | |
3691 printf ("ebrowse %s\n", VERSION); | |
39514
542ef74db0d2
(struct alias): Add two new struct members: NAMESP and
Gerd Moellmann <gerd@gnu.org>
parents:
39076
diff
changeset
|
3692 puts ("Copyright (C) 1992-1999, 2000, 2001 Free Software Foundation, Inc."); |
28523 | 3693 puts ("This program is distributed under the same terms as Emacs."); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3694 exit (EXIT_SUCCESS); |
28523 | 3695 } |
3696 | |
3697 | |
3698 /* Parse one input file FILE, adding classes and members to the symbol | |
3699 table. */ | |
3700 | |
3701 void | |
3702 process_file (file) | |
3703 char *file; | |
3704 { | |
3705 FILE *fp; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3706 |
28523 | 3707 fp = open_file (file); |
3708 if (fp) | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3709 { |
28523 | 3710 int nread, nbytes; |
3711 | |
3712 /* Give a progress indication if needed. */ | |
3713 if (f_very_verbose) | |
3714 { | |
3715 puts (filename); | |
3716 fflush (stdout); | |
3717 } | |
3718 else if (f_verbose) | |
3719 { | |
3720 putchar ('.'); | |
3721 fflush (stdout); | |
3722 } | |
3723 | |
3724 /* Read file to inbuffer. */ | |
3725 for (nread = 0;;) | |
3726 { | |
3727 if (nread + READ_CHUNK_SIZE >= inbuffer_size) | |
3728 { | |
3729 inbuffer_size = nread + READ_CHUNK_SIZE + 1; | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3730 inbuffer = (char *) xrealloc (inbuffer, inbuffer_size); |
28523 | 3731 } |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3732 |
28523 | 3733 nbytes = fread (inbuffer + nread, 1, READ_CHUNK_SIZE, fp); |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3734 if (nbytes <= 0) |
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3735 break; |
28523 | 3736 nread += nbytes; |
3737 } | |
28773
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3738 if (nread < 0) |
9afdf8a67091
(PATH_LIST_SEPARATOR) [__MSDOS__ || WINDOWSNT]: Define
Eli Zaretskii <eliz@gnu.org>
parents:
28645
diff
changeset
|
3739 nread = 0; |
28523 | 3740 inbuffer[nread] = '\0'; |
3741 | |
3742 /* Reinitialize scanner and parser for the new input file. */ | |
3743 re_init_scanner (); | |
3744 re_init_parser (); | |
3745 | |
3746 /* Parse it and close the file. */ | |
3747 yyparse (); | |
3748 fclose (fp); | |
3749 } | |
3750 } | |
3751 | |
3752 | |
3753 /* Read a line from stream FP and return a pointer to a static buffer | |
3754 containing its contents without the terminating newline. Value | |
3755 is null when EOF is reached. */ | |
3756 | |
3757 char * | |
3758 read_line (fp) | |
3759 FILE *fp; | |
3760 { | |
3761 static char *buffer; | |
3762 static int buffer_size; | |
3763 int i = 0, c; | |
3764 | |
3765 while ((c = getc (fp)) != EOF && c != '\n') | |
3766 { | |
3767 if (i >= buffer_size) | |
3768 { | |
3769 buffer_size = max (100, buffer_size * 2); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3770 buffer = (char *) xrealloc (buffer, buffer_size); |
28523 | 3771 } |
3772 | |
3773 buffer[i++] = c; | |
3774 } | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3775 |
28523 | 3776 if (c == EOF && i == 0) |
3777 return NULL; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3778 |
28523 | 3779 if (i == buffer_size) |
3780 { | |
3781 buffer_size = max (100, buffer_size * 2); | |
30232
ad501fc526c2
(xrealloc, xmalloc): Renamed from yrealloc and
Gerd Moellmann <gerd@gnu.org>
parents:
30138
diff
changeset
|
3782 buffer = (char *) xrealloc (buffer, buffer_size); |
28523 | 3783 } |
3784 | |
3785 buffer[i] = '\0'; | |
36478
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3786 if (i > 0 && buffer[i - 1] == '\r') |
742df7c33f75
(parse_qualified_param_ident_or_type): Return a
Gerd Moellmann <gerd@gnu.org>
parents:
35591
diff
changeset
|
3787 buffer[i - 1] = '\0'; |
28523 | 3788 return buffer; |
3789 } | |
3790 | |
3791 | |
3792 /* Main entry point. */ | |
3793 | |
3794 int | |
3795 main (argc, argv) | |
3796 int argc; | |
3797 char **argv; | |
3798 { | |
3799 int i; | |
3800 int any_inputfiles = 0; | |
3801 static char *out_filename = DEFAULT_OUTFILE; | |
3802 static char **input_filenames = NULL; | |
3803 static int input_filenames_size = 0; | |
3804 static int n_input_files; | |
3805 | |
3806 filename = "command line"; | |
3807 yyout = stdout; | |
3808 | |
3809 while ((i = getopt_long (argc, argv, "af:I:m:M:no:p:svVx", | |
3810 options, NULL)) != EOF) | |
3811 { | |
3812 switch (i) | |
3813 { | |
3814 /* Experimental. */ | |
3815 case 'p': | |
3816 info_position = atoi (optarg); | |
3817 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3818 |
28523 | 3819 case 'n': |
3820 f_nested_classes = 0; | |
3821 break; | |
3822 | |
3823 case 'x': | |
3824 f_regexps = 0; | |
3825 break; | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3826 |
28523 | 3827 /* Add the name of a file containing more input files. */ |
3828 case 'f': | |
3829 if (n_input_files == input_filenames_size) | |
3830 { | |
3831 input_filenames_size = max (10, 2 * input_filenames_size); | |
34954
ff4771c51345
(enter_namespace, main): Cast variables to shut up
Eli Zaretskii <eliz@gnu.org>
parents:
34610
diff
changeset
|
3832 input_filenames = (char **) xrealloc ((void *)input_filenames, |
28523 | 3833 input_filenames_size); |
3834 } | |
3835 input_filenames[n_input_files++] = xstrdup (optarg); | |
3836 break; | |
3837 | |
3838 /* Append new output to output file instead of truncating it. */ | |
3839 case 'a': | |
3840 f_append = 1; | |
3841 break; | |
3842 | |
3843 /* Include structs in the output */ | |
3844 case 's': | |
3845 f_structs = 0; | |
3846 break; | |
3847 | |
3848 /* Be verbose (give a progress indication). */ | |
3849 case 'v': | |
3850 f_verbose = 1; | |
3851 break; | |
3852 | |
3853 /* Be very verbose (print file names as they are processed). */ | |
3854 case 'V': | |
3855 f_verbose = 1; | |
3856 f_very_verbose = 1; | |
3857 break; | |
3858 | |
3859 /* Change the name of the output file. */ | |
3860 case 'o': | |
3861 out_filename = optarg; | |
3862 break; | |
3863 | |
3864 /* Set minimum length for regular expression strings | |
3865 when recorded in the output file. */ | |
3866 case 'm': | |
3867 min_regexp = atoi (optarg); | |
3868 break; | |
3869 | |
3870 /* Set maximum length for regular expression strings | |
3871 when recorded in the output file. */ | |
3872 case 'M': | |
3873 max_regexp = atoi (optarg); | |
3874 break; | |
3875 | |
3876 /* Add to search path. */ | |
3877 case 'I': | |
3878 add_search_path (optarg); | |
3879 break; | |
3880 | |
3881 /* Display help */ | |
3882 case -2: | |
3883 usage (0); | |
3884 break; | |
3885 | |
3886 case -3: | |
3887 version (); | |
3888 break; | |
3889 } | |
3890 } | |
3891 | |
3892 /* Call init_scanner after command line flags have been processed to be | |
3893 able to add keywords depending on command line (not yet | |
3894 implemented). */ | |
3895 init_scanner (); | |
3896 init_sym (); | |
3897 | |
3898 /* Open output file */ | |
3899 if (*out_filename) | |
3900 { | |
38429
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3901 if (f_append) |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3902 { |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3903 /* Check that the file to append to exists, and is not |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3904 empty. More specifically, it should be a valid file |
38769 | 3905 produced by a previous run of ebrowse, but that's too |
38429
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3906 difficult to check. */ |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3907 FILE *fp; |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3908 int rc; |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3909 |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3910 fp = fopen (out_filename, "r"); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3911 if (fp == NULL) |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3912 yyerror ("file `%s' must exist for --append", out_filename); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3913 |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3914 rc = fseek (fp, 0, SEEK_END); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3915 if (rc == -1) |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3916 yyerror ("error seeking in file `%s'", out_filename); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3917 |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3918 rc = ftell (fp); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3919 if (rc == -1) |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3920 yyerror ("error getting size of file `%s'", out_filename); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3921 else if (rc == 0) |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3922 yyerror ("file `%s' is empty", out_filename); |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3923 |
38429
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3924 fclose (fp); |
3960fdb54cfd
(main): Check that the output file exists and
Gerd Moellmann <gerd@gnu.org>
parents:
37615
diff
changeset
|
3925 } |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3926 |
28523 | 3927 yyout = fopen (out_filename, f_append ? "a" : "w"); |
3928 if (yyout == NULL) | |
3929 { | |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
3930 yyerror ("cannot open output file `%s'", out_filename); |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3931 exit (EXIT_FAILURE); |
28523 | 3932 } |
3933 } | |
3934 | |
3935 /* Process input files specified on the command line. */ | |
3936 while (optind < argc) | |
3937 { | |
3938 process_file (argv[optind++]); | |
3939 any_inputfiles = 1; | |
3940 } | |
3941 | |
3942 /* Process files given on stdin if no files specified. */ | |
3943 if (!any_inputfiles && n_input_files == 0) | |
3944 { | |
3945 char *file; | |
3946 while ((file = read_line (stdin)) != NULL) | |
3947 process_file (file); | |
3948 } | |
3949 else | |
3950 { | |
3951 /* Process files from `--files=FILE'. Every line in FILE names | |
3952 one input file to process. */ | |
3953 for (i = 0; i < n_input_files; ++i) | |
3954 { | |
3955 FILE *fp = fopen (input_filenames[i], "r"); | |
42174
e3b97ef49aee
Include stdlib.h and string.h conditionally.
Pavel Janík <Pavel@Janik.cz>
parents:
41112
diff
changeset
|
3956 |
28523 | 3957 if (fp == NULL) |
34990
49cf406a0cab
(yyerror): Changed to take two arguments. Prototype
Gerd Moellmann <gerd@gnu.org>
parents:
34954
diff
changeset
|
3958 yyerror ("cannot open input file `%s'", input_filenames[i]); |
28523 | 3959 else |
3960 { | |
3961 char *file; | |
3962 while ((file = read_line (fp)) != NULL) | |
3963 process_file (file); | |
3964 fclose (fp); | |
3965 } | |
3966 } | |
3967 } | |
3968 | |
3969 /* Write output file. */ | |
3970 dump_roots (yyout); | |
3971 | |
3972 /* Close output file. */ | |
3973 if (yyout != stdout) | |
3974 fclose (yyout); | |
3975 | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3976 return EXIT_SUCCESS; |
28523 | 3977 } |
3978 | |
52401 | 3979 /* arch-tag: fc03b4bc-91a9-4c3d-b3b9-12a77fa86dd8 |
3980 (do not change this comment) */ | |
55442
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3981 |
a47704955f8d
Throughout, replace 0 destined for `exit' arg with `EXIT_SUCCESS'.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents:
52401
diff
changeset
|
3982 /* ebrowse.c ends here */ |