]>
Commit | Line | Data |
---|---|---|
7f2935c7 | 1 | /* CPP Library. |
5e7b4e25 JL |
2 | Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3 | 1999, 2000 Free Software Foundation, Inc. | |
4c8cc616 | 4 | Contributed by Per Bothner, 1994-95. |
d8bfa78c | 5 | Based on CCCP program by Paul Rubin, June 1986 |
7f2935c7 PB |
6 | Adapted to ANSI C, Richard Stallman, Jan 1987 |
7 | ||
8 | This program is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU General Public License as published by the | |
10 | Free Software Foundation; either version 2, or (at your option) any | |
11 | later version. | |
12 | ||
13 | This program 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 | |
19 | along with this program; if not, write to the Free Software | |
956d6950 | 20 | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
7f2935c7 | 21 | |
956d6950 | 22 | #include "config.h" |
b04cd507 | 23 | #include "system.h" |
7f2935c7 | 24 | |
956d6950 JL |
25 | #include "cpplib.h" |
26 | #include "cpphash.h" | |
ab87f8c8 | 27 | #include "intl.h" |
49e6c08e | 28 | #include "mkdeps.h" |
7f2935c7 | 29 | |
a9ae4483 | 30 | #define SKIP_WHITE_SPACE(p) do { while (is_hspace(*p)) p++; } while (0) |
7f2935c7 PB |
31 | |
32 | #define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) ? CPP_BUFFER (pfile)->cur[N] : EOF) | |
33 | #define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N)) | |
34 | #define GETC() CPP_BUF_GET (CPP_BUFFER (pfile)) | |
35 | #define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile)) | |
36 | /* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion. | |
6de1e2a9 ZW |
37 | (Note that it is false while we're expanding macro *arguments*.) */ |
38 | #define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL) | |
7f2935c7 | 39 | |
564ad5f4 ZW |
40 | /* ACTIVE_MARK_P is true if there's a live mark in the buffer, in which |
41 | case CPP_BUMP_LINE must not be called. */ | |
42 | #define ACTIVE_MARK_P() (CPP_BUFFER (pfile)->mark != -1) | |
43 | ||
7f2935c7 PB |
44 | /* `struct directive' defines one #-directive, including how to handle it. */ |
45 | ||
ba412f14 ZW |
46 | struct directive |
47 | { | |
7f2935c7 | 48 | int length; /* Length of name */ |
487a6e06 | 49 | int (*func) /* Function to handle directive */ |
2ac9349e ZW |
50 | PARAMS ((cpp_reader *, const struct directive *)); |
51 | const char *name; /* Name of directive */ | |
0f41302f | 52 | enum node_type type; /* Code which describes which directive. */ |
7f2935c7 PB |
53 | }; |
54 | ||
487a6e06 KG |
55 | /* These functions are declared to return int instead of void since they |
56 | are going to be placed in a table and some old compilers have trouble with | |
57 | pointers to functions returning void. */ | |
58 | ||
2ac9349e ZW |
59 | static int do_define PARAMS ((cpp_reader *, const struct directive *)); |
60 | static int do_line PARAMS ((cpp_reader *, const struct directive *)); | |
61 | static int do_include PARAMS ((cpp_reader *, const struct directive *)); | |
62 | static int do_undef PARAMS ((cpp_reader *, const struct directive *)); | |
63 | static int do_error PARAMS ((cpp_reader *, const struct directive *)); | |
64 | static int do_pragma PARAMS ((cpp_reader *, const struct directive *)); | |
65 | static int do_ident PARAMS ((cpp_reader *, const struct directive *)); | |
66 | static int do_if PARAMS ((cpp_reader *, const struct directive *)); | |
67 | static int do_xifdef PARAMS ((cpp_reader *, const struct directive *)); | |
68 | static int do_else PARAMS ((cpp_reader *, const struct directive *)); | |
69 | static int do_elif PARAMS ((cpp_reader *, const struct directive *)); | |
70 | static int do_endif PARAMS ((cpp_reader *, const struct directive *)); | |
487a6e06 | 71 | #ifdef SCCS_DIRECTIVE |
2ac9349e | 72 | static int do_sccs PARAMS ((cpp_reader *, const struct directive *)); |
487a6e06 | 73 | #endif |
2ac9349e ZW |
74 | static int do_assert PARAMS ((cpp_reader *, const struct directive *)); |
75 | static int do_unassert PARAMS ((cpp_reader *, const struct directive *)); | |
76 | static int do_warning PARAMS ((cpp_reader *, const struct directive *)); | |
1316f1f7 ZW |
77 | |
78 | /* Forward declarations. */ | |
79 | ||
1316f1f7 ZW |
80 | static void validate_else PARAMS ((cpp_reader *, const char *)); |
81 | static HOST_WIDEST_INT eval_if_expression PARAMS ((cpp_reader *)); | |
82 | static void conditional_skip PARAMS ((cpp_reader *, int, | |
83 | enum node_type, U_CHAR *)); | |
84 | static void skip_if_group PARAMS ((cpp_reader *)); | |
85 | static void parse_name PARAMS ((cpp_reader *, int)); | |
86 | static void parse_string PARAMS ((cpp_reader *, int)); | |
87 | static int parse_assertion PARAMS ((cpp_reader *)); | |
88 | static const char *if_directive_name PARAMS ((cpp_reader *, | |
89 | struct if_stack *)); | |
90 | static enum cpp_token null_underflow PARAMS ((cpp_reader *)); | |
91 | static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *)); | |
92 | static int skip_comment PARAMS ((cpp_reader *, int)); | |
93 | static int copy_comment PARAMS ((cpp_reader *, int)); | |
ba412f14 | 94 | static void skip_string PARAMS ((cpp_reader *, int)); |
cf4ed945 ZW |
95 | static void skip_rest_of_line PARAMS ((cpp_reader *)); |
96 | static void cpp_skip_hspace PARAMS ((cpp_reader *)); | |
1316f1f7 ZW |
97 | static int handle_directive PARAMS ((cpp_reader *)); |
98 | static void pass_thru_directive PARAMS ((const U_CHAR *, size_t, | |
99 | cpp_reader *, | |
100 | const struct directive *)); | |
1316f1f7 | 101 | static int read_line_number PARAMS ((cpp_reader *, int *)); |
1316f1f7 ZW |
102 | static U_CHAR *detect_if_not_defined PARAMS ((cpp_reader *)); |
103 | static int consider_directive_while_skipping PARAMS ((cpp_reader *, | |
104 | IF_STACK_FRAME *)); | |
105 | static void skip_block_comment PARAMS ((cpp_reader *)); | |
106 | static void skip_line_comment PARAMS ((cpp_reader *)); | |
564ad5f4 ZW |
107 | static void parse_set_mark PARAMS ((cpp_reader *)); |
108 | static void parse_goto_mark PARAMS ((cpp_reader *)); | |
ba412f14 | 109 | static int get_macro_name PARAMS ((cpp_reader *)); |
2ac9349e ZW |
110 | |
111 | /* Here is the actual list of #-directives. | |
112 | This table is ordered by frequency of occurrence; the numbers | |
113 | at the end are directive counts from all the source code I have | |
114 | lying around (egcs and libc CVS as of 1999-05-18, plus grub-0.5.91, | |
115 | linux-2.2.9, and pcmcia-cs-3.0.9). */ | |
116 | ||
117 | static const struct directive directive_table[] = { | |
118 | /* In C89 */ | |
119 | { 6, do_define, "define", T_DEFINE }, /* 270554 */ | |
120 | { 7, do_include, "include", T_INCLUDE }, /* 52262 */ | |
121 | { 5, do_endif, "endif", T_ENDIF }, /* 45855 */ | |
122 | { 5, do_xifdef, "ifdef", T_IFDEF }, /* 22000 */ | |
123 | { 2, do_if, "if", T_IF }, /* 18162 */ | |
124 | { 4, do_else, "else", T_ELSE }, /* 9863 */ | |
125 | { 6, do_xifdef, "ifndef", T_IFNDEF }, /* 9675 */ | |
126 | { 5, do_undef, "undef", T_UNDEF }, /* 4837 */ | |
127 | { 4, do_line, "line", T_LINE }, /* 2465 */ | |
128 | { 4, do_elif, "elif", T_ELIF }, /* 610 */ | |
129 | { 5, do_error, "error", T_ERROR }, /* 475 */ | |
130 | { 6, do_pragma, "pragma", T_PRAGMA }, /* 195 */ | |
131 | ||
132 | /* Extensions. All deprecated except #warning and #include_next. */ | |
133 | { 7, do_warning, "warning", T_WARNING }, /* 22 - GNU */ | |
134 | { 12, do_include, "include_next", T_INCLUDE_NEXT }, /* 19 - GNU */ | |
135 | { 5, do_ident, "ident", T_IDENT }, /* 11 - SVR4 */ | |
136 | { 6, do_include, "import", T_IMPORT }, /* 0 - ObjC */ | |
137 | { 6, do_assert, "assert", T_ASSERT }, /* 0 - SVR4 */ | |
138 | { 8, do_unassert, "unassert", T_UNASSERT }, /* 0 - SVR4 */ | |
7f2935c7 | 139 | #ifdef SCCS_DIRECTIVE |
2ac9349e | 140 | { 4, do_sccs, "sccs", T_SCCS }, /* 0 - SVR2? */ |
7f2935c7 | 141 | #endif |
941e09b6 | 142 | { -1, 0, "", T_UNUSED } |
7f2935c7 | 143 | }; |
7f2935c7 PB |
144 | |
145 | /* Place into PFILE a quoted string representing the string SRC. | |
0f41302f MS |
146 | Caller must reserve enough space in pfile->token_buffer. */ |
147 | ||
6de1e2a9 | 148 | void |
7f2935c7 PB |
149 | quote_string (pfile, src) |
150 | cpp_reader *pfile; | |
6de1e2a9 | 151 | const char *src; |
7f2935c7 PB |
152 | { |
153 | U_CHAR c; | |
154 | ||
155 | CPP_PUTC_Q (pfile, '\"'); | |
156 | for (;;) | |
157 | switch ((c = *src++)) | |
158 | { | |
159 | default: | |
e9a780ec | 160 | if (ISPRINT (c)) |
7f2935c7 PB |
161 | CPP_PUTC_Q (pfile, c); |
162 | else | |
163 | { | |
e9a25f70 | 164 | sprintf ((char *)CPP_PWRITTEN (pfile), "\\%03o", c); |
7f2935c7 PB |
165 | CPP_ADJUST_WRITTEN (pfile, 4); |
166 | } | |
167 | break; | |
168 | ||
169 | case '\"': | |
170 | case '\\': | |
171 | CPP_PUTC_Q (pfile, '\\'); | |
172 | CPP_PUTC_Q (pfile, c); | |
173 | break; | |
174 | ||
175 | case '\0': | |
176 | CPP_PUTC_Q (pfile, '\"'); | |
177 | CPP_NUL_TERMINATE_Q (pfile); | |
178 | return; | |
179 | } | |
180 | } | |
181 | ||
0f41302f | 182 | /* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */ |
7f2935c7 PB |
183 | |
184 | void | |
185 | cpp_grow_buffer (pfile, n) | |
186 | cpp_reader *pfile; | |
187 | long n; | |
188 | { | |
189 | long old_written = CPP_WRITTEN (pfile); | |
190 | pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; | |
0f41302f | 191 | pfile->token_buffer = (U_CHAR *) |
7f2935c7 PB |
192 | xrealloc(pfile->token_buffer, pfile->token_buffer_size); |
193 | CPP_SET_WRITTEN (pfile, old_written); | |
194 | } | |
195 | ||
cf4ed945 | 196 | /* Process the string STR as if it appeared as the body of a #define. |
5538ada6 ZW |
197 | If STR is just an identifier, define it with value 1. |
198 | If STR has anything after the identifier, then it should | |
199 | be identifier=definition. */ | |
7f2935c7 | 200 | |
b13b05f6 PB |
201 | void |
202 | cpp_define (pfile, str) | |
7f2935c7 PB |
203 | cpp_reader *pfile; |
204 | U_CHAR *str; | |
205 | { | |
206 | U_CHAR *buf, *p; | |
5538ada6 | 207 | size_t count; |
7f2935c7 | 208 | |
2387c1d4 ZW |
209 | p = strchr (str, '='); |
210 | /* Copy the entire option so we can modify it. | |
211 | Change the first "=" in the string to a space. If there is none, | |
212 | tack " 1" on the end. Then add a newline and a NUL. */ | |
213 | ||
5538ada6 | 214 | if (p) |
7f2935c7 | 215 | { |
2387c1d4 ZW |
216 | count = strlen (str) + 2; |
217 | buf = (U_CHAR *) alloca (count); | |
218 | memcpy (buf, str, count - 2); | |
219 | buf[p - str] = ' '; | |
220 | buf[count - 2] = '\n'; | |
221 | buf[count - 1] = '\0'; | |
7f2935c7 PB |
222 | } |
223 | else | |
2387c1d4 ZW |
224 | { |
225 | count = strlen (str) + 4; | |
226 | buf = (U_CHAR *) alloca (count); | |
227 | memcpy (buf, str, count - 4); | |
228 | strcpy (&buf[count-4], " 1\n"); | |
229 | } | |
230 | ||
5538ada6 | 231 | if (cpp_push_buffer (pfile, buf, count - 1) != NULL) |
941e09b6 ZW |
232 | { |
233 | do_define (pfile, NULL); | |
234 | cpp_pop_buffer (pfile); | |
235 | } | |
7f2935c7 | 236 | } |
7f2935c7 | 237 | |
5538ada6 ZW |
238 | /* Process the string STR as if it appeared as the body of a #assert. */ |
239 | void | |
240 | cpp_assert (pfile, str) | |
7f2935c7 | 241 | cpp_reader *pfile; |
7f2935c7 PB |
242 | U_CHAR *str; |
243 | { | |
5538ada6 | 244 | if (cpp_push_buffer (pfile, str, strlen (str)) != NULL) |
e2f79f3c | 245 | { |
941e09b6 | 246 | do_assert (pfile, NULL); |
e2f79f3c PB |
247 | cpp_pop_buffer (pfile); |
248 | } | |
7f2935c7 | 249 | } |
7f2935c7 | 250 | |
cf4ed945 ZW |
251 | /* Determine whether the identifier ID, of length LEN, is a defined macro. */ |
252 | int | |
253 | cpp_defined (pfile, id, len) | |
254 | cpp_reader *pfile; | |
255 | const U_CHAR *id; | |
256 | int len; | |
257 | { | |
b0699dad | 258 | HASHNODE *hp = _cpp_lookup (pfile, id, len); |
cf4ed945 ZW |
259 | if (hp && hp->type == T_POISON) |
260 | { | |
261 | cpp_error (pfile, "attempt to use poisoned `%s'", hp->name); | |
262 | return 0; | |
263 | } | |
264 | return (hp != NULL); | |
265 | } | |
7f2935c7 | 266 | |
6de1e2a9 | 267 | static enum cpp_token |
7f2935c7 | 268 | null_underflow (pfile) |
d6f4ec51 | 269 | cpp_reader *pfile ATTRIBUTE_UNUSED; |
7f2935c7 PB |
270 | { |
271 | return CPP_EOF; | |
272 | } | |
273 | ||
6de1e2a9 | 274 | static int |
7f2935c7 | 275 | null_cleanup (pbuf, pfile) |
d6f4ec51 KG |
276 | cpp_buffer *pbuf ATTRIBUTE_UNUSED; |
277 | cpp_reader *pfile ATTRIBUTE_UNUSED; | |
7f2935c7 PB |
278 | { |
279 | return 0; | |
280 | } | |
281 | ||
75ec21db ZW |
282 | /* Skip a C-style block comment. We know it's a comment, and point is |
283 | at the second character of the starter. */ | |
284 | static void | |
285 | skip_block_comment (pfile) | |
286 | cpp_reader *pfile; | |
287 | { | |
288 | int c, prev_c = -1; | |
289 | long line, col; | |
290 | ||
291 | FORWARD(1); | |
292 | cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col); | |
293 | for (;;) | |
294 | { | |
295 | c = GETC (); | |
296 | if (c == EOF) | |
297 | { | |
298 | cpp_error_with_line (pfile, line, col, "unterminated comment"); | |
299 | return; | |
300 | } | |
301 | else if (c == '\n' || c == '\r') | |
564ad5f4 ZW |
302 | { |
303 | /* \r cannot be a macro escape marker here. */ | |
304 | if (!ACTIVE_MARK_P()) | |
305 | CPP_BUMP_LINE (pfile); | |
306 | } | |
75ec21db ZW |
307 | else if (c == '/' && prev_c == '*') |
308 | return; | |
309 | else if (c == '*' && prev_c == '/' | |
310 | && CPP_OPTIONS (pfile)->warn_comments) | |
311 | cpp_warning (pfile, "`/*' within comment"); | |
312 | ||
313 | prev_c = c; | |
314 | } | |
315 | } | |
316 | ||
317 | /* Skip a C++/Chill line comment. We know it's a comment, and point | |
318 | is at the second character of the initiator. */ | |
319 | static void | |
320 | skip_line_comment (pfile) | |
321 | cpp_reader *pfile; | |
322 | { | |
323 | FORWARD(1); | |
324 | for (;;) | |
325 | { | |
326 | int c = GETC (); | |
327 | ||
328 | /* We don't have to worry about EOF in here. */ | |
329 | if (c == '\n') | |
330 | { | |
331 | /* Don't consider final '\n' to be part of comment. */ | |
332 | FORWARD(-1); | |
333 | return; | |
334 | } | |
335 | else if (c == '\r') | |
336 | { | |
337 | /* \r cannot be a macro escape marker here. */ | |
564ad5f4 ZW |
338 | if (!ACTIVE_MARK_P()) |
339 | CPP_BUMP_LINE (pfile); | |
75ec21db ZW |
340 | if (CPP_OPTIONS (pfile)->warn_comments) |
341 | cpp_warning (pfile, "backslash-newline within line comment"); | |
342 | } | |
343 | } | |
344 | } | |
345 | ||
3fdc651f ZW |
346 | /* Skip a comment - C, C++, or Chill style. M is the first character |
347 | of the comment marker. If this really is a comment, skip to its | |
75ec21db ZW |
348 | end and return ' '. If this is not a comment, return M (which will |
349 | be '/' or '-'). */ | |
7f2935c7 PB |
350 | |
351 | static int | |
3fdc651f | 352 | skip_comment (pfile, m) |
7f2935c7 | 353 | cpp_reader *pfile; |
3fdc651f | 354 | int m; |
7f2935c7 | 355 | { |
3fdc651f | 356 | if (m == '/' && PEEKC() == '*') |
7f2935c7 | 357 | { |
75ec21db ZW |
358 | skip_block_comment (pfile); |
359 | return ' '; | |
360 | } | |
361 | else if (m == '/' && PEEKC() == '/') | |
362 | { | |
363 | if (CPP_BUFFER (pfile)->system_header_p) | |
7f2935c7 | 364 | { |
75ec21db ZW |
365 | /* We silently allow C++ comments in system headers, irrespective |
366 | of conformance mode, because lots of busted systems do that | |
367 | and trying to clean it up in fixincludes is a nightmare. */ | |
368 | skip_line_comment (pfile); | |
369 | return ' '; | |
370 | } | |
371 | else if (CPP_OPTIONS (pfile)->cplusplus_comments) | |
372 | { | |
373 | if (CPP_OPTIONS (pfile)->c89 | |
374 | && CPP_PEDANTIC (pfile) | |
375 | && ! CPP_BUFFER (pfile)->warned_cplusplus_comments) | |
7f2935c7 | 376 | { |
75ec21db ZW |
377 | cpp_pedwarn (pfile, |
378 | "C++ style comments are not allowed in ISO C89"); | |
379 | cpp_pedwarn (pfile, | |
380 | "(this will be reported only once per input file)"); | |
381 | CPP_BUFFER (pfile)->warned_cplusplus_comments = 1; | |
7f2935c7 | 382 | } |
75ec21db ZW |
383 | skip_line_comment (pfile); |
384 | return ' '; | |
7f2935c7 | 385 | } |
75ec21db ZW |
386 | else |
387 | return m; | |
7f2935c7 | 388 | } |
75ec21db ZW |
389 | else if (m == '-' && PEEKC() == '-' |
390 | && CPP_OPTIONS (pfile)->chill) | |
7f2935c7 | 391 | { |
75ec21db ZW |
392 | skip_line_comment (pfile); |
393 | return ' '; | |
3fdc651f ZW |
394 | } |
395 | else | |
396 | return m; | |
397 | } | |
398 | ||
399 | /* Identical to skip_comment except that it copies the comment into the | |
564ad5f4 | 400 | token_buffer. This is used if !discard_comments. */ |
3fdc651f ZW |
401 | static int |
402 | copy_comment (pfile, m) | |
403 | cpp_reader *pfile; | |
404 | int m; | |
405 | { | |
75ec21db ZW |
406 | U_CHAR *start = CPP_BUFFER (pfile)->cur; /* XXX Layering violation */ |
407 | U_CHAR *limit; | |
3fdc651f | 408 | |
75ec21db | 409 | if (skip_comment (pfile, m) == m) |
3fdc651f | 410 | return m; |
3fdc651f | 411 | |
ba412f14 ZW |
412 | limit = CPP_BUFFER (pfile)->cur; |
413 | CPP_RESERVE (pfile, limit - start + 2); | |
414 | CPP_PUTC_Q (pfile, m); | |
415 | for (; start <= limit; start++) | |
75ec21db | 416 | if (*start != '\r') |
ba412f14 ZW |
417 | CPP_PUTC_Q (pfile, *start); |
418 | ||
75ec21db ZW |
419 | return ' '; |
420 | } | |
7f2935c7 PB |
421 | |
422 | /* Skip whitespace \-newline and comments. Does not macro-expand. */ | |
0f41302f | 423 | |
cf4ed945 | 424 | static void |
7f2935c7 PB |
425 | cpp_skip_hspace (pfile) |
426 | cpp_reader *pfile; | |
427 | { | |
3fdc651f | 428 | int c; |
7f2935c7 PB |
429 | while (1) |
430 | { | |
3fdc651f | 431 | c = GETC(); |
7f2935c7 | 432 | if (c == EOF) |
3fdc651f | 433 | return; |
a9ae4483 | 434 | else if (is_hspace(c)) |
7f2935c7 PB |
435 | { |
436 | if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile)) | |
437 | cpp_pedwarn (pfile, "%s in preprocessing directive", | |
438 | c == '\f' ? "formfeed" : "vertical tab"); | |
7f2935c7 | 439 | } |
3fdc651f | 440 | else if (c == '\r') |
7f2935c7 | 441 | { |
ed45de98 ZW |
442 | /* \r is a backslash-newline marker if !has_escapes, and |
443 | a deletable-whitespace or no-reexpansion marker otherwise. */ | |
444 | if (CPP_BUFFER (pfile)->has_escapes) | |
445 | { | |
446 | if (PEEKC() == ' ') | |
447 | FORWARD(1); | |
448 | else | |
449 | break; | |
450 | } | |
451 | else | |
ba412f14 | 452 | CPP_BUMP_LINE (pfile); |
3fdc651f ZW |
453 | } |
454 | else if (c == '/' || c == '-') | |
455 | { | |
456 | c = skip_comment (pfile, c); | |
75ec21db | 457 | if (c != ' ') |
ed45de98 | 458 | break; |
3fdc651f ZW |
459 | } |
460 | else | |
ed45de98 | 461 | break; |
7f2935c7 | 462 | } |
ed45de98 | 463 | FORWARD(-1); |
7f2935c7 PB |
464 | } |
465 | ||
ba412f14 | 466 | /* Read and discard the rest of the current line. */ |
7f2935c7 | 467 | |
e2f79f3c | 468 | static void |
ba412f14 | 469 | skip_rest_of_line (pfile) |
7f2935c7 PB |
470 | cpp_reader *pfile; |
471 | { | |
7f2935c7 PB |
472 | for (;;) |
473 | { | |
474 | int c = GETC(); | |
7f2935c7 PB |
475 | switch (c) |
476 | { | |
3fdc651f ZW |
477 | case '\n': |
478 | FORWARD(-1); | |
7f2935c7 | 479 | case EOF: |
3fdc651f ZW |
480 | return; |
481 | ||
482 | case '\r': | |
ba412f14 ZW |
483 | if (! CPP_BUFFER (pfile)->has_escapes) |
484 | CPP_BUMP_LINE (pfile); | |
485 | break; | |
486 | ||
7f2935c7 PB |
487 | case '\'': |
488 | case '\"': | |
ba412f14 ZW |
489 | skip_string (pfile, c); |
490 | break; | |
491 | ||
7f2935c7 | 492 | case '/': |
3fdc651f | 493 | case '-': |
ba412f14 | 494 | skip_comment (pfile, c); |
7f2935c7 | 495 | break; |
3fdc651f | 496 | |
7f2935c7 PB |
497 | case '\f': |
498 | case '\v': | |
499 | if (CPP_PEDANTIC (pfile)) | |
500 | cpp_pedwarn (pfile, "%s in preprocessing directive", | |
501 | c == '\f' ? "formfeed" : "vertical tab"); | |
502 | break; | |
503 | ||
7f2935c7 | 504 | } |
7f2935c7 | 505 | } |
7f2935c7 PB |
506 | } |
507 | ||
7f2935c7 PB |
508 | /* Handle a possible # directive. |
509 | '#' has already been read. */ | |
510 | ||
6de1e2a9 | 511 | static int |
7f2935c7 PB |
512 | handle_directive (pfile) |
513 | cpp_reader *pfile; | |
3fdc651f ZW |
514 | { |
515 | int c; | |
2ac9349e | 516 | register const struct directive *kt; |
7f2935c7 | 517 | int ident_length; |
941e09b6 | 518 | U_CHAR *ident; |
7f2935c7 PB |
519 | long old_written = CPP_WRITTEN (pfile); |
520 | ||
ba412f14 ZW |
521 | if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) |
522 | { | |
523 | cpp_ice (pfile, "handle_directive called on macro buffer"); | |
524 | return 0; | |
525 | } | |
526 | ||
7f2935c7 PB |
527 | cpp_skip_hspace (pfile); |
528 | ||
529 | c = PEEKC (); | |
40c79d58 ZW |
530 | /* # followed by a number is equivalent to #line. Do not recognize |
531 | this form in assembly language source files. Complain about this | |
532 | form if we're being pedantic, but not if this is regurgitated | |
533 | input (preprocessed or fed back in by the C++ frontend). */ | |
7f2935c7 PB |
534 | if (c >= '0' && c <= '9') |
535 | { | |
40c79d58 | 536 | if (CPP_OPTIONS (pfile)->lang_asm) |
eaefae0e | 537 | return 0; |
40c79d58 | 538 | |
e6ad5e90 JM |
539 | if (CPP_PEDANTIC (pfile) |
540 | && ! CPP_PREPROCESSED (pfile) | |
541 | && ! CPP_BUFFER (pfile)->manual_pop) | |
7f2935c7 | 542 | cpp_pedwarn (pfile, "`#' followed by integer"); |
941e09b6 | 543 | do_line (pfile, NULL); |
3caee4a8 | 544 | return 1; |
7f2935c7 PB |
545 | } |
546 | ||
40c79d58 ZW |
547 | /* If we are rescanning preprocessed input, don't obey any directives |
548 | other than # nnn. */ | |
549 | if (CPP_PREPROCESSED (pfile)) | |
550 | return 0; | |
551 | ||
0f41302f | 552 | /* Now find the directive name. */ |
7f2935c7 PB |
553 | CPP_PUTC (pfile, '#'); |
554 | parse_name (pfile, GETC()); | |
555 | ident = pfile->token_buffer + old_written + 1; | |
556 | ident_length = CPP_PWRITTEN (pfile) - ident; | |
3caee4a8 | 557 | if (ident_length == 0) |
7f2935c7 | 558 | { |
eaefae0e | 559 | /* A line of just `#' becomes blank. A line with something |
c1212d2f ZW |
560 | other than an identifier after the # is reparsed as a non- |
561 | directive line. */ | |
eaefae0e ZW |
562 | CPP_SET_WRITTEN (pfile, old_written); |
563 | return (PEEKC() == '\n'); | |
7f2935c7 PB |
564 | } |
565 | ||
eaefae0e | 566 | /* Decode the keyword and call the appropriate expansion routine. */ |
3caee4a8 | 567 | for (kt = directive_table; ; kt++) |
7f2935c7 | 568 | { |
3caee4a8 | 569 | if (kt->length <= 0) |
eaefae0e ZW |
570 | /* # identifier, but not a legit directive. Pass onward as a |
571 | CPP_DIRECTIVE token anyway - let the consumer worry about it. */ | |
572 | return 1; | |
3caee4a8 ZW |
573 | if (kt->length == ident_length |
574 | && !strncmp (kt->name, ident, ident_length)) | |
575 | break; | |
7f2935c7 | 576 | } |
e9a25f70 | 577 | |
3caee4a8 | 578 | CPP_SET_WRITTEN (pfile, old_written); |
5237f531 ZW |
579 | |
580 | if (pfile->no_directives) | |
581 | { | |
582 | cpp_error (pfile, "`#%s' may not be used inside a macro argument", | |
583 | kt->name); | |
584 | skip_rest_of_line (pfile); | |
585 | } | |
586 | else | |
587 | (*kt->func) (pfile, kt); | |
7f2935c7 | 588 | |
3caee4a8 | 589 | return 1; |
7f2935c7 PB |
590 | } |
591 | ||
592 | /* Pass a directive through to the output file. | |
593 | BUF points to the contents of the directive, as a contiguous string. | |
3caee4a8 | 594 | LEN is the length of the string pointed to by BUF. |
7f2935c7 PB |
595 | KEYWORD is the keyword-table entry for the directive. */ |
596 | ||
597 | static void | |
3caee4a8 | 598 | pass_thru_directive (buf, len, pfile, keyword) |
bcc5cac9 | 599 | const U_CHAR *buf; |
3caee4a8 | 600 | size_t len; |
7f2935c7 | 601 | cpp_reader *pfile; |
2ac9349e | 602 | const struct directive *keyword; |
7f2935c7 PB |
603 | { |
604 | register unsigned keyword_length = keyword->length; | |
605 | ||
3caee4a8 | 606 | CPP_RESERVE (pfile, 1 + keyword_length + len); |
7f2935c7 PB |
607 | CPP_PUTC_Q (pfile, '#'); |
608 | CPP_PUTS_Q (pfile, keyword->name, keyword_length); | |
3caee4a8 | 609 | if (len != 0 && buf[0] != ' ') |
7f2935c7 | 610 | CPP_PUTC_Q (pfile, ' '); |
3caee4a8 | 611 | CPP_PUTS_Q (pfile, buf, len); |
7f2935c7 | 612 | } |
7f2935c7 | 613 | |
ba412f14 ZW |
614 | /* Subroutine of do_define: determine the name of the macro to be |
615 | defined. */ | |
7f2935c7 | 616 | |
ba412f14 ZW |
617 | static int |
618 | get_macro_name (pfile) | |
7f2935c7 | 619 | cpp_reader *pfile; |
7f2935c7 | 620 | { |
ba412f14 ZW |
621 | long here, len; |
622 | ||
623 | here = CPP_WRITTEN (pfile); | |
624 | pfile->no_macro_expand++; | |
625 | if (get_directive_token (pfile) != CPP_NAME) | |
626 | { | |
627 | cpp_error (pfile, "`#define' must be followed by an identifier"); | |
628 | goto invalid; | |
629 | } | |
630 | ||
631 | len = CPP_WRITTEN (pfile) - here; | |
632 | if (len == 7 && !strncmp (pfile->token_buffer + here, "defined", 7)) | |
633 | { | |
634 | cpp_error (pfile, "`defined' is not a legal macro name"); | |
635 | goto invalid; | |
636 | } | |
637 | ||
638 | pfile->no_macro_expand--; | |
639 | return len; | |
640 | ||
641 | invalid: | |
642 | skip_rest_of_line (pfile); | |
643 | pfile->no_macro_expand--; | |
644 | return 0; | |
7f2935c7 PB |
645 | } |
646 | ||
7f2935c7 | 647 | /* Process a #define command. |
fc009f96 | 648 | KEYWORD is the keyword-table entry for #define, |
ba412f14 | 649 | or NULL for a "predefined" macro. */ |
7f2935c7 PB |
650 | |
651 | static int | |
941e09b6 | 652 | do_define (pfile, keyword) |
7f2935c7 | 653 | cpp_reader *pfile; |
c45da1ca | 654 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 655 | { |
7f2935c7 | 656 | HASHNODE *hp; |
ba412f14 | 657 | DEFINITION *def; |
941e09b6 | 658 | long here; |
ba412f14 ZW |
659 | int len, c; |
660 | int funlike = 0; | |
661 | U_CHAR *sym; | |
941e09b6 ZW |
662 | |
663 | here = CPP_WRITTEN (pfile); | |
ba412f14 ZW |
664 | len = get_macro_name (pfile); |
665 | if (len == 0) | |
666 | return 0; | |
941e09b6 | 667 | |
ba412f14 ZW |
668 | /* Copy out the name so we can pop the token buffer. */ |
669 | len = CPP_WRITTEN (pfile) - here; | |
670 | sym = (U_CHAR *) alloca (len + 1); | |
671 | memcpy (sym, pfile->token_buffer + here, len); | |
672 | sym[len] = '\0'; | |
941e09b6 | 673 | CPP_SET_WRITTEN (pfile, here); |
7f2935c7 | 674 | |
ba412f14 ZW |
675 | /* If the next character, with no intervening whitespace, is '(', |
676 | then this is a function-like macro. */ | |
677 | c = PEEKC (); | |
678 | if (c == '(') | |
679 | funlike = 1; | |
680 | else if (c != '\n' && !is_hspace (c)) | |
681 | /* Otherwise, C99 requires white space after the name. We treat it | |
682 | as an object-like macro if this happens, with a warning. */ | |
683 | cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym); | |
684 | ||
b0699dad | 685 | def = _cpp_create_definition (pfile, funlike); |
ba412f14 | 686 | if (def == 0) |
3caee4a8 | 687 | return 0; |
7f2935c7 | 688 | |
b0699dad | 689 | if ((hp = _cpp_lookup (pfile, sym, len)) != NULL) |
7f2935c7 | 690 | { |
a2a76ce7 ZW |
691 | int ok; |
692 | ||
7f2935c7 | 693 | /* Redefining a macro is ok if the definitions are the same. */ |
a2a76ce7 | 694 | if (hp->type == T_MACRO) |
b0699dad | 695 | ok = ! _cpp_compare_defs (pfile, def, hp->value.defn); |
7f2935c7 | 696 | /* Redefining a constant is ok with -D. */ |
0961816a | 697 | else if (hp->type == T_CONST || hp->type == T_STDC) |
7f2935c7 | 698 | ok = ! CPP_OPTIONS (pfile)->done_initializing; |
a2a76ce7 ZW |
699 | /* Otherwise it's not ok. */ |
700 | else | |
701 | ok = 0; | |
fc009f96 | 702 | /* Print the warning or error if it's not ok. */ |
a2a76ce7 | 703 | if (! ok) |
7f2935c7 | 704 | { |
fc009f96 | 705 | if (hp->type == T_POISON) |
ba412f14 | 706 | cpp_error (pfile, "redefining poisoned `%.*s'", len, sym); |
fc009f96 | 707 | else |
ba412f14 | 708 | cpp_pedwarn (pfile, "`%.*s' redefined", len, sym); |
59495f38 | 709 | if (hp->type == T_MACRO && CPP_OPTIONS (pfile)->done_initializing) |
ba412f14 ZW |
710 | { |
711 | DEFINITION *d = hp->value.defn; | |
712 | cpp_pedwarn_with_file_and_line (pfile, d->file, d->line, d->col, | |
3caee4a8 | 713 | "this is the location of the previous definition"); |
ba412f14 | 714 | } |
7f2935c7 | 715 | } |
fc009f96 GK |
716 | if (hp->type != T_POISON) |
717 | { | |
718 | /* Replace the old definition. */ | |
f9ba428f | 719 | if (hp->type == T_MACRO) |
b0699dad | 720 | _cpp_free_definition (hp->value.defn); |
a2a76ce7 | 721 | hp->type = T_MACRO; |
ba412f14 | 722 | hp->value.defn = def; |
fc009f96 | 723 | } |
7f2935c7 PB |
724 | } |
725 | else | |
b0699dad | 726 | _cpp_install (pfile, sym, len, T_MACRO, (char *) def); |
3caee4a8 | 727 | |
c45da1ca ZW |
728 | if (CPP_OPTIONS (pfile)->debug_output |
729 | || CPP_OPTIONS (pfile)->dump_macros == dump_definitions) | |
b0699dad | 730 | _cpp_dump_definition (pfile, sym, len, def); |
c45da1ca ZW |
731 | else if (CPP_OPTIONS (pfile)->dump_macros == dump_names) |
732 | pass_thru_directive (sym, len, pfile, keyword); | |
7f2935c7 PB |
733 | |
734 | return 0; | |
7f2935c7 PB |
735 | } |
736 | ||
7f2935c7 | 737 | |
d013f05e PB |
738 | /* Allocate a new cpp_buffer for PFILE, and push it on the input buffer stack. |
739 | If BUFFER != NULL, then use the LENGTH characters in BUFFER | |
740 | as the new input buffer. | |
0f41302f | 741 | Return the new buffer, or NULL on failure. */ |
d013f05e | 742 | |
0f41302f | 743 | cpp_buffer * |
7f2935c7 PB |
744 | cpp_push_buffer (pfile, buffer, length) |
745 | cpp_reader *pfile; | |
746 | U_CHAR *buffer; | |
747 | long length; | |
748 | { | |
4d9a1b48 ZW |
749 | cpp_buffer *buf = CPP_BUFFER (pfile); |
750 | cpp_buffer *new; | |
751 | if (++pfile->buffer_stack_depth == CPP_STACK_MAX) | |
e2f79f3c | 752 | { |
4d9a1b48 | 753 | cpp_fatal (pfile, "macro or `#include' recursion too deep"); |
e2f79f3c PB |
754 | return NULL; |
755 | } | |
4d9a1b48 | 756 | |
236d1439 | 757 | new = (cpp_buffer *) xcalloc (1, sizeof (cpp_buffer)); |
4d9a1b48 ZW |
758 | |
759 | new->if_stack = pfile->if_stack; | |
760 | new->cleanup = null_cleanup; | |
761 | new->underflow = null_underflow; | |
762 | new->buf = new->cur = buffer; | |
763 | new->alimit = new->rlimit = buffer + length; | |
764 | new->prev = buf; | |
3fdc651f | 765 | new->mark = -1; |
ba412f14 | 766 | new->line_base = NULL; |
4d9a1b48 ZW |
767 | |
768 | CPP_BUFFER (pfile) = new; | |
769 | return new; | |
7f2935c7 PB |
770 | } |
771 | ||
0f41302f | 772 | cpp_buffer * |
7f2935c7 PB |
773 | cpp_pop_buffer (pfile) |
774 | cpp_reader *pfile; | |
775 | { | |
776 | cpp_buffer *buf = CPP_BUFFER (pfile); | |
564ad5f4 ZW |
777 | if (ACTIVE_MARK_P()) |
778 | cpp_ice (pfile, "mark active in cpp_pop_buffer"); | |
7f2935c7 | 779 | (*buf->cleanup) (buf, pfile); |
4d9a1b48 ZW |
780 | CPP_BUFFER (pfile) = CPP_PREV_BUFFER (buf); |
781 | free (buf); | |
782 | pfile->buffer_stack_depth--; | |
783 | return CPP_BUFFER (pfile); | |
7f2935c7 PB |
784 | } |
785 | ||
786 | /* Scan until CPP_BUFFER (PFILE) is exhausted into PFILE->token_buffer. | |
0f41302f | 787 | Pop the buffer when done. */ |
7f2935c7 PB |
788 | |
789 | void | |
790 | cpp_scan_buffer (pfile) | |
791 | cpp_reader *pfile; | |
792 | { | |
793 | cpp_buffer *buffer = CPP_BUFFER (pfile); | |
5d83f44b ZW |
794 | enum cpp_token token; |
795 | if (CPP_OPTIONS (pfile)->no_output) | |
7f2935c7 | 796 | { |
5d83f44b ZW |
797 | long old_written = CPP_WRITTEN (pfile); |
798 | /* In no-output mode, we can ignore everything but directives. */ | |
799 | for (;;) | |
7f2935c7 | 800 | { |
5d83f44b ZW |
801 | if (! pfile->only_seen_white) |
802 | skip_rest_of_line (pfile); | |
803 | token = cpp_get_token (pfile); | |
804 | if (token == CPP_EOF) /* Should not happen ... */ | |
805 | break; | |
806 | if (token == CPP_POP && CPP_BUFFER (pfile) == buffer) | |
807 | { | |
808 | if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) | |
809 | != CPP_NULL_BUFFER (pfile)) | |
810 | cpp_pop_buffer (pfile); | |
811 | break; | |
812 | } | |
813 | } | |
814 | CPP_SET_WRITTEN (pfile, old_written); | |
815 | } | |
816 | else | |
817 | { | |
818 | for (;;) | |
819 | { | |
820 | token = cpp_get_token (pfile); | |
821 | if (token == CPP_EOF) /* Should not happen ... */ | |
822 | break; | |
823 | if (token == CPP_POP && CPP_BUFFER (pfile) == buffer) | |
824 | { | |
825 | if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) | |
826 | != CPP_NULL_BUFFER (pfile)) | |
827 | cpp_pop_buffer (pfile); | |
828 | break; | |
829 | } | |
7f2935c7 PB |
830 | } |
831 | } | |
832 | } | |
833 | ||
834 | /* | |
782331f4 | 835 | * Rescan a string (which may have escape marks) into pfile's buffer. |
7f2935c7 PB |
836 | * Place the result in pfile->token_buffer. |
837 | * | |
838 | * The input is copied before it is scanned, so it is safe to pass | |
839 | * it something from the token_buffer that will get overwritten | |
840 | * (because it follows CPP_WRITTEN). This is used by do_include. | |
7f2935c7 PB |
841 | */ |
842 | ||
6de1e2a9 | 843 | void |
7f2935c7 PB |
844 | cpp_expand_to_buffer (pfile, buf, length) |
845 | cpp_reader *pfile; | |
bcc5cac9 | 846 | const U_CHAR *buf; |
7f2935c7 PB |
847 | int length; |
848 | { | |
849 | register cpp_buffer *ip; | |
7f2935c7 | 850 | U_CHAR *buf1; |
5d83f44b | 851 | int save_no_output; |
7f2935c7 PB |
852 | |
853 | if (length < 0) | |
34ca9541 | 854 | { |
c1212d2f | 855 | cpp_ice (pfile, "length < 0 in cpp_expand_to_buffer"); |
34ca9541 ZW |
856 | return; |
857 | } | |
7f2935c7 PB |
858 | |
859 | /* Set up the input on the input stack. */ | |
860 | ||
861 | buf1 = (U_CHAR *) alloca (length + 1); | |
5538ada6 | 862 | memcpy (buf1, buf, length); |
7f2935c7 PB |
863 | buf1[length] = 0; |
864 | ||
865 | ip = cpp_push_buffer (pfile, buf1, length); | |
e2f79f3c PB |
866 | if (ip == NULL) |
867 | return; | |
782331f4 | 868 | ip->has_escapes = 1; |
7f2935c7 PB |
869 | |
870 | /* Scan the input, create the output. */ | |
5d83f44b ZW |
871 | save_no_output = CPP_OPTIONS (pfile)->no_output; |
872 | CPP_OPTIONS (pfile)->no_output = 0; | |
c45da1ca | 873 | CPP_OPTIONS (pfile)->no_line_commands++; |
7f2935c7 | 874 | cpp_scan_buffer (pfile); |
c45da1ca | 875 | CPP_OPTIONS (pfile)->no_line_commands--; |
5d83f44b | 876 | CPP_OPTIONS (pfile)->no_output = save_no_output; |
7f2935c7 | 877 | |
7f2935c7 PB |
878 | CPP_NUL_TERMINATE (pfile); |
879 | } | |
880 | ||
7f2935c7 PB |
881 | void |
882 | cpp_buf_line_and_col (pbuf, linep, colp) | |
883 | register cpp_buffer *pbuf; | |
884 | long *linep, *colp; | |
885 | { | |
7f2935c7 PB |
886 | if (pbuf) |
887 | { | |
888 | *linep = pbuf->lineno; | |
3fdc651f ZW |
889 | if (colp) |
890 | *colp = pbuf->cur - pbuf->line_base; | |
7f2935c7 PB |
891 | } |
892 | else | |
893 | { | |
894 | *linep = 0; | |
3fdc651f ZW |
895 | if (colp) |
896 | *colp = 0; | |
7f2935c7 PB |
897 | } |
898 | } | |
899 | ||
0f41302f | 900 | /* Return the cpp_buffer that corresponds to a file (not a macro). */ |
7f2935c7 | 901 | |
0f41302f | 902 | cpp_buffer * |
7f2935c7 PB |
903 | cpp_file_buffer (pfile) |
904 | cpp_reader *pfile; | |
905 | { | |
22bbceaf | 906 | cpp_buffer *ip = CPP_BUFFER (pfile); |
7f2935c7 | 907 | |
22bbceaf | 908 | for ( ; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip)) |
7f2935c7 PB |
909 | if (ip->fname != NULL) |
910 | return ip; | |
911 | return NULL; | |
912 | } | |
913 | ||
7f2935c7 PB |
914 | /* |
915 | * write out a #line command, for instance, after an #include file. | |
7f2935c7 PB |
916 | * FILE_CHANGE says whether we are entering a file, leaving, or neither. |
917 | */ | |
918 | ||
6de1e2a9 | 919 | void |
80e9dcb4 | 920 | output_line_command (pfile, file_change) |
7f2935c7 | 921 | cpp_reader *pfile; |
7f2935c7 PB |
922 | enum file_change_code file_change; |
923 | { | |
80e9dcb4 | 924 | long line; |
c45da1ca | 925 | cpp_buffer *ip; |
7f2935c7 | 926 | |
e2f79f3c PB |
927 | if (CPP_OPTIONS (pfile)->no_line_commands |
928 | || CPP_OPTIONS (pfile)->no_output) | |
929 | return; | |
930 | ||
c45da1ca ZW |
931 | ip = cpp_file_buffer (pfile); |
932 | cpp_buf_line_and_col (ip, &line, NULL); | |
7f2935c7 | 933 | |
80e9dcb4 ZW |
934 | /* If the current file has not changed, we omit the #line if it would |
935 | appear to be a no-op, and we output a few newlines instead | |
936 | if we want to increase the line number by a small amount. | |
937 | We cannot do this if pfile->lineno is zero, because that means we | |
938 | haven't output any line commands yet. (The very first line command | |
939 | output is a `same_file' command.) */ | |
940 | if (file_change == same_file && pfile->lineno != 0) | |
3fdc651f ZW |
941 | { |
942 | if (line == pfile->lineno) | |
943 | return; | |
a8259c76 | 944 | |
3fdc651f ZW |
945 | /* If the inherited line number is a little too small, |
946 | output some newlines instead of a #line command. */ | |
947 | if (line > pfile->lineno && line < pfile->lineno + 8) | |
948 | { | |
949 | CPP_RESERVE (pfile, 20); | |
950 | while (line > pfile->lineno) | |
951 | { | |
952 | CPP_PUTC_Q (pfile, '\n'); | |
953 | pfile->lineno++; | |
954 | } | |
955 | return; | |
956 | } | |
7f2935c7 | 957 | } |
7f2935c7 PB |
958 | |
959 | CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50); | |
3fdc651f | 960 | CPP_PUTS_Q (pfile, "# ", 2); |
7f2935c7 | 961 | |
e9a25f70 | 962 | sprintf ((char *) CPP_PWRITTEN (pfile), "%ld ", line); |
7f2935c7 PB |
963 | CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile))); |
964 | ||
965 | quote_string (pfile, ip->nominal_fname); | |
656ac110 | 966 | if (file_change != same_file && file_change != rename_file) |
3fdc651f ZW |
967 | { |
968 | CPP_PUTC_Q (pfile, ' '); | |
969 | CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2'); | |
970 | } | |
7f2935c7 | 971 | /* Tell cc1 if following text comes from a system header file. */ |
3fdc651f ZW |
972 | if (ip->system_header_p) |
973 | { | |
974 | CPP_PUTC_Q (pfile, ' '); | |
975 | CPP_PUTC_Q (pfile, '3'); | |
976 | } | |
7f2935c7 PB |
977 | #ifndef NO_IMPLICIT_EXTERN_C |
978 | /* Tell cc1plus if following text should be treated as C. */ | |
3fdc651f ZW |
979 | if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus) |
980 | { | |
981 | CPP_PUTC_Q (pfile, ' '); | |
982 | CPP_PUTC_Q (pfile, '4'); | |
983 | } | |
7f2935c7 PB |
984 | #endif |
985 | CPP_PUTC_Q (pfile, '\n'); | |
986 | pfile->lineno = line; | |
987 | } | |
6de1e2a9 ZW |
988 | |
989 | ||
990 | /* Like cpp_get_token, except that it does not read past end-of-line. | |
991 | Also, horizontal space is skipped, and macros are popped. */ | |
7f2935c7 | 992 | |
cf4ed945 | 993 | enum cpp_token |
6de1e2a9 | 994 | get_directive_token (pfile) |
7f2935c7 | 995 | cpp_reader *pfile; |
7f2935c7 | 996 | { |
eaefae0e ZW |
997 | long old_written = CPP_WRITTEN (pfile); |
998 | enum cpp_token token; | |
999 | ||
7f2935c7 PB |
1000 | for (;;) |
1001 | { | |
6de1e2a9 ZW |
1002 | cpp_skip_hspace (pfile); |
1003 | if (PEEKC () == '\n') | |
eaefae0e ZW |
1004 | return CPP_VSPACE; |
1005 | ||
7f2935c7 | 1006 | token = cpp_get_token (pfile); |
eaefae0e ZW |
1007 | /* token could be hspace at the beginning of a macro. */ |
1008 | if (token == CPP_HSPACE || token == CPP_COMMENT) | |
1009 | { | |
6de1e2a9 | 1010 | CPP_SET_WRITTEN (pfile, old_written); |
eaefae0e ZW |
1011 | continue; |
1012 | } | |
1013 | ||
1014 | /* token cannot be vspace, it would have been caught above. */ | |
1015 | if (token == CPP_VSPACE) | |
1016 | { | |
c1212d2f | 1017 | cpp_ice (pfile, "VSPACE in get_directive_token"); |
6de1e2a9 | 1018 | return token; |
eaefae0e ZW |
1019 | } |
1020 | ||
1021 | /* token cannot be POP unless the buffer is a macro buffer. */ | |
1022 | if (token != CPP_POP) | |
1023 | return token; | |
1024 | ||
1025 | if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) | |
1026 | { | |
c1212d2f | 1027 | cpp_ice (pfile, "POP of file buffer in get_directive_token"); |
eaefae0e ZW |
1028 | return token; |
1029 | } | |
1030 | ||
c1212d2f ZW |
1031 | /* We must pop the buffer by hand, or else cpp_get_token might |
1032 | hand us white space or newline on the next invocation. */ | |
eaefae0e | 1033 | cpp_pop_buffer (pfile); |
7f2935c7 | 1034 | } |
7f2935c7 PB |
1035 | } |
1036 | \f | |
6de1e2a9 ZW |
1037 | /* Handle #include and #import. |
1038 | This function expects to see "fname" or <fname> on the input. | |
1039 | ||
1040 | The input is normally in part of the output_buffer following | |
1041 | CPP_WRITTEN, and will get overwritten by output_line_command. | |
1042 | I.e. in input file specification has been popped by handle_directive. | |
1043 | This is safe. */ | |
7f2935c7 PB |
1044 | |
1045 | static int | |
6de1e2a9 | 1046 | do_include (pfile, keyword) |
7f2935c7 | 1047 | cpp_reader *pfile; |
2ac9349e | 1048 | const struct directive *keyword; |
7f2935c7 | 1049 | { |
6de1e2a9 ZW |
1050 | int importing = (keyword->type == T_IMPORT); |
1051 | int skip_dirs = (keyword->type == T_INCLUDE_NEXT); | |
1052 | int angle_brackets = 0; /* 0 for "...", 1 for <...> */ | |
1053 | int before; /* included before? */ | |
1054 | long flen; | |
3caee4a8 | 1055 | unsigned char *ftok; |
6de1e2a9 | 1056 | cpp_buffer *fp; |
7f2935c7 | 1057 | |
6de1e2a9 | 1058 | enum cpp_token token; |
7f2935c7 | 1059 | |
6de1e2a9 ZW |
1060 | /* Chain of dirs to search */ |
1061 | struct include_hash *ihash; | |
1062 | struct file_name_list *search_start; | |
1063 | ||
1064 | long old_written = CPP_WRITTEN (pfile); | |
7f2935c7 | 1065 | |
6de1e2a9 | 1066 | int fd; |
7f2935c7 | 1067 | |
83ecd27e | 1068 | if (CPP_PEDANTIC (pfile)) |
7f2935c7 | 1069 | { |
6de1e2a9 ZW |
1070 | if (importing) |
1071 | cpp_pedwarn (pfile, "ANSI C does not allow `#import'"); | |
1072 | if (skip_dirs) | |
1073 | cpp_pedwarn (pfile, "ANSI C does not allow `#include_next'"); | |
1074 | } | |
7f2935c7 | 1075 | |
6de1e2a9 ZW |
1076 | if (importing && CPP_OPTIONS (pfile)->warn_import |
1077 | && !CPP_OPTIONS (pfile)->inhibit_warnings | |
1078 | && !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning) | |
1079 | { | |
1080 | pfile->import_warning = 1; | |
3caee4a8 ZW |
1081 | cpp_warning (pfile, |
1082 | "#import is obsolete, use an #ifndef wrapper in the header file"); | |
6de1e2a9 | 1083 | } |
7f2935c7 | 1084 | |
6de1e2a9 ZW |
1085 | pfile->parsing_include_directive++; |
1086 | token = get_directive_token (pfile); | |
1087 | pfile->parsing_include_directive--; | |
7f2935c7 | 1088 | |
6de1e2a9 ZW |
1089 | if (token == CPP_STRING) |
1090 | { | |
3caee4a8 ZW |
1091 | if (pfile->token_buffer[old_written] == '<') |
1092 | angle_brackets = 1; | |
6de1e2a9 ZW |
1093 | } |
1094 | #ifdef VMS | |
1095 | else if (token == CPP_NAME) | |
1096 | { | |
3caee4a8 ZW |
1097 | /* Support '#include xyz' like VAX-C. It is taken as |
1098 | '#include <xyz.h>' and generates a warning. */ | |
6de1e2a9 | 1099 | cpp_warning (pfile, |
3caee4a8 | 1100 | "`#include filename' is obsolete, use `#include <filename.h>'"); |
6de1e2a9 | 1101 | angle_brackets = 1; |
7f2935c7 | 1102 | |
6de1e2a9 | 1103 | /* Append the missing `.h' to the name. */ |
3caee4a8 | 1104 | CPP_PUTS (pfile, ".h", 2); |
7f2935c7 | 1105 | } |
5dfa4da1 | 1106 | #endif |
6de1e2a9 | 1107 | else |
7f2935c7 | 1108 | { |
6de1e2a9 ZW |
1109 | cpp_error (pfile, |
1110 | "`#%s' expects \"FILENAME\" or <FILENAME>", keyword->name); | |
1111 | CPP_SET_WRITTEN (pfile, old_written); | |
1112 | skip_rest_of_line (pfile); | |
1113 | return 0; | |
7f2935c7 | 1114 | } |
7f2935c7 | 1115 | |
3caee4a8 | 1116 | flen = CPP_WRITTEN (pfile) - old_written; |
e7553be5 | 1117 | ftok = (unsigned char *) alloca (flen + 1); |
3caee4a8 ZW |
1118 | memcpy (ftok, pfile->token_buffer + old_written, flen); |
1119 | ftok[flen] = '\0'; | |
1120 | ||
1121 | if (get_directive_token (pfile) != CPP_VSPACE) | |
7f2935c7 | 1122 | { |
6de1e2a9 ZW |
1123 | cpp_error (pfile, "junk at end of `#include'"); |
1124 | skip_rest_of_line (pfile); | |
7f2935c7 | 1125 | } |
7f2935c7 | 1126 | |
6de1e2a9 | 1127 | CPP_SET_WRITTEN (pfile, old_written); |
7f2935c7 | 1128 | |
6de1e2a9 ZW |
1129 | if (flen == 0) |
1130 | { | |
1131 | cpp_error (pfile, "empty file name in `#%s'", keyword->name); | |
1132 | return 0; | |
1133 | } | |
7f2935c7 | 1134 | |
3caee4a8 ZW |
1135 | if (CPP_OPTIONS (pfile)->dump_includes) |
1136 | pass_thru_directive (ftok, | |
1137 | flen | |
1138 | #ifdef VMS | |
1139 | - ((token == CPP_NAME) ? 2 : 0) | |
1140 | #endif | |
1141 | , pfile, keyword); | |
1142 | ||
1143 | #ifdef VMS | |
1144 | if (token == CPP_STRING) | |
1145 | #endif | |
1146 | { | |
1147 | ftok++; | |
1148 | flen -= 2; | |
1149 | ftok[flen] = '\0'; | |
1150 | } | |
1151 | ||
6de1e2a9 | 1152 | search_start = 0; |
7f2935c7 | 1153 | |
6de1e2a9 ZW |
1154 | for (fp = CPP_BUFFER (pfile); |
1155 | fp != CPP_NULL_BUFFER (pfile); | |
1156 | fp = CPP_PREV_BUFFER (fp)) | |
1157 | if (fp->fname != NULL) | |
1158 | break; | |
e8037d57 | 1159 | |
6de1e2a9 | 1160 | if (fp == CPP_NULL_BUFFER (pfile)) |
20dc7361 | 1161 | { |
c1212d2f | 1162 | cpp_ice (pfile, "fp == NULL_BUFFER in do_include"); |
3caee4a8 | 1163 | return 0; |
20dc7361 | 1164 | } |
6de1e2a9 ZW |
1165 | |
1166 | /* For #include_next, skip in the search path past the dir in which the | |
1167 | containing file was found. Treat files specified using an absolute path | |
1168 | as if there are no more directories to search. Treat the primary source | |
1169 | file like any other included source, but generate a warning. */ | |
1170 | if (skip_dirs && CPP_PREV_BUFFER(fp) != CPP_NULL_BUFFER (pfile)) | |
7f2935c7 | 1171 | { |
6de1e2a9 ZW |
1172 | if (fp->ihash->foundhere != ABSOLUTE_PATH) |
1173 | search_start = fp->ihash->foundhere->next; | |
1174 | } | |
1175 | else | |
1176 | { | |
1177 | if (skip_dirs) | |
1178 | cpp_warning (pfile, "#include_next in primary source file"); | |
1179 | ||
1180 | if (angle_brackets) | |
1181 | search_start = CPP_OPTIONS (pfile)->bracket_include; | |
1182 | else | |
1183 | { | |
1184 | if (!CPP_OPTIONS (pfile)->ignore_srcdir) | |
7f2935c7 | 1185 | { |
6de1e2a9 ZW |
1186 | if (fp) |
1187 | search_start = fp->actual_dir; | |
7f2935c7 | 1188 | } |
7f2935c7 | 1189 | else |
6de1e2a9 | 1190 | search_start = CPP_OPTIONS (pfile)->quote_include; |
7f2935c7 PB |
1191 | } |
1192 | } | |
1193 | ||
6de1e2a9 | 1194 | if (!search_start) |
7f2935c7 | 1195 | { |
3caee4a8 | 1196 | cpp_error (pfile, "No include path in which to find %s", ftok); |
6de1e2a9 | 1197 | return 0; |
7f2935c7 | 1198 | } |
7f2935c7 | 1199 | |
b0699dad | 1200 | fd = _cpp_find_include_file (pfile, ftok, search_start, &ihash, &before); |
7f2935c7 | 1201 | |
6de1e2a9 ZW |
1202 | if (fd == -2) |
1203 | return 0; | |
1204 | ||
1205 | if (fd == -1) | |
1206 | { | |
1207 | if (CPP_OPTIONS (pfile)->print_deps_missing_files | |
1208 | && CPP_PRINT_DEPS (pfile) > (angle_brackets || | |
1209 | (pfile->system_include_depth > 0))) | |
1210 | { | |
1211 | if (!angle_brackets) | |
49e6c08e | 1212 | deps_add_dep (pfile->deps, ftok); |
6de1e2a9 | 1213 | else |
7f2935c7 | 1214 | { |
6de1e2a9 ZW |
1215 | char *p; |
1216 | struct file_name_list *ptr; | |
1217 | /* If requested as a system header, assume it belongs in | |
1218 | the first system header directory. */ | |
1219 | if (CPP_OPTIONS (pfile)->bracket_include) | |
1220 | ptr = CPP_OPTIONS (pfile)->bracket_include; | |
1221 | else | |
1222 | ptr = CPP_OPTIONS (pfile)->quote_include; | |
7f2935c7 | 1223 | |
6de1e2a9 | 1224 | p = (char *) alloca (strlen (ptr->name) |
3caee4a8 | 1225 | + strlen (ftok) + 2); |
6de1e2a9 ZW |
1226 | if (*ptr->name != '\0') |
1227 | { | |
1228 | strcpy (p, ptr->name); | |
1229 | strcat (p, "/"); | |
1230 | } | |
3caee4a8 | 1231 | strcat (p, ftok); |
49e6c08e | 1232 | deps_add_dep (pfile->deps, p); |
7f2935c7 | 1233 | } |
7f2935c7 | 1234 | } |
6de1e2a9 ZW |
1235 | /* If -M was specified, and this header file won't be added to |
1236 | the dependency list, then don't count this as an error, | |
1237 | because we can still produce correct output. Otherwise, we | |
1238 | can't produce correct output, because there may be | |
1239 | dependencies we need inside the missing file, and we don't | |
1240 | know what directory this missing file exists in. */ | |
1241 | else if (CPP_PRINT_DEPS (pfile) | |
1242 | && (CPP_PRINT_DEPS (pfile) | |
1243 | <= (angle_brackets || (pfile->system_include_depth > 0)))) | |
3caee4a8 | 1244 | cpp_warning (pfile, "No include path in which to find %s", ftok); |
6de1e2a9 | 1245 | else |
3caee4a8 | 1246 | cpp_error_from_errno (pfile, ftok); |
7f2935c7 | 1247 | |
6de1e2a9 ZW |
1248 | return 0; |
1249 | } | |
7f2935c7 | 1250 | |
6de1e2a9 ZW |
1251 | /* For -M, add the file to the dependencies on its first inclusion. */ |
1252 | if (!before && (CPP_PRINT_DEPS (pfile) | |
1253 | > (angle_brackets || (pfile->system_include_depth > 0)))) | |
49e6c08e | 1254 | deps_add_dep (pfile->deps, ihash->name); |
7f2935c7 | 1255 | |
6de1e2a9 ZW |
1256 | /* Handle -H option. */ |
1257 | if (CPP_OPTIONS(pfile)->print_include_names) | |
1258 | { | |
1259 | fp = CPP_BUFFER (pfile); | |
1260 | while ((fp = CPP_PREV_BUFFER (fp)) != CPP_NULL_BUFFER (pfile)) | |
1261 | putc ('.', stderr); | |
1262 | fprintf (stderr, " %s\n", ihash->name); | |
7f2935c7 PB |
1263 | } |
1264 | ||
6de1e2a9 | 1265 | /* Actually process the file */ |
7f2935c7 | 1266 | |
6de1e2a9 ZW |
1267 | if (importing) |
1268 | ihash->control_macro = ""; | |
7f2935c7 | 1269 | |
6de1e2a9 | 1270 | if (cpp_push_buffer (pfile, NULL, 0) == NULL) |
20dc7361 | 1271 | { |
6de1e2a9 ZW |
1272 | close (fd); |
1273 | return 0; | |
20dc7361 | 1274 | } |
6de1e2a9 ZW |
1275 | |
1276 | if (angle_brackets) | |
1277 | pfile->system_include_depth++; /* Decremented in file_cleanup. */ | |
7f2935c7 | 1278 | |
b0699dad | 1279 | if (_cpp_read_include_file (pfile, fd, ihash)) |
7f2935c7 | 1280 | { |
80e9dcb4 | 1281 | output_line_command (pfile, enter_file); |
6de1e2a9 | 1282 | pfile->only_seen_white = 2; |
7f2935c7 | 1283 | } |
6de1e2a9 ZW |
1284 | |
1285 | return 0; | |
7f2935c7 | 1286 | } |
7f2935c7 | 1287 | |
d3a34a0a JM |
1288 | /* Subroutine of do_line. Read next token from PFILE without adding it to |
1289 | the output buffer. If it is a number between 1 and 4, store it in *NUM | |
1290 | and return 1; otherwise, return 0 and complain if we aren't at the end | |
1291 | of the directive. */ | |
1292 | ||
1293 | static int | |
1294 | read_line_number (pfile, num) | |
1295 | cpp_reader *pfile; | |
1296 | int *num; | |
1297 | { | |
1298 | long save_written = CPP_WRITTEN (pfile); | |
1299 | U_CHAR *p = pfile->token_buffer + save_written; | |
1300 | enum cpp_token token = get_directive_token (pfile); | |
1301 | CPP_SET_WRITTEN (pfile, save_written); | |
1302 | ||
1303 | if (token == CPP_NUMBER && *p >= '1' && *p <= '4' && p[1] == '\0') | |
1304 | { | |
1305 | *num = p[0] - '0'; | |
1306 | return 1; | |
1307 | } | |
1308 | else | |
1309 | { | |
ba412f14 | 1310 | if (token != CPP_VSPACE && token != CPP_EOF) |
d3a34a0a JM |
1311 | cpp_error (pfile, "invalid format `#line' command"); |
1312 | return 0; | |
1313 | } | |
1314 | } | |
1315 | ||
6de1e2a9 ZW |
1316 | /* Interpret #line command. |
1317 | Note that the filename string (if any) is treated as if it were an | |
1318 | include filename. That means no escape handling. */ | |
7f2935c7 PB |
1319 | |
1320 | static int | |
6de1e2a9 | 1321 | do_line (pfile, keyword) |
7f2935c7 | 1322 | cpp_reader *pfile; |
2ac9349e | 1323 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1324 | { |
6de1e2a9 ZW |
1325 | cpp_buffer *ip = CPP_BUFFER (pfile); |
1326 | int new_lineno; | |
7f2935c7 | 1327 | long old_written = CPP_WRITTEN (pfile); |
6de1e2a9 ZW |
1328 | enum file_change_code file_change = same_file; |
1329 | enum cpp_token token; | |
1330 | char *x; | |
7f2935c7 | 1331 | |
6de1e2a9 | 1332 | token = get_directive_token (pfile); |
7f2935c7 | 1333 | |
6de1e2a9 | 1334 | if (token != CPP_NUMBER) |
cfb3ee16 | 1335 | { |
6de1e2a9 ZW |
1336 | cpp_error (pfile, "token after `#line' is not an integer"); |
1337 | goto bad_line_directive; | |
cfb3ee16 RK |
1338 | } |
1339 | ||
6de1e2a9 ZW |
1340 | new_lineno = strtol (pfile->token_buffer + old_written, &x, 10); |
1341 | if (x[0] != '\0') | |
7f2935c7 | 1342 | { |
6de1e2a9 ZW |
1343 | cpp_error (pfile, "token after `#line' is not an integer"); |
1344 | goto bad_line_directive; | |
1345 | } | |
1346 | CPP_SET_WRITTEN (pfile, old_written); | |
1347 | ||
7113a160 | 1348 | if (CPP_PEDANTIC (pfile) && (new_lineno <= 0 || new_lineno > 32767)) |
6de1e2a9 | 1349 | cpp_pedwarn (pfile, "line number out of range in `#line' command"); |
7f2935c7 | 1350 | |
7f2935c7 | 1351 | token = get_directive_token (pfile); |
7f2935c7 PB |
1352 | |
1353 | if (token == CPP_STRING) | |
1354 | { | |
6de1e2a9 ZW |
1355 | U_CHAR *fname = pfile->token_buffer + old_written + 1; |
1356 | U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1; | |
d3a34a0a | 1357 | int action_number = 0; |
add7091b | 1358 | |
656ac110 AO |
1359 | file_change = rename_file; |
1360 | ||
d3a34a0a | 1361 | if (read_line_number (pfile, &action_number)) |
6de1e2a9 | 1362 | { |
6de1e2a9 ZW |
1363 | if (CPP_PEDANTIC (pfile)) |
1364 | cpp_pedwarn (pfile, "garbage at end of `#line' command"); | |
add7091b | 1365 | |
d3a34a0a JM |
1366 | if (action_number == 1) |
1367 | { | |
1368 | file_change = enter_file; | |
1369 | read_line_number (pfile, &action_number); | |
1370 | } | |
1371 | else if (action_number == 2) | |
6de1e2a9 | 1372 | { |
d3a34a0a JM |
1373 | file_change = leave_file; |
1374 | read_line_number (pfile, &action_number); | |
6de1e2a9 | 1375 | } |
d3a34a0a | 1376 | if (action_number == 3) |
5538ada6 | 1377 | { |
d3a34a0a JM |
1378 | ip->system_header_p = 1; |
1379 | read_line_number (pfile, &action_number); | |
5538ada6 | 1380 | } |
d3a34a0a | 1381 | if (action_number == 4) |
5538ada6 | 1382 | { |
d3a34a0a JM |
1383 | ip->system_header_p = 2; |
1384 | read_line_number (pfile, &action_number); | |
5538ada6 ZW |
1385 | } |
1386 | } | |
1387 | ||
1388 | *end_name = '\0'; | |
1389 | ||
1390 | if (strcmp (fname, ip->nominal_fname)) | |
1391 | { | |
a9ae4483 | 1392 | const char *newname, *oldname; |
5538ada6 ZW |
1393 | if (!strcmp (fname, ip->fname)) |
1394 | newname = ip->fname; | |
1395 | else if (ip->last_nominal_fname | |
1396 | && !strcmp (fname, ip->last_nominal_fname)) | |
1397 | newname = ip->last_nominal_fname; | |
1398 | else | |
1399 | newname = xstrdup (fname); | |
7f2935c7 | 1400 | |
5538ada6 ZW |
1401 | oldname = ip->nominal_fname; |
1402 | ip->nominal_fname = newname; | |
7f2935c7 | 1403 | |
5538ada6 ZW |
1404 | if (ip->last_nominal_fname |
1405 | && ip->last_nominal_fname != oldname | |
4d9a1b48 ZW |
1406 | && ip->last_nominal_fname != newname |
1407 | && ip->last_nominal_fname != ip->fname) | |
a9ae4483 | 1408 | free ((void *) ip->last_nominal_fname); |
5538ada6 ZW |
1409 | |
1410 | if (newname == ip->fname) | |
1411 | ip->last_nominal_fname = NULL; | |
1412 | else | |
1413 | ip->last_nominal_fname = oldname; | |
1414 | } | |
7f2935c7 | 1415 | } |
5538ada6 ZW |
1416 | else if (token != CPP_VSPACE && token != CPP_EOF) |
1417 | { | |
1418 | cpp_error (pfile, "token after `#line %d' is not a string", new_lineno); | |
1419 | goto bad_line_directive; | |
1420 | } | |
1421 | ||
1422 | /* The Newline at the end of this line remains to be processed. | |
1423 | To put the next line at the specified line number, | |
1424 | we must store a line number now that is one less. */ | |
1425 | ip->lineno = new_lineno - 1; | |
1426 | CPP_SET_WRITTEN (pfile, old_written); | |
80e9dcb4 | 1427 | output_line_command (pfile, file_change); |
5538ada6 | 1428 | return 0; |
7f2935c7 | 1429 | |
7f2935c7 PB |
1430 | bad_line_directive: |
1431 | skip_rest_of_line (pfile); | |
1432 | CPP_SET_WRITTEN (pfile, old_written); | |
7f2935c7 PB |
1433 | return 0; |
1434 | } | |
1435 | ||
5538ada6 ZW |
1436 | /* Remove the definition of a symbol from the symbol table. |
1437 | According to the C standard, it is not an error to undef | |
1438 | something that has no definitions. */ | |
7f2935c7 | 1439 | static int |
941e09b6 | 1440 | do_undef (pfile, keyword) |
7f2935c7 | 1441 | cpp_reader *pfile; |
2ac9349e | 1442 | const struct directive *keyword; |
7f2935c7 | 1443 | { |
a2a76ce7 | 1444 | int len; |
7f2935c7 | 1445 | HASHNODE *hp; |
941e09b6 ZW |
1446 | U_CHAR *buf, *name, *limit; |
1447 | int c; | |
1448 | long here = CPP_WRITTEN (pfile); | |
1449 | enum cpp_token token; | |
1450 | ||
1451 | cpp_skip_hspace (pfile); | |
1452 | c = GETC(); | |
a9ae4483 | 1453 | if (! is_idstart(c)) |
941e09b6 ZW |
1454 | { |
1455 | cpp_error (pfile, "token after #undef is not an identifier"); | |
1456 | skip_rest_of_line (pfile); | |
1457 | return 1; | |
1458 | } | |
1459 | ||
1460 | parse_name (pfile, c); | |
1461 | buf = pfile->token_buffer + here; | |
1462 | limit = CPP_PWRITTEN(pfile); | |
1463 | ||
1464 | /* Copy out the token so we can pop the token buffer. */ | |
a2a76ce7 ZW |
1465 | len = limit - buf; |
1466 | name = (U_CHAR *) alloca (len + 1); | |
1467 | memcpy (name, buf, len); | |
ba412f14 | 1468 | name[len] = '\0'; |
941e09b6 ZW |
1469 | |
1470 | token = get_directive_token (pfile); | |
ba412f14 | 1471 | if (token != CPP_VSPACE) |
941e09b6 ZW |
1472 | { |
1473 | cpp_pedwarn (pfile, "junk on line after #undef"); | |
1474 | skip_rest_of_line (pfile); | |
1475 | } | |
941e09b6 | 1476 | CPP_SET_WRITTEN (pfile, here); |
7f2935c7 | 1477 | |
b0699dad | 1478 | while ((hp = _cpp_lookup (pfile, name, len)) != NULL) |
7f2935c7 PB |
1479 | { |
1480 | /* If we are generating additional info for debugging (with -g) we | |
1481 | need to pass through all effective #undef commands. */ | |
1482 | if (CPP_OPTIONS (pfile)->debug_output && keyword) | |
a2a76ce7 | 1483 | pass_thru_directive (name, len, pfile, keyword); |
fc009f96 GK |
1484 | if (hp->type == T_POISON) |
1485 | cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name); | |
1486 | else | |
1487 | { | |
1488 | if (hp->type != T_MACRO) | |
1489 | cpp_warning (pfile, "undefining `%s'", hp->name); | |
b0699dad | 1490 | _cpp_delete_macro (hp); |
fc009f96 | 1491 | } |
7f2935c7 PB |
1492 | } |
1493 | ||
7f2935c7 PB |
1494 | return 0; |
1495 | } | |
941e09b6 ZW |
1496 | |
1497 | /* Wrap do_undef for -U processing. */ | |
6de1e2a9 | 1498 | void |
941e09b6 ZW |
1499 | cpp_undef (pfile, macro) |
1500 | cpp_reader *pfile; | |
1501 | U_CHAR *macro; | |
1502 | { | |
2387c1d4 ZW |
1503 | /* Copy the string so we can append a newline. */ |
1504 | size_t len = strlen (macro); | |
1505 | U_CHAR *buf = alloca (len + 2); | |
1506 | memcpy (buf, macro, len); | |
1507 | buf[len] = '\n'; | |
1508 | buf[len + 1] = '\0'; | |
1509 | if (cpp_push_buffer (pfile, buf, len + 1)) | |
941e09b6 | 1510 | { |
6de1e2a9 ZW |
1511 | do_undef (pfile, NULL); |
1512 | cpp_pop_buffer (pfile); | |
941e09b6 ZW |
1513 | } |
1514 | } | |
1515 | ||
7f2935c7 PB |
1516 | /* |
1517 | * Report an error detected by the program we are processing. | |
1518 | * Use the text of the line in the error message. | |
1519 | * (We use error because it prints the filename & line#.) | |
1520 | */ | |
1521 | ||
1522 | static int | |
941e09b6 | 1523 | do_error (pfile, keyword) |
7f2935c7 | 1524 | cpp_reader *pfile; |
2ac9349e | 1525 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1526 | { |
a2a76ce7 | 1527 | U_CHAR *text, *limit; |
941e09b6 | 1528 | |
a2a76ce7 ZW |
1529 | cpp_skip_hspace (pfile); |
1530 | text = CPP_BUFFER (pfile)->cur; | |
1531 | skip_rest_of_line (pfile); | |
1532 | limit = CPP_BUFFER (pfile)->cur; | |
1533 | ||
1534 | cpp_error (pfile, "#error %.*s", (int)(limit - text), text); | |
7f2935c7 PB |
1535 | return 0; |
1536 | } | |
1537 | ||
1538 | /* | |
1539 | * Report a warning detected by the program we are processing. | |
1540 | * Use the text of the line in the warning message, then continue. | |
7f2935c7 PB |
1541 | */ |
1542 | ||
1543 | static int | |
941e09b6 | 1544 | do_warning (pfile, keyword) |
7f2935c7 | 1545 | cpp_reader *pfile; |
2ac9349e | 1546 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1547 | { |
a2a76ce7 ZW |
1548 | U_CHAR *text, *limit; |
1549 | ||
1550 | cpp_skip_hspace (pfile); | |
1551 | text = CPP_BUFFER (pfile)->cur; | |
1552 | skip_rest_of_line (pfile); | |
1553 | limit = CPP_BUFFER (pfile)->cur; | |
f5963e61 | 1554 | |
83ecd27e | 1555 | if (CPP_PEDANTIC (pfile)) |
487a6e06 | 1556 | cpp_pedwarn (pfile, "ANSI C does not allow `#warning'"); |
f5963e61 | 1557 | |
a2a76ce7 | 1558 | cpp_warning (pfile, "#warning %.*s", (int)(limit - text), text); |
7f2935c7 PB |
1559 | return 0; |
1560 | } | |
1561 | ||
a2a76ce7 | 1562 | /* Report program identification. */ |
7f2935c7 PB |
1563 | |
1564 | static int | |
941e09b6 | 1565 | do_ident (pfile, keyword) |
7f2935c7 | 1566 | cpp_reader *pfile; |
2ac9349e | 1567 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1568 | { |
a2a76ce7 ZW |
1569 | long old_written = CPP_WRITTEN (pfile); |
1570 | ||
7f2935c7 | 1571 | /* Allow #ident in system headers, since that's not user's fault. */ |
83ecd27e | 1572 | if (CPP_PEDANTIC (pfile)) |
7f2935c7 PB |
1573 | cpp_pedwarn (pfile, "ANSI C does not allow `#ident'"); |
1574 | ||
3caee4a8 | 1575 | CPP_PUTS (pfile, "#ident ", 7); |
a2a76ce7 ZW |
1576 | |
1577 | /* Next token should be a string constant. */ | |
1578 | if (get_directive_token (pfile) == CPP_STRING) | |
1579 | /* And then a newline. */ | |
1580 | if (get_directive_token (pfile) == CPP_VSPACE) | |
1581 | /* Good - ship it. */ | |
1582 | return 0; | |
1583 | ||
1584 | cpp_error (pfile, "invalid #ident"); | |
1585 | skip_rest_of_line (pfile); | |
1586 | CPP_SET_WRITTEN (pfile, old_written); /* discard directive */ | |
7f2935c7 PB |
1587 | |
1588 | return 0; | |
1589 | } | |
1590 | ||
a2a76ce7 ZW |
1591 | /* Pragmata handling. We handle some of these, and pass the rest on |
1592 | to the front end. C99 defines three pragmas and says that no macro | |
1593 | expansion is to be performed on them; whether or not macro | |
1594 | expansion happens for other pragmas is implementation defined. | |
1595 | This implementation never macro-expands the text after #pragma. | |
1596 | ||
1597 | We currently do not support the _Pragma operator. Support for that | |
1598 | has to be coordinated with the front end. Proposed implementation: | |
1599 | both #pragma blah blah and _Pragma("blah blah") become | |
1600 | __builtin_pragma(blah blah) and we teach the parser about that. */ | |
1601 | ||
1602 | /* Sub-handlers for the pragmas needing treatment here. | |
1603 | They return 1 if the token buffer is to be popped, 0 if not. */ | |
1604 | static int do_pragma_once PARAMS ((cpp_reader *)); | |
1605 | static int do_pragma_implementation PARAMS ((cpp_reader *)); | |
1606 | static int do_pragma_poison PARAMS ((cpp_reader *)); | |
1607 | static int do_pragma_default PARAMS ((cpp_reader *)); | |
7f2935c7 PB |
1608 | |
1609 | static int | |
941e09b6 | 1610 | do_pragma (pfile, keyword) |
7f2935c7 | 1611 | cpp_reader *pfile; |
2ac9349e | 1612 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1613 | { |
a2a76ce7 | 1614 | long here, key; |
941e09b6 | 1615 | U_CHAR *buf; |
a2a76ce7 | 1616 | int pop; |
0172e2bc | 1617 | enum cpp_token token; |
3caee4a8 | 1618 | |
3caee4a8 | 1619 | here = CPP_WRITTEN (pfile); |
a2a76ce7 | 1620 | CPP_PUTS (pfile, "#pragma ", 8); |
add7091b | 1621 | |
a2a76ce7 ZW |
1622 | key = CPP_WRITTEN (pfile); |
1623 | pfile->no_macro_expand++; | |
0172e2bc AO |
1624 | token = get_directive_token (pfile); |
1625 | if (token != CPP_NAME) | |
1626 | { | |
1627 | if (token == CPP_VSPACE) | |
1628 | goto empty; | |
1629 | else | |
1630 | goto skip; | |
1631 | } | |
a2a76ce7 ZW |
1632 | |
1633 | buf = pfile->token_buffer + key; | |
1634 | CPP_PUTC (pfile, ' '); | |
1635 | ||
1636 | #define tokis(x) !strncmp(buf, x, sizeof(x) - 1) | |
1637 | if (tokis ("once")) | |
1638 | pop = do_pragma_once (pfile); | |
1639 | else if (tokis ("implementation")) | |
1640 | pop = do_pragma_implementation (pfile); | |
1641 | else if (tokis ("poison")) | |
1642 | pop = do_pragma_poison (pfile); | |
1643 | else | |
1644 | pop = do_pragma_default (pfile); | |
1645 | #undef tokis | |
7f2935c7 | 1646 | |
a2a76ce7 ZW |
1647 | if (get_directive_token (pfile) != CPP_VSPACE) |
1648 | goto skip; | |
1649 | ||
1650 | if (pop) | |
1651 | CPP_SET_WRITTEN (pfile, here); | |
1652 | pfile->no_macro_expand--; | |
1653 | return 0; | |
1654 | ||
1655 | skip: | |
1656 | cpp_error (pfile, "malformed #pragma directive"); | |
1657 | skip_rest_of_line (pfile); | |
0172e2bc | 1658 | empty: |
a2a76ce7 ZW |
1659 | CPP_SET_WRITTEN (pfile, here); |
1660 | pfile->no_macro_expand--; | |
1661 | return 0; | |
1662 | } | |
1663 | ||
1664 | static int | |
1665 | do_pragma_default (pfile) | |
1666 | cpp_reader *pfile; | |
1667 | { | |
1668 | while (get_directive_token (pfile) != CPP_VSPACE) | |
1669 | CPP_PUTC (pfile, ' '); | |
1670 | return 0; | |
1671 | } | |
1672 | ||
1673 | static int | |
1674 | do_pragma_once (pfile) | |
1675 | cpp_reader *pfile; | |
1676 | { | |
1677 | cpp_buffer *ip = CPP_BUFFER (pfile); | |
1678 | ||
1679 | if (ip->fname == NULL) | |
0b3d776a | 1680 | { |
a2a76ce7 ZW |
1681 | cpp_ice (pfile, "ip->fname == NULL in do_pragma_once"); |
1682 | return 1; | |
7f2935c7 | 1683 | } |
a2a76ce7 ZW |
1684 | |
1685 | /* Allow #pragma once in system headers, since that's not the user's | |
1686 | fault. */ | |
1687 | if (!ip->system_header_p) | |
1688 | cpp_warning (pfile, "`#pragma once' is obsolete"); | |
1689 | ||
1690 | if (CPP_PREV_BUFFER (ip) == CPP_NULL_BUFFER (pfile)) | |
1691 | cpp_warning (pfile, "`#pragma once' outside include file"); | |
1692 | else | |
1693 | ip->ihash->control_macro = ""; /* never repeat */ | |
fc009f96 | 1694 | |
a2a76ce7 ZW |
1695 | return 1; |
1696 | } | |
fc009f96 | 1697 | |
a2a76ce7 ZW |
1698 | static int |
1699 | do_pragma_implementation (pfile) | |
1700 | cpp_reader *pfile; | |
1701 | { | |
1702 | /* Be quiet about `#pragma implementation' for a file only if it hasn't | |
1703 | been included yet. */ | |
a2a76ce7 ZW |
1704 | enum cpp_token token; |
1705 | long written = CPP_WRITTEN (pfile); | |
1706 | U_CHAR *name; | |
1707 | U_CHAR *copy; | |
fc009f96 | 1708 | |
a2a76ce7 ZW |
1709 | token = get_directive_token (pfile); |
1710 | if (token == CPP_VSPACE) | |
1711 | return 0; | |
1712 | else if (token != CPP_STRING) | |
1713 | { | |
1714 | cpp_error (pfile, "malformed #pragma implementation"); | |
1715 | return 1; | |
1716 | } | |
fc009f96 | 1717 | |
a2a76ce7 ZW |
1718 | name = pfile->token_buffer + written + 1; |
1719 | copy = xstrdup (name); | |
1720 | copy[strlen(copy)] = '\0'; /* trim trailing quote */ | |
b0699dad ZW |
1721 | |
1722 | if (cpp_included (pfile, copy)) | |
a2a76ce7 ZW |
1723 | cpp_warning (pfile, |
1724 | "`#pragma implementation' for `%s' appears after file is included", | |
1725 | copy); | |
1726 | free (copy); | |
1727 | return 0; | |
1728 | } | |
fc009f96 | 1729 | |
a2a76ce7 ZW |
1730 | static int |
1731 | do_pragma_poison (pfile) | |
1732 | cpp_reader *pfile; | |
1733 | { | |
1734 | /* Poison these symbols so that all subsequent usage produces an | |
1735 | error message. */ | |
1736 | U_CHAR *p; | |
1737 | HASHNODE *hp; | |
1738 | long written; | |
1739 | size_t len; | |
1740 | enum cpp_token token; | |
1741 | int writeit; | |
1742 | /* As a rule, don't include #pragma poison commands in output, | |
1743 | unless the user asks for them. */ | |
1744 | writeit = (CPP_OPTIONS (pfile)->debug_output | |
1745 | || CPP_OPTIONS (pfile)->dump_macros == dump_definitions | |
1746 | || CPP_OPTIONS (pfile)->dump_macros == dump_names); | |
1747 | ||
1748 | for (;;) | |
1749 | { | |
1750 | written = CPP_WRITTEN (pfile); | |
1751 | token = get_directive_token (pfile); | |
1752 | if (token == CPP_VSPACE) | |
1753 | break; | |
1754 | if (token != CPP_NAME) | |
fc009f96 | 1755 | { |
a2a76ce7 ZW |
1756 | cpp_error (pfile, "invalid #pragma poison directive"); |
1757 | skip_rest_of_line (pfile); | |
1758 | return 1; | |
fc009f96 GK |
1759 | } |
1760 | ||
a2a76ce7 ZW |
1761 | p = pfile->token_buffer + written; |
1762 | len = strlen (p); | |
b0699dad | 1763 | if ((hp = _cpp_lookup (pfile, p, len))) |
fc009f96 | 1764 | { |
a2a76ce7 | 1765 | if (hp->type != T_POISON) |
fc009f96 | 1766 | { |
a2a76ce7 | 1767 | cpp_warning (pfile, "poisoning existing macro `%s'", p); |
b0699dad ZW |
1768 | if (hp->type == T_MACRO) |
1769 | _cpp_free_definition (hp->value.defn); | |
a2a76ce7 ZW |
1770 | hp->value.defn = 0; |
1771 | hp->type = T_POISON; | |
fc009f96 | 1772 | } |
fc009f96 | 1773 | } |
a2a76ce7 | 1774 | else |
b0699dad | 1775 | _cpp_install (pfile, p, len, T_POISON, 0); |
a2a76ce7 ZW |
1776 | if (writeit) |
1777 | CPP_PUTC (pfile, ' '); | |
fc009f96 | 1778 | } |
a2a76ce7 | 1779 | return !writeit; |
7f2935c7 | 1780 | } |
a2a76ce7 | 1781 | |
72e19470 | 1782 | #ifdef SCCS_DIRECTIVE |
7f2935c7 PB |
1783 | /* Just ignore #sccs, on systems where we define it at all. */ |
1784 | ||
1785 | static int | |
941e09b6 | 1786 | do_sccs (pfile, keyword) |
7f2935c7 | 1787 | cpp_reader *pfile; |
2ac9349e | 1788 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 PB |
1789 | { |
1790 | if (CPP_PEDANTIC (pfile)) | |
1791 | cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'"); | |
941e09b6 | 1792 | skip_rest_of_line (pfile); |
7f2935c7 PB |
1793 | return 0; |
1794 | } | |
72e19470 | 1795 | #endif |
1d0e51ba JM |
1796 | |
1797 | /* We've found an `#if' directive. If the only thing before it in | |
1798 | this file is white space, and if it is of the form | |
1799 | `#if ! defined SYMBOL', then SYMBOL is a possible controlling macro | |
1800 | for inclusion of this file. (See redundant_include_p in cppfiles.c | |
1801 | for an explanation of controlling macros.) If so, return a | |
1802 | malloc'd copy of SYMBOL. Otherwise, return NULL. */ | |
1803 | ||
1804 | static U_CHAR * | |
1805 | detect_if_not_defined (pfile) | |
1806 | cpp_reader *pfile; | |
1807 | { | |
1808 | U_CHAR *control_macro = 0; | |
1809 | ||
1810 | if (pfile->only_seen_white == 2) | |
1811 | { | |
1812 | char *ident; | |
1813 | enum cpp_token token; | |
1814 | int base_offset; | |
1815 | int token_offset; | |
1816 | int need_rparen = 0; | |
1817 | ||
1818 | /* Save state required for restore. */ | |
1819 | pfile->no_macro_expand++; | |
1820 | parse_set_mark (pfile); | |
1821 | base_offset = CPP_WRITTEN (pfile); | |
1822 | ||
1823 | /* Look for `!', */ | |
1824 | if (get_directive_token (pfile) != CPP_OTHER | |
1825 | || CPP_WRITTEN (pfile) != (size_t) base_offset + 1 | |
1826 | || CPP_PWRITTEN (pfile)[-1] != '!') | |
1827 | goto restore; | |
1828 | ||
1829 | /* ...then `defined', */ | |
1830 | token_offset = CPP_WRITTEN (pfile); | |
1831 | token = get_directive_token (pfile); | |
1832 | if (token != CPP_NAME) | |
1833 | goto restore; | |
1834 | ident = pfile->token_buffer + token_offset; | |
1835 | CPP_NUL_TERMINATE (pfile); | |
1836 | if (strcmp (ident, "defined")) | |
1837 | goto restore; | |
1838 | ||
1839 | /* ...then an optional '(' and the name, */ | |
1840 | token_offset = CPP_WRITTEN (pfile); | |
1841 | token = get_directive_token (pfile); | |
1842 | if (token == CPP_LPAREN) | |
1843 | { | |
1844 | token_offset = CPP_WRITTEN (pfile); | |
1845 | token = get_directive_token (pfile); | |
1846 | if (token != CPP_NAME) | |
1847 | goto restore; | |
1848 | need_rparen = 1; | |
1849 | } | |
1850 | else if (token != CPP_NAME) | |
1851 | goto restore; | |
1852 | ||
1853 | ident = pfile->token_buffer + token_offset; | |
1854 | CPP_NUL_TERMINATE (pfile); | |
1855 | ||
1856 | /* ...then the ')', if necessary, */ | |
1857 | if ((!need_rparen || get_directive_token (pfile) == CPP_RPAREN) | |
1858 | /* ...and make sure there's nothing else on the line. */ | |
1859 | && get_directive_token (pfile) == CPP_VSPACE) | |
1860 | control_macro = xstrdup (ident); | |
1861 | ||
1862 | restore: | |
1863 | CPP_SET_WRITTEN (pfile, base_offset); | |
1864 | pfile->no_macro_expand--; | |
1865 | parse_goto_mark (pfile); | |
1866 | } | |
1867 | ||
1868 | return control_macro; | |
1869 | } | |
1870 | ||
7f2935c7 PB |
1871 | /* |
1872 | * handle #if command by | |
1873 | * 1) inserting special `defined' keyword into the hash table | |
1874 | * that gets turned into 0 or 1 by special_symbol (thus, | |
1875 | * if the luser has a symbol called `defined' already, it won't | |
1876 | * work inside the #if command) | |
1877 | * 2) rescan the input into a temporary output buffer | |
1878 | * 3) pass the output buffer to the yacc parser and collect a value | |
1879 | * 4) clean up the mess left from steps 1 and 2. | |
1880 | * 5) call conditional_skip to skip til the next #endif (etc.), | |
1881 | * or not, depending on the value from step 3. | |
1882 | */ | |
1883 | ||
1884 | static int | |
941e09b6 | 1885 | do_if (pfile, keyword) |
7f2935c7 | 1886 | cpp_reader *pfile; |
2ac9349e | 1887 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1888 | { |
1d0e51ba | 1889 | U_CHAR *control_macro = detect_if_not_defined (pfile); |
e915b770 | 1890 | HOST_WIDEST_INT value = eval_if_expression (pfile); |
1d0e51ba | 1891 | conditional_skip (pfile, value == 0, T_IF, control_macro); |
7f2935c7 PB |
1892 | return 0; |
1893 | } | |
1894 | ||
1895 | /* | |
1896 | * handle a #elif directive by not changing if_stack either. | |
1897 | * see the comment above do_else. | |
1898 | */ | |
1899 | ||
1900 | static int | |
941e09b6 | 1901 | do_elif (pfile, keyword) |
7f2935c7 | 1902 | cpp_reader *pfile; |
2ac9349e | 1903 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1904 | { |
40ea76de ZW |
1905 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) |
1906 | { | |
1907 | cpp_error (pfile, "`#elif' not within a conditional"); | |
1908 | return 0; | |
1909 | } | |
1910 | else | |
1911 | { | |
1912 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) | |
1913 | { | |
1914 | cpp_error (pfile, "`#elif' after `#else'"); | |
1915 | cpp_error_with_line (pfile, pfile->if_stack->lineno, -1, | |
1916 | "the conditional began here"); | |
1917 | } | |
1918 | pfile->if_stack->type = T_ELIF; | |
7f2935c7 | 1919 | } |
7f2935c7 PB |
1920 | |
1921 | if (pfile->if_stack->if_succeeded) | |
ed705a82 | 1922 | skip_if_group (pfile); |
40ea76de ZW |
1923 | else |
1924 | { | |
1925 | HOST_WIDEST_INT value = eval_if_expression (pfile); | |
1926 | if (value == 0) | |
1927 | skip_if_group (pfile); | |
1928 | else | |
1929 | { | |
1930 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | |
1931 | output_line_command (pfile, same_file); | |
1932 | } | |
7f2935c7 | 1933 | } |
7f2935c7 PB |
1934 | return 0; |
1935 | } | |
1936 | ||
1937 | /* | |
1938 | * evaluate a #if expression in BUF, of length LENGTH, | |
1939 | * then parse the result as a C expression and return the value as an int. | |
1940 | */ | |
0f41302f | 1941 | |
e915b770 | 1942 | static HOST_WIDEST_INT |
941e09b6 | 1943 | eval_if_expression (pfile) |
7f2935c7 | 1944 | cpp_reader *pfile; |
7f2935c7 | 1945 | { |
e915b770 | 1946 | HOST_WIDEST_INT value; |
7f2935c7 PB |
1947 | long old_written = CPP_WRITTEN (pfile); |
1948 | ||
ba412f14 | 1949 | pfile->parsing_if_directive++; |
b0699dad | 1950 | value = _cpp_parse_expr (pfile); |
ba412f14 | 1951 | pfile->parsing_if_directive--; |
7f2935c7 | 1952 | |
cf4ed945 | 1953 | skip_rest_of_line (pfile); |
7f2935c7 PB |
1954 | CPP_SET_WRITTEN (pfile, old_written); /* Pop */ |
1955 | ||
1956 | return value; | |
1957 | } | |
1958 | ||
1959 | /* | |
1960 | * routine to handle ifdef/ifndef. Try to look up the symbol, | |
1961 | * then do or don't skip to the #endif/#else/#elif depending | |
1962 | * on what directive is actually being processed. | |
1963 | */ | |
1964 | ||
1965 | static int | |
941e09b6 | 1966 | do_xifdef (pfile, keyword) |
7f2935c7 | 1967 | cpp_reader *pfile; |
2ac9349e | 1968 | const struct directive *keyword; |
7f2935c7 PB |
1969 | { |
1970 | int skip; | |
1971 | cpp_buffer *ip = CPP_BUFFER (pfile); | |
0f41302f | 1972 | U_CHAR *ident; |
7f2935c7 PB |
1973 | int ident_length; |
1974 | enum cpp_token token; | |
1975 | int start_of_file = 0; | |
1976 | U_CHAR *control_macro = 0; | |
1977 | int old_written = CPP_WRITTEN (pfile); | |
1978 | ||
1979 | /* Detect a #ifndef at start of file (not counting comments). */ | |
1980 | if (ip->fname != 0 && keyword->type == T_IFNDEF) | |
1981 | start_of_file = pfile->only_seen_white == 2; | |
1982 | ||
1983 | pfile->no_macro_expand++; | |
1984 | token = get_directive_token (pfile); | |
1985 | pfile->no_macro_expand--; | |
1986 | ||
1987 | ident = pfile->token_buffer + old_written; | |
1988 | ident_length = CPP_WRITTEN (pfile) - old_written; | |
1989 | CPP_SET_WRITTEN (pfile, old_written); /* Pop */ | |
1990 | ||
1991 | if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) | |
1992 | { | |
1993 | skip = (keyword->type == T_IFDEF); | |
1994 | if (! CPP_TRADITIONAL (pfile)) | |
1995 | cpp_pedwarn (pfile, "`#%s' with no argument", keyword->name); | |
1996 | } | |
1997 | else if (token == CPP_NAME) | |
1998 | { | |
a2a76ce7 ZW |
1999 | skip = cpp_defined (pfile, ident, ident_length); |
2000 | if (keyword->type == T_IFDEF) | |
2001 | skip = !skip; | |
2002 | ||
7f2935c7 PB |
2003 | if (start_of_file && !skip) |
2004 | { | |
2005 | control_macro = (U_CHAR *) xmalloc (ident_length + 1); | |
2006 | bcopy (ident, control_macro, ident_length + 1); | |
2007 | } | |
2008 | } | |
2009 | else | |
2010 | { | |
2011 | skip = (keyword->type == T_IFDEF); | |
2012 | if (! CPP_TRADITIONAL (pfile)) | |
2013 | cpp_error (pfile, "`#%s' with invalid argument", keyword->name); | |
2014 | } | |
2015 | ||
2016 | if (!CPP_TRADITIONAL (pfile)) | |
2017 | { int c; | |
2018 | cpp_skip_hspace (pfile); | |
2019 | c = PEEKC (); | |
2020 | if (c != EOF && c != '\n') | |
2021 | cpp_pedwarn (pfile, "garbage at end of `#%s' argument", keyword->name); | |
2022 | } | |
2023 | skip_rest_of_line (pfile); | |
2024 | ||
7f2935c7 PB |
2025 | conditional_skip (pfile, skip, T_IF, control_macro); |
2026 | return 0; | |
2027 | } | |
2028 | ||
2029 | /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. | |
2030 | If this is a #ifndef starting at the beginning of a file, | |
2031 | CONTROL_MACRO is the macro name tested by the #ifndef. | |
2032 | Otherwise, CONTROL_MACRO is 0. */ | |
2033 | ||
2034 | static void | |
2035 | conditional_skip (pfile, skip, type, control_macro) | |
2036 | cpp_reader *pfile; | |
2037 | int skip; | |
2038 | enum node_type type; | |
2039 | U_CHAR *control_macro; | |
2040 | { | |
2041 | IF_STACK_FRAME *temp; | |
2042 | ||
2043 | temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); | |
2044 | temp->fname = CPP_BUFFER (pfile)->nominal_fname; | |
7f2935c7 | 2045 | temp->lineno = CPP_BUFFER (pfile)->lineno; |
7f2935c7 PB |
2046 | temp->next = pfile->if_stack; |
2047 | temp->control_macro = control_macro; | |
2048 | pfile->if_stack = temp; | |
2049 | ||
2050 | pfile->if_stack->type = type; | |
2051 | ||
2052 | if (skip != 0) { | |
ed705a82 | 2053 | skip_if_group (pfile); |
7f2935c7 PB |
2054 | return; |
2055 | } else { | |
2056 | ++pfile->if_stack->if_succeeded; | |
80e9dcb4 | 2057 | output_line_command (pfile, same_file); |
7f2935c7 PB |
2058 | } |
2059 | } | |
2060 | ||
ed705a82 ZW |
2061 | /* Subroutine of skip_if_group. Examine one preprocessing directive and |
2062 | return 0 if skipping should continue, 1 if it should halt. Also | |
2063 | adjusts the if_stack as appropriate. | |
2064 | The `#' has been read, but not the identifier. */ | |
2065 | ||
2066 | static int | |
2067 | consider_directive_while_skipping (pfile, stack) | |
2068 | cpp_reader *pfile; | |
2069 | IF_STACK_FRAME *stack; | |
2070 | { | |
2071 | long ident_len, ident; | |
2ac9349e | 2072 | const struct directive *kt; |
ed705a82 ZW |
2073 | IF_STACK_FRAME *temp; |
2074 | ||
2075 | cpp_skip_hspace (pfile); | |
2076 | ||
2077 | ident = CPP_WRITTEN (pfile); | |
2078 | parse_name (pfile, GETC()); | |
2079 | ident_len = CPP_WRITTEN (pfile) - ident; | |
2080 | ||
2081 | CPP_SET_WRITTEN (pfile, ident); | |
2082 | ||
2083 | for (kt = directive_table; kt->length >= 0; kt++) | |
2084 | if (kt->length == ident_len | |
2085 | && strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0) | |
2086 | switch (kt->type) | |
2087 | { | |
2088 | case T_IF: | |
2089 | case T_IFDEF: | |
2090 | case T_IFNDEF: | |
2091 | temp = (IF_STACK_FRAME *) xmalloc (sizeof (IF_STACK_FRAME)); | |
2092 | temp->next = pfile->if_stack; | |
2093 | pfile->if_stack = temp; | |
2094 | temp->fname = CPP_BUFFER(pfile)->nominal_fname; | |
2095 | temp->type = kt->type; | |
2096 | return 0; | |
2097 | ||
2098 | case T_ELSE: | |
75ec21db | 2099 | if (pfile->if_stack != stack) |
ed705a82 ZW |
2100 | validate_else (pfile, "#else"); |
2101 | /* fall through */ | |
2102 | case T_ELIF: | |
ed705a82 ZW |
2103 | if (pfile->if_stack == stack) |
2104 | return 1; | |
2105 | else | |
2106 | { | |
2107 | pfile->if_stack->type = kt->type; | |
2108 | return 0; | |
2109 | } | |
2110 | ||
2111 | case T_ENDIF: | |
75ec21db | 2112 | if (pfile->if_stack != stack) |
ed705a82 ZW |
2113 | validate_else (pfile, "#endif"); |
2114 | ||
2115 | if (pfile->if_stack == stack) | |
2116 | return 1; | |
2117 | ||
2118 | temp = pfile->if_stack; | |
2119 | pfile->if_stack = temp->next; | |
2120 | free (temp); | |
2121 | return 0; | |
2122 | ||
2123 | default: | |
2124 | return 0; | |
2125 | } | |
2126 | ||
2127 | /* Don't let erroneous code go by. */ | |
2128 | if (!CPP_OPTIONS (pfile)->lang_asm && CPP_PEDANTIC (pfile)) | |
2129 | cpp_pedwarn (pfile, "invalid preprocessor directive name"); | |
2130 | return 0; | |
2131 | } | |
2132 | ||
2133 | /* skip to #endif, #else, or #elif. adjust line numbers, etc. | |
7f2935c7 | 2134 | * leaves input ptr at the sharp sign found. |
7f2935c7 PB |
2135 | */ |
2136 | static void | |
ed705a82 ZW |
2137 | skip_if_group (pfile) |
2138 | cpp_reader *pfile; | |
7f2935c7 PB |
2139 | { |
2140 | int c; | |
7f2935c7 | 2141 | IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */ |
ed705a82 ZW |
2142 | U_CHAR *beg_of_line; |
2143 | long old_written; | |
7f2935c7 | 2144 | |
ed705a82 ZW |
2145 | old_written = CPP_WRITTEN (pfile); |
2146 | ||
2147 | for (;;) | |
2148 | { | |
2149 | beg_of_line = CPP_BUFFER (pfile)->cur; | |
7f2935c7 | 2150 | |
ed705a82 ZW |
2151 | if (! CPP_TRADITIONAL (pfile)) |
2152 | cpp_skip_hspace (pfile); | |
2153 | c = GETC(); | |
2154 | if (c == '\n') | |
7f2935c7 | 2155 | { |
3fdc651f | 2156 | CPP_BUMP_LINE (pfile); |
ed705a82 ZW |
2157 | continue; |
2158 | } | |
2159 | else if (c == '#') | |
2160 | { | |
2161 | if (consider_directive_while_skipping (pfile, save_if_stack)) | |
2162 | break; | |
2163 | } | |
2164 | else if (c == EOF) | |
2165 | return; /* Caller will issue error. */ | |
7f2935c7 | 2166 | |
ed705a82 | 2167 | FORWARD(-1); |
ba412f14 | 2168 | skip_rest_of_line (pfile); |
7f2935c7 | 2169 | |
ed705a82 ZW |
2170 | c = GETC(); |
2171 | if (c == EOF) | |
2172 | return; /* Caller will issue error. */ | |
2173 | else | |
ba412f14 | 2174 | CPP_BUMP_LINE (pfile); |
ed705a82 ZW |
2175 | } |
2176 | ||
2177 | /* Back up to the beginning of this line. Caller will process the | |
2178 | directive. */ | |
2179 | CPP_BUFFER (pfile)->cur = beg_of_line; | |
7f2935c7 | 2180 | pfile->only_seen_white = 1; |
7f2935c7 PB |
2181 | } |
2182 | ||
2183 | /* | |
2184 | * handle a #else directive. Do this by just continuing processing | |
2185 | * without changing if_stack ; this is so that the error message | |
2186 | * for missing #endif's etc. will point to the original #if. It | |
2187 | * is possible that something different would be better. | |
2188 | */ | |
2189 | ||
2190 | static int | |
941e09b6 | 2191 | do_else (pfile, keyword) |
7f2935c7 | 2192 | cpp_reader *pfile; |
2ac9349e | 2193 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 2194 | { |
75ec21db | 2195 | validate_else (pfile, "#else"); |
7f2935c7 PB |
2196 | skip_rest_of_line (pfile); |
2197 | ||
40ea76de ZW |
2198 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) |
2199 | { | |
2200 | cpp_error (pfile, "`#else' not within a conditional"); | |
2201 | return 0; | |
2202 | } | |
2203 | else | |
2204 | { | |
2205 | /* #ifndef can't have its special treatment for containing the whole file | |
2206 | if it has a #else clause. */ | |
2207 | pfile->if_stack->control_macro = 0; | |
2208 | ||
2209 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) | |
2210 | { | |
2211 | cpp_error (pfile, "`#else' after `#else'"); | |
2212 | cpp_error_with_line (pfile, pfile->if_stack->lineno, -1, | |
2213 | "the conditional began here"); | |
2214 | } | |
2215 | pfile->if_stack->type = T_ELSE; | |
2216 | } | |
7f2935c7 PB |
2217 | |
2218 | if (pfile->if_stack->if_succeeded) | |
ed705a82 | 2219 | skip_if_group (pfile); |
40ea76de ZW |
2220 | else |
2221 | { | |
2222 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | |
2223 | output_line_command (pfile, same_file); | |
2224 | } | |
7f2935c7 PB |
2225 | return 0; |
2226 | } | |
2227 | ||
2228 | /* | |
2229 | * unstack after #endif command | |
2230 | */ | |
2231 | ||
2232 | static int | |
941e09b6 | 2233 | do_endif (pfile, keyword) |
7f2935c7 | 2234 | cpp_reader *pfile; |
2ac9349e | 2235 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 2236 | { |
75ec21db | 2237 | validate_else (pfile, "#endif"); |
7f2935c7 PB |
2238 | skip_rest_of_line (pfile); |
2239 | ||
2240 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) | |
6ee2c979 | 2241 | cpp_error (pfile, "`#endif' not within a conditional"); |
7f2935c7 PB |
2242 | else |
2243 | { | |
2244 | IF_STACK_FRAME *temp = pfile->if_stack; | |
2245 | pfile->if_stack = temp->next; | |
2246 | if (temp->control_macro != 0) | |
2247 | { | |
2248 | /* This #endif matched a #ifndef at the start of the file. | |
2249 | See if it is at the end of the file. */ | |
7f2935c7 PB |
2250 | int c; |
2251 | ||
3fdc651f | 2252 | parse_set_mark (pfile); |
7f2935c7 PB |
2253 | |
2254 | for (;;) | |
2255 | { | |
2256 | cpp_skip_hspace (pfile); | |
2257 | c = GETC (); | |
2258 | if (c != '\n') | |
2259 | break; | |
2260 | } | |
3fdc651f | 2261 | parse_goto_mark (pfile); |
7f2935c7 PB |
2262 | |
2263 | if (c == EOF) | |
2264 | { | |
0b3d776a | 2265 | /* This #endif ends a #ifndef |
7f2935c7 PB |
2266 | that contains all of the file (aside from whitespace). |
2267 | Arrange not to include the file again | |
0b3d776a ZW |
2268 | if the macro that was tested is defined. */ |
2269 | struct cpp_buffer *ip; | |
2270 | for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) | |
2271 | if (ip->fname != NULL) | |
2272 | break; | |
8db99db2 | 2273 | ip->ihash->control_macro = (char *) temp->control_macro; |
7f2935c7 PB |
2274 | } |
2275 | } | |
2276 | free (temp); | |
80e9dcb4 | 2277 | output_line_command (pfile, same_file); |
7f2935c7 PB |
2278 | } |
2279 | return 0; | |
2280 | } | |
2281 | ||
75ec21db ZW |
2282 | /* Issue -pedantic warning for text which is not a comment following |
2283 | an #else or #endif. Do not warn in system headers, as this is harmless | |
2284 | and very common on old systems. */ | |
7f2935c7 PB |
2285 | |
2286 | static void | |
2287 | validate_else (pfile, directive) | |
2288 | cpp_reader *pfile; | |
2ac9349e | 2289 | const char *directive; |
7f2935c7 | 2290 | { |
83ecd27e | 2291 | if (! CPP_PEDANTIC (pfile)) |
75ec21db ZW |
2292 | return; |
2293 | ||
7f2935c7 | 2294 | cpp_skip_hspace (pfile); |
75ec21db | 2295 | if (PEEKC () != '\n') |
7f2935c7 PB |
2296 | cpp_pedwarn (pfile, |
2297 | "text following `%s' violates ANSI standard", directive); | |
2298 | } | |
2299 | ||
6ee2c979 ZW |
2300 | /* Convert T_IF, etc. to a string. Used in error messages. */ |
2301 | static const char * | |
2302 | if_directive_name (pfile, ifs) | |
2303 | cpp_reader *pfile; | |
2304 | struct if_stack *ifs; | |
2305 | { | |
2306 | switch (ifs->type) | |
2307 | { | |
2308 | case T_IF: return "#if"; | |
2309 | case T_IFDEF: return "#ifdef"; | |
2310 | case T_IFNDEF: return "#ifndef"; | |
2311 | case T_ELIF: return "#elif"; | |
2312 | case T_ELSE: return "#else"; | |
2313 | default: | |
c1212d2f | 2314 | cpp_ice (pfile, "impossible if_stack->type value %d", ifs->type); |
6ee2c979 ZW |
2315 | return "unknown"; |
2316 | } | |
2317 | } | |
2318 | ||
22bbceaf | 2319 | /* Get the next token, and add it to the text in pfile->token_buffer. |
0f41302f | 2320 | Return the kind of token we got. */ |
eaefae0e | 2321 | |
7f2935c7 PB |
2322 | enum cpp_token |
2323 | cpp_get_token (pfile) | |
2324 | cpp_reader *pfile; | |
2325 | { | |
2326 | register int c, c2, c3; | |
7f2935c7 PB |
2327 | enum cpp_token token; |
2328 | struct cpp_options *opts = CPP_OPTIONS (pfile); | |
4d9a1b48 | 2329 | |
7f2935c7 PB |
2330 | get_next: |
2331 | c = GETC(); | |
2332 | if (c == EOF) | |
2333 | { | |
e7f9deae JM |
2334 | if (CPP_BUFFER (pfile)->manual_pop) |
2335 | /* If we've been reading from redirected input, the | |
2336 | frontend will pop the buffer. */ | |
2337 | return CPP_EOF; | |
2338 | else if (CPP_BUFFER (pfile)->seen_eof) | |
7f2935c7 | 2339 | { |
e7f9deae | 2340 | if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == CPP_NULL_BUFFER (pfile)) |
7f2935c7 | 2341 | return CPP_EOF; |
4d9a1b48 ZW |
2342 | |
2343 | cpp_pop_buffer (pfile); | |
2344 | goto get_next; | |
7f2935c7 PB |
2345 | } |
2346 | else | |
2347 | { | |
6ee2c979 ZW |
2348 | cpp_buffer *next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile)); |
2349 | struct if_stack *ifs, *nifs; | |
2350 | ||
2351 | /* Unwind the conditional stack and generate error messages. */ | |
2352 | for (ifs = pfile->if_stack; | |
2353 | ifs != CPP_BUFFER (pfile)->if_stack; | |
2354 | ifs = nifs) | |
2355 | { | |
2356 | cpp_error_with_line (pfile, ifs->lineno, -1, | |
2357 | "unterminated `%s' conditional", | |
2358 | if_directive_name (pfile, ifs)); | |
2359 | ||
2360 | nifs = ifs->next; | |
2361 | free (ifs); | |
2362 | } | |
2363 | pfile->if_stack = ifs; | |
2364 | ||
d013f05e PB |
2365 | if (CPP_BUFFER (pfile)->nominal_fname |
2366 | && next_buf != CPP_NULL_BUFFER (pfile)) | |
7f2935c7 PB |
2367 | { |
2368 | /* We're about to return from an #include file. | |
ddd5a7c1 | 2369 | Emit #line information now (as part of the CPP_POP) result. |
0f41302f | 2370 | But the #line refers to the file we will pop to. */ |
7f2935c7 PB |
2371 | cpp_buffer *cur_buffer = CPP_BUFFER (pfile); |
2372 | CPP_BUFFER (pfile) = next_buf; | |
2373 | pfile->input_stack_listing_current = 0; | |
80e9dcb4 | 2374 | output_line_command (pfile, leave_file); |
7f2935c7 PB |
2375 | CPP_BUFFER (pfile) = cur_buffer; |
2376 | } | |
6ee2c979 ZW |
2377 | |
2378 | CPP_BUFFER (pfile)->seen_eof = 1; | |
7f2935c7 PB |
2379 | return CPP_POP; |
2380 | } | |
2381 | } | |
2382 | else | |
2383 | { | |
2384 | switch (c) | |
2385 | { | |
7f2935c7 PB |
2386 | case '/': |
2387 | if (PEEKC () == '=') | |
2388 | goto op2; | |
3fdc651f ZW |
2389 | |
2390 | comment: | |
564ad5f4 | 2391 | if (opts->discard_comments) |
3fdc651f | 2392 | c = skip_comment (pfile, c); |
564ad5f4 ZW |
2393 | else |
2394 | c = copy_comment (pfile, c); | |
75ec21db | 2395 | if (c != ' ') |
3fdc651f ZW |
2396 | goto randomchar; |
2397 | ||
7f2935c7 PB |
2398 | /* Comments are equivalent to spaces. |
2399 | For -traditional, a comment is equivalent to nothing. */ | |
564ad5f4 | 2400 | if (opts->traditional || !opts->discard_comments) |
3fdc651f | 2401 | return CPP_COMMENT; |
7f2935c7 PB |
2402 | else |
2403 | { | |
3fdc651f | 2404 | CPP_PUTC (pfile, c); |
7f2935c7 PB |
2405 | return CPP_HSPACE; |
2406 | } | |
1316f1f7 | 2407 | |
7f2935c7 | 2408 | case '#': |
ba412f14 ZW |
2409 | if (pfile->parsing_if_directive) |
2410 | { | |
2411 | cpp_skip_hspace (pfile); | |
2412 | parse_assertion (pfile); | |
2413 | return CPP_ASSERTION; | |
2414 | } | |
2415 | ||
2416 | if (pfile->parsing_define_directive && ! CPP_TRADITIONAL (pfile)) | |
2417 | { | |
2418 | CPP_RESERVE (pfile, 3); | |
2419 | CPP_PUTC_Q (pfile, '#'); | |
2420 | CPP_NUL_TERMINATE_Q (pfile); | |
2421 | if (PEEKC () != '#') | |
2422 | return CPP_STRINGIZE; | |
2423 | ||
2424 | FORWARD (1); | |
2425 | CPP_PUTC_Q (pfile, '#'); | |
2426 | CPP_NUL_TERMINATE_Q (pfile); | |
2427 | return CPP_TOKPASTE; | |
2428 | } | |
2429 | ||
7f2935c7 PB |
2430 | if (!pfile->only_seen_white) |
2431 | goto randomchar; | |
40c79d58 ZW |
2432 | /* -traditional directives are recognized only with the # in |
2433 | column 1. | |
2434 | XXX Layering violation. */ | |
2435 | if (CPP_TRADITIONAL (pfile) | |
2436 | && CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base != 1) | |
2437 | goto randomchar; | |
7f2935c7 PB |
2438 | if (handle_directive (pfile)) |
2439 | return CPP_DIRECTIVE; | |
2440 | pfile->only_seen_white = 0; | |
eaefae0e | 2441 | goto randomchar; |
7f2935c7 PB |
2442 | |
2443 | case '\"': | |
2444 | case '\'': | |
3fdc651f | 2445 | parse_string (pfile, c); |
7f2935c7 PB |
2446 | pfile->only_seen_white = 0; |
2447 | return c == '\'' ? CPP_CHAR : CPP_STRING; | |
2448 | ||
2449 | case '$': | |
2450 | if (!opts->dollars_in_ident) | |
2451 | goto randomchar; | |
2452 | goto letter; | |
2453 | ||
2454 | case ':': | |
2455 | if (opts->cplusplus && PEEKC () == ':') | |
2456 | goto op2; | |
2457 | goto randomchar; | |
2458 | ||
2459 | case '&': | |
2460 | case '+': | |
2461 | case '|': | |
7f2935c7 PB |
2462 | c2 = PEEKC (); |
2463 | if (c2 == c || c2 == '=') | |
2464 | goto op2; | |
2465 | goto randomchar; | |
2466 | ||
2467 | case '*': | |
2468 | case '!': | |
2469 | case '%': | |
2470 | case '=': | |
2471 | case '^': | |
7f2935c7 PB |
2472 | if (PEEKC () == '=') |
2473 | goto op2; | |
2474 | goto randomchar; | |
2475 | ||
2476 | case '-': | |
7f2935c7 PB |
2477 | c2 = PEEKC (); |
2478 | if (c2 == '-' && opts->chill) | |
3fdc651f | 2479 | goto comment; /* Chill style comment */ |
3773a46b | 2480 | if (c2 == '-' || c2 == '=') |
7f2935c7 | 2481 | goto op2; |
3773a46b JM |
2482 | if (c2 == '>') |
2483 | { | |
2484 | if (opts->cplusplus && PEEKN (1) == '*') | |
2485 | { | |
2486 | /* In C++, there's a ->* operator. */ | |
3773a46b JM |
2487 | token = CPP_OTHER; |
2488 | pfile->only_seen_white = 0; | |
2489 | CPP_RESERVE (pfile, 4); | |
2490 | CPP_PUTC_Q (pfile, c); | |
2491 | CPP_PUTC_Q (pfile, GETC ()); | |
2492 | CPP_PUTC_Q (pfile, GETC ()); | |
2493 | CPP_NUL_TERMINATE_Q (pfile); | |
2494 | return token; | |
2495 | } | |
2496 | goto op2; | |
2497 | } | |
7f2935c7 PB |
2498 | goto randomchar; |
2499 | ||
2500 | case '<': | |
2501 | if (pfile->parsing_include_directive) | |
2502 | { | |
2503 | for (;;) | |
2504 | { | |
2505 | CPP_PUTC (pfile, c); | |
2506 | if (c == '>') | |
2507 | break; | |
2508 | c = GETC (); | |
7f2935c7 PB |
2509 | if (c == '\n' || c == EOF) |
2510 | { | |
2511 | cpp_error (pfile, | |
2512 | "missing '>' in `#include <FILENAME>'"); | |
2513 | break; | |
2514 | } | |
3fdc651f ZW |
2515 | else if (c == '\r') |
2516 | { | |
ed45de98 ZW |
2517 | if (!CPP_BUFFER (pfile)->has_escapes) |
2518 | { | |
2519 | /* Backslash newline is replaced by nothing. */ | |
2520 | CPP_ADJUST_WRITTEN (pfile, -1); | |
2521 | CPP_BUMP_LINE (pfile); | |
2522 | } | |
2523 | else | |
2524 | { | |
2525 | /* We might conceivably get \r- or \r<space> in | |
2526 | here. Just delete 'em. */ | |
2527 | int d = GETC(); | |
2528 | if (d != '-' && d != ' ') | |
c1212d2f | 2529 | cpp_ice (pfile, "unrecognized escape \\r%c", d); |
ed45de98 ZW |
2530 | CPP_ADJUST_WRITTEN (pfile, -1); |
2531 | } | |
3fdc651f | 2532 | } |
7f2935c7 PB |
2533 | } |
2534 | return CPP_STRING; | |
2535 | } | |
2536 | /* else fall through */ | |
2537 | case '>': | |
7f2935c7 PB |
2538 | c2 = PEEKC (); |
2539 | if (c2 == '=') | |
2540 | goto op2; | |
3773a46b JM |
2541 | /* GNU C++ supports MIN and MAX operators <? and >?. */ |
2542 | if (c2 != c && (!opts->cplusplus || c2 != '?')) | |
7f2935c7 PB |
2543 | goto randomchar; |
2544 | FORWARD(1); | |
2545 | CPP_RESERVE (pfile, 4); | |
2546 | CPP_PUTC (pfile, c); | |
2547 | CPP_PUTC (pfile, c2); | |
7f2935c7 PB |
2548 | c3 = PEEKC (); |
2549 | if (c3 == '=') | |
2550 | CPP_PUTC_Q (pfile, GETC ()); | |
2551 | CPP_NUL_TERMINATE_Q (pfile); | |
2552 | pfile->only_seen_white = 0; | |
2553 | return CPP_OTHER; | |
2554 | ||
7f2935c7 | 2555 | case '.': |
7f2935c7 | 2556 | c2 = PEEKC (); |
e9a780ec | 2557 | if (ISDIGIT(c2)) |
7f2935c7 PB |
2558 | { |
2559 | CPP_RESERVE(pfile, 2); | |
2560 | CPP_PUTC_Q (pfile, '.'); | |
2561 | c = GETC (); | |
2562 | goto number; | |
2563 | } | |
3773a46b JM |
2564 | |
2565 | /* In C++ there's a .* operator. */ | |
2566 | if (opts->cplusplus && c2 == '*') | |
2567 | goto op2; | |
2568 | ||
7f2935c7 PB |
2569 | if (c2 == '.' && PEEKN(1) == '.') |
2570 | { | |
2571 | CPP_RESERVE(pfile, 4); | |
2572 | CPP_PUTC_Q (pfile, '.'); | |
2573 | CPP_PUTC_Q (pfile, '.'); | |
2574 | CPP_PUTC_Q (pfile, '.'); | |
2575 | FORWARD (2); | |
2576 | CPP_NUL_TERMINATE_Q (pfile); | |
2577 | pfile->only_seen_white = 0; | |
2578 | return CPP_3DOTS; | |
2579 | } | |
2580 | goto randomchar; | |
2581 | ||
2582 | op2: | |
2583 | token = CPP_OTHER; | |
2584 | pfile->only_seen_white = 0; | |
7f2935c7 PB |
2585 | CPP_RESERVE(pfile, 3); |
2586 | CPP_PUTC_Q (pfile, c); | |
2587 | CPP_PUTC_Q (pfile, GETC ()); | |
2588 | CPP_NUL_TERMINATE_Q (pfile); | |
2589 | return token; | |
2590 | ||
2591 | case 'L': | |
7f2935c7 PB |
2592 | c2 = PEEKC (); |
2593 | if ((c2 == '\'' || c2 == '\"') && !CPP_TRADITIONAL (pfile)) | |
2594 | { | |
2595 | CPP_PUTC (pfile, c); | |
2596 | c = GETC (); | |
525bc95d AO |
2597 | parse_string (pfile, c); |
2598 | pfile->only_seen_white = 0; | |
2599 | return c == '\'' ? CPP_WCHAR : CPP_WSTRING; | |
7f2935c7 PB |
2600 | } |
2601 | goto letter; | |
2602 | ||
2603 | case '0': case '1': case '2': case '3': case '4': | |
2604 | case '5': case '6': case '7': case '8': case '9': | |
2605 | number: | |
2606 | c2 = '.'; | |
2607 | for (;;) | |
2608 | { | |
2609 | CPP_RESERVE (pfile, 2); | |
2610 | CPP_PUTC_Q (pfile, c); | |
7f2935c7 PB |
2611 | c = PEEKC (); |
2612 | if (c == EOF) | |
2613 | break; | |
455d2586 | 2614 | if (!is_numchar(c) && c != '.' |
641d4443 RK |
2615 | && ((c2 != 'e' && c2 != 'E' |
2616 | && ((c2 != 'p' && c2 != 'P') || CPP_C89 (pfile))) | |
2617 | || (c != '+' && c != '-'))) | |
7f2935c7 PB |
2618 | break; |
2619 | FORWARD(1); | |
2620 | c2= c; | |
2621 | } | |
2622 | CPP_NUL_TERMINATE_Q (pfile); | |
2623 | pfile->only_seen_white = 0; | |
2624 | return CPP_NUMBER; | |
2625 | case 'b': case 'c': case 'd': case 'h': case 'o': | |
2626 | case 'B': case 'C': case 'D': case 'H': case 'O': | |
2627 | if (opts->chill && PEEKC () == '\'') | |
2628 | { | |
2629 | pfile->only_seen_white = 0; | |
2630 | CPP_RESERVE (pfile, 2); | |
2631 | CPP_PUTC_Q (pfile, c); | |
2632 | CPP_PUTC_Q (pfile, '\''); | |
2633 | FORWARD(1); | |
2634 | for (;;) | |
2635 | { | |
2636 | c = GETC(); | |
2637 | if (c == EOF) | |
2638 | goto chill_number_eof; | |
455d2586 | 2639 | if (!is_numchar(c)) |
3fdc651f | 2640 | break; |
7f2935c7 PB |
2641 | CPP_PUTC (pfile, c); |
2642 | } | |
2643 | if (c == '\'') | |
2644 | { | |
2645 | CPP_RESERVE (pfile, 2); | |
2646 | CPP_PUTC_Q (pfile, c); | |
2647 | CPP_NUL_TERMINATE_Q (pfile); | |
2648 | return CPP_STRING; | |
2649 | } | |
2650 | else | |
2651 | { | |
2652 | FORWARD(-1); | |
2653 | chill_number_eof: | |
2654 | CPP_NUL_TERMINATE (pfile); | |
2655 | return CPP_NUMBER; | |
2656 | } | |
2657 | } | |
2658 | else | |
2659 | goto letter; | |
2660 | case '_': | |
2661 | case 'a': case 'e': case 'f': case 'g': case 'i': case 'j': | |
2662 | case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': | |
2663 | case 'r': case 's': case 't': case 'u': case 'v': case 'w': | |
2664 | case 'x': case 'y': case 'z': | |
2665 | case 'A': case 'E': case 'F': case 'G': case 'I': case 'J': | |
2666 | case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R': | |
2667 | case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': | |
2668 | case 'Y': case 'Z': | |
2669 | letter: | |
2670 | { | |
2671 | HASHNODE *hp; | |
2672 | unsigned char *ident; | |
2673 | int before_name_written = CPP_WRITTEN (pfile); | |
2674 | int ident_len; | |
2675 | parse_name (pfile, c); | |
2676 | pfile->only_seen_white = 0; | |
2677 | if (pfile->no_macro_expand) | |
2678 | return CPP_NAME; | |
2679 | ident = pfile->token_buffer + before_name_written; | |
2680 | ident_len = CPP_PWRITTEN (pfile) - ident; | |
b0699dad | 2681 | hp = _cpp_lookup (pfile, ident, ident_len); |
7f2935c7 PB |
2682 | if (!hp) |
2683 | return CPP_NAME; | |
2684 | if (hp->type == T_DISABLED) | |
2685 | { | |
2686 | if (pfile->output_escapes) | |
ed45de98 | 2687 | { /* Return "\r-IDENT", followed by '\0'. */ |
7f2935c7 PB |
2688 | int i; |
2689 | CPP_RESERVE (pfile, 3); | |
2690 | ident = pfile->token_buffer + before_name_written; | |
2691 | CPP_ADJUST_WRITTEN (pfile, 2); | |
2692 | for (i = ident_len; i >= 0; i--) ident[i+2] = ident[i]; | |
ed45de98 | 2693 | ident[0] = '\r'; |
7f2935c7 PB |
2694 | ident[1] = '-'; |
2695 | } | |
2696 | return CPP_NAME; | |
2697 | } | |
2698 | ||
cf4ed945 | 2699 | /* If macro wants an arglist, verify that a '(' follows. */ |
7f2935c7 PB |
2700 | if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) |
2701 | { | |
564ad5f4 ZW |
2702 | int macbuf_whitespace = 0; |
2703 | ||
2704 | while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) | |
2705 | { | |
2706 | U_CHAR *point = CPP_BUFFER (pfile)->cur; | |
2707 | for (;;) | |
2708 | { | |
2709 | cpp_skip_hspace (pfile); | |
2710 | c = PEEKC (); | |
2711 | if (c == '\n') | |
2712 | FORWARD(1); | |
2713 | else | |
2714 | break; | |
2715 | } | |
2716 | if (point != CPP_BUFFER (pfile)->cur) | |
2717 | macbuf_whitespace = 1; | |
2718 | if (c == '(') | |
2719 | goto is_macro_call; | |
2720 | else if (c != EOF) | |
2721 | goto not_macro_call; | |
2722 | cpp_pop_buffer (pfile); | |
2723 | } | |
c55ade02 | 2724 | |
3fdc651f | 2725 | parse_set_mark (pfile); |
7f2935c7 PB |
2726 | for (;;) |
2727 | { | |
2728 | cpp_skip_hspace (pfile); | |
2729 | c = PEEKC (); | |
564ad5f4 ZW |
2730 | if (c == '\n') |
2731 | FORWARD(1); | |
2732 | else | |
2733 | break; | |
7f2935c7 | 2734 | } |
564ad5f4 ZW |
2735 | parse_goto_mark (pfile); |
2736 | ||
2737 | if (c == '(') | |
2738 | goto is_macro_call; | |
2739 | ||
2740 | not_macro_call: | |
2741 | if (macbuf_whitespace) | |
2742 | CPP_PUTC (pfile, ' '); | |
2743 | return CPP_NAME; | |
7f2935c7 | 2744 | } |
564ad5f4 | 2745 | is_macro_call: |
20dc7361 ZW |
2746 | /* This is now known to be a macro call. |
2747 | Expand the macro, reading arguments as needed, | |
2748 | and push the expansion on the input stack. */ | |
b0699dad | 2749 | _cpp_macroexpand (pfile, hp); |
20dc7361 | 2750 | CPP_SET_WRITTEN (pfile, before_name_written); |
7f2935c7 | 2751 | } |
782331f4 | 2752 | goto get_next; |
7f2935c7 | 2753 | |
3fdc651f | 2754 | case ' ': case '\t': case '\v': |
7f2935c7 PB |
2755 | for (;;) |
2756 | { | |
2757 | CPP_PUTC (pfile, c); | |
2758 | c = PEEKC (); | |
a9ae4483 | 2759 | if (c == EOF || !is_hspace(c)) |
7f2935c7 PB |
2760 | break; |
2761 | FORWARD(1); | |
2762 | } | |
2763 | return CPP_HSPACE; | |
2764 | ||
3fdc651f | 2765 | case '\r': |
ed45de98 ZW |
2766 | if (CPP_BUFFER (pfile)->has_escapes) |
2767 | { | |
2768 | c = GETC (); | |
2769 | if (c == '-') | |
2770 | { | |
2771 | if (pfile->output_escapes) | |
2772 | CPP_PUTS (pfile, "\r-", 2); | |
2773 | parse_name (pfile, GETC ()); | |
2774 | return CPP_NAME; | |
2775 | } | |
2776 | else if (c == ' ') | |
2777 | { | |
2778 | CPP_RESERVE (pfile, 2); | |
2779 | if (pfile->output_escapes) | |
2780 | CPP_PUTC_Q (pfile, '\r'); | |
2781 | CPP_PUTC_Q (pfile, c); | |
2782 | return CPP_HSPACE; | |
2783 | } | |
2784 | else | |
2785 | { | |
c1212d2f | 2786 | cpp_ice (pfile, "unrecognized escape \\r%c", c); |
ed45de98 ZW |
2787 | goto get_next; |
2788 | } | |
2789 | } | |
2790 | else | |
2791 | { | |
2792 | /* Backslash newline is ignored. */ | |
2793 | CPP_BUMP_LINE (pfile); | |
2794 | goto get_next; | |
2795 | } | |
7f2935c7 PB |
2796 | |
2797 | case '\n': | |
2798 | CPP_PUTC (pfile, c); | |
2799 | if (pfile->only_seen_white == 0) | |
2800 | pfile->only_seen_white = 1; | |
3fdc651f | 2801 | CPP_BUMP_LINE (pfile); |
80e9dcb4 ZW |
2802 | if (! CPP_OPTIONS (pfile)->no_line_commands) |
2803 | { | |
2804 | pfile->lineno++; | |
2805 | if (CPP_BUFFER (pfile)->lineno != pfile->lineno) | |
2806 | output_line_command (pfile, same_file); | |
2807 | } | |
7f2935c7 PB |
2808 | return CPP_VSPACE; |
2809 | ||
2810 | case '(': token = CPP_LPAREN; goto char1; | |
2811 | case ')': token = CPP_RPAREN; goto char1; | |
2812 | case '{': token = CPP_LBRACE; goto char1; | |
2813 | case '}': token = CPP_RBRACE; goto char1; | |
2814 | case ',': token = CPP_COMMA; goto char1; | |
2815 | case ';': token = CPP_SEMICOLON; goto char1; | |
2816 | ||
2817 | randomchar: | |
2818 | default: | |
2819 | token = CPP_OTHER; | |
2820 | char1: | |
2821 | pfile->only_seen_white = 0; | |
2822 | CPP_PUTC (pfile, c); | |
2823 | return token; | |
2824 | } | |
2825 | } | |
2826 | } | |
2827 | ||
0f41302f MS |
2828 | /* Like cpp_get_token, but skip spaces and comments. */ |
2829 | ||
7f2935c7 PB |
2830 | enum cpp_token |
2831 | cpp_get_non_space_token (pfile) | |
2832 | cpp_reader *pfile; | |
2833 | { | |
2834 | int old_written = CPP_WRITTEN (pfile); | |
2835 | for (;;) | |
2836 | { | |
2837 | enum cpp_token token = cpp_get_token (pfile); | |
2838 | if (token != CPP_COMMENT && token != CPP_POP | |
2839 | && token != CPP_HSPACE && token != CPP_VSPACE) | |
2840 | return token; | |
2841 | CPP_SET_WRITTEN (pfile, old_written); | |
2842 | } | |
2843 | } | |
2844 | ||
0f41302f | 2845 | /* Parse an identifier starting with C. */ |
7f2935c7 | 2846 | |
3fdc651f | 2847 | static void |
7f2935c7 | 2848 | parse_name (pfile, c) |
3fdc651f ZW |
2849 | cpp_reader *pfile; |
2850 | int c; | |
7f2935c7 PB |
2851 | { |
2852 | for (;;) | |
2853 | { | |
a9ae4483 | 2854 | if (! is_idchar(c)) |
7f2935c7 | 2855 | { |
7f2935c7 PB |
2856 | FORWARD (-1); |
2857 | break; | |
2858 | } | |
2859 | ||
9e979f8f | 2860 | if (c == '$' && CPP_PEDANTIC (pfile)) |
487a6e06 | 2861 | cpp_pedwarn (pfile, "`$' in identifier"); |
9e979f8f | 2862 | |
0f41302f | 2863 | CPP_RESERVE(pfile, 2); /* One more for final NUL. */ |
7f2935c7 PB |
2864 | CPP_PUTC_Q (pfile, c); |
2865 | c = GETC(); | |
2866 | if (c == EOF) | |
2867 | break; | |
2868 | } | |
2869 | CPP_NUL_TERMINATE_Q (pfile); | |
3fdc651f ZW |
2870 | return; |
2871 | } | |
2872 | ||
ba412f14 ZW |
2873 | /* Parse and skip over a string starting with C. A single quoted |
2874 | string is treated like a double -- some programs (e.g., troff) are | |
2875 | perverse this way. (However, a single quoted string is not allowed | |
2876 | to extend over multiple lines.) */ | |
3fdc651f | 2877 | static void |
ba412f14 | 2878 | skip_string (pfile, c) |
3fdc651f ZW |
2879 | cpp_reader *pfile; |
2880 | int c; | |
2881 | { | |
2882 | long start_line, start_column; | |
3fdc651f ZW |
2883 | cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column); |
2884 | ||
3fdc651f ZW |
2885 | while (1) |
2886 | { | |
2887 | int cc = GETC(); | |
ba412f14 | 2888 | switch (cc) |
3fdc651f | 2889 | { |
ba412f14 | 2890 | case EOF: |
6ee2c979 ZW |
2891 | cpp_error_with_line (pfile, start_line, start_column, |
2892 | "unterminated string or character constant"); | |
2893 | if (pfile->multiline_string_line != start_line | |
2894 | && pfile->multiline_string_line != 0) | |
2895 | cpp_error_with_line (pfile, | |
2896 | pfile->multiline_string_line, -1, | |
2897 | "possible real start of unterminated constant"); | |
2898 | pfile->multiline_string_line = 0; | |
ba412f14 ZW |
2899 | return; |
2900 | ||
3fdc651f ZW |
2901 | case '\n': |
2902 | CPP_BUMP_LINE (pfile); | |
40c79d58 ZW |
2903 | /* In Fortran and assembly language, silently terminate |
2904 | strings of either variety at end of line. This is a | |
2905 | kludge around not knowing where comments are in these | |
2906 | languages. */ | |
2907 | if (CPP_OPTIONS (pfile)->lang_fortran | |
2908 | || CPP_OPTIONS (pfile)->lang_asm) | |
ba412f14 ZW |
2909 | { |
2910 | FORWARD(-1); | |
2911 | return; | |
2912 | } | |
6ee2c979 | 2913 | /* Character constants may not extend over multiple lines. |
40c79d58 ZW |
2914 | In Standard C, neither may strings. We accept multiline |
2915 | strings as an extension. */ | |
3fdc651f ZW |
2916 | if (c == '\'') |
2917 | { | |
2918 | cpp_error_with_line (pfile, start_line, start_column, | |
2919 | "unterminated character constant"); | |
ba412f14 | 2920 | FORWARD(-1); |
3fdc651f ZW |
2921 | return; |
2922 | } | |
2923 | if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0) | |
40c79d58 ZW |
2924 | cpp_pedwarn_with_line (pfile, start_line, start_column, |
2925 | "string constant runs past end of line"); | |
3fdc651f ZW |
2926 | if (pfile->multiline_string_line == 0) |
2927 | pfile->multiline_string_line = start_line; | |
2928 | break; | |
2929 | ||
2930 | case '\r': | |
ed45de98 ZW |
2931 | if (CPP_BUFFER (pfile)->has_escapes) |
2932 | { | |
c1212d2f | 2933 | cpp_ice (pfile, "\\r escape inside string constant"); |
ed45de98 ZW |
2934 | FORWARD(1); |
2935 | } | |
2936 | else | |
2937 | /* Backslash newline is replaced by nothing at all. */ | |
2938 | CPP_BUMP_LINE (pfile); | |
3fdc651f ZW |
2939 | break; |
2940 | ||
2941 | case '\\': | |
ba412f14 | 2942 | FORWARD(1); |
3fdc651f ZW |
2943 | break; |
2944 | ||
2945 | case '\"': | |
2946 | case '\'': | |
2947 | if (cc == c) | |
2948 | return; | |
2949 | break; | |
2950 | } | |
2951 | } | |
7f2935c7 PB |
2952 | } |
2953 | ||
ba412f14 ZW |
2954 | /* Parse a string and copy it to the output. */ |
2955 | ||
2956 | static void | |
2957 | parse_string (pfile, c) | |
2958 | cpp_reader *pfile; | |
2959 | int c; | |
2960 | { | |
2961 | U_CHAR *start = CPP_BUFFER (pfile)->cur; /* XXX Layering violation */ | |
2962 | U_CHAR *limit; | |
2963 | ||
2964 | skip_string (pfile, c); | |
2965 | ||
2966 | limit = CPP_BUFFER (pfile)->cur; | |
2967 | CPP_RESERVE (pfile, limit - start + 2); | |
2968 | CPP_PUTC_Q (pfile, c); | |
2969 | for (; start < limit; start++) | |
2970 | if (*start != '\r') | |
2971 | CPP_PUTC_Q (pfile, *start); | |
2972 | } | |
2973 | ||
7061aa5a ZW |
2974 | /* Read an assertion into the token buffer, converting to |
2975 | canonical form: `#predicate(a n swe r)' The next non-whitespace | |
2976 | character to read should be the first letter of the predicate. | |
2977 | Returns 0 for syntax error, 1 for bare predicate, 2 for predicate | |
2978 | with answer (see callers for why). In case of 0, an error has been | |
2979 | printed. */ | |
2980 | static int | |
2981 | parse_assertion (pfile) | |
2982 | cpp_reader *pfile; | |
2983 | { | |
2984 | int c, dropwhite; | |
2985 | cpp_skip_hspace (pfile); | |
2986 | c = PEEKC(); | |
a9ae4483 | 2987 | if (! is_idstart(c)) |
782331f4 | 2988 | { |
7061aa5a ZW |
2989 | cpp_error (pfile, "assertion predicate is not an identifier"); |
2990 | return 0; | |
782331f4 | 2991 | } |
7061aa5a ZW |
2992 | CPP_PUTC(pfile, '#'); |
2993 | FORWARD(1); | |
2994 | parse_name(pfile, c); | |
782331f4 | 2995 | |
7061aa5a ZW |
2996 | c = PEEKC(); |
2997 | if (c != '(') | |
2998 | { | |
a9ae4483 | 2999 | if (is_hspace(c) || c == '\r') |
7061aa5a ZW |
3000 | cpp_skip_hspace (pfile); |
3001 | c = PEEKC(); | |
3002 | } | |
3003 | if (c != '(') | |
3004 | return 1; | |
3005 | ||
3006 | CPP_PUTC(pfile, '('); | |
3007 | FORWARD(1); | |
3008 | dropwhite = 1; | |
3009 | while ((c = GETC()) != ')') | |
3010 | { | |
a9ae4483 | 3011 | if (is_space(c)) |
7061aa5a ZW |
3012 | { |
3013 | if (! dropwhite) | |
3014 | { | |
3015 | CPP_PUTC(pfile, ' '); | |
3016 | dropwhite = 1; | |
3017 | } | |
3018 | } | |
7061aa5a ZW |
3019 | else if (c == '\n' || c == EOF) |
3020 | { | |
3021 | if (c == '\n') FORWARD(-1); | |
3022 | cpp_error (pfile, "un-terminated assertion answer"); | |
3023 | return 0; | |
3024 | } | |
3fdc651f | 3025 | else if (c == '\r') |
ed45de98 | 3026 | /* \r cannot be a macro escape here. */ |
3fdc651f | 3027 | CPP_BUMP_LINE (pfile); |
7061aa5a ZW |
3028 | else |
3029 | { | |
3fdc651f | 3030 | CPP_PUTC (pfile, c); |
7061aa5a ZW |
3031 | dropwhite = 0; |
3032 | } | |
3033 | } | |
3034 | ||
3035 | if (pfile->limit[-1] == ' ') | |
3036 | pfile->limit[-1] = ')'; | |
3037 | else if (pfile->limit[-1] == '(') | |
3038 | { | |
3039 | cpp_error (pfile, "empty token sequence in assertion"); | |
3040 | return 0; | |
3041 | } | |
3042 | else | |
3fdc651f | 3043 | CPP_PUTC (pfile, ')'); |
7061aa5a | 3044 | |
3fdc651f | 3045 | CPP_NUL_TERMINATE (pfile); |
7061aa5a | 3046 | return 2; |
782331f4 | 3047 | } |
7061aa5a | 3048 | |
7f2935c7 | 3049 | static int |
941e09b6 | 3050 | do_assert (pfile, keyword) |
7f2935c7 | 3051 | cpp_reader *pfile; |
2ac9349e | 3052 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 3053 | { |
7061aa5a ZW |
3054 | char *sym; |
3055 | int ret, c; | |
3056 | HASHNODE *base, *this; | |
3057 | int baselen, thislen; | |
7f2935c7 | 3058 | |
83ecd27e | 3059 | if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing) |
7f2935c7 PB |
3060 | cpp_pedwarn (pfile, "ANSI C does not allow `#assert'"); |
3061 | ||
3062 | cpp_skip_hspace (pfile); | |
8db99db2 | 3063 | sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */ |
7061aa5a ZW |
3064 | ret = parse_assertion (pfile); |
3065 | if (ret == 0) | |
7f2935c7 | 3066 | goto error; |
7061aa5a ZW |
3067 | else if (ret == 1) |
3068 | { | |
3069 | cpp_error (pfile, "missing token-sequence in `#assert'"); | |
7f2935c7 PB |
3070 | goto error; |
3071 | } | |
7061aa5a | 3072 | |
7f2935c7 | 3073 | cpp_skip_hspace (pfile); |
7061aa5a | 3074 | c = PEEKC(); |
7f2935c7 | 3075 | if (c != EOF && c != '\n') |
7061aa5a ZW |
3076 | { |
3077 | cpp_error (pfile, "junk at end of `#assert'"); | |
3078 | goto error; | |
3079 | } | |
7f2935c7 | 3080 | |
7061aa5a ZW |
3081 | thislen = strlen (sym); |
3082 | baselen = index (sym, '(') - sym; | |
b0699dad | 3083 | this = _cpp_lookup (pfile, sym, thislen); |
7061aa5a ZW |
3084 | if (this) |
3085 | { | |
3086 | cpp_warning (pfile, "`%s' re-asserted", sym); | |
3087 | goto error; | |
7f2935c7 PB |
3088 | } |
3089 | ||
b0699dad | 3090 | base = _cpp_lookup (pfile, sym, baselen); |
7061aa5a | 3091 | if (! base) |
b0699dad | 3092 | base = _cpp_install (pfile, sym, baselen, T_ASSERT, 0); |
7061aa5a ZW |
3093 | else if (base->type != T_ASSERT) |
3094 | { | |
3095 | /* Token clash - but with what?! */ | |
c1212d2f | 3096 | cpp_ice (pfile, "base->type != T_ASSERT in do_assert"); |
7061aa5a | 3097 | goto error; |
7f2935c7 | 3098 | } |
7061aa5a | 3099 | |
b0699dad | 3100 | this = _cpp_install (pfile, sym, thislen, T_ASSERT, |
bb52fa7f | 3101 | (char *)base->value.aschain); |
7061aa5a ZW |
3102 | base->value.aschain = this; |
3103 | ||
8db99db2 | 3104 | pfile->limit = (unsigned char *) sym; /* Pop */ |
7f2935c7 | 3105 | return 0; |
7061aa5a | 3106 | |
7f2935c7 | 3107 | error: |
7f2935c7 | 3108 | skip_rest_of_line (pfile); |
3caee4a8 ZW |
3109 | pfile->limit = (unsigned char *) sym; /* Pop */ |
3110 | return 0; | |
7f2935c7 | 3111 | } |
7061aa5a | 3112 | |
7f2935c7 | 3113 | static int |
941e09b6 | 3114 | do_unassert (pfile, keyword) |
7f2935c7 | 3115 | cpp_reader *pfile; |
2ac9349e | 3116 | const struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 3117 | { |
7061aa5a ZW |
3118 | int c, ret; |
3119 | char *sym; | |
3120 | long baselen, thislen; | |
3121 | HASHNODE *base, *this, *next; | |
3122 | ||
83ecd27e | 3123 | if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing) |
7f2935c7 PB |
3124 | cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'"); |
3125 | ||
3126 | cpp_skip_hspace (pfile); | |
3127 | ||
8db99db2 | 3128 | sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */ |
7061aa5a ZW |
3129 | ret = parse_assertion (pfile); |
3130 | if (ret == 0) | |
3131 | goto error; | |
3132 | ||
7f2935c7 PB |
3133 | cpp_skip_hspace (pfile); |
3134 | c = PEEKC (); | |
3135 | if (c != EOF && c != '\n') | |
3136 | cpp_error (pfile, "junk at end of `#unassert'"); | |
7f2935c7 | 3137 | |
7061aa5a ZW |
3138 | thislen = strlen (sym); |
3139 | if (ret == 1) | |
3140 | { | |
b0699dad | 3141 | base = _cpp_lookup (pfile, sym, thislen); |
7061aa5a ZW |
3142 | if (! base) |
3143 | goto error; /* It isn't an error to #undef what isn't #defined, | |
3144 | so it isn't an error to #unassert what isn't | |
3145 | #asserted either. */ | |
3146 | ||
3147 | for (this = base->value.aschain; this; this = next) | |
3148 | { | |
3149 | next = this->value.aschain; | |
b0699dad | 3150 | _cpp_delete_macro (this); |
7f2935c7 | 3151 | } |
b0699dad | 3152 | _cpp_delete_macro (base); |
7f2935c7 | 3153 | } |
7061aa5a ZW |
3154 | else |
3155 | { | |
3156 | baselen = index (sym, '(') - sym; | |
b0699dad | 3157 | base = _cpp_lookup (pfile, sym, baselen); |
7061aa5a | 3158 | if (! base) goto error; |
b0699dad | 3159 | this = _cpp_lookup (pfile, sym, thislen); |
7061aa5a ZW |
3160 | if (! this) goto error; |
3161 | ||
3162 | next = base; | |
3163 | while (next->value.aschain != this) | |
3164 | next = next->value.aschain; | |
7f2935c7 | 3165 | |
7061aa5a | 3166 | next->value.aschain = this->value.aschain; |
b0699dad | 3167 | _cpp_delete_macro (this); |
7061aa5a ZW |
3168 | |
3169 | if (base->value.aschain == NULL) | |
b0699dad | 3170 | _cpp_delete_macro (base); /* Last answer for this predicate deleted. */ |
7061aa5a ZW |
3171 | } |
3172 | ||
8db99db2 | 3173 | pfile->limit = (unsigned char *) sym; /* Pop */ |
7f2935c7 PB |
3174 | return 0; |
3175 | error: | |
7f2935c7 | 3176 | skip_rest_of_line (pfile); |
3caee4a8 ZW |
3177 | pfile->limit = (unsigned char *) sym; /* Pop */ |
3178 | return 0; | |
7f2935c7 | 3179 | } |
7f2935c7 | 3180 | |
0b22d65c ZW |
3181 | /* Process STR as if it appeared as the body of an #unassert. */ |
3182 | void | |
3183 | cpp_unassert (pfile, str) | |
3184 | cpp_reader *pfile; | |
3185 | unsigned char *str; | |
3186 | { | |
3187 | if (cpp_push_buffer (pfile, str, strlen (str)) != NULL) | |
3188 | { | |
ba412f14 | 3189 | do_unassert (pfile, NULL); |
0b22d65c ZW |
3190 | cpp_pop_buffer (pfile); |
3191 | } | |
3192 | } | |
3193 | ||
cf4ed945 ZW |
3194 | /* Remember the current position of PFILE so it may be returned to |
3195 | after looking ahead a bit. | |
3196 | ||
3197 | Note that when you set a mark, you _must_ return to that mark. You | |
3198 | may not forget about it and continue parsing. You may not pop a | |
3199 | buffer with an active mark. You may not call CPP_BUMP_LINE while a | |
3200 | mark is active. */ | |
0f41302f | 3201 | |
564ad5f4 | 3202 | static void |
3fdc651f | 3203 | parse_set_mark (pfile) |
7f2935c7 PB |
3204 | cpp_reader *pfile; |
3205 | { | |
3fdc651f | 3206 | cpp_buffer *ip = CPP_BUFFER (pfile); |
564ad5f4 ZW |
3207 | if (ACTIVE_MARK_P()) |
3208 | cpp_ice (pfile, "mark active in parse_set_mark"); | |
0f41302f | 3209 | |
3fdc651f | 3210 | ip->mark = ip->cur - ip->buf; |
7f2935c7 PB |
3211 | } |
3212 | ||
3fdc651f ZW |
3213 | /* Backup the current position of PFILE to that saved in its mark, |
3214 | and clear the mark. */ | |
7f2935c7 | 3215 | |
564ad5f4 | 3216 | static void |
3fdc651f | 3217 | parse_goto_mark (pfile) |
7f2935c7 PB |
3218 | cpp_reader *pfile; |
3219 | { | |
3fdc651f | 3220 | cpp_buffer *ip = CPP_BUFFER (pfile); |
564ad5f4 ZW |
3221 | if (!ACTIVE_MARK_P()) |
3222 | cpp_ice (pfile, "mark not active in parse_goto_mark"); | |
3fdc651f ZW |
3223 | |
3224 | ip->cur = ip->buf + ip->mark; | |
3225 | ip->mark = -1; | |
7f2935c7 | 3226 | } |