]>
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 | |
6de1e2a9 ZW |
1211 | /* Interpret #line command. |
1212 | Note that the filename string (if any) is treated as if it were an | |
1213 | include filename. That means no escape handling. */ | |
7f2935c7 PB |
1214 | |
1215 | static int | |
6de1e2a9 | 1216 | do_line (pfile, keyword) |
7f2935c7 | 1217 | cpp_reader *pfile; |
6de1e2a9 | 1218 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1219 | { |
6de1e2a9 ZW |
1220 | cpp_buffer *ip = CPP_BUFFER (pfile); |
1221 | int new_lineno; | |
7f2935c7 | 1222 | long old_written = CPP_WRITTEN (pfile); |
6de1e2a9 ZW |
1223 | enum file_change_code file_change = same_file; |
1224 | enum cpp_token token; | |
1225 | char *x; | |
7f2935c7 | 1226 | |
6de1e2a9 | 1227 | token = get_directive_token (pfile); |
7f2935c7 | 1228 | |
6de1e2a9 | 1229 | if (token != CPP_NUMBER) |
cfb3ee16 | 1230 | { |
6de1e2a9 ZW |
1231 | cpp_error (pfile, "token after `#line' is not an integer"); |
1232 | goto bad_line_directive; | |
cfb3ee16 RK |
1233 | } |
1234 | ||
6de1e2a9 ZW |
1235 | new_lineno = strtol (pfile->token_buffer + old_written, &x, 10); |
1236 | if (x[0] != '\0') | |
7f2935c7 | 1237 | { |
6de1e2a9 ZW |
1238 | cpp_error (pfile, "token after `#line' is not an integer"); |
1239 | goto bad_line_directive; | |
1240 | } | |
1241 | CPP_SET_WRITTEN (pfile, old_written); | |
1242 | ||
1243 | if (CPP_PEDANTIC (pfile) && new_lineno <= 0) | |
1244 | cpp_pedwarn (pfile, "line number out of range in `#line' command"); | |
7f2935c7 | 1245 | |
7f2935c7 | 1246 | token = get_directive_token (pfile); |
7f2935c7 PB |
1247 | |
1248 | if (token == CPP_STRING) | |
1249 | { | |
6de1e2a9 ZW |
1250 | U_CHAR *fname = pfile->token_buffer + old_written + 1; |
1251 | U_CHAR *end_name = CPP_PWRITTEN (pfile) - 1; | |
1252 | long num_start = CPP_WRITTEN (pfile); | |
add7091b | 1253 | |
6de1e2a9 ZW |
1254 | token = get_directive_token (pfile); |
1255 | if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) | |
1256 | { | |
1257 | U_CHAR *p = pfile->token_buffer + num_start; | |
1258 | if (CPP_PEDANTIC (pfile)) | |
1259 | cpp_pedwarn (pfile, "garbage at end of `#line' command"); | |
add7091b | 1260 | |
6de1e2a9 ZW |
1261 | if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0') |
1262 | { | |
1263 | cpp_error (pfile, "invalid format `#line' command"); | |
1264 | goto bad_line_directive; | |
1265 | } | |
1266 | if (*p == '1') | |
1267 | file_change = enter_file; | |
1268 | else if (*p == '2') | |
1269 | file_change = leave_file; | |
1270 | else if (*p == '3') | |
1271 | ip->system_header_p = 1; | |
1272 | else /* if (*p == '4') */ | |
1273 | ip->system_header_p = 2; | |
5538ada6 ZW |
1274 | |
1275 | CPP_SET_WRITTEN (pfile, num_start); | |
1276 | token = get_directive_token (pfile); | |
1277 | p = pfile->token_buffer + num_start; | |
1278 | if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) | |
1279 | { | |
1280 | ip->system_header_p = *p == '3' ? 1 : 2; | |
1281 | token = get_directive_token (pfile); | |
1282 | } | |
1283 | if (token != CPP_VSPACE) | |
1284 | { | |
1285 | cpp_error (pfile, "invalid format `#line' command"); | |
1286 | goto bad_line_directive; | |
1287 | } | |
1288 | } | |
1289 | ||
1290 | *end_name = '\0'; | |
1291 | ||
1292 | if (strcmp (fname, ip->nominal_fname)) | |
1293 | { | |
1294 | char *newname, *oldname; | |
1295 | if (!strcmp (fname, ip->fname)) | |
1296 | newname = ip->fname; | |
1297 | else if (ip->last_nominal_fname | |
1298 | && !strcmp (fname, ip->last_nominal_fname)) | |
1299 | newname = ip->last_nominal_fname; | |
1300 | else | |
1301 | newname = xstrdup (fname); | |
7f2935c7 | 1302 | |
5538ada6 ZW |
1303 | oldname = ip->nominal_fname; |
1304 | ip->nominal_fname = newname; | |
7f2935c7 | 1305 | |
5538ada6 ZW |
1306 | if (ip->last_nominal_fname |
1307 | && ip->last_nominal_fname != oldname | |
4d9a1b48 ZW |
1308 | && ip->last_nominal_fname != newname |
1309 | && ip->last_nominal_fname != ip->fname) | |
5538ada6 ZW |
1310 | free (ip->last_nominal_fname); |
1311 | ||
1312 | if (newname == ip->fname) | |
1313 | ip->last_nominal_fname = NULL; | |
1314 | else | |
1315 | ip->last_nominal_fname = oldname; | |
1316 | } | |
7f2935c7 | 1317 | } |
5538ada6 ZW |
1318 | else if (token != CPP_VSPACE && token != CPP_EOF) |
1319 | { | |
1320 | cpp_error (pfile, "token after `#line %d' is not a string", new_lineno); | |
1321 | goto bad_line_directive; | |
1322 | } | |
1323 | ||
1324 | /* The Newline at the end of this line remains to be processed. | |
1325 | To put the next line at the specified line number, | |
1326 | we must store a line number now that is one less. */ | |
1327 | ip->lineno = new_lineno - 1; | |
1328 | CPP_SET_WRITTEN (pfile, old_written); | |
80e9dcb4 | 1329 | output_line_command (pfile, file_change); |
5538ada6 | 1330 | return 0; |
7f2935c7 | 1331 | |
7f2935c7 PB |
1332 | bad_line_directive: |
1333 | skip_rest_of_line (pfile); | |
1334 | CPP_SET_WRITTEN (pfile, old_written); | |
7f2935c7 PB |
1335 | return 0; |
1336 | } | |
1337 | ||
5538ada6 ZW |
1338 | /* Remove the definition of a symbol from the symbol table. |
1339 | According to the C standard, it is not an error to undef | |
1340 | something that has no definitions. */ | |
7f2935c7 | 1341 | static int |
941e09b6 | 1342 | do_undef (pfile, keyword) |
7f2935c7 PB |
1343 | cpp_reader *pfile; |
1344 | struct directive *keyword; | |
7f2935c7 PB |
1345 | { |
1346 | int sym_length; | |
1347 | HASHNODE *hp; | |
941e09b6 ZW |
1348 | U_CHAR *buf, *name, *limit; |
1349 | int c; | |
1350 | long here = CPP_WRITTEN (pfile); | |
1351 | enum cpp_token token; | |
1352 | ||
1353 | cpp_skip_hspace (pfile); | |
1354 | c = GETC(); | |
1355 | if (! is_idstart[c]) | |
1356 | { | |
1357 | cpp_error (pfile, "token after #undef is not an identifier"); | |
1358 | skip_rest_of_line (pfile); | |
1359 | return 1; | |
1360 | } | |
1361 | ||
1362 | parse_name (pfile, c); | |
1363 | buf = pfile->token_buffer + here; | |
1364 | limit = CPP_PWRITTEN(pfile); | |
1365 | ||
1366 | /* Copy out the token so we can pop the token buffer. */ | |
e7553be5 | 1367 | name = (U_CHAR *) alloca (limit - buf + 1); |
941e09b6 ZW |
1368 | bcopy(buf, name, limit - buf); |
1369 | name[limit - buf] = '\0'; | |
1370 | ||
1371 | token = get_directive_token (pfile); | |
16deb3fb | 1372 | if (token != CPP_VSPACE && token != CPP_POP) |
941e09b6 ZW |
1373 | { |
1374 | cpp_pedwarn (pfile, "junk on line after #undef"); | |
1375 | skip_rest_of_line (pfile); | |
1376 | } | |
1377 | ||
1378 | CPP_SET_WRITTEN (pfile, here); | |
7f2935c7 | 1379 | |
ab87f8c8 | 1380 | sym_length = check_macro_name (pfile, buf, 0); |
7f2935c7 | 1381 | |
941e09b6 | 1382 | while ((hp = cpp_lookup (pfile, name, sym_length, -1)) != NULL) |
7f2935c7 PB |
1383 | { |
1384 | /* If we are generating additional info for debugging (with -g) we | |
1385 | need to pass through all effective #undef commands. */ | |
1386 | if (CPP_OPTIONS (pfile)->debug_output && keyword) | |
3caee4a8 | 1387 | pass_thru_directive (name, sym_length, pfile, keyword); |
7f2935c7 PB |
1388 | if (hp->type != T_MACRO) |
1389 | cpp_warning (pfile, "undefining `%s'", hp->name); | |
1390 | delete_macro (hp); | |
1391 | } | |
1392 | ||
7f2935c7 PB |
1393 | return 0; |
1394 | } | |
941e09b6 ZW |
1395 | |
1396 | /* Wrap do_undef for -U processing. */ | |
6de1e2a9 | 1397 | void |
941e09b6 ZW |
1398 | cpp_undef (pfile, macro) |
1399 | cpp_reader *pfile; | |
1400 | U_CHAR *macro; | |
1401 | { | |
6de1e2a9 | 1402 | if (cpp_push_buffer (pfile, macro, strlen (macro))) |
941e09b6 | 1403 | { |
6de1e2a9 ZW |
1404 | do_undef (pfile, NULL); |
1405 | cpp_pop_buffer (pfile); | |
941e09b6 ZW |
1406 | } |
1407 | } | |
1408 | ||
7f2935c7 PB |
1409 | \f |
1410 | /* | |
1411 | * Report an error detected by the program we are processing. | |
1412 | * Use the text of the line in the error message. | |
1413 | * (We use error because it prints the filename & line#.) | |
1414 | */ | |
1415 | ||
1416 | static int | |
941e09b6 | 1417 | do_error (pfile, keyword) |
7f2935c7 | 1418 | cpp_reader *pfile; |
487a6e06 | 1419 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1420 | { |
941e09b6 ZW |
1421 | long here = CPP_WRITTEN (pfile); |
1422 | U_CHAR *text; | |
1423 | copy_rest_of_line (pfile); | |
1424 | text = pfile->token_buffer + here; | |
1425 | SKIP_WHITE_SPACE(text); | |
1426 | ||
1427 | cpp_error (pfile, "#error %s", text); | |
1428 | CPP_SET_WRITTEN (pfile, here); | |
7f2935c7 PB |
1429 | return 0; |
1430 | } | |
1431 | ||
1432 | /* | |
1433 | * Report a warning detected by the program we are processing. | |
1434 | * Use the text of the line in the warning message, then continue. | |
7f2935c7 PB |
1435 | */ |
1436 | ||
1437 | static int | |
941e09b6 | 1438 | do_warning (pfile, keyword) |
7f2935c7 | 1439 | cpp_reader *pfile; |
487a6e06 | 1440 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1441 | { |
941e09b6 ZW |
1442 | U_CHAR *text; |
1443 | long here = CPP_WRITTEN(pfile); | |
1444 | copy_rest_of_line (pfile); | |
1445 | text = pfile->token_buffer + here; | |
1446 | SKIP_WHITE_SPACE(text); | |
f5963e61 JL |
1447 | |
1448 | if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) | |
487a6e06 | 1449 | cpp_pedwarn (pfile, "ANSI C does not allow `#warning'"); |
f5963e61 | 1450 | |
cfb3ee16 RK |
1451 | /* Use `pedwarn' not `warning', because #warning isn't in the C Standard; |
1452 | if -pedantic-errors is given, #warning should cause an error. */ | |
941e09b6 ZW |
1453 | cpp_pedwarn (pfile, "#warning %s", text); |
1454 | CPP_SET_WRITTEN (pfile, here); | |
7f2935c7 PB |
1455 | return 0; |
1456 | } | |
1457 | ||
3caee4a8 ZW |
1458 | /* Report program identification. |
1459 | This is not precisely what cccp does with #ident, however I believe | |
1460 | it matches `closely enough' (behavior is identical as long as there | |
1461 | are no macros on the #ident line, which is pathological in my opinion). */ | |
7f2935c7 PB |
1462 | |
1463 | static int | |
941e09b6 | 1464 | do_ident (pfile, keyword) |
7f2935c7 | 1465 | cpp_reader *pfile; |
487a6e06 | 1466 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1467 | { |
7f2935c7 PB |
1468 | /* Allow #ident in system headers, since that's not user's fault. */ |
1469 | if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p) | |
1470 | cpp_pedwarn (pfile, "ANSI C does not allow `#ident'"); | |
1471 | ||
3caee4a8 ZW |
1472 | CPP_PUTS (pfile, "#ident ", 7); |
1473 | cpp_skip_hspace (pfile); | |
1474 | copy_rest_of_line (pfile); | |
7f2935c7 PB |
1475 | |
1476 | return 0; | |
1477 | } | |
1478 | ||
941e09b6 ZW |
1479 | /* Just check for some recognized pragmas that need validation here, |
1480 | and leave the text in the token buffer to be output. */ | |
7f2935c7 PB |
1481 | |
1482 | static int | |
941e09b6 | 1483 | do_pragma (pfile, keyword) |
7f2935c7 | 1484 | cpp_reader *pfile; |
487a6e06 | 1485 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1486 | { |
3caee4a8 | 1487 | long here; |
941e09b6 | 1488 | U_CHAR *buf; |
3caee4a8 ZW |
1489 | |
1490 | CPP_PUTS (pfile, "#pragma ", 8); | |
1491 | cpp_skip_hspace (pfile); | |
941e09b6 | 1492 | |
3caee4a8 | 1493 | here = CPP_WRITTEN (pfile); |
941e09b6 ZW |
1494 | copy_rest_of_line (pfile); |
1495 | buf = pfile->token_buffer + here; | |
941e09b6 | 1496 | |
add7091b ZW |
1497 | if (!strncmp (buf, "once", 4)) |
1498 | { | |
1499 | cpp_buffer *ip = NULL; | |
add7091b ZW |
1500 | |
1501 | /* Allow #pragma once in system headers, since that's not the user's | |
1502 | fault. */ | |
1503 | if (!CPP_BUFFER (pfile)->system_header_p) | |
1504 | cpp_warning (pfile, "`#pragma once' is obsolete"); | |
1505 | ||
1506 | for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) | |
1507 | { | |
1508 | if (ip == CPP_NULL_BUFFER (pfile)) | |
1509 | return 0; | |
1510 | if (ip->fname != NULL) | |
1511 | break; | |
1512 | } | |
7f2935c7 | 1513 | |
0b3d776a ZW |
1514 | if (CPP_PREV_BUFFER (ip) == CPP_NULL_BUFFER (pfile)) |
1515 | cpp_warning (pfile, "`#pragma once' outside include file"); | |
1516 | else | |
1517 | ip->ihash->control_macro = ""; /* never repeat */ | |
1518 | } | |
3caee4a8 | 1519 | else if (!strncmp (buf, "implementation", 14)) |
0b3d776a ZW |
1520 | { |
1521 | /* Be quiet about `#pragma implementation' for a file only if it hasn't | |
1522 | been included yet. */ | |
1523 | struct include_hash *ptr; | |
1524 | U_CHAR *p = buf + 14, *fname, *fcopy; | |
1525 | SKIP_WHITE_SPACE (p); | |
1526 | if (*p == '\n' || *p != '\"') | |
1527 | return 0; | |
1528 | ||
1529 | fname = p + 1; | |
1530 | p = (U_CHAR *) index (fname, '\"'); | |
1531 | ||
e7553be5 | 1532 | fcopy = (U_CHAR *) alloca (p - fname + 1); |
0b3d776a ZW |
1533 | bcopy (fname, fcopy, p - fname); |
1534 | fcopy[p-fname] = '\0'; | |
1535 | ||
1536 | ptr = include_hash (pfile, fcopy, 0); | |
1537 | if (ptr) | |
1538 | cpp_warning (pfile, | |
1539 | "`#pragma implementation' for `%s' appears after file is included", | |
1540 | fcopy); | |
7f2935c7 | 1541 | } |
7f2935c7 PB |
1542 | |
1543 | return 0; | |
1544 | } | |
1545 | ||
72e19470 | 1546 | #ifdef SCCS_DIRECTIVE |
7f2935c7 PB |
1547 | /* Just ignore #sccs, on systems where we define it at all. */ |
1548 | ||
1549 | static int | |
941e09b6 | 1550 | do_sccs (pfile, keyword) |
7f2935c7 | 1551 | cpp_reader *pfile; |
487a6e06 | 1552 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 PB |
1553 | { |
1554 | if (CPP_PEDANTIC (pfile)) | |
1555 | cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'"); | |
941e09b6 | 1556 | skip_rest_of_line (pfile); |
7f2935c7 PB |
1557 | return 0; |
1558 | } | |
72e19470 | 1559 | #endif |
7f2935c7 PB |
1560 | \f |
1561 | /* | |
1562 | * handle #if command by | |
1563 | * 1) inserting special `defined' keyword into the hash table | |
1564 | * that gets turned into 0 or 1 by special_symbol (thus, | |
1565 | * if the luser has a symbol called `defined' already, it won't | |
1566 | * work inside the #if command) | |
1567 | * 2) rescan the input into a temporary output buffer | |
1568 | * 3) pass the output buffer to the yacc parser and collect a value | |
1569 | * 4) clean up the mess left from steps 1 and 2. | |
1570 | * 5) call conditional_skip to skip til the next #endif (etc.), | |
1571 | * or not, depending on the value from step 3. | |
1572 | */ | |
1573 | ||
1574 | static int | |
941e09b6 | 1575 | do_if (pfile, keyword) |
7f2935c7 | 1576 | cpp_reader *pfile; |
487a6e06 | 1577 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1578 | { |
e915b770 | 1579 | HOST_WIDEST_INT value = eval_if_expression (pfile); |
7f2935c7 PB |
1580 | conditional_skip (pfile, value == 0, T_IF, NULL_PTR); |
1581 | return 0; | |
1582 | } | |
1583 | ||
1584 | /* | |
1585 | * handle a #elif directive by not changing if_stack either. | |
1586 | * see the comment above do_else. | |
1587 | */ | |
1588 | ||
1589 | static int | |
941e09b6 | 1590 | do_elif (pfile, keyword) |
7f2935c7 | 1591 | cpp_reader *pfile; |
487a6e06 | 1592 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 1593 | { |
7f2935c7 PB |
1594 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) { |
1595 | cpp_error (pfile, "`#elif' not within a conditional"); | |
1596 | return 0; | |
1597 | } else { | |
1598 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) { | |
1599 | cpp_error (pfile, "`#elif' after `#else'"); | |
1600 | #if 0 | |
1601 | fprintf (stderr, " (matches line %d", pfile->if_stack->lineno); | |
1602 | #endif | |
1603 | if (pfile->if_stack->fname != NULL && CPP_BUFFER (pfile)->fname != NULL | |
1604 | && strcmp (pfile->if_stack->fname, | |
1605 | CPP_BUFFER (pfile)->nominal_fname) != 0) | |
1606 | fprintf (stderr, ", file %s", pfile->if_stack->fname); | |
1607 | fprintf (stderr, ")\n"); | |
1608 | } | |
1609 | pfile->if_stack->type = T_ELIF; | |
1610 | } | |
1611 | ||
1612 | if (pfile->if_stack->if_succeeded) | |
ed705a82 | 1613 | skip_if_group (pfile); |
7f2935c7 | 1614 | else { |
e915b770 | 1615 | HOST_WIDEST_INT value = eval_if_expression (pfile); |
7f2935c7 | 1616 | if (value == 0) |
ed705a82 | 1617 | skip_if_group (pfile); |
7f2935c7 PB |
1618 | else { |
1619 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | |
80e9dcb4 | 1620 | output_line_command (pfile, same_file); |
7f2935c7 PB |
1621 | } |
1622 | } | |
1623 | return 0; | |
1624 | } | |
1625 | ||
1626 | /* | |
1627 | * evaluate a #if expression in BUF, of length LENGTH, | |
1628 | * then parse the result as a C expression and return the value as an int. | |
1629 | */ | |
0f41302f | 1630 | |
e915b770 | 1631 | static HOST_WIDEST_INT |
941e09b6 | 1632 | eval_if_expression (pfile) |
7f2935c7 | 1633 | cpp_reader *pfile; |
7f2935c7 | 1634 | { |
e915b770 | 1635 | HOST_WIDEST_INT value; |
7f2935c7 PB |
1636 | long old_written = CPP_WRITTEN (pfile); |
1637 | ||
7f2935c7 | 1638 | pfile->pcp_inside_if = 1; |
7f2935c7 PB |
1639 | value = cpp_parse_expr (pfile); |
1640 | pfile->pcp_inside_if = 0; | |
7f2935c7 PB |
1641 | |
1642 | CPP_SET_WRITTEN (pfile, old_written); /* Pop */ | |
1643 | ||
1644 | return value; | |
1645 | } | |
1646 | ||
1647 | /* | |
1648 | * routine to handle ifdef/ifndef. Try to look up the symbol, | |
1649 | * then do or don't skip to the #endif/#else/#elif depending | |
1650 | * on what directive is actually being processed. | |
1651 | */ | |
1652 | ||
1653 | static int | |
941e09b6 | 1654 | do_xifdef (pfile, keyword) |
7f2935c7 PB |
1655 | cpp_reader *pfile; |
1656 | struct directive *keyword; | |
7f2935c7 PB |
1657 | { |
1658 | int skip; | |
1659 | cpp_buffer *ip = CPP_BUFFER (pfile); | |
0f41302f | 1660 | U_CHAR *ident; |
7f2935c7 PB |
1661 | int ident_length; |
1662 | enum cpp_token token; | |
1663 | int start_of_file = 0; | |
1664 | U_CHAR *control_macro = 0; | |
1665 | int old_written = CPP_WRITTEN (pfile); | |
1666 | ||
1667 | /* Detect a #ifndef at start of file (not counting comments). */ | |
1668 | if (ip->fname != 0 && keyword->type == T_IFNDEF) | |
1669 | start_of_file = pfile->only_seen_white == 2; | |
1670 | ||
1671 | pfile->no_macro_expand++; | |
1672 | token = get_directive_token (pfile); | |
1673 | pfile->no_macro_expand--; | |
1674 | ||
1675 | ident = pfile->token_buffer + old_written; | |
1676 | ident_length = CPP_WRITTEN (pfile) - old_written; | |
1677 | CPP_SET_WRITTEN (pfile, old_written); /* Pop */ | |
1678 | ||
1679 | if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF) | |
1680 | { | |
1681 | skip = (keyword->type == T_IFDEF); | |
1682 | if (! CPP_TRADITIONAL (pfile)) | |
1683 | cpp_pedwarn (pfile, "`#%s' with no argument", keyword->name); | |
1684 | } | |
1685 | else if (token == CPP_NAME) | |
1686 | { | |
1687 | HASHNODE *hp = cpp_lookup (pfile, ident, ident_length, -1); | |
1688 | skip = (hp == NULL) ^ (keyword->type == T_IFNDEF); | |
1689 | if (start_of_file && !skip) | |
1690 | { | |
1691 | control_macro = (U_CHAR *) xmalloc (ident_length + 1); | |
1692 | bcopy (ident, control_macro, ident_length + 1); | |
1693 | } | |
1694 | } | |
1695 | else | |
1696 | { | |
1697 | skip = (keyword->type == T_IFDEF); | |
1698 | if (! CPP_TRADITIONAL (pfile)) | |
1699 | cpp_error (pfile, "`#%s' with invalid argument", keyword->name); | |
1700 | } | |
1701 | ||
1702 | if (!CPP_TRADITIONAL (pfile)) | |
1703 | { int c; | |
1704 | cpp_skip_hspace (pfile); | |
1705 | c = PEEKC (); | |
1706 | if (c != EOF && c != '\n') | |
1707 | cpp_pedwarn (pfile, "garbage at end of `#%s' argument", keyword->name); | |
1708 | } | |
1709 | skip_rest_of_line (pfile); | |
1710 | ||
1711 | #if 0 | |
1712 | if (pcp_outfile) { | |
1713 | /* Output a precondition for this macro. */ | |
1714 | if (hp && hp->value.defn->predefined) | |
1715 | fprintf (pcp_outfile, "#define %s\n", hp->name); | |
1716 | else { | |
1717 | U_CHAR *cp = buf; | |
1718 | fprintf (pcp_outfile, "#undef "); | |
1719 | while (is_idchar[*cp]) /* Ick! */ | |
1720 | fputc (*cp++, pcp_outfile); | |
1721 | putc ('\n', pcp_outfile); | |
1722 | } | |
1723 | #endif | |
1724 | ||
1725 | conditional_skip (pfile, skip, T_IF, control_macro); | |
1726 | return 0; | |
1727 | } | |
1728 | ||
1729 | /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead. | |
1730 | If this is a #ifndef starting at the beginning of a file, | |
1731 | CONTROL_MACRO is the macro name tested by the #ifndef. | |
1732 | Otherwise, CONTROL_MACRO is 0. */ | |
1733 | ||
1734 | static void | |
1735 | conditional_skip (pfile, skip, type, control_macro) | |
1736 | cpp_reader *pfile; | |
1737 | int skip; | |
1738 | enum node_type type; | |
1739 | U_CHAR *control_macro; | |
1740 | { | |
1741 | IF_STACK_FRAME *temp; | |
1742 | ||
1743 | temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME)); | |
1744 | temp->fname = CPP_BUFFER (pfile)->nominal_fname; | |
1745 | #if 0 | |
1746 | temp->lineno = CPP_BUFFER (pfile)->lineno; | |
1747 | #endif | |
1748 | temp->next = pfile->if_stack; | |
1749 | temp->control_macro = control_macro; | |
1750 | pfile->if_stack = temp; | |
1751 | ||
1752 | pfile->if_stack->type = type; | |
1753 | ||
1754 | if (skip != 0) { | |
ed705a82 | 1755 | skip_if_group (pfile); |
7f2935c7 PB |
1756 | return; |
1757 | } else { | |
1758 | ++pfile->if_stack->if_succeeded; | |
80e9dcb4 | 1759 | output_line_command (pfile, same_file); |
7f2935c7 PB |
1760 | } |
1761 | } | |
1762 | ||
ed705a82 ZW |
1763 | /* Subroutine of skip_if_group. Examine one preprocessing directive and |
1764 | return 0 if skipping should continue, 1 if it should halt. Also | |
1765 | adjusts the if_stack as appropriate. | |
1766 | The `#' has been read, but not the identifier. */ | |
1767 | ||
1768 | static int | |
1769 | consider_directive_while_skipping (pfile, stack) | |
1770 | cpp_reader *pfile; | |
1771 | IF_STACK_FRAME *stack; | |
1772 | { | |
1773 | long ident_len, ident; | |
1774 | struct directive *kt; | |
1775 | IF_STACK_FRAME *temp; | |
1776 | ||
1777 | cpp_skip_hspace (pfile); | |
1778 | ||
1779 | ident = CPP_WRITTEN (pfile); | |
1780 | parse_name (pfile, GETC()); | |
1781 | ident_len = CPP_WRITTEN (pfile) - ident; | |
1782 | ||
1783 | CPP_SET_WRITTEN (pfile, ident); | |
1784 | ||
1785 | for (kt = directive_table; kt->length >= 0; kt++) | |
1786 | if (kt->length == ident_len | |
1787 | && strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0) | |
1788 | switch (kt->type) | |
1789 | { | |
1790 | case T_IF: | |
1791 | case T_IFDEF: | |
1792 | case T_IFNDEF: | |
1793 | temp = (IF_STACK_FRAME *) xmalloc (sizeof (IF_STACK_FRAME)); | |
1794 | temp->next = pfile->if_stack; | |
1795 | pfile->if_stack = temp; | |
1796 | temp->fname = CPP_BUFFER(pfile)->nominal_fname; | |
1797 | temp->type = kt->type; | |
1798 | return 0; | |
1799 | ||
1800 | case T_ELSE: | |
1801 | if (CPP_PEDANTIC (pfile) && pfile->if_stack != stack) | |
1802 | validate_else (pfile, "#else"); | |
1803 | /* fall through */ | |
1804 | case T_ELIF: | |
1805 | if (pfile->if_stack->type == T_ELSE) | |
1806 | cpp_error (pfile, "`%s' after `#else'", kt->name); | |
1807 | ||
1808 | if (pfile->if_stack == stack) | |
1809 | return 1; | |
1810 | else | |
1811 | { | |
1812 | pfile->if_stack->type = kt->type; | |
1813 | return 0; | |
1814 | } | |
1815 | ||
1816 | case T_ENDIF: | |
1817 | if (CPP_PEDANTIC (pfile) && pfile->if_stack != stack) | |
1818 | validate_else (pfile, "#endif"); | |
1819 | ||
1820 | if (pfile->if_stack == stack) | |
1821 | return 1; | |
1822 | ||
1823 | temp = pfile->if_stack; | |
1824 | pfile->if_stack = temp->next; | |
1825 | free (temp); | |
1826 | return 0; | |
1827 | ||
1828 | default: | |
1829 | return 0; | |
1830 | } | |
1831 | ||
1832 | /* Don't let erroneous code go by. */ | |
1833 | if (!CPP_OPTIONS (pfile)->lang_asm && CPP_PEDANTIC (pfile)) | |
1834 | cpp_pedwarn (pfile, "invalid preprocessor directive name"); | |
1835 | return 0; | |
1836 | } | |
1837 | ||
1838 | /* skip to #endif, #else, or #elif. adjust line numbers, etc. | |
7f2935c7 | 1839 | * leaves input ptr at the sharp sign found. |
7f2935c7 PB |
1840 | */ |
1841 | static void | |
ed705a82 ZW |
1842 | skip_if_group (pfile) |
1843 | cpp_reader *pfile; | |
7f2935c7 PB |
1844 | { |
1845 | int c; | |
7f2935c7 | 1846 | IF_STACK_FRAME *save_if_stack = pfile->if_stack; /* don't pop past here */ |
ed705a82 ZW |
1847 | U_CHAR *beg_of_line; |
1848 | long old_written; | |
7f2935c7 | 1849 | |
7f2935c7 PB |
1850 | if (CPP_OPTIONS (pfile)->output_conditionals) |
1851 | { | |
ed705a82 ZW |
1852 | CPP_PUTS (pfile, "#failed\n", 8); |
1853 | pfile->lineno++; | |
80e9dcb4 | 1854 | output_line_command (pfile, same_file); |
7f2935c7 | 1855 | } |
7f2935c7 | 1856 | |
ed705a82 ZW |
1857 | old_written = CPP_WRITTEN (pfile); |
1858 | ||
1859 | for (;;) | |
1860 | { | |
1861 | beg_of_line = CPP_BUFFER (pfile)->cur; | |
7f2935c7 | 1862 | |
ed705a82 ZW |
1863 | if (! CPP_TRADITIONAL (pfile)) |
1864 | cpp_skip_hspace (pfile); | |
1865 | c = GETC(); | |
1866 | if (c == '\n') | |
7f2935c7 | 1867 | { |
ed705a82 ZW |
1868 | if (CPP_OPTIONS (pfile)->output_conditionals) |
1869 | CPP_PUTC (pfile, c); | |
3fdc651f | 1870 | CPP_BUMP_LINE (pfile); |
ed705a82 ZW |
1871 | continue; |
1872 | } | |
1873 | else if (c == '#') | |
1874 | { | |
1875 | if (consider_directive_while_skipping (pfile, save_if_stack)) | |
1876 | break; | |
1877 | } | |
1878 | else if (c == EOF) | |
1879 | return; /* Caller will issue error. */ | |
7f2935c7 | 1880 | |
ed705a82 ZW |
1881 | FORWARD(-1); |
1882 | if (CPP_OPTIONS (pfile)->output_conditionals) | |
1883 | { | |
1884 | CPP_PUTS (pfile, beg_of_line, CPP_BUFFER (pfile)->cur - beg_of_line); | |
1885 | copy_rest_of_line (pfile); | |
1886 | } | |
1887 | else | |
1888 | { | |
1889 | copy_rest_of_line (pfile); | |
1890 | CPP_SET_WRITTEN (pfile, old_written); /* discard it */ | |
1891 | } | |
7f2935c7 | 1892 | |
ed705a82 ZW |
1893 | c = GETC(); |
1894 | if (c == EOF) | |
1895 | return; /* Caller will issue error. */ | |
1896 | else | |
1897 | { | |
1898 | /* \n */ | |
1899 | if (CPP_OPTIONS (pfile)->output_conditionals) | |
3fdc651f ZW |
1900 | { |
1901 | CPP_PUTC (pfile, c); | |
1902 | pfile->lineno++; | |
1903 | } | |
1904 | CPP_BUMP_LINE (pfile); | |
7f2935c7 | 1905 | } |
ed705a82 ZW |
1906 | } |
1907 | ||
1908 | /* Back up to the beginning of this line. Caller will process the | |
1909 | directive. */ | |
1910 | CPP_BUFFER (pfile)->cur = beg_of_line; | |
7f2935c7 | 1911 | pfile->only_seen_white = 1; |
ed705a82 ZW |
1912 | if (CPP_OPTIONS (pfile)->output_conditionals) |
1913 | { | |
1914 | CPP_PUTS (pfile, "#endfailed\n", 11); | |
1915 | pfile->lineno++; | |
1916 | } | |
7f2935c7 PB |
1917 | } |
1918 | ||
1919 | /* | |
1920 | * handle a #else directive. Do this by just continuing processing | |
1921 | * without changing if_stack ; this is so that the error message | |
1922 | * for missing #endif's etc. will point to the original #if. It | |
1923 | * is possible that something different would be better. | |
1924 | */ | |
1925 | ||
1926 | static int | |
941e09b6 | 1927 | do_else (pfile, keyword) |
7f2935c7 | 1928 | cpp_reader *pfile; |
487a6e06 | 1929 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 PB |
1930 | { |
1931 | cpp_buffer *ip = CPP_BUFFER (pfile); | |
1932 | ||
1933 | if (CPP_PEDANTIC (pfile)) | |
1934 | validate_else (pfile, "#else"); | |
1935 | skip_rest_of_line (pfile); | |
1936 | ||
1937 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) { | |
1938 | cpp_error (pfile, "`#else' not within a conditional"); | |
1939 | return 0; | |
1940 | } else { | |
1941 | /* #ifndef can't have its special treatment for containing the whole file | |
1942 | if it has a #else clause. */ | |
1943 | pfile->if_stack->control_macro = 0; | |
1944 | ||
1945 | if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF) { | |
1946 | cpp_error (pfile, "`#else' after `#else'"); | |
1947 | fprintf (stderr, " (matches line %d", pfile->if_stack->lineno); | |
1948 | if (strcmp (pfile->if_stack->fname, ip->nominal_fname) != 0) | |
1949 | fprintf (stderr, ", file %s", pfile->if_stack->fname); | |
1950 | fprintf (stderr, ")\n"); | |
1951 | } | |
1952 | pfile->if_stack->type = T_ELSE; | |
1953 | } | |
1954 | ||
1955 | if (pfile->if_stack->if_succeeded) | |
ed705a82 | 1956 | skip_if_group (pfile); |
7f2935c7 PB |
1957 | else { |
1958 | ++pfile->if_stack->if_succeeded; /* continue processing input */ | |
80e9dcb4 | 1959 | output_line_command (pfile, same_file); |
7f2935c7 PB |
1960 | } |
1961 | return 0; | |
1962 | } | |
1963 | ||
1964 | /* | |
1965 | * unstack after #endif command | |
1966 | */ | |
1967 | ||
1968 | static int | |
941e09b6 | 1969 | do_endif (pfile, keyword) |
7f2935c7 | 1970 | cpp_reader *pfile; |
487a6e06 | 1971 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 PB |
1972 | { |
1973 | if (CPP_PEDANTIC (pfile)) | |
1974 | validate_else (pfile, "#endif"); | |
1975 | skip_rest_of_line (pfile); | |
1976 | ||
1977 | if (pfile->if_stack == CPP_BUFFER (pfile)->if_stack) | |
1978 | cpp_error (pfile, "unbalanced `#endif'"); | |
1979 | else | |
1980 | { | |
1981 | IF_STACK_FRAME *temp = pfile->if_stack; | |
1982 | pfile->if_stack = temp->next; | |
1983 | if (temp->control_macro != 0) | |
1984 | { | |
1985 | /* This #endif matched a #ifndef at the start of the file. | |
1986 | See if it is at the end of the file. */ | |
7f2935c7 PB |
1987 | int c; |
1988 | ||
3fdc651f | 1989 | parse_set_mark (pfile); |
7f2935c7 PB |
1990 | |
1991 | for (;;) | |
1992 | { | |
1993 | cpp_skip_hspace (pfile); | |
1994 | c = GETC (); | |
1995 | if (c != '\n') | |
1996 | break; | |
1997 | } | |
3fdc651f | 1998 | parse_goto_mark (pfile); |
7f2935c7 PB |
1999 | |
2000 | if (c == EOF) | |
2001 | { | |
0b3d776a | 2002 | /* This #endif ends a #ifndef |
7f2935c7 PB |
2003 | that contains all of the file (aside from whitespace). |
2004 | Arrange not to include the file again | |
0b3d776a ZW |
2005 | if the macro that was tested is defined. */ |
2006 | struct cpp_buffer *ip; | |
2007 | for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) | |
2008 | if (ip->fname != NULL) | |
2009 | break; | |
8db99db2 | 2010 | ip->ihash->control_macro = (char *) temp->control_macro; |
7f2935c7 PB |
2011 | } |
2012 | } | |
2013 | free (temp); | |
80e9dcb4 | 2014 | output_line_command (pfile, same_file); |
7f2935c7 PB |
2015 | } |
2016 | return 0; | |
2017 | } | |
2018 | ||
2019 | /* When an #else or #endif is found while skipping failed conditional, | |
2020 | if -pedantic was specified, this is called to warn about text after | |
2021 | the command name. P points to the first char after the command name. */ | |
2022 | ||
2023 | static void | |
2024 | validate_else (pfile, directive) | |
2025 | cpp_reader *pfile; | |
2026 | char *directive; | |
2027 | { | |
2028 | int c; | |
2029 | cpp_skip_hspace (pfile); | |
2030 | c = PEEKC (); | |
2031 | if (c != EOF && c != '\n') | |
2032 | cpp_pedwarn (pfile, | |
2033 | "text following `%s' violates ANSI standard", directive); | |
2034 | } | |
2035 | ||
22bbceaf | 2036 | /* Get the next token, and add it to the text in pfile->token_buffer. |
0f41302f | 2037 | Return the kind of token we got. */ |
7f2935c7 | 2038 | |
7f2935c7 PB |
2039 | enum cpp_token |
2040 | cpp_get_token (pfile) | |
2041 | cpp_reader *pfile; | |
2042 | { | |
2043 | register int c, c2, c3; | |
7f2935c7 PB |
2044 | enum cpp_token token; |
2045 | struct cpp_options *opts = CPP_OPTIONS (pfile); | |
4d9a1b48 | 2046 | |
7f2935c7 PB |
2047 | get_next: |
2048 | c = GETC(); | |
2049 | if (c == EOF) | |
2050 | { | |
2051 | handle_eof: | |
e7f9deae JM |
2052 | if (CPP_BUFFER (pfile)->manual_pop) |
2053 | /* If we've been reading from redirected input, the | |
2054 | frontend will pop the buffer. */ | |
2055 | return CPP_EOF; | |
2056 | else if (CPP_BUFFER (pfile)->seen_eof) | |
7f2935c7 | 2057 | { |
e7f9deae | 2058 | if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)) == CPP_NULL_BUFFER (pfile)) |
7f2935c7 | 2059 | return CPP_EOF; |
4d9a1b48 ZW |
2060 | |
2061 | cpp_pop_buffer (pfile); | |
2062 | goto get_next; | |
7f2935c7 PB |
2063 | } |
2064 | else | |
2065 | { | |
2066 | cpp_buffer *next_buf | |
2067 | = CPP_PREV_BUFFER (CPP_BUFFER (pfile)); | |
2068 | CPP_BUFFER (pfile)->seen_eof = 1; | |
d013f05e PB |
2069 | if (CPP_BUFFER (pfile)->nominal_fname |
2070 | && next_buf != CPP_NULL_BUFFER (pfile)) | |
7f2935c7 PB |
2071 | { |
2072 | /* We're about to return from an #include file. | |
ddd5a7c1 | 2073 | Emit #line information now (as part of the CPP_POP) result. |
0f41302f | 2074 | But the #line refers to the file we will pop to. */ |
7f2935c7 PB |
2075 | cpp_buffer *cur_buffer = CPP_BUFFER (pfile); |
2076 | CPP_BUFFER (pfile) = next_buf; | |
2077 | pfile->input_stack_listing_current = 0; | |
80e9dcb4 | 2078 | output_line_command (pfile, leave_file); |
7f2935c7 PB |
2079 | CPP_BUFFER (pfile) = cur_buffer; |
2080 | } | |
2081 | return CPP_POP; | |
2082 | } | |
2083 | } | |
2084 | else | |
2085 | { | |
2086 | switch (c) | |
2087 | { | |
7f2935c7 PB |
2088 | case '/': |
2089 | if (PEEKC () == '=') | |
2090 | goto op2; | |
3fdc651f ZW |
2091 | |
2092 | comment: | |
7f2935c7 | 2093 | if (opts->put_out_comments) |
3fdc651f ZW |
2094 | c = copy_comment (pfile, c); |
2095 | else | |
2096 | c = skip_comment (pfile, c); | |
7f2935c7 | 2097 | if (c == EOF) |
3fdc651f ZW |
2098 | goto handle_eof; |
2099 | else if (c != ' ') | |
2100 | goto randomchar; | |
2101 | ||
7f2935c7 PB |
2102 | /* Comments are equivalent to spaces. |
2103 | For -traditional, a comment is equivalent to nothing. */ | |
3fdc651f ZW |
2104 | if (opts->traditional || opts->put_out_comments) |
2105 | return CPP_COMMENT; | |
7f2935c7 PB |
2106 | else |
2107 | { | |
3fdc651f | 2108 | CPP_PUTC (pfile, c); |
7f2935c7 PB |
2109 | return CPP_HSPACE; |
2110 | } | |
7f2935c7 | 2111 | #if 0 |
782331f4 | 2112 | if (opts->for_lint) { |
7f2935c7 PB |
2113 | U_CHAR *argbp; |
2114 | int cmdlen, arglen; | |
2115 | char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen); | |
2116 | ||
2117 | if (lintcmd != NULL) { | |
2118 | /* I believe it is always safe to emit this newline: */ | |
2119 | obp[-1] = '\n'; | |
2120 | bcopy ("#pragma lint ", (char *) obp, 13); | |
2121 | obp += 13; | |
2122 | bcopy (lintcmd, (char *) obp, cmdlen); | |
2123 | obp += cmdlen; | |
2124 | ||
2125 | if (arglen != 0) { | |
2126 | *(obp++) = ' '; | |
2127 | bcopy (argbp, (char *) obp, arglen); | |
2128 | obp += arglen; | |
2129 | } | |
2130 | ||
2131 | /* OK, now bring us back to the state we were in before we entered | |
956d6950 JL |
2132 | this branch. We need #line because the newline for the pragma |
2133 | could mess things up. */ | |
80e9dcb4 | 2134 | output_line_command (pfile, same_file); |
7f2935c7 PB |
2135 | *(obp++) = ' '; /* just in case, if comments are copied thru */ |
2136 | *(obp++) = '/'; | |
2137 | } | |
7f2935c7 | 2138 | } |
782331f4 | 2139 | #endif |
7f2935c7 PB |
2140 | |
2141 | case '#': | |
2142 | #if 0 | |
2143 | /* If this is expanding a macro definition, don't recognize | |
2144 | preprocessor directives. */ | |
2145 | if (ip->macro != 0) | |
2146 | goto randomchar; | |
2147 | /* If this is expand_into_temp_buffer, recognize them | |
2148 | only after an actual newline at this level, | |
2149 | not at the beginning of the input level. */ | |
2150 | if (ip->fname == 0 && beg_of_line == ip->buf) | |
2151 | goto randomchar; | |
2152 | if (ident_length) | |
2153 | goto specialchar; | |
2154 | #endif | |
2155 | ||
2156 | if (!pfile->only_seen_white) | |
2157 | goto randomchar; | |
2158 | if (handle_directive (pfile)) | |
2159 | return CPP_DIRECTIVE; | |
2160 | pfile->only_seen_white = 0; | |
2161 | return CPP_OTHER; | |
2162 | ||
2163 | case '\"': | |
2164 | case '\'': | |
20dc7361 | 2165 | string: |
3fdc651f | 2166 | parse_string (pfile, c); |
7f2935c7 PB |
2167 | pfile->only_seen_white = 0; |
2168 | return c == '\'' ? CPP_CHAR : CPP_STRING; | |
2169 | ||
2170 | case '$': | |
2171 | if (!opts->dollars_in_ident) | |
2172 | goto randomchar; | |
2173 | goto letter; | |
2174 | ||
2175 | case ':': | |
2176 | if (opts->cplusplus && PEEKC () == ':') | |
2177 | goto op2; | |
2178 | goto randomchar; | |
2179 | ||
2180 | case '&': | |
2181 | case '+': | |
2182 | case '|': | |
7f2935c7 PB |
2183 | c2 = PEEKC (); |
2184 | if (c2 == c || c2 == '=') | |
2185 | goto op2; | |
2186 | goto randomchar; | |
2187 | ||
2188 | case '*': | |
2189 | case '!': | |
2190 | case '%': | |
2191 | case '=': | |
2192 | case '^': | |
7f2935c7 PB |
2193 | if (PEEKC () == '=') |
2194 | goto op2; | |
2195 | goto randomchar; | |
2196 | ||
2197 | case '-': | |
7f2935c7 PB |
2198 | c2 = PEEKC (); |
2199 | if (c2 == '-' && opts->chill) | |
3fdc651f | 2200 | goto comment; /* Chill style comment */ |
3773a46b | 2201 | if (c2 == '-' || c2 == '=') |
7f2935c7 | 2202 | goto op2; |
3773a46b JM |
2203 | if (c2 == '>') |
2204 | { | |
2205 | if (opts->cplusplus && PEEKN (1) == '*') | |
2206 | { | |
2207 | /* In C++, there's a ->* operator. */ | |
3773a46b JM |
2208 | token = CPP_OTHER; |
2209 | pfile->only_seen_white = 0; | |
2210 | CPP_RESERVE (pfile, 4); | |
2211 | CPP_PUTC_Q (pfile, c); | |
2212 | CPP_PUTC_Q (pfile, GETC ()); | |
2213 | CPP_PUTC_Q (pfile, GETC ()); | |
2214 | CPP_NUL_TERMINATE_Q (pfile); | |
2215 | return token; | |
2216 | } | |
2217 | goto op2; | |
2218 | } | |
7f2935c7 PB |
2219 | goto randomchar; |
2220 | ||
2221 | case '<': | |
2222 | if (pfile->parsing_include_directive) | |
2223 | { | |
2224 | for (;;) | |
2225 | { | |
2226 | CPP_PUTC (pfile, c); | |
2227 | if (c == '>') | |
2228 | break; | |
2229 | c = GETC (); | |
7f2935c7 PB |
2230 | if (c == '\n' || c == EOF) |
2231 | { | |
2232 | cpp_error (pfile, | |
2233 | "missing '>' in `#include <FILENAME>'"); | |
2234 | break; | |
2235 | } | |
3fdc651f ZW |
2236 | else if (c == '\r') |
2237 | { | |
ed45de98 ZW |
2238 | if (!CPP_BUFFER (pfile)->has_escapes) |
2239 | { | |
2240 | /* Backslash newline is replaced by nothing. */ | |
2241 | CPP_ADJUST_WRITTEN (pfile, -1); | |
2242 | CPP_BUMP_LINE (pfile); | |
2243 | } | |
2244 | else | |
2245 | { | |
2246 | /* We might conceivably get \r- or \r<space> in | |
2247 | here. Just delete 'em. */ | |
2248 | int d = GETC(); | |
2249 | if (d != '-' && d != ' ') | |
2250 | cpp_fatal (pfile, | |
2251 | "internal error: unrecognized escape \\r%c", | |
2252 | d); | |
2253 | CPP_ADJUST_WRITTEN (pfile, -1); | |
2254 | } | |
3fdc651f | 2255 | } |
7f2935c7 PB |
2256 | } |
2257 | return CPP_STRING; | |
2258 | } | |
2259 | /* else fall through */ | |
2260 | case '>': | |
7f2935c7 PB |
2261 | c2 = PEEKC (); |
2262 | if (c2 == '=') | |
2263 | goto op2; | |
3773a46b JM |
2264 | /* GNU C++ supports MIN and MAX operators <? and >?. */ |
2265 | if (c2 != c && (!opts->cplusplus || c2 != '?')) | |
7f2935c7 PB |
2266 | goto randomchar; |
2267 | FORWARD(1); | |
2268 | CPP_RESERVE (pfile, 4); | |
2269 | CPP_PUTC (pfile, c); | |
2270 | CPP_PUTC (pfile, c2); | |
7f2935c7 PB |
2271 | c3 = PEEKC (); |
2272 | if (c3 == '=') | |
2273 | CPP_PUTC_Q (pfile, GETC ()); | |
2274 | CPP_NUL_TERMINATE_Q (pfile); | |
2275 | pfile->only_seen_white = 0; | |
2276 | return CPP_OTHER; | |
2277 | ||
7f2935c7 | 2278 | case '.': |
7f2935c7 | 2279 | c2 = PEEKC (); |
e9a780ec | 2280 | if (ISDIGIT(c2)) |
7f2935c7 PB |
2281 | { |
2282 | CPP_RESERVE(pfile, 2); | |
2283 | CPP_PUTC_Q (pfile, '.'); | |
2284 | c = GETC (); | |
2285 | goto number; | |
2286 | } | |
3773a46b JM |
2287 | |
2288 | /* In C++ there's a .* operator. */ | |
2289 | if (opts->cplusplus && c2 == '*') | |
2290 | goto op2; | |
2291 | ||
7f2935c7 PB |
2292 | if (c2 == '.' && PEEKN(1) == '.') |
2293 | { | |
2294 | CPP_RESERVE(pfile, 4); | |
2295 | CPP_PUTC_Q (pfile, '.'); | |
2296 | CPP_PUTC_Q (pfile, '.'); | |
2297 | CPP_PUTC_Q (pfile, '.'); | |
2298 | FORWARD (2); | |
2299 | CPP_NUL_TERMINATE_Q (pfile); | |
2300 | pfile->only_seen_white = 0; | |
2301 | return CPP_3DOTS; | |
2302 | } | |
2303 | goto randomchar; | |
2304 | ||
2305 | op2: | |
2306 | token = CPP_OTHER; | |
2307 | pfile->only_seen_white = 0; | |
7f2935c7 PB |
2308 | CPP_RESERVE(pfile, 3); |
2309 | CPP_PUTC_Q (pfile, c); | |
2310 | CPP_PUTC_Q (pfile, GETC ()); | |
2311 | CPP_NUL_TERMINATE_Q (pfile); | |
2312 | return token; | |
2313 | ||
2314 | case 'L': | |
7f2935c7 PB |
2315 | c2 = PEEKC (); |
2316 | if ((c2 == '\'' || c2 == '\"') && !CPP_TRADITIONAL (pfile)) | |
2317 | { | |
2318 | CPP_PUTC (pfile, c); | |
2319 | c = GETC (); | |
2320 | goto string; | |
2321 | } | |
2322 | goto letter; | |
2323 | ||
2324 | case '0': case '1': case '2': case '3': case '4': | |
2325 | case '5': case '6': case '7': case '8': case '9': | |
2326 | number: | |
2327 | c2 = '.'; | |
2328 | for (;;) | |
2329 | { | |
2330 | CPP_RESERVE (pfile, 2); | |
2331 | CPP_PUTC_Q (pfile, c); | |
7f2935c7 PB |
2332 | c = PEEKC (); |
2333 | if (c == EOF) | |
2334 | break; | |
2335 | if (!is_idchar[c] && c != '.' | |
641d4443 RK |
2336 | && ((c2 != 'e' && c2 != 'E' |
2337 | && ((c2 != 'p' && c2 != 'P') || CPP_C89 (pfile))) | |
2338 | || (c != '+' && c != '-'))) | |
7f2935c7 PB |
2339 | break; |
2340 | FORWARD(1); | |
2341 | c2= c; | |
2342 | } | |
2343 | CPP_NUL_TERMINATE_Q (pfile); | |
2344 | pfile->only_seen_white = 0; | |
2345 | return CPP_NUMBER; | |
2346 | case 'b': case 'c': case 'd': case 'h': case 'o': | |
2347 | case 'B': case 'C': case 'D': case 'H': case 'O': | |
2348 | if (opts->chill && PEEKC () == '\'') | |
2349 | { | |
2350 | pfile->only_seen_white = 0; | |
2351 | CPP_RESERVE (pfile, 2); | |
2352 | CPP_PUTC_Q (pfile, c); | |
2353 | CPP_PUTC_Q (pfile, '\''); | |
2354 | FORWARD(1); | |
2355 | for (;;) | |
2356 | { | |
2357 | c = GETC(); | |
2358 | if (c == EOF) | |
2359 | goto chill_number_eof; | |
2360 | if (!is_idchar[c]) | |
3fdc651f | 2361 | break; |
7f2935c7 PB |
2362 | CPP_PUTC (pfile, c); |
2363 | } | |
2364 | if (c == '\'') | |
2365 | { | |
2366 | CPP_RESERVE (pfile, 2); | |
2367 | CPP_PUTC_Q (pfile, c); | |
2368 | CPP_NUL_TERMINATE_Q (pfile); | |
2369 | return CPP_STRING; | |
2370 | } | |
2371 | else | |
2372 | { | |
2373 | FORWARD(-1); | |
2374 | chill_number_eof: | |
2375 | CPP_NUL_TERMINATE (pfile); | |
2376 | return CPP_NUMBER; | |
2377 | } | |
2378 | } | |
2379 | else | |
2380 | goto letter; | |
2381 | case '_': | |
2382 | case 'a': case 'e': case 'f': case 'g': case 'i': case 'j': | |
2383 | case 'k': case 'l': case 'm': case 'n': case 'p': case 'q': | |
2384 | case 'r': case 's': case 't': case 'u': case 'v': case 'w': | |
2385 | case 'x': case 'y': case 'z': | |
2386 | case 'A': case 'E': case 'F': case 'G': case 'I': case 'J': | |
2387 | case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R': | |
2388 | case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': | |
2389 | case 'Y': case 'Z': | |
2390 | letter: | |
2391 | { | |
2392 | HASHNODE *hp; | |
2393 | unsigned char *ident; | |
2394 | int before_name_written = CPP_WRITTEN (pfile); | |
2395 | int ident_len; | |
2396 | parse_name (pfile, c); | |
2397 | pfile->only_seen_white = 0; | |
2398 | if (pfile->no_macro_expand) | |
2399 | return CPP_NAME; | |
2400 | ident = pfile->token_buffer + before_name_written; | |
2401 | ident_len = CPP_PWRITTEN (pfile) - ident; | |
2402 | hp = cpp_lookup (pfile, ident, ident_len, -1); | |
2403 | if (!hp) | |
2404 | return CPP_NAME; | |
2405 | if (hp->type == T_DISABLED) | |
2406 | { | |
2407 | if (pfile->output_escapes) | |
ed45de98 | 2408 | { /* Return "\r-IDENT", followed by '\0'. */ |
7f2935c7 PB |
2409 | int i; |
2410 | CPP_RESERVE (pfile, 3); | |
2411 | ident = pfile->token_buffer + before_name_written; | |
2412 | CPP_ADJUST_WRITTEN (pfile, 2); | |
2413 | for (i = ident_len; i >= 0; i--) ident[i+2] = ident[i]; | |
ed45de98 | 2414 | ident[0] = '\r'; |
7f2935c7 PB |
2415 | ident[1] = '-'; |
2416 | } | |
2417 | return CPP_NAME; | |
2418 | } | |
2419 | ||
2420 | /* If macro wants an arglist, verify that a '(' follows. | |
2421 | first skip all whitespace, copying it to the output | |
2422 | after the macro name. Then, if there is no '(', | |
2423 | decide this is not a macro call and leave things that way. */ | |
2424 | if (hp->type == T_MACRO && hp->value.defn->nargs >= 0) | |
2425 | { | |
c55ade02 DB |
2426 | int is_macro_call, macbuf_whitespace = 0; |
2427 | ||
3fdc651f | 2428 | parse_set_mark (pfile); |
7f2935c7 PB |
2429 | for (;;) |
2430 | { | |
2431 | cpp_skip_hspace (pfile); | |
2432 | c = PEEKC (); | |
2433 | is_macro_call = c == '('; | |
c55ade02 DB |
2434 | if (c != EOF) |
2435 | { | |
2436 | if (c != '\n') | |
2437 | break; | |
2438 | FORWARD (1); | |
2439 | } | |
2440 | else | |
2441 | { | |
2442 | if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) | |
2443 | { | |
3fdc651f | 2444 | if (CPP_BUFFER (pfile)->mark != |
c55ade02 DB |
2445 | (CPP_BUFFER (pfile)->cur |
2446 | - CPP_BUFFER (pfile)->buf)) | |
2447 | macbuf_whitespace = 1; | |
2448 | ||
3fdc651f ZW |
2449 | /* The mark goes away automatically when |
2450 | the buffer is popped. */ | |
c55ade02 | 2451 | cpp_pop_buffer (pfile); |
3fdc651f | 2452 | parse_set_mark (pfile); |
c55ade02 DB |
2453 | } |
2454 | else | |
2455 | break; | |
2456 | } | |
7f2935c7 PB |
2457 | } |
2458 | if (!is_macro_call) | |
c55ade02 | 2459 | { |
3fdc651f | 2460 | parse_goto_mark (pfile); |
c55ade02 DB |
2461 | if (macbuf_whitespace) |
2462 | CPP_PUTC (pfile, ' '); | |
2463 | } | |
3fdc651f ZW |
2464 | else |
2465 | parse_clear_mark (pfile); | |
7f2935c7 PB |
2466 | if (!is_macro_call) |
2467 | return CPP_NAME; | |
2468 | } | |
20dc7361 ZW |
2469 | /* This is now known to be a macro call. |
2470 | Expand the macro, reading arguments as needed, | |
2471 | and push the expansion on the input stack. */ | |
2472 | macroexpand (pfile, hp); | |
2473 | CPP_SET_WRITTEN (pfile, before_name_written); | |
7f2935c7 | 2474 | } |
782331f4 | 2475 | goto get_next; |
7f2935c7 | 2476 | |
3fdc651f | 2477 | case ' ': case '\t': case '\v': |
7f2935c7 PB |
2478 | for (;;) |
2479 | { | |
2480 | CPP_PUTC (pfile, c); | |
2481 | c = PEEKC (); | |
2482 | if (c == EOF || !is_hor_space[c]) | |
2483 | break; | |
2484 | FORWARD(1); | |
2485 | } | |
2486 | return CPP_HSPACE; | |
2487 | ||
3fdc651f | 2488 | case '\r': |
ed45de98 ZW |
2489 | if (CPP_BUFFER (pfile)->has_escapes) |
2490 | { | |
2491 | c = GETC (); | |
2492 | if (c == '-') | |
2493 | { | |
2494 | if (pfile->output_escapes) | |
2495 | CPP_PUTS (pfile, "\r-", 2); | |
2496 | parse_name (pfile, GETC ()); | |
2497 | return CPP_NAME; | |
2498 | } | |
2499 | else if (c == ' ') | |
2500 | { | |
2501 | CPP_RESERVE (pfile, 2); | |
2502 | if (pfile->output_escapes) | |
2503 | CPP_PUTC_Q (pfile, '\r'); | |
2504 | CPP_PUTC_Q (pfile, c); | |
2505 | return CPP_HSPACE; | |
2506 | } | |
2507 | else | |
2508 | { | |
2509 | cpp_fatal (pfile, | |
2510 | "internal error: unrecognized escape \\r%c", c); | |
2511 | goto get_next; | |
2512 | } | |
2513 | } | |
2514 | else | |
2515 | { | |
2516 | /* Backslash newline is ignored. */ | |
2517 | CPP_BUMP_LINE (pfile); | |
2518 | goto get_next; | |
2519 | } | |
7f2935c7 PB |
2520 | |
2521 | case '\n': | |
2522 | CPP_PUTC (pfile, c); | |
2523 | if (pfile->only_seen_white == 0) | |
2524 | pfile->only_seen_white = 1; | |
3fdc651f | 2525 | CPP_BUMP_LINE (pfile); |
80e9dcb4 ZW |
2526 | if (! CPP_OPTIONS (pfile)->no_line_commands) |
2527 | { | |
2528 | pfile->lineno++; | |
2529 | if (CPP_BUFFER (pfile)->lineno != pfile->lineno) | |
2530 | output_line_command (pfile, same_file); | |
2531 | } | |
7f2935c7 PB |
2532 | return CPP_VSPACE; |
2533 | ||
2534 | case '(': token = CPP_LPAREN; goto char1; | |
2535 | case ')': token = CPP_RPAREN; goto char1; | |
2536 | case '{': token = CPP_LBRACE; goto char1; | |
2537 | case '}': token = CPP_RBRACE; goto char1; | |
2538 | case ',': token = CPP_COMMA; goto char1; | |
2539 | case ';': token = CPP_SEMICOLON; goto char1; | |
2540 | ||
2541 | randomchar: | |
2542 | default: | |
2543 | token = CPP_OTHER; | |
2544 | char1: | |
2545 | pfile->only_seen_white = 0; | |
2546 | CPP_PUTC (pfile, c); | |
2547 | return token; | |
2548 | } | |
2549 | } | |
2550 | } | |
2551 | ||
0f41302f MS |
2552 | /* Like cpp_get_token, but skip spaces and comments. */ |
2553 | ||
7f2935c7 PB |
2554 | enum cpp_token |
2555 | cpp_get_non_space_token (pfile) | |
2556 | cpp_reader *pfile; | |
2557 | { | |
2558 | int old_written = CPP_WRITTEN (pfile); | |
2559 | for (;;) | |
2560 | { | |
2561 | enum cpp_token token = cpp_get_token (pfile); | |
2562 | if (token != CPP_COMMENT && token != CPP_POP | |
2563 | && token != CPP_HSPACE && token != CPP_VSPACE) | |
2564 | return token; | |
2565 | CPP_SET_WRITTEN (pfile, old_written); | |
2566 | } | |
2567 | } | |
2568 | ||
0f41302f | 2569 | /* Parse an identifier starting with C. */ |
7f2935c7 | 2570 | |
3fdc651f | 2571 | static void |
7f2935c7 | 2572 | parse_name (pfile, c) |
3fdc651f ZW |
2573 | cpp_reader *pfile; |
2574 | int c; | |
7f2935c7 PB |
2575 | { |
2576 | for (;;) | |
2577 | { | |
2578 | if (! is_idchar[c]) | |
2579 | { | |
7f2935c7 PB |
2580 | FORWARD (-1); |
2581 | break; | |
2582 | } | |
2583 | ||
9e979f8f | 2584 | if (c == '$' && CPP_PEDANTIC (pfile)) |
487a6e06 | 2585 | cpp_pedwarn (pfile, "`$' in identifier"); |
9e979f8f | 2586 | |
0f41302f | 2587 | CPP_RESERVE(pfile, 2); /* One more for final NUL. */ |
7f2935c7 PB |
2588 | CPP_PUTC_Q (pfile, c); |
2589 | c = GETC(); | |
2590 | if (c == EOF) | |
2591 | break; | |
2592 | } | |
2593 | CPP_NUL_TERMINATE_Q (pfile); | |
3fdc651f ZW |
2594 | return; |
2595 | } | |
2596 | ||
2597 | /* Parse a string starting with C. A single quoted string is treated | |
2598 | like a double -- some programs (e.g., troff) are perverse this way. | |
2599 | (However, a single quoted string is not allowed to extend over | |
3773a46b | 2600 | multiple lines.) */ |
3fdc651f ZW |
2601 | static void |
2602 | parse_string (pfile, c) | |
2603 | cpp_reader *pfile; | |
2604 | int c; | |
2605 | { | |
2606 | long start_line, start_column; | |
2607 | ||
2608 | cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column); | |
2609 | ||
2610 | CPP_PUTC (pfile, c); | |
2611 | while (1) | |
2612 | { | |
2613 | int cc = GETC(); | |
2614 | if (cc == EOF) | |
2615 | { | |
2616 | if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) | |
2617 | { | |
2618 | /* try harder: this string crosses a macro expansion | |
2619 | boundary. This can happen naturally if -traditional. | |
2620 | Otherwise, only -D can make a macro with an unmatched | |
2621 | quote. */ | |
2622 | cpp_pop_buffer (pfile); | |
2623 | continue; | |
2624 | } | |
2625 | if (!CPP_TRADITIONAL (pfile)) | |
2626 | { | |
2627 | cpp_error_with_line (pfile, start_line, start_column, | |
2628 | "unterminated string or character constant"); | |
2629 | if (pfile->multiline_string_line != start_line | |
2630 | && pfile->multiline_string_line != 0) | |
2631 | cpp_error_with_line (pfile, | |
2632 | pfile->multiline_string_line, -1, | |
2633 | "possible real start of unterminated constant"); | |
2634 | pfile->multiline_string_line = 0; | |
2635 | } | |
2636 | break; | |
2637 | } | |
2638 | CPP_PUTC (pfile, cc); | |
2639 | switch (cc) | |
2640 | { | |
2641 | case '\n': | |
2642 | CPP_BUMP_LINE (pfile); | |
2643 | pfile->lineno++; | |
2644 | /* Traditionally, end of line ends a string constant with | |
2645 | no error. */ | |
2646 | if (CPP_TRADITIONAL (pfile)) | |
2647 | return; | |
2648 | /* Character constants may not extend over multiple lines. */ | |
2649 | if (c == '\'') | |
2650 | { | |
2651 | cpp_error_with_line (pfile, start_line, start_column, | |
2652 | "unterminated character constant"); | |
2653 | return; | |
2654 | } | |
2655 | if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0) | |
2656 | { | |
2657 | cpp_pedwarn_with_line (pfile, start_line, start_column, | |
2658 | "string constant runs past end of line"); | |
2659 | } | |
2660 | if (pfile->multiline_string_line == 0) | |
2661 | pfile->multiline_string_line = start_line; | |
2662 | break; | |
2663 | ||
2664 | case '\r': | |
3fdc651f | 2665 | CPP_ADJUST_WRITTEN (pfile, -1); |
ed45de98 ZW |
2666 | if (CPP_BUFFER (pfile)->has_escapes) |
2667 | { | |
2668 | cpp_fatal (pfile, | |
2669 | "internal error: \\r escape inside string constant"); | |
2670 | FORWARD(1); | |
2671 | } | |
2672 | else | |
2673 | /* Backslash newline is replaced by nothing at all. */ | |
2674 | CPP_BUMP_LINE (pfile); | |
3fdc651f ZW |
2675 | break; |
2676 | ||
2677 | case '\\': | |
2678 | cc = GETC(); | |
2679 | if (cc != EOF) | |
2680 | CPP_PUTC (pfile, cc); | |
2681 | break; | |
2682 | ||
2683 | case '\"': | |
2684 | case '\'': | |
2685 | if (cc == c) | |
2686 | return; | |
2687 | break; | |
2688 | } | |
2689 | } | |
7f2935c7 PB |
2690 | } |
2691 | ||
7061aa5a ZW |
2692 | /* Read an assertion into the token buffer, converting to |
2693 | canonical form: `#predicate(a n swe r)' The next non-whitespace | |
2694 | character to read should be the first letter of the predicate. | |
2695 | Returns 0 for syntax error, 1 for bare predicate, 2 for predicate | |
2696 | with answer (see callers for why). In case of 0, an error has been | |
2697 | printed. */ | |
2698 | static int | |
2699 | parse_assertion (pfile) | |
2700 | cpp_reader *pfile; | |
2701 | { | |
2702 | int c, dropwhite; | |
2703 | cpp_skip_hspace (pfile); | |
2704 | c = PEEKC(); | |
2705 | if (! is_idstart[c]) | |
782331f4 | 2706 | { |
7061aa5a ZW |
2707 | cpp_error (pfile, "assertion predicate is not an identifier"); |
2708 | return 0; | |
782331f4 | 2709 | } |
7061aa5a ZW |
2710 | CPP_PUTC(pfile, '#'); |
2711 | FORWARD(1); | |
2712 | parse_name(pfile, c); | |
782331f4 | 2713 | |
7061aa5a ZW |
2714 | c = PEEKC(); |
2715 | if (c != '(') | |
2716 | { | |
3fdc651f | 2717 | if (is_hor_space[c] || c == '\r') |
7061aa5a ZW |
2718 | cpp_skip_hspace (pfile); |
2719 | c = PEEKC(); | |
2720 | } | |
2721 | if (c != '(') | |
2722 | return 1; | |
2723 | ||
2724 | CPP_PUTC(pfile, '('); | |
2725 | FORWARD(1); | |
2726 | dropwhite = 1; | |
2727 | while ((c = GETC()) != ')') | |
2728 | { | |
2729 | if (is_hor_space[c]) | |
2730 | { | |
2731 | if (! dropwhite) | |
2732 | { | |
2733 | CPP_PUTC(pfile, ' '); | |
2734 | dropwhite = 1; | |
2735 | } | |
2736 | } | |
7061aa5a ZW |
2737 | else if (c == '\n' || c == EOF) |
2738 | { | |
2739 | if (c == '\n') FORWARD(-1); | |
2740 | cpp_error (pfile, "un-terminated assertion answer"); | |
2741 | return 0; | |
2742 | } | |
3fdc651f | 2743 | else if (c == '\r') |
ed45de98 | 2744 | /* \r cannot be a macro escape here. */ |
3fdc651f | 2745 | CPP_BUMP_LINE (pfile); |
7061aa5a ZW |
2746 | else |
2747 | { | |
3fdc651f | 2748 | CPP_PUTC (pfile, c); |
7061aa5a ZW |
2749 | dropwhite = 0; |
2750 | } | |
2751 | } | |
2752 | ||
2753 | if (pfile->limit[-1] == ' ') | |
2754 | pfile->limit[-1] = ')'; | |
2755 | else if (pfile->limit[-1] == '(') | |
2756 | { | |
2757 | cpp_error (pfile, "empty token sequence in assertion"); | |
2758 | return 0; | |
2759 | } | |
2760 | else | |
3fdc651f | 2761 | CPP_PUTC (pfile, ')'); |
7061aa5a | 2762 | |
3fdc651f | 2763 | CPP_NUL_TERMINATE (pfile); |
7061aa5a | 2764 | return 2; |
782331f4 | 2765 | } |
7061aa5a | 2766 | |
7f2935c7 | 2767 | static int |
941e09b6 | 2768 | do_assert (pfile, keyword) |
7f2935c7 | 2769 | cpp_reader *pfile; |
487a6e06 | 2770 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 2771 | { |
7061aa5a ZW |
2772 | char *sym; |
2773 | int ret, c; | |
2774 | HASHNODE *base, *this; | |
2775 | int baselen, thislen; | |
7f2935c7 PB |
2776 | |
2777 | if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing | |
2778 | && !CPP_BUFFER (pfile)->system_header_p) | |
2779 | cpp_pedwarn (pfile, "ANSI C does not allow `#assert'"); | |
2780 | ||
2781 | cpp_skip_hspace (pfile); | |
8db99db2 | 2782 | sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */ |
7061aa5a ZW |
2783 | ret = parse_assertion (pfile); |
2784 | if (ret == 0) | |
7f2935c7 | 2785 | goto error; |
7061aa5a ZW |
2786 | else if (ret == 1) |
2787 | { | |
2788 | cpp_error (pfile, "missing token-sequence in `#assert'"); | |
7f2935c7 PB |
2789 | goto error; |
2790 | } | |
7061aa5a | 2791 | |
7f2935c7 | 2792 | cpp_skip_hspace (pfile); |
7061aa5a | 2793 | c = PEEKC(); |
7f2935c7 | 2794 | if (c != EOF && c != '\n') |
7061aa5a ZW |
2795 | { |
2796 | cpp_error (pfile, "junk at end of `#assert'"); | |
2797 | goto error; | |
2798 | } | |
7f2935c7 | 2799 | |
7061aa5a ZW |
2800 | thislen = strlen (sym); |
2801 | baselen = index (sym, '(') - sym; | |
2802 | this = cpp_lookup (pfile, sym, thislen, -1); | |
2803 | if (this) | |
2804 | { | |
2805 | cpp_warning (pfile, "`%s' re-asserted", sym); | |
2806 | goto error; | |
7f2935c7 PB |
2807 | } |
2808 | ||
7061aa5a ZW |
2809 | base = cpp_lookup (pfile, sym, baselen, -1); |
2810 | if (! base) | |
122ae89b | 2811 | base = cpp_install (pfile, sym, baselen, T_ASSERT, 0, -1); |
7061aa5a ZW |
2812 | else if (base->type != T_ASSERT) |
2813 | { | |
2814 | /* Token clash - but with what?! */ | |
2815 | cpp_fatal (pfile, | |
2816 | "cpp internal error: base->type != T_ASSERT in do_assert"); | |
2817 | goto error; | |
7f2935c7 | 2818 | } |
7061aa5a | 2819 | |
122ae89b ZW |
2820 | this = cpp_install (pfile, sym, thislen, T_ASSERT, |
2821 | (char *)base->value.aschain, -1); | |
7061aa5a ZW |
2822 | base->value.aschain = this; |
2823 | ||
8db99db2 | 2824 | pfile->limit = (unsigned char *) sym; /* Pop */ |
7f2935c7 | 2825 | return 0; |
7061aa5a | 2826 | |
7f2935c7 | 2827 | error: |
7f2935c7 | 2828 | skip_rest_of_line (pfile); |
3caee4a8 ZW |
2829 | pfile->limit = (unsigned char *) sym; /* Pop */ |
2830 | return 0; | |
7f2935c7 | 2831 | } |
7061aa5a | 2832 | |
7f2935c7 | 2833 | static int |
941e09b6 | 2834 | do_unassert (pfile, keyword) |
7f2935c7 | 2835 | cpp_reader *pfile; |
487a6e06 | 2836 | struct directive *keyword ATTRIBUTE_UNUSED; |
7f2935c7 | 2837 | { |
7061aa5a ZW |
2838 | int c, ret; |
2839 | char *sym; | |
2840 | long baselen, thislen; | |
2841 | HASHNODE *base, *this, *next; | |
2842 | ||
7f2935c7 PB |
2843 | if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing |
2844 | && !CPP_BUFFER (pfile)->system_header_p) | |
2845 | cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'"); | |
2846 | ||
2847 | cpp_skip_hspace (pfile); | |
2848 | ||
8db99db2 | 2849 | sym = (char *) CPP_PWRITTEN (pfile); /* remember where it starts */ |
7061aa5a ZW |
2850 | ret = parse_assertion (pfile); |
2851 | if (ret == 0) | |
2852 | goto error; | |
2853 | ||
7f2935c7 PB |
2854 | cpp_skip_hspace (pfile); |
2855 | c = PEEKC (); | |
2856 | if (c != EOF && c != '\n') | |
2857 | cpp_error (pfile, "junk at end of `#unassert'"); | |
7f2935c7 | 2858 | |
7061aa5a ZW |
2859 | thislen = strlen (sym); |
2860 | if (ret == 1) | |
2861 | { | |
2862 | base = cpp_lookup (pfile, sym, thislen, -1); | |
2863 | if (! base) | |
2864 | goto error; /* It isn't an error to #undef what isn't #defined, | |
2865 | so it isn't an error to #unassert what isn't | |
2866 | #asserted either. */ | |
2867 | ||
2868 | for (this = base->value.aschain; this; this = next) | |
2869 | { | |
2870 | next = this->value.aschain; | |
2871 | delete_macro (this); | |
7f2935c7 | 2872 | } |
7061aa5a | 2873 | delete_macro (base); |
7f2935c7 | 2874 | } |
7061aa5a ZW |
2875 | else |
2876 | { | |
2877 | baselen = index (sym, '(') - sym; | |
2878 | base = cpp_lookup (pfile, sym, baselen, -1); | |
2879 | if (! base) goto error; | |
2880 | this = cpp_lookup (pfile, sym, thislen, -1); | |
2881 | if (! this) goto error; | |
2882 | ||
2883 | next = base; | |
2884 | while (next->value.aschain != this) | |
2885 | next = next->value.aschain; | |
7f2935c7 | 2886 | |
7061aa5a ZW |
2887 | next->value.aschain = this->value.aschain; |
2888 | delete_macro (this); | |
2889 | ||
2890 | if (base->value.aschain == NULL) | |
2891 | delete_macro (base); /* Last answer for this predicate deleted. */ | |
2892 | } | |
2893 | ||
8db99db2 | 2894 | pfile->limit = (unsigned char *) sym; /* Pop */ |
7f2935c7 PB |
2895 | return 0; |
2896 | error: | |
7f2935c7 | 2897 | skip_rest_of_line (pfile); |
3caee4a8 ZW |
2898 | pfile->limit = (unsigned char *) sym; /* Pop */ |
2899 | return 0; | |
7f2935c7 | 2900 | } |
7f2935c7 | 2901 | |
0b22d65c ZW |
2902 | /* Process STR as if it appeared as the body of an #unassert. */ |
2903 | void | |
2904 | cpp_unassert (pfile, str) | |
2905 | cpp_reader *pfile; | |
2906 | unsigned char *str; | |
2907 | { | |
2908 | if (cpp_push_buffer (pfile, str, strlen (str)) != NULL) | |
2909 | { | |
2910 | do_assert (pfile, NULL); | |
2911 | cpp_pop_buffer (pfile); | |
2912 | } | |
2913 | } | |
2914 | ||
7f2935c7 | 2915 | int |
7061aa5a | 2916 | cpp_read_check_assertion (pfile) |
7f2935c7 | 2917 | cpp_reader *pfile; |
7f2935c7 | 2918 | { |
8db99db2 | 2919 | U_CHAR *name = CPP_PWRITTEN (pfile); |
7061aa5a ZW |
2920 | int result; |
2921 | HASHNODE *hp; | |
2922 | ||
2923 | FORWARD (1); /* Skip '#' */ | |
2924 | cpp_skip_hspace (pfile); | |
2925 | if (! parse_assertion (pfile)) | |
2926 | result = 0; | |
2927 | else | |
7f2935c7 | 2928 | { |
8db99db2 | 2929 | hp = cpp_lookup (pfile, name, CPP_PWRITTEN (pfile) - name, -1); |
7061aa5a | 2930 | result = (hp != 0); |
7f2935c7 PB |
2931 | } |
2932 | ||
7061aa5a ZW |
2933 | pfile->limit = name; |
2934 | return result; | |
7f2935c7 | 2935 | } |
7f2935c7 | 2936 | |
3fdc651f | 2937 | /* Remember the current position of PFILE. */ |
0f41302f | 2938 | |
7f2935c7 | 2939 | void |
3fdc651f | 2940 | parse_set_mark (pfile) |
7f2935c7 PB |
2941 | cpp_reader *pfile; |
2942 | { | |
3fdc651f ZW |
2943 | cpp_buffer *ip = CPP_BUFFER (pfile); |
2944 | if (ip->mark != -1) | |
2945 | cpp_fatal (pfile, | |
2946 | "cpp internal error: ip->mark != -1 in parse_set_mark"); | |
0f41302f | 2947 | |
3fdc651f | 2948 | ip->mark = ip->cur - ip->buf; |
7f2935c7 PB |
2949 | } |
2950 | ||
3fdc651f | 2951 | /* Clear the current mark - we no longer need it. */ |
7f2935c7 PB |
2952 | |
2953 | void | |
3fdc651f | 2954 | parse_clear_mark (pfile) |
7f2935c7 PB |
2955 | cpp_reader *pfile; |
2956 | { | |
3fdc651f ZW |
2957 | cpp_buffer *ip = CPP_BUFFER (pfile); |
2958 | if (ip->mark == -1) | |
2959 | cpp_fatal (pfile, | |
2960 | "cpp internal error: ip->mark == -1 in parse_clear_mark"); | |
2961 | ||
2962 | ip->mark = -1; | |
7f2935c7 PB |
2963 | } |
2964 | ||
3fdc651f ZW |
2965 | /* Backup the current position of PFILE to that saved in its mark, |
2966 | and clear the mark. */ | |
7f2935c7 PB |
2967 | |
2968 | void | |
3fdc651f | 2969 | parse_goto_mark (pfile) |
7f2935c7 PB |
2970 | cpp_reader *pfile; |
2971 | { | |
3fdc651f ZW |
2972 | cpp_buffer *ip = CPP_BUFFER (pfile); |
2973 | if (ip->mark == -1) | |
2974 | cpp_fatal (pfile, | |
2975 | "cpp internal error: ip->mark == -1 in parse_goto_mark"); | |
2976 | ||
2977 | ip->cur = ip->buf + ip->mark; | |
2978 | ip->mark = -1; | |
7f2935c7 PB |
2979 | } |
2980 | ||
355142da PB |
2981 | void |
2982 | cpp_print_file_and_line (pfile) | |
2983 | cpp_reader *pfile; | |
2984 | { | |
2985 | cpp_buffer *ip = cpp_file_buffer (pfile); | |
2986 | ||
2987 | if (ip != NULL) | |
2988 | { | |
2989 | long line, col; | |
2990 | cpp_buf_line_and_col (ip, &line, &col); | |
487a6e06 | 2991 | cpp_file_line_for_message (pfile, ip->nominal_fname, |
355142da PB |
2992 | line, pfile->show_column ? col : -1); |
2993 | } | |
2994 | } | |
2995 | ||
487a6e06 | 2996 | static void |
ab87f8c8 | 2997 | v_cpp_error (pfile, msgid, ap) |
487a6e06 | 2998 | cpp_reader *pfile; |
ab87f8c8 | 2999 | const char *msgid; |
487a6e06 | 3000 | va_list ap; |
355142da PB |
3001 | { |
3002 | cpp_print_containing_files (pfile); | |
3003 | cpp_print_file_and_line (pfile); | |
ab87f8c8 | 3004 | v_cpp_message (pfile, 1, msgid, ap); |
487a6e06 KG |
3005 | } |
3006 | ||
3007 | void | |
ab87f8c8 | 3008 | cpp_error VPROTO ((cpp_reader * pfile, const char *msgid, ...)) |
487a6e06 | 3009 | { |
5148a72b | 3010 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3011 | cpp_reader *pfile; |
ab87f8c8 | 3012 | const char *msgid; |
487a6e06 KG |
3013 | #endif |
3014 | va_list ap; | |
3015 | ||
ab87f8c8 | 3016 | VA_START(ap, msgid); |
487a6e06 | 3017 | |
5148a72b | 3018 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3019 | pfile = va_arg (ap, cpp_reader *); |
ab87f8c8 | 3020 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3021 | #endif |
3022 | ||
ab87f8c8 | 3023 | v_cpp_error (pfile, msgid, ap); |
487a6e06 | 3024 | va_end(ap); |
355142da PB |
3025 | } |
3026 | ||
3027 | /* Print error message but don't count it. */ | |
3028 | ||
487a6e06 | 3029 | static void |
ab87f8c8 | 3030 | v_cpp_warning (pfile, msgid, ap) |
487a6e06 | 3031 | cpp_reader *pfile; |
ab87f8c8 | 3032 | const char *msgid; |
487a6e06 | 3033 | va_list ap; |
355142da PB |
3034 | { |
3035 | if (CPP_OPTIONS (pfile)->inhibit_warnings) | |
3036 | return; | |
3037 | ||
3038 | if (CPP_OPTIONS (pfile)->warnings_are_errors) | |
3039 | pfile->errors++; | |
3040 | ||
3041 | cpp_print_containing_files (pfile); | |
3042 | cpp_print_file_and_line (pfile); | |
ab87f8c8 | 3043 | v_cpp_message (pfile, 0, msgid, ap); |
487a6e06 KG |
3044 | } |
3045 | ||
3046 | void | |
ab87f8c8 | 3047 | cpp_warning VPROTO ((cpp_reader * pfile, const char *msgid, ...)) |
487a6e06 | 3048 | { |
5148a72b | 3049 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3050 | cpp_reader *pfile; |
1c5d09e4 | 3051 | const char *msgid; |
487a6e06 KG |
3052 | #endif |
3053 | va_list ap; | |
3054 | ||
ab87f8c8 | 3055 | VA_START (ap, msgid); |
487a6e06 | 3056 | |
5148a72b | 3057 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3058 | pfile = va_arg (ap, cpp_reader *); |
ab87f8c8 | 3059 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3060 | #endif |
3061 | ||
ab87f8c8 | 3062 | v_cpp_warning (pfile, msgid, ap); |
487a6e06 | 3063 | va_end(ap); |
355142da PB |
3064 | } |
3065 | ||
3066 | /* Print an error message and maybe count it. */ | |
3067 | ||
3068 | void | |
ab87f8c8 | 3069 | cpp_pedwarn VPROTO ((cpp_reader * pfile, const char *msgid, ...)) |
355142da | 3070 | { |
5148a72b | 3071 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3072 | cpp_reader *pfile; |
ab87f8c8 | 3073 | const char *msgid; |
487a6e06 KG |
3074 | #endif |
3075 | va_list ap; | |
3076 | ||
ab87f8c8 | 3077 | VA_START (ap, msgid); |
487a6e06 | 3078 | |
5148a72b | 3079 | #ifndef ANSI_PROTOTYPES |
487a6e06 | 3080 | pfile = va_arg (ap, cpp_reader *); |
ab87f8c8 | 3081 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3082 | #endif |
3083 | ||
355142da | 3084 | if (CPP_OPTIONS (pfile)->pedantic_errors) |
ab87f8c8 | 3085 | v_cpp_error (pfile, msgid, ap); |
355142da | 3086 | else |
ab87f8c8 | 3087 | v_cpp_warning (pfile, msgid, ap); |
487a6e06 | 3088 | va_end(ap); |
355142da PB |
3089 | } |
3090 | ||
487a6e06 | 3091 | static void |
ab87f8c8 | 3092 | v_cpp_error_with_line (pfile, line, column, msgid, ap) |
487a6e06 KG |
3093 | cpp_reader * pfile; |
3094 | int line; | |
3095 | int column; | |
ab87f8c8 | 3096 | const char * msgid; |
487a6e06 | 3097 | va_list ap; |
355142da | 3098 | { |
355142da PB |
3099 | cpp_buffer *ip = cpp_file_buffer (pfile); |
3100 | ||
3101 | cpp_print_containing_files (pfile); | |
3102 | ||
3103 | if (ip != NULL) | |
487a6e06 | 3104 | cpp_file_line_for_message (pfile, ip->nominal_fname, line, column); |
355142da | 3105 | |
ab87f8c8 | 3106 | v_cpp_message (pfile, 1, msgid, ap); |
487a6e06 KG |
3107 | } |
3108 | ||
3109 | void | |
ab87f8c8 JL |
3110 | cpp_error_with_line VPROTO ((cpp_reader * pfile, int line, int column, |
3111 | const char *msgid, ...)) | |
487a6e06 | 3112 | { |
5148a72b | 3113 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3114 | cpp_reader *pfile; |
3115 | int line; | |
3116 | int column; | |
ab87f8c8 | 3117 | const char *msgid; |
487a6e06 KG |
3118 | #endif |
3119 | va_list ap; | |
3120 | ||
ab87f8c8 | 3121 | VA_START (ap, msgid); |
487a6e06 | 3122 | |
5148a72b | 3123 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3124 | pfile = va_arg (ap, cpp_reader *); |
3125 | line = va_arg (ap, int); | |
3126 | column = va_arg (ap, int); | |
ab87f8c8 | 3127 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3128 | #endif |
3129 | ||
ab87f8c8 | 3130 | v_cpp_error_with_line(pfile, line, column, msgid, ap); |
487a6e06 | 3131 | va_end(ap); |
355142da PB |
3132 | } |
3133 | ||
3232050c | 3134 | static void |
ab87f8c8 | 3135 | v_cpp_warning_with_line (pfile, line, column, msgid, ap) |
487a6e06 KG |
3136 | cpp_reader * pfile; |
3137 | int line; | |
3138 | int column; | |
ab87f8c8 | 3139 | const char *msgid; |
487a6e06 | 3140 | va_list ap; |
355142da | 3141 | { |
355142da PB |
3142 | cpp_buffer *ip; |
3143 | ||
3144 | if (CPP_OPTIONS (pfile)->inhibit_warnings) | |
3145 | return; | |
3146 | ||
3147 | if (CPP_OPTIONS (pfile)->warnings_are_errors) | |
3148 | pfile->errors++; | |
3149 | ||
3150 | cpp_print_containing_files (pfile); | |
3151 | ||
3152 | ip = cpp_file_buffer (pfile); | |
3153 | ||
3154 | if (ip != NULL) | |
487a6e06 | 3155 | cpp_file_line_for_message (pfile, ip->nominal_fname, line, column); |
355142da | 3156 | |
ab87f8c8 | 3157 | v_cpp_message (pfile, 0, msgid, ap); |
487a6e06 KG |
3158 | } |
3159 | ||
554fbeef | 3160 | void |
ab87f8c8 JL |
3161 | cpp_warning_with_line VPROTO ((cpp_reader * pfile, int line, int column, |
3162 | const char *msgid, ...)) | |
487a6e06 | 3163 | { |
5148a72b | 3164 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3165 | cpp_reader *pfile; |
3166 | int line; | |
3167 | int column; | |
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 KG |
3175 | pfile = va_arg (ap, cpp_reader *); |
3176 | line = va_arg (ap, int); | |
3177 | column = va_arg (ap, int); | |
ab87f8c8 | 3178 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3179 | #endif |
3180 | ||
ab87f8c8 | 3181 | v_cpp_warning_with_line (pfile, line, column, msgid, ap); |
487a6e06 | 3182 | va_end(ap); |
355142da PB |
3183 | } |
3184 | ||
3185 | void | |
ab87f8c8 JL |
3186 | cpp_pedwarn_with_line VPROTO ((cpp_reader * pfile, int line, int column, |
3187 | const char *msgid, ...)) | |
355142da | 3188 | { |
5148a72b | 3189 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3190 | cpp_reader *pfile; |
3191 | int line; | |
3192 | int column; | |
ab87f8c8 | 3193 | const char *msgid; |
487a6e06 KG |
3194 | #endif |
3195 | va_list ap; | |
3196 | ||
ab87f8c8 | 3197 | VA_START (ap, msgid); |
487a6e06 | 3198 | |
5148a72b | 3199 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3200 | pfile = va_arg (ap, cpp_reader *); |
3201 | line = va_arg (ap, int); | |
3202 | column = va_arg (ap, int); | |
ab87f8c8 | 3203 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3204 | #endif |
3205 | ||
355142da | 3206 | if (CPP_OPTIONS (pfile)->pedantic_errors) |
ab87f8c8 | 3207 | v_cpp_error_with_line (pfile, column, line, msgid, ap); |
355142da | 3208 | else |
ab87f8c8 | 3209 | v_cpp_warning_with_line (pfile, line, column, msgid, ap); |
487a6e06 | 3210 | va_end(ap); |
355142da PB |
3211 | } |
3212 | ||
3213 | /* Report a warning (or an error if pedantic_errors) | |
3214 | giving specified file name and line number, not current. */ | |
3215 | ||
3216 | void | |
ab87f8c8 JL |
3217 | cpp_pedwarn_with_file_and_line VPROTO ((cpp_reader *pfile, char *file, int line, |
3218 | const char *msgid, ...)) | |
355142da | 3219 | { |
5148a72b | 3220 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3221 | cpp_reader *pfile; |
3222 | char *file; | |
3223 | int line; | |
ab87f8c8 | 3224 | const char *msgid; |
487a6e06 KG |
3225 | #endif |
3226 | va_list ap; | |
3227 | ||
ab87f8c8 | 3228 | VA_START (ap, msgid); |
487a6e06 | 3229 | |
5148a72b | 3230 | #ifndef ANSI_PROTOTYPES |
487a6e06 KG |
3231 | pfile = va_arg (ap, cpp_reader *); |
3232 | file = va_arg (ap, char *); | |
3233 | line = va_arg (ap, int); | |
ab87f8c8 | 3234 | msgid = va_arg (ap, const char *); |
487a6e06 KG |
3235 | #endif |
3236 | ||
355142da PB |
3237 | if (!CPP_OPTIONS (pfile)->pedantic_errors |
3238 | && CPP_OPTIONS (pfile)->inhibit_warnings) | |
3239 | return; | |
3240 | if (file != NULL) | |
487a6e06 | 3241 | cpp_file_line_for_message (pfile, file, line, -1); |
ab87f8c8 | 3242 | v_cpp_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors, msgid, ap); |
487a6e06 | 3243 | va_end(ap); |
355142da PB |
3244 | } |
3245 | ||
0f41302f MS |
3246 | /* my_strerror - return the descriptive text associated with an |
3247 | `errno' code. */ | |
355142da | 3248 | |
6cd5dccd | 3249 | static char * |
355142da PB |
3250 | my_strerror (errnum) |
3251 | int errnum; | |
3252 | { | |
3253 | char *result; | |
3254 | ||
3255 | #ifndef VMS | |
3256 | #ifndef HAVE_STRERROR | |
3257 | result = (char *) ((errnum < sys_nerr) ? sys_errlist[errnum] : 0); | |
3258 | #else | |
3259 | result = strerror (errnum); | |
3260 | #endif | |
3261 | #else /* VMS */ | |
3262 | /* VAXCRTL's strerror() takes an optional second argument, which only | |
3263 | matters when the first argument is EVMSERR. However, it's simplest | |
3264 | just to pass it unconditionally. `vaxc$errno' is declared in | |
3265 | <errno.h>, and maintained by the library in parallel with `errno'. | |
3266 | We assume that caller's `errnum' either matches the last setting of | |
3267 | `errno' by the library or else does not have the value `EVMSERR'. */ | |
3268 | ||
3269 | result = strerror (errnum, vaxc$errno); | |
3270 | #endif | |
3271 | ||
3272 | if (!result) | |
ab87f8c8 | 3273 | result = "errno = ?"; |
355142da PB |
3274 | |
3275 | return result; | |
3276 | } | |
3277 | ||
3278 | /* Error including a message from `errno'. */ | |
3279 | ||
3280 | void | |
3281 | cpp_error_from_errno (pfile, name) | |
3282 | cpp_reader *pfile; | |
487a6e06 | 3283 | const char *name; |
d2f8cffa DB |
3284 | { |
3285 | cpp_message_from_errno (pfile, 1, name); | |
3286 | } | |
3287 | ||
3288 | void | |
3289 | cpp_message_from_errno (pfile, is_error, name) | |
3290 | cpp_reader *pfile; | |
3291 | int is_error; | |
3292 | const char *name; | |
355142da | 3293 | { |
e5e809f4 | 3294 | int e = errno; |
355142da PB |
3295 | cpp_buffer *ip = cpp_file_buffer (pfile); |
3296 | ||
3297 | cpp_print_containing_files (pfile); | |
3298 | ||
3299 | if (ip != NULL) | |
487a6e06 | 3300 | cpp_file_line_for_message (pfile, ip->nominal_fname, ip->lineno, -1); |
355142da | 3301 | |
4f70758f | 3302 | cpp_message (pfile, is_error, "%s: %s", name, my_strerror (e)); |
355142da PB |
3303 | } |
3304 | ||
3305 | void | |
3306 | cpp_perror_with_name (pfile, name) | |
3307 | cpp_reader *pfile; | |
487a6e06 | 3308 | const char *name; |
355142da | 3309 | { |
22bbceaf | 3310 | cpp_message (pfile, 1, "%s: %s: %s", progname, name, my_strerror (errno)); |
355142da | 3311 | } |
7f2935c7 PB |
3312 | |
3313 | /* TODO: | |
3314 | * No pre-compiled header file support. | |
3315 | * | |
3316 | * Possibly different enum token codes for each C/C++ token. | |
3317 | * | |
7f2935c7 PB |
3318 | * Find and cleanup remaining uses of static variables, |
3319 | * | |
7f2935c7 | 3320 | * Support -dM flag (dump_all_macros). |
782331f4 PB |
3321 | * |
3322 | * Support for_lint flag. | |
7f2935c7 | 3323 | */ |