Don't try calling lsl when file is missing.
[splint-patched.git] / src / cpplib.c
blobc70060ab548f05b3d82fdad71ec8e60025aa4fbb
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2003 University of Virginia,
4 ** Massachusetts Institute of Technology
5 **
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
10 **
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
15 **
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
25 ** cpplib.c
28 Copyright (C) 1986, 87, 89, 92-6, 1997 Free Software Foundation, Inc.
29 Contributed by Per Bothner, 1994-95.
30 Based on CCCP program by Paul Rubin, June 1986
31 Adapted to ANSI C, Richard Stallman, Jan 1987
33 This program is free software; you can redistribute it and/or modify it
34 under the terms of the GNU General Public License as published by the
35 Free Software Foundation; either version 2, or (at your option) any
36 later version.
38 This program is distributed in the hope that it will be useful,
39 but WITHOUT ANY WARRANTY; without even the implied warranty of
40 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41 GNU General Public License for more details.
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
47 In other words, you are welcome to use, share and improve this program.
48 You are forbidden to forbid anyone else to use, share and improve
49 what you give them. Help stamp out software-hoarding! */
51 # include <time.h>
52 # include <errno.h>
54 # include "splintMacros.nf"
55 # include "basic.h"
57 # include "cppconf.h"
58 # include "cpplib.h"
59 # include "cpperror.h"
60 # include "cpphash.h"
61 # include "cppexp.h"
62 # include "osd.h"
65 ** This is really kludgey code...
68 /*@+boolint@*/
69 /*@+charint@*/
71 /* Warnings for using sprintf - suppress them all for now... */
72 /*@-bufferoverflowhigh@*/
73 /*@-bounds@*/
75 /*@constant int IMPORT_FOUND@*/
76 # define IMPORT_FOUND -2
78 /*@constant int SKIP_INCLUDE@*/
79 # define SKIP_INCLUDE IMPORT_FOUND
81 /*@constant unused int IMPORT_NOT_FOUND@*/
82 # define IMPORT_NOT_FOUND -1
84 #ifndef STDC_VALUE
85 /*@constant unused int STDC_VALUE@*/
86 #define STDC_VALUE 1
87 #endif
89 /*@notfunction@*/
90 #define constlen(f) (sizeof(f) - 1)
92 static void parse_name (cppReader *, int);
94 static int cpp_openIncludeFile (char *p_filename)
95 /*@modifies fileSystem @*/ ;
97 static void cpp_setLocation (cppReader *p_pfile)
98 /*@modifies g_currentloc@*/ ;
100 static enum cpp_token cpp_handleComment (cppReader *p_pfile,
101 struct parse_marker *p_smark)
102 /*@modifies p_pfile, p_smark@*/;
104 static bool cpp_shouldCheckMacroAux (const char *p_p);
105 static bool cpp_shouldCheckMacro (cppReader *p_pfile, const char *p_p);
107 static size_t identifier_length (const /*@observer@*/ char *p_symname);
108 static bool identifier_seems_valid (const /*@observer@*/ char *p_symname);
109 static bool macro_name_is_valid (const /*@observer@*/ char *p_symname, size_t p_symlen);
110 static /*@only@*/ cstring invalid_macro_message (const /*@observer@*/ char *p_symname, size_t symlen);
112 static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
114 /* Symbols to predefine. */
116 static /*@observer@*/ const char *predefs = CPP_PREDEFINES;
118 /* We let tm.h override the types used here, to handle trivial differences
119 such as the choice of unsigned int or long unsigned int for size_t.
120 When machines start needing nontrivial differences in the size type,
121 it would be best to do something here to figure out automatically
122 from other information what type to use. */
124 /* The string value for __SIZE_TYPE__. */
126 #ifndef SIZE_TYPE
127 /*@constant observer char *SIZE_TYPE@*/
128 #define SIZE_TYPE "long unsigned int"
129 #endif
131 /* The string value for __PTRDIFF_TYPE__. */
133 #ifndef PTRDIFF_TYPE
134 /*@constant observer char *PTRDIFF_TYPE@*/
135 #define PTRDIFF_TYPE "long int"
136 #endif
138 /* The string value for __WCHAR_TYPE__. */
140 #ifndef WCHAR_TYPE
141 /*@constant observer char *WCHAR_TYPE@*/
142 #define WCHAR_TYPE "int"
143 #endif
145 /* The string value for __USER_LABEL_PREFIX__ */
147 #ifndef USER_LABEL_PREFIX
148 /*@constant observer char *USER_LABEL_PREFIX@*/
149 #define USER_LABEL_PREFIX ""
150 #endif
152 /* The string value for __REGISTER_PREFIX__ */
154 #ifndef REGISTER_PREFIX
155 /*@constant observer char *REGISTER_PREFIX@*/
156 #define REGISTER_PREFIX ""
157 #endif
159 /* table to tell if char can be part of a C identifier. */
160 static bool is_idchar[256];
161 /* table to tell if char can be first char of a c identifier. */
162 static bool is_idstart[256];
163 /* table to tell if c is horizontal space. */
164 static bool is_hor_space[256];
165 /* table to tell if c is horizontal or vertical space. */
166 static bool is_space[256];
168 static /*@exposed@*/ /*@null@*/ cppBuffer *
169 cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)
170 /*@uses p_pfile->buffer@*/
171 /*@modifies nothing@*/ ;
173 /*@notfunction@*/
174 # define SKIP_CLASS(p,class) do { /*@access cstring@*/ while (class[(int) *(p)]) { (p)++; } } /*@noaccess cstring@*/ while (0)
176 /*@notfunction@*/
177 # define SKIP_WHITE_SPACE(p) SKIP_CLASS(p, is_hor_space)
179 #ifdef DEADCODE
180 /*@notfunction@*/
181 # define SKIP_ALL_WHITE_SPACE(p) SKIP_CLASS(p, is_space)
182 #endif
184 /*@notfunction@*/
185 # define SKIP_IDENTIFIER(p) SKIP_CLASS(p, is_idchar)
187 static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;
189 static void cppReader_growBuffer (cppReader *, size_t);
191 /* Make sure PFILE->token_buffer has space for at least N more characters. */
193 /*@function static void cpplib_reserve (sef cppReader *, sef size_t); @*/
194 #define cpplib_reserve(PFILE, N) \
195 do { \
196 if ((cpplib_getWritten (PFILE) + (N) > (PFILE)->token_buffer_size)) \
197 cppReader_growBuffer (PFILE, (N)); \
198 } while (0)
200 /*@function static int cppBuffer_get (sef cppBuffer *p_b) modifies *p_b ; @*/
201 # define cppBuffer_get(BUFFER) \
202 ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
204 /*@function static int cppBuffer_reachedEOF (sef cppBuffer *p_b) modifies nothing; @*/
205 # define cppBuffer_reachedEOF(b) \
206 ((b)->cur < (b)->rlimit ? FALSE : TRUE)
208 /* Append string STR (of length N) to PFILE's output buffer. Assume there is enough space. */
210 /*@function static void cppReader_putStrN (sef cppReader *p_file, const @unique@ char *p_str,
211 sef size_t p_n) modifies *p_file; @*/
212 #define cppReader_putStrN(PFILE, STR, N) \
213 do { memcpy ((PFILE)->limit, STR, (N)); (PFILE)->limit += (N); } while (0)
215 /* Append string STR (of length N) to PFILE's output buffer. Make space. */
217 /*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)
218 modifies *p_file; @*/
219 # define cppReader_puts(PFILE, STR, N) \
220 do { cpplib_reserve(PFILE, N); cppReader_putStrN (PFILE, STR,N); } while (0)
222 /* Append character CH to PFILE's output buffer. Assume sufficient space. */
224 /*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)
225 modifies *p_file; @*/
226 # define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
228 /* Append character CH to PFILE's output buffer. Make space if need be. */
230 /*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)
231 modifies *p_file; @*/
232 #define cppReader_putChar(PFILE, CH) \
233 do { cpplib_reserve (PFILE, (size_t) 1); cppReader_putCharQ (PFILE, CH); } while (0)
235 /* Make sure PFILE->limit is followed by '\0'. */
237 /*@function static void cppReader_nullTerminateQ (cppReader *p_file)
238 modifies *p_file; @*/
239 #define cppReader_nullTerminateQ(PFILE) (*(PFILE)->limit = 0)
241 /*@function static void cppReader_nullTerminate (sef cppReader *p_file)
242 modifies *p_file; @*/
243 # define cppReader_nullTerminate(PFILE) \
244 do { cpplib_reserve (PFILE, (size_t) 1); *(PFILE)->limit = 0; } while (0)
246 /*@function static void cppReader_adjustWritten (cppReader *p_file, size_t)
247 modifies *p_file; @*/
248 #define cppReader_adjustWritten(PFILE,DELTA) ((PFILE)->limit += (DELTA))
250 /*@function static bool cppReader_isC89 (cppReader *) modifies nothing; @*/
251 #define cppReader_isC89(PFILE) (CPPOPTIONS(PFILE)->c89)
253 static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ ;
255 /*@function static void cppReader_forward (cppReader *p_pfile, int) modifies *p_pfile; @*/
256 # define cppReader_forward(pfile, N) \
257 (cppBuffer_forward (cppReader_getBufferSafe (pfile), (N)))
259 /*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/
260 # define cppReader_getC(pfile) (cppBuffer_get (cppReader_getBufferSafe (pfile)))
262 /*@function static int cppReader_reachedEOF (sef cppReader *p_pfile) modifies *p_pfile; @*/
263 # define cppReader_reachedEOF(pfile) (cppBuffer_reachedEOF (cppReader_getBufferSafe (pfile)))
265 /*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/
266 # define cppReader_peekC(pfile) (cpplib_bufPeek (cppReader_getBufferSafe (pfile)))
268 /* Move all backslash-newline pairs out of embarrassing places.
269 Exchange all such pairs following BP
270 with any potentially-embarrassing characters that follow them.
271 Potentially-embarrassing characters are / and *
272 (because a backslash-newline inside a comment delimiter
273 would cause it not to be recognized). */
275 /*@notfunction@*/
276 # define NEWLINE_FIX \
277 do { \
278 while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n') \
280 cppReader_forward (pfile, 2); \
282 } while(FALSE)
284 /* Same, but assume we've already read the potential '\\' into C. */
286 /*@notfunction@*/
287 # define NEWLINE_FIX1(C) \
288 do { \
289 while ((C) == '\\' && cppReader_peekC (pfile) == '\n') \
291 cppReader_forward (pfile, 1); \
292 (C) = cppReader_getC (pfile); \
294 } while(FALSE)
296 static void parseSetMark (/*@out@*/ struct parse_marker *,
297 cppReader *);
298 static void parseClearMark (struct parse_marker *);
299 static void parseGotoMark (struct parse_marker *, cppReader *);
300 static void parseMoveMark (struct parse_marker *, cppReader *);
302 /* If we have a huge buffer, may need to cache more recent counts */
303 static /*@exposed@*/ char *cppLineBase (/*@sef@*/ cppBuffer *);
305 static /*@exposed@*/ /*@null@*/ cppBuffer *
306 cppReader_pushBuffer (cppReader *p_pfile,
307 /*@owned@*/ /*@null@*/ char *, size_t)
308 /*@modifies p_pfile@*/ ;
310 static void cppReader_appendIncludeChain (cppReader *p_pfile,
311 /*@keep@*/ struct file_name_list *p_first,
312 /*@dependent@*/ struct file_name_list *p_last,
313 bool p_system);
315 static void cppReader_macroCleanup (cppBuffer *p_pbuf, cppReader *p_pfile);
316 static enum cpp_token cppReader_nullUnderflow (/*@unused@*/ cppReader *p_pfile);
318 static void cppReader_nullCleanup (/*@unused@*/ cppBuffer *p_pbuf,
319 /*@unused@*/ cppReader *p_pfile);
321 static void cppReader_fileCleanup (cppBuffer *p_pbuf,
322 /*@unused@*/ cppReader *p_pfile);
324 static int cppReader_handleDirective (cppReader *p_pfile);
326 static void cppReader_scanBuffer (cppReader *p_pfile);
329 ** cppBuffer_isMacro is true if the buffer contains macro expansion.
330 ** (Note that it is false while we're expanding marco *arguments*.)
333 static bool cppBuffer_isMacro (/*@null@*/ cppBuffer *) /*@*/ ;
335 static void initialize_builtins (cppReader *p_pfile)
336 /*@modifies p_pfile@*/ ;
338 static void initialize_char_syntax (struct cppOptions *p_opts) ;
340 static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f,
341 cstring p_fname,
342 bool p_system_header_p,
343 /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);
345 static void validate_else (cppReader *p_pfile, cstring p_directive);
347 static void conditional_skip (cppReader *p_pfile, int p_skip,
348 enum node_type p_type,
349 /*@dependent@*/ /*@null@*/ char *p_control_macro);
351 static HOST_WIDE_INT eval_if_expression (cppReader *p_pfile);
353 static void skip_if_group (cppReader *p_pfile, bool p_any);
355 static bool comp_def_part (bool p_first, char *p_beg1, int p_len1,
356 char *p_beg2, int p_len2, bool p_last);
358 static bool redundant_include_p (cppReader *p_pfile, /*@null@*/ cstring p_name);
359 static bool is_system_include (cppReader *p_pfile, cstring p_filename);
361 static /*@observer@*/ /*@null@*/ struct file_name_map *
362 read_name_map (cppReader *p_pfile, cstring p_dirname);
364 static cstring read_filename_string (int p_ch, /*:open:*/ FILE *p_f);
366 static int open_include_file (cppReader *p_pfile,
367 /*@owned@*/ cstring p_fname,
368 /*@null@*/ struct file_name_list *p_searchptr);
370 static void push_macro_expansion (cppReader *,
371 /*@owned@*/ char *, size_t,
372 /*@dependent@*/ hashNode);
374 /* Last arg to output_line_command. */
375 enum file_change_code {
376 same_file, enter_file, leave_file
379 struct directive;
380 typedef void (*handleDirective) (cppReader *, struct directive *, const char *, const char *);
382 /* `struct directive' defines one #-directive, including how to handle it. */
384 struct directive {
385 int length; /* Length of name */
386 /*@null@*/ handleDirective func; /* Function to handle directive */
387 const /*@observer@*/ char *name; /* Name of directive */
388 enum node_type type; /* Code which describes which directive. */
389 bool command_reads_line; /* True if rest of line is read by func. */
390 bool traditional_comments; /* True: keep comments if -traditional. */
391 bool pass_thru; /* Copy preprocessed directive to output file.*/
394 static void do_define (cppReader *, /*@null@*/ struct directive *,
395 const /*@exposed@*/ char *, const char *);
396 static void do_defineAux (cppReader *, /*@null@*/ struct directive *,
397 const /*@exposed@*/ char *, const char *, bool);
399 static void do_line (cppReader *, /*@null@*/ struct directive *, const char *, const char *);
400 static void do_include (cppReader *, struct directive *, const char *, const char *);
401 static void do_undef (cppReader *, struct directive *, const char *, const char *);
402 static void do_error (cppReader *, struct directive *, const char *, const char *);
403 static void do_pragma (cppReader *, struct directive *, const char *, const char *);
404 static void do_ident (cppReader *, struct directive *, const char *, const char *);
405 static void do_if (cppReader *, struct directive *, const char *, const char *);
406 static void do_xifdef (cppReader *, struct directive *, const char *, const char *);
407 static void do_else (cppReader *, struct directive *, const char *, const char *);
408 static void do_elif (cppReader *, struct directive *, const char *, const char *);
409 static void do_endif (cppReader *, struct directive *, const char *, const char *);
410 static void do_warning (cppReader *, struct directive *, const char *, const char *);
412 /* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found
413 via the same directory as the file that #included it. */
415 /*@constant observer struct file_name_list *SELF_DIR_DUMMY@*/
416 #define SELF_DIR_DUMMY ((struct file_name_list *) (~0))
418 /* #include "file" looks in source file dir, then stack. */
419 /* #include <file> just looks in the stack. */
420 /* -I directories are added to the end, then the defaults are added. */
422 /* Here is the actual list of #-directives, most-often-used first.
423 The initialize_builtins function assumes #define is the very first. */
425 /*@access cstring@*/
427 static struct directive directive_table[] = {
428 { 6, do_define, "define", T_DEFINE, FALSE, TRUE, FALSE },
429 { 5, do_xifdef, "ifdef", T_IFDEF, TRUE, FALSE, FALSE },
430 { 6, do_xifdef, "ifndef", T_IFNDEF, TRUE, FALSE, FALSE },
431 { 7, do_include, "include", T_INCLUDE, TRUE, FALSE, FALSE },
432 #if 0
433 { 12, do_include, "include_next", T_INCLUDE_NEXT, TRUE, FALSE, FALSE },
434 #endif
435 { 5, do_endif, "endif", T_ENDIF, TRUE, FALSE, FALSE },
436 { 4, do_else, "else", T_ELSE, TRUE, FALSE, FALSE },
437 { 2, do_if, "if", T_IF, TRUE, FALSE, FALSE },
438 { 4, do_elif, "elif", T_ELIF, TRUE, FALSE, FALSE },
439 { 5, do_undef, "undef", T_UNDEF, FALSE, FALSE, FALSE },
440 { 5, do_error, "error", T_ERROR, FALSE, FALSE, FALSE },
441 { 7, do_warning, "warning", T_WARNING, FALSE, FALSE, FALSE },
442 { 6, do_pragma, "pragma", T_PRAGMA, FALSE, FALSE, TRUE},
443 { 4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },
444 { 5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },
445 /* { 8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */
446 { -1, NULL, "", T_UNUSED, FALSE, FALSE, FALSE },
448 /*@noaccess cstring@*/
450 static cstring searchPath_unparse (struct file_name_list *search_start)
452 cstring res = cstring_newEmpty ();
453 struct file_name_list *searchptr;
455 for (searchptr = search_start; searchptr != NULL;
456 searchptr = searchptr->next)
458 if (!cstring_isEmpty (searchptr->fname))
460 res = cstring_concatFree1 (res, searchptr->fname);
461 if (searchptr->next != NULL) {
462 res = cstring_appendChar (res, PATH_SEPARATOR);
467 return res;
470 /*@+charint@*/
471 static void
472 initialize_char_syntax (struct cppOptions *opts)
474 char i;
477 * Set up is_idchar and is_idstart tables. These should be
478 * faster than saying (is_alpha (c) || c == '_'), etc.
479 * Set up these things before calling any routines that
480 * refer to them.
483 for (i = 'a'; i <= 'z'; i++) {
484 is_idchar[i - 'a' + 'A'] = TRUE;
485 is_idchar[(int) i] = TRUE;
486 is_idstart[i - 'a' + 'A'] = TRUE;
487 is_idstart[(int) i] = TRUE;
490 for (i = '0'; i <= '9'; i++)
492 is_idchar[(int) i] = TRUE;
495 is_idchar['_'] = TRUE;
496 is_idstart['_'] = TRUE;
497 is_idchar['$'] = opts->dollars_in_ident;
498 is_idstart['$'] = opts->dollars_in_ident;
500 /* horizontal space table */
501 is_hor_space[' '] = TRUE;
502 is_hor_space['\t'] = TRUE;
503 is_hor_space['\v'] = TRUE;
504 is_hor_space['\f'] = TRUE;
505 is_hor_space['\r'] = TRUE;
507 is_space[' '] = TRUE;
508 is_space['\t'] = TRUE;
509 is_space['\v'] = TRUE;
510 is_space['\f'] = TRUE;
511 is_space['\n'] = TRUE;
512 is_space['\r'] = TRUE;
515 /* Place into P_PFILE a quoted string representing the string SRC.
516 Caller must reserve enough space in pfile->token_buffer. */
518 static void
519 quote_string (cppReader *pfile, const char *src)
521 cppReader_putCharQ (pfile, '\"');
522 for (;;)
524 char c = *src++;
526 switch (c)
528 default:
529 if (isprint (c))
530 cppReader_putCharQ (pfile, c);
531 else
533 sprintf (cpplib_getPWritten (pfile), "\\%03o",
534 (unsigned int) c);
535 cppReader_adjustWritten (pfile, (size_t) 4);
537 /*@switchbreak@*/ break;
539 case '\"':
540 case '\\':
541 cppReader_putCharQ (pfile, '\\');
542 cppReader_putCharQ (pfile, c);
543 /*@switchbreak@*/ break;
545 case '\0':
546 cppReader_putCharQ (pfile, '\"');
547 cppReader_nullTerminateQ (pfile);
548 return;
553 /* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
555 static void
556 cppReader_growBuffer (cppReader *pfile, size_t n)
558 size_t old_written = cpplib_getWritten (pfile);
559 pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
560 pfile->token_buffer = (char *)
561 drealloc (pfile->token_buffer, pfile->token_buffer_size);
562 cppReader_setWritten (pfile, old_written);
566 * process a given definition string, for initialization
567 * If STR is just an identifier, define it with value 1.
568 * If STR has anything after the identifier, then it should
569 * be identifier=definition.
572 static void
573 cppReader_defineReal (cppReader *pfile, const char *str)
575 char *buf = NULL;
576 const char *p;
577 size_t idlen;
579 DPRINTF (("Cpp reader define: %s", cstring_fromChars (str)));
581 idlen = identifier_length (str);
582 if (idlen == 0)
584 cppReader_error (pfile,
585 message ("Malformed option `-D%s'",
586 cstring_fromChars (str)));
587 return;
589 p = str + idlen;
591 if (*p == '(') {
592 p++;
593 while (*p != ')' && *p != '\0') {
594 p++;
597 if (*p == ')') {
598 p++;
599 } else {
600 cppReader_error
601 (pfile,
602 message ("Malformed option: -D%s (no closing parenthesis)",
603 cstring_fromChars (str)));
607 DPRINTF (("Here 2"));
609 if (*p == '\0')
611 buf = (char *) dmalloc (size_fromInt (p - str + 4));
612 strcpy ((char *) buf, str);
613 strcat ((char *) buf, " 1");
615 else if (*p != '=')
617 DPRINTF (("ERROR 2"));
618 cppReader_error (pfile,
619 message ("Malformed option: -D%s (expected '=', found '%c')",
620 cstring_fromChars (str),
621 *p));
622 return;
624 else
626 char *q;
627 /* Copy the entire option so we can modify it. */
628 DPRINTF (("Copying..."));
629 buf = (char *) dmalloc (2 * strlen (str) + 1);
630 strncpy (buf, str, size_fromInt (p - str));
632 /* Change the = to a space. */
633 buf[p - str] = ' ';
634 /* Scan for any backslash-newline and remove it. */
635 p++;
636 q = &buf[p - str];
638 while (*p != '\0')
640 if (*p == '\\' && p[1] == '\n')
641 p += 2;
642 else
643 *q++ = *p++;
646 DPRINTF (("Here we are..."));
647 *q = '\0';
650 llassert (buf != NULL);
651 DPRINTF (("Do define: %s / %ld", buf, size_toLong (strlen (buf))));
652 (void) cpp_shouldCheckMacroAux (buf);
653 do_define (pfile, NULL, buf, buf + strlen (buf));
654 sfree (buf);
657 static void
658 cppReader_define (cppReader *pfile, const char *str)
660 cppBuffer *tbuf = CPPBUFFER (pfile);
662 CPPBUFFER (pfile) = NULL;
663 cppReader_defineReal (pfile, str);
664 CPPBUFFER (pfile) = tbuf;
667 /* Append a chain of `struct file_name_list's
668 to the end of the main include chain.
669 FIRST is the beginning of the chain to append, and LAST is the end. */
671 static void
672 cppReader_appendIncludeChain (cppReader *pfile,
673 struct file_name_list *first,
674 struct file_name_list *last,
675 bool system)
677 struct cppOptions *opts = CPPOPTIONS (pfile);
679 if (first == NULL || last == NULL)
681 return;
684 if (opts->include == NULL)
686 opts->include = first;
688 else
690 llassert (opts->last_include->next == NULL);
691 opts->last_include->next = first;
694 if (opts->first_bracket_include == NULL)
696 opts->first_bracket_include = first;
699 if (system)
701 /*@-usereleased@*/ /* Spurious warnings for opts->first_system_include */
702 if (opts->first_system_include == NULL)
704 opts->first_system_include = first;
706 /*@=usereleased@*/
709 llassert (last->next == NULL);
710 opts->last_include = last;
713 static void
714 cppReader_appendDirIncludeChain (cppReader *pfile, char* fname, bool system)
716 struct file_name_list *dirtmp;
718 DPRINTF (("Adding include dir: %s", fname));
720 dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));
721 llassert (dirtmp != NULL);
723 /* create a chain of only one element */
724 dirtmp->fname = mstring_copy (fname);
725 dirtmp->next = NULL;
726 dirtmp->control_macro = NULL;
727 dirtmp->name_map = NULL;
728 dirtmp->got_name_map = FALSE;
730 cppReader_appendIncludeChain (pfile, dirtmp, dirtmp, system);
733 static void
734 pathList_to_fileNameList (const char *pathList,
735 struct file_name_list **pfirst, struct file_name_list **plast)
737 struct file_name_list *first = NULL, *last = NULL;
739 llassert (pfirst != NULL);
740 llassert (plast != NULL);
742 if (pathList != NULL && *pathList != '\0')
744 const char *p, *q;
746 #ifdef __CYGWIN32__
747 char *win32temp;
749 /* if we have a posix path list, convert to win32 path list */
750 win32temp = (char *) dmalloc /*@i4@*/
751 (cygwin32_posix_to_win32_path_list_buf_size (pathList));
752 cygwin32_posix_to_win32_path_list (pathList, win32temp);
753 p = win32temp;
754 #else
755 p = pathList;
756 #endif
760 q = p;
762 /* Find the end of this name. */
763 while (*q != '\0' && *q != PATH_SEPARATOR)
765 q++;
769 char *name;
770 struct file_name_list *tmp;
772 if (q == p)
774 /* An empty name in the path stands for the current directory. */
775 name = (char *) dmalloc ((size_t) 2);
776 name[0] = '.';
777 name[1] = '\0';
779 else
781 /* Otherwise use the directory that is named. */
782 size_t len = size_fromInt (q-p);
783 name = (char *) dmalloc (len + 1);
784 memcpy (name, p, len);
785 name[len] = '\0';
788 tmp = (struct file_name_list *) dmalloc (sizeof (*tmp));
789 llassert (tmp != NULL);
791 tmp->next = NULL; /* New one goes on the end */
792 tmp->fname = cstring_fromChars (name);
793 tmp->control_macro = NULL;
794 tmp->name_map = NULL;
795 tmp->got_name_map = FALSE;
797 if (last == NULL) /* initialize first & last */
799 llassert (first == NULL);
800 last = first = tmp;
802 else
804 llassert (first != NULL);
806 last->next = tmp;
807 last = tmp;
811 p = q+1; /* Advance past this name. */
813 while (*q != '\0');
815 #ifdef __CYGWIN32__
816 sfree (win32temp);
817 #endif
820 *pfirst = first;
821 *plast = last;
824 static void
825 cppReader_appendPathListIncludeChain (cppReader *pfile,
826 const char *pathList, bool system)
828 struct file_name_list *first, *last;
829 pathList_to_fileNameList (pathList, &first, &last);
830 cppReader_appendIncludeChain (pfile, first, last, system);
833 static void
834 cppOptions_init (/*@out@*/ cppOptions *opts)
836 memset ((char *) opts, 0, sizeof *opts);
837 assertSet (opts);
839 opts->in_fname = NULL;
840 opts->out_fname = NULL;
842 /* Initialize is_idchar to allow $. */
843 opts->dollars_in_ident = TRUE;
845 opts->no_line_commands = FALSE;
846 opts->no_trigraphs = TRUE;
847 opts->put_out_comments = TRUE;
848 opts->dump_macros = DUMP_DEFINITIONS; /* DUMP_NONE; */
849 opts->no_output = FALSE;
851 opts->cplusplus_comments = TRUE;
852 opts->verbose = FALSE;
853 opts->lang_asm = FALSE;
854 opts->pedantic_errors = FALSE;
855 opts->warn_comments = FALSE;
856 opts->warnings_are_errors = FALSE;
858 /* Added 2003-07-10: */
859 opts->traditional = FALSE;
860 opts->c89 = TRUE;
863 enum cpp_token
864 cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile)
866 return CPP_EOF;
869 void
870 cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,
871 /*@unused@*/ cppReader *pfile)
876 void
877 cppReader_macroCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
879 hashNode macro = pbuf->hnode;
881 if (macro->type == T_DISABLED)
883 macro->type = T_MACRO;
886 if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
888 sfree (pbuf->buf);
889 pbuf->buf = NULL;
893 void
894 cppReader_fileCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
896 if (pbuf->buf != NULL)
898 sfree (pbuf->buf);
899 pbuf->buf = NULL;
903 /* Assuming we have read '/'.
904 If this is the start of a comment (followed by '*' or '/'),
905 skip to the end of the comment, and return ' '.
906 Return EOF if we reached the end of file before the end of the comment.
907 If not the start of a comment, return '/'. */
909 static int
910 skip_comment (cppReader *pfile, /*@null@*/ long *linep)
912 llassert (pfile->buffer != NULL);
913 llassert (pfile->buffer->cur != NULL);
915 while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n')
917 if (linep != NULL)
919 (*linep)++;
922 cppReader_forward (pfile, 2);
925 if (cppReader_peekC (pfile) == '*')
927 int c = 0;
929 cppReader_forward (pfile, 1);
931 for (;;)
933 int prev_c = c;
934 c = cppReader_getC (pfile);
936 if (c == EOF)
938 return EOF;
941 while (c == (int) '\\' && cppReader_peekC (pfile) == (int) '\n')
943 if (linep != NULL )
945 (*linep)++;
948 cppReader_forward (pfile, 1), c = cppReader_getC (pfile);
951 if (prev_c == (int) '*' && c == (int) '/')
953 return (int) ' ';
956 if (c == (int) '\n' && (linep != NULL))
958 (*linep)++;
962 else if (cppReader_peekC (pfile) == '/'
963 && CPPOPTIONS (pfile)->cplusplus_comments)
965 (void) cppoptgenerror
966 (FLG_SLASHSLASHCOMMENT,
967 message ("C++ style // comment"
969 pfile);
971 cppReader_forward (pfile, 1);
973 for (;;)
975 int c = cppReader_getC (pfile);
977 if (c == EOF)
979 /* Allow hash comment to be terminated by EOF. */
980 return (int) ' ';
983 while (c == (int) '\\' && cppReader_peekC (pfile) == '\n')
985 cppReader_forward (pfile, 1);
986 c = cppReader_getC (pfile);
988 if (linep != NULL)
990 (*linep)++;
994 if (c == (int) '\n')
996 /* Don't consider final '\n' to be part of comment. */
997 cppReader_forward (pfile, -1);
998 return (int) ' ';
1002 else
1004 return (int) '/';
1008 /* Skip whitespace \-newline and comments. Does not macro-expand. */
1009 int /*@alt void@*/
1010 cppSkipHspace (cppReader *pfile)
1012 int nspaces = 0;
1014 while (TRUE)
1016 int c;
1018 llassert (pfile->buffer != NULL);
1020 c = cppReader_peekC (pfile);
1022 if (c == EOF)
1024 return 0; /* FIXME */
1027 if (is_hor_space[c])
1029 if ((c == '\f' || c == '\v') && cppReader_isPedantic (pfile))
1030 cppReader_pedwarn (pfile,
1031 message ("%s in preprocessing directive",
1032 c == '\f'
1033 ? cstring_makeLiteralTemp ("formfeed")
1034 : cstring_makeLiteralTemp ("vertical tab")));
1036 nspaces++;
1037 cppReader_forward (pfile, 1);
1039 else if (c == '/')
1041 cppReader_forward (pfile, 1);
1042 c = skip_comment (pfile, NULL);
1044 if (c == '/')
1046 cppReader_forward (pfile, -1);
1049 if (c == EOF || c == '/')
1051 return nspaces;
1054 else if (c == '\\' && cpp_peekN (pfile, 1) == '\n')
1056 cppReader_forward (pfile, 2);
1058 else if (c == '@' && CPPBUFFER (pfile)->has_escapes
1059 && is_hor_space [cpp_peekN (pfile, 1)])
1061 cppReader_forward (pfile, 2);
1063 else
1065 return nspaces;
1070 /* Read the rest of the current line.
1071 The line is appended to PFILE's output buffer. */
1073 static void
1074 copy_rest_of_line (cppReader *pfile)
1076 struct cppOptions *opts = CPPOPTIONS (pfile);
1078 for (;;)
1080 int c;
1081 int nextc;
1083 llassert (pfile->buffer != NULL);
1085 c = cppReader_getC (pfile);
1087 switch (c)
1089 case EOF:
1090 goto end_directive;
1091 case '\\':
1093 ** Patch from Brian St. Pierre for handling MS-DOS files.
1096 DPRINTF (("Reading directive: %d", (int) c));
1098 if (cppReader_peekC (pfile) == '\n'
1099 || cppReader_peekC (pfile) == '\r')
1101 DPRINTF (("Reading directive..."));
1102 if (cppReader_peekC (pfile) == '\r')
1104 DPRINTF (("Reading directive..."));
1105 cppReader_forward (pfile, 1);
1108 DPRINTF (("Reading directive..."));
1109 cppReader_forward (pfile, 1);
1110 continue;
1113 DPRINTF (("Falling..."));
1114 /*@fallthrough@*/ case '\'': case '\"':
1115 goto scan_directive_token;
1117 case '/':
1118 nextc = cppReader_peekC (pfile);
1121 ** was (opts->cplusplus_comments && nextc == '*')
1122 ** yoikes!
1125 if (nextc == '*'
1126 || (opts->cplusplus_comments && nextc == '/'))
1128 goto scan_directive_token;
1130 /*@switchbreak@*/ break;
1131 case '\f':
1132 case '\v':
1133 if (cppReader_isPedantic (pfile))
1134 cppReader_pedwarn (pfile,
1135 message ("%s in preprocessing directive",
1136 c == '\f'
1137 ? cstring_makeLiteralTemp ("formfeed")
1138 : cstring_makeLiteralTemp ("vertical tab")));
1139 /*@switchbreak@*/ break;
1141 case '\n':
1142 cppReader_forward (pfile, -1);
1143 goto end_directive;
1144 scan_directive_token:
1145 cppReader_forward (pfile, -1);
1146 (void) cpplib_getToken (pfile);
1147 continue;
1149 cppReader_putChar (pfile, (char) c);
1151 end_directive: ;
1152 cppReader_nullTerminate (pfile);
1155 void
1156 cppReader_skipRestOfLine (cppReader *pfile)
1158 size_t old = cpplib_getWritten (pfile);
1159 copy_rest_of_line (pfile);
1160 cppReader_setWritten (pfile, old);
1163 /* Handle a possible # directive.
1164 '#' has already been read. */
1166 static int
1167 cppReader_handleDirective (cppReader *pfile)
1169 int c;
1170 struct directive *kt;
1171 int ident_length;
1172 size_t after_ident = 0;
1173 char *ident = NULL;
1174 char *line_end = NULL;
1175 size_t old_written = cpplib_getWritten (pfile);
1176 int nspaces = cppSkipHspace (pfile);
1178 c = cppReader_peekC (pfile);
1180 if (c >= '0' && c <= '9')
1182 /* Handle # followed by a line number. */
1183 if (cppReader_isPedantic (pfile))
1185 cppReader_pedwarnLit
1186 (pfile,
1187 cstring_makeLiteralTemp ("`#' followed by integer"));
1190 do_line (pfile, NULL, NULL, NULL);
1191 return 1;
1195 /* Now find the directive name. */
1197 cppReader_putChar (pfile, '#');
1199 parse_name (pfile, cppReader_getC (pfile));
1201 llassert (pfile->token_buffer != NULL);
1202 ident = pfile->token_buffer + old_written + 1;
1204 ident_length = cpplib_getPWritten (pfile) - ident;
1206 if (ident_length == 0 && cppReader_peekC (pfile) == '\n')
1208 /* A line of just `#' becomes blank. */
1209 return 1;
1212 for (kt = directive_table; ; kt++)
1214 if (kt->length <= 0)
1216 return 0; /* goto not_a_directive; */
1219 if (kt->length == ident_length &&
1220 strncmp (kt->name, ident, size_fromInt (kt->length)) == 0)
1222 break;
1226 if (kt->command_reads_line)
1228 after_ident = 0;
1230 else
1232 /* True means do not delete comments within the directive.
1233 #define needs this when -traditional. */
1234 bool save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
1235 CPPOPTIONS (pfile)->put_out_comments =
1236 /*cppReader_isTraditional (pfile) && kt->traditional_comments */ TRUE;
1237 after_ident = cpplib_getWritten (pfile);
1238 copy_rest_of_line (pfile);
1239 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
1243 /* For #pragma and #define, we may want to pass through the directive.
1244 Other directives may create output, but we don't want the directive
1245 itself out, so we pop it now. For example #include may write a #line
1246 command (see comment in do_include), and conditionals may emit
1247 #failed ... #endfailed stuff. But note that popping the buffer
1248 means the parameters to kt->func may point after pfile->limit
1249 so these parameters are invalid as soon as something gets appended
1250 to the token_buffer. */
1252 line_end = cpplib_getPWritten (pfile);
1255 if (!kt->pass_thru && kt->type != T_DEFINE)
1257 cppReader_setWritten (pfile, old_written);
1260 llassert (pfile->token_buffer != NULL);
1262 /* was kt->pass_thru || */
1264 if (kt->type == T_DEFINE
1265 && cpp_shouldCheckMacro (pfile, pfile->token_buffer + old_written))
1267 char *p = pfile->token_buffer + old_written;
1270 ** Still need to record value for preprocessing, so
1271 ** #ifdef's, etc. using the value behave correctly.
1274 do_defineAux (pfile, kt,
1275 pfile->token_buffer + after_ident,
1276 line_end,
1277 FALSE);
1280 ** Transform "[#{hor_space}*]define" to "[ ]@QLMR(x)", where x
1281 ** is the minimum between 9 and nspaces.
1284 if (*p == '#')
1286 *p = ' ';
1289 SKIP_WHITE_SPACE (p);
1291 llassert (constlen (LLMRCODE) + 1 == size_fromInt (kt->length));
1292 strcpy (p, LLMRCODE);
1293 p += constlen (LLMRCODE);
1296 ** This is way-bogus. We use the last char to record the number of
1297 ** spaces. Its too hard to get them back into the input stream.
1300 if (nspaces > 9) nspaces = 9;
1302 *p++ = '0' + nspaces;
1304 return 0; /* not_a_directive */
1306 else if (kt->pass_thru)
1308 /* Just leave the entire #define in the output stack. */
1309 return 0; /* not_a_directive */
1311 else if (kt->type == T_DEFINE
1312 && CPPOPTIONS (pfile)->dump_macros == DUMP_NAMES)
1314 char *p = pfile->token_buffer + old_written + 1 + kt->length; /* Skip "#define". */
1315 SKIP_WHITE_SPACE (p);
1316 SKIP_IDENTIFIER (p);
1317 pfile->limit = p;
1318 cppReader_putChar (pfile, '\n');
1320 else if (kt->type == T_DEFINE)
1322 cppReader_setWritten (pfile, old_written);
1324 else
1329 llassert (kt->func != NULL);
1330 (kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
1331 return 1;
1334 /* Pass a directive through to the output file.
1335 BUF points to the contents of the directive, as a contiguous string.
1336 LIMIT points to the first character past the end of the directive.
1337 KEYWORD is the keyword-table entry for the directive. */
1339 static void
1340 pass_thru_directive (const char *buf, const char *limit,
1341 cppReader *pfile,
1342 struct directive *keyword)
1344 int keyword_length = keyword->length;
1346 cpplib_reserve (pfile,
1347 size_fromInt (2 + keyword_length + (limit - buf)));
1348 cppReader_putCharQ (pfile, '#');
1349 /*@-observertrans@*/
1350 cppReader_putStrN (pfile, keyword->name, size_fromInt (keyword_length));
1351 /*:=observertrans@*/
1353 if (limit != buf && buf[0] != ' ')
1355 /* Was a bug, since reserve only used 1 + ... */
1356 cppReader_putCharQ (pfile, ' ');
1359 cppReader_putStrN (pfile, buf, size_fromInt (limit - buf));
1362 /* The arglist structure is built by create_definition to tell
1363 collect_expansion where the argument names begin. That
1364 is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
1365 would contain pointers to the strings x, y, and z.
1366 collect_expansion would then build a DEFINITION node,
1367 with reflist nodes pointing to the places x, y, and z had
1368 appeared. So the arglist is just convenience data passed
1369 between these two routines. It is not kept around after
1370 the current #define has been processed and entered into the
1371 hash table. */
1373 struct arglist {
1374 /*@null@*/ struct arglist *next;
1375 const /*@dependent@*/ char *name;
1376 size_t length;
1377 int argno;
1378 bool rest_args;
1382 /* Read a replacement list for a macro with parameters.
1383 Build the DEFINITION structure.
1384 Reads characters of text starting at BUF until LIMIT.
1385 ARGLIST specifies the formal parameters to look for
1386 in the text of the definition; NARGS is the number of args
1387 in that list, or -1 for a macro name that wants no argument list.
1388 MACRONAME is the macro name itself (so we can avoid recursive expansion)
1389 and NAMELEN is its length in characters.
1391 Note that comments, backslash-newlines, and leading white space
1392 have already been deleted from the argument. */
1394 static DEFINITION *
1395 collect_expansion (cppReader *pfile, const char *buf, const char *limit,
1396 int nargs, /*@null@*/ struct arglist *arglist)
1398 DEFINITION *defn;
1399 const char *p, *lastp;
1400 char *exp_p;
1401 struct reflist *endpat = NULL;
1402 /* Pointer to first nonspace after last ## seen. */
1403 const char *concat = NULL;
1404 /* Pointer to first nonspace after last single-# seen. */
1405 const char *stringify = NULL;
1406 size_t maxsize;
1407 char expected_delimiter = '\0';
1409 llassert (buf <= limit);
1411 /* Scan thru the replacement list, ignoring comments and quoted
1412 strings, picking up on the macro calls. It does a linear search
1413 thru the arg list on every potential symbol. Profiling might say
1414 that something smarter should happen. */
1416 /* Find the beginning of the trailing whitespace. */
1417 while (buf < limit && is_space[(int) limit[-1]])
1419 limit--;
1422 /* Allocate space for the text in the macro definition.
1423 Leading and trailing whitespace chars need 2 bytes each.
1424 Each other input char may or may not need 1 byte,
1425 so this is an upper bound. The extra 5 are for invented
1426 leading and trailing newline-marker and final null. */
1427 maxsize = (sizeof (*defn) + (limit - buf) + 5);
1429 /* Occurrences of '@' get doubled, so allocate extra space for them. */
1430 p = buf;
1431 while (p < limit)
1433 if (*p++ == '@')
1435 maxsize++;
1439 defn = (DEFINITION *) dmalloc (maxsize);
1440 defn->expand = TRUE;
1441 defn->file = NULL;
1442 defn->pattern = NULL;
1443 defn->nargs = nargs;
1444 defn->predefined = NULL;
1446 exp_p = defn->expansion = (char *) defn + sizeof (*defn);
1447 *defn->expansion = '\0'; /* convince splint it is initialized */
1449 defn->line = 0;
1450 defn->rest_args = FALSE;
1451 defn->args.argnames = NULL;
1453 lastp = exp_p;
1455 /* Add one initial space escape-marker to prevent accidental
1456 token-pasting (often removed by cpplib_macroExpand). */
1457 *exp_p++ = '@';
1458 *exp_p++ = ' ';
1460 p = buf;
1461 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
1462 cppReader_errorLit (pfile,
1463 cstring_makeLiteralTemp ("`##' at start of macro definition"));
1464 p += 2;
1467 /* Process the main body of the definition. */
1468 while (p < limit) {
1469 char c = *p++;
1471 *exp_p++ = c;
1473 if (!cppReader_isTraditional (pfile)) {
1474 switch (c) {
1475 case '\'':
1476 case '\"':
1477 if (expected_delimiter != '\0')
1479 if (c == expected_delimiter)
1480 expected_delimiter = '\0';
1482 else
1484 expected_delimiter = c;
1486 /*@switchbreak@*/ break;
1488 case '\\':
1489 if (p < limit && (expected_delimiter != '\0'))
1491 /* In a string, backslash goes through
1492 and makes next char ordinary. */
1493 *exp_p++ = *p++;
1495 /*@switchbreak@*/ break;
1497 case '@':
1498 /* An '@' in a string or character constant stands for itself,
1499 and does not need to be escaped. */
1500 if (expected_delimiter == '\0')
1502 *exp_p++ = c;
1505 /*@switchbreak@*/ break;
1507 case '#':
1508 /* # is ordinary inside a string. */
1509 if (expected_delimiter != '\0')
1511 /*@switchbreak@*/ break;
1514 if (p < limit && *p == '#') {
1515 /* ##: concatenate preceding and following tokens. */
1516 /* Take out the first #, discard preceding whitespace. */
1517 exp_p--;
1519 /*@-usedef@*/
1520 while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
1522 --exp_p;
1524 /*@=usedef@*/
1526 /* Skip the second #. */
1527 p++;
1528 /* Discard following whitespace. */
1529 SKIP_WHITE_SPACE (p);
1530 concat = p;
1531 if (p == limit)
1533 cppReader_errorLit (pfile,
1534 cstring_makeLiteralTemp ("`##' at end of macro definition"));
1536 } else if (nargs >= 0) {
1537 /* Single #: stringify following argument ref.
1538 Don't leave the # in the expansion. */
1539 exp_p--;
1540 SKIP_WHITE_SPACE (p);
1541 if (p >= limit || !identifier_seems_valid (p))
1542 cppReader_errorLit (pfile,
1543 cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));
1544 else
1545 stringify = p;
1546 } else {
1547 ; /* BADBRANCH; */
1550 /*@switchbreak@*/ break;
1552 } else {
1553 /* In -traditional mode, recognize arguments inside strings and
1554 and character constants, and ignore special properties of #.
1555 Arguments inside strings are considered "stringified", but no
1556 extra quote marks are supplied. */
1557 switch (c) {
1558 case '\'':
1559 case '\"':
1560 if (expected_delimiter != '\0') {
1561 if (c == expected_delimiter)
1562 expected_delimiter = '\0';
1563 } else
1564 expected_delimiter = c;
1565 /*@switchbreak@*/ break;
1567 case '\\':
1568 /* Backslash quotes delimiters and itself, but not macro args. */
1569 if (expected_delimiter != '\0' && p < limit
1570 && (*p == expected_delimiter || *p == '\\')) {
1571 *exp_p++ = *p++;
1572 continue;
1574 /*@switchbreak@*/ break;
1576 case '/':
1577 if (expected_delimiter != '\0') /* No comments inside strings. */
1578 /*@switchbreak@*/ break;
1579 if (*p == '*') {
1580 /* If we find a comment that wasn't removed by cppReader_handleDirective,
1581 this must be -traditional. So replace the comment with
1582 nothing at all. */
1583 exp_p--;
1584 p += 1;
1585 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
1587 p++;
1590 /*@switchbreak@*/ break;
1594 /* Handle the start of a symbol. */
1595 if (is_idchar[(int) c] && nargs > 0) {
1596 const char *id_beg = p - 1;
1597 size_t id_len;
1598 bool skipped_arg = FALSE;
1600 --exp_p;
1601 while (p != limit && is_idchar[(int) *p])
1603 p++;
1606 id_len = size_fromInt (p - id_beg);
1608 if (id_len == 0 || identifier_seems_valid (id_beg)) {
1609 struct arglist *arg;
1611 for (arg = arglist; arg != NULL; arg = arg->next) {
1612 struct reflist *tpat;
1614 if (arg->name[0] == c
1615 && arg->length == id_len
1616 && strncmp (arg->name, id_beg, id_len) == 0) {
1617 if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
1618 if (cppReader_isTraditional (pfile)) {
1619 cppReader_warning (pfile,
1620 message ("macro argument `%x' is stringified.",
1621 cstring_prefix (cstring_fromChars (arg->name), id_len)));
1622 } else {
1623 cppReader_warning (pfile,
1624 message ("macro arg `%x' would be stringified with -traditional.",
1625 cstring_prefix (cstring_fromChars (arg->name), id_len)));
1628 /* If ANSI, don't actually substitute inside a string. */
1629 if (!cppReader_isTraditional (pfile) && expected_delimiter)
1630 /*@innerbreak@*/ break;
1631 /* make a pat node for this arg and append it to the end of
1632 the pat list */
1633 tpat = (struct reflist *) dmalloc (sizeof (*tpat));
1634 tpat->next = NULL;
1635 tpat->raw_before = (concat == id_beg);
1636 tpat->raw_after = FALSE;
1637 tpat->rest_args = arg->rest_args;
1638 tpat->stringify = (cppReader_isTraditional (pfile)
1639 ? expected_delimiter != '\0'
1640 : stringify == id_beg);
1642 if (endpat == NULL)
1644 defn->pattern = tpat;
1646 else
1648 endpat->next = tpat;
1649 /*@-branchstate@*/
1650 } /*@=branchstate@*/ /* evs 2000 was =branchstate */
1652 endpat = tpat;
1654 tpat->argno = arg->argno;
1655 tpat->nchars = exp_p - lastp;
1658 const char *p1 = p;
1660 SKIP_WHITE_SPACE (p1);
1662 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
1664 tpat->raw_after = TRUE;
1668 lastp = exp_p; /* place to start copying from next time */
1669 skipped_arg = TRUE;
1671 /*@innerbreak@*/ break;
1676 /* If this was not a macro arg, copy it into the expansion. */
1677 if (!skipped_arg) {
1678 const char *lim1 = p;
1679 p = id_beg;
1681 while (p != lim1)
1683 *exp_p++ = *p++;
1686 if (stringify == id_beg)
1687 cppReader_errorLit (pfile,
1688 cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name"));
1693 if (!cppReader_isTraditional (pfile) && expected_delimiter == '\0')
1695 /* If ANSI, put in a "@ " marker to prevent token pasting.
1696 But not if "inside a string" (which in ANSI mode
1697 happens only for -D option). */
1698 *exp_p++ = '@';
1699 *exp_p++ = ' ';
1702 *exp_p = '\0';
1704 defn->length = size_fromInt (exp_p - defn->expansion);
1706 /* Crash now if we overrun the allocated size. */
1707 if (defn->length + 1 > maxsize)
1709 llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
1712 return defn; /* Spurious warning here */
1715 # if 0 /* FIXME */
1717 ** evans 2001-12-31
1718 ** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
1721 static DEFINITION *
1722 collect_expansionLoc (fileloc loc, const char *buf, const char *limit,
1723 int nargs, /*@null@*/ struct arglist *arglist)
1725 DEFINITION *defn;
1726 const char *p, *lastp;
1727 char *exp_p;
1728 struct reflist *endpat = NULL;
1729 /* Pointer to first nonspace after last ## seen. */
1730 const char *concat = NULL;
1731 /* Pointer to first nonspace after last single-# seen. */
1732 const char *stringify = NULL;
1733 size_t maxsize;
1734 char expected_delimiter = '\0';
1736 llassert (buf <= limit);
1738 /* Scan thru the replacement list, ignoring comments and quoted
1739 strings, picking up on the macro calls. It does a linear search
1740 thru the arg list on every potential symbol. Profiling might say
1741 that something smarter should happen. */
1743 /* Find the beginning of the trailing whitespace. */
1744 while (buf < limit && is_space[(int) limit[-1]])
1746 limit--;
1749 /* Allocate space for the text in the macro definition.
1750 Leading and trailing whitespace chars need 2 bytes each.
1751 Each other input char may or may not need 1 byte,
1752 so this is an upper bound. The extra 5 are for invented
1753 leading and trailing newline-marker and final null. */
1754 maxsize = (sizeof (*defn) + (limit - buf) + 5);
1756 /* Occurrences of '@' get doubled, so allocate extra space for them. */
1757 p = buf;
1758 while (p < limit)
1760 if (*p++ == '@')
1762 maxsize++;
1766 defn = (DEFINITION *) dmalloc (maxsize);
1767 defn->expand = TRUE;
1768 defn->file = NULL;
1769 defn->pattern = NULL;
1770 defn->nargs = nargs;
1771 defn->predefined = NULL;
1772 exp_p = defn->expansion = (char *) defn + sizeof (*defn);
1774 defn->line = 0;
1775 defn->rest_args = FALSE;
1776 defn->args.argnames = NULL;
1778 lastp = exp_p;
1780 /* Add one initial space escape-marker to prevent accidental
1781 token-pasting (often removed by cpplib_macroExpand). */
1782 *exp_p++ = '@';
1783 *exp_p++ = ' ';
1785 p = buf;
1786 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
1787 voptgenerror (FLG_PREPROC,
1788 cstring_makeLiteral ("Paste marker ## at start of macro definition"),
1789 loc);
1790 p += 2;
1793 /* Process the main body of the definition. */
1794 while (p < limit) {
1795 char c = *p++;
1797 *exp_p++ = c;
1799 if (/* !cppReader_isTraditional (pfile) */ TRUE) {
1800 switch (c) {
1801 case '\'':
1802 case '\"':
1803 if (expected_delimiter != '\0')
1805 if (c == expected_delimiter)
1806 expected_delimiter = '\0';
1808 else
1810 expected_delimiter = c;
1812 /*@switchbreak@*/ break;
1814 case '\\':
1815 if (p < limit && (expected_delimiter != '\0'))
1817 /* In a string, backslash goes through
1818 and makes next char ordinary. */
1819 *exp_p++ = *p++;
1821 /*@switchbreak@*/ break;
1823 case '@':
1824 /* An '@' in a string or character constant stands for itself,
1825 and does not need to be escaped. */
1826 if (expected_delimiter == '\0')
1828 *exp_p++ = c;
1831 /*@switchbreak@*/ break;
1833 case '#':
1834 /* # is ordinary inside a string. */
1835 if (expected_delimiter != '\0')
1837 /*@switchbreak@*/ break;
1840 if (p < limit && *p == '#') {
1841 /* ##: concatenate preceding and following tokens. */
1842 /* Take out the first #, discard preceding whitespace. */
1843 exp_p--;
1845 /*@-usedef@*/
1846 while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
1848 --exp_p;
1850 /*@=usedef@*/
1852 /* Skip the second #. */
1853 p++;
1854 /* Discard following whitespace. */
1855 SKIP_WHITE_SPACE (p);
1856 concat = p;
1857 if (p == limit)
1859 voptgenerror (FLG_PREPROC,
1860 cstring_makeLiteral ("`##' at end of macro definition"),
1861 loc);
1863 } else if (nargs >= 0) {
1864 /* Single #: stringify following argument ref.
1865 Don't leave the # in the expansion. */
1866 exp_p--;
1867 SKIP_WHITE_SPACE (p);
1868 if (p >= limit || !identifier_seems_valid (p))
1870 voptgenerror
1871 (FLG_PREPROC,
1872 cstring_makeLiteral ("`#' operator is not followed by a macro argument name"),
1873 loc);
1875 else
1876 stringify = p;
1877 } else {
1878 ; /* BADBRANCH; */
1881 /*@switchbreak@*/ break;
1883 } else {
1884 /* In -traditional mode, recognize arguments inside strings and
1885 and character constants, and ignore special properties of #.
1886 Arguments inside strings are considered "stringified", but no
1887 extra quote marks are supplied. */
1888 switch (c) {
1889 case '\'':
1890 case '\"':
1891 if (expected_delimiter != '\0') {
1892 if (c == expected_delimiter)
1893 expected_delimiter = '\0';
1894 } else
1895 expected_delimiter = c;
1896 /*@switchbreak@*/ break;
1898 case '\\':
1899 /* Backslash quotes delimiters and itself, but not macro args. */
1900 if (expected_delimiter != '\0' && p < limit
1901 && (*p == expected_delimiter || *p == '\\')) {
1902 *exp_p++ = *p++;
1903 continue;
1905 /*@switchbreak@*/ break;
1907 case '/':
1908 if (expected_delimiter != '\0') /* No comments inside strings. */
1909 /*@switchbreak@*/ break;
1910 if (*p == '*') {
1911 /* If we find a comment that wasn't removed by cppReader_handleDirective,
1912 this must be -traditional. So replace the comment with
1913 nothing at all. */
1914 exp_p--;
1915 p += 1;
1916 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
1918 p++;
1921 /*@switchbreak@*/ break;
1925 /* Handle the start of a symbol. */
1926 if (is_idchar[(int) c] && nargs > 0) {
1927 const char *id_beg = p - 1;
1928 size_t id_len;
1929 bool skipped_arg = FALSE;
1931 --exp_p;
1932 while (p != limit && is_idchar[(int) *p])
1934 p++;
1937 id_len = size_fromInt (p - id_beg);
1939 if (id_len == 0 || identifier_seems_valid (id_beg)) {
1940 struct arglist *arg;
1942 for (arg = arglist; arg != NULL; arg = arg->next) {
1943 struct reflist *tpat;
1945 if (arg->name[0] == c
1946 && arg->length == id_len
1947 && strncmp (arg->name, id_beg, id_len) == 0) {
1948 if (expected_delimiter /* && CPPOPTIONS (pfile)->warn_stringify */) {
1949 if (/* cppReader_isTraditional (pfile) */ FALSE) {
1950 voptgenerror (FLG_PREPROC,
1951 message ("macro argument `%x' is stringified.",
1952 cstring_prefix (cstring_fromChars (arg->name), id_len)),
1953 loc);
1955 } else {
1956 voptgenerror (FLG_PREPROC,
1957 message ("Macro arg `%x' would be stringified with -traditional.",
1958 cstring_prefix (cstring_fromChars (arg->name), id_len)),
1959 loc);
1963 /* If ANSI, don't actually substitute inside a string. */
1964 if (/* !cppReader_isTraditional (pfile) && */ expected_delimiter)
1965 /*@innerbreak@*/ break;
1966 /* make a pat node for this arg and append it to the end of
1967 the pat list */
1968 tpat = (struct reflist *) dmalloc (sizeof (*tpat));
1969 tpat->next = NULL;
1970 tpat->raw_before = (concat == id_beg);
1971 tpat->raw_after = FALSE;
1972 tpat->rest_args = arg->rest_args;
1973 tpat->stringify = (FALSE /* cppReader_isTraditional (pfile) */
1974 ? expected_delimiter != '\0'
1975 : stringify == id_beg);
1977 if (endpat == NULL)
1979 defn->pattern = tpat;
1981 else
1983 endpat->next = tpat;
1984 /*@-branchstate@*/
1985 } /*@=branchstate@*/ /* evs 2000 was =branchstate */
1987 endpat = tpat;
1989 tpat->argno = arg->argno;
1990 tpat->nchars = exp_p - lastp;
1993 const char *p1 = p;
1995 SKIP_WHITE_SPACE (p1);
1997 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
1999 tpat->raw_after = TRUE;
2003 lastp = exp_p; /* place to start copying from next time */
2004 skipped_arg = TRUE;
2006 /*@innerbreak@*/ break;
2011 /* If this was not a macro arg, copy it into the expansion. */
2012 if (!skipped_arg) {
2013 const char *lim1 = p;
2014 p = id_beg;
2016 while (p != lim1)
2018 *exp_p++ = *p++;
2021 if (stringify == id_beg)
2023 voptgenerror
2024 (FLG_PREPROC,
2025 cstring_makeLiteral ("# operator should be followed by a macro argument name"),
2026 loc);
2032 if (/*!cppReader_isTraditional (pfile) && */ expected_delimiter == '\0')
2034 /* If ANSI, put in a "@ " marker to prevent token pasting.
2035 But not if "inside a string" (which in ANSI mode
2036 happens only for -D option). */
2037 *exp_p++ = '@';
2038 *exp_p++ = ' ';
2041 *exp_p = '\0';
2043 defn->length = size_fromInt (exp_p - defn->expansion);
2045 /* Crash now if we overrun the allocated size. */
2046 if (defn->length + 1 > maxsize)
2048 llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
2051 /*@-compdef@*/ /* defn->expansion defined? */
2052 return defn;
2053 /*@=compdef@*/
2055 # endif
2058 * special extension string that can be added to the last macro argument to
2059 * allow it to absorb the "rest" of the arguments when expanded. Ex:
2060 * #define wow(a, b...) process (b, a, b)
2061 * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
2062 * { wow (one, two); } -> { process (two, one, two); }
2063 * if this "rest_arg" is used with the concat token '##' and if it is not
2064 * supplied then the token attached to with ## will not be outputted. Ex:
2065 * #define wow (a, b...) process (b ## , a, ## b)
2066 * { wow (1, 2); } -> { process (2, 1, 2); }
2067 * { wow (one); } -> { process (one); {
2070 /*@-readonlytrans@*/
2071 static const char rest_extension[] = "...";
2072 /*:=readonlytrans@*/
2074 /*@notfunction@*/
2075 #define REST_EXTENSION_LENGTH (constlen (rest_extension))
2077 /*@-readonlytrans@*/
2078 static const char rest_name[] = "__VA_ARGS__";
2079 /*:=readonlytrans@*/
2081 /*@notfunction@*/
2082 #define REST_NAME_LENGTH (constlen (rest_name))
2084 /* Create a DEFINITION node from a #define directive. Arguments are
2085 as for do_define. */
2087 static /*@null@*/ macroDef
2088 create_definition (/*@exposed@*/ const char *buf, const char *limit,
2089 cppReader *pfile, bool predefinition,
2090 bool expand)
2092 const char *bp; /* temp ptr into input buffer */
2093 const char *symname; /* remember where symbol name starts */
2094 size_t sym_length; /* and how long it is */
2095 int line;
2096 cstring file = (CPPBUFFER (pfile) != NULL)
2097 ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
2098 DEFINITION *defn;
2099 macroDef mdef;
2100 struct arglist *arg_ptrs = NULL;
2102 cppBuffer_getLineAndColumn (CPPBUFFER (pfile), &line, NULL);
2104 bp = buf;
2106 SKIP_WHITE_SPACE (bp);
2108 symname = bp; /* remember where it starts */
2110 sym_length = identifier_length (symname);
2111 if (!macro_name_is_valid (symname, sym_length))
2113 cppReader_error (pfile, invalid_macro_message (symname, sym_length));
2114 goto nope;
2117 bp += sym_length;
2119 /* Lossage will occur if identifiers or control keywords are broken
2120 across lines using backslash. This is not the right place to take
2121 care of that. */
2123 if (*bp == '(') {
2124 size_t arglengths = 0; /* Accumulate lengths of arg names
2125 plus number of args. */
2126 int argno = 0;
2127 bool rest_args = FALSE;
2129 bp++; /* skip '(' */
2130 SKIP_WHITE_SPACE (bp);
2132 /* Loop over macro argument names. */
2133 while (*bp != ')')
2135 struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
2136 temp->name = bp;
2137 temp->next = arg_ptrs;
2138 temp->argno = argno++;
2140 arg_ptrs = temp;
2142 if (rest_args)
2144 cppReader_pedwarn (pfile,
2145 message ("another parameter follows `%s'",
2146 cstring_fromChars (rest_extension)));
2149 temp->length = identifier_length (bp);
2150 bp += temp->length;
2152 if (temp->length == REST_NAME_LENGTH &&
2153 strncmp(temp->name, rest_name, REST_NAME_LENGTH) == 0)
2155 cppReader_warning (pfile,
2156 message ("ISO C99 forbids the use of %s as a macro parameter name",
2157 cstring_fromChars (rest_name)));
2160 /* do we have a "special" rest-args extension here? */
2161 if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
2162 && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
2164 rest_args = TRUE;
2165 temp->rest_args = TRUE;
2166 if (temp->length == 0) /* ellipsis without identifier */
2168 temp->name = rest_name;
2169 temp->length = REST_NAME_LENGTH;
2171 else
2173 if (!context_getFlag (FLG_GNUEXTENSIONS))
2175 genppllerrorhint (FLG_PREPROC,
2176 cstring_makeLiteral ("Macros with named variadic parameters list are not supported by ISO C99"),
2177 cstring_makeLiteral ("Use +gnuextensions to allow macros with named variadic parameters list"
2178 "(and other GNU language extensions) without this warning"));
2181 bp += REST_EXTENSION_LENGTH;
2183 else
2185 temp->rest_args = FALSE;
2188 if (temp->length == 0) /* not (valid name or ellipsis) */
2190 cppReader_errorLit (pfile,
2191 cstring_makeLiteralTemp ("Invalid character in macro parameter name"));
2192 goto nope;
2195 SKIP_WHITE_SPACE (bp);
2197 if (*bp != ',' && *bp != ')') {
2198 cppReader_errorLit (pfile,
2199 cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
2200 goto nope;
2203 if (*bp == ',') {
2204 bp++;
2205 SKIP_WHITE_SPACE (bp);
2206 if (*bp == ')') {
2207 cppReader_errorLit (pfile,
2208 cstring_makeLiteralTemp ("Missing parameter name in #define"));
2209 goto nope;
2213 struct arglist *otemp;
2215 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
2217 if (temp->length == otemp->length &&
2218 strncmp (temp->name, otemp->name, temp->length) == 0) {
2219 cstring name = cstring_copyLength (temp->name, temp->length);
2220 cppReader_error (pfile,
2221 message ("duplicate argument name `%x' in `#define'", name));
2222 goto nope;
2226 arglengths += temp->length + 2;
2229 ++bp; /* skip paren */
2230 SKIP_WHITE_SPACE (bp);
2232 if (bp > limit)
2234 cppReader_errorLit (pfile,
2235 cstring_makeLiteralTemp ("Unterminated parameter list in #define"));
2236 goto nope;
2239 /* now everything from bp before limit is the definition. */
2240 defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
2241 defn->rest_args = rest_args;
2243 /* Now set defn->args.argnames to the result of concatenating
2244 the argument names in reverse order
2245 with comma-space between them. */
2246 defn->args.argnames = (char *) dmalloc (arglengths + 1);
2249 struct arglist *temp;
2250 size_t i = 0;
2251 for (temp = arg_ptrs; temp != NULL; temp = temp->next)
2253 memcpy (&defn->args.argnames[i], temp->name, temp->length);
2254 i += temp->length;
2255 if (temp->next != 0)
2257 defn->args.argnames[i++] = ',';
2258 defn->args.argnames[i++] = ' ';
2262 defn->args.argnames[i] = '\0';
2264 } else { /* Simple expansion or empty definition. */
2265 if (bp < limit)
2267 if (is_hor_space[(int) *bp]) {
2268 bp++;
2269 SKIP_WHITE_SPACE (bp);
2270 } else {
2271 switch (*bp) {
2272 case '!': case '\"': case '#': case '%': case '&': case '\'':
2273 case ')': case '*': case '+': case ',': case '-': case '.':
2274 case '/': case ':': case ';': case '<': case '=': case '>':
2275 case '?': case '[': case '\\': case ']': case '^': case '{':
2276 case '|': case '}': case '~':
2277 cppReader_warning (pfile,
2278 message ("Missing white space after #define %x",
2279 cstring_prefix (cstring_fromChars (symname),
2280 sym_length)));
2281 break;
2283 default:
2284 cppReader_pedwarn (pfile,
2285 message ("Missing white space after #define %x",
2286 cstring_prefix (cstring_fromChars (symname),
2287 sym_length)));
2288 break;
2293 if (bp > limit)
2295 cppReader_errorLit (pfile,
2296 cstring_makeLiteralTemp ("Failed to process #define"));
2297 goto nope;
2300 /* now everything from bp before limit is the definition. */
2301 defn = collect_expansion (pfile, bp, limit, -1, NULL);
2302 defn->args.argnames = mstring_createEmpty ();
2305 defn->expand = expand;
2306 DPRINTF (("Expand: %d", expand));
2308 defn->line = line;
2310 /* not: llassert (cstring_isUndefined (defn->file)); */
2311 defn->file = file;
2313 /* OP is null if this is a predefinition */
2314 defn->predefined = predefinition;
2315 mdef.defn = defn;
2316 mdef.symnam = symname;
2317 mdef.symlen = sym_length;
2319 goto leave;
2321 nope:
2322 mdef.defn = NULL;
2323 mdef.symnam = NULL;
2325 leave:
2326 while (arg_ptrs != NULL)
2328 struct arglist *temp = arg_ptrs->next;
2329 sfree (arg_ptrs);
2330 arg_ptrs = temp;
2332 return mdef;
2335 # if 0
2336 /*@null@*/ macroDef
2337 cpplib_createDefinition (cstring def,
2338 fileloc loc,
2339 bool predefinition,
2340 bool expand)
2342 const char *buf = cstring_toCharsSafe (def);
2343 const char *limit = buf + cstring_length (def);
2344 const char *bp; /* temp ptr into input buffer */
2345 const char *symname; /* remember where symbol name starts */
2346 size_t sym_length; /* and how long it is */
2347 int line = fileloc_lineno (loc);
2348 cstring file = fileloc_filename (loc);
2349 DEFINITION *defn;
2350 macroDef mdef;
2351 struct arglist *arg_ptrs = NULL;
2353 DPRINTF (("Creating definition: %s", buf));
2355 bp = buf;
2357 SKIP_WHITE_SPACE (bp);
2359 symname = bp; /* remember where it starts */
2361 sym_length = identifier_length (symname);
2362 if (!macro_name_is_valid (symname, sym_length))
2364 voptgenerror (FLG_PREPROC,
2365 invalid_macro_message (symname, sym_length), loc);
2366 goto nope;
2369 DPRINTF (("length: %d", sym_length));
2371 bp += sym_length;
2373 DPRINTF (("Here: %s", bp));
2375 /* Lossage will occur if identifiers or control keywords are broken
2376 across lines using backslash. This is not the right place to take
2377 care of that. */
2379 if (*bp == '(') {
2380 size_t arglengths = 0; /* Accumulate lengths of arg names
2381 plus number of args. */
2382 int argno = 0;
2383 bool rest_args = FALSE;
2385 bp++; /* skip '(' */
2386 SKIP_WHITE_SPACE (bp);
2388 /* Loop over macro argument names. */
2389 while (*bp != ')')
2391 struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
2392 temp->name = bp;
2393 temp->next = arg_ptrs;
2394 temp->argno = argno++;
2396 arg_ptrs = temp;
2398 if (rest_args)
2400 voptgenerror (FLG_PREPROC,
2401 message ("Another parameter follows %s",
2402 cstring_fromChars (rest_extension)),
2403 loc);
2406 temp->length = identifier_length (bp);
2407 bp += temp->length;
2409 if (temp->length == REST_NAME_LENGTH &&
2410 strncmp(temp->name, rest_name, REST_NAME_LENGTH) == 0)
2412 voptgenerror (FLG_PREPROC,
2413 message ("ISO C99 forbids the use of %s as a macro parameter name",
2414 cstring_fromChars (rest_name)),
2415 loc);
2418 /* do we have a "special" rest-args extension here? */
2419 if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
2420 && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
2422 rest_args = TRUE;
2423 temp->rest_args = TRUE;
2424 if (temp->length == 0) /* ellipsis without identifier */
2426 temp->name = rest_name;
2427 temp->length = REST_NAME_LENGTH;
2429 else
2431 if (!context_flagOn (FLG_GNUEXTENSIONS, loc))
2433 llgenhinterror (FLG_PREPROC,
2434 cstring_makeLiteral ("Macros with named variadic parameters list are not supported by ISO C99"),
2435 cstring_makeLiteral ("Use +gnuextensions to allow macros with named variadic parameters list "
2436 "(and other GNU language extensions) without this warning"),
2437 loc);
2440 bp += REST_EXTENSION_LENGTH;
2442 else
2444 temp->rest_args = FALSE;
2447 if (temp->length == 0) /* not (valid name or ellipsis) */
2449 voptgenerror (FLG_PREPROC,
2450 message ("Invalid character in macro parameter name: %c", *bp),
2451 loc);
2452 goto nope;
2455 SKIP_WHITE_SPACE (bp);
2457 if (*bp != ',' && *bp != ')') {
2458 voptgenerror (FLG_PREPROC,
2459 cstring_makeLiteral ("Parameter list for #define is not parseable"),
2460 loc);
2461 goto nope;
2464 if (*bp == ',') {
2465 bp++;
2466 SKIP_WHITE_SPACE (bp);
2467 if (*bp == ')') {
2468 voptgenerror (FLG_PREPROC,
2469 cstring_makeLiteral ("Missing parameter name in #define"),
2470 loc);
2471 goto nope;
2475 struct arglist *otemp;
2477 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
2479 if (temp->length == otemp->length &&
2480 strncmp (temp->name, otemp->name, temp->length) == 0) {
2481 cstring name = cstring_copyLength (temp->name, temp->length);
2483 voptgenerror (FLG_PREPROC,
2484 message ("Duplicate argument name in #define: %s", name),
2485 loc);
2486 goto nope;
2490 arglengths += temp->length + 2;
2493 ++bp; /* skip paren */
2494 SKIP_WHITE_SPACE (bp);
2496 if (bp > limit)
2498 voptgenerror (FLG_PREPROC,
2499 cstring_makeLiteral ("Unterminated parameter list in #define"),
2500 loc);
2501 goto nope;
2504 /* now everything from bp before limit is the definition. */
2505 defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs);
2506 defn->rest_args = rest_args;
2508 /* Now set defn->args.argnames to the result of concatenating
2509 the argument names in reverse order
2510 with comma-space between them. */
2511 defn->args.argnames = (char *) dmalloc (arglengths + 1);
2514 struct arglist *temp;
2515 size_t i = 0;
2516 for (temp = arg_ptrs; temp != NULL; temp = temp->next)
2518 memcpy (&defn->args.argnames[i], temp->name, temp->length);
2519 i += temp->length;
2520 if (temp->next != 0)
2522 defn->args.argnames[i++] = ',';
2523 defn->args.argnames[i++] = ' ';
2527 defn->args.argnames[i] = '\0';
2529 } else { /* Simple expansion or empty definition. */
2530 if (bp < limit)
2532 if (is_hor_space[(int) *bp]) {
2533 bp++;
2534 SKIP_WHITE_SPACE (bp);
2535 } else {
2536 switch (*bp) {
2537 case '!': case '\"': case '#': case '%': case '&': case '\'':
2538 case ')': case '*': case '+': case ',': case '-': case '.':
2539 case '/': case ':': case ';': case '<': case '=': case '>':
2540 case '?': case '[': case '\\': case ']': case '^': case '{':
2541 case '|': case '}': case '~':
2542 voptgenerror (FLG_PREPROC,
2543 message ("Missing white space after #define %x",
2544 cstring_prefix (cstring_fromChars (symname),
2545 sym_length)),
2546 loc);
2547 break;
2549 default:
2550 voptgenerror (FLG_PREPROC,
2551 message ("Missing white space after #define %x",
2552 cstring_prefix (cstring_fromChars (symname),
2553 sym_length)),
2554 loc);
2555 break;
2560 if (bp > limit)
2562 voptgenerror (FLG_PREPROC,
2563 cstring_makeLiteral ("Failed to process #define"),
2564 loc);
2565 goto nope;
2568 /* now everything from bp before limit is the definition. */
2569 defn = collect_expansionLoc (loc, bp, limit, -1, NULL);
2570 defn->args.argnames = mstring_createEmpty ();
2573 defn->expand = expand;
2574 DPRINTF (("Expand: %d", expand));
2576 defn->line = line;
2578 /* not: llassert (cstring_isUndefined (defn->file)); */
2579 defn->file = file;
2581 /* OP is null if this is a predefinition */
2582 defn->predefined = predefinition;
2584 mdef.defn = defn;
2585 mdef.symnam = symname;
2586 mdef.symlen = sym_length;
2588 goto leave;
2590 nope:
2591 mdef.defn = NULL;
2592 mdef.symnam = NULL;
2594 leave:
2595 while (arg_ptrs != NULL)
2597 struct arglist *temp = arg_ptrs->next;
2598 sfree (arg_ptrs);
2599 arg_ptrs = temp;
2601 return mdef;
2603 # endif
2605 /* Yield the length of a purported macro name SYMNAME. */
2607 static size_t
2608 identifier_length (const char *symname)
2610 const char *p = symname;
2611 if (!is_idstart[(int) *symname])
2612 return 0;
2613 ++p;
2614 SKIP_IDENTIFIER (p);
2615 return size_fromInt (p - symname);
2618 /* Check a purported identifier name SYMNAME. */
2620 static bool
2621 identifier_seems_valid (const char *symname)
2623 if (!is_idstart[(int) *symname])
2624 return FALSE;
2625 if (symname[0] == 'L' && (symname[1] == '\'' || symname[1] == '\"'))
2626 return FALSE;
2628 return TRUE;
2631 /* Check a purported macro name SYMNAME. */
2633 static bool
2634 macro_name_is_valid (const char *symname, size_t symlen)
2636 if (symlen == 0)
2637 return FALSE;
2638 if (!identifier_seems_valid (symname))
2639 return FALSE;
2640 if (symlen == 7 && strncmp (symname, "defined", 7) == 0)
2641 return FALSE;
2642 if (symlen == REST_NAME_LENGTH && strncmp (symname, rest_name, REST_NAME_LENGTH) == 0)
2643 return FALSE;
2645 return TRUE;
2648 static /*@only@*/ cstring
2649 invalid_macro_message (const char *symname, size_t symlen)
2651 return (symname == 0) ?
2652 cstring_makeLiteral ("invalid macro name") :
2653 message ("invalid macro name `%q'", cstring_copyLength (symname, symlen));
2656 /* Return zero if two DEFINITIONs are isomorphic. */
2658 static bool
2659 compare_defs (DEFINITION *d1, DEFINITION *d2)
2661 struct reflist *a1, *a2;
2662 char *p1 = d1->expansion;
2663 char *p2 = d2->expansion;
2664 bool first = TRUE;
2666 if (d1->nargs != d2->nargs)
2668 return TRUE;
2671 llassert (d1->args.argnames != NULL);
2672 llassert (d2->args.argnames != NULL);
2674 if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames) != 0)
2676 return TRUE;
2679 for (a1 = d1->pattern, a2 = d2->pattern;
2680 (a1 != NULL) && (a2 != NULL);
2681 a1 = a1->next, a2 = a2->next) {
2682 if (!((a1->nchars == a2->nchars
2683 && (strncmp (p1, p2, size_fromInt (a1->nchars)) == 0))
2684 || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
2685 || a1->argno != a2->argno
2686 || a1->stringify != a2->stringify
2687 || a1->raw_before != a2->raw_before
2688 || a1->raw_after != a2->raw_after)
2689 return TRUE;
2690 first = 0;
2691 p1 += a1->nchars;
2692 p2 += a2->nchars;
2694 if (a1 != a2)
2695 return TRUE;
2697 if (comp_def_part (first, p1, size_toInt (d1->length - (p1 - d1->expansion)),
2698 p2, size_toInt (d2->length - (p2 - d2->expansion)), 1))
2699 return TRUE;
2701 return FALSE;
2705 ** Return TRUE if two parts of two macro definitions are effectively different.
2706 ** One of the parts starts at BEG1 and has LEN1 chars;
2707 ** the other has LEN2 chars at BEG2.
2708 ** Any sequence of whitespace matches any other sequence of whitespace.
2709 ** FIRST means these parts are the first of a macro definition;
2710 ** so ignore leading whitespace entirely.
2711 ** LAST means these parts are the last of a macro definition;
2712 ** so ignore trailing whitespace entirely.
2715 static bool
2716 comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
2718 char *end1 = beg1 + len1;
2719 char *end2 = beg2 + len2;
2721 if (first) {
2722 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
2723 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
2725 if (last) {
2726 while (beg1 != end1 && is_space[(int) end1[-1]]) { end1--; }
2727 while (beg2 != end2 && is_space[(int) end2[-1]]) { end2--; }
2729 while (beg1 != end1 && beg2 != end2) {
2730 if (is_space[(int) *beg1] && is_space[(int) *beg2]) {
2731 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
2732 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
2733 } else if (*beg1 == *beg2) {
2734 beg1++; beg2++;
2735 } else break;
2737 return (beg1 != end1) || (beg2 != end2);
2741 ** Process a #define command.
2742 ** BUF points to the contents of the #define command, as a contiguous string.
2743 ** LIMIT points to the first character past the end of the definition.
2744 ** KEYWORD is the keyword-table entry for #define,
2745 ** or NULL for a "predefined" macro.
2748 static void
2749 do_defineAux (cppReader *pfile, struct directive *keyword,
2750 const /*@exposed@*/ char *buf, const char *limit, bool expand)
2752 int hashcode;
2753 macroDef mdef;
2754 hashNode hp;
2756 mdef = create_definition (buf, limit, pfile, keyword == NULL, expand);
2758 if (mdef.defn == NULL)
2759 return;
2761 hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
2763 if ((hp = cpphash_lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL)
2765 bool ok;
2767 /* Redefining a precompiled key is ok. */
2768 if (hp->type == T_PCSTRING)
2769 ok = TRUE;
2770 /* Redefining a macro is ok if the definitions are the same. */
2771 else if (hp->type == T_MACRO)
2772 ok = !compare_defs (mdef.defn, hp->value.defn);
2773 /* Redefining a constant is ok with -D. */
2774 else if (hp->type == T_CONST)
2775 ok = !pfile->done_initializing;
2776 else
2777 ok = FALSE; /* Redefining anything else is bad. */
2779 /* Print the warning if it's not ok. */
2780 if (!ok)
2783 ** If we are passing through #define and #undef directives, do
2784 ** that for this re-definition now.
2787 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
2789 /* llassert (keyword != NULL); */
2790 pass_thru_directive (buf, limit, pfile, keyword);
2793 cpp_setLocation (pfile);
2795 if (hp->type == T_MACRO)
2797 if (hp->value.defn->expand)
2799 genppllerrorhint
2800 (FLG_MACROREDEF,
2801 message ("Macro %q already defined",
2802 cstring_copyLength (mdef.symnam, mdef.symlen)),
2803 message ("%q: Previous definition of %q",
2804 fileloc_unparseRaw (hp->value.defn->file,
2805 (int) hp->value.defn->line),
2806 cstring_copyLength (mdef.symnam, mdef.symlen)));
2808 /* else error will be reported checking macros */
2810 else
2812 genppllerror (FLG_MACROREDEF,
2813 message ("Macro %q already defined",
2814 cstring_copyLength (mdef.symnam,
2815 mdef.symlen)));
2819 /* Replace the old definition. */
2820 hp->type = T_MACRO;
2821 hp->value.defn = mdef.defn;
2823 else
2826 ** If we are passing through #define and #undef directives, do
2827 ** that for this new definition now.
2830 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
2832 pass_thru_directive (buf, limit, pfile, keyword);
2835 DPRINTF (("Define macro: %s / %d",
2836 mdef.symnam, mdef.defn->expand));
2838 cpphash_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
2839 /*@-branchstate@*/
2840 } /*@=branchstate@*/
2843 static void
2844 do_define (cppReader *pfile, struct directive *keyword,
2845 const /*@exposed@*/ char *buf, const char *limit)
2847 DPRINTF (("Regular do define"));
2848 do_defineAux (pfile, keyword, buf, limit, TRUE);
2852 ** This structure represents one parsed argument in a macro call.
2853 ** `raw' points to the argument text as written (`raw_length' is its length).
2854 ** `expanded' points to the argument's macro-expansion
2855 ** (its length is `expand_length').
2856 ** `stringified_length' is the length the argument would have
2857 ** if stringified.
2858 ** `use_count' is the number of times this macro arg is substituted
2859 ** into the macro. If the actual use count exceeds 10,
2860 ** the value stored is 10.
2863 /* raw and expanded are relative to ARG_BASE */
2864 /*@notfunction@*/
2865 #define ARG_BASE ((pfile)->token_buffer)
2867 struct argdata {
2868 /* Strings relative to pfile->token_buffer */
2869 long raw;
2870 size_t expanded;
2871 size_t stringified;
2872 int raw_length;
2873 int expand_length;
2874 int stringified_length;
2875 bool newlines;
2876 int use_count;
2880 ** Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
2881 ** If BUFFER != NULL, then use the LENGTH characters in BUFFER
2882 ** as the new input buffer.
2883 ** Return the new buffer, or NULL on failure.
2886 /*@null@*/ /*@exposed@*/ cppBuffer *
2887 cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
2889 cppBuffer *buf = cppReader_getBufferSafe (pfile);
2891 if (buf == pfile->buffer_stack)
2893 cppReader_fatalError
2894 (pfile,
2895 message ("%s: macro or `#include' recursion too deep",
2896 (buf->fname != NULL)
2897 ? buf->fname
2898 : cstring_makeLiteral ("<no name>")));
2899 sfreeEventually (buffer);
2900 return NULL;
2903 llassert (buf != NULL);
2905 buf--;
2906 memset ((char *) buf, 0, sizeof (*buf));
2907 DPRINTF (("Pushing buffer: %s", cstring_copyLength (buffer, length)));
2908 CPPBUFFER (pfile) = buf;
2910 buf->if_stack = pfile->if_stack;
2911 buf->cleanup = cppReader_nullCleanup;
2912 buf->underflow = cppReader_nullUnderflow;
2913 buf->buf = buffer;
2914 buf->cur = buf->buf;
2916 if (buffer != NULL)
2918 buf->alimit = buf->rlimit = buffer + length;
2920 else
2922 buf->alimit = buf->rlimit = NULL;
2925 return buf;
2928 cppBuffer *
2929 cppReader_popBuffer (cppReader *pfile)
2931 cppBuffer *buf = CPPBUFFER (pfile);
2933 llassert (buf != NULL);
2935 (void) (*buf->cleanup) (buf, pfile);
2936 return ++CPPBUFFER (pfile);
2940 ** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
2941 ** Pop the buffer when done.
2944 void
2945 cppReader_scanBuffer (cppReader *pfile)
2947 cppBuffer *buffer = CPPBUFFER (pfile);
2948 for (;;)
2950 enum cpp_token token;
2952 token = cpplib_getToken (pfile);
2954 if (token == CPP_EOF) /* Should not happen ... */
2956 break;
2959 if (token == CPP_POP && CPPBUFFER (pfile) == buffer)
2961 (void) cppReader_popBuffer (pfile);
2962 break;
2968 * Rescan a string (which may have escape marks) into pfile's buffer.
2969 * Place the result in pfile->token_buffer.
2971 * The input is copied before it is scanned, so it is safe to pass
2972 * it something from the token_buffer that will get overwritten
2973 * (because it follows cpplib_getWritten). This is used by do_include.
2976 static void
2977 cpp_expand_to_buffer (cppReader *pfile, const char *buf, size_t length)
2979 cppBuffer *ip;
2980 cstring newbuf;
2982 newbuf = cstring_copyLength (buf, length);
2983 DPRINTF (("Expand to buffer: %s", newbuf));
2985 /* Set up the input on the input stack. */
2986 ip = cppReader_pushBuffer (pfile, cstring_toCharsSafe (newbuf), length);
2988 if (ip == NULL)
2989 return;
2991 ip->has_escapes = TRUE;
2993 /* Scan the input, create the output. */
2994 cppReader_scanBuffer (pfile);
2996 cppReader_nullTerminate (pfile);
2999 static void
3000 adjust_position (char *buf, char *limit, int *linep, int *colp)
3002 while (buf < limit)
3004 char ch = *buf++;
3005 if (ch == '\n')
3006 (*linep)++, (*colp) = 1;
3007 else
3008 (*colp)++;
3012 /* Move line_base forward, updating lineno and colno. */
3014 static void
3015 update_position (cppBuffer *pbuf)
3017 char *old_pos;
3018 char *new_pos = pbuf->cur;
3019 struct parse_marker *mark;
3021 llassert (pbuf->buf != NULL);
3022 old_pos = pbuf->buf + pbuf->line_base;
3024 for (mark = pbuf->marks; mark != NULL; mark = mark->next)
3026 if (pbuf->buf + mark->position < new_pos)
3027 new_pos = pbuf->buf + mark->position;
3029 pbuf->line_base += new_pos - old_pos;
3031 llassert (old_pos != NULL);
3032 llassert (new_pos != NULL);
3034 adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
3037 void
3038 cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
3039 /*@null@*/ /*@out@*/ int *colp)
3041 int dummy;
3043 if (colp == NULL)
3045 colp = &dummy;
3046 /*@-branchstate@*/
3047 } /*@=branchstate@*/
3049 if (pbuf != NULL)
3051 *linep = pbuf->lineno;
3052 *colp = pbuf->colno;
3054 llassert (pbuf->buf != NULL);
3055 llassert (pbuf->cur != NULL);
3057 adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
3059 else
3061 *linep = 0;
3062 *colp = 0;
3066 /* Return the cppBuffer that corresponds to a file (not a macro). */
3068 /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_fileBuffer (cppReader *pfile)
3070 cppBuffer *ip = cppReader_getBuffer (pfile);
3072 for ( ;
3073 ip != NULL && ip != cppReader_nullBuffer (pfile);
3074 ip = cppBuffer_prevBuffer (ip))
3076 if (ip->fname != NULL)
3078 return ip;
3082 return NULL;
3085 static long
3086 count_newlines (char *buf, char *limit)
3088 long count = 0;
3090 while (buf < limit)
3092 char ch = *buf++;
3093 if (ch == '\n')
3094 count++;
3096 return count;
3100 * write out a #line command, for instance, after an #include file.
3101 * If CONDITIONAL is true, we can omit the #line if it would
3102 * appear to be a no-op, and we can output a few newlines instead
3103 * if we want to increase the line number by a small amount.
3104 * FILE_CHANGE says whether we are entering a file, leaving, or neither.
3107 static void
3108 output_line_command (cppReader *pfile, bool conditional,
3109 enum file_change_code file_change)
3111 int line, col;
3112 cppBuffer *ip = CPPBUFFER (pfile);
3113 cppBuffer *buf;
3115 llassert (ip != NULL);
3117 if (ip->fname == NULL)
3118 return;
3120 update_position (ip);
3122 if (CPPOPTIONS (pfile)->no_line_commands
3123 || CPPOPTIONS (pfile)->no_output)
3124 return;
3126 buf = CPPBUFFER (pfile);
3128 llassert (buf != NULL);
3130 line = buf->lineno;
3131 col = buf->colno;
3133 llassert (ip->cur != NULL);
3135 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
3137 if (CPPOPTIONS (pfile)->no_line_commands)
3138 return;
3140 if (conditional) {
3141 if (line == pfile->lineno)
3142 return;
3144 /* If the inherited line number is a little too small,
3145 output some newlines instead of a #line command. */
3147 if (line > pfile->lineno && line < pfile->lineno + 8)
3149 cpplib_reserve (pfile, 20);
3150 while (line > pfile->lineno)
3152 cppReader_putCharQ (pfile, '\n');
3153 pfile->lineno++;
3156 return;
3160 cpplib_reserve (pfile, 4 * cstring_length (ip->nominal_fname) + 50);
3163 #ifdef OUTPUT_LINE_COMMANDS
3164 static const char sharp_line[] = "#line ";
3165 #else
3166 static const char sharp_line[] = "# ";
3167 #endif
3168 cppReader_putStrN (pfile, sharp_line, constlen(sharp_line));
3171 sprintf (cpplib_getPWritten (pfile), "%d ", line);
3172 cppReader_adjustWritten (pfile, strlen (cpplib_getPWritten (pfile)));
3174 quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));
3176 if (file_change != same_file) {
3177 cppReader_putCharQ (pfile, ' ');
3178 cppReader_putCharQ (pfile, file_change == enter_file ? '1' : '2');
3180 /* Tell cc1 if following text comes from a system header file. */
3181 if (ip->system_header_p) {
3182 cppReader_putCharQ (pfile, ' ');
3183 cppReader_putCharQ (pfile, '3');
3185 cppReader_putCharQ (pfile, '\n');
3186 pfile->lineno = line;
3191 * Parse a macro argument and append the info on PFILE's token_buffer.
3192 * REST_ARGS means to absorb the rest of the args.
3193 * Return nonzero to indicate a syntax error.
3196 static enum cpp_token
3197 macarg (cppReader *pfile, bool rest_args)
3199 int paren = 0;
3200 enum cpp_token token;
3201 char save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
3202 bool oldexpand = pfile->no_macro_expand;
3203 CPPOPTIONS (pfile)->put_out_comments = 1;
3205 /* Try to parse as much of the argument as exists at this
3206 input stack level. */
3208 pfile->no_macro_expand = TRUE;
3210 for (;;)
3212 token = cpplib_getToken (pfile);
3214 switch (token)
3216 case CPP_EOF:
3217 goto done;
3218 case CPP_POP:
3219 /* If we've hit end of file, it's an error (reported by caller).
3220 Ditto if it's the end of cpp_expand_to_buffer text.
3221 If we've hit end of macro, just continue. */
3222 if (!cppBuffer_isMacro (CPPBUFFER (pfile)))
3223 goto done;
3224 /*@switchbreak@*/ break;
3225 case CPP_LPAREN:
3226 paren++;
3227 /*@switchbreak@*/ break;
3228 case CPP_RPAREN:
3229 if (--paren < 0)
3230 goto found;
3231 /*@switchbreak@*/ break;
3232 case CPP_COMMA:
3233 /* if we've returned to lowest level and
3234 we aren't absorbing all args */
3235 if (paren == 0 && !rest_args)
3236 goto found;
3237 /*@switchbreak@*/ break;
3238 found:
3239 /* Remove ',' or ')' from argument buffer. */
3240 cppReader_adjustWritten (pfile, -1);
3241 goto done;
3242 default:
3247 done:
3248 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
3249 pfile->no_macro_expand = oldexpand;
3251 return token;
3255 /* Turn newlines to spaces in the string of length LENGTH at START,
3256 except inside of string constants.
3257 The string is copied into itself with its beginning staying fixed. */
3259 static int
3260 change_newlines (char *start, int length)
3262 char *ibp;
3263 char *obp;
3264 char *limit;
3266 ibp = start;
3267 limit = start + length;
3268 obp = start;
3270 while (ibp < limit) {
3271 char c;
3272 *obp++ = c = *ibp++;
3273 switch (c) {
3275 case '\'':
3276 case '\"':
3277 /* Notice and skip strings, so that we don't delete newlines in them. */
3279 char quotec = c;
3280 while (ibp < limit) {
3281 *obp++ = c = *ibp++;
3282 if (c == quotec)
3283 /*@innerbreak@*/ break;
3284 if (c == '\n' && quotec == '\'')
3285 /*@innerbreak@*/ break;
3288 /*@switchbreak@*/ break;
3292 return obp - start;
3295 static /*@observer@*/ struct tm *
3296 timestamp (/*@returned@*/ cppReader *pfile)
3298 if (pfile->timebuf == NULL)
3300 time_t t = time ((time_t *) 0);
3301 pfile->timebuf = localtime (&t);
3304 llassert (pfile->timebuf != NULL);
3306 return pfile->timebuf;
3309 static /*@observer@*/ const char* monthnames[] = {
3310 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3311 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
3315 * expand things like __FILE__. Place the expansion into the output
3316 * buffer *without* rescanning.
3319 static void
3320 special_symbol (hashNode hp, cppReader *pfile)
3322 cstring buf = cstring_undefined;
3323 size_t len;
3324 int true_indepth;
3325 cppBuffer *ip;
3327 int paren = 0; /* For special `defined' keyword */
3329 for (ip = cppReader_getBuffer (pfile); ip != NULL; ip = cppBuffer_prevBuffer (ip))
3331 if (ip == cppReader_nullBuffer (pfile))
3333 cppReader_errorLit (pfile,
3334 cstring_makeLiteralTemp ("cccp error: not in any file?!"));
3335 return; /* the show must go on */
3338 if (ip != NULL && ip->fname != NULL)
3340 break;
3344 switch (hp->type)
3346 case T_FILE:
3347 case T_BASE_FILE:
3349 const char *string;
3350 if (hp->type == T_BASE_FILE)
3352 while (cppBuffer_prevBuffer (ip) != cppReader_nullBuffer (pfile))
3354 ip = cppBuffer_prevBuffer (ip);
3358 llassert (ip != NULL);
3359 string = cstring_toCharsSafe (ip->nominal_fname);
3361 if (string == NULL)
3363 string = "";
3366 cpplib_reserve (pfile, 3 + 4 * strlen (string));
3367 quote_string (pfile, string);
3368 return;
3371 case T_INCLUDE_LEVEL:
3372 true_indepth = 0;
3373 ip = cppReader_getBuffer (pfile);
3375 for (; ip != cppReader_nullBuffer (pfile) && ip != NULL;
3376 ip = cppBuffer_prevBuffer (ip))
3378 if (ip != NULL && ip->fname != NULL)
3380 true_indepth++;
3384 buf = message ("%d", true_indepth - 1);
3385 break;
3387 case T_VERSION:
3388 buf = cstring_makeLiteral ("\"--- cpp version---\"");
3389 break;
3391 #ifndef NO_BUILTIN_SIZE_TYPE
3392 case T_SIZE_TYPE:
3393 buf = cstring_makeLiteral (SIZE_TYPE);
3394 break;
3395 #endif
3397 #ifndef NO_BUILTIN_PTRDIFF_TYPE
3398 case T_PTRDIFF_TYPE:
3399 buf = cstring_makeLiteral (PTRDIFF_TYPE);
3400 break;
3401 #endif
3403 case T_WCHAR_TYPE:
3404 buf = cstring_makeLiteral (WCHAR_TYPE);
3405 break;
3407 case T_USER_LABEL_PREFIX_TYPE:
3408 buf = cstring_makeLiteral (USER_LABEL_PREFIX);
3409 break;
3411 case T_REGISTER_PREFIX_TYPE:
3412 buf = cstring_makeLiteral (REGISTER_PREFIX);
3413 break;
3415 case T_CONST:
3416 buf = message ("%d", hp->value.ival);
3417 break;
3419 case T_SPECLINE:
3421 if (ip != NULL)
3423 int line = ip->lineno;
3424 int col = ip->colno;
3426 llassert (ip->cur != NULL);
3427 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
3429 buf = message ("%d", (int) line);
3431 else
3433 BADBRANCH;
3436 break;
3438 case T_DATE:
3439 case T_TIME:
3441 struct tm *timebuf;
3442 char *sbuf = (char *) dmalloc (20);
3443 timebuf = timestamp (pfile);
3444 if (hp->type == T_DATE)
3446 sprintf (sbuf, "\"%3s %2d %4d\"", monthnames[timebuf->tm_mon],
3447 timebuf->tm_mday, timebuf->tm_year + 1900);
3449 else
3451 sprintf (sbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
3452 timebuf->tm_sec);
3455 buf = cstring_fromCharsNew (sbuf);
3456 sfree (sbuf);
3457 break;
3460 case T_SPEC_DEFINED:
3461 buf = cstring_makeLiteral (" 0 "); /* Assume symbol is not defined */
3462 ip = cppReader_getBuffer (pfile);
3463 llassert (ip != NULL);
3464 llassert (ip->cur != NULL);
3465 SKIP_WHITE_SPACE (ip->cur);
3467 if (*ip->cur == '(')
3469 paren++;
3470 ip->cur++; /* Skip over the paren */
3471 SKIP_WHITE_SPACE (ip->cur);
3475 size_t idlen = identifier_length (ip->cur);
3476 if (idlen == 0 || !identifier_seems_valid (ip->cur))
3477 goto oops;
3479 if ((hp = cpphash_lookup (ip->cur, idlen, -1)) != 0)
3481 cstring_free (buf);
3482 buf = cstring_makeLiteral (" 1 ");
3484 ip->cur += idlen;
3486 SKIP_WHITE_SPACE (ip->cur);
3488 if (paren != 0)
3490 if (*ip->cur != ')')
3491 goto oops;
3492 ++ip->cur;
3494 break;
3496 oops:
3498 cppReader_errorLit (pfile,
3499 cstring_makeLiteralTemp ("`defined' without an identifier"));
3500 break;
3502 default:
3503 cpp_setLocation (pfile);
3504 llfatalerror (message ("Pre-processing error: invalid special hash type"));
3507 len = cstring_length (buf);
3509 cpplib_reserve (pfile, len + 1);
3510 cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
3511 cppReader_nullTerminateQ (pfile);
3513 cstring_free (buf);
3514 return;
3517 /* Write out a #define command for the special named MACRO_NAME
3518 to PFILE's token_buffer. */
3520 static void
3521 dump_special_to_buffer (cppReader *pfile, const char *macro_name)
3523 static const char define_directive[] = "#define ";
3524 size_t macro_name_length = strlen (macro_name);
3525 output_line_command (pfile, 0, same_file);
3526 cpplib_reserve (pfile, constlen(define_directive) + macro_name_length + 1);
3527 cppReader_putStrN (pfile, define_directive, constlen(define_directive));
3528 cppReader_putStrN (pfile, macro_name, macro_name_length);
3529 cppReader_putCharQ (pfile, ' ');
3530 cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
3531 cppReader_putChar (pfile, '\n');
3534 /* Initialize the built-in macros. */
3536 static void
3537 cpplib_installBuiltinAux (const /*@observer@*/ char *name, size_t len,
3538 ctype ctyp, enum node_type type,
3539 int ivalue, /*@null@*/ /*@only@*/ char *value,
3540 int hash)
3542 cstring sname = cstring_fromCharsNew (name);
3544 llassert (usymtab_inGlobalScope ());
3547 ** Be careful here: this is done before the ctype table has
3548 ** been initialized.
3551 if (!usymtab_exists (sname))
3553 uentry ue = uentry_makeConstant (sname, ctyp, fileloc_createBuiltin ());
3555 if (ctype_equal (ctyp, ctype_string))
3557 qualList ql = qualList_new ();
3558 ql = qualList_add (ql, qual_createObserver ());
3559 uentry_reflectQualifiers (ue, ql);
3560 qualList_free (ql);
3563 usymtab_addGlobalEntry (ue);
3565 else
3570 (void) cpphash_install (name, len, type, ivalue, value, hash);
3571 cstring_free (sname);
3574 static void
3575 cpplib_installBuiltinTypeAux (const /*@observer@*/ char *name, size_t len,
3576 ctype ctyp, enum node_type type,
3577 int ivalue, /*@only@*/ /*@null@*/ char *value,
3578 int hash)
3580 cstring sname = cstring_fromChars (name);
3582 llassert (usymtab_inGlobalScope ());
3584 if (!usymtab_existsTypeEither (sname))
3586 uentry ue = uentry_makeDatatype (sname, ctyp,
3587 NO, qual_createConcrete (),
3588 fileloc_createBuiltin ());
3589 llassert (!usymtab_existsEither (sname));
3590 usymtab_addGlobalEntry (ue);
3593 (void) cpphash_install (name, len, type, ivalue, value, hash);
3596 #define cpplib_installBuiltin(name, ctyp, type, ivalue, value, hash) \
3597 cpplib_installBuiltinAux(name, constlen(name), ctyp, type, ivalue, value, hash)
3599 #define cpplib_installBuiltinType(name, ctyp, type, ivalue, value, hash) \
3600 cpplib_installBuiltinTypeAux (name, constlen(name), ctyp, type, ivalue, value, hash)
3602 static void
3603 initialize_builtins (cppReader *pfile)
3605 cpplib_installBuiltin ("__LINE__", ctype_int, T_SPECLINE, 0, NULL, -1);
3606 cpplib_installBuiltin ("__DATE__", ctype_string, T_DATE, 0, NULL, -1);
3607 cpplib_installBuiltin ("__FILE__", ctype_string, T_FILE, 0, NULL, -1);
3608 cpplib_installBuiltin ("__BASE_FILE__", ctype_string, T_BASE_FILE, 0, NULL, -1);
3609 cpplib_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, T_INCLUDE_LEVEL, 0, NULL, -1);
3610 cpplib_installBuiltin ("__VERSION__", ctype_string, T_VERSION, 0, NULL, -1);
3611 #ifndef NO_BUILTIN_SIZE_TYPE
3612 cpplib_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, T_SIZE_TYPE, 0, NULL, -1);
3613 #endif
3614 #ifndef NO_BUILTIN_PTRDIFF_TYPE
3615 cpplib_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, T_PTRDIFF_TYPE, 0, NULL, -1);
3616 #endif
3617 cpplib_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, T_WCHAR_TYPE, 0, NULL, -1);
3618 cpplib_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
3619 cpplib_installBuiltin ("__REGISTER_PREFIX__", ctype_string, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
3620 cpplib_installBuiltin ("__TIME__", ctype_string, T_TIME, 0, NULL, -1);
3622 if (!cppReader_isTraditional (pfile))
3624 cpplib_installBuiltin ("__STDC__", ctype_int, T_CONST, STDC_VALUE, NULL, -1);
3628 ** This is supplied using a -D by the compiler driver
3629 ** so that it is present only when truly compiling with GNU C.
3632 /* cpplib_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
3634 cpplib_installBuiltin ("S_SPLINT_S", ctype_int, T_CONST, 2, NULL, -1);
3635 cpplib_installBuiltin ("__LCLINT__", ctype_int, T_CONST, 2, NULL, -1);
3637 if (CPPOPTIONS (pfile)->debug_output)
3639 dump_special_to_buffer (pfile, "__BASE_FILE__");
3640 dump_special_to_buffer (pfile, "__VERSION__");
3641 #ifndef NO_BUILTIN_SIZE_TYPE
3642 dump_special_to_buffer (pfile, "__SIZE_TYPE__");
3643 #endif
3644 #ifndef NO_BUILTIN_PTRDIFF_TYPE
3645 dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
3646 #endif
3647 dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
3648 dump_special_to_buffer (pfile, "__DATE__");
3649 dump_special_to_buffer (pfile, "__TIME__");
3650 if (!cppReader_isTraditional (pfile))
3651 dump_special_to_buffer (pfile, "__STDC__");
3656 /* Return 1 iff a token ending in C1 followed directly by a token C2
3657 could cause mis-tokenization. */
3659 static bool
3660 unsafe_chars (char c1, char c2)
3662 switch (c1)
3664 case '+': case '-':
3665 if (c2 == c1 || c2 == '=')
3666 return 1;
3667 goto letter;
3668 case '.':
3669 case '0': case '1': case '2': case '3': case '4':
3670 case '5': case '6': case '7': case '8': case '9':
3671 case 'e': case 'E': case 'p': case 'P':
3672 if (c2 == '-' || c2 == '+')
3673 return 1; /* could extend a pre-processing number */
3674 goto letter;
3675 case 'L':
3676 if (c2 == '\'' || c2 == '\"')
3677 return 1; /* Could turn into L"xxx" or L'xxx'. */
3678 goto letter;
3679 letter:
3680 case '_':
3681 case 'a': case 'b': case 'c': case 'd': case 'f':
3682 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
3683 case 'm': case 'n': case 'o': case 'q': case 'r':
3684 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
3685 case 'y': case 'z':
3686 case 'A': case 'B': case 'C': case 'D': case 'F':
3687 case 'G': case 'H': case 'I': case 'J': case 'K':
3688 case 'M': case 'N': case 'O': case 'Q': case 'R':
3689 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
3690 case 'Y': case 'Z':
3691 /* We're in the middle of either a name or a pre-processing number. */
3692 return (is_idchar[(int) c2] || c2 == '.');
3693 case '<': case '>': case '!': case '%': case '#': case ':':
3694 case '^': case '&': case '|': case '*': case '/': case '=':
3695 return (c2 == c1 || c2 == '=');
3697 return 0;
3700 /* Expand a macro call.
3701 HP points to the symbol that is the macro being called.
3702 Put the result of expansion onto the input stack
3703 so that subsequent input by our caller will use it.
3705 If macro wants arguments, caller has already verified that
3706 an argument list follows; arguments come from the input stack. */
3708 static void
3709 cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
3711 int nargs;
3712 DEFINITION *defn = hp->value.defn;
3713 char *xbuf;
3714 char *oxbuf = NULL;
3715 int start_line;
3716 int start_column;
3717 int end_line;
3718 int end_column;
3719 size_t xbuf_len;
3720 size_t old_written = cpplib_getWritten (pfile);
3721 bool rest_zero = FALSE;
3722 int i;
3723 struct argdata *args = NULL;
3725 pfile->output_escapes++;
3726 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
3727 DPRINTF (("Expand macro: %d:%d", start_line, start_column));
3729 nargs = defn->nargs;
3731 if (nargs >= 0)
3733 enum cpp_token token = CPP_EOF;
3734 bool rest_args;
3736 args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
3738 for (i = 0; i < nargs; i++)
3740 args[i].expanded = 0;
3741 args[i].raw = 0;
3742 args[i].raw_length = 0;
3743 args[i].expand_length = args[i].stringified_length = -1;
3744 args[i].use_count = 0;
3748 ** Parse all the macro args that are supplied. I counts them.
3749 ** The first NARGS args are stored in ARGS.
3750 ** The rest are discarded. If rest_args is set then we assume
3751 ** macarg absorbed the rest of the args.
3754 i = 0;
3755 rest_args = FALSE;
3757 cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg. */
3760 if (rest_args)
3762 continue;
3765 if (i < nargs || (nargs == 0 && i == 0))
3767 /* if we are working on last arg which absorbs rest of args... */
3768 if (i == nargs - 1 && defn->rest_args)
3770 rest_args = TRUE;
3773 args[i].raw = size_toLong (cpplib_getWritten (pfile));
3774 token = macarg (pfile, rest_args);
3775 args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
3776 args[i].newlines = FALSE; /* FIXME */
3778 else
3780 token = macarg (pfile, FALSE);
3783 if (token == CPP_EOF || token == CPP_POP)
3785 cppReader_errorWithLine (pfile, start_line, start_column,
3786 cstring_fromCharsNew ("unterminated macro call"));
3787 sfree (args);
3788 return;
3790 i++;
3791 } while (token == CPP_COMMA);
3793 /* If we got one arg but it was just whitespace, call that 0 args. */
3794 if (i == 1)
3796 char *bp;
3797 char *lim;
3799 assertSet (args);
3801 bp = ARG_BASE + args[0].raw;
3802 lim = bp + args[0].raw_length;
3804 /* cpp.texi says for foo ( ) we provide one argument.
3805 However, if foo wants just 0 arguments, treat this as 0. */
3807 if (nargs == 0)
3809 while (bp != lim && is_space[(int) *bp])
3811 bp++;
3815 if (bp == lim)
3816 i = 0;
3819 /* Don't output an error message if we have already output one for
3820 a parse error above. */
3821 rest_zero = FALSE;
3823 if (nargs == 0 && i > 0)
3825 cppReader_error (pfile,
3826 message ("arguments given to macro `%s'", hp->name));
3828 else if (i < nargs)
3830 /* traditional C allows foo() if foo wants one argument. */
3831 if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
3835 /* the rest args token is allowed to absorb 0 tokens */
3836 else if (i == nargs - 1 && defn->rest_args)
3837 rest_zero = TRUE;
3838 else if (i == 0)
3839 cppReader_error (pfile,
3840 message ("macro `%s' used without args", hp->name));
3841 else if (i == 1)
3842 cppReader_error (pfile,
3843 message ("macro `%s' used with just one arg", hp->name));
3844 else
3846 cppReader_error (pfile,
3847 message ("macro `%s' used with only %d args",
3848 hp->name, i));
3851 else if (i > nargs)
3853 cppReader_error (pfile,
3854 message ("macro `%s' used with too many (%d) args", hp->name, i));
3856 else
3863 ** If the agrument list was multiple lines, need to insert new lines to keep line
3864 ** numbers accurate.
3867 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
3868 DPRINTF (("Expand macro: %d:%d", end_line, end_column));
3870 /* If macro wants zero args, we parsed the arglist for checking only.
3871 Read directly from the macro definition. */
3873 if (nargs <= 0)
3875 xbuf = defn->expansion;
3876 xbuf_len = defn->length;
3878 else
3880 char *exp = defn->expansion;
3881 int offset; /* offset in expansion,
3882 copied a piece at a time */
3883 size_t totlen; /* total amount of exp buffer filled so far */
3885 struct reflist *ap, *last_ap;
3887 assertSet (args); /* args is defined since the nargs > 0 path was taken */
3889 /* Macro really takes args. Compute the expansion of this call. */
3891 /* Compute length in characters of the macro's expansion.
3892 Also count number of times each arg is used. */
3893 xbuf_len = defn->length;
3895 llassert (args != NULL);
3897 for (ap = defn->pattern; ap != NULL; ap = ap->next)
3899 if (ap->stringify)
3901 struct argdata *arg = &args[ap->argno];
3903 /* Stringify it it hasn't already been */
3904 assertSet (arg);
3906 if (arg->stringified_length < 0)
3908 int arglen = arg->raw_length;
3909 bool escaped = FALSE;
3910 char in_string = '\0';
3912 /* Initially need_space is -1. Otherwise, 1 means the
3913 previous character was a space, but we suppressed it;
3914 0 means the previous character was a non-space. */
3915 int need_space = -1;
3917 i = 0;
3918 arg->stringified = cpplib_getWritten (pfile);
3919 if (!cppReader_isTraditional (pfile))
3920 cppReader_putChar (pfile, '\"'); /* insert beginning quote */
3921 for (; i < arglen; i++)
3923 char c = (ARG_BASE + arg->raw)[i];
3925 if (in_string == '\0')
3927 /* Internal sequences of whitespace are replaced by
3928 one space except within an string or char token.*/
3929 if (is_space[(int) c])
3931 if (cpplib_getWritten (pfile) > arg->stringified
3932 && (cpplib_getPWritten (pfile))[-1] == '@')
3934 /* "@ " escape markers are removed */
3935 cppReader_adjustWritten (pfile, -1);
3936 /*@innercontinue@*/ continue;
3938 if (need_space == 0)
3939 need_space = 1;
3940 /*@innercontinue@*/ continue;
3942 else if (need_space > 0)
3943 cppReader_putChar (pfile, ' ');
3944 else
3949 need_space = 0;
3952 if (escaped)
3953 escaped = 0;
3954 else
3956 if (c == '\\')
3957 escaped = 1;
3959 if (in_string != '\0')
3961 if (c == in_string)
3962 in_string = '\0';
3964 else if (c == '\"' || c == '\'')
3966 in_string = c;
3968 else
3974 /* Escape these chars */
3975 if (c == '\"' || (in_string != '\0' && c == '\\'))
3976 cppReader_putChar (pfile, '\\');
3977 if (isprint (c))
3978 cppReader_putChar (pfile, c);
3979 else
3981 cpplib_reserve (pfile, 4);
3982 sprintf (cpplib_getPWritten (pfile), "\\%03o",
3983 (unsigned int) c);
3984 cppReader_adjustWritten (pfile, 4);
3987 if (!cppReader_isTraditional (pfile))
3988 cppReader_putChar (pfile, '\"'); /* insert ending quote */
3989 arg->stringified_length
3990 = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
3993 xbuf_len += args[ap->argno].stringified_length;
3995 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
3997 /* Add 4 for two newline-space markers to prevent token concatenation. */
3998 assertSet (args); /* Splint shouldn't need this */
3999 xbuf_len += args[ap->argno].raw_length + 4;
4001 else
4003 /* We have an ordinary (expanded) occurrence of the arg.
4004 So compute its expansion, if we have not already. */
4006 assertSet (args); /* shouldn't need this */
4008 if (args[ap->argno].expand_length < 0)
4010 args[ap->argno].expanded = cpplib_getWritten (pfile);
4011 cpp_expand_to_buffer (pfile,
4012 ARG_BASE + args[ap->argno].raw,
4013 size_fromInt (args[ap->argno].raw_length));
4015 args[ap->argno].expand_length
4016 = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
4019 /* Add 4 for two newline-space markers to prevent
4020 token concatenation. */
4021 xbuf_len += args[ap->argno].expand_length + 4;
4023 if (args[ap->argno].use_count < 10)
4024 args[ap->argno].use_count++;
4027 xbuf = (char *) dmalloc (xbuf_len + 1);
4028 oxbuf = xbuf;
4031 ** Generate in XBUF the complete expansion
4032 ** with arguments substituted in.
4033 ** TOTLEN is the total size generated so far.
4034 ** OFFSET is the index in the definition
4035 ** of where we are copying from.
4038 offset = 0;
4039 totlen = 0;
4041 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
4042 last_ap = ap, ap = ap->next)
4044 struct argdata *arg = &args[ap->argno];
4045 size_t count_before = totlen;
4047 /* Add chars to XBUF. */
4048 for (i = 0; i < ap->nchars; i++, offset++)
4050 xbuf[totlen++] = exp[offset];
4053 /* If followed by an empty rest arg with concatenation,
4054 delete the last run of nonwhite chars. */
4055 if (rest_zero && totlen > count_before
4056 && ((ap->rest_args && ap->raw_before)
4057 || (last_ap != NULL && last_ap->rest_args
4058 && last_ap->raw_after)))
4060 /* Delete final whitespace. */
4061 while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
4063 totlen--;
4066 /* Delete the nonwhites before them. */
4067 while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
4069 totlen--;
4073 if (ap->stringify != 0)
4075 assertSet(arg);
4076 memcpy (xbuf + totlen,
4077 ARG_BASE + arg->stringified,
4078 size_fromInt (arg->stringified_length));
4079 totlen += arg->stringified_length;
4081 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4083 char *p1;
4084 char *l1;
4086 assertSet (arg);
4088 p1 = ARG_BASE + arg->raw;
4089 l1 = p1 + arg->raw_length;
4091 if (ap->raw_before)
4093 while (p1 != l1 && is_space[(int) *p1])
4095 p1++;
4098 while (p1 != l1 && is_idchar[(int) *p1])
4100 xbuf[totlen++] = *p1++;
4103 /* Delete any no-reexpansion marker that follows
4104 an identifier at the beginning of the argument
4105 if the argument is concatenated with what precedes it. */
4106 if (p1[0] == '@' && p1[1] == '-')
4107 p1 += 2;
4109 if (ap->raw_after)
4111 /* Arg is concatenated after: delete trailing whitespace,
4112 whitespace markers, and no-reexpansion markers. */
4113 while (p1 != l1)
4115 if (is_space[(int) l1[-1]]) l1--;
4116 else if (l1[-1] == '-')
4118 char *p2 = l1 - 1;
4119 /* If a `-' is preceded by an odd number of newlines then it
4120 and the last newline are a no-reexpansion marker. */
4121 while (p2 != p1 && p2[-1] == '\n')
4123 p2--;
4126 if (((l1 - 1 - p2) & 1) != 0)
4128 l1 -= 2;
4130 else
4132 /*@innerbreak@*/ break;
4135 else
4137 /*@innerbreak@*/ break;
4142 memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
4143 totlen += l1 - p1;
4145 else
4147 char *expanded;
4149 assertSet (arg);
4150 expanded = ARG_BASE + arg->expanded;
4152 if (!ap->raw_before && totlen > 0
4153 && (arg->expand_length != 0)
4154 && !cppReader_isTraditional(pfile)
4155 && unsafe_chars (xbuf[totlen-1], expanded[0]))
4157 xbuf[totlen++] = '@';
4158 xbuf[totlen++] = ' ';
4161 memcpy (xbuf + totlen, expanded,
4162 size_fromInt (arg->expand_length));
4163 totlen += arg->expand_length;
4165 if (!ap->raw_after && totlen > 0
4166 && offset < size_toInt (defn->length)
4167 && !cppReader_isTraditional(pfile)
4168 && unsafe_chars (xbuf[totlen-1], exp[offset]))
4170 xbuf[totlen++] = '@';
4171 xbuf[totlen++] = ' ';
4174 /* If a macro argument with newlines is used multiple times,
4175 then only expand the newlines once. This avoids creating
4176 output lines which don't correspond to any input line,
4177 which confuses gdb and gcov. */
4178 if (arg->use_count > 1 && arg->newlines > 0)
4180 /* Don't bother doing change_newlines for subsequent
4181 uses of arg. */
4182 arg->use_count = 1;
4183 arg->expand_length
4184 = change_newlines (expanded, arg->expand_length);
4188 if (totlen > xbuf_len)
4190 cppReader_error (pfile,
4191 cstring_makeLiteral ("failure in macro expansion"));
4192 sfree (args);
4193 return;
4197 /* if there is anything left of the definition
4198 after handling the arg list, copy that in too. */
4200 for (i = offset; i < size_toInt (defn->length); i++)
4202 /* if we've reached the end of the macro */
4203 if (exp[i] == ')')
4204 rest_zero = FALSE;
4205 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
4206 && last_ap->raw_after))
4207 xbuf[totlen++] = exp[i];
4210 xbuf[totlen] = '\0';
4211 xbuf_len = totlen;
4214 pfile->output_escapes--;
4216 /* Now put the expansion on the input stack
4217 so our caller will commence reading from it. */
4218 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4220 if (end_line != start_line)
4222 /* xbuf must have enough newlines */
4223 int newlines = end_line - start_line;
4224 int foundnewlines = 0;
4225 char *xbufptr = xbuf;
4227 while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
4229 foundnewlines++;
4230 xbufptr++;
4232 if (*xbufptr == '\0')
4234 break;
4238 if (foundnewlines < newlines)
4240 cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
4242 while (foundnewlines < newlines)
4244 newbuf = cstring_appendChar (newbuf, '\n');
4245 foundnewlines++;
4248 sfree (oxbuf);
4249 xbuf = cstring_toCharsSafe (newbuf);
4250 xbuf_len = cstring_length (newbuf);
4251 /*@-branchstate@*/
4252 } /*@=branchstate@*/
4255 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4257 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
4258 DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4259 cppReader_getBufferSafe (pfile)->has_escapes = 1;
4261 /* Pop the space we've used in the token_buffer for argument expansion. */
4262 cppReader_setWritten (pfile, old_written);
4263 DPRINTF (("Done set written"));
4265 /* Recursive macro use sometimes works traditionally.
4266 #define foo(x,y) bar (x (y,0), y)
4267 foo (foo, baz) */
4269 if (!cppReader_isTraditional (pfile))
4270 hp->type = T_DISABLED;
4272 sfree (args);
4275 static void
4276 push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
4277 /*@dependent@*/ hashNode hp)
4279 cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
4281 if (mbuf == NULL)
4283 return;
4286 mbuf->cleanup = cppReader_macroCleanup;
4288 llassert (mbuf->hnode == NULL);
4289 mbuf->hnode = hp;
4291 /* The first chars of the expansion should be a "@ " added by
4292 collect_expansion. This is to prevent accidental token-pasting
4293 between the text preceding the macro invocation, and the macro
4294 expansion text.
4296 We would like to avoid adding unneeded spaces (for the sake of
4297 tools that use cpp, such as imake). In some common cases we can
4298 tell that it is safe to omit the space.
4300 The character before the macro invocation cannot have been an
4301 idchar (or else it would have been pasted with the idchars of
4302 the macro name). Therefore, if the first non-space character
4303 of the expansion is an idchar, we do not need the extra space
4304 to prevent token pasting.
4306 Also, we don't need the extra space if the first char is '(',
4307 or some other (less common) characters. */
4309 if (xbuf[0] == '@' && xbuf[1] == ' '
4310 && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
4311 || xbuf[2] == '\"'))
4313 llassert (mbuf->cur != NULL);
4314 DPRINTF (("Eating: %c", xbuf[2]));
4315 mbuf->cur += 2;
4321 /* Like cpplib_getToken, except that it does not read past end-of-line.
4322 Also, horizontal space is skipped, and macros are popped. */
4324 static enum cpp_token
4325 get_directive_token (cppReader *pfile)
4327 for (;;)
4329 size_t old_written = cpplib_getWritten (pfile);
4330 enum cpp_token token;
4331 cppSkipHspace (pfile);
4332 if (cppReader_peekC (pfile) == '\n')
4334 return CPP_VSPACE;
4337 token = cpplib_getToken (pfile);
4339 switch (token)
4341 case CPP_POP:
4342 if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
4343 return token;
4344 /*@fallthrough@*/
4345 case CPP_HSPACE:
4346 case CPP_COMMENT:
4347 cppReader_setWritten (pfile, old_written);
4348 /*@switchbreak@*/ break;
4349 default:
4350 return token;
4355 /* Handle #include and #import.
4356 This function expects to see "fname" or <fname> on the input.
4358 The input is normally in part of the output_buffer following
4359 cpplib_getWritten, and will get overwritten by output_line_command.
4360 I.e. in input file specification has been popped by cppReader_handleDirective.
4361 This is safe. */
4363 static void
4364 do_include (cppReader *pfile, struct directive *keyword,
4365 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
4367 bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
4368 cstring fname;
4369 char *fbeg, *fend; /* Beginning and end of fname */
4370 enum cpp_token token;
4372 /* Chain of dirs to search */
4373 struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
4374 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
4375 struct file_name_list *searchptr = NULL;
4376 size_t old_written = cpplib_getWritten (pfile);
4377 size_t flen;
4379 int f; /* file number */
4380 int angle_brackets = 0; /* 0 for "...", 1 for <...> */
4381 f= -1; /* JF we iz paranoid! */
4383 pfile->parsing_include_directive = TRUE;
4384 token = get_directive_token (pfile);
4385 pfile->parsing_include_directive = FALSE;
4387 if (token == CPP_STRING)
4389 /* FIXME - check no trailing garbage */
4390 fbeg = pfile->token_buffer + old_written + 1;
4391 fend = cpplib_getPWritten (pfile) - 1;
4392 if (fbeg[-1] == '<')
4394 angle_brackets = 1;
4395 /* If -I-, start with the first -I dir after the -I-. */
4396 if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
4397 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4399 /* If -I- was specified, don't search current dir, only spec'd ones. */
4400 else if (!CPPOPTIONS (pfile)->ignore_srcdir)
4402 cppBuffer *fp = CPPBUFFER (pfile);
4403 /* We have "filename". Figure out directory this source
4404 file is coming from and put it on the front of the list. */
4406 for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4408 char *ep,*nam;
4410 llassert (fp != NULL);
4412 nam = NULL;
4414 if (cstring_isDefined (fp->nominal_fname))
4416 nam = cstring_toCharsSafe (fp->nominal_fname);
4418 /* Found a named file. Figure out dir of the file,
4419 and put it in front of the search list. */
4420 dsp[0].next = search_start;
4421 search_start = dsp;
4423 ep = strrchr (nam, CONNECTCHAR);
4424 if (ep != NULL)
4426 int n;
4427 char save;
4429 n = ep - nam;
4430 save = nam[n];
4431 nam[n] = '\0';
4433 /*@-onlytrans@*/ /* This looks like a memory leak... */
4434 dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
4435 /*@=onlytrans@*/
4436 nam[n] = save;
4438 else
4440 dsp[0].fname = cstring_undefined; /* Current directory */
4443 dsp[0].got_name_map = FALSE;
4444 break;
4448 else
4453 else
4455 cppReader_error (pfile,
4456 message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
4457 cstring_fromChars (keyword->name)));
4459 cppReader_setWritten (pfile, old_written);
4460 cppReader_skipRestOfLine (pfile);
4461 return;
4464 *fend = 0;
4466 token = get_directive_token (pfile);
4467 if (token != CPP_VSPACE)
4469 cppReader_errorLit (pfile,
4470 cstring_makeLiteralTemp ("Junk at end of #include"));
4472 while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
4474 token = get_directive_token (pfile);
4479 ** For #include_next, skip in the search path
4480 ** past the dir in which the containing file was found.
4483 if (skip_dirs)
4485 cppBuffer *fp = CPPBUFFER (pfile);
4487 for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4489 llassert (fp != NULL);
4491 if (fp->fname != NULL)
4493 /* fp->dir is null if the containing file was specified with
4494 an absolute file name. In that case, don't skip anything. */
4495 if (fp->dir == SELF_DIR_DUMMY)
4497 search_start = CPPOPTIONS (pfile)->include;
4499 else if (fp->dir != NULL)
4501 search_start = fp->dir->next;
4503 else
4508 break;
4513 cppReader_setWritten (pfile, old_written);
4515 flen = size_fromInt (fend - fbeg);
4517 DPRINTF (("fbeg: %s", fbeg));
4519 if (flen == 0)
4521 cppReader_error (pfile,
4522 message ("Empty file name in #%s", cstring_fromChars (keyword->name)));
4523 return;
4527 ** Allocate this permanently, because it gets stored in the definitions
4528 ** of macros.
4531 fname = cstring_undefined;
4533 /* If specified file name is absolute, just open it. */
4535 if (osd_pathIsAbsolute (fbeg))
4537 fname = cstring_copyLength (fbeg, flen);
4539 if (redundant_include_p (pfile, fname))
4541 cstring_free (fname);
4542 return;
4545 f = open_include_file (pfile, fname, NULL);
4547 if (f == IMPORT_FOUND)
4549 return; /* Already included this file */
4552 else
4554 /* Search directory path, trying to open the file.
4555 Copy each filename tried into FNAME. */
4557 for (searchptr = search_start; searchptr != NULL;
4558 searchptr = searchptr->next)
4560 #if 0
4561 /* The empty string in a search path is ignored.
4562 This makes it possible to turn off entirely
4563 a standard piece of the list. */
4564 if (cstring_isEmpty (searchptr->fname))
4565 continue;
4566 #endif
4567 if (!cstring_isEmpty (searchptr->fname))
4569 fname = cstring_copy (searchptr->fname);
4570 fname = cstring_appendChar (fname, CONNECTCHAR);
4571 osd_pathMakeNative (fname);
4572 DPRINTF (("Here: %s", fname));
4574 else
4579 fname = cstring_concatLength (fname, fbeg, flen);
4581 DPRINTF (("fname: %s", fname));
4583 /* ??? There are currently 3 separate mechanisms for avoiding processing
4584 of redundant include files: #import, #pragma once, and
4585 redundant_include_p. It would be nice if they were unified. */
4587 if (redundant_include_p (pfile, fname))
4589 cstring_free (fname);
4590 return;
4593 DPRINTF (("Trying: %s", fname));
4595 f = open_include_file (pfile, fname, searchptr);
4597 if (f == IMPORT_FOUND)
4599 return; /* Already included this file */
4601 #ifdef EACCES
4602 else if (f == IMPORT_NOT_FOUND && errno == EACCES)
4604 cppReader_warning (pfile,
4605 message ("Header file %s exists, but is not readable", fname));
4607 #endif
4609 if (f >= 0)
4611 break;
4616 if (f < 0)
4618 /* A file that was not found. */
4619 fname = cstring_copyLength (fbeg, flen);
4621 if (search_start != NULL)
4623 cppReader_error (pfile,
4624 message ("Cannot find include file %s on search path: %x",
4625 fname,
4626 searchPath_unparse (search_start)));
4628 else
4630 cppReader_error (pfile,
4631 message ("No include path in which to find %s", fname));
4634 else {
4636 ** Check to see if this include file is a once-only include file.
4637 ** If so, give up.
4640 struct file_name_list *ptr;
4642 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
4644 if (cstring_equal (ptr->fname, fname))
4646 /* This file was included before. */
4647 break;
4651 if (ptr == NULL)
4653 /* This is the first time for this file. */
4654 /* Add it to list of files included. */
4656 ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
4657 ptr->control_macro = NULL;
4658 ptr->next = pfile->all_include_files;
4659 ptr->fname = fname;
4660 ptr->name_map = NULL;
4661 ptr->got_name_map = FALSE;
4663 DPRINTF (("Including file: %s", fname));
4664 pfile->all_include_files = ptr;
4665 assertSet (pfile->all_include_files);
4668 if (angle_brackets != 0)
4670 pfile->system_include_depth++;
4673 /* Actually process the file */
4674 if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
4676 cstring_free (fname);
4677 return;
4680 if (finclude (pfile, f, fname, is_system_include (pfile, fname),
4681 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
4683 output_line_command (pfile, 0, enter_file);
4684 pfile->only_seen_white = 2;
4687 if (angle_brackets)
4689 pfile->system_include_depth--;
4691 /*@-branchstate@*/
4692 } /*@=branchstate@*/
4695 /* Return true if there is no need to include file NAME
4696 because it has already been included and it contains a conditional
4697 to make a repeated include do nothing. */
4699 static bool
4700 redundant_include_p (cppReader *pfile, cstring name)
4702 struct file_name_list *l = pfile->all_include_files;
4704 for (; l != NULL; l = l->next)
4706 if (cstring_equal (name, l->fname)
4707 && (l->control_macro != NULL)
4708 && (cpphash_lookup (l->control_macro, identifier_length(l->control_macro), -1) != NULL))
4710 return TRUE;
4714 return FALSE;
4717 /* Return true if the given FILENAME is an absolute pathname which
4718 designates a file within one of the known "system" include file
4719 directories. We assume here that if the given FILENAME looks like
4720 it is the name of a file which resides either directly in a "system"
4721 include file directory, or within any subdirectory thereof, then the
4722 given file must be a "system" include file. This function tells us
4723 if we should suppress pedantic errors/warnings for the given FILENAME. */
4725 static bool
4726 is_system_include (cppReader *pfile, cstring filename)
4728 struct file_name_list *searchptr;
4730 for (searchptr = CPPOPTIONS (pfile)->first_system_include;
4731 searchptr != NULL;
4732 searchptr = searchptr->next)
4734 if (!cstring_isEmpty (searchptr->fname))
4736 cstring sys_dir = searchptr->fname;
4737 size_t length = cstring_length (sys_dir);
4739 if (cstring_equalLen (sys_dir, filename, length)
4740 && osd_isConnectChar (cstring_getChar (filename, length)))
4742 return TRUE;
4747 return FALSE;
4750 /* Convert a character string literal into a nul-terminated string.
4751 The input string is [IN ... LIMIT).
4752 The result is placed in RESULT. RESULT can be the same as IN.
4753 The value returned in the end of the string written to RESULT,
4754 or NULL on error. */
4756 static /*@null@*/ char *
4757 convert_string (cppReader *pfile, /*@returned@*/ char *result,
4758 char *in, char *limit, int handle_escapes)
4760 char c;
4761 c = *in++;
4763 if (c != '\"')
4765 return NULL;
4768 while (in < limit)
4770 c = *in++;
4772 switch (c)
4774 case '\0':
4775 return NULL;
4776 case '\"':
4777 limit = in;
4778 /*@switchbreak@*/ break;
4779 case '\\':
4780 if (handle_escapes)
4782 char *bpc = (char *) in;
4783 int i = (char) cppReader_parseEscape (pfile, &bpc);
4784 in = (char *) bpc;
4785 if (i >= 0)
4786 *result++ = (char) c;
4787 /*@switchbreak@*/ break;
4790 /*@fallthrough@*/
4791 default:
4792 *result++ = c;
4796 *result = 0;
4797 return result;
4801 * interpret #line command. Remembers previously seen fnames
4802 * in its very own hash table.
4805 /*@constant int FNAME_HASHSIZE@*/
4806 #define FNAME_HASHSIZE 37
4808 static void
4809 do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword,
4810 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
4812 cppBuffer *ip = cppReader_getBuffer (pfile);
4813 int new_lineno;
4814 size_t old_written = cpplib_getWritten (pfile);
4815 enum file_change_code file_change = same_file;
4816 enum cpp_token token;
4818 llassert (ip != NULL);
4819 token = get_directive_token (pfile);
4821 if (token != CPP_NUMBER
4822 || !isdigit(pfile->token_buffer[old_written]))
4824 cppReader_errorLit (pfile,
4825 cstring_makeLiteralTemp ("invalid format `#line' command"));
4827 goto bad_line_directive;
4830 /* The Newline at the end of this line remains to be processed.
4831 To put the next line at the specified line number,
4832 we must store a line number now that is one less. */
4833 new_lineno = atoi (pfile->token_buffer + old_written) - 1;
4834 cppReader_setWritten (pfile, old_written);
4836 /* NEW_LINENO is one less than the actual line number here. */
4837 if (cppReader_isPedantic (pfile) && new_lineno < 0)
4838 cppReader_pedwarnLit (pfile,
4839 cstring_makeLiteralTemp ("line number out of range in `#line' command"));
4841 token = get_directive_token (pfile);
4843 if (token == CPP_STRING) {
4844 char *fname = pfile->token_buffer + old_written;
4845 char *end_name;
4846 static hashNode fname_table[FNAME_HASHSIZE];
4847 hashNode hp;
4848 hashNode *hash_bucket;
4849 char *p;
4850 size_t num_start;
4851 size_t fname_length;
4853 /* Turn the file name, which is a character string literal,
4854 into a null-terminated string. Do this in place. */
4855 end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
4856 if (end_name == NULL)
4858 cppReader_errorLit (pfile,
4859 cstring_makeLiteralTemp ("invalid format `#line' command"));
4860 goto bad_line_directive;
4863 fname_length = size_fromInt (end_name - fname);
4864 num_start = cpplib_getWritten (pfile);
4866 token = get_directive_token (pfile);
4867 if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
4868 p = pfile->token_buffer + num_start;
4869 if (cppReader_isPedantic (pfile))
4870 cppReader_pedwarnLit (pfile,
4871 cstring_makeLiteralTemp ("garbage at end of `#line' command"));
4873 if (token != CPP_NUMBER || *p < '0' || *p > '3' || p[1] != '\0')
4875 cppReader_errorLit (pfile,
4876 cstring_makeLiteralTemp ("invalid format `#line' command"));
4877 goto bad_line_directive;
4879 if (*p == '1')
4880 file_change = enter_file;
4881 else if (*p == 2)
4882 file_change = leave_file;
4883 else /* if (*p == 3) */
4884 ip->system_header_p = TRUE;
4886 cppReader_setWritten (pfile, num_start);
4887 token = get_directive_token (pfile);
4888 p = pfile->token_buffer + num_start;
4889 if (token == CPP_NUMBER && p[1] == '\0' && *p == '3') {
4890 ip->system_header_p = TRUE;
4891 token = get_directive_token (pfile);
4893 if (token != CPP_VSPACE) {
4894 cppReader_errorLit (pfile,
4895 cstring_makeLiteralTemp ("invalid format `#line' command"));
4897 goto bad_line_directive;
4901 hash_bucket =
4902 &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
4904 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
4906 if (hp->length == fname_length)
4908 llassert (hp->value.cpval != NULL);
4910 if (strncmp (hp->value.cpval, fname, fname_length) == 0)
4912 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
4913 break;
4918 if (hp == 0) {
4919 /* Didn't find it; cons up a new one. */
4920 hp = (hashNode) dmalloc (sizeof (*hp));
4922 hp->prev = NULL;
4923 hp->bucket_hdr = NULL;
4924 hp->type = T_NONE;
4925 hp->name = cstring_undefined;
4926 hp->next = *hash_bucket;
4928 *hash_bucket = hp;
4930 hp->length = fname_length;
4931 hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
4932 memcpy (hp->value.cpval, fname, fname_length);
4933 hp->value.cpval[fname_length] = '\0';
4934 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
4937 else if (token != CPP_VSPACE && token != CPP_EOF)
4939 cppReader_errorLit (pfile,
4940 cstring_makeLiteralTemp ("invalid format `#line' command"));
4941 goto bad_line_directive;
4943 else
4948 ip->lineno = new_lineno;
4949 bad_line_directive:
4950 cppReader_skipRestOfLine (pfile);
4951 cppReader_setWritten (pfile, old_written);
4952 output_line_command (pfile, 0, file_change);
4956 * remove the definition of a symbol from the symbol table.
4957 * according to un*x /lib/cpp, it is not an error to undef
4958 * something that has no definitions, so it isn't one here either.
4961 static void
4962 do_undef (cppReader *pfile, struct directive *keyword, const char *buf, const char *limit)
4964 size_t sym_length;
4965 hashNode hp;
4966 const char *orig_buf = buf;
4968 SKIP_WHITE_SPACE (buf);
4970 sym_length = identifier_length (buf);
4971 if (!macro_name_is_valid (buf, sym_length))
4973 cppReader_error (pfile, invalid_macro_message (buf, sym_length));
4975 else
4977 while ((hp = cpphash_lookup (buf, sym_length, -1)) != NULL)
4979 /* If we are generating additional info for debugging (with -g) we
4980 need to pass through all effective #undef commands. */
4981 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
4983 pass_thru_directive (orig_buf, limit, pfile, keyword);
4986 if (hp->type != T_MACRO)
4988 cppReader_warning (pfile,
4989 message ("Undefining preprocessor builtin: %s",
4990 hp->name));
4993 cpphash_deleteMacro (hp);
4997 if (cppReader_isPedantic (pfile)) {
4998 buf += sym_length;
4999 SKIP_WHITE_SPACE (buf);
5000 if (buf != limit)
5002 cppReader_pedwarnLit (pfile,
5003 cstring_makeLiteralTemp ("garbage after `#undef' directive"));
5010 * Report an error detected by the program we are processing.
5011 * Use the text of the line in the error message.
5012 * (We use error because it prints the filename & line#.)
5015 static void
5016 do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5017 const char *buf, const char *limit)
5019 cstring msg;
5020 SKIP_WHITE_SPACE (buf);
5021 if (buf >= limit)
5022 msg = cstring_makeLiteral("#error");
5023 else
5024 msg = message ("#error %q",
5025 cstring_copyLength (buf, size_fromInt (limit - buf)));
5026 cppReader_error (pfile, msg);
5030 * Report a warning detected by the program we are processing.
5031 * Use the text of the line in the warning message, then continue.
5032 * (We use error because it prints the filename & line#.)
5035 static void
5036 do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5037 const char *buf, const char *limit)
5039 cstring msg;
5040 SKIP_WHITE_SPACE (buf);
5041 if (buf >= limit)
5042 msg = cstring_makeLiteral("#warning");
5043 else
5044 msg = message ("#warning %q",
5045 cstring_copyLength (buf, size_fromInt (limit - buf)));
5046 cppReader_warning (pfile, msg);
5050 /* #ident has already been copied to the output file, so just ignore it. */
5052 static void
5053 do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5054 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5056 /* Allow #ident in system headers, since that's not user's fault. */
5057 if (cppReader_isPedantic (pfile)
5058 && !cppReader_getBufferSafe (pfile)->system_header_p)
5059 cppReader_pedwarnLit (pfile,
5060 cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
5062 /* Leave rest of line to be read by later calls to cpplib_getToken. */
5065 /* #pragma and its argument line have already been copied to the output file.
5066 Just check for some recognized pragmas that need validation here. */
5068 static void
5069 do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5070 const char *buf, const /*@unused@*/ char *limit)
5072 static const char implstr[] = "implementation";
5074 SKIP_WHITE_SPACE (buf);
5076 if (strncmp (buf, implstr, constlen(implstr)) == 0) {
5077 /* Be quiet about `#pragma implementation' for a file only if it hasn't
5078 been included yet. */
5079 struct file_name_list *ptr;
5080 const char *p, *fname;
5081 size_t fname_len;
5083 p = buf + constlen(implstr);
5084 SKIP_WHITE_SPACE (p);
5085 if (*p == '\n' || *p != '\"')
5086 return;
5088 fname = p + 1;
5089 p = (char *) strchr (fname, '\"');
5090 fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
5092 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
5094 char *inc_fname = strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
5095 inc_fname = (inc_fname != NULL)
5096 ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
5098 if ((inc_fname != NULL)
5099 && (strncmp (inc_fname, fname, fname_len) == 0))
5101 cpp_setLocation (pfile);
5103 ppllerror (message ("`#pragma %s' for `%s' appears after file is included",
5104 cstring_fromChars (implstr), cstring_fromChars (fname)));
5111 * handle #if command by
5112 * 1) inserting special `defined' keyword into the hash table
5113 * that gets turned into 0 or 1 by special_symbol (thus,
5114 * if the luser has a symbol called `defined' already, it won't
5115 * work inside the #if command)
5116 * 2) rescan the input into a temporary output buffer
5117 * 3) pass the output buffer to the yacc parser and collect a value
5118 * 4) clean up the mess left from steps 1 and 2.
5119 * 5) call conditional_skip to skip til the next #endif (etc.),
5120 * or not, depending on the value from step 3.
5123 static void
5124 do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5125 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5127 HOST_WIDE_INT value;
5128 value = eval_if_expression (pfile);
5129 conditional_skip (pfile, value == 0, T_IF, NULL);
5133 * handle a #elif directive by not changing if_stack either.
5134 * see the comment above do_else.
5137 static void
5138 do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5139 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5141 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5143 cppReader_errorLit (pfile,
5144 cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
5145 return;
5147 else
5149 llassert (pfile->if_stack != NULL);
5151 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5153 cppReader_errorLit (pfile,
5154 cstring_makeLiteralTemp ("`#elif' after `#else'"));
5156 if (pfile->if_stack->fname != NULL
5157 && cppReader_getBufferSafe (pfile)->fname != NULL
5158 && !cstring_equal (pfile->if_stack->fname,
5159 cppReader_getBufferSafe (pfile)->nominal_fname))
5160 fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
5161 fprintf (stderr, ")\n");
5163 pfile->if_stack->type = T_ELIF;
5166 if (pfile->if_stack->if_succeeded)
5168 skip_if_group (pfile, FALSE);
5170 else
5172 HOST_WIDE_INT value = eval_if_expression (pfile);
5173 if (value == 0)
5174 skip_if_group (pfile, FALSE);
5175 else
5177 ++pfile->if_stack->if_succeeded; /* continue processing input */
5178 output_line_command (pfile, 1, same_file);
5184 * evaluate a #if expression in BUF, of length LENGTH,
5185 * then parse the result as a C expression and return the value as an int.
5188 static HOST_WIDE_INT
5189 eval_if_expression (cppReader *pfile)
5191 hashNode save_defined;
5192 HOST_WIDE_INT value;
5193 size_t old_written = cpplib_getWritten (pfile);
5194 static const char defstr[] = "defined";
5196 DPRINTF (("Saving defined..."));
5197 save_defined = cpphash_install (defstr, constlen(defstr), T_SPEC_DEFINED, 0, 0, -1);
5198 pfile->pcp_inside_if = TRUE;
5200 value = cppReader_parseExpression (pfile);
5201 pfile->pcp_inside_if = FALSE;
5203 /* Clean up special symbol */
5204 DPRINTF (("Removing defined..."));
5205 cpphash_deleteMacro (save_defined);
5206 cppReader_setWritten (pfile, old_written); /* Pop */
5208 return value;
5212 * routine to handle ifdef/ifndef. Try to look up the symbol,
5213 * then do or don't skip to the #endif/#else/#elif depending
5214 * on what directive is actually being processed.
5217 static void
5218 do_xifdef (cppReader *pfile, struct directive *keyword,
5219 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5221 int skip;
5222 cppBuffer *ip = cppReader_getBufferSafe (pfile);
5223 char *ident;
5224 size_t ident_length;
5225 enum cpp_token token;
5226 int start_of_file = 0;
5227 char *control_macro = 0;
5228 size_t old_written = cpplib_getWritten (pfile);
5230 DPRINTF (("do xifdef: %d",
5231 keyword->type == T_IFNDEF));
5233 /* Detect a #ifndef at start of file (not counting comments). */
5234 if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
5236 start_of_file = pfile->only_seen_white == 2;
5239 pfile->no_macro_expand = TRUE;
5240 token = get_directive_token (pfile);
5241 pfile->no_macro_expand = FALSE;
5243 ident = pfile->token_buffer + old_written;
5244 DPRINTF (("Ident: %s", ident));
5246 ident_length = cpplib_getWritten (pfile) - old_written;
5247 cppReader_setWritten (pfile, old_written); /* Pop */
5249 if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
5251 skip = (keyword->type == T_IFDEF);
5252 if (! cppReader_isTraditional (pfile))
5254 cppReader_pedwarn (pfile,
5255 message ("`#%s' with no argument", cstring_fromChars (keyword->name)));
5258 else if (token == CPP_NAME)
5260 hashNode hp = cpphash_lookup (ident, ident_length, -1);
5262 skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
5264 DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
5266 if (start_of_file && !skip)
5268 DPRINTF (("Not skipping!"));
5269 control_macro = (char *) dmalloc (ident_length + 1);
5270 memcpy (control_macro, ident, ident_length + 1);
5273 else
5275 skip = (keyword->type == T_IFDEF);
5276 if (! cppReader_isTraditional (pfile))
5278 cppReader_error (pfile,
5279 message ("`#%s' with invalid argument", cstring_fromChars (keyword->name)));
5283 if (!cppReader_isTraditional (pfile))
5285 int c;
5286 cppSkipHspace (pfile);
5287 c = cppReader_peekC (pfile);
5288 if (c != EOF && c != '\n')
5290 cppReader_pedwarn (pfile,
5291 message ("garbage at end of `#%s' argument", cstring_fromChars (keyword->name)));
5295 cppReader_skipRestOfLine (pfile);
5297 DPRINTF (("Conditional skip: %d", skip));
5298 conditional_skip (pfile, skip, T_IF, control_macro);
5301 /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
5302 If this is a #ifndef starting at the beginning of a file,
5303 CONTROL_MACRO is the macro name tested by the #ifndef.
5304 Otherwise, CONTROL_MACRO is 0. */
5306 static void
5307 conditional_skip (cppReader *pfile, int skip,
5308 enum node_type type,
5309 /*@dependent@*/ char *control_macro)
5311 cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5313 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
5314 temp->next = pfile->if_stack;
5315 temp->control_macro = control_macro;
5316 temp->lineno = 0;
5317 temp->if_succeeded = 0;
5319 pfile->if_stack = temp;
5320 pfile->if_stack->type = type;
5322 if (skip != 0)
5324 skip_if_group (pfile, FALSE);
5325 return;
5327 else
5329 ++pfile->if_stack->if_succeeded;
5330 output_line_command (pfile, 1, same_file);
5335 * skip to #endif, #else, or #elif. adjust line numbers, etc.
5336 * leaves input ptr at the sharp sign found.
5337 * If ANY is true, return at next directive of any sort.
5340 static void
5341 skip_if_group (cppReader *pfile, bool any)
5343 int c;
5344 struct directive *kt;
5345 cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
5346 int ident_length;
5347 char *ident;
5348 struct parse_marker line_start_mark;
5350 parseSetMark (&line_start_mark, pfile);
5352 if (CPPOPTIONS (pfile)->output_conditionals) {
5353 static const char failed[] = "#failed\n";
5354 cppReader_puts (pfile, failed, constlen(failed));
5355 pfile->lineno++;
5356 output_line_command (pfile, 1, same_file);
5359 beg_of_line:
5360 if (CPPOPTIONS (pfile)->output_conditionals)
5362 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
5363 char *start_line;
5365 llassert (pbuf->buf != NULL);
5367 start_line = pbuf->buf + line_start_mark.position;
5368 cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
5371 parseMoveMark (&line_start_mark, pfile);
5373 if (!cppReader_isTraditional (pfile))
5375 cppSkipHspace (pfile);
5378 c = cppReader_getC (pfile);
5379 if (c == '#')
5381 size_t old_written = cpplib_getWritten (pfile);
5382 cppSkipHspace (pfile);
5384 parse_name (pfile, cppReader_getC (pfile));
5385 ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
5386 ident = pfile->token_buffer + old_written;
5387 pfile->limit = ident;
5389 for (kt = directive_table; kt->length >= 0; kt++)
5391 cppIfStackFrame *temp;
5392 if (ident_length == kt->length &&
5393 cstring_equalPrefix (cstring_fromChars (kt->name),
5394 cstring_fromChars (ident)))
5396 /* If we are asked to return on next directive, do so now. */
5397 if (any)
5399 goto done;
5402 switch (kt->type)
5404 case T_IF:
5405 case T_IFDEF:
5406 case T_IFNDEF:
5407 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5408 temp->next = pfile->if_stack;
5409 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
5410 temp->type = kt->type;
5411 temp->lineno = 0;
5412 temp->if_succeeded = 0;
5413 temp->control_macro = NULL;
5415 pfile->if_stack = temp;
5416 /*@switchbreak@*/ break;
5417 case T_ELSE:
5418 case T_ENDIF:
5419 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
5420 validate_else (pfile,
5421 cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
5422 /*@fallthrough@*/
5423 case T_ELIF:
5424 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5426 cppReader_error (pfile,
5427 message ("Preprocessor command #%s is not within a conditional",
5428 cstring_fromChars (kt->name)));
5429 /*@switchbreak@*/ break;
5431 else if (pfile->if_stack == save_if_stack)
5433 goto done; /* found what we came for */
5435 else
5440 if (kt->type != T_ENDIF)
5442 llassert (pfile->if_stack != NULL);
5444 if (pfile->if_stack->type == T_ELSE)
5446 cppReader_errorLit (pfile,
5447 cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
5450 pfile->if_stack->type = kt->type;
5451 /*@switchbreak@*/ break;
5454 temp = pfile->if_stack;
5455 llassert (temp != NULL);
5456 pfile->if_stack = temp->next;
5457 sfree (temp);
5458 /*@switchbreak@*/ break;
5459 default: ;
5460 /*@-branchstate@*/
5462 /*@=branchstate@*/
5463 break;
5466 /* Don't let erroneous code go by. */
5468 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
5469 && cppReader_isPedantic (pfile))
5471 cppReader_pedwarnLit (pfile,
5472 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
5476 c = cppReader_getC (pfile);
5478 /* We're in the middle of a line. Skip the rest of it. */
5479 for (;;) {
5480 size_t old;
5482 switch (c)
5484 case EOF:
5485 goto done;
5486 case '/': /* possible comment */
5487 c = skip_comment (pfile, NULL);
5488 if (c == EOF)
5489 goto done;
5490 /*@switchbreak@*/ break;
5491 case '\"':
5492 case '\'':
5493 cppReader_forward (pfile, -1);
5494 old = cpplib_getWritten (pfile);
5495 (void) cpplib_getToken (pfile);
5496 cppReader_setWritten (pfile, old);
5497 /*@switchbreak@*/ break;
5498 case '\\':
5499 /* Char after backslash loses its special meaning. */
5500 if (cppReader_peekC (pfile) == '\n')
5502 cppReader_forward (pfile, 1);
5505 /*@switchbreak@*/ break;
5506 case '\n':
5507 goto beg_of_line;
5509 c = cppReader_getC (pfile);
5511 done:
5512 if (CPPOPTIONS (pfile)->output_conditionals) {
5513 static const char end_failed[] = "#endfailed\n";
5514 cppReader_puts (pfile, end_failed, constlen(end_failed));
5515 pfile->lineno++;
5517 pfile->only_seen_white = 1;
5519 parseGotoMark (&line_start_mark, pfile);
5520 parseClearMark (&line_start_mark);
5524 * handle a #else directive. Do this by just continuing processing
5525 * without changing if_stack ; this is so that the error message
5526 * for missing #endif's etc. will point to the original #if. It
5527 * is possible that something different would be better.
5530 static void
5531 do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5532 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5534 if (cppReader_isPedantic (pfile))
5536 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5539 cppReader_skipRestOfLine (pfile);
5541 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
5542 cppReader_errorLit (pfile,
5543 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5544 return;
5545 } else {
5546 /* #ifndef can't have its special treatment for containing the whole file
5547 if it has a #else clause. */
5549 llassert (pfile->if_stack != NULL);
5551 pfile->if_stack->control_macro = 0;
5553 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5555 cpp_setLocation (pfile);
5556 genppllerrorhint (FLG_PREPROC,
5557 message ("Pre-processor directive #else after #else"),
5558 message ("%q: Location of match",
5559 fileloc_unparseRaw (pfile->if_stack->fname,
5560 pfile->if_stack->lineno)));
5563 pfile->if_stack->type = T_ELSE;
5566 if (pfile->if_stack->if_succeeded)
5567 skip_if_group (pfile, FALSE);
5568 else {
5569 ++pfile->if_stack->if_succeeded; /* continue processing input */
5570 output_line_command (pfile, 1, same_file);
5575 * unstack after #endif command
5578 static void
5579 do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5580 const /*@unused@*/ char *buf, const /*@unused@*/ char *limit)
5582 if (cppReader_isPedantic (pfile))
5584 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5587 cppReader_skipRestOfLine (pfile);
5589 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5591 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5593 else
5595 cppIfStackFrame *temp = pfile->if_stack;
5597 llassert (temp != NULL);
5599 pfile->if_stack = temp->next;
5600 if (temp->control_macro != 0)
5602 /* This #endif matched a #ifndef at the start of the file.
5603 See if it is at the end of the file. */
5604 struct parse_marker start_mark;
5605 int c;
5607 parseSetMark (&start_mark, pfile);
5609 for (;;)
5611 cppSkipHspace (pfile);
5612 c = cppReader_getC (pfile);
5614 if (c != '\n')
5615 break;
5618 parseGotoMark (&start_mark, pfile);
5619 parseClearMark (&start_mark);
5621 if (c == EOF)
5623 /* If we get here, this #endif ends a #ifndef
5624 that contains all of the file (aside from whitespace).
5625 Arrange not to include the file again
5626 if the macro that was tested is defined.
5628 Do not do this for the top-level file in a -include or any
5629 file in a -imacros. */
5630 struct file_name_list *ifile = pfile->all_include_files;
5632 for ( ; ifile != NULL; ifile = ifile->next)
5634 if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
5636 ifile->control_macro = temp->control_macro;
5637 break;
5643 sfree (temp);
5644 output_line_command (pfile, 1, same_file);
5648 /* When an #else or #endif is found while skipping failed conditional,
5649 if -pedantic was specified, this is called to warn about text after
5650 the command name. P points to the first char after the command name. */
5652 static void
5653 validate_else (cppReader *pfile, cstring directive)
5655 int c;
5656 cppSkipHspace (pfile);
5657 c = cppReader_peekC (pfile);
5658 if (c != EOF && c != '\n')
5660 cppReader_pedwarn (pfile,
5661 message ("text following `%s' violates ANSI standard", directive));
5666 ** Get the next token, and add it to the text in pfile->token_buffer.
5667 ** Return the kind of token we got.
5670 static enum cpp_token
5671 cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
5673 int c, c2, c3;
5674 size_t old_written = 0;
5675 int start_line, start_column;
5676 enum cpp_token token;
5677 struct cppOptions *opts = CPPOPTIONS (pfile);
5678 cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
5680 get_next:
5681 c = cppReader_getC (pfile);
5682 DPRINTF (("Get next token: %c", c));
5684 if (c == EOF)
5686 handle_eof:
5687 if (cppReader_getBufferSafe (pfile)->seen_eof)
5689 cppBuffer *buf = cppReader_popBuffer (pfile);
5691 if (buf != cppReader_nullBuffer (pfile))
5693 goto get_next;
5695 else
5697 return CPP_EOF;
5700 else
5702 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
5703 cppReader_getBufferSafe (pfile)->seen_eof = TRUE;
5705 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
5706 && next_buf != cppReader_nullBuffer (pfile))
5708 /* We're about to return from an #include file.
5709 Emit #line information now (as part of the CPP_POP) result.
5710 But the #line refers to the file we will pop to. */
5711 cppBuffer *cur_buffer = CPPBUFFER (pfile);
5712 CPPBUFFER (pfile) = next_buf;
5713 pfile->input_stack_listing_current = FALSE;
5714 output_line_command (pfile, 0, leave_file);
5715 CPPBUFFER (pfile) = cur_buffer;
5717 return CPP_POP;
5720 else
5722 long newlines;
5723 struct parse_marker start_mark;
5725 switch (c)
5727 case '/':
5728 if (cppReader_peekC (pfile) == '=')
5730 goto op2;
5733 if (opts->put_out_comments)
5735 parseSetMark (&start_mark, pfile);
5738 newlines = 0;
5739 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
5740 &start_line, &start_column);
5741 c = skip_comment (pfile, &newlines);
5742 DPRINTF (("c = %c", c));
5743 if (opts->put_out_comments && (c == '/' || c == EOF))
5745 assertSet (&start_mark);
5746 parseClearMark (&start_mark);
5749 if (c == '/')
5750 goto randomchar;
5751 if (c == EOF)
5753 cppReader_errorWithLine (pfile, start_line, start_column,
5754 cstring_makeLiteral ("Unterminated comment"));
5755 goto handle_eof;
5757 /* Comments are equivalent to spaces.
5758 For -traditional, a comment is equivalent to nothing. */
5760 if (opts->put_out_comments)
5762 enum cpp_token res;
5764 assertSet (&start_mark);
5765 res = cpp_handleComment (pfile, &start_mark);
5766 pfile->lineno += newlines;
5767 return res;
5769 else if (cppReader_isTraditional (pfile))
5771 return CPP_COMMENT;
5773 else
5775 cpplib_reserve(pfile, 1);
5776 cppReader_putCharQ (pfile, ' ');
5777 return CPP_HSPACE;
5780 case '#':
5781 if (!pfile->only_seen_white)
5783 goto randomchar;
5786 if (cppReader_handleDirective (pfile))
5788 return CPP_DIRECTIVE;
5791 pfile->only_seen_white = 0;
5792 return CPP_OTHER;
5794 case '\"':
5795 case '\'':
5796 /* A single quoted string is treated like a double -- some
5797 programs (e.g., troff) are perverse this way */
5798 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
5799 &start_line, &start_column);
5800 old_written = cpplib_getWritten (pfile);
5801 string:
5802 DPRINTF (("Reading string: %c", c));
5803 cppReader_putChar (pfile, (char) c);
5804 while (TRUE)
5806 /* evans-2003-06-07
5807 ** Because of ISO8859-1 characters in string literals, we need a special test here.
5810 if (cppReader_reachedEOF (pfile))
5813 DPRINTF (("Matches EOF!"));
5814 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
5816 /* try harder: this string crosses a macro expansion
5817 boundary. This can happen naturally if -traditional.
5818 Otherwise, only -D can make a macro with an unmatched
5819 quote. */
5820 cppBuffer *next_buf
5821 = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
5822 (*cppReader_getBufferSafe (pfile)->cleanup)
5823 (cppReader_getBufferSafe (pfile), pfile);
5824 CPPBUFFER (pfile) = next_buf;
5825 continue;
5828 if (!cppReader_isTraditional (pfile))
5830 cpp_setLocation (pfile);
5832 setLine (long_toInt (start_line));
5833 setColumn (long_toInt (start_column));
5835 if (pfile->multiline_string_line != long_toInt (start_line)
5836 && pfile->multiline_string_line != 0)
5838 genppllerrorhint
5839 (FLG_PREPROC,
5840 message ("Unterminated string or character constant"),
5841 message ("%q: Possible real start of unterminated constant",
5842 fileloc_unparseRaw
5843 (fileloc_filename (g_currentloc),
5844 pfile->multiline_string_line)));
5845 pfile->multiline_string_line = 0;
5847 else
5849 genppllerror
5850 (FLG_PREPROC,
5851 message ("Unterminated string or character constant"));
5854 /*@loopbreak@*/ break;
5856 else
5858 int cc = cppReader_getC (pfile);
5859 DPRINTF (("cc: %c [%d]", cc, cc));
5860 DPRINTF (("putting char: %c", (char) cc));
5861 cppReader_putChar (pfile, (char) cc);
5862 switch (cc)
5864 case '\n':
5865 /* Traditionally, end of line ends a string constant with
5866 no error. So exit the loop and record the new line. */
5867 if (cppReader_isTraditional (pfile))
5868 goto while2end;
5869 if (c == '\'')
5871 goto while2end;
5873 if (cppReader_isPedantic (pfile)
5874 && pfile->multiline_string_line == 0)
5876 cppReader_pedwarnWithLine
5877 (pfile, long_toInt (start_line),
5878 long_toInt (start_column),
5879 cstring_makeLiteral ("String constant runs past end of line"));
5881 if (pfile->multiline_string_line == 0)
5883 pfile->multiline_string_line = start_line;
5886 /*@switchbreak@*/ break;
5888 case '\\':
5889 cc = cppReader_getC (pfile);
5890 if (cc == '\n')
5892 /* Backslash newline is replaced by nothing at all. */
5893 pfile->lineno++; /* 2003-11-03: AMiller suggested adding this, but
5894 its not clear why it is needed. */
5895 cppReader_adjustWritten (pfile, -1);
5896 pfile->lineno++;
5898 else
5900 /* ANSI stupidly requires that in \\ the second \
5901 is *not* prevented from combining with a newline. */
5902 NEWLINE_FIX1(cc);
5903 if (cc != EOF)
5904 cppReader_putChar (pfile, (char) cc);
5906 /*@switchbreak@*/ break;
5908 case '\"':
5909 case '\'':
5910 if (cc == c)
5911 goto while2end;
5912 /*@switchbreak@*/ break;
5916 while2end:
5917 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
5918 cpplib_getPWritten (pfile));
5919 pfile->only_seen_white = 0;
5920 return c == '\'' ? CPP_CHAR : CPP_STRING;
5922 case '$':
5923 if (!opts->dollars_in_ident)
5924 goto randomchar;
5925 goto letter;
5927 case ':':
5928 goto randomchar;
5930 case '&':
5931 case '+':
5932 case '|':
5933 NEWLINE_FIX;
5934 c2 = cppReader_peekC (pfile);
5935 if (c2 == c || c2 == '=')
5936 goto op2;
5937 goto randomchar;
5939 case '*':
5940 case '!':
5941 case '%':
5942 case '=':
5943 case '^':
5944 NEWLINE_FIX;
5945 if (cppReader_peekC (pfile) == '=')
5946 goto op2;
5947 goto randomchar;
5949 case '-':
5950 NEWLINE_FIX;
5951 c2 = cppReader_peekC (pfile);
5952 if (c2 == '-' || c2 == '=' || c2 == '>')
5953 goto op2;
5954 goto randomchar;
5956 case '<':
5957 if (pfile->parsing_include_directive)
5959 for (;;)
5961 cppReader_putChar (pfile, (char) c);
5962 if (c == '>')
5963 /*@loopbreak@*/ break;
5964 c = cppReader_getC (pfile);
5965 NEWLINE_FIX1 (c);
5966 if (c == '\n' || c == EOF)
5968 cppReader_errorLit (pfile,
5969 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
5970 /*@loopbreak@*/ break;
5973 return CPP_STRING;
5975 /*@fallthrough@*/
5976 case '>':
5977 NEWLINE_FIX;
5978 c2 = cppReader_peekC (pfile);
5979 if (c2 == '=')
5980 goto op2;
5981 if (c2 != c)
5982 goto randomchar;
5983 cppReader_forward (pfile, 1);
5984 cpplib_reserve (pfile, 4);
5985 cppReader_putChar (pfile, (char) c);
5986 cppReader_putChar (pfile, (char) c2);
5987 NEWLINE_FIX;
5988 c3 = cppReader_peekC (pfile);
5989 if (c3 == '=')
5990 cppReader_putCharQ (pfile, (char) cppReader_getC (pfile));
5991 cppReader_nullTerminateQ (pfile);
5992 pfile->only_seen_white = 0;
5993 return CPP_OTHER;
5995 case '@':
5996 DPRINTF (("Macro @!"));
5997 if (cppReader_getBufferSafe (pfile)->has_escapes)
5999 c = cppReader_getC (pfile);
6000 DPRINTF (("got c: %c", c));
6001 if (c == '-')
6003 if (pfile->output_escapes)
6004 cppReader_puts (pfile, "@-", 2);
6005 parse_name (pfile, cppReader_getC (pfile));
6006 return CPP_NAME;
6008 else if (is_space [c])
6010 cpplib_reserve (pfile, 2);
6011 if (pfile->output_escapes)
6012 cppReader_putCharQ (pfile, '@');
6013 cppReader_putCharQ (pfile, (char) c);
6014 return CPP_HSPACE;
6016 else
6021 if (pfile->output_escapes)
6023 cppReader_puts (pfile, "@@", 2);
6024 return CPP_OTHER;
6026 goto randomchar;
6027 case '.':
6028 NEWLINE_FIX;
6029 c2 = cppReader_peekC (pfile);
6030 if (isdigit(c2))
6032 cpplib_reserve(pfile, 2);
6033 cppReader_putCharQ (pfile, '.');
6034 c = cppReader_getC (pfile);
6035 goto number;
6038 /* FIXME - misses the case "..\\\n." */
6039 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
6041 cpplib_reserve(pfile, 4);
6042 cppReader_putCharQ (pfile, '.');
6043 cppReader_putCharQ (pfile, '.');
6044 cppReader_putCharQ (pfile, '.');
6045 cppReader_forward (pfile, 2);
6046 cppReader_nullTerminateQ (pfile);
6047 pfile->only_seen_white = 0;
6048 return CPP_3DOTS;
6050 goto randomchar;
6051 op2:
6052 token = CPP_OTHER;
6053 pfile->only_seen_white = 0;
6054 op2any: /* jumped to for \ continuations */
6055 cpplib_reserve(pfile, 3);
6056 cppReader_putCharQ (pfile, (char) c);
6058 /* evans 2003-08-24: This is a hack to fix line output for \
6059 continuations. Someday I really should get a decent pre-processor!
6062 if (c == '\\') {
6063 (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */
6064 } else {
6065 cppReader_putCharQ (pfile, (char) cppReader_getC (pfile));
6068 cppReader_nullTerminateQ (pfile);
6069 return token;
6071 case 'L':
6072 NEWLINE_FIX;
6073 c2 = cppReader_peekC (pfile);
6074 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6076 cppReader_putChar (pfile, (char) c);
6077 c = cppReader_getC (pfile);
6078 goto string;
6080 goto letter;
6082 case '0': case '1': case '2': case '3': case '4':
6083 case '5': case '6': case '7': case '8': case '9':
6084 number:
6085 c2 = '.';
6086 for (;;)
6088 cpplib_reserve (pfile, 2);
6089 cppReader_putCharQ (pfile, (char) c);
6090 NEWLINE_FIX;
6091 c = cppReader_peekC (pfile);
6092 if (c == EOF)
6093 /*@loopbreak@*/ break;
6094 if (!is_idchar[c] && c != '.'
6095 && ((c2 != 'e' && c2 != 'E'
6096 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6097 || (c != '+' && c != '-')))
6098 /*@loopbreak@*/ break;
6099 cppReader_forward (pfile, 1);
6100 c2= c;
6103 cppReader_nullTerminateQ (pfile);
6104 pfile->only_seen_white = 0;
6105 return CPP_NUMBER;
6107 case '_':
6108 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
6109 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
6110 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
6111 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
6112 case 'y': case 'z':
6113 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
6114 case 'G': case 'H': case 'I': case 'J': case 'K':
6115 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
6116 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6117 case 'Y': case 'Z':
6118 letter:
6120 hashNode hp;
6121 char *ident;
6122 size_t before_name_written = cpplib_getWritten (pfile);
6123 size_t ident_len;
6124 parse_name (pfile, c);
6125 pfile->only_seen_white = 0;
6127 if (pfile->no_macro_expand)
6129 DPRINTF (("Not expanding: %s", pfile->token_buffer));
6130 return CPP_NAME;
6133 ident = pfile->token_buffer + before_name_written;
6134 DPRINTF (("Ident: %s", ident));
6136 ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
6138 hp = cpphash_lookupExpand (ident, ident_len, -1, forceExpand);
6140 if (hp == NULL)
6142 DPRINTF (("No expand: %s %d", ident, ident_len));
6143 return CPP_NAME;
6146 if (hp->type == T_DISABLED)
6148 DPRINTF (("Disabled!"));
6150 if (pfile->output_escapes)
6151 { /* Return "@-IDENT", followed by '\0'. */
6152 int i;
6153 cpplib_reserve (pfile, 3);
6154 ident = pfile->token_buffer + before_name_written;
6155 cppReader_adjustWritten (pfile, 2);
6157 for (i = size_toInt (ident_len); i >= 0; i--)
6159 ident[i+2] = ident[i];
6162 ident[0] = '@';
6163 ident[1] = '-';
6165 return CPP_NAME;
6169 ** If macro wants an arglist, verify that a '(' follows.
6170 ** first skip all whitespace, copying it to the output
6171 ** after the macro name. Then, if there is no '(',
6172 ** decide this is not a macro call and leave things that way.
6175 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6177 struct parse_marker macro_mark;
6178 int is_macro_call;
6180 DPRINTF (("Arglist macro!"));
6183 ** evans 2002-07-03: Moved this here (from below).
6184 ** This bug caused necessary whitespace to be lost
6185 ** when parsing parameterized macros without parameters.
6188 parseSetMark (&macro_mark, pfile);
6190 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6192 cppBuffer *next_buf;
6193 cppSkipHspace (pfile);
6194 if (cppReader_peekC (pfile) != EOF)
6196 DPRINTF (("Peeking!"));
6197 /*@loopbreak@*/ break;
6200 next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6201 (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
6202 CPPBUFFER (pfile) = next_buf;
6205 /* parseSetMark (&macro_mark, pfile); */
6207 for (;;)
6209 cppSkipHspace (pfile);
6210 c = cppReader_peekC (pfile);
6211 DPRINTF (("c: %c", c));
6212 is_macro_call = c == '(';
6213 if (c != '\n')
6214 /*@loopbreak@*/ break;
6215 cppReader_forward (pfile, 1);
6218 if (!is_macro_call)
6220 parseGotoMark (&macro_mark, pfile);
6223 parseClearMark (&macro_mark);
6225 if (!is_macro_call)
6227 DPRINTF (("not macro call!"));
6228 return CPP_NAME;
6232 /* This is now known to be a macro call. */
6234 /* it might not actually be a macro. */
6235 if (hp->type != T_MACRO)
6237 size_t xbuf_len;
6238 char *xbuf;
6240 cppReader_setWritten (pfile, before_name_written);
6241 special_symbol (hp, pfile);
6242 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
6243 xbuf = (char *) dmalloc (xbuf_len + 1);
6244 cppReader_setWritten (pfile, before_name_written);
6245 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
6246 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6248 else
6251 ** Expand the macro, reading arguments as needed,
6252 ** and push the expansion on the input stack.
6255 cpplib_macroExpand (pfile, hp);
6256 cppReader_setWritten (pfile, before_name_written);
6259 /* An extra "@ " is added to the end of a macro expansion
6260 to prevent accidental token pasting. We prefer to avoid
6261 unneeded extra spaces (for the sake of cpp-using tools like
6262 imake). Here we remove the space if it is safe to do so. */
6264 llassert (pfile->buffer->rlimit != NULL);
6266 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6267 && pfile->buffer->rlimit[-2] == '@'
6268 && pfile->buffer->rlimit[-1] == ' ')
6270 int c1 = pfile->buffer->rlimit[-3];
6271 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
6273 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6274 pfile->buffer->rlimit -= 2;
6277 goto get_next;
6280 case ' ': case '\t': case '\v': case '\r':
6281 for (;;)
6283 cppReader_putChar (pfile, (char) c);
6284 c = cppReader_peekC (pfile);
6285 if (c == EOF || !is_hor_space[c])
6286 /*@loopbreak@*/ break;
6287 cppReader_forward (pfile, 1);
6289 return CPP_HSPACE;
6291 case '\\':
6292 c2 = cppReader_peekC (pfile);
6293 /* allow other stuff here if a flag is set? */
6294 DPRINTF (("Got continuation!"));
6295 if (c2 != '\n')
6296 goto randomchar;
6297 token = CPP_HSPACE;
6298 goto op2any;
6300 case '\n':
6301 cppReader_putChar (pfile, (char) c);
6302 if (pfile->only_seen_white == 0)
6303 pfile->only_seen_white = 1;
6304 pfile->lineno++;
6305 output_line_command (pfile, 1, same_file);
6306 return CPP_VSPACE;
6308 case '(': token = CPP_LPAREN; goto char1;
6309 case ')': token = CPP_RPAREN; goto char1;
6310 case '{': token = CPP_LBRACE; goto char1;
6311 case '}': token = CPP_RBRACE; goto char1;
6312 case ',': token = CPP_COMMA; goto char1;
6313 case ';': token = CPP_SEMICOLON; goto char1;
6315 randomchar:
6316 default:
6317 token = CPP_OTHER;
6318 char1:
6319 pfile->only_seen_white = 0;
6320 cppReader_putChar (pfile, (char) c);
6321 return token;
6325 /*@notreached@*/
6326 BADBRANCH;
6329 enum cpp_token
6330 cpplib_getToken (cppReader *pfile)
6332 return cpplib_getTokenAux (pfile, FALSE);
6335 enum cpp_token
6336 cpplib_getTokenForceExpand (cppReader *pfile)
6338 return cpplib_getTokenAux (pfile, TRUE);
6341 /* Parse an identifier starting with C. */
6343 void
6344 parse_name (cppReader *pfile, int c)
6346 for (;;)
6348 if (!is_idchar[c])
6350 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6352 cppReader_forward (pfile, 2);
6353 continue;
6356 cppReader_forward (pfile, -1);
6357 break;
6360 if (c == '$' && cppReader_isPedantic (pfile))
6362 cppReader_pedwarnLit (pfile,
6363 cstring_makeLiteralTemp ("`$' in identifier"));
6366 cpplib_reserve(pfile, 2); /* One more for final NUL. */
6367 cppReader_putCharQ (pfile, (char) c);
6368 c = cppReader_getC (pfile);
6370 if (c == EOF)
6371 break;
6374 cppReader_nullTerminateQ (pfile);
6377 /* The file_name_map structure holds a mapping of file names for a
6378 particular directory. This mapping is read from the file named
6379 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
6380 map filenames on a file system with severe filename restrictions,
6381 such as DOS. The format of the file name map file is just a series
6382 of lines with two tokens on each line. The first token is the name
6383 to map, and the second token is the actual name to use. */
6385 struct file_name_map
6387 struct file_name_map *map_next;
6388 cstring map_from;
6389 cstring map_to;
6392 /*@constant observer char *FILE_NAME_MAP_FILE*/
6393 #define FILE_NAME_MAP_FILE "header.gcc"
6395 /* Read a space delimited string of unlimited length from a stdio
6396 file. */
6398 static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6400 char *alloc, *set;
6401 size_t len;
6403 len = 20;
6404 set = alloc = dmalloc (len + 1);
6406 if (!is_space[ch])
6408 *set++ = (char) ch;
6409 while ((ch = getc (f)) != EOF && !is_space[ch])
6411 if (set - alloc == size_toInt (len))
6413 len *= 2;
6414 alloc = drealloc (alloc, len + 1);
6415 set = alloc + len / 2;
6416 /*@-branchstate@*/ }
6418 *set++ = (char) ch;
6419 } /*@=branchstate@*/
6421 *set = '\0';
6422 check (ungetc (ch, f) != EOF);
6424 return cstring_fromChars (alloc);
6427 /* This structure holds a linked list of file name maps, one per directory. */
6429 struct file_name_map_list
6431 /*@only@*/ struct file_name_map_list *map_list_next;
6432 /*@only@*/ cstring map_list_name;
6433 /*@null@*/ struct file_name_map *map_list_map;
6436 /* Read the file name map file for DIRNAME. */
6438 static struct file_name_map *
6439 read_name_map (cppReader *pfile, cstring dirname)
6441 struct file_name_map_list *map_list_ptr;
6442 cstring name;
6443 FILE *f;
6445 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6446 map_list_ptr != NULL;
6447 map_list_ptr = map_list_ptr->map_list_next)
6449 if (cstring_equal (map_list_ptr->map_list_name, dirname))
6451 return map_list_ptr->map_list_map;
6455 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6456 map_list_ptr->map_list_name = cstring_copy (dirname);
6457 map_list_ptr->map_list_map = NULL;
6459 name = cstring_copy (dirname);
6461 if (cstring_length (dirname) > 0)
6463 name = cstring_appendChar (name, CONNECTCHAR);
6466 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6468 f = fileTable_openReadFile (context_fileTable (), name);
6469 cstring_free (name);
6471 if (f == NULL)
6473 map_list_ptr->map_list_map = NULL;
6475 else
6477 int ch;
6479 while ((ch = getc (f)) != EOF)
6481 cstring from, to;
6482 struct file_name_map *ptr;
6484 if (is_space[ch])
6486 continue;
6489 from = read_filename_string (ch, f);
6490 while ((ch = getc (f)) != EOF && is_hor_space[ch])
6495 to = read_filename_string (ch, f);
6497 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6498 ptr->map_from = from;
6500 /* Make the real filename absolute. */
6501 if (cstring_length (to) > 1
6502 && osd_isConnectChar (cstring_firstChar (to)))
6504 ptr->map_to = to;
6506 else
6508 ptr->map_to = cstring_copy (dirname);
6509 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6510 ptr->map_to = cstring_concatFree (ptr->map_to, to);
6513 ptr->map_next = map_list_ptr->map_list_map;
6514 map_list_ptr->map_list_map = ptr;
6516 while ((ch = getc (f)) != '\n')
6518 if (ch == EOF)
6520 /*@innerbreak@*/ break;
6525 assertSet (map_list_ptr->map_list_map);
6526 check (fileTable_closeFile (context_fileTable (),f) == 0);
6529 map_list_ptr->map_list_next = pfile->opts->map_list;
6530 pfile->opts->map_list = map_list_ptr;
6532 return map_list_ptr->map_list_map;
6535 /* Try to open include file FILENAME. SEARCHPTR is the directory
6536 being tried from the include file search path. This function maps
6537 filenames on file systems based on information read by
6538 read_name_map. */
6540 static int
6541 open_include_file (cppReader *pfile,
6542 cstring fname,
6543 struct file_name_list *searchptr)
6545 char *filename = cstring_toCharsSafe (fname);
6546 struct file_name_map *map;
6547 char *from;
6548 char *p, *dir;
6550 cstring_markOwned (fname);
6552 cpp_setLocation (pfile);
6554 if (context_getFlag (FLG_NEVERINCLUDE))
6556 if (fileLib_isHeader (fname))
6558 return SKIP_INCLUDE;
6562 if ((searchptr != NULL) && ! searchptr->got_name_map)
6564 searchptr->name_map = read_name_map (pfile,
6565 !cstring_isEmpty (searchptr->fname)
6566 ? searchptr->fname :
6567 cstring_makeLiteralTemp ("."));
6568 searchptr->got_name_map = TRUE;
6571 /* First check the mapping for the directory we are using. */
6573 if ((searchptr != NULL)
6574 && (searchptr->name_map != NULL))
6576 from = filename;
6578 if (!cstring_isEmpty (searchptr->fname))
6580 from += cstring_length (searchptr->fname) + 1;
6583 for (map = searchptr->name_map;
6584 map != NULL;
6585 map = map->map_next)
6587 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6589 if (cpp_skipIncludeFile (map->map_to))
6591 return SKIP_INCLUDE;
6593 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6599 ** Try to find a mapping file for the particular directory we are
6600 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6601 ** in /usr/include/header.gcc and look up types.h in
6602 ** /usr/include/sys/header.gcc.
6605 p = strrchr (filename, CONNECTCHAR);
6606 if (p == NULL)
6608 p = filename;
6611 if ((searchptr != NULL)
6612 && (cstring_isDefined (searchptr->fname))
6613 && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
6614 && !strncmp (cstring_toCharsSafe (searchptr->fname),
6615 filename,
6616 size_fromInt (p - filename)))
6618 /* filename is in SEARCHPTR, which we've already checked. */
6619 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6621 return SKIP_INCLUDE;
6623 return cpp_openIncludeFile (filename);
6626 if (p == filename)
6628 dir = mstring_copy (".");
6629 from = filename;
6631 else
6633 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
6634 memcpy (dir, filename, size_fromInt (p - filename));
6635 dir[p - filename] = '\0';
6636 from = p + 1;
6639 for (map = read_name_map (pfile, cstring_fromChars (dir));
6640 map != NULL;
6641 map = map->map_next)
6643 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6645 sfree (dir);
6646 if (cpp_skipIncludeFile (map->map_to))
6648 return SKIP_INCLUDE;
6650 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6654 sfree (dir);
6656 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6658 return SKIP_INCLUDE;
6660 return cpp_openIncludeFile (filename);
6663 /* Process the contents of include file FNAME, already open on descriptor F,
6664 with output to OP.
6665 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
6666 "system" include directories (as decided by the `is_system_include'
6667 function above).
6668 DIRPTR is the link in the dir path through which this file was found,
6669 or 0 if the file name was absolute or via the current directory.
6670 Return 1 on success, 0 on failure.
6672 The caller is responsible for the cppReader_pushBuffer. */
6674 static int
6675 finclude (cppReader *pfile, int f,
6676 cstring fname,
6677 bool system_header_p,
6678 /*@dependent@*/ struct file_name_list *dirptr)
6680 filemode mode;
6681 size_t size;
6682 long i;
6683 int length = 0;
6684 cppBuffer *fp; /* For input stack frame */
6686 if (osd_file_mode_and_size (f, &mode, &size) < 0)
6688 cppReader_perrorWithName (pfile, fname);
6689 check (osd_close (f) == 0);
6690 (void) cppReader_popBuffer (pfile);
6691 /*@-mustfree@*/
6692 return 0;
6693 /*@=mustfree@*/
6696 fp = cppReader_getBufferSafe (pfile);
6698 /*@-temptrans@*/ /* fname shouldn't really be temp */
6699 fp->nominal_fname = fp->fname = fname;
6700 /*@=temptrans@*/
6702 fp->dir = dirptr;
6703 fp->system_header_p = system_header_p;
6704 fp->lineno = 1;
6705 fp->colno = 1;
6706 fp->cleanup = cppReader_fileCleanup;
6708 if (mode == OSD_MODEREGULAR)
6710 sfree (fp->buf);
6711 fp->buf = (char *) dmalloc (size + 2);
6712 fp->alimit = fp->buf + size + 2;
6713 fp->cur = fp->buf;
6715 /* Read the file contents, knowing that size is an upper bound
6716 on the number of bytes we can read. */
6717 length = osd_readSafe (f, fp->buf, size_toInt (size));
6718 fp->rlimit = fp->buf + length;
6719 if (length < 0) goto nope;
6721 else if (mode == OSD_MODEDIRECTORY)
6723 cppReader_error (pfile,
6724 message ("Directory specified where file is expected: %s", fname));
6725 check (osd_close (f) == 0);
6726 return 0;
6728 else
6731 ** Cannot count its file size before reading.
6732 ** First read the entire file into heap and
6733 ** copy them into buffer on stack.
6736 size_t bsize = 2000;
6738 size = 0;
6740 sfree (fp->buf);
6741 fp->buf = (char *) dmalloc (bsize + 2);
6743 for (;;) {
6744 i = osd_readSafe (f, fp->buf + size, size_toInt (bsize - size));
6746 if (i < 0)
6747 goto nope; /* error! */
6748 size += i;
6750 if (size != bsize)
6752 break; /* End of file */
6755 bsize *= 2;
6756 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
6759 fp->cur = fp->buf;
6760 length = size_toInt (size);
6763 if ((length > 0 && fp->buf[length - 1] != '\n')
6764 /* Backslash-newline at end is not good enough. */
6765 || (length > 1 && fp->buf[length - 2] == '\\')) {
6766 fp->buf[length++] = '\n';
6769 fp->buf[length] = '\0';
6770 fp->rlimit = fp->buf + length;
6772 /* Close descriptor now, so nesting does not use lots of descriptors. */
6773 check (osd_close (f) == 0);
6775 /* Must do this before calling trigraph_pcp, so that the correct file name
6776 will be printed in warning messages. */
6778 pfile->input_stack_listing_current = FALSE;
6779 return 1;
6781 nope:
6783 cppReader_perrorWithName (pfile, fname);
6784 check (osd_close (f) == 0);
6785 sfree (fp->buf);
6786 return 1;
6789 static void
6790 cpplib_init (/*@out@*/ cppReader *pfile)
6792 memset ((char *) pfile, 0, sizeof (*pfile));
6794 pfile->get_token = cpplib_getToken;
6795 pfile->token_buffer_size = 200;
6796 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
6797 pfile->all_include_files = NULL;
6799 assertSet (pfile);
6801 cppReader_setWritten (pfile, 0);
6803 pfile->system_include_depth = 0;
6804 pfile->timebuf = NULL;
6805 pfile->only_seen_white = 1;
6807 pfile->buffer = cppReader_nullBuffer (pfile);
6809 pfile->opts = (struct cppOptions *) dmalloc (sizeof (struct cppOptions));
6812 void
6813 cppReader_finish (/*@unused@*/ cppReader *pfile)
6818 /* Free resources used by PFILE.
6819 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
6821 void
6822 cppCleanup (/*@special@*/ cppReader *pfile)
6823 /*@uses pfile@*/
6824 /*@releases pfile@*/
6826 DPRINTF (("cppCleanup!"));
6828 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
6830 (void) cppReader_popBuffer (pfile);
6833 if (pfile->token_buffer != NULL)
6835 sfree (pfile->token_buffer);
6836 pfile->token_buffer = NULL;
6839 while (pfile->if_stack != NULL)
6841 cppIfStackFrame *temp = pfile->if_stack;
6842 pfile->if_stack = temp->next;
6843 sfree (temp);
6846 while (pfile->all_include_files != NULL)
6848 struct file_name_list *temp = pfile->all_include_files;
6849 pfile->all_include_files = temp->next;
6850 /*@-dependenttrans@*/
6851 cstring_free (temp->fname);
6852 /*@=dependenttrans@*/
6853 sfree (temp);
6856 /* evans 2002-07-12 */
6857 while (pfile->opts->map_list != NULL)
6859 struct file_name_map_list *temp = pfile->opts->map_list;
6860 pfile->opts->map_list = pfile->opts->map_list->map_list_next;
6861 cstring_free (temp->map_list_name);
6862 sfree (temp);
6865 while (pfile->opts->include != NULL)
6867 struct file_name_list *temp = pfile->opts->include;
6868 pfile->opts->include = pfile->opts->include->next;
6869 /* cstring_free (temp->fname); */
6870 sfree (temp);
6873 sfree (pfile->opts);
6874 pfile->opts = NULL;
6875 cpphash_cleanup ();
6878 /* Initialize PMARK to remember the current position of PFILE. */
6880 void
6881 parseSetMark (struct parse_marker *pmark, cppReader *pfile)
6883 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
6885 pmark->next = pbuf->marks;
6886 /*@-temptrans@*/
6887 pbuf->marks = pmark;
6888 /*@=temptrans@*/
6890 pmark->buf = pbuf;
6891 pmark->position = pbuf->cur - pbuf->buf;
6892 DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
6895 /* Cleanup PMARK - we no longer need it. */
6897 void parseClearMark (struct parse_marker *pmark)
6899 struct parse_marker **pp = &pmark->buf->marks;
6901 for (; ; pp = &(*pp)->next)
6903 llassert (*pp != NULL);
6904 if (*pp == pmark) break;
6907 *pp = pmark->next;
6910 /* Backup the current position of PFILE to that saved in PMARK. */
6912 void
6913 parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
6915 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
6917 if (pbuf != pmark->buf)
6919 cpp_setLocation (pfile);
6920 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
6923 llassert (pbuf->buf != NULL);
6924 pbuf->cur = pbuf->buf + pmark->position;
6925 DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
6928 /* Reset PMARK to point to the current position of PFILE. (Same
6929 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
6931 static void
6932 parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
6934 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
6936 if (pbuf != pmark->buf)
6938 cpp_setLocation (pfile);
6939 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
6942 pmark->position = pbuf->cur - pbuf->buf;
6943 DPRINTF (("move mark: %d", pmark->position));
6946 static void
6947 handleCmdFlag (cppReader *pfile, /* const */ char *arg)
6949 llassert (CPPOPTIONS (pfile) != NULL);
6950 llassert (arg[0] == 'D' || arg[0] == 'U' || arg[0] == 'I');
6952 if (arg[0] == 'D') {
6953 cppReader_define (pfile, arg+1);
6954 } else if (arg[0] == 'U') {
6955 size_t sym_length;
6956 hashNode hp;
6958 sym_length = identifier_length (arg+1);
6959 if (!macro_name_is_valid (arg+1, sym_length))
6961 cppReader_error (pfile, invalid_macro_message (arg+1, sym_length));
6963 else
6965 while ((hp = cpphash_lookup (arg+1, sym_length, -1)) != NULL)
6967 cpphash_deleteMacro (hp);
6970 } else /* if (arg[0] == 'I') */ {
6971 if (mstring_equal (arg+1, "-")) { /* Special handle for "-I-". */
6972 CPPOPTIONS (pfile)->ignore_srcdir = TRUE;
6973 CPPOPTIONS (pfile)->first_bracket_include = NULL;
6974 } else {
6975 cppReader_appendDirIncludeChain (pfile, arg+1, FALSE);
6980 void cpplib_initializeReader (cppReader *pfile, cstringList *cmdArgs)
6982 struct cppOptions *opts;
6984 cpplib_init (pfile);
6986 opts = CPPOPTIONS (pfile);
6987 cppOptions_init (opts);
6989 /* Now that dollars_in_ident is known, initialize is_idchar. */
6990 initialize_char_syntax (opts);
6992 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
6993 and option processing. */
6994 initialize_builtins (pfile);
6996 /* Do standard #defines and assertions
6997 that identify system and machine type. */
6998 if (!opts->inhibit_predefs) {
6999 char *p, *r;
7000 r = p = (char *) dmalloc (strlen (predefs) + 1);
7001 strcpy (p, predefs);
7003 while (*p)
7005 char *q;
7007 SKIP_WHITE_SPACE (p);
7009 /* expect -D options. */
7010 if (p[0] != '-' || p[1] != 'D')
7012 llfatalbug (message ("Unexpected predefine option %s",
7013 cstring_fromChars(p)));
7016 q = &p[2];
7017 while (*p && !is_hor_space [(int) *p])
7019 p++;
7022 if (*p != 0)
7024 *p++= 0;
7027 if (opts->debug_output)
7029 output_line_command (pfile, 0, same_file);
7032 cppReader_define (pfile, q);
7034 SKIP_WHITE_SPACE (p);
7037 sfree (r);
7040 /* Process user -D, -U and -I options, if any. */
7041 DPRINTF (("Pass through: %s", cstringSList_unparse (*cmdArgs)));
7042 cstringList_elements (*cmdArgs, thisarg)
7044 handleCmdFlag (pfile, cstring_toCharsSafe (thisarg));
7046 end_cstringList_elements;
7048 pfile->done_initializing = TRUE;
7050 cppReader_appendPathListIncludeChain(pfile,
7051 # if defined(WIN32) || defined(OS2)
7052 getenv ("INCLUDE"),
7053 # else
7054 getenv ("CPATH"),
7055 # endif
7056 FALSE);
7058 /* Unless -nostdinc,
7059 tack on the standard include file dirs to the specified list */
7060 if (!opts->no_standard_includes)
7062 cppReader_appendIncludeChain (pfile, opts->before_system,
7063 opts->last_before_system, TRUE);
7065 cppReader_appendPathListIncludeChain(pfile, getenv ("C_INCLUDE_PATH"), TRUE);
7067 cppReader_appendPathListIncludeChain(pfile, context_getString (FLG_SYSTEMDIRS), TRUE);
7069 /* Tack the after_include chain at the end of the include chain. */
7070 cppReader_appendIncludeChain (pfile, opts->after_include,
7071 opts->last_after_include, TRUE);
7074 /* With -v, print the list of dirs to search. */
7075 if (opts->verbose)
7077 struct file_name_list *p;
7078 fprintf (stderr, "#include \"...\" search starts here:\n");
7080 for (p = opts->include; p != NULL; p = p->next) {
7081 if (p == opts->first_bracket_include)
7082 fprintf (stderr, "#include <...> search starts here:\n");
7083 if (p == opts->first_system_include)
7084 fprintf (stderr, "system search starts here:\n");
7085 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7087 fprintf (stderr, "End of search list.\n");
7091 int cppReader_startProcess (cppReader *pfile, cstring fname)
7093 cppBuffer *fp;
7094 int f;
7095 struct cppOptions *opts = CPPOPTIONS (pfile);
7097 fp = cppReader_pushBuffer (pfile, NULL, 0);
7099 if (fp == NULL)
7101 return 0;
7104 if (opts->in_fname == NULL)
7106 opts->in_fname = cstring_makeLiteralTemp ("");
7109 fp->fname = opts->in_fname;
7110 fp->nominal_fname = fp->fname;
7111 fp->lineno = 0;
7113 /* Copy the entire contents of the main input file into
7114 the stacked input buffer previously allocated for it. */
7116 if (cstring_isEmpty (fname))
7118 fname = cstring_makeLiteralTemp ("");
7119 f = 0;
7121 else if ((f = osd_openForReading (cstring_toCharsSafe (fname))) < 0)
7123 cppReader_error (pfile,
7124 message ("Error opening %s for reading: %s",
7125 fname, lldecodeerror (errno)));
7127 return 0;
7129 else
7134 if (finclude (pfile, f, fname, FALSE, NULL))
7136 output_line_command (pfile, 0, same_file);
7139 return 1;
7142 static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7144 return pfile->buffer;
7147 /*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7149 llassert (pfile->buffer != NULL);
7150 return pfile->buffer;
7153 /*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7155 llassert (buf->buf != NULL);
7156 return (buf->buf + buf->line_base);
7159 int cpplib_bufPeek (cppBuffer *buf)
7161 if (buf->cur == NULL || buf->rlimit == NULL) {
7162 return EOF;
7165 if (buf->cur < buf->rlimit) {
7166 return *(buf->cur);
7169 return EOF;
7172 bool cppBuffer_isMacro (cppBuffer *buf)
7174 if (buf != NULL)
7176 return (buf->cleanup == cppReader_macroCleanup);
7179 return FALSE;
7182 static void cpp_setLocation (cppReader *pfile)
7184 fileloc res;
7186 if (pfile->buffer != NULL)
7188 cppBuffer *buf;
7189 fileId fid;
7191 buf = cppReader_getBufferSafe (pfile);
7193 if (cstring_isDefined (buf->nominal_fname))
7195 DPRINTF (("Looking up: %s", buf->nominal_fname));
7197 if (fileTable_exists (context_fileTable (), buf->nominal_fname))
7199 fid = fileTable_lookup (context_fileTable (), buf->nominal_fname);
7201 else
7203 DPRINTF (("Trying %s", buf->fname));
7205 fid = fileTable_lookup (context_fileTable (), buf->fname);
7208 else
7210 fid = fileTable_lookup (context_fileTable (), buf->fname);
7213 if (fileId_isValid (fid))
7215 res = fileloc_create (fid, buf->lineno, 1);
7217 else
7219 res = fileloc_createBuiltin ();
7222 else
7224 res = fileloc_createBuiltin ();
7227 fileloc_free (g_currentloc);
7228 g_currentloc = res;
7231 static bool notparseable = FALSE; /* preceeded by @notparseable@ */
7232 static bool notfunction = FALSE; /* preceeded by @notfunction@ */
7233 static bool expectiter = FALSE; /* preceeded by @iter@ */
7234 static bool expectenditer = FALSE; /* second after @iter@ */
7235 static bool expectconstant = FALSE;/* preceeded by @constant@ */
7238 ** Returns true if the macro should be checked, false
7239 ** if it should be expanded normally.
7242 static bool cpp_shouldCheckMacro (cppReader *pfile, const char *p)
7244 cpp_setLocation (pfile);
7246 DPRINTF (("Should check macro? %s", p));
7248 if (expectiter || expectconstant || expectenditer)
7250 if (expectiter)
7252 expectiter = FALSE;
7253 expectenditer = TRUE;
7255 else
7257 expectiter = FALSE;
7258 expectconstant = FALSE;
7259 expectenditer = FALSE;
7262 if (notfunction || notparseable)
7264 notfunction = FALSE;
7265 notparseable = FALSE;
7266 return FALSE;
7268 return TRUE;
7271 llassert (*p == '#');
7272 p++;
7274 SKIP_WHITE_SPACE (p);
7275 llassert (strncmp (p, "define", 6) == 0);
7277 p += 6;
7278 SKIP_WHITE_SPACE (p);
7280 return cpp_shouldCheckMacroAux (p);
7283 static bool cpp_shouldCheckMacroAux (const char *p)
7285 bool checkmacro;
7286 bool hasParams;
7287 bool nocontent;
7288 cstring sname;
7291 char c;
7292 const char* q = p;
7294 while (((c = *q) != '\0')
7295 && !is_hor_space[(int)c]
7296 && c != '\\' && c != '('
7297 && !iscntrl (c))
7299 q++;
7302 sname = cstring_copyLength (p, (size_t) (q - p));
7304 hasParams = (*q == '(');
7306 SKIP_WHITE_SPACE (q);
7307 nocontent = (*q == '\0');
7310 DPRINTF (("Check macro: %s", sname));
7312 checkmacro = FALSE;
7313 if (notparseable)
7315 notparseable = FALSE;
7317 else if (notfunction)
7319 notfunction = FALSE;
7321 else if (fileloc_isStandardLib (g_currentloc))
7325 else if (usymtab_existsReal (sname))
7327 uentry ue = usymtab_lookup (sname);
7329 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7331 if (fileloc_isPreproc (uentry_whereLast (ue)))
7333 goto macroDne;
7335 else
7337 if (uentry_isSpecified (ue))
7339 checkmacro = context_getFlag (FLG_SPECMACROS);
7341 else
7343 if (hasParams)
7345 checkmacro = context_getFlag (FLG_LIBMACROS)
7346 || context_getFlag (FLG_FCNMACROS);
7351 else
7353 DPRINTF (("Macro doesn't exist"));
7355 macroDne:
7356 if (fileloc_isSystemFile (g_currentloc)
7357 && context_getFlag (FLG_SYSTEMDIREXPAND))
7359 DPRINTF (("Don't check"));
7361 else
7363 uentry le;
7365 if (hasParams)
7367 DPRINTF (("Has params..."));
7369 if (context_getFlag (FLG_FCNMACROS))
7371 if (usymtab_exists (sname))
7374 ** only get here is macro is redefined
7375 ** error reported elsewhere
7378 DPRINTF (("It exists!"));
7380 else
7383 ** We make it a forward function, since it might be declared elsewhere.
7384 ** After all headers have been processed, we should check the forward
7385 ** functions.
7388 fileloc loc = fileloc_makePreproc (g_currentloc);
7389 /* the line is off-by-one, since the newline was already read */
7390 decLine ();
7391 le = uentry_makeForwardFunction (sname,
7392 typeId_invalid, loc);
7393 fileloc_free (loc);
7394 incLine ();
7396 /* Do not define here! */
7398 (void) usymtab_addGlobalEntry (le);
7401 checkmacro = TRUE;
7404 else
7406 DPRINTF (("No params"));
7408 if (context_getFlag (FLG_CONSTMACROS))
7410 if (!usymtab_exists (sname))
7412 fileloc loc = fileloc_makePreproc (g_currentloc);
7413 DPRINTF (("Make constant: %s", sname));
7414 le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
7415 /* Note: don't free loc! */
7416 (void) usymtab_addGlobalEntry (le);
7419 checkmacro = !nocontent;
7423 if (checkmacro && usymtab_existsType (sname))
7425 DPRINTF (("Making false..."));
7426 decLine ();
7427 ppllerror (message ("Specified type implemented as macro: %s", sname));
7428 checkmacro = FALSE;
7429 incLine ();
7434 if (!checkmacro)
7436 fileloc tloc = fileloc_makePreproc (g_currentloc);
7438 if (usymtab_exists (sname))
7440 uentry ue = usymtab_lookupExpose (sname);
7441 uentry_setDefined (ue, tloc);
7442 uentry_setUsed (ue, fileloc_undefined);
7444 else
7446 (void) usymtab_addGlobalEntry (uentry_makeExpandedMacro (sname, tloc));
7449 fileloc_free (tloc);
7452 cstring_free (sname);
7454 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
7455 return checkmacro;
7458 static enum cpp_token
7459 cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
7461 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
7462 char *start;
7463 int len;
7464 fileloc loc;
7465 bool eliminateComment = FALSE;
7467 llassert (pbuf->buf != NULL);
7469 start = pbuf->buf + smark->position;
7471 llassert (pbuf->cur != NULL);
7472 len = pbuf->cur - start;
7474 if (start[0] == '*'
7475 && start[1] == context_getCommentMarkerChar ())
7477 int i;
7478 char *scomment = start + 2;
7479 char savec = start[len];
7481 cpp_setLocation (pfile);
7482 loc = fileloc_copy (g_currentloc);
7484 start[0] = BEFORE_COMMENT_MARKER[0];
7485 start[1] = BEFORE_COMMENT_MARKER[1];
7487 llassert (start[len - 2] == '*');
7488 start[len - 2] = AFTER_COMMENT_MARKER[0];
7490 llassert (start[len - 1] == '/');
7491 start[len - 1] = AFTER_COMMENT_MARKER[1];
7493 cpplib_reserve(pfile, size_fromInt (1 + len));
7494 cppReader_putCharQ (pfile, ' ');
7496 cpp_setLocation (pfile);
7498 start[len] = '\0';
7500 if (mstring_containsString (scomment, "/*"))
7502 (void) cppoptgenerror
7503 (FLG_NESTCOMMENT,
7504 message ("Comment starts inside syntactic comment: %s",
7505 cstring_fromChars (scomment)),
7506 pfile);
7509 start[len] = savec;
7511 if (mstring_equalPrefix (scomment, "ignore"))
7513 if (!context_getFlag (FLG_NOCOMMENTS))
7515 context_enterSuppressRegion (loc);
7518 else if (mstring_equalPrefix (scomment, "end"))
7520 if (!context_getFlag (FLG_NOCOMMENTS))
7522 context_exitSuppressRegion (loc);
7525 else if (mstring_equalPrefix (scomment, "notparseable"))
7527 notparseable = TRUE;
7528 eliminateComment = TRUE;
7530 else if (mstring_equalPrefix (scomment, "notfunction"))
7532 notfunction = TRUE;
7533 eliminateComment = TRUE;
7535 else if (mstring_equalPrefix (scomment, "iter"))
7537 expectiter = TRUE;
7539 else if (mstring_equalPrefix (scomment, "function"))
7543 else if (mstring_equalPrefix (scomment, "constant"))
7545 expectconstant = TRUE;
7547 else
7549 char sChar = *scomment;
7551 if (sChar == '='
7552 || sChar == '-'
7553 || sChar == '+')
7555 char *rest = scomment + 1;
7556 static const char commchar[] = "commentchar";
7558 if (mstring_equalPrefix (rest, commchar))
7560 eliminateComment = TRUE;
7562 if (sChar == '=')
7564 ppllerror (cstring_makeLiteral
7565 ("Cannot restore commentchar"));
7567 else if (!is_space[(int) scomment[constlen(commchar) + 1]])
7569 ppllerror
7570 (message
7571 ("Syntactic commentchar comment is not followed by a "
7572 "whitespace character: %c",
7573 scomment[1 + constlen(commchar)]));
7575 else if (scomment[constlen(commchar) + 1 + 1] == '\0')
7577 ppllerror (cstring_makeLiteral
7578 ("Cannot set commentchar to NUL"));
7580 else
7582 context_setCommentMarkerChar (scomment[constlen(commchar) + 1 + 1]);
7585 else if (mstring_equalPrefix (rest, "nestcomment"))
7587 /* fix from Mike Miller <MikeM@xata.com> */
7588 context_fileSetFlag (FLG_NESTCOMMENT,
7589 ynm_fromCodeChar (sChar),
7590 loc);
7592 else if (mstring_equalPrefix (rest, "namechecks"))
7594 context_fileSetFlag (FLG_NAMECHECKS,
7595 ynm_fromCodeChar (sChar),
7596 loc);
7598 else if (mstring_equalPrefix (rest, "macroredef"))
7600 context_fileSetFlag (FLG_MACROREDEF,
7601 ynm_fromCodeChar (sChar),
7602 loc);
7604 else if (mstring_equalPrefix (rest, "usevarargs"))
7606 context_fileSetFlag (FLG_USEVARARGS,
7607 ynm_fromCodeChar (sChar),
7608 loc);
7610 else if (mstring_equalPrefix (rest, "nextlinemacros"))
7612 context_fileSetFlag (FLG_MACRONEXTLINE,
7613 ynm_fromCodeChar (sChar),
7614 loc);
7616 else if (mstring_equalPrefix (rest, "allmacros")
7617 || mstring_equalPrefix (rest, "fcnmacros")
7618 || mstring_equalPrefix (rest, "constmacros"))
7620 flagcode fl;
7622 if (mstring_equalPrefix (rest, "allmacros"))
7624 fl = FLG_ALLMACROS;
7626 else if (mstring_equalPrefix (rest, "fcnmacros"))
7628 fl = FLG_FCNMACROS;
7630 else
7632 llassert (mstring_equalPrefix (rest, "constmacros"));
7633 fl = FLG_CONSTMACROS;
7636 context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
7637 notfunction = FALSE;
7639 else
7644 else
7650 if (eliminateComment)
7652 goto removeComment;
7655 /* Replaces comment char's in start with spaces */
7657 for (i = 2; i < len - 2; i++)
7659 if (start[i] == BEFORE_COMMENT_MARKER[0]
7660 || start[i] == BEFORE_COMMENT_MARKER[1]
7661 || start[i] == context_getCommentMarkerChar ())
7663 start[i] = ' ';
7667 cppReader_putStrN (pfile, start, size_fromInt (len));
7668 parseClearMark (smark);
7669 return CPP_COMMENT;
7671 else
7673 removeComment:
7675 int i;
7678 ** Output the comment as all spaces so line/column
7679 ** in output file is still correct.
7682 char c = ' ';
7683 cstring lintcomment;
7685 if (!context_getFlag (FLG_LINTCOMMENTS))
7687 lintcomment = cstring_undefined;
7689 else if (mstring_equalPrefix (start, "*NOTREACHED*/"))
7691 lintcomment = cstring_makeLiteralTemp ("l_notreach");
7693 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
7695 lintcomment = cstring_makeLiteralTemp ("l_printfli");
7697 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
7699 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
7701 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
7703 lintcomment = cstring_makeLiteralTemp ("l_argsus");
7705 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
7707 lintcomment = cstring_makeLiteralTemp ("l_fallth");
7709 else
7711 lintcomment = cstring_undefined;
7714 if (cstring_isDefined (lintcomment))
7716 c = BEFORE_COMMENT_MARKER[0];
7717 start[0] = BEFORE_COMMENT_MARKER[1];
7719 llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
7721 for (i = 1; i < len - 2; i++)
7723 start[i] = cstring_getChar (lintcomment, size_fromInt (i));
7726 start[len - 2] = AFTER_COMMENT_MARKER[0];
7727 start[len - 1] = AFTER_COMMENT_MARKER[1];
7729 else
7731 /* Replaces char's in start with spaces */
7732 for (i = 0; i < len; i++)
7734 if (start[i] == '/'
7735 && i < len - 1
7736 && start[i + 1] == '*') {
7737 (void) cppoptgenerror
7738 (FLG_NESTCOMMENT,
7739 message ("Comment starts inside comment"),
7740 pfile);
7743 if (start[i] != '\n')
7745 start[i] = ' ';
7750 cpplib_reserve (pfile, size_fromInt (1 + len));
7751 cppReader_putCharQ (pfile, c);
7752 cppReader_putStrN (pfile, start, size_fromInt (len));
7753 parseClearMark (smark);
7754 return CPP_COMMENT;
7759 static int cpp_openIncludeFile (char *filename)
7761 int res = osd_openForReading (filename);
7763 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
7764 if (res >= 0)
7766 if (!fileTable_exists (context_fileTable (),
7767 cstring_fromChars (filename)))
7769 fileType ftype = context_inXHFile () ? FILE_XH : FILE_HEADER;
7770 (void) fileTable_addFile (context_fileTable (), ftype,
7771 cstring_fromChars (filename));
7773 else
7775 DPRINTF (("File already exists: %s", filename));
7779 return res;
7782 static bool cpp_skipIncludeFile (cstring fname)
7784 if (context_isSystemDir (fname))
7786 DPRINTF (("System dir: %s", fname));
7788 if (fileLib_isSkipHeader (fname))
7790 DPRINTF (("Skip include TRUE: %s", fname));
7791 return TRUE;
7794 if (context_getFlag (FLG_SKIPSYSHEADERS))
7797 ** 2003-04-18: Patch from Randal Parsons
7801 ** Don't skip include file unless the file actually exists.
7802 ** It may be in a different directory.
7805 if (osd_fileIsReadable(fname))
7807 DPRINTF (("Skip include TRUE: %s", fname));
7808 return TRUE;
7810 else
7812 ; /* Keep looking... */
7817 if (context_getFlag (FLG_SINGLEINCLUDE))
7819 fname = osd_removePreDirs (fname);
7821 osd_pathMakePosix (fname);
7823 if (fileTable_exists (context_fileTable (), fname))
7825 DPRINTF (("Skip include TRUE: %s", fname));
7826 return TRUE;
7830 DPRINTF (("Skip include FALSE: %s", fname));
7831 return FALSE;
7834 static int cpp_peekN (cppReader *pfile, int n)
7836 cppBuffer *buf = cppReader_getBufferSafe (pfile);
7838 llassert (buf->cur != NULL);
7840 return (buf->rlimit - buf->cur >= (n)
7841 ? buf->cur[n]
7842 : EOF);
7845 cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
7847 return buf + 1;
7850 void cppBuffer_forward (cppBuffer *buf, int n)
7852 llassert (buf->cur != NULL);
7853 buf->cur += n;
7856 /*@=bufferoverflowhigh@*/
7857 /*@=bounds@*/