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