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