]> andersk Git - splint.git/blame - src/cpplib.c
Fixed \ line parsing.
[splint.git] / src / cpplib.c
CommitLineData
ac0860d8 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
ac0860d8 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.
19**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
ac0860d8 23*/
24/*
25** cpplib.c
26*/
27/*
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
32
33This program is free software; you can redistribute it and/or modify it
34under the terms of the GNU General Public License as published by the
35Free Software Foundation; either version 2, or (at your option) any
36later version.
37
38This program is distributed in the hope that it will be useful,
39but WITHOUT ANY WARRANTY; without even the implied warranty of
40MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41GNU General Public License for more details.
42
43You should have received a copy of the GNU General Public License
44along with this program; if not, write to the Free Software
45Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
46
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! */
50
51/*
52 * Herbert 06/12/2000:
53 * - OS2 drive specs like WIN32
54 * - Includes for IBMs OS/2 compiler
55 */
56
57# include <ctype.h>
58# include <stdio.h>
59# include <signal.h>
60# ifdef __STDC__
61# include <stdlib.h>
62# endif
63
64# include <string.h>
ac0860d8 65# if !(defined (WIN32) || defined (OS2) && defined (__IBMC__))
66# include <unistd.h>
67# endif
ac0860d8 68# include <sys/types.h>
69# include <sys/stat.h>
70# include <fcntl.h>
ac0860d8 71# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
72# include <io.h>
73# include <sys/utime.h> /* for __DATE__ and __TIME__ */
74# include <time.h>
75# else
76# ifndef VMS
ce7034f0 77/*
78** evans 2002-07-03: exception for WATCOM 10.6 compiler suggest by Adam Clarke
79*/
80# if !defined (USG) && !defined (__WATCOMC__)
ac0860d8 81# include <time.h> /* Reported by Paul Smith */
82# include <sys/time.h>
83# include <sys/resource.h>
84# else
85# include <sys/times.h>
86# include <time.h>
87# include <fcntl.h>
88# endif /* USG */
89# endif /* not VMS */
90# endif /* not WIN32 */
91
92/* This defines "errno" properly for VMS, and gives us EACCES. */
93# include <errno.h>
94
1b8ae690 95# include "splintMacros.nf"
b73d1009 96# include "basic.h"
ac0860d8 97# include "lcllib.h"
98# include "cpplib.h"
99# include "cpperror.h"
100# include "cpphash.h"
101# include "cppexp.h"
102# include "version.h"
ac0860d8 103# include "osd.h"
104
105/*
106** This is really kludgey code...
107*/
108
109/*@+boolint@*/
110/*@+charint@*/
111
f9264521 112/* Warnings for using sprintf - suppress them all for now... */
113/*@-bufferoverflowhigh@*/
0fe21ba7 114/*@-bounds@*/
f9264521 115
ac0860d8 116#define NO_SHORTNAMES
117
118# ifdef open
119# undef open
120# undef read
121# undef write
122# endif /* open */
123
124/*@constant int IMPORT_FOUND@*/
125# define IMPORT_FOUND -2
126
127/*@constant int SKIP_INCLUDE@*/
128# define SKIP_INCLUDE IMPORT_FOUND
129
130/*@constant unused int IMPORT_NOT_FOUND@*/
131# define IMPORT_NOT_FOUND -1
132
133#ifndef STDC_VALUE
134/*@constant unused int STDC_VALUE@*/
135#define STDC_VALUE 1
136#endif
137
138/* By default, colon separates directories in a path. */
139#ifndef PATH_SEPARATOR
140/*@constant char PATH_SEPARATOR@*/
141#define PATH_SEPARATOR ':'
142#endif
143
144static void parse_name (cppReader *, int);
145
146static int cpp_openIncludeFile (char *p_filename)
147 /*@modifies fileSystem @*/ ;
148
149static void cpp_setLocation (cppReader *p_pfile)
150 /*@modifies g_currentloc@*/ ;
151
152static enum cpp_token cpp_handleComment (cppReader *p_pfile,
153 struct parse_marker *p_smark)
80489f0a 154 /*@modifies p_pfile, p_smark@*/;
abd7f895 155
2209bcb7 156static bool cpp_shouldCheckMacro (cppReader *p_pfile, char *p_p) /*@modifies p_p@*/ ;
ac0860d8 157
abd7f895 158static size_t cppReader_checkMacroNameLoc (fileloc p_loc, char *p_symname, cstring p_usage) ;
3e3ec469 159
ac0860d8 160static bool cpp_skipIncludeFile (cstring p_fname) /*@*/ ;
161
162#ifndef O_RDONLY
163#define O_RDONLY 0
164#endif
165
166/* Symbols to predefine. */
abd7f895 167
ac0860d8 168#ifdef CPP_PREDEFINES
169static /*@observer@*/ char *predefs = CPP_PREDEFINES;
170#else
171static /*@observer@*/ char *predefs = "";
172#endif
173
174/* We let tm.h override the types used here, to handle trivial differences
175 such as the choice of unsigned int or long unsigned int for size_t.
176 When machines start needing nontrivial differences in the size type,
177 it would be best to do something here to figure out automatically
178 from other information what type to use. */
179
180/* The string value for __SIZE_TYPE__. */
181
182#ifndef SIZE_TYPE
183/*@constant observer char *SIZE_TYPE@*/
184#define SIZE_TYPE "long unsigned int"
185#endif
186
187/* The string value for __PTRDIFF_TYPE__. */
188
189#ifndef PTRDIFF_TYPE
190/*@constant observer char *PTRDIFF_TYPE@*/
191#define PTRDIFF_TYPE "long int"
192#endif
193
194/* The string value for __WCHAR_TYPE__. */
195
196#ifndef WCHAR_TYPE
197/*@constant observer char *WCHAR_TYPE@*/
198#define WCHAR_TYPE "int"
199#endif
abd7f895 200
ac0860d8 201/* The string value for __USER_LABEL_PREFIX__ */
202
203#ifndef USER_LABEL_PREFIX
204/*@constant observer char *USER_LABEL_PREFIX@*/
205#define USER_LABEL_PREFIX ""
206#endif
207
208/* The string value for __REGISTER_PREFIX__ */
209
210#ifndef REGISTER_PREFIX
211/*@constant observer char *REGISTER_PREFIX@*/
212#define REGISTER_PREFIX ""
213#endif
214
215/* table to tell if char can be part of a C identifier. */
216static bool is_idchar[256];
217/* table to tell if char can be first char of a c identifier. */
218static bool is_idstart[256];
219/* table to tell if c is horizontal space. */
220static bool is_hor_space[256];
221/* table to tell if c is horizontal or vertical space. */
222static bool is_space[256];
abd7f895 223
ac0860d8 224static /*@exposed@*/ /*@null@*/ cppBuffer *
225cppReader_getBuffer (/*@special@*/ cppReader *p_pfile)
226 /*@uses p_pfile->buffer@*/
227 /*@modifies nothing@*/ ;
228
229/*@notfunction@*/
230# define SKIP_WHITE_SPACE(p) do { /*@access cstring@*/ while (is_hor_space[(int) *(p)]) { (p)++; } } /*@noaccess cstring@*/ while (0)
231
232/*@notfunction@*/
233# define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*(p)]) { (p)++; } } while (0)
234
235static int cpp_peekN (cppReader *p_pfile, int p_n) /*@*/ ;
236
237/*@function static int cppBuffer_get (sef cppBuffer *p_b) modifies *p_b ; @*/
238# define cppBuffer_get(BUFFER) \
239 ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
240
c09ebffe 241/*@function static int cppBuffer_reachedEOF (sef cppBuffer *p_b) modifies nothing; @*/
242# define cppBuffer_reachedEOF(b) \
243 ((b)->cur < (b)->rlimit ? FALSE : TRUE)
244
ac0860d8 245/* Append string STR (of length N) to PFILE's output buffer. Make space. */
246/*@function static void cppReader_puts (sef cppReader *p_file, char *p_str, sef size_t p_n)
247 modifies *p_file; @*/
248# define cppReader_puts(PFILE, STR, N) \
3e3ec469 249 cpplib_reserve(PFILE, N), cppReader_putStrN (PFILE, STR,N)
abd7f895 250
ac0860d8 251/* Append character CH to PFILE's output buffer. Assume sufficient space. */
252
253/*@function static void cppReader_putCharQ (cppReader *p_file, char p_ch)
254 modifies *p_file; @*/
255# define cppReader_putCharQ(PFILE, CH) (*(PFILE)->limit++ = (CH))
ce7034f0 256/*
257static void cppReader_putCharQ (cppReader *p_file, char p_ch)
258{
259 fprintf (stderr, "put char: %c\n", p_ch);
260 (*(p_file)->limit++ = (p_ch));
261}
262*/
ac0860d8 263/* Append character CH to PFILE's output buffer. Make space if need be. */
264
265/*@function static void cppReader_putChar (sef cppReader *p_file, char p_ch)
266 modifies *p_file; @*/
3e3ec469 267#define cppReader_putChar(PFILE, CH) (cpplib_reserve (PFILE, (size_t) 1), cppReader_putCharQ (PFILE, CH))
ac0860d8 268
269/* Make sure PFILE->limit is followed by '\0'. */
270/*@function static void cppReader_nullTerminateQ (cppReader *p_file)
271 modifies *p_file; @*/
272
273#define cppReader_nullTerminateQ(PFILE) (*(PFILE)->limit = 0)
274
275/*@function static void cppReader_nullTerminate (sef cppReader *p_file)
276 modifies *p_file; @*/
277# define cppReader_nullTerminate(PFILE) \
3e3ec469 278 (cpplib_reserve (PFILE, (size_t) 1), *(PFILE)->limit = 0)
ac0860d8 279
280/*@function static void cppReader_adjustWritten (cppReader *p_file, size_t)
281 modifies *p_file; @*/
282#define cppReader_adjustWritten(PFILE,DELTA) ((PFILE)->limit += (DELTA))
283
284/*@function static bool cppReader_isC89 (cppReader *) modifies nothing; @*/
285#define cppReader_isC89(PFILE) (CPPOPTIONS(PFILE)->c89)
286
287/*@function static observer char *cppReader_wcharType (cppReader *)
288 modifies nothing; @*/
289
290# define cppReader_wcharType(PFILE) \
291 (CPPOPTIONS (PFILE)->cplusplus ? "__wchar_t" : WCHAR_TYPE)
292
293static void cppBuffer_forward (cppBuffer *p_buf, int p_n) /*@modifies *p_buf@*/ ;
294
295/*@function static void cppReader_forward (cppReader *p_pfile, int) modifies *p_pfile; @*/
296# define cppReader_forward(pfile, N) \
297 (cppBuffer_forward (cppReader_getBufferSafe (pfile), (N)))
298
299/*@function static int cppReader_getC (cppReader *p_pfile) modifies *p_pfile; @*/
300# define cppReader_getC(pfile) (cppBuffer_get (cppReader_getBufferSafe (pfile)))
301
c09ebffe 302/*@function static int cppReader_reachedEOF (sef cppReader *p_pfile) modifies *p_pfile; @*/
303# define cppReader_reachedEOF(pfile) (cppBuffer_reachedEOF (cppReader_getBufferSafe (pfile)))
304
ac0860d8 305/*@function static int cppReader_peekC (cppReader *) modifies nothing;@*/
3e3ec469 306# define cppReader_peekC(pfile) (cpplib_bufPeek (cppReader_getBufferSafe (pfile)))
ac0860d8 307
308/* Move all backslash-newline pairs out of embarrassing places.
309 Exchange all such pairs following BP
310 with any potentially-embarrassing characters that follow them.
311 Potentially-embarrassing characters are / and *
312 (because a backslash-newline inside a comment delimiter
313 would cause it not to be recognized). */
314
315/*@notfunction@*/
316# define NEWLINE_FIX \
317 do { while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n') { cppReader_forward (pfile, 2); } } while(FALSE)
318
319 /* Same, but assume we've already read the potential '\\' into C. */
320/*@notfunction@*/
321# define NEWLINE_FIX1(C) do { \
322 while ((C) == '\\' && cppReader_peekC (pfile) == '\n') { cppReader_forward (pfile, 1); (C) = cppReader_getC (pfile); }\
323 } while(0)
324
325static void parseSetMark (/*@out@*/ struct parse_marker *,
326 cppReader *);
327static void parseClearMark (struct parse_marker *);
328static void parseGotoMark (struct parse_marker *, cppReader *);
329static void parseMoveMark (struct parse_marker *, cppReader *);
330
331/* If we have a huge buffer, may need to cache more recent counts */
332static /*@exposed@*/ char *cppLineBase (/*@sef@*/ cppBuffer *);
333
334static /*@exposed@*/ /*@null@*/ cppBuffer *
335 cppReader_pushBuffer (cppReader *p_pfile,
336 /*@owned@*/ /*@null@*/ char *, size_t)
337 /*@modifies p_pfile@*/ ;
338
339static void cppReader_appendIncludeChain
340(cppReader *p_pfile,
341 /*@keep@*/ struct file_name_list *p_first,
342 /*@dependent@*/ struct file_name_list *p_last);
343
344static void cppReader_macroCleanup (cppBuffer *p_pbuf, cppReader *p_pfile);
345static enum cpp_token cppReader_nullUnderflow (/*@unused@*/ cppReader *p_pfile);
346
347static void cppReader_nullCleanup (/*@unused@*/ cppBuffer *p_pbuf,
348 /*@unused@*/ cppReader *p_pfile);
349
350static void cppReader_fileCleanup (cppBuffer *p_pbuf,
351 /*@unused@*/ cppReader *p_pfile);
352
353static int cppReader_handleDirective (cppReader *p_pfile);
354
355static void cppReader_scanBuffer (cppReader *p_pfile);
356
357# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
358
359/*
360** WIN32 (at least the VC++ include files) does not define mode_t.
361*/
362
363/*@-incondefs@*/ /*@-czechtypes@*/
364typedef unsigned int mode_t;
365/*@=incondefs@*/ /*@=czechtypes@*/
366
367# endif
368
369static int file_size_and_mode (int p_fd, /*@out@*/ mode_t *p_mode_pointer,
370 /*@out@*/ size_t *p_size_pointer);
371static int safe_read (int p_desc, /*@out@*/ char *p_ptr, int p_len);
372
373
374/*
375** cppBuffer_isMacro is true if the buffer contains macro expansion.
376** (Note that it is false while we're expanding marco *arguments*.)
377*/
378
379static bool cppBuffer_isMacro (/*@null@*/ cppBuffer *) /*@*/ ;
380
381static void path_include (cppReader *p_pfile, char *p_path)
382 /*@modifies p_pfile@*/ ;
383
384static void initialize_builtins (cppReader *p_pfile)
385 /*@modifies p_pfile@*/ ;
386
387static void initialize_char_syntax (struct cppOptions *p_opts) ;
388
389static int /*@alt void@*/ finclude (cppReader *p_pfile, int p_f,
390 cstring p_fname,
391 bool p_system_header_p,
392 /*@dependent@*/ /*@null@*/ struct file_name_list *p_dirptr);
393
394static void validate_else (cppReader *p_pfile, cstring p_directive);
abd7f895 395
ac0860d8 396static void conditional_skip (cppReader *p_pfile, int p_skip,
397 enum node_type p_type,
398 /*@dependent@*/ /*@null@*/ char *p_control_macro);
399
400static HOST_WIDE_INT eval_if_expression (cppReader *p_pfile,
401 char *p_buf,
402 int p_length);
403
404static void skip_if_group (cppReader *p_pfile, int p_any);
405
406static bool comp_def_part (bool p_first, char *p_beg1, int p_len1,
407 char *p_beg2, int p_len2, bool p_last);
408
409#ifdef abort
410extern void fancy_abort ();
411#endif
412
413static bool redundant_include_p (cppReader *p_pfile, /*@null@*/ cstring p_name);
414static bool is_system_include (cppReader *p_pfile, cstring p_filename);
415
416static /*@observer@*/ /*@null@*/ struct file_name_map *
417read_name_map (cppReader *p_pfile, cstring p_dirname);
418
419static cstring read_filename_string (int p_ch, /*:open:*/ FILE *p_f);
420
421static int open_include_file (cppReader *p_pfile,
422 /*@owned@*/ cstring p_fname,
423 /*@null@*/ struct file_name_list *p_searchptr);
424
425static void push_macro_expansion (cppReader *,
426 /*@owned@*/ char *, size_t,
427 /*@dependent@*/ hashNode);
428
429/* Last arg to output_line_command. */
430enum file_change_code {
431 same_file, enter_file, leave_file
432};
433
434/* `struct directive' defines one #-directive, including how to handle it. */
435
436struct directive {
437 int length; /* Length of name */
438 /*@null@*/ int (*func)(); /* Function to handle directive */
439 /*@observer@*/ cstring name; /* Name of directive */
440 enum node_type type; /* Code which describes which directive. */
441 bool command_reads_line; /* One if rest of line is read by func. */
442 bool traditional_comments; /* Nonzero: keep comments if -traditional. */
443 bool pass_thru; /* Copy preprocessed directive to output file.*/
444};
445
446/* These functions are declared to return int instead of void since they
447 are going to be placed in a table and some old compilers have trouble with
448 pointers to functions returning void. */
449
450static int do_define (cppReader *, /*@null@*/ struct directive *,
2209bcb7 451 /*@exposed@*/ char *, char *);
ac0860d8 452static int do_defineAux (cppReader *, /*@null@*/ struct directive *,
2209bcb7 453 /*@exposed@*/ char *, char *, bool);
ac0860d8 454
455static int do_line (cppReader *, /*@null@*/ struct directive *);
456static int do_include (cppReader *, struct directive *, char *, char *);
457static int do_undef (cppReader *, struct directive *, char *, char *);
458static int do_error (cppReader *, struct directive *, char *, char *);
459static int do_pragma (cppReader *, struct directive *, char *, char *);
460static int do_ident (cppReader *, struct directive *, char *, char *);
461static int do_if (cppReader *, struct directive *, char *, char *);
462static int do_xifdef (cppReader *, struct directive *, char *, char *);
463static int do_else (cppReader *, struct directive *, char *, char *);
464static int do_elif (cppReader *, struct directive *, char *, char *);
465static int do_endif (cppReader *, struct directive *, char *, char *);
466static int do_warning (cppReader *, struct directive *, char *, char *);
467
468/* If a buffer's dir field is SELF_DIR_DUMMY, it means the file was found
469 via the same directory as the file that #included it. */
470
471/*@constant observer struct file_name_list *SELF_DIR_DUMMY@*/
472#define SELF_DIR_DUMMY ((struct file_name_list *) (~0))
473
474/* #include "file" looks in source file dir, then stack. */
475/* #include <file> just looks in the stack. */
476/* -I directories are added to the end, then the defaults are added. */
477
478/*@access cstring@*/
abd7f895 479
ac0860d8 480static struct default_include {
481 /*@dependent@*/ /*@observer@*/ cstring fname; /* The name of the directory. */
482 int cplusplus; /* Only look here if we're compiling C++. */
483 int cxx_aware; /* Includes in this directory don't need to
484 be wrapped in extern "C" when compiling
485 C++. */
486} include_defaults_array[]
487= {
488 /* This is the dir for fixincludes. Put it just before
489 the files that we fix. */
490 { GCC_INCLUDE_DIR, 0, 0 },
491 { GCC_INCLUDE_DIR2, 0, 0 },
492 { cstring_undefined, 0, 0 }
493};
494
495/*@noaccess cstring@*/
496
497/* Here is the actual list of #-directives, most-often-used first.
498 The initialize_builtins function assumes #define is the very first. */
499
500/*@access cstring@*/
501
502static struct directive directive_table[] = {
503 { 6, do_define, "define", T_DEFINE, FALSE, TRUE, FALSE },
504 { 5, do_xifdef, "ifdef", T_IFDEF, TRUE, FALSE, FALSE },
505 { 6, do_xifdef, "ifndef", T_IFNDEF, TRUE, FALSE, FALSE },
506 { 7, do_include, "include", T_INCLUDE, TRUE, FALSE, FALSE },
507 { 5, do_endif, "endif", T_ENDIF, TRUE, FALSE, FALSE },
508 { 4, do_else, "else", T_ELSE, TRUE, FALSE, FALSE },
509 { 2, do_if, "if", T_IF, TRUE, FALSE, FALSE },
510 { 4, do_elif, "elif", T_ELIF, TRUE, FALSE, FALSE },
511 { 5, do_undef, "undef", T_UNDEF, FALSE, FALSE, FALSE },
512 { 5, do_error, "error", T_ERROR, FALSE, FALSE, FALSE },
513 { 7, do_warning, "warning", T_WARNING, FALSE, FALSE, FALSE },
514 { 6, do_pragma, "pragma", T_PRAGMA, FALSE, FALSE, TRUE},
515 { 4, do_line, "line", T_LINE, TRUE, FALSE, FALSE },
516 { 5, do_ident, "ident", T_IDENT, TRUE, FALSE, TRUE },
517 /* { 8, do_unassert, "unassert", T_UNASSERT, TRUE, FALSE, FALSE }, */
8fe44445 518 { -1, NULL, "", T_UNUSED, FALSE, FALSE, FALSE },
ac0860d8 519};
520/*@noaccess cstring@*/
521
522static cstring searchPath_unparse (struct file_name_list *search_start)
523{
524 cstring res = cstring_newEmpty ();
525 struct file_name_list *searchptr = NULL;
526
527 for (searchptr = search_start; searchptr != NULL;
528 searchptr = searchptr->next)
529 {
530 if (!cstring_isEmpty (searchptr->fname)) {
531 res = cstring_concatFree1 (res, searchptr->fname);
532 if (searchptr->next != NULL) {
533 res = cstring_appendChar (res, ';');
534 }
535 }
536 }
537
538 return res;
539}
540
541/*@+charint@*/
542static void
543initialize_char_syntax (struct cppOptions *opts)
544{
545 char i;
546
547 /*
548 * Set up is_idchar and is_idstart tables. These should be
549 * faster than saying (is_alpha (c) || c == '_'), etc.
550 * Set up these things before calling any routines tthat
551 * refer to them.
552 */
553
554 for (i = 'a'; i <= 'z'; i++) {
555 is_idchar[i - 'a' + 'A'] = TRUE;
556 is_idchar[(int) i] = TRUE;
557 is_idstart[i - 'a' + 'A'] = TRUE;
558 is_idstart[(int) i] = TRUE;
559 }
560
561 for (i = '0'; i <= '9'; i++)
562 {
563 is_idchar[(int) i] = TRUE;
564 }
565
566 is_idchar['_'] = TRUE;
567 is_idstart['_'] = TRUE;
568 is_idchar['$'] = opts->dollars_in_ident;
569 is_idstart['$'] = opts->dollars_in_ident;
570
571 /* horizontal space table */
572 is_hor_space[' '] = TRUE;
573 is_hor_space['\t'] = TRUE;
574 is_hor_space['\v'] = TRUE;
575 is_hor_space['\f'] = TRUE;
576 is_hor_space['\r'] = TRUE;
577
578 is_space[' '] = TRUE;
579 is_space['\t'] = TRUE;
580 is_space['\v'] = TRUE;
581 is_space['\f'] = TRUE;
582 is_space['\n'] = TRUE;
583 is_space['\r'] = TRUE;
584}
585
586bool isIdentifierChar (char c)
587{
588 return is_idchar[(int) c];
589}
590
591/* Place into P_PFILE a quoted string representing the string SRC.
592 Caller must reserve enough space in pfile->token_buffer. */
593
594static void
595quote_string (cppReader *pfile, char *src)
596{
597 char c;
abd7f895 598
ac0860d8 599 cppReader_putCharQ (pfile, '\"');
600 for (;;)
601 {
602 switch ((c = *src++))
603 {
604 default:
605 if (isprint (c))
606 cppReader_putCharQ (pfile, c);
607 else
608 {
3e3ec469 609 sprintf (cpplib_getPWritten (pfile), "\\%03o",
ac0860d8 610 (unsigned int) c);
611 cppReader_adjustWritten (pfile, (size_t) 4);
612 }
613 /*@switchbreak@*/ break;
614
615 case '\"':
616 case '\\':
617 cppReader_putCharQ (pfile, '\\');
618 cppReader_putCharQ (pfile, c);
619 /*@switchbreak@*/ break;
620
621 case '\0':
622 cppReader_putCharQ (pfile, '\"');
623 cppReader_nullTerminateQ (pfile);
624 return;
625 }
626 }
627}
628
629/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
630
631void
632cppReader_growBuffer (cppReader *pfile, size_t n)
633{
3e3ec469 634 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 635 pfile->token_buffer_size = n + 2 * pfile->token_buffer_size;
636 pfile->token_buffer = (char *)
637 drealloc (pfile->token_buffer, pfile->token_buffer_size);
638 cppReader_setWritten (pfile, old_written);
639}
640
641/*
642 * process a given definition string, for initialization
643 * If STR is just an identifier, define it with value 1.
644 * If STR has anything after the identifier, then it should
645 * be identifier=definition.
646 */
647
648void
649cppReader_define (cppReader *pfile, char *str)
650{
651 char *buf = NULL;
652 char *p = str;
653
654 DPRINTF (("Cpp reader define: %s", str));
655
656 if (!is_idstart[(int) *p])
657 {
658 DPRINTF (("ERROR 1"));
659 cppReader_error (pfile,
660 message ("Malformed option `-D%s'",
661 cstring_fromChars (str)));
662
663 return;
664 }
665
666 p++;
667
668 DPRINTF (("Here 2"));
669
670 while (is_idchar[(int) *p])
671 {
672 p++;
673 }
674
675 if (*p == '(') {
676 p++;
677 while (*p != ')' && *p != '\0') {
678 p++;
679 }
680
681 if (*p == ')') {
682 p++;
683 } else {
684 cppReader_error
685 (pfile,
686 message ("Malformed option: -D%s (no closing parenthesis)",
687 cstring_fromChars (str)));
688 }
689 }
690
691 DPRINTF (("Here 2"));
692
693 if (*p == '\0')
694 {
695 buf = (char *) dmalloc (size_fromInt (p - str + 4));
696 strcpy ((char *) buf, str);
697 strcat ((char *) buf, " 1");
698 }
699 else if (*p != '=')
700 {
701 DPRINTF (("ERROR 2"));
702 cppReader_error (pfile,
703 message ("Malformed option: -D%s (expected '=', found '%c')",
704 cstring_fromChars (str),
705 *p));
706 return;
707 }
708 else
709 {
710 char *q;
711 /* Copy the entire option so we can modify it. */
712 DPRINTF (("Copying..."));
713 buf = (char *) dmalloc (2 * strlen (str) + 1);
714 strncpy (buf, str, size_fromInt (p - str));
715
716 /* Change the = to a space. */
717 buf[p - str] = ' ';
718 /* Scan for any backslash-newline and remove it. */
719 p++;
720 q = &buf[p - str];
721
722 while (*p != '\0')
723 {
724 if (*p == '\\' && p[1] == '\n')
725 p += 2;
726 else
727 *q++ = *p++;
728 }
729
730 DPRINTF (("Here we are..."));
731 *q = '\0';
732 }
733
734 llassert (buf != NULL);
735 DPRINTF (("Do define: %s / %ld", buf, size_toLong (strlen (buf))));
736 (void) do_define (pfile, NULL, buf, buf + strlen (buf));
737 sfree (buf);
738}
abd7f895 739
ac0860d8 740/* Append a chain of `struct file_name_list's
741 to the end of the main include chain.
742 FIRST is gthe beginning of the chain to append, and LAST is the end. */
743
744void
745cppReader_appendIncludeChain (cppReader *pfile,
746 struct file_name_list *first,
747 struct file_name_list *last)
748{
749 struct cppOptions *opts = CPPOPTIONS (pfile);
750 struct file_name_list *dir;
751
752 if (first == NULL || last == NULL)
753 {
754 return;
755 }
756
757 if (opts->include == 0)
758 {
759 opts->include = first;
760 }
761 else
762 {
763 llassert (opts->last_include->next == NULL);
764 opts->last_include->next = first;
765 }
766
767 if (opts->first_bracket_include == 0)
768 {
769 opts->first_bracket_include = first;
770
771 for (dir = first; ; dir = dir->next) {
e5081f8c 772 size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
773
ac0860d8 774 if (len > pfile->max_include_len)
e5081f8c 775 {
776 pfile->max_include_len = len;
777 }
778
ac0860d8 779 if (dir == last)
e5081f8c 780 {
781 break;
782 }
ac0860d8 783 }
784 }
785
786 llassert (last->next == NULL);
787 /* last->next = NULL; */
788 opts->last_include = last;
789}
abd7f895 790
ac0860d8 791# if 0
792static /*@unused@*/ void
793cppReader_showIncludeChain (cppReader *pfile)
794{
795 struct file_name_list *dirs = CPPOPTIONS (pfile)->include;
796
797 if (dirs != NULL)
798 {
799 while (dirs != NULL)
800 {
801 fprintf (stderr, "*%s*:", cstring_toCharsSafe (dirs->fname));
802 dirs = dirs->next;
803 }
804
805 fprintf (stderr, "\n");
806 }
807 else
808 {
809 fprintf (stderr, "No includes\n");
810 }
811}
812# endif
abd7f895 813
ac0860d8 814cstring
815cppReader_getIncludePath ()
816{
817 cppReader *pfile = &g_cppState;
818 struct file_name_list *dirs = CPPOPTIONS (pfile)->include;
819 cstring res = cstring_undefined;
820
821 if (dirs != NULL)
822 {
823 while (dirs != NULL)
824 {
825 res = message ("%q%c%s", res, PATH_SEPARATOR, dirs->fname);
826 dirs = dirs->next;
827 }
828 }
829 else
830 {
831 res = cstring_makeLiteral ("<no include path>");
832 }
833
834 return res;
835}
836
837void
6fcd0b1e 838cppReader_addIncludeChain (cppReader *pfile, /*@only@*/ struct file_name_list *dir)
ac0860d8 839{
840 struct cppOptions *opts = CPPOPTIONS (pfile);
841
6fcd0b1e 842 if (dir == NULL)
ac0860d8 843 {
844 return;
845 }
846
847 if (opts->include == 0)
848 {
849 opts->include = dir;
850 }
851 else
852 {
853 llassert (opts->last_include->next == NULL);
854 opts->last_include->next = dir;
855 }
856
857 if (opts->first_bracket_include == 0)
858 {
e5081f8c 859 size_t len = cstring_length (dir->fname) + INCLUDE_LEN_FUDGE;
ac0860d8 860 opts->first_bracket_include = dir;
e5081f8c 861
ac0860d8 862 if (len > pfile->max_include_len)
863 {
864 pfile->max_include_len = len;
865 }
866 }
867
868 dir->next = NULL;
869 opts->last_include = dir;
870 /* cppReader_showIncludeChain (pfile); */
871}
872
873/* Given a colon-separated list of file names PATH,
874 add all the names to the search path for include files. */
875
876static void
877path_include (cppReader *pfile, char *path)
878{
879 char *p;
abd7f895 880
ac0860d8 881#ifdef __CYGWIN32__
882 char *win32temp;
883
884 /* if we have a posix path list, convert to win32 path list */
885 win32temp = (char *) dmalloc /*@i4@*/
886 (cygwin32_posix_to_win32_path_list_buf_size (path));
887 cygwin32_posix_to_win32_path_list (path, win32temp);
888 path = win32temp;
889#endif
890
891 p = path;
892
893 if (*p != '\0')
894 while (1) {
895 char *q = p;
896 char *name;
897 struct file_name_list *dirtmp;
898
899 /* Find the end of this name. */
900 while (*q != '\0' && *q != PATH_SEPARATOR)
901 {
902 q++;
903 }
904
905 if (p == q)
906 {
907 /* An empty name in the path stands for the current directory. */
908 name = (char *) dmalloc ((size_t) 2);
909 name[0] = '.';
910 name[1] = '\0';
911 }
912 else
913 {
914 /* Otherwise use the directory that is named. */
915 name = (char *) dmalloc (size_fromInt (q - p + 1));
916 memcpy (name, p, size_fromInt (q - p));
917 name[q - p] = '\0';
918 }
919
920 dirtmp = (struct file_name_list *) dmalloc (sizeof (*dirtmp));
921 dirtmp->next = 0; /* New one goes on the end */
922 dirtmp->control_macro = 0;
923 dirtmp->c_system_include_path = 0;
924 dirtmp->fname = cstring_fromChars (name);
925 dirtmp->got_name_map = 0;
926 cppReader_addIncludeChain (pfile, dirtmp);
927
928 /* Advance past this name. */
929 p = q;
930 if (*p == '\0')
931 break;
932 /* Skip the colon. */
933 p++;
934 }
935}
abd7f895 936
ac0860d8 937void
938cppOptions_init (cppOptions *opts)
939{
940 memset ((char *) opts, 0, sizeof *opts);
941 assertSet (opts);
942
943 opts->in_fname = NULL;
944 opts->out_fname = NULL;
945
946 /* Initialize is_idchar to allow $. */
947 opts->dollars_in_ident = TRUE;
948
949 opts->no_line_commands = 0;
950 opts->no_trigraphs = TRUE;
951 opts->put_out_comments = 1;
952 opts->print_include_names = 0;
953 opts->dump_macros = DUMP_DEFINITIONS; /* DUMP_NONE; */
954 opts->no_output = 0;
955 opts->cplusplus = 0;
956
957 opts->cplusplus_comments = 1;
958 opts->verbose = 0;
959 opts->lang_asm = 0;
960 opts->for_lint = 0;
961 opts->chill = 0;
962 opts->pedantic_errors = 0;
963 opts->warn_comments = 0;
964 opts->warnings_are_errors = 0;
965
8ea5df88 966 /* Added 2003-07-10: */
967 opts->traditional = FALSE;
968 opts->c89 = TRUE;
ac0860d8 969 initialize_char_syntax (opts);
970}
971
972enum cpp_token
973cppReader_nullUnderflow (/*@unused@*/ cppReader *pfile)
974{
975 return CPP_EOF;
976}
977
978void
979cppReader_nullCleanup (/*@unused@*/ cppBuffer *pbuf,
6fcd0b1e 980 /*@unused@*/ cppReader *pfile)
ac0860d8 981{
982 ;
983}
984
985void
986cppReader_macroCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
987{
988 hashNode macro = pbuf->hnode;
989
990 if (macro->type == T_DISABLED)
991 {
992 macro->type = T_MACRO;
993 }
994
995 if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
996 {
997 sfree (pbuf->buf);
998 pbuf->buf = NULL;
999 }
1000}
1001
1002void
1003cppReader_fileCleanup (cppBuffer *pbuf, /*@unused@*/ cppReader *pfile)
1004{
1005 if (pbuf->buf != NULL)
1006 {
1007 sfree (pbuf->buf);
1008 pbuf->buf = NULL;
1009 }
1010}
1011
1012/* Assuming we have read '/'.
1013 If this is the start of a comment (followed by '*' or '/'),
1014 skip to the end of the comment, and return ' '.
1015 Return EOF if we reached the end of file before the end of the comment.
1016 If not the start of a comment, return '/'. */
1017
1018static int
1019skip_comment (cppReader *pfile, /*@null@*/ long *linep)
1020{
1021 int c = 0;
1022
1023 llassert (pfile->buffer != NULL);
1024 llassert (pfile->buffer->cur != NULL);
1025
1026 while (cppReader_peekC (pfile) == '\\' && cpp_peekN (pfile, 1) == '\n')
1027 {
1028 if (linep != NULL)
1029 {
1030 (*linep)++;
1031 }
1032
1033 cppReader_forward (pfile, 2);
1034 }
1035
1036 if (cppReader_peekC (pfile) == '*')
1037 {
1038 cppReader_forward (pfile, 1);
1039
1040 for (;;)
1041 {
1042 int prev_c = c;
1043 c = cppReader_getC (pfile);
1044
1045 if (c == EOF)
1046 {
1047 return EOF;
1048 }
1049
1050 while (c == (int) '\\' && cppReader_peekC (pfile) == (int) '\n')
1051 {
1052 if (linep != NULL )
1053 {
1054 (*linep)++;
1055 }
1056
1057 cppReader_forward (pfile, 1), c = cppReader_getC (pfile);
1058 }
1059
1060 if (prev_c == (int) '*' && c == (int) '/')
1061 {
1062 return (int) ' ';
1063 }
1064
1065 if (c == (int) '\n' && (linep != NULL))
1066 {
1067 (*linep)++;
1068 }
1069 }
1070 }
1071 else if (cppReader_peekC (pfile) == '/'
1072 && CPPOPTIONS (pfile)->cplusplus_comments)
1073 {
e5f31c00 1074
1075 (void) cppoptgenerror
1076 (FLG_SLASHSLASHCOMMENT,
1077 message ("C++ style // comment"
1078 ),
1079 pfile);
1080
ac0860d8 1081 cppReader_forward (pfile, 1);
1082
1083 for (;;)
1084 {
1085 c = cppReader_getC (pfile);
1086
1087 if (c == EOF)
1088 {
1089 /* Allow hash comment to be terminated by EOF. */
1090 return (int) ' ';
1091 }
1092
1093 while (c == (int) '\\' && cppReader_peekC (pfile) == '\n')
1094 {
1095 cppReader_forward (pfile, 1);
1096 c = cppReader_getC (pfile);
1097
1098 if (linep != NULL)
1099 {
1100 (*linep)++;
1101 }
1102 }
1103
1104 if (c == (int) '\n')
1105 {
1106 /* Don't consider final '\n' to be part of comment. */
1107 cppReader_forward (pfile, -1);
1108 return (int) ' ';
1109 }
1110 }
1111 }
1112 else
1113 {
1114 return (int) '/';
1115 }
1116}
1117
1118/* Skip whitespace \-newline and comments. Does not macro-expand. */
1119int /*@alt void@*/
1120cppSkipHspace (cppReader *pfile)
1121{
1122 int nspaces = 0;
1123
1124 while (TRUE)
1125 {
1126 int c;
1127
1128 llassert (pfile->buffer != NULL);
1129
1130 c = cppReader_peekC (pfile);
1131
1132 if (c == EOF)
1133 {
1134 return 0; /* FIXME */
1135 }
1136
1137 if (is_hor_space[c])
1138 {
1139 if ((c == '\f' || c == '\v') && cppReader_isPedantic (pfile))
1140 cppReader_pedwarn (pfile,
1141 message ("%s in preprocessing directive",
1142 c == '\f'
1143 ? cstring_makeLiteralTemp ("formfeed")
1144 : cstring_makeLiteralTemp ("vertical tab")));
1145
1146 nspaces++;
1147 cppReader_forward (pfile, 1);
1148 }
1149 else if (c == '/')
1150 {
1151 cppReader_forward (pfile, 1);
1152 c = skip_comment (pfile, NULL);
1153
1154 if (c == '/')
1155 {
1156 cppReader_forward (pfile, -1);
1157 }
1158
1159 if (c == EOF || c == '/')
1160 {
1161 return nspaces;
1162 }
1163 }
1164 else if (c == '\\' && cpp_peekN (pfile, 1) == '\n')
1165 {
1166 cppReader_forward (pfile, 2);
1167 }
1168 else if (c == '@' && CPPBUFFER (pfile)->has_escapes
1169 && is_hor_space [cpp_peekN (pfile, 1)])
1170 {
1171 cppReader_forward (pfile, 2);
1172 }
1173 else
1174 {
1175 return nspaces;
1176 }
1177 }
1178}
1179
1180/* Read the rest of the current line.
1181 The line is appended to PFILE's output buffer. */
1182
1183static void
1184copy_rest_of_line (cppReader *pfile)
1185{
1186 struct cppOptions *opts = CPPOPTIONS (pfile);
1187
1188 for (;;)
1189 {
1190 int c;
1191 int nextc;
1192
1193 llassert (pfile->buffer != NULL);
1194
1195 c = cppReader_getC (pfile);
2f2892c2 1196
ac0860d8 1197 switch (c)
1198 {
1199 case EOF:
1200 goto end_directive;
1201 case '\\':
140c27a8 1202 /*
1203 ** Patch from Brian St. Pierre for handling MS-DOS files.
1204 */
1205
2f2892c2 1206 DPRINTF (("Reading directive: %d", (int) c));
1207
140c27a8 1208 if (cppReader_peekC (pfile) == '\n'
1209 || cppReader_peekC (pfile) == '\r')
ac0860d8 1210 {
2f2892c2 1211 DPRINTF (("Reading directive..."));
140c27a8 1212 if (cppReader_peekC (pfile) == '\r')
1213 {
2f2892c2 1214 DPRINTF (("Reading directive..."));
140c27a8 1215 cppReader_forward (pfile, 1);
1216 }
1217
2f2892c2 1218 DPRINTF (("Reading directive..."));
ac0860d8 1219 cppReader_forward (pfile, 1);
1220 continue;
1221 }
1222
2f2892c2 1223 DPRINTF (("Falling..."));
ac0860d8 1224 /*@fallthrough@*/ case '\'': case '\"':
1225 goto scan_directive_token;
1226
1227 case '/':
1228 nextc = cppReader_peekC (pfile);
1229
1230 /*
1231 ** was (opts->cplusplus_comments && nextc == '*')
1232 ** yoikes!
1233 */
1234
1235 if (nextc == '*'
1236 || (opts->cplusplus_comments && nextc == '/'))
1237 {
1238 goto scan_directive_token;
1239 }
1240 /*@switchbreak@*/ break;
1241 case '\f':
1242 case '\v':
1243 if (cppReader_isPedantic (pfile))
1244 cppReader_pedwarn (pfile,
1245 message ("%s in preprocessing directive",
1246 c == '\f'
1247 ? cstring_makeLiteralTemp ("formfeed")
1248 : cstring_makeLiteralTemp ("vertical tab")));
1249 /*@switchbreak@*/ break;
1250
1251 case '\n':
1252 cppReader_forward (pfile, -1);
1253 goto end_directive;
1254 scan_directive_token:
1255 cppReader_forward (pfile, -1);
3e3ec469 1256 (void) cpplib_getToken (pfile);
ac0860d8 1257 continue;
1258 }
1259 cppReader_putChar (pfile, c);
1260 }
1261end_directive: ;
1262 cppReader_nullTerminate (pfile);
1263}
1264
1265void
1266cppReader_skipRestOfLine (cppReader *pfile)
1267{
3e3ec469 1268 size_t old = cpplib_getWritten (pfile);
ac0860d8 1269 copy_rest_of_line (pfile);
1270 cppReader_setWritten (pfile, old);
1271}
1272
1273/* Handle a possible # directive.
1274 '#' has already been read. */
1275
1276int
1277cppReader_handleDirective (cppReader *pfile)
1278{
1279 int c;
1280 struct directive *kt = NULL;
1281 int ident_length;
1282 size_t after_ident = 0;
1283 char *ident = NULL;
1284 char *line_end = NULL;
3e3ec469 1285 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 1286 int nspaces = cppSkipHspace (pfile);
1287
1288 c = cppReader_peekC (pfile);
1289
1290 if (c >= '0' && c <= '9')
1291 {
1292 /* Handle # followed by a line number. */
1293 if (cppReader_isPedantic (pfile))
1294 {
1295 cppReader_pedwarnLit
1296 (pfile,
1297 cstring_makeLiteralTemp ("`#' followed by integer"));
1298 }
1299
1300 (void) do_line (pfile, NULL);
1301 goto done_a_directive;
1302 }
1303
1304
1305 /* Now find the directive name. */
1306
1307 cppReader_putChar (pfile, '#');
1308
1309 parse_name (pfile, cppReader_getC (pfile));
1310
1311 llassert (pfile->token_buffer != NULL);
1312 ident = pfile->token_buffer + old_written + 1;
1313
3e3ec469 1314 ident_length = cpplib_getPWritten (pfile) - ident;
ac0860d8 1315
1316 if (ident_length == 0 && cppReader_peekC (pfile) == '\n')
1317 {
1318 /* A line of just `#' becomes blank. */
1319 return 1;
1320 }
1321
1322 for (kt = directive_table; ; kt++)
1323 {
1324 if (kt->length <= 0)
1325 {
1326 return 0; /* goto not_a_directive; */
1327 }
1328
1329 if (kt->length == ident_length
1330 && (cstring_equalPrefix (kt->name, cstring_fromChars (ident))))
1331 {
1332 break;
1333 }
1334 }
1335
1336 if (kt->command_reads_line)
1337 {
1338 after_ident = 0;
1339 }
1340 else
1341 {
1342 /* Nonzero means do not delete comments within the directive.
1343 #define needs this when -traditional. */
1344 bool comments = 1; /*cppReader_isTraditional (pfile) && kt->traditional_comments; */
1345 int save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
1346 CPPOPTIONS (pfile)->put_out_comments = comments;
3e3ec469 1347 after_ident = cpplib_getWritten (pfile);
ac0860d8 1348 copy_rest_of_line (pfile);
1349 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
1350 }
1351
1352
1353 /* For #pragma and #define, we may want to pass through the directive.
1354 Other directives may create output, but we don't want the directive
1355 itself out, so we pop it now. For example #include may write a #line
1356 command (see comment in do_include), and conditionals may emit
1357 #failed ... #endfailed stuff. But note that popping the buffer
1358 means the parameters to kt->func may point after pfile->limit
1359 so these parameters are invalid as soon as something gets appended
1360 to the token_buffer. */
1361
3e3ec469 1362 line_end = cpplib_getPWritten (pfile);
ac0860d8 1363
1364
1365 if (!kt->pass_thru && kt->type != T_DEFINE)
1366 {
1367 cppReader_setWritten (pfile, old_written);
1368 }
1369
1370 llassert (pfile->token_buffer != NULL);
1371
1372 /* was kt->pass_thru || */
1373
1374 if (kt->type == T_DEFINE
1375 && cpp_shouldCheckMacro (pfile, pfile->token_buffer + old_written))
1376 {
1377 char *p = pfile->token_buffer + old_written;
1378
1379 /*
1380 ** Still need to record value for preprocessing, so
1381 ** #ifdef's, etc. using the value behave correctly.
1382 */
1383
1384 (void) do_defineAux (pfile, kt,
1385 pfile->token_buffer + after_ident,
1386 line_end,
1387 TRUE);
1388
1389 if (*p == '#')
1390 {
1391 *p = ' ';
1392 }
1393
1394 SKIP_WHITE_SPACE (p);
1395
1396 llassert (*p == 'd');
1397 *p++ = LLMRCODE[0];
1398
1399 llassert (*p == 'e');
1400 *p++ = LLMRCODE[1];
1401
1402 llassert (*p == 'f');
1403 *p++ = LLMRCODE[2];
1404
1405 llassert (*p == 'i');
1406 *p++ = LLMRCODE[3];
1407
1408 llassert (*p == 'n');
1409 *p++ = LLMRCODE[4];
1410
1411 llassert (*p == 'e');
1412
1413 /*
1414 ** This is way-bogus. We use the last char to record the number of
1415 ** spaces. Its too hard to get them back into the input stream.
1416 */
1417
1418 if (nspaces > 9) nspaces = 9;
1419
1420 *p++ = '0' + nspaces;
1421
1422 return 0; /* not_a_directive */
1423 }
1424 else if (kt->pass_thru)
1425 {
1426 /* Just leave the entire #define in the output stack. */
1427 return 0; /* not_a_directive */
1428
1429 }
1430 else if (kt->type == T_DEFINE
1431 && CPPOPTIONS (pfile)->dump_macros == DUMP_NAMES)
1432 {
1433 char *p = pfile->token_buffer + old_written + 7; /* Skip "#define". */
1434 SKIP_WHITE_SPACE (p);
1435
1436 while (is_idchar[(int) *p])
1437 {
1438 p++;
1439 }
1440
1441 pfile->limit = p;
1442 cppReader_putChar (pfile, '\n');
1443 }
1444 else if (kt->type == T_DEFINE)
1445 {
1446 cppReader_setWritten (pfile, old_written);
1447 }
1448 else
1449 {
1450 ;
1451 }
1452
1453done_a_directive:
1454 if (kt == NULL) {
1455 return 1;
1456 } else {
1457 llassert (kt->func != NULL);
1458 (void) (kt->func) (pfile, kt, pfile->token_buffer + after_ident, line_end);
1459 return 1;
1460 }
1461}
1462
1463/* Pass a directive through to the output file.
1464 BUF points to the contents of the directive, as a contiguous string.
1465 LIMIT points to the first character past the end of the directive.
1466 KEYWORD is the keyword-table entry for the directive. */
1467
1468static void
1469pass_thru_directive (char *buf, char *limit,
1470 cppReader *pfile,
1471 struct directive *keyword)
1472{
1473 int keyword_length = keyword->length;
1474
3e3ec469 1475 cpplib_reserve (pfile,
ac0860d8 1476 size_fromInt (2 + keyword_length + (limit - buf)));
1477 cppReader_putCharQ (pfile, '#');
1478 /*@-observertrans@*/
1479 cppReader_putStrN (pfile, cstring_toCharsSafe (keyword->name),
1480 size_fromInt (keyword_length));
1481 /*:=observertrans@*/
1482
1483 if (limit != buf && buf[0] != ' ')
1484 {
1485 /* Was a bug, since reserve only used 1 + ... */
1486 cppReader_putCharQ (pfile, ' ');
1487 }
1488
1489 cppReader_putStrN (pfile, buf, size_fromInt (limit - buf));
1490}
1491
1492/* Read a replacement list for a macro with parameters.
1493 Build the DEFINITION structure.
1494 Reads characters of text starting at BUF until END.
1495 ARGLIST specifies the formal parameters to look for
1496 in the text of the definition; NARGS is the number of args
1497 in that list, or -1 for a macro name that wants no argument list.
1498 MACRONAME is the macro name itself (so we can avoid recursive expansion)
1499 and NAMELEN is its length in characters.
1500
1501 Note that comments, backslash-newlines, and leading white space
1502 have already been deleted from the argument. */
1503
1504static DEFINITION *
1505collect_expansion (cppReader *pfile, char *buf, char *limit,
1506 int nargs, /*@null@*/ struct arglist *arglist)
1507{
1508 DEFINITION *defn;
1509 char *p, *lastp, *exp_p;
1510 struct reflist *endpat = NULL;
1511 /* Pointer to first nonspace after last ## seen. */
1512 char *concat = 0;
1513 /* Pointer to first nonspace after last single-# seen. */
1514 char *stringify = 0;
1515 size_t maxsize;
1516 char expected_delimiter = '\0';
1517
1518
1519 /* Scan thru the replacement list, ignoring comments and quoted
1520 strings, picking up on the macro calls. It does a linear search
1521 thru the arg list on every potential symbol. Profiling might say
1522 that something smarter should happen. */
1523
1524 if (limit < buf)
1525 abort ();
1526
1527 /* Find the beginning of the trailing whitespace. */
1528 p = buf;
1529
1530 while (p < limit && is_space[(int) limit[-1]])
1531 {
1532 limit--;
1533 }
1534
1535 /* Allocate space for the text in the macro definition.
1536 Leading and trailing whitespace chars need 2 bytes each.
1537 Each other input char may or may not need 1 byte,
1538 so this is an upper bound. The extra 5 are for invented
1539 leading and trailing newline-marker and final null. */
1540 maxsize = (sizeof (*defn) + (limit - p) + 5);
1541
1542 /* Occurrences of '@' get doubled, so allocate extra space for them. */
1543 while (p < limit)
1544 {
1545 if (*p++ == '@')
1546 {
1547 maxsize++;
1548 }
1549 }
1550
1551 defn = (DEFINITION *) dmalloc (maxsize);
1552 defn->noExpand = FALSE;
1553 defn->file = NULL;
1554 defn->pattern = NULL;
1555 defn->nargs = nargs;
1556 defn->predefined = NULL;
1557
1558 exp_p = defn->expansion = (char *) defn + sizeof (*defn);
1559
1560 defn->line = 0;
1561 defn->rest_args = NULL;
1562 defn->args.argnames = NULL;
1563
1564 lastp = exp_p;
1565
1566 p = buf;
1567
1568 /* Add one initial space escape-marker to prevent accidental
3e3ec469 1569 token-pasting (often removed by cpplib_macroExpand). */
ac0860d8 1570 *exp_p++ = '@';
1571 *exp_p++ = ' ';
1572
1573 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
1574 cppReader_errorLit (pfile,
1575 cstring_makeLiteralTemp ("`##' at start of macro definition"));
1576 p += 2;
1577 }
1578
1579 /* Process the main body of the definition. */
1580 while (p < limit) {
1581 int skipped_arg = 0;
1582 register char c = *p++;
1583
1584 *exp_p++ = c;
1585
1586 if (!cppReader_isTraditional (pfile)) {
1587 switch (c) {
1588 case '\'':
1589 case '\"':
1590 if (expected_delimiter != '\0')
1591 {
1592 if (c == expected_delimiter)
1593 expected_delimiter = '\0';
1594 }
1595 else
1596 {
1597 expected_delimiter = c;
1598 }
1599 /*@switchbreak@*/ break;
1600
1601 case '\\':
1602 if (p < limit && (expected_delimiter != '\0'))
1603 {
1604 /* In a string, backslash goes through
1605 and makes next char ordinary. */
1606 *exp_p++ = *p++;
1607 }
1608 /*@switchbreak@*/ break;
1609
1610 case '@':
1611 /* An '@' in a string or character constant stands for itself,
1612 and does not need to be escaped. */
1613 if (expected_delimiter == '\0')
1614 {
1615 *exp_p++ = c;
1616 }
1617
1618 /*@switchbreak@*/ break;
1619
1620 case '#':
1621 /* # is ordinary inside a string. */
1622 if (expected_delimiter != '\0')
1623 {
1624 /*@switchbreak@*/ break;
1625 }
1626
1627 if (p < limit && *p == '#') {
1628 /* ##: concatenate preceding and following tokens. */
1629 /* Take out the first #, discard preceding whitespace. */
1630 exp_p--;
1631
1632 /*@-usedef@*/
1633 while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
1634 {
1635 --exp_p;
1636 }
1637 /*@=usedef@*/
1638
1639 /* Skip the second #. */
1640 p++;
1641 /* Discard following whitespace. */
1642 SKIP_WHITE_SPACE (p);
1643 concat = p;
1644 if (p == limit)
1645 {
1646 cppReader_errorLit (pfile,
1647 cstring_makeLiteralTemp ("`##' at end of macro definition"));
1648 }
1649 } else if (nargs >= 0) {
1650 /* Single #: stringify following argument ref.
1651 Don't leave the # in the expansion. */
1652 exp_p--;
1653 SKIP_WHITE_SPACE (p);
1654 if (p == limit || ! is_idstart[(int) *p]
ee229125 1655 || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"')))
ac0860d8 1656 cppReader_errorLit (pfile,
1657 cstring_makeLiteralTemp ("`#' operator is not followed by a macro argument name"));
1658 else
1659 stringify = p;
1660 } else {
1661 ; /* BADBRANCH; */
1662 }
1663
1664 /*@switchbreak@*/ break;
1665 }
1666 } else {
1667 /* In -traditional mode, recognize arguments inside strings and
1668 and character constants, and ignore special properties of #.
1669 Arguments inside strings are considered "stringified", but no
1670 extra quote marks are supplied. */
1671 switch (c) {
1672 case '\'':
1673 case '\"':
1674 if (expected_delimiter != '\0') {
1675 if (c == expected_delimiter)
1676 expected_delimiter = '\0';
1677 } else
1678 expected_delimiter = c;
1679 /*@switchbreak@*/ break;
1680
1681 case '\\':
1682 /* Backslash quotes delimiters and itself, but not macro args. */
1683 if (expected_delimiter != '\0' && p < limit
1684 && (*p == expected_delimiter || *p == '\\')) {
1685 *exp_p++ = *p++;
1686 continue;
1687 }
1688 /*@switchbreak@*/ break;
1689
1690 case '/':
1691 if (expected_delimiter != '\0') /* No comments inside strings. */
1692 /*@switchbreak@*/ break;
1693 if (*p == '*') {
1694 /* If we find a comment that wasn't removed by cppReader_handleDirective,
1695 this must be -traditional. So replace the comment with
1696 nothing at all. */
1697 exp_p--;
1698 p += 1;
1699 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
1700 {
1701 p++;
1702 }
1703 }
1704 /*@switchbreak@*/ break;
1705 }
1706 }
1707
1708 /* Handle the start of a symbol. */
1709 if (is_idchar[(int) c] && nargs > 0) {
1710 char *id_beg = p - 1;
abd7f895 1711 size_t id_len;
ac0860d8 1712
1713 --exp_p;
1714 while (p != limit && is_idchar[(int) *p])
1715 {
1716 p++;
1717 }
1718
abd7f895 1719 id_len = size_fromInt (p - id_beg);
ac0860d8 1720
1721 if (is_idstart[(int) c]
ee229125 1722 && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
ac0860d8 1723 register struct arglist *arg;
1724
1725 for (arg = arglist; arg != NULL; arg = arg->next) {
1726 struct reflist *tpat;
1727
1728 if (arg->name[0] == c
1729 && arg->length == id_len
abd7f895 1730 && strncmp (arg->name, id_beg, id_len) == 0) {
ac0860d8 1731 char *p1;
1732
1733 if (expected_delimiter && CPPOPTIONS (pfile)->warn_stringify) {
1734 if (cppReader_isTraditional (pfile)) {
1735 cppReader_warning (pfile,
1736 message ("macro argument `%x' is stringified.",
1737 cstring_prefix (cstring_fromChars (arg->name), id_len)));
1738 } else {
3e3ec469 1739 cppReader_warning (pfile,
1740 message ("macro arg `%x' would be stringified with -traditional.",
1741 cstring_prefix (cstring_fromChars (arg->name), id_len)));
1742 }
1743 }
1744 /* If ANSI, don't actually substitute inside a string. */
1745 if (!cppReader_isTraditional (pfile) && expected_delimiter)
1746 /*@innerbreak@*/ break;
1747 /* make a pat node for this arg and append it to the end of
1748 the pat list */
1749 tpat = (struct reflist *) dmalloc (sizeof (*tpat));
1750 tpat->next = NULL;
1751 tpat->raw_before = (concat == id_beg);
1752 tpat->raw_after = 0;
1753 tpat->rest_args = arg->rest_args;
1754 tpat->stringify = (cppReader_isTraditional (pfile)
1755 ? expected_delimiter != '\0'
1756 : stringify == id_beg);
1757
1758 if (endpat == NULL)
1759 {
1760 defn->pattern = tpat;
1761 }
1762 else
1763 {
1764 endpat->next = tpat;
1765 /*@-branchstate@*/
1766 } /*@=branchstate@*/ /* evs 2000 was =branchstate */
1767
1768 endpat = tpat;
1769
1770 tpat->argno = arg->argno;
1771 tpat->nchars = exp_p - lastp;
1772
1773 p1 = p;
1774
1775 SKIP_WHITE_SPACE (p1);
1776
1777 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
1778 {
1779 tpat->raw_after = 1;
1780 }
1781
1782 lastp = exp_p; /* place to start copying from next time */
1783 skipped_arg = 1;
1784
1785 /*@innerbreak@*/ break;
1786 }
1787 }
1788 }
1789
1790 /* If this was not a macro arg, copy it into the expansion. */
1791 if (skipped_arg == 0) {
1792 register char *lim1 = p;
1793 p = id_beg;
1794
1795 while (p != lim1)
1796 {
1797 *exp_p++ = *p++;
1798 }
1799
1800 if (stringify == id_beg)
1801 cppReader_errorLit (pfile,
1802 cstring_makeLiteralTemp ("`#' operator should be followed by a macro argument name"));
1803 }
1804 }
1805 }
1806
1807 if (!cppReader_isTraditional (pfile) && expected_delimiter == '\0')
1808 {
1809 /* If ANSI, put in a "@ " marker to prevent token pasting.
1810 But not if "inside a string" (which in ANSI mode
1811 happens only for -D option). */
1812 *exp_p++ = '@';
1813 *exp_p++ = ' ';
1814 }
1815
1816 *exp_p = '\0';
1817
1818 defn->length = size_fromInt (exp_p - defn->expansion);
1819
1820 /* Crash now if we overrun the allocated size. */
1821 if (defn->length + 1 > maxsize)
1822 {
1823 llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
1824 }
1825
1826 return defn;
1827}
1828
1829/*
1830** evans 2001-12-31
1831** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
1832*/
1833
1834static DEFINITION *
1835collect_expansionLoc (fileloc loc, char *buf, char *limit,
1836 int nargs, /*@null@*/ struct arglist *arglist)
1837{
1838 DEFINITION *defn;
1839 char *p, *lastp, *exp_p;
1840 struct reflist *endpat = NULL;
1841 /* Pointer to first nonspace after last ## seen. */
1842 char *concat = 0;
1843 /* Pointer to first nonspace after last single-# seen. */
1844 char *stringify = 0;
1845 size_t maxsize;
1846 char expected_delimiter = '\0';
1847
1848
1849 /* Scan thru the replacement list, ignoring comments and quoted
1850 strings, picking up on the macro calls. It does a linear search
1851 thru the arg list on every potential symbol. Profiling might say
1852 that something smarter should happen. */
1853
1854 if (limit < buf)
1855 {
1856 llfatalbug (message ("%q: Limit is less than initial buffer pointer",
1857 fileloc_unparse (loc)));
1858 }
1859
1860 /* Find the beginning of the trailing whitespace. */
1861 p = buf;
1862
1863 while (p < limit && is_space[(int) limit[-1]])
1864 {
1865 limit--;
1866 }
1867
1868 /* Allocate space for the text in the macro definition.
1869 Leading and trailing whitespace chars need 2 bytes each.
1870 Each other input char may or may not need 1 byte,
1871 so this is an upper bound. The extra 5 are for invented
1872 leading and trailing newline-marker and final null. */
1873 maxsize = (sizeof (*defn) + (limit - p) + 5);
1874
1875 /* Occurrences of '@' get doubled, so allocate extra space for them. */
1876 while (p < limit)
1877 {
1878 if (*p++ == '@')
1879 {
1880 maxsize++;
1881 }
1882 }
1883
1884 defn = (DEFINITION *) dmalloc (maxsize);
1885 defn->noExpand = FALSE;
1886 defn->file = NULL;
1887 defn->pattern = NULL;
1888 defn->nargs = nargs;
1889 defn->predefined = NULL;
1890
1891 exp_p = defn->expansion = (char *) defn + sizeof (*defn);
1892
1893 defn->line = 0;
1894 defn->rest_args = NULL;
1895 defn->args.argnames = NULL;
1896
1897 lastp = exp_p;
1898
1899 p = buf;
1900
1901 /* Add one initial space escape-marker to prevent accidental
1902 token-pasting (often removed by cpplib_macroExpand). */
1903 *exp_p++ = '@';
1904 *exp_p++ = ' ';
1905
1906 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
1907 voptgenerror (FLG_PREPROC,
1908 cstring_makeLiteral ("Paste marker ## at start of macro definition"),
1909 loc);
1910 p += 2;
1911 }
1912
1913 /* Process the main body of the definition. */
1914 while (p < limit) {
1915 int skipped_arg = 0;
1916 register char c = *p++;
1917
1918 *exp_p++ = c;
1919
1920 if (TRUE) { /* !cppReader_isTraditional (pfile)) { */
1921 switch (c) {
1922 case '\'':
1923 case '\"':
1924 if (expected_delimiter != '\0')
1925 {
1926 if (c == expected_delimiter)
1927 expected_delimiter = '\0';
1928 }
1929 else
1930 {
1931 expected_delimiter = c;
1932 }
1933 /*@switchbreak@*/ break;
1934
1935 case '\\':
1936 if (p < limit && (expected_delimiter != '\0'))
1937 {
1938 /* In a string, backslash goes through
1939 and makes next char ordinary. */
1940 *exp_p++ = *p++;
1941 }
1942 /*@switchbreak@*/ break;
1943
1944 case '@':
1945 /* An '@' in a string or character constant stands for itself,
1946 and does not need to be escaped. */
1947 if (expected_delimiter == '\0')
1948 {
1949 *exp_p++ = c;
1950 }
1951
1952 /*@switchbreak@*/ break;
1953
1954 case '#':
1955 /* # is ordinary inside a string. */
1956 if (expected_delimiter != '\0')
1957 {
1958 /*@switchbreak@*/ break;
1959 }
1960
1961 if (p < limit && *p == '#') {
1962 /* ##: concatenate preceding and following tokens. */
1963 /* Take out the first #, discard preceding whitespace. */
1964 exp_p--;
1965
1966 /*@-usedef@*/
1967 while (exp_p > lastp && is_hor_space[(int) exp_p[-1]])
1968 {
1969 --exp_p;
1970 }
1971 /*@=usedef@*/
1972
1973 /* Skip the second #. */
1974 p++;
1975 /* Discard following whitespace. */
1976 SKIP_WHITE_SPACE (p);
1977 concat = p;
1978 if (p == limit)
1979 {
1980 voptgenerror (FLG_PREPROC,
1981 cstring_makeLiteral ("`##' at end of macro definition"),
1982 loc);
1983 }
1984 } else if (nargs >= 0) {
1985 /* Single #: stringify following argument ref.
1986 Don't leave the # in the expansion. */
1987 exp_p--;
1988 SKIP_WHITE_SPACE (p);
1989 if (p == limit || ! is_idstart[(int) *p]
1990 || (*p == 'L' && p + 1 < limit && (p[1] == '\'' || p[1] == '\"')))
1991 {
1992 voptgenerror
1993 (FLG_PREPROC,
1994 cstring_makeLiteral ("`#' operator is not followed by a macro argument name"),
1995 loc);
1996 }
1997 else
1998 stringify = p;
1999 } else {
2000 ; /* BADBRANCH; */
2001 }
2002
2003 /*@switchbreak@*/ break;
2004 }
2005 } else {
2006 /* In -traditional mode, recognize arguments inside strings and
2007 and character constants, and ignore special properties of #.
2008 Arguments inside strings are considered "stringified", but no
2009 extra quote marks are supplied. */
2010 switch (c) {
2011 case '\'':
2012 case '\"':
2013 if (expected_delimiter != '\0') {
2014 if (c == expected_delimiter)
2015 expected_delimiter = '\0';
2016 } else
2017 expected_delimiter = c;
2018 /*@switchbreak@*/ break;
2019
2020 case '\\':
2021 /* Backslash quotes delimiters and itself, but not macro args. */
2022 if (expected_delimiter != '\0' && p < limit
2023 && (*p == expected_delimiter || *p == '\\')) {
2024 *exp_p++ = *p++;
2025 continue;
2026 }
2027 /*@switchbreak@*/ break;
abd7f895 2028
3e3ec469 2029 case '/':
2030 if (expected_delimiter != '\0') /* No comments inside strings. */
2031 /*@switchbreak@*/ break;
2032 if (*p == '*') {
2033 /* If we find a comment that wasn't removed by cppReader_handleDirective,
2034 this must be -traditional. So replace the comment with
2035 nothing at all. */
2036 exp_p--;
2037 p += 1;
2038 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
2039 {
2040 p++;
2041 }
2042 }
2043 /*@switchbreak@*/ break;
2044 }
2045 }
2046
2047 /* Handle the start of a symbol. */
2048 if (is_idchar[(int) c] && nargs > 0) {
2049 char *id_beg = p - 1;
abd7f895 2050 size_t id_len;
3e3ec469 2051
2052 --exp_p;
2053 while (p != limit && is_idchar[(int) *p])
2054 {
2055 p++;
2056 }
2057
abd7f895 2058 id_len = size_fromInt (p - id_beg);
3e3ec469 2059
2060 if (is_idstart[(int) c]
2061 && ! (id_len == 1 && c == 'L' && (*p == '\'' || *p == '\"'))) {
2062 register struct arglist *arg;
2063
2064 for (arg = arglist; arg != NULL; arg = arg->next) {
2065 struct reflist *tpat;
2066
2067 if (arg->name[0] == c
2068 && arg->length == id_len
abd7f895 2069 && strncmp (arg->name, id_beg, id_len) == 0) {
3e3ec469 2070 char *p1;
2071
2072 if (expected_delimiter) { /* && CPPOPTIONS (pfile)->warn_stringify) { */
2073 if (FALSE) { /* cppReader_isTraditional (pfile)) { */
2074 voptgenerror (FLG_PREPROC,
2075 message ("macro argument `%x' is stringified.",
2076 cstring_prefix (cstring_fromChars (arg->name), id_len)),
2077 loc);
2078
2079 } else {
2080 voptgenerror (FLG_PREPROC,
2081 message ("Macro arg `%x' would be stringified with -traditional.",
2082 cstring_prefix (cstring_fromChars (arg->name), id_len)),
2083 loc);
2084
ac0860d8 2085 }
2086 }
2087 /* If ANSI, don't actually substitute inside a string. */
3e3ec469 2088 if (TRUE /* !cppReader_isTraditional (pfile) */ && expected_delimiter)
ac0860d8 2089 /*@innerbreak@*/ break;
2090 /* make a pat node for this arg and append it to the end of
2091 the pat list */
2092 tpat = (struct reflist *) dmalloc (sizeof (*tpat));
2093 tpat->next = NULL;
2094 tpat->raw_before = (concat == id_beg);
2095 tpat->raw_after = 0;
2096 tpat->rest_args = arg->rest_args;
3e3ec469 2097 tpat->stringify = (FALSE /* cppReader_isTraditional (pfile) */
ac0860d8 2098 ? expected_delimiter != '\0'
2099 : stringify == id_beg);
2100
2101 if (endpat == NULL)
2102 {
2103 defn->pattern = tpat;
2104 }
2105 else
2106 {
2107 endpat->next = tpat;
2108 /*@-branchstate@*/
2109 } /*@=branchstate@*/ /* evs 2000 was =branchstate */
2110
2111 endpat = tpat;
2112
2113 tpat->argno = arg->argno;
2114 tpat->nchars = exp_p - lastp;
2115
2116 p1 = p;
2117
2118 SKIP_WHITE_SPACE (p1);
2119
2120 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
2121 {
2122 tpat->raw_after = 1;
2123 }
2124
2125 lastp = exp_p; /* place to start copying from next time */
2126 skipped_arg = 1;
2127
2128 /*@innerbreak@*/ break;
2129 }
2130 }
2131 }
2132
2133 /* If this was not a macro arg, copy it into the expansion. */
2134 if (skipped_arg == 0) {
2135 register char *lim1 = p;
2136 p = id_beg;
2137
2138 while (p != lim1)
2139 {
2140 *exp_p++ = *p++;
2141 }
2142
2143 if (stringify == id_beg)
3e3ec469 2144 {
2145 voptgenerror
2146 (FLG_PREPROC,
2147 cstring_makeLiteral ("# operator should be followed by a macro argument name"),
2148 loc);
2149 }
ac0860d8 2150 }
2151 }
2152 }
2153
3e3ec469 2154 if (/*!cppReader_isTraditional (pfile) && */ expected_delimiter == '\0')
ac0860d8 2155 {
2156 /* If ANSI, put in a "@ " marker to prevent token pasting.
2157 But not if "inside a string" (which in ANSI mode
2158 happens only for -D option). */
2159 *exp_p++ = '@';
2160 *exp_p++ = ' ';
2161 }
2162
2163 *exp_p = '\0';
2164
2165 defn->length = size_fromInt (exp_p - defn->expansion);
2166
2167 /* Crash now if we overrun the allocated size. */
2168 if (defn->length + 1 > maxsize)
2169 {
2170 llfatalbug (cstring_makeLiteral ("Maximum definition size exceeded."));
2171 }
2172
2173 return defn;
2174}
2175
2176/*
2177 * special extension string that can be added to the last macro argument to
2178 * allow it to absorb the "rest" of the arguments when expanded. Ex:
2179 * #define wow(a, b...) process (b, a, b)
2180 * { wow (1, 2, 3); } -> { process (2, 3, 1, 2, 3); }
2181 * { wow (one, two); } -> { process (two, one, two); }
2182 * if this "rest_arg" is used with the concat token '##' and if it is not
2183 * supplied then the token attached to with ## will not be outputted. Ex:
2184 * #define wow (a, b...) process (b ## , a, ## b)
2185 * { wow (1, 2); } -> { process (2, 1, 2); }
2186 * { wow (one); } -> { process (one); {
2187 */
2188
2189/*@-readonlytrans@*/
2190static char rest_extension[] = "...";
2191/*:=readonlytrans@*/
2192
2193/*@notfunction@*/
2194#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
2195
2196/* Create a DEFINITION node from a #define directive. Arguments are
2197 as for do_define. */
2198
abd7f895 2199
3e3ec469 2200static /*@null@*/ macroDef
2209bcb7 2201create_definition (/*@exposed@*/ char *buf, char *limit,
ac0860d8 2202 cppReader *pfile, bool predefinition,
2203 bool noExpand)
2204{
2205 char *bp; /* temp ptr into input buffer */
2206 char *symname; /* remember where symbol name starts */
abd7f895 2207 size_t sym_length; /* and how long it is */
ac0860d8 2208 int rest_args = 0; /* really int! */
2209 int line;
2210 int col;
2211 cstring file = (CPPBUFFER (pfile) != NULL)
2212 ? CPPBUFFER (pfile)->nominal_fname : cstring_makeLiteralTemp ("");
2213 DEFINITION *defn;
2214 int arglengths = 0; /* Accumulate lengths of arg names
2215 plus number of args. */
3e3ec469 2216 macroDef mdef;
2217 char save = *limit;
2218 *limit = '\0';
2219 DPRINTF (("Create definition: %s", buf));
2220 *limit = save;
ac0860d8 2221
80489f0a 2222 cppBuffer_getLineAndColumn (CPPBUFFER (pfile), &line, &col);
ac0860d8 2223
2224 bp = buf;
2225
2226 while (is_hor_space[(int) *bp])
2227 {
2228 bp++;
2229 }
2230
2231 symname = bp; /* remember where it starts */
2232
2233 sym_length = cppReader_checkMacroName (pfile, bp, cstring_makeLiteralTemp ("macro"));
2234
2235 bp += sym_length;
2236
2237 /* Lossage will occur if identifiers or control keywords are broken
2238 across lines using backslash. This is not the right place to take
2239 care of that. */
2240
2241 if (*bp == '(') {
2242 struct arglist *arg_ptrs = NULL;
2243 int argno = 0;
2244
2245 bp++; /* skip '(' */
2246 SKIP_WHITE_SPACE (bp);
2247
2248 /* Loop over macro argument names. */
2249 while (*bp != ')')
2250 {
2251 struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
2252 temp->name = bp;
2253 temp->next = arg_ptrs;
2254 temp->argno = argno++;
2255 temp->rest_args = 0;
2256
2257 arg_ptrs = temp;
2258
2259 if (rest_args != 0)
2260 {
2261 cppReader_pedwarn (pfile,
2262 message ("another parameter follows `%s'",
2263 cstring_fromChars (rest_extension)));
2264 }
2265
2266 if (!is_idstart[(int) *bp])
2267 {
2268 cppReader_pedwarnLit (pfile,
6fcd0b1e 2269 cstring_makeLiteralTemp ("Invalid character in macro parameter name"));
ac0860d8 2270 }
2271
2272 /* Find the end of the arg name. */
2273 while (is_idchar[(int) *bp])
2274 {
2275 bp++;
2276 /* do we have a "special" rest-args extension here? */
2277 if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
2278 && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
2279 {
2280 rest_args = 1;
2281 temp->rest_args = 1;
2282 /*@innerbreak@*/ break;
2283 }
2284 }
2285
abd7f895 2286 temp->length = size_fromInt (bp - temp->name);
ac0860d8 2287
2288 if (rest_args != 0)
2289 {
2290 bp += REST_EXTENSION_LENGTH;
2291 }
2292
2293 arglengths += temp->length + 2;
2294 SKIP_WHITE_SPACE (bp);
2295
2296 if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
2297 cppReader_errorLit (pfile,
2298 cstring_makeLiteralTemp ("Parameter list for #define is not parseable"));
2299 goto nope;
2300 }
2301
2302 if (*bp == ',') {
2303 bp++;
2304 SKIP_WHITE_SPACE (bp);
2305 }
2306 if (bp >= limit) {
2307 cppReader_errorLit (pfile,
2308 cstring_makeLiteralTemp ("unterminated parameter list in `#define'"));
2309 goto nope;
2310 }
2311 {
2312 struct arglist *otemp;
2313
2314 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
2315 {
2316 if (temp->length == otemp->length &&
abd7f895 2317 strncmp (temp->name, otemp->name, temp->length) == 0) {
ac0860d8 2318 cstring name = cstring_copyLength (temp->name, temp->length);
2319 cppReader_error (pfile,
2320 message ("duplicate argument name `%x' in `#define'", name));
2321 goto nope;
2322 }
2323 }
2324 }
2325 }
abd7f895 2326
ac0860d8 2327 ++bp; /* skip paren */
2328 SKIP_WHITE_SPACE (bp);
2329 /* now everything from bp before limit is the definition. */
2330 defn = collect_expansion (pfile, bp, limit, argno, arg_ptrs);
2331 defn->rest_args = rest_args;
2332
2333 /* Now set defn->args.argnames to the result of concatenating
2334 the argument names in reverse order
2335 with comma-space between them. */
2336 defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
abd7f895 2337
ac0860d8 2338 {
2339 struct arglist *temp;
2340 int i = 0;
abd7f895 2341 for (temp = arg_ptrs; temp != NULL; temp = temp->next)
2342 {
2343 memcpy (&defn->args.argnames[i], temp->name, temp->length);
2344 i += temp->length;
2345 if (temp->next != 0)
2346 {
2347 defn->args.argnames[i++] = ',';
2348 defn->args.argnames[i++] = ' ';
2349 }
ac0860d8 2350 }
abd7f895 2351
ac0860d8 2352 defn->args.argnames[i] = '\0';
2353 }
2354
2355 sfree (arg_ptrs);
2356 } else {
2357 /* Simple expansion or empty definition. */
2358
2359 if (bp < limit)
2360 {
2361 if (is_hor_space[(int) *bp]) {
2362 bp++;
2363 SKIP_WHITE_SPACE (bp);
2364 } else {
2365 switch (*bp) {
ee229125 2366 case '!': case '\"': case '#': case '%': case '&': case '\'':
ac0860d8 2367 case ')': case '*': case '+': case ',': case '-': case '.':
2368 case '/': case ':': case ';': case '<': case '=': case '>':
2369 case '?': case '[': case '\\': case ']': case '^': case '{':
2370 case '|': case '}': case '~':
2371 cppReader_warning (pfile,
2372 message ("Missing white space after #define %x",
2373 cstring_prefix (cstring_fromChars (symname),
2374 sym_length)));
2375 break;
2376
2377 default:
2378 cppReader_pedwarn (pfile,
2379 message ("Missing white space after #define %x",
2380 cstring_prefix (cstring_fromChars (symname),
2381 sym_length)));
2382 break;
2383 }
2384 }
2385 }
2386 /* now everything from bp before limit is the definition. */
2387 defn = collect_expansion (pfile, bp, limit, -1, NULL);
2388 defn->args.argnames = mstring_createEmpty ();
2389 }
2390
2391 defn->noExpand = noExpand;
2392 DPRINTF (("No expand: %d", noExpand));
2393
2394 defn->line = line;
2395
2396 /* not: llassert (cstring_isUndefined (defn->file)); */
2397 defn->file = file;
2398
2399 /* OP is null if this is a predefinition */
2400 defn->predefined = predefinition;
2401 mdef.defn = defn;
2402 mdef.symnam = symname;
2403 mdef.symlen = sym_length;
2404
2405 return mdef;
2406
2407nope:
2408 mdef.defn = NULL;
2409 mdef.symnam = NULL;
2410 return mdef;
2411}
2412
3e3ec469 2413/*@null@*/ macroDef
2414cpplib_createDefinition (cstring def,
2415 fileloc loc,
2416 bool predefinition,
2417 bool noExpand)
2418{
2419 char *buf = cstring_toCharsSafe (def);
2420 char *limit = buf + cstring_length (def);
2421 char *bp; /* temp ptr into input buffer */
2422 char *symname; /* remember where symbol name starts */
abd7f895 2423 size_t sym_length; /* and how long it is */
3e3ec469 2424 int rest_args = 0; /* really int! */
2425 int line = fileloc_lineno (loc);
2426 cstring file = fileloc_filename (loc);
2427 DEFINITION *defn;
2428 int arglengths = 0; /* Accumulate lengths of arg names
2429 plus number of args. */
2430 macroDef mdef;
2431
2432 bp = buf;
2433
2434 DPRINTF (("Creating definition: %s", buf));
2435
2436 while (is_hor_space[(int) *bp])
2437 {
2438 bp++;
2439 }
2440
2441 symname = bp; /* remember where it starts */
2442
2443 sym_length = cppReader_checkMacroNameLoc (loc, symname, cstring_makeLiteralTemp ("macro"));
2444
2445 DPRINTF (("length: %d", sym_length));
2446
2447 bp += sym_length;
2448
2449 DPRINTF (("Here: %s", bp));
2450
2451 /* Lossage will occur if identifiers or control keywords are broken
2452 across lines using backslash. This is not the right place to take
2453 care of that. */
2454
2455 if (*bp == '(') {
2456 struct arglist *arg_ptrs = NULL;
2457 int argno = 0;
abd7f895 2458
3e3ec469 2459 bp++; /* skip '(' */
2460 SKIP_WHITE_SPACE (bp);
2461
2462 /* Loop over macro argument names. */
2463 while (*bp != ')')
2464 {
2465 struct arglist *temp = (struct arglist *) dmalloc (sizeof (*temp));
2466 temp->name = bp;
2467 temp->next = arg_ptrs;
2468 temp->argno = argno++;
2469 temp->rest_args = 0;
2470
2471 arg_ptrs = temp;
2472
2473 if (rest_args != 0)
2474 {
2475 voptgenerror (FLG_PREPROC,
2476 message ("Another parameter follows %s",
2477 cstring_fromChars (rest_extension)),
2478 loc);
2479 }
2480
2481 if (!is_idstart[(int) *bp])
2482 {
2483 voptgenerror (FLG_PREPROC,
2484 message ("Invalid character in macro parameter name: %c", *bp),
2485 loc);
2486 }
2487
2488 /* Find the end of the arg name. */
2489 while (is_idchar[(int) *bp])
2490 {
2491 bp++;
2492 /* do we have a "special" rest-args extension here? */
2493 if (limit - bp > size_toInt (REST_EXTENSION_LENGTH)
2494 && strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)
2495 {
2496 rest_args = 1;
2497 temp->rest_args = 1;
2498 /*@innerbreak@*/ break;
2499 }
2500 }
2501
abd7f895 2502 temp->length = size_fromInt (bp - temp->name);
3e3ec469 2503
2504 if (rest_args != 0)
2505 {
2506 bp += REST_EXTENSION_LENGTH;
2507 }
2508
2509 arglengths += temp->length + 2;
2510 SKIP_WHITE_SPACE (bp);
2511
2512 if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
2513 voptgenerror (FLG_PREPROC,
2514 cstring_makeLiteral ("Parameter list for #define is not parseable"),
2515 loc);
2516 goto nope;
2517 }
2518
2519 if (*bp == ',') {
2520 bp++;
2521 SKIP_WHITE_SPACE (bp);
2522 }
2523 if (bp >= limit) {
2524 voptgenerror (FLG_PREPROC,
2525 cstring_makeLiteral ("Unterminated parameter list in #define'"),
2526 loc);
2527 goto nope;
2528 }
2529 {
2530 struct arglist *otemp;
2531
2532 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
2533 {
2534 if (temp->length == otemp->length &&
abd7f895 2535 strncmp (temp->name, otemp->name, temp->length) == 0) {
3e3ec469 2536 cstring name = cstring_copyLength (temp->name, temp->length);
2537
2538 voptgenerror (FLG_PREPROC,
2539 message ("Duplicate argument name in #define: %s", name),
2540 loc);
2541 goto nope;
2542 }
2543 }
2544 }
2545 }
2546
2547 ++bp; /* skip paren */
2548 SKIP_WHITE_SPACE (bp);
2549 /* now everything from bp before limit is the definition. */
2550 defn = collect_expansionLoc (loc, bp, limit, argno, arg_ptrs);
2551 defn->rest_args = rest_args;
2552
2553 /* Now set defn->args.argnames to the result of concatenating
2554 the argument names in reverse order
2555 with comma-space between them. */
2556 defn->args.argnames = (char *) dmalloc (size_fromInt (arglengths + 1));
2557
2558 {
2559 struct arglist *temp;
2560 int i = 0;
2561 for (temp = arg_ptrs; temp != NULL; temp = temp->next) {
abd7f895 2562 memcpy (&defn->args.argnames[i], temp->name, temp->length);
3e3ec469 2563 i += temp->length;
2564 if (temp->next != 0) {
2565 defn->args.argnames[i++] = ',';
2566 defn->args.argnames[i++] = ' ';
2567 }
2568 }
2569
2570 defn->args.argnames[i] = '\0';
2571 }
2572
2573 sfree (arg_ptrs);
2574 } else {
2575 /* Simple expansion or empty definition. */
2576
2577 if (bp < limit)
2578 {
2579 if (is_hor_space[(int) *bp]) {
2580 bp++;
2581 SKIP_WHITE_SPACE (bp);
2582 } else {
2583 switch (*bp) {
2584 case '!': case '\"': case '#': case '%': case '&': case '\'':
2585 case ')': case '*': case '+': case ',': case '-': case '.':
2586 case '/': case ':': case ';': case '<': case '=': case '>':
2587 case '?': case '[': case '\\': case ']': case '^': case '{':
2588 case '|': case '}': case '~':
2589 voptgenerror (FLG_PREPROC,
2590 message ("Missing white space after #define %x",
2591 cstring_prefix (cstring_fromChars (symname),
2592 sym_length)),
2593 loc);
2594 break;
2595
2596 default:
2597 voptgenerror (FLG_PREPROC,
2598 message ("Missing white space after #define %x",
2599 cstring_prefix (cstring_fromChars (symname),
2600 sym_length)),
2601 loc);
2602 break;
2603 }
2604 }
2605 }
2606
2607 /* now everything from bp before limit is the definition. */
2608 llassert (limit > bp);
2609 defn = collect_expansionLoc (loc, bp, limit, -1, NULL);
2610 defn->args.argnames = mstring_createEmpty ();
2611 }
2612
2613 defn->noExpand = noExpand;
2614 DPRINTF (("No expand: %d", noExpand));
2615
2616 defn->line = line;
2617
2618 /* not: llassert (cstring_isUndefined (defn->file)); */
2619 defn->file = file;
2620
2621 /* OP is null if this is a predefinition */
2622 defn->predefined = predefinition;
2623
2624 mdef.defn = defn;
2625 mdef.symnam = symname;
2626 mdef.symlen = sym_length;
2627
2628 return mdef;
2629
2630nope:
2631 mdef.defn = NULL;
2632 mdef.symnam = NULL;
2633 return mdef;
2634}
2635
ac0860d8 2636/* Check a purported macro name SYMNAME, and yield its length.
2637 USAGE is the kind of name this is intended for. */
2638
abd7f895 2639size_t cppReader_checkMacroName (cppReader *pfile, char *symname, cstring usage)
ac0860d8 2640{
2641 char *p;
2642 size_t sym_length;
3e3ec469 2643
ac0860d8 2644 for (p = symname; is_idchar[(int) *p]; p++)
2645 {
2646 ;
2647 }
3e3ec469 2648
ac0860d8 2649 sym_length = size_fromInt (p - symname);
3e3ec469 2650
ac0860d8 2651 if (sym_length == 0
ee229125 2652 || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"')))
3e3ec469 2653 {
2654 cppReader_error (pfile, message ("invalid %s name", usage));
2655 }
ac0860d8 2656 else if (!is_idstart[(int) *symname])
2657 {
2658 char *msg = (char *) dmalloc (sym_length + 1);
2659 memcpy (msg, symname, sym_length);
2660 msg[sym_length] = '\0';
2661 cppReader_error (pfile, message ("invalid %s name `%s'", usage,
2662 cstring_fromChars (msg)));
2663 sfree (msg);
2664 }
2665 else
2666 {
2667 if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
2668 {
2669 cppReader_error (pfile, message ("invalid %s name `defined'", usage));
2670 }
2671 }
2672
abd7f895 2673 return sym_length;
ac0860d8 2674}
abd7f895 2675
3e3ec469 2676/*
2677** evans 2001-12-31
2678** Gasp...cut-and-pasted from above to deal with pfile (should replace throughout with this...)
2679*/
2680
abd7f895 2681size_t cppReader_checkMacroNameLoc (fileloc loc, char *symname, cstring usage)
3e3ec469 2682{
2683 char *p;
2684 size_t sym_length;
2685
2686 for (p = symname; is_idchar[(int) *p]; p++)
2687 {
2688 ;
2689 }
2690
2691 sym_length = size_fromInt (p - symname);
2692
2693 if (sym_length == 0
2694 || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '\"')))
2695 {
2696 voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage,
2697 cstring_fromChars (symname)), loc);
2698 }
2699 else if (!is_idstart[(int) *symname])
2700 {
2701 char *msg = (char *) dmalloc (sym_length + 1);
2702 memcpy (msg, symname, sym_length);
2703 msg[sym_length] = '\0';
2704 voptgenerror (FLG_PREPROC, message ("Invalid %s name: %s", usage,
2705 cstring_fromChars (msg)),
2706 loc);
2707 sfree (msg);
2708 }
2709 else
2710 {
2711 if ((strncmp (symname, "defined", 7) == 0) && sym_length == 7)
2712 {
2713 voptgenerror (FLG_PREPROC, message ("Invalid %s name: defined", usage), loc);
2714 }
2715 }
2716
abd7f895 2717 return sym_length;
3e3ec469 2718}
abd7f895 2719
ac0860d8 2720/* Return zero if two DEFINITIONs are isomorphic. */
2721
2722static bool
2723compare_defs (DEFINITION *d1, DEFINITION *d2)
2724{
2725 register struct reflist *a1, *a2;
2726 register char *p1 = d1->expansion;
2727 register char *p2 = d2->expansion;
2728 bool first = TRUE;
2729
2730 if (d1->nargs != d2->nargs)
2731 {
2732 return TRUE;
2733 }
2734
2735 llassert (d1->args.argnames != NULL);
2736 llassert (d2->args.argnames != NULL);
2737
2738 if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames) != 0)
2739 {
2740 return TRUE;
2741 }
2742
2743 for (a1 = d1->pattern, a2 = d2->pattern;
2744 (a1 != NULL) && (a2 != NULL);
2745 a1 = a1->next, a2 = a2->next) {
2746 if (!((a1->nchars == a2->nchars
2747 && (strncmp (p1, p2, size_fromInt (a1->nchars)) == 0))
2748 || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
2749 || a1->argno != a2->argno
2750 || a1->stringify != a2->stringify
2751 || a1->raw_before != a2->raw_before
2752 || a1->raw_after != a2->raw_after)
2753 return TRUE;
2754 first = 0;
2755 p1 += a1->nchars;
2756 p2 += a2->nchars;
2757 }
2758 if (a1 != a2)
2759 return TRUE;
2760
e5081f8c 2761 if (comp_def_part (first, p1, size_toInt (d1->length - (p1 - d1->expansion)),
2762 p2, size_toInt (d2->length - (p2 - d2->expansion)), 1))
ac0860d8 2763 return TRUE;
2764
2765 return FALSE;
2766}
2767
b73d1009 2768/*
2769** Return TRUE if two parts of two macro definitions are effectively different.
2770** One of the parts starts at BEG1 and has LEN1 chars;
2771** the other has LEN2 chars at BEG2.
2772** Any sequence of whitespace matches any other sequence of whitespace.
2773** FIRST means these parts are the first of a macro definition;
2774** so ignore leading whitespace entirely.
2775** LAST means these parts are the last of a macro definition;
2776** so ignore trailing whitespace entirely.
2777*/
2778
ac0860d8 2779static bool
2780comp_def_part (bool first, char *beg1, int len1, char *beg2, int len2, bool last)
2781{
2782 char *end1 = beg1 + len1;
2783 char *end2 = beg2 + len2;
2784
2785 if (first) {
2786 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
2787 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
2788 }
2789 if (last) {
2790 while (beg1 != end1 && is_space[(int) end1[-1]]) { end1--; }
2791 while (beg2 != end2 && is_space[(int) end2[-1]]) { end2--; }
2792 }
2793 while (beg1 != end1 && beg2 != end2) {
2794 if (is_space[(int) *beg1] && is_space[(int) *beg2]) {
2795 while (beg1 != end1 && is_space[(int) *beg1]) { beg1++; }
2796 while (beg2 != end2 && is_space[(int) *beg2]) { beg2++; }
2797 } else if (*beg1 == *beg2) {
2798 beg1++; beg2++;
2799 } else break;
2800 }
2801 return (beg1 != end1) || (beg2 != end2);
2802}
2803
b73d1009 2804/*
2805** Process a #define command.
2806** BUF points to the contents of the #define command, as a contiguous string.
2807** LIMIT points to the first character past the end of the definition.
2808** KEYWORD is the keyword-table entry for #define,
2809** or NULL for a "predefined" macro.
2810*/
2811
ac0860d8 2812static int
2813do_defineAux (cppReader *pfile, struct directive *keyword,
2209bcb7 2814 /*@exposed@*/ char *buf, char *limit, bool noExpand)
ac0860d8 2815{
2816 int hashcode;
3e3ec469 2817 macroDef mdef;
ac0860d8 2818 hashNode hp;
b73d1009 2819
ac0860d8 2820 mdef = create_definition (buf, limit, pfile, keyword == NULL, noExpand);
2821
2822 if (mdef.defn == 0)
2823 goto nope;
b73d1009 2824
3e3ec469 2825 hashcode = cpphash_hashCode (mdef.symnam, mdef.symlen, CPP_HASHSIZE);
b73d1009 2826
abd7f895 2827 if ((hp = cpphash_lookup (mdef.symnam, size_toInt (mdef.symlen), hashcode)) != NULL)
ac0860d8 2828 {
2829 bool ok = FALSE;
2830
2831 /* Redefining a precompiled key is ok. */
2832 if (hp->type == T_PCSTRING)
2833 ok = TRUE;
2834 /* Redefining a macro is ok if the definitions are the same. */
2835 else if (hp->type == T_MACRO)
2836 ok = !compare_defs (mdef.defn, hp->value.defn);
2837 /* Redefining a constant is ok with -D. */
2838 else if (hp->type == T_CONST)
2839 ok = !CPPOPTIONS (pfile)->done_initializing;
2840 else {
2841 BADBRANCH;
2842 }
b73d1009 2843
ac0860d8 2844 /* Print the warning if it's not ok. */
2845 if (!ok)
2846 {
2847 /*
2848 ** If we are passing through #define and #undef directives, do
2849 ** that for this re-definition now.
2850 */
2851
2852 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
2853 {
2854 /* llassert (keyword != NULL); */
2855 pass_thru_directive (buf, limit, pfile, keyword);
2856 }
2857
2858 cpp_setLocation (pfile);
b73d1009 2859
ac0860d8 2860 if (hp->type == T_MACRO)
2861 {
2862 if (hp->value.defn->noExpand)
2863 {
2864 ; /* error will be reported checking macros */
2865 }
2866 else
2867 {
2868 genppllerrorhint
2869 (FLG_MACROREDEF,
2870 message ("Macro %q already defined",
2871 cstring_copyLength (mdef.symnam, mdef.symlen)),
2872 message ("%q: Previous definition of %q",
2873 fileloc_unparseRaw (hp->value.defn->file,
2874 (int) hp->value.defn->line),
2875 cstring_copyLength (mdef.symnam, mdef.symlen)));
2876 }
2877 }
2878 else
2879 {
2880 genppllerror (FLG_MACROREDEF,
2881 message ("Macro %q already defined",
2882 cstring_copyLength (mdef.symnam,
2883 mdef.symlen)));
ac0860d8 2884 }
2885 }
2886
2887 /* Replace the old definition. */
2888 hp->type = T_MACRO;
2889 hp->value.defn = mdef.defn;
2890 }
2891 else
2892 {
2893 /*
2894 ** If we are passing through #define and #undef directives, do
2895 ** that for this new definition now.
2896 */
2897
2898 hashNode hn;
b73d1009 2899
ac0860d8 2900 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
2901 {
2902 pass_thru_directive (buf, limit, pfile, keyword);
2903 }
2904
2905 DPRINTF (("Define macro: %s / %d",
2906 mdef.symnam, mdef.defn->noExpand));
2907
3e3ec469 2908 hn = cpphash_installMacro (mdef.symnam, mdef.symlen, mdef.defn, hashcode);
ac0860d8 2909 /*@-branchstate@*/
2910 } /*@=branchstate@*/
2911
2912 return 0;
b73d1009 2913
ac0860d8 2914nope:
ac0860d8 2915 return 1;
2916}
2917
2918static int
2919do_define (cppReader *pfile, struct directive *keyword,
2209bcb7 2920 /*@exposed@*/ char *buf, char *limit)
ac0860d8 2921{
2922 DPRINTF (("Regular do define"));
2923 return do_defineAux (pfile, keyword, buf, limit, FALSE);
2924}
b73d1009 2925
2926/*
2927** This structure represents one parsed argument in a macro call.
2928** `raw' points to the argument text as written (`raw_length' is its length).
2929** `expanded' points to the argument's macro-expansion
2930** (its length is `expand_length').
2931** `stringified_length' is the length the argument would have
2932** if stringified.
2933** `use_count' is the number of times this macro arg is substituted
2934** into the macro. If the actual use count exceeds 10,
2935** the value stored is 10.
2936*/
2937
ac0860d8 2938/* raw and expanded are relative to ARG_BASE */
2939/*@notfunction@*/
2940#define ARG_BASE ((pfile)->token_buffer)
b73d1009 2941
ac0860d8 2942struct argdata {
2943 /* Strings relative to pfile->token_buffer */
2944 long raw;
2945 size_t expanded;
2946 size_t stringified;
2947 int raw_length;
2948 int expand_length;
2949 int stringified_length;
2950 bool newlines;
2951 int use_count;
2952};
2953
b73d1009 2954/*
2955** Allocate a new cppBuffer for PFILE, and push it on the input buffer stack.
2956** If BUFFER != NULL, then use the LENGTH characters in BUFFER
2957** as the new input buffer.
2958** Return the new buffer, or NULL on failure.
2959*/
2960
ac0860d8 2961/*@null@*/ /*@exposed@*/ cppBuffer *
2962cppReader_pushBuffer (cppReader *pfile, char *buffer, size_t length)
2963{
abd7f895 2964 cppBuffer *buf = cppReader_getBufferSafe (pfile);
ac0860d8 2965
2966 if (buf == pfile->buffer_stack)
2967 {
2968 cppReader_fatalError
2969 (pfile,
2970 message ("%s: macro or `#include' recursion too deep",
2971 (buf->fname != NULL)
2972 ? buf->fname
2973 : cstring_makeLiteral ("<no name>")));
2974 sfreeEventually (buffer);
2975 return NULL;
2976 }
2977
2978 llassert (buf != NULL);
2979
2980 buf--;
2981 memset ((char *) buf, 0, sizeof (*buf));
ce7034f0 2982 DPRINTF (("Pushing buffer: %s", cstring_copyLength (buffer, length)));
ac0860d8 2983 CPPBUFFER (pfile) = buf;
2984
2985 buf->if_stack = pfile->if_stack;
2986 buf->cleanup = cppReader_nullCleanup;
2987 buf->underflow = cppReader_nullUnderflow;
2988 buf->buf = buffer;
2989 buf->cur = buf->buf;
2990
2991 if (buffer != NULL)
2992 {
2993 buf->alimit = buf->rlimit = buffer + length;
2994 }
2995 else
2996 {
2997 buf->alimit = buf->rlimit = NULL;
2998 }
2999
3000 return buf;
3001}
b73d1009 3002
ac0860d8 3003cppBuffer *
3004cppReader_popBuffer (cppReader *pfile)
3005{
3006 cppBuffer *buf = CPPBUFFER (pfile);
3007
3008 llassert (buf != NULL);
3009
3010 (void) (*buf->cleanup) (buf, pfile);
3011 return ++CPPBUFFER (pfile);
3012}
3013
b73d1009 3014/*
3015** Scan until CPPBUFFER (PFILE) is exhausted into PFILE->token_buffer.
3016** Pop the buffer when done.
3017*/
3018
ac0860d8 3019void
3020cppReader_scanBuffer (cppReader *pfile)
3021{
3022 cppBuffer *buffer = CPPBUFFER (pfile);
3023 for (;;)
3024 {
3025 enum cpp_token token;
3026
3e3ec469 3027 token = cpplib_getToken (pfile);
ac0860d8 3028
3029 if (token == CPP_EOF) /* Should not happen ... */
3030 {
3031 break;
3032 }
3033
3034 if (token == CPP_POP && CPPBUFFER (pfile) == buffer)
3035 {
3036 (void) cppReader_popBuffer (pfile);
3037 break;
3038 }
3039 }
3040}
3041
3042/*
3043 * Rescan a string (which may have escape marks) into pfile's buffer.
3044 * Place the result in pfile->token_buffer.
3045 *
3046 * The input is copied before it is scanned, so it is safe to pass
3047 * it something from the token_buffer that will get overwritten
3e3ec469 3048 * (because it follows cpplib_getWritten). This is used by do_include.
ac0860d8 3049 */
3050
3051static void
3052cpp_expand_to_buffer (cppReader *pfile, char *buf, size_t length)
3053{
3054 register cppBuffer *ip;
3055 char *limit = buf + length;
3056 char *buf1, *p1, *p2;
3057
ce7034f0 3058 DPRINTF (("Expand to buffer: %s", cstring_copyLength (buf, length)));
3059
ac0860d8 3060 /* evans - 2001-08-26
3061 ** length is unsigned - this doesn't make sense
3062 if (length < 0)
3063 abort ();
3064 **
3065 */
3066
3067 /* Set up the input on the input stack. */
3068
3069 buf1 = (char *) dmalloc (length + 1);
3070
3071 p1 = buf;
3072 p2 = buf1;
3073
3074 while (p1 != limit)
3075 {
3076 *p2++ = *p1++;
3077 }
3078
3079 buf1[length] = '\0';
3080
3081 ip = cppReader_pushBuffer (pfile, buf1, length);
3082
3083 if (ip == NULL)
3084 return;
3085
3086 ip->has_escapes = TRUE;
3087
3088 /* Scan the input, create the output. */
3089 cppReader_scanBuffer (pfile);
3090
3091 cppReader_nullTerminate (pfile);
3092}
3093
3094static void
3095adjust_position (char *buf, char *limit, int *linep, int *colp)
3096{
3097 while (buf < limit)
3098 {
3099 char ch = *buf++;
3100 if (ch == '\n')
3101 (*linep)++, (*colp) = 1;
3102 else
3103 (*colp)++;
3104 }
3105}
3106
3107/* Move line_base forward, updating lineno and colno. */
3108
3109static void
3110update_position (cppBuffer *pbuf)
3111{
3112 char *old_pos;
3113 char *new_pos = pbuf->cur;
3114 register struct parse_marker *mark;
3115
3116 llassert (pbuf->buf != NULL);
3117 old_pos = pbuf->buf + pbuf->line_base;
3118
3119 for (mark = pbuf->marks; mark != NULL; mark = mark->next)
3120 {
3121 if (pbuf->buf + mark->position < new_pos)
3122 new_pos = pbuf->buf + mark->position;
3123 }
3124 pbuf->line_base += new_pos - old_pos;
3125
3126 llassert (old_pos != NULL);
3127 llassert (new_pos != NULL);
3128
3129 adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);
3130}
3131
3132void
80489f0a 3133cppBuffer_getLineAndColumn (/*@null@*/ cppBuffer *pbuf, /*@out@*/ int *linep,
6fcd0b1e 3134 /*@null@*/ /*@out@*/ int *colp)
ac0860d8 3135{
3136 int dummy;
3137
3138 if (colp == NULL)
3139 {
3140 colp = &dummy;
3141 /*@-branchstate@*/
3142 } /*@=branchstate@*/
3143
3144 if (pbuf != NULL)
3145 {
3146 *linep = pbuf->lineno;
3147 *colp = pbuf->colno;
3148
3149 llassert (pbuf->buf != NULL);
3150 llassert (pbuf->cur != NULL);
3151
3152 adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp);
3153 }
3154 else
3155 {
3156 *linep = 0;
3157 *colp = 0;
3158 }
3159}
3160
3161/* Return the cppBuffer that corresponds to a file (not a macro). */
3162
3163/*@exposed@*/ /*@null@*/ cppBuffer *cppReader_fileBuffer (cppReader *pfile)
3164{
3165 cppBuffer *ip = cppReader_getBuffer (pfile);
3166
3167 for ( ;
3168 ip != NULL && ip != cppReader_nullBuffer (pfile);
3169 ip = cppBuffer_prevBuffer (ip))
3170 {
3171 if (ip->fname != NULL)
3172 {
3173 return ip;
3174 }
3175 }
3176
3177 return NULL;
3178}
3179
3180static long
3181count_newlines (char *buf, char *limit)
3182{
3183 register long count = 0;
3184
3185 while (buf < limit)
3186 {
3187 char ch = *buf++;
3188 if (ch == '\n')
3189 count++;
3190 }
3191 return count;
3192}
3193
3194/*
3195 * write out a #line command, for instance, after an #include file.
3196 * If CONDITIONAL is nonzero, we can omit the #line if it would
3197 * appear to be a no-op, and we can output a few newlines instead
3198 * if we want to increase the line number by a small amount.
3199 * FILE_CHANGE says whether we are entering a file, leaving, or neither.
3200 */
3201
3202static void
3203output_line_command (cppReader *pfile, bool conditional,
3204 enum file_change_code file_change)
3205{
3206 int line, col;
3207 cppBuffer *ip = CPPBUFFER (pfile);
3208 cppBuffer *buf;
3209
3210 llassert (ip != NULL);
3211
3212 if (ip->fname == NULL)
3213 return;
3214
3215 update_position (ip);
3216
3217 if (CPPOPTIONS (pfile)->no_line_commands
3218 || CPPOPTIONS (pfile)->no_output)
3219 return;
3220
3221 buf = CPPBUFFER (pfile);
3222
3223 llassert (buf != NULL);
3224
3225 line = buf->lineno;
3226 col = buf->colno;
3227
3228 llassert (ip->cur != NULL);
3229
3230 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
3231
3232 if (CPPOPTIONS (pfile)->no_line_commands)
3233 return;
3234
3235 if (conditional) {
3236 if (line == pfile->lineno)
3237 return;
3238
3239 /* If the inherited line number is a little too small,
3240 output some newlines instead of a #line command. */
3241
3242 if (line > pfile->lineno && line < pfile->lineno + 8)
3243 {
3e3ec469 3244 cpplib_reserve (pfile, 20);
ac0860d8 3245 while (line > pfile->lineno)
3246 {
3247 cppReader_putCharQ (pfile, '\n');
3248 pfile->lineno++;
3249 }
3250
3251 return;
3252 }
3253 }
3254
e5081f8c 3255 cpplib_reserve (pfile, 4 * cstring_length (ip->nominal_fname) + 50);
ac0860d8 3256
3257 {
3258#ifdef OUTPUT_LINE_COMMANDS
3259 static char sharp_line[] = "#line ";
3260#else
3261 static char sharp_line[] = "# ";
3262#endif
3263 cppReader_putStrN (pfile, sharp_line, sizeof(sharp_line)-1);
3264 }
3265
3e3ec469 3266 sprintf (cpplib_getPWritten (pfile), "%d ", line);
3267 cppReader_adjustWritten (pfile, strlen (cpplib_getPWritten (pfile)));
ac0860d8 3268
3269 quote_string (pfile, cstring_toCharsSafe (ip->nominal_fname));
3270
3271 if (file_change != same_file) {
3272 cppReader_putCharQ (pfile, ' ');
3273 cppReader_putCharQ (pfile, file_change == enter_file ? '1' : '2');
3274 }
3275 /* Tell cc1 if following text comes from a system header file. */
3276 if (ip->system_header_p != '\0') {
3277 cppReader_putCharQ (pfile, ' ');
3278 cppReader_putCharQ (pfile, '3');
3279 }
3280#ifndef NO_IMPLICIT_EXTERN_C
3281 /* Tell cc1plus if following text should be treated as C. */
3282 if (ip->system_header_p == (char) 2 && CPPOPTIONS (pfile)->cplusplus) {
3283 cppReader_putCharQ (pfile, ' ');
3284 cppReader_putCharQ (pfile, '4');
3285 }
3286#endif
3287 cppReader_putCharQ (pfile, '\n');
3288 pfile->lineno = line;
3289}
3290
3291
3292/*
3293 * Parse a macro argument and append the info on PFILE's token_buffer.
3294 * REST_ARGS means to absorb the rest of the args.
3295 * Return nonzero to indicate a syntax error.
3296 */
3297
3298static enum cpp_token
3299macarg (cppReader *pfile, int rest_args)
3300{
3301 int paren = 0;
3302 enum cpp_token token;
3303 char save_put_out_comments = CPPOPTIONS (pfile)->put_out_comments;
3304 bool oldexpand = pfile->no_macro_expand;
3305 CPPOPTIONS (pfile)->put_out_comments = 1;
3306
3307 /* Try to parse as much of the argument as exists at this
3308 input stack level. */
3309
3310 pfile->no_macro_expand = TRUE;
3311
3312 for (;;)
3313 {
3e3ec469 3314 token = cpplib_getToken (pfile);
ac0860d8 3315
3316 switch (token)
3317 {
3318 case CPP_EOF:
3319 goto done;
3320 case CPP_POP:
3321 /* If we've hit end of file, it's an error (reported by caller).
3322 Ditto if it's the end of cpp_expand_to_buffer text.
3323 If we've hit end of macro, just continue. */
3324 if (!cppBuffer_isMacro (CPPBUFFER (pfile)))
3325 goto done;
3326 /*@switchbreak@*/ break;
3327 case CPP_LPAREN:
3328 paren++;
3329 /*@switchbreak@*/ break;
3330 case CPP_RPAREN:
3331 if (--paren < 0)
3332 goto found;
3333 /*@switchbreak@*/ break;
3334 case CPP_COMMA:
3335 /* if we've returned to lowest level and
3336 we aren't absorbing all args */
3337 if (paren == 0 && rest_args == 0)
3338 goto found;
3339 /*@switchbreak@*/ break;
3340 found:
3341 /* Remove ',' or ')' from argument buffer. */
3342 cppReader_adjustWritten (pfile, -1);
3343 goto done;
3344 default:
3345 ;
3346 }
3347 }
3348
3349done:
3350 CPPOPTIONS (pfile)->put_out_comments = save_put_out_comments;
3351 pfile->no_macro_expand = oldexpand;
3352
3353 return token;
3354}
3355
3356
3357/* Turn newlines to spaces in the string of length LENGTH at START,
3358 except inside of string constants.
3359 The string is copied into itself with its beginning staying fixed. */
3360
3361static int
3362change_newlines (char *start, int length)
3363{
3364 register char *ibp;
3365 register char *obp;
3366 register char *limit;
3367 char c;
3368
3369 ibp = start;
3370 limit = start + length;
3371 obp = start;
3372
3373 while (ibp < limit) {
3374 *obp++ = c = *ibp++;
3375 switch (c) {
3376
3377 case '\'':
3378 case '\"':
3379 /* Notice and skip strings, so that we don't delete newlines in them. */
3380 {
3381 char quotec = c;
3382 while (ibp < limit) {
3383 *obp++ = c = *ibp++;
3384 if (c == quotec)
3385 /*@innerbreak@*/ break;
3386 if (c == '\n' && quotec == '\'')
3387 /*@innerbreak@*/ break;
3388 }
3389 }
3390 /*@switchbreak@*/ break;
3391 }
3392 }
3393
3394 return obp - start;
3395}
3396
3397static /*@observer@*/ struct tm *
3398timestamp (/*@returned@*/ cppReader *pfile)
3399{
3400 if (pfile->timebuf == NULL)
3401 {
3402 time_t t = time ((time_t *) 0);
3403 pfile->timebuf = localtime (&t);
3404 }
3405
3406 llassert (pfile->timebuf != NULL);
3407
3408 return pfile->timebuf;
3409}
3410
3411static ob_mstring monthnames[] = {
3412 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3413 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
3414} ;
3415
3416/*
3417 * expand things like __FILE__. Place the expansion into the output
3418 * buffer *without* rescanning.
3419 */
3420
3421static void
3422special_symbol (hashNode hp, cppReader *pfile)
3423{
3424 cstring buf = cstring_undefined;
3425 size_t len;
3426 int true_indepth;
3427 cppBuffer *ip;
3428 struct tm *timebuf;
3429
3430 int paren = 0; /* For special `defined' keyword */
3431
3432 for (ip = cppReader_getBuffer (pfile); ip != NULL; ip = cppBuffer_prevBuffer (ip))
3433 {
3434 if (ip == cppReader_nullBuffer (pfile))
3435 {
3436 cppReader_errorLit (pfile,
3437 cstring_makeLiteralTemp ("cccp error: not in any file?!"));
3438 return; /* the show must go on */
3439 }
3440
3441 if (ip != NULL && ip->fname != NULL)
3442 {
3443 break;
3444 }
3445 }
3446
3447 switch (hp->type)
3448 {
3449 case T_FILE:
3450 case T_BASE_FILE:
3451 {
3452 char *string;
3453 if (hp->type == T_BASE_FILE)
3454 {
3455 while (cppBuffer_prevBuffer (ip) != cppReader_nullBuffer (pfile))
3456 {
3457 ip = cppBuffer_prevBuffer (ip);
3458 }
3459 }
3460
3461 llassert (ip != NULL);
3462 string = cstring_toCharsSafe (ip->nominal_fname);
3463
3464 if (string == NULL)
3465 {
3466 string = "";
3467 }
3468
3e3ec469 3469 cpplib_reserve (pfile, 3 + 4 * strlen (string));
ac0860d8 3470 quote_string (pfile, string);
3471 return;
3472 }
4caf866b 3473 case T_FUNC: /* added in ISO C99 */
3474 {
3475 /* We don't know the actual name of the function, but it doesn't matter */
3476 char *string = "** function-name **";
3477 cpplib_reserve (pfile, 3 + 4 * strlen (string));
3478 quote_string (pfile, string);
3479 return;
3480 }
ac0860d8 3481
3482 case T_INCLUDE_LEVEL:
3483 true_indepth = 0;
3484 ip = cppReader_getBuffer (pfile);
3485
3486 for (; ip != cppReader_nullBuffer (pfile) && ip != NULL;
3487 ip = cppBuffer_prevBuffer (ip))
3488 {
3489 if (ip != NULL && ip->fname != NULL)
3490 {
3491 true_indepth++;
3492 }
3493 }
3494
3495 buf = message ("%d", true_indepth - 1);
3496 break;
3497
3498 case T_VERSION:
899dbcf7 3499 buf = cstring_makeLiteral ("\"--- cpp version---\"");
ac0860d8 3500 break;
3501
3502#ifndef NO_BUILTIN_SIZE_TYPE
3503 case T_SIZE_TYPE:
3504 buf = cstring_makeLiteral (SIZE_TYPE);
3505 break;
3506#endif
3507
3508#ifndef NO_BUILTIN_PTRDIFF_TYPE
3509 case T_PTRDIFF_TYPE:
3510 buf = cstring_makeLiteral (PTRDIFF_TYPE);
3511 break;
3512#endif
3513
3514 case T_WCHAR_TYPE:
3515 buf = cstring_makeLiteral (cppReader_wcharType (pfile));
3516 break;
3517
3518 case T_USER_LABEL_PREFIX_TYPE:
3519 buf = cstring_makeLiteral (USER_LABEL_PREFIX);
3520 break;
3521
3522 case T_REGISTER_PREFIX_TYPE:
3523 buf = cstring_makeLiteral (REGISTER_PREFIX);
3524 break;
3525
3526 case T_CONST:
3527 buf = message ("%d", hp->value.ival);
3528 break;
3529
3530 case T_SPECLINE:
3531 {
3532 if (ip != NULL)
3533 {
3534 int line = ip->lineno;
3535 int col = ip->colno;
3536
3537 llassert (ip->cur != NULL);
3538 adjust_position (cppLineBase (ip), ip->cur, &line, &col);
3539
3540 buf = message ("%d", (int) line);
3541 }
3542 else
3543 {
3544 BADBRANCH;
3545 }
3546 }
3547 break;
3548
3549 case T_DATE:
3550 case T_TIME:
3551 {
3552 char *sbuf = (char *) dmalloc (20);
3553 timebuf = timestamp (pfile);
3554 if (hp->type == T_DATE)
3555 {
3556 sprintf (sbuf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
3557 timebuf->tm_mday, timebuf->tm_year + 1900);
3558 }
3559 else
3560 {
3561 sprintf (sbuf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
3562 timebuf->tm_sec);
3563 }
3564
3565 buf = cstring_fromCharsNew (sbuf);
3566 sfree (sbuf);
3567 break;
3568 }
3569
3570 case T_SPEC_DEFINED:
3571 buf = cstring_makeLiteral (" 0 "); /* Assume symbol is not defined */
3572 ip = cppReader_getBuffer (pfile);
abd7f895 3573 llassert (ip != NULL);
ac0860d8 3574 llassert (ip->cur != NULL);
3575 SKIP_WHITE_SPACE (ip->cur);
3576
3577 if (*ip->cur == '(')
3578 {
3579 paren++;
3580 ip->cur++; /* Skip over the paren */
3581 SKIP_WHITE_SPACE (ip->cur);
3582 }
3583
3584 if (!is_idstart[(int) *ip->cur])
3585 goto oops;
ee229125 3586 if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '\"'))
ac0860d8 3587 goto oops;
3588
3e3ec469 3589 if ((hp = cpphash_lookup (ip->cur, -1, -1)) != 0)
ac0860d8 3590 {
3591 cstring_free (buf);
3592 buf = cstring_makeLiteral (" 1 ");
3593 }
3594
3595 while (is_idchar[(int) *ip->cur])
3596 {
3597 ++ip->cur;
3598 }
3599
3600 SKIP_WHITE_SPACE (ip->cur);
3601
3602 if (paren != 0)
3603 {
3604 if (*ip->cur != ')')
3605 goto oops;
3606 ++ip->cur;
3607 }
3608 break;
3609
3610 oops:
3611
3612 cppReader_errorLit (pfile,
3613 cstring_makeLiteralTemp ("`defined' without an identifier"));
3614 break;
3615
3616 default:
3617 cpp_setLocation (pfile);
3618 llfatalerror (message ("Pre-processing error: invalid special hash type"));
3619 }
3620
abd7f895 3621 len = cstring_length (buf);
ac0860d8 3622
3e3ec469 3623 cpplib_reserve (pfile, len + 1);
ac0860d8 3624 cppReader_putStrN (pfile, cstring_toCharsSafe (buf), len);
3625 cppReader_nullTerminateQ (pfile);
3626
3627 cstring_free (buf);
3628 return;
3629}
3630
3631/* Write out a #define command for the special named MACRO_NAME
3632 to PFILE's token_buffer. */
3633
3634static void
3635dump_special_to_buffer (cppReader *pfile, char *macro_name)
3636{
3637 static char define_directive[] = "#define ";
3638 size_t macro_name_length = strlen (macro_name);
3639 output_line_command (pfile, 0, same_file);
3e3ec469 3640 cpplib_reserve (pfile, sizeof(define_directive) + macro_name_length);
ac0860d8 3641 cppReader_putStrN (pfile, define_directive, sizeof(define_directive)-1);
3642 cppReader_putStrN (pfile, macro_name, macro_name_length);
3643 cppReader_putCharQ (pfile, ' ');
3644 cpp_expand_to_buffer (pfile, macro_name, macro_name_length);
3645 cppReader_putChar (pfile, '\n');
3646}
3647
3648/* Initialize the built-in macros. */
3649
3650static void
3e3ec469 3651cpplib_installBuiltin (/*@observer@*/ char *name, ctype ctyp,
3652 int len, enum node_type type,
3653 int ivalue, /*@null@*/ /*@only@*/ char *value,
3654 int hash)
ac0860d8 3655{
3656 cstring sname = cstring_fromCharsNew (name);
3657
3658 llassert (usymtab_inGlobalScope ());
3659
3660 /*
3661 ** Be careful here: this is done before the ctype table has
3662 ** been initialized.
3663 */
3664
3665 if (!usymtab_exists (sname))
3666 {
3667 uentry ue = uentry_makeConstant (sname, ctyp, fileloc_createBuiltin ());
3668
3669 if (ctype_equal (ctyp, ctype_string))
3670 {
3671 qualList ql = qualList_new ();
3672 ql = qualList_add (ql, qual_createObserver ());
3673 uentry_reflectQualifiers (ue, ql);
3674 qualList_free (ql);
3675 }
3676
3677 usymtab_addGlobalEntry (ue);
3678 }
3679 else
3680 {
3681 ;
3682 }
3683
3e3ec469 3684 (void) cpphash_install (name, len, type, ivalue, value, hash);
ac0860d8 3685 cstring_free (sname);
3686}
3687
3688static void
3e3ec469 3689cpplib_installBuiltinType (/*@observer@*/ char *name, ctype ctyp,
3690 int len, enum node_type type,
3691 int ivalue,
3692 /*@only@*/ /*@null@*/ char *value, int hash)
ac0860d8 3693{
3694 cstring sname = cstring_fromChars (name);
1b8ae690 3695 /* evs 2000 07 10 - removed a memory leak, detected by splint */
ac0860d8 3696
3697 llassert (usymtab_inGlobalScope ());
3698
3699 if (!usymtab_existsTypeEither (sname))
3700 {
3701 uentry ue = uentry_makeDatatype (sname, ctyp,
e5081f8c 3702 NO, qual_createConcrete (),
ac0860d8 3703 fileloc_createBuiltin ());
3704 llassert (!usymtab_existsEither (sname));
3705 usymtab_addGlobalEntry (ue);
3706 }
3707
3e3ec469 3708 (void) cpphash_install (name, len, type, ivalue, value, hash);
ac0860d8 3709}
3710
3711static void
3712initialize_builtins (cppReader *pfile)
3713{
3e3ec469 3714 cpplib_installBuiltin ("__LINE__", ctype_int, -1, T_SPECLINE, 0, NULL, -1);
3715 cpplib_installBuiltin ("__DATE__", ctype_string, -1, T_DATE, 0, NULL, -1);
3716 cpplib_installBuiltin ("__FILE__", ctype_string, -1, T_FILE, 0, NULL, -1);
3717 cpplib_installBuiltin ("__BASE_FILE__", ctype_string, -1, T_BASE_FILE, 0, NULL, -1);
4caf866b 3718 cpplib_installBuiltin ("__func__", ctype_string, -1, T_FUNC, 0, NULL, -1);
3e3ec469 3719 cpplib_installBuiltin ("__INCLUDE_LEVEL__", ctype_int, -1, T_INCLUDE_LEVEL, 0, NULL, -1);
3720 cpplib_installBuiltin ("__VERSION__", ctype_string, -1, T_VERSION, 0, NULL, -1);
ac0860d8 3721#ifndef NO_BUILTIN_SIZE_TYPE
3e3ec469 3722 cpplib_installBuiltinType ("__SIZE_TYPE__", ctype_anyintegral, -1, T_SIZE_TYPE, 0, NULL, -1);
ac0860d8 3723#endif
3724#ifndef NO_BUILTIN_PTRDIFF_TYPE
3e3ec469 3725 cpplib_installBuiltinType ("__PTRDIFF_TYPE__", ctype_anyintegral, -1, T_PTRDIFF_TYPE, 0, NULL, -1);
ac0860d8 3726#endif
3e3ec469 3727 cpplib_installBuiltinType ("__WCHAR_TYPE__", ctype_anyintegral, -1, T_WCHAR_TYPE, 0, NULL, -1);
3728 cpplib_installBuiltin ("__USER_LABEL_PREFIX__", ctype_string, -1, T_USER_LABEL_PREFIX_TYPE, 0, NULL, -1);
3729 cpplib_installBuiltin ("__REGISTER_PREFIX__", ctype_string, -1, T_REGISTER_PREFIX_TYPE, 0, NULL, -1);
3730 cpplib_installBuiltin ("__TIME__", ctype_string, -1, T_TIME, 0, NULL, -1);
ac0860d8 3731
ac0860d8 3732 if (!cppReader_isTraditional (pfile))
3733 {
3e3ec469 3734 cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
ac0860d8 3735 }
3736
ac0860d8 3737# ifdef WIN32
3e3ec469 3738 cpplib_installBuiltin ("_WIN32", ctype_int, -1, T_CONST, STDC_VALUE, NULL, -1);
ac0860d8 3739# endif
3740
3741 /*
3742 ** This is supplied using a -D by the compiler driver
3743 ** so that it is present only when truly compiling with GNU C.
3744 */
3745
3e3ec469 3746 /* cpplib_install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
ac0860d8 3747
3e3ec469 3748 cpplib_installBuiltin ("S_SPLINT_S", ctype_int, -1, T_CONST, 2, NULL, -1);
3749 cpplib_installBuiltin ("__LCLINT__", ctype_int, -1, T_CONST, 2, NULL, -1);
ac0860d8 3750
f7bbce9e 3751 /*drl 1/9/2001/ try to define the right symbol for the architecture
3752 We use autoconf to determine the target cpu
3753 */
3754 cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
3755
9882c722 3756 /*drl 1/2/2002 set some flags based on uname
3757 I'd like to be able to do this with autoconf macro instead...
3758 */
3759
3760 /*Thanks to Nelson Beebe for suggesting possible values for these */
3761
3762 if (! strcmp (UNAME, "Linux"))
3763 {
3764#ifdef __ppc
3765 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3766#endif
3767 }
3768
3769 else if(! strcmp (UNAME, "Darwin"))
3770 {
3771 cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3772 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3773 }
3774 else if(! strcmp (UNAME, "HP-UX"))
3775 {
3776 cpplib_installBuiltin ("PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3777 cpplib_installBuiltin ("_HIUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3778 cpplib_installBuiltin ("_HPUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3779 cpplib_installBuiltin ("_PA_RISC1_1", ctype_int, -1, T_CONST, 2, NULL, -1);
3780 cpplib_installBuiltin ("__PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3781 cpplib_installBuiltin ("__PWB__", ctype_int, -1, T_CONST, 2, NULL, -1);
3782 cpplib_installBuiltin ("__STDC_EXT__", ctype_int, -1, T_CONST, 2, NULL, -1);
3783 cpplib_installBuiltin ("__hp9000s700", ctype_int, -1, T_CONST, 2, NULL, -1);
3784 cpplib_installBuiltin ("__hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3785 cpplib_installBuiltin ("__hp9000s800__", ctype_int, -1, T_CONST, 2, NULL, -1);
3786 cpplib_installBuiltin ("__hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3787 cpplib_installBuiltin ("__hp9k8__", ctype_int, -1, T_CONST, 2, NULL, -1);
3788 cpplib_installBuiltin ("__hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3789 cpplib_installBuiltin ("__hppa__", ctype_int, -1, T_CONST, 2, NULL, -1);
3790 cpplib_installBuiltin ("__hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3791 cpplib_installBuiltin ("__hpux__", ctype_int, -1, T_CONST, 2, NULL, -1);
3792 cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3793 cpplib_installBuiltin ("__unix__", ctype_int, -1, T_CONST, 2, NULL, -1);
3794 cpplib_installBuiltin ("hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3795 cpplib_installBuiltin ("hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3796 cpplib_installBuiltin ("hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3797 cpplib_installBuiltin ("hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3798 cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3799 }
3800 else if(! strcmp (UNAME, "IRIX64"))
3801 {
3802 cpplib_installBuiltin ("LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3803 cpplib_installBuiltin ("MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3804 cpplib_installBuiltin ("_ABIN32", ctype_int, -1, T_CONST, 2, NULL, -1);
3805 cpplib_installBuiltin ("_COMPILER_VERSION", ctype_int, -1, T_CONST, 730, NULL, -1);
3806 cpplib_installBuiltin ("_LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3807 cpplib_installBuiltin ("_LONGLONG", ctype_int, -1, T_CONST, 2, NULL, -1);
3808 cpplib_installBuiltin ("_MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3809 cpplib_installBuiltin ("_MIPS_FPSET", ctype_int, -1, T_CONST, 32, NULL, -1);
3810 cpplib_installBuiltin ("_MIPS_ISA", ctype_int, -1, T_CONST, 3, NULL, -1);
3811 /*_MIPS_SIM=_ABIN32*/
3812 cpplib_installBuiltin ("_MIPS_SIM", ctype_int, -1, T_CONST, 2, NULL , -1);
3813 cpplib_installBuiltin ("_MIPS_SZINT", ctype_int, -1, T_CONST, 32, NULL, -1);
3814 cpplib_installBuiltin ("_MIPS_SZLONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3815 cpplib_installBuiltin ("_MIPS_SZPTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3816 cpplib_installBuiltin ("_MODERN_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3817 cpplib_installBuiltin ("_PIC", ctype_int, -1, T_CONST, 2, NULL, -1);
3818 cpplib_installBuiltin ("_SGI_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3819 cpplib_installBuiltin ("_SIZE_INT", ctype_int, -1, T_CONST, 32, NULL, -1);
3820 cpplib_installBuiltin ("_SIZE_LONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3821 cpplib_installBuiltin ("_SIZE_PTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3822 cpplib_installBuiltin ("_SVR4_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3823 cpplib_installBuiltin ("_SYSTYPE_SVR4", ctype_int, -1, T_CONST, 2, NULL, -1);
3824 cpplib_installBuiltin ("__DSO__", ctype_int, -1, T_CONST, 2, NULL, -1);
3825 cpplib_installBuiltin ("__EXTENSIONS__", ctype_int, -1, T_CONST, 2, NULL, -1);
3826 cpplib_installBuiltin ("__INLINE_INTRINSICS", ctype_int, -1, T_CONST, 2, NULL, -1);
3827 cpplib_installBuiltin ("__MATH_HAS_NO_SIDE_EFFECTS", ctype_int, -1, T_CONST, 2, NULL, -1);
3828 cpplib_installBuiltin ("__host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3829 cpplib_installBuiltin ("__mips", ctype_int, -1, T_CONST, 3, NULL, -1);
3830 cpplib_installBuiltin ("__sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3831 cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3832 cpplib_installBuiltin ("host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3833 cpplib_installBuiltin ("mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3834 cpplib_installBuiltin ("sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3835 cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3836 }
3837 else if(! strcmp (UNAME, "OSF1"))
3838 {
3839 cpplib_installBuiltin ("__alpha", ctype_int, -1, T_CONST, 2, NULL, -1);
3840 }
3841 else if (!strcmp (UNAME, "Rhapsody"))
3842 {
3843 cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3844 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3845 }
3846
3847 else if (!strcmp (UNAME, "SunOS"))
3848 {
3849 cpplib_installBuiltin ("__OPEN_MAX", ctype_int, -1, T_CONST, 20, NULL, -1);
3850 cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, 2, NULL, -1);
3851 cpplib_installBuiltin ("__sparc", ctype_int, -1, T_CONST, 2, NULL, -1);
3852 /* This define "-Dfileno(f)=0" should be inserted but we're going to stick to deinfe constants for now...*/
3853 }
3854 else
3855 {
3856 /*
3857 types which we have not explictedly handled.
3858 AIX, FreeBSD, IRIX, Mach
3859 */
3860
3861 }
f7bbce9e 3862
ac0860d8 3863 if (CPPOPTIONS (pfile)->debug_output)
3864 {
3865 dump_special_to_buffer (pfile, "__BASE_FILE__");
3866 dump_special_to_buffer (pfile, "__VERSION__");
3867#ifndef NO_BUILTIN_SIZE_TYPE
3868 dump_special_to_buffer (pfile, "__SIZE_TYPE__");
3869#endif
3870#ifndef NO_BUILTIN_PTRDIFF_TYPE
3871 dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
3872#endif
3873 dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
3874 dump_special_to_buffer (pfile, "__DATE__");
3875 dump_special_to_buffer (pfile, "__TIME__");
3876 if (!cppReader_isTraditional (pfile))
3877 dump_special_to_buffer (pfile, "__STDC__");
3878 }
3879}
3880
3881
3882/* Return 1 iff a token ending in C1 followed directly by a token C2
3883 could cause mis-tokenization. */
3884
3885static bool
3886unsafe_chars (char c1, char c2)
3887{
3888 switch (c1)
3889 {
3890 case '+': case '-':
3891 if (c2 == c1 || c2 == '=')
3892 return 1;
3893 goto letter;
3894 case '.':
3895 case '0': case '1': case '2': case '3': case '4':
3896 case '5': case '6': case '7': case '8': case '9':
3897 case 'e': case 'E': case 'p': case 'P':
3898 if (c2 == '-' || c2 == '+')
3899 return 1; /* could extend a pre-processing number */
3900 goto letter;
3901 case 'L':
3902 if (c2 == '\'' || c2 == '\"')
3903 return 1; /* Could turn into L"xxx" or L'xxx'. */
3904 goto letter;
3905 letter:
3906 case '_':
3907 case 'a': case 'b': case 'c': case 'd': case 'f':
3908 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
3909 case 'm': case 'n': case 'o': case 'q': case 'r':
3910 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
3911 case 'y': case 'z':
3912 case 'A': case 'B': case 'C': case 'D': case 'F':
3913 case 'G': case 'H': case 'I': case 'J': case 'K':
3914 case 'M': case 'N': case 'O': case 'Q': case 'R':
3915 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
3916 case 'Y': case 'Z':
3917 /* We're in the middle of either a name or a pre-processing number. */
3918 return (is_idchar[(int) c2] || c2 == '.');
3919 case '<': case '>': case '!': case '%': case '#': case ':':
3920 case '^': case '&': case '|': case '*': case '/': case '=':
3921 return (c2 == c1 || c2 == '=');
3922 }
3923 return 0;
3924}
3925
3926/* Expand a macro call.
3927 HP points to the symbol that is the macro being called.
3928 Put the result of expansion onto the input stack
3929 so that subsequent input by our caller will use it.
3930
3931 If macro wants arguments, caller has already verified that
3932 an argument list follows; arguments come from the input stack. */
3933
3934static void
3e3ec469 3935cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
ac0860d8 3936{
3937 int nargs;
3938 DEFINITION *defn = hp->value.defn;
3939 char *xbuf;
3940 char *oxbuf = NULL;
3941 int start_line;
3942 int start_column;
abd7f895 3943 int end_line;
3944 int end_column;
ac0860d8 3945 size_t xbuf_len;
3e3ec469 3946 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 3947 int rest_args;
3948 int rest_zero = 0;
3949 int i;
3950 struct argdata *args = NULL;
3951
3952 pfile->output_escapes++;
80489f0a 3953 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
abd7f895 3954 DPRINTF (("Expand macro: %d:%d", start_line, start_column));
ac0860d8 3955
3956 nargs = defn->nargs;
3957
3958 if (nargs >= 0)
3959 {
3960 enum cpp_token token = CPP_EOF;
3961
3962 args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
3963
3964 for (i = 0; i < nargs; i++)
3965 {
3966 args[i].expanded = 0;
3967 args[i].raw = 0;
3968 args[i].raw_length = 0;
3969 args[i].expand_length = args[i].stringified_length = -1;
3970 args[i].use_count = 0;
3971 }
3972
3973 /*
3974 ** Parse all the macro args that are supplied. I counts them.
3975 ** The first NARGS args are stored in ARGS.
3976 ** The rest are discarded. If rest_args is set then we assume
3977 ** macarg absorbed the rest of the args.
3978 */
3979
3980 i = 0;
3981 rest_args = 0;
3982
3983 cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg. */
3984 do
3985 {
3986 if (rest_args != 0)
3987 {
3988 continue;
3989 }
3990
3991 if (i < nargs || (nargs == 0 && i == 0))
3992 {
3993 /* if we are working on last arg which absorbs rest of args... */
3994 if (i == nargs - 1 && defn->rest_args)
3995 {
3996 rest_args = 1;
3997 }
3998
3e3ec469 3999 args[i].raw = size_toLong (cpplib_getWritten (pfile));
ac0860d8 4000 token = macarg (pfile, rest_args);
e5081f8c 4001 args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
ac0860d8 4002 args[i].newlines = FALSE; /* FIXME */
4003 }
4004 else
4005 {
4006 token = macarg (pfile, 0);
4007 }
4008
4009 if (token == CPP_EOF || token == CPP_POP)
4010 {
4011 cppReader_errorWithLine (pfile, start_line, start_column,
4012 cstring_fromCharsNew ("unterminated macro call"));
4013 sfree (args);
4014 return;
4015 }
4016 i++;
4017 } while (token == CPP_COMMA);
4018
4019 /* If we got one arg but it was just whitespace, call that 0 args. */
4020 if (i == 1)
4021 {
4022 char *bp;
4023 char *lim;
4024
4025 assertSet (args);
4026
4027 bp = ARG_BASE + args[0].raw;
4028 lim = bp + args[0].raw_length;
4029
4030 /* cpp.texi says for foo ( ) we provide one argument.
4031 However, if foo wants just 0 arguments, treat this as 0. */
4032
4033 if (nargs == 0)
4034 {
4035 while (bp != lim && is_space[(int) *bp])
4036 {
4037 bp++;
4038 }
4039 }
4040
4041 if (bp == lim)
4042 i = 0;
4043 }
4044
4045 /* Don't output an error message if we have already output one for
4046 a parse error above. */
4047 rest_zero = 0;
4048
4049 if (nargs == 0 && i > 0)
4050 {
4051 cppReader_error (pfile,
4052 message ("arguments given to macro `%s'", hp->name));
4053 }
4054 else if (i < nargs)
4055 {
4056 /* traditional C allows foo() if foo wants one argument. */
4057 if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
4058 {
4059 ;
4060 }
4061 /* the rest args token is allowed to absorb 0 tokens */
4062 else if (i == nargs - 1 && defn->rest_args)
4063 rest_zero = 1;
4064 else if (i == 0)
4065 cppReader_error (pfile,
4066 message ("macro `%s' used without args", hp->name));
4067 else if (i == 1)
4068 cppReader_error (pfile,
4069 message ("macro `%s' used with just one arg", hp->name));
4070 else
4071 {
4072 cppReader_error (pfile,
4073 message ("macro `%s' used with only %d args",
4074 hp->name, i));
4075 }
4076 }
4077 else if (i > nargs)
4078 {
4079 cppReader_error (pfile,
4080 message ("macro `%s' used with too many (%d) args", hp->name, i));
4081 }
4082 else
4083 {
4084 ;
4085 }
4086 }
4087
abd7f895 4088 /*
4089 ** If the agrument list was multiple lines, need to insert new lines to keep line
4090 ** numbers accurate.
4091 */
4092
80489f0a 4093 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
abd7f895 4094 DPRINTF (("Expand macro: %d:%d", end_line, end_column));
ce7034f0 4095
ac0860d8 4096 /* If macro wants zero args, we parsed the arglist for checking only.
4097 Read directly from the macro definition. */
4098
4099 if (nargs <= 0)
4100 {
4101 xbuf = defn->expansion;
4102 xbuf_len = defn->length;
4103 }
4104 else
4105 {
4106 char *exp = defn->expansion;
4107 int offset; /* offset in expansion,
4108 copied a piece at a time */
4109 size_t totlen; /* total amount of exp buffer filled so far */
4110
4111 register struct reflist *ap, *last_ap;
4112
4113 assertSet (args); /* args is defined since the nargs > 0 path was taken */
4114
4115 /* Macro really takes args. Compute the expansion of this call. */
4116
4117 /* Compute length in characters of the macro's expansion.
4118 Also count number of times each arg is used. */
4119 xbuf_len = defn->length;
4120
4121 llassert (args != NULL);
4122
4123 for (ap = defn->pattern; ap != NULL; ap = ap->next)
4124 {
4125 if (ap->stringify)
4126 {
4127 struct argdata *arg = &args[ap->argno];
4128
4129 /* Stringify it it hasn't already been */
4130 assertSet (arg);
4131
4132 if (arg->stringified_length < 0)
4133 {
4134 int arglen = arg->raw_length;
4135 bool escaped = FALSE;
4136 char in_string = '\0';
4137 char c;
4138
4139 /* Initially need_space is -1. Otherwise, 1 means the
4140 previous character was a space, but we suppressed it;
4141 0 means the previous character was a non-space. */
4142 int need_space = -1;
4143
4144 i = 0;
3e3ec469 4145 arg->stringified = cpplib_getWritten (pfile);
ac0860d8 4146 if (!cppReader_isTraditional (pfile))
4147 cppReader_putChar (pfile, '\"'); /* insert beginning quote */
4148 for (; i < arglen; i++)
4149 {
4150 c = (ARG_BASE + arg->raw)[i];
4151
4152 if (in_string == '\0')
4153 {
4154 /* Internal sequences of whitespace are replaced by
4155 one space except within an string or char token.*/
4156 if (is_space[(int) c])
4157 {
3e3ec469 4158 if (cpplib_getWritten (pfile) > arg->stringified
4159 && (cpplib_getPWritten (pfile))[-1] == '@')
ac0860d8 4160 {
4161 /* "@ " escape markers are removed */
4162 cppReader_adjustWritten (pfile, -1);
4163 /*@innercontinue@*/ continue;
4164 }
4165 if (need_space == 0)
4166 need_space = 1;
4167 /*@innercontinue@*/ continue;
4168 }
4169 else if (need_space > 0)
4170 cppReader_putChar (pfile, ' ');
4171 else
4172 {
4173 ;
4174 }
4175
4176 need_space = 0;
4177 }
4178
4179 if (escaped)
4180 escaped = 0;
4181 else
4182 {
4183 if (c == '\\')
4184 escaped = 1;
4185
4186 if (in_string != '\0')
4187 {
4188 if (c == in_string)
4189 in_string = '\0';
4190 }
4191 else if (c == '\"' || c == '\'')
4192 {
4193 in_string = c;
4194 }
4195 else
4196 {
4197 ;
4198 }
4199 }
4200
4201 /* Escape these chars */
4202 if (c == '\"' || (in_string != '\0' && c == '\\'))
4203 cppReader_putChar (pfile, '\\');
4204 if (isprint (c))
4205 cppReader_putChar (pfile, c);
4206 else
4207 {
3e3ec469 4208 cpplib_reserve (pfile, 4);
4209 sprintf (cpplib_getPWritten (pfile), "\\%03o",
ac0860d8 4210 (unsigned int) c);
4211 cppReader_adjustWritten (pfile, 4);
4212 }
4213 }
4214 if (!cppReader_isTraditional (pfile))
4215 cppReader_putChar (pfile, '\"'); /* insert ending quote */
4216 arg->stringified_length
3e3ec469 4217 = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
ac0860d8 4218 }
4219
4220 xbuf_len += args[ap->argno].stringified_length;
4221 }
4222 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4223 {
b73d1009 4224 /* Add 4 for two newline-space markers to prevent token concatenation. */
4225 assertSet (args); /* Splint shouldn't need this */
ac0860d8 4226 xbuf_len += args[ap->argno].raw_length + 4;
4227 }
4228 else
4229 {
4230 /* We have an ordinary (expanded) occurrence of the arg.
4231 So compute its expansion, if we have not already. */
4232
b73d1009 4233 assertSet (args); /* shouldn't need this */
ac0860d8 4234
4235 if (args[ap->argno].expand_length < 0)
4236 {
3e3ec469 4237 args[ap->argno].expanded = cpplib_getWritten (pfile);
ac0860d8 4238 cpp_expand_to_buffer (pfile,
4239 ARG_BASE + args[ap->argno].raw,
4240 size_fromInt (args[ap->argno].raw_length));
4241
4242 args[ap->argno].expand_length
3e3ec469 4243 = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
ac0860d8 4244 }
4245
4246 /* Add 4 for two newline-space markers to prevent
4247 token concatenation. */
4248 xbuf_len += args[ap->argno].expand_length + 4;
4249 }
4250 if (args[ap->argno].use_count < 10)
4251 args[ap->argno].use_count++;
4252 }
4253
4254 xbuf = (char *) dmalloc (xbuf_len + 1);
4255 oxbuf = xbuf;
4256
4257 /*
4258 ** Generate in XBUF the complete expansion
4259 ** with arguments substituted in.
4260 ** TOTLEN is the total size generated so far.
4261 ** OFFSET is the index in the definition
4262 ** of where we are copying from.
4263 */
4264
4265 offset = 0;
4266 totlen = 0;
4267
4268 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
4269 last_ap = ap, ap = ap->next)
4270 {
4271 register struct argdata *arg = &args[ap->argno];
4272 size_t count_before = totlen;
4273
4274 /* Add chars to XBUF. */
4275 for (i = 0; i < ap->nchars; i++, offset++)
4276 {
4277 xbuf[totlen++] = exp[offset];
4278 }
4279
4280 /* If followed by an empty rest arg with concatenation,
4281 delete the last run of nonwhite chars. */
4282 if (rest_zero && totlen > count_before
4283 && ((ap->rest_args && ap->raw_before)
4284 || (last_ap != NULL && last_ap->rest_args
4285 && last_ap->raw_after)))
4286 {
4287 /* Delete final whitespace. */
4288 while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
4289 {
4290 totlen--;
4291 }
4292
4293 /* Delete the nonwhites before them. */
4294 while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
4295 {
4296 totlen--;
4297 }
4298 }
4299
4300 if (ap->stringify != 0)
4301 {
4302 assertSet(arg);
4303 memcpy (xbuf + totlen,
4304 ARG_BASE + arg->stringified,
4305 size_fromInt (arg->stringified_length));
4306 totlen += arg->stringified_length;
4307 }
4308 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4309 {
4310 char *p1;
4311 char *l1;
4312
4313 assertSet (arg);
4314
4315 p1 = ARG_BASE + arg->raw;
4316 l1 = p1 + arg->raw_length;
4317
4318 if (ap->raw_before)
4319 {
4320 while (p1 != l1 && is_space[(int) *p1])
4321 {
4322 p1++;
4323 }
4324
4325 while (p1 != l1 && is_idchar[(int) *p1])
4326 {
4327 xbuf[totlen++] = *p1++;
4328 }
4329
4330 /* Delete any no-reexpansion marker that follows
4331 an identifier at the beginning of the argument
4332 if the argument is concatenated with what precedes it. */
4333 if (p1[0] == '@' && p1[1] == '-')
4334 p1 += 2;
4335 }
4336 if (ap->raw_after)
4337 {
4338 /* Arg is concatenated after: delete trailing whitespace,
4339 whitespace markers, and no-reexpansion markers. */
4340 while (p1 != l1)
4341 {
4342 if (is_space[(int) l1[-1]]) l1--;
4343 else if (l1[-1] == '-')
4344 {
4345 char *p2 = l1 - 1;
4346 /* If a `-' is preceded by an odd number of newlines then it
4347 and the last newline are a no-reexpansion marker. */
4348 while (p2 != p1 && p2[-1] == '\n')
4349 {
4350 p2--;
4351 }
4352
4353 if (((l1 - 1 - p2) & 1) != 0)
4354 {
4355 l1 -= 2;
4356 }
4357 else
4358 {
4359 /*@innerbreak@*/ break;
4360 }
4361 }
4362 else
4363 {
4364 /*@innerbreak@*/ break;
4365 }
4366 }
4367 }
4368
4369 memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
4370 totlen += l1 - p1;
4371 }
4372 else
4373 {
4374 char *expanded;
4375
4376 assertSet (arg);
4377 expanded = ARG_BASE + arg->expanded;
4378
4379 if (!ap->raw_before && totlen > 0
4380 && (arg->expand_length != 0)
4381 && !cppReader_isTraditional(pfile)
4382 && unsafe_chars (xbuf[totlen-1], expanded[0]))
4383 {
4384 xbuf[totlen++] = '@';
4385 xbuf[totlen++] = ' ';
4386 }
4387
4388 memcpy (xbuf + totlen, expanded,
4389 size_fromInt (arg->expand_length));
4390 totlen += arg->expand_length;
4391
4392 if (!ap->raw_after && totlen > 0
4393 && offset < size_toInt (defn->length)
4394 && !cppReader_isTraditional(pfile)
4395 && unsafe_chars (xbuf[totlen-1], exp[offset]))
4396 {
4397 xbuf[totlen++] = '@';
4398 xbuf[totlen++] = ' ';
4399 }
4400
4401 /* If a macro argument with newlines is used multiple times,
4402 then only expand the newlines once. This avoids creating
4403 output lines which don't correspond to any input line,
4404 which confuses gdb and gcov. */
4405 if (arg->use_count > 1 && arg->newlines > 0)
4406 {
4407 /* Don't bother doing change_newlines for subsequent
4408 uses of arg. */
4409 arg->use_count = 1;
4410 arg->expand_length
4411 = change_newlines (expanded, arg->expand_length);
4412 }
4413 }
4414
4415 if (totlen > xbuf_len)
4416 abort ();
4417 }
4418
4419 /* if there is anything left of the definition
4420 after handling the arg list, copy that in too. */
4421
4422 for (i = offset; i < size_toInt (defn->length); i++)
4423 {
4424 /* if we've reached the end of the macro */
4425 if (exp[i] == ')')
4426 rest_zero = 0;
4427 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
4428 && last_ap->raw_after))
4429 xbuf[totlen++] = exp[i];
4430 }
4431
4432 xbuf[totlen] = '\0';
4433 xbuf_len = totlen;
4434 }
4435
4436 pfile->output_escapes--;
4437
4438 /* Now put the expansion on the input stack
4439 so our caller will commence reading from it. */
abd7f895 4440 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
ce7034f0 4441
abd7f895 4442 if (end_line != start_line)
4443 {
4444 /* xbuf must have enough newlines */
4445 int newlines = end_line - start_line;
4446 int foundnewlines = 0;
4447 char *xbufptr = xbuf;
4448
4449 while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
4450 {
4451 foundnewlines++;
4452 xbufptr++;
4453
4454 if (*xbufptr == '\0')
4455 {
4456 break;
4457 }
4458 }
4459
4460 if (foundnewlines < newlines)
4461 {
4462 cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
4463
4464 while (foundnewlines < newlines)
4465 {
4466 newbuf = cstring_appendChar (newbuf, '\n');
4467 foundnewlines++;
4468 }
4469
4470 sfree (oxbuf);
4471 xbuf = cstring_toCharsSafe (newbuf);
4472 xbuf_len = cstring_length (newbuf);
4473 /*@-branchstate@*/
4474 } /*@=branchstate@*/
4475 }
4476
4477 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4478
ac0860d8 4479 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
ce7034f0 4480 DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
abd7f895 4481 cppReader_getBufferSafe (pfile)->has_escapes = 1;
ac0860d8 4482
4483 /* Pop the space we've used in the token_buffer for argument expansion. */
4484 cppReader_setWritten (pfile, old_written);
ce7034f0 4485 DPRINTF (("Done set written"));
4486
ac0860d8 4487 /* Recursive macro use sometimes works traditionally.
4488 #define foo(x,y) bar (x (y,0), y)
4489 foo (foo, baz) */
4490
4491 if (!cppReader_isTraditional (pfile))
4492 hp->type = T_DISABLED;
4493
4494 sfree (args);
4495}
4496
4497static void
4498push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
4499 /*@dependent@*/ hashNode hp)
4500{
4501 cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
4502
4503 if (mbuf == NULL)
4504 {
4505 return;
4506 }
4507
4508 mbuf->cleanup = cppReader_macroCleanup;
4509
4510 llassert (mbuf->hnode == NULL);
4511 mbuf->hnode = hp;
4512
4513 /* The first chars of the expansion should be a "@ " added by
4514 collect_expansion. This is to prevent accidental token-pasting
4515 between the text preceding the macro invocation, and the macro
4516 expansion text.
4517
4518 We would like to avoid adding unneeded spaces (for the sake of
4519 tools that use cpp, such as imake). In some common cases we can
4520 tell that it is safe to omit the space.
4521
4522 The character before the macro invocation cannot have been an
4523 idchar (or else it would have been pasted with the idchars of
4524 the macro name). Therefore, if the first non-space character
4525 of the expansion is an idchar, we do not need the extra space
4526 to prevent token pasting.
4527
4528 Also, we don't need the extra space if the first char is '(',
4529 or some other (less common) characters. */
4530
4531 if (xbuf[0] == '@' && xbuf[1] == ' '
4532 && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
4533 || xbuf[2] == '\"'))
4534 {
4535 llassert (mbuf->cur != NULL);
ce7034f0 4536 DPRINTF (("Eating: %c", xbuf[2]));
ac0860d8 4537 mbuf->cur += 2;
4538 }
ce7034f0 4539
ac0860d8 4540}
4541
4542
3e3ec469 4543/* Like cpplib_getToken, except that it does not read past end-of-line.
ac0860d8 4544 Also, horizontal space is skipped, and macros are popped. */
4545
4546static enum cpp_token
4547get_directive_token (cppReader *pfile)
4548{
4549 for (;;)
4550 {
3e3ec469 4551 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 4552 enum cpp_token token;
4553 cppSkipHspace (pfile);
4554 if (cppReader_peekC (pfile) == '\n')
4555 {
4556 return CPP_VSPACE;
4557 }
4558
3e3ec469 4559 token = cpplib_getToken (pfile);
ac0860d8 4560
4561 switch (token)
4562 {
4563 case CPP_POP:
4564 if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
4565 return token;
4566 /*@fallthrough@*/
4567 case CPP_HSPACE:
4568 case CPP_COMMENT:
4569 cppReader_setWritten (pfile, old_written);
4570 /*@switchbreak@*/ break;
4571 default:
4572 return token;
4573 }
4574 }
4575}
4576
4577
4578/* Handle #include and #import.
4579 This function expects to see "fname" or <fname> on the input.
4580
4581 The input is normally in part of the output_buffer following
3e3ec469 4582 cpplib_getWritten, and will get overwritten by output_line_command.
ac0860d8 4583 I.e. in input file specification has been popped by cppReader_handleDirective.
4584 This is safe. */
4585
4586static int
4587do_include (cppReader *pfile, struct directive *keyword,
4588 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
4589{
4590 bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
4591 cstring fname;
4592 char *fbeg, *fend; /* Beginning and end of fname */
4593 enum cpp_token token;
4594
4595 /* Chain of dirs to search */
4596 struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
4597 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
4598 struct file_name_list *searchptr = NULL;
3e3ec469 4599 size_t old_written = cpplib_getWritten (pfile);
abd7f895 4600 size_t flen;
ac0860d8 4601
4602 int f; /* file number */
4603 int angle_brackets = 0; /* 0 for "...", 1 for <...> */
4604 f= -1; /* JF we iz paranoid! */
4605
4606 pfile->parsing_include_directive++;
4607 token = get_directive_token (pfile);
4608 pfile->parsing_include_directive--;
4609
4610 if (token == CPP_STRING)
4611 {
4612 /* FIXME - check no trailing garbage */
4613 fbeg = pfile->token_buffer + old_written + 1;
3e3ec469 4614 fend = cpplib_getPWritten (pfile) - 1;
ac0860d8 4615 if (fbeg[-1] == '<')
4616 {
4617 angle_brackets = 1;
4618 /* If -I-, start with the first -I dir after the -I-. */
4619 if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
4620 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4621 }
4622 /* If -I- was specified, don't search current dir, only spec'd ones. */
4623 else if (!CPPOPTIONS (pfile)->ignore_srcdir)
4624 {
4625 cppBuffer *fp = CPPBUFFER (pfile);
4626 /* We have "filename". Figure out directory this source
4627 file is coming from and put it on the front of the list. */
4628
4629 for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4630 {
4631 int n;
4632 char *ep,*nam;
4633
4634 llassert (fp != NULL);
4635
4636 nam = NULL;
4637
4638 if (cstring_isDefined (fp->nominal_fname))
4639 {
4640 nam = cstring_toCharsSafe (fp->nominal_fname);
4641
4642 /* Found a named file. Figure out dir of the file,
4643 and put it in front of the search list. */
4644 dsp[0].next = search_start;
4645 search_start = dsp;
4646
4647#ifndef VMS
4648 ep = strrchr (nam, CONNECTCHAR);
4649#else /* VMS */
4650 ep = strrchr (nam, ']');
4651 if (ep == NULL) ep = strrchr (nam, '>');
4652 if (ep == NULL) ep = strrchr (nam, ':');
4653 if (ep != NULL) ep++;
4654#endif /* VMS */
4655 if (ep != NULL)
4656 {
4657 char save;
4658
4659 n = ep - nam;
4660 save = nam[n];
4661 nam[n] = '\0';
4662
4663 /*@-onlytrans@*/ /* This looks like a memory leak... */
4664 dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
4665 /*@=onlytrans@*/
4666 nam[n] = save;
4667
e5081f8c 4668 if (n + INCLUDE_LEN_FUDGE > size_toInt (pfile->max_include_len))
4669 pfile->max_include_len = size_fromInt (n + INCLUDE_LEN_FUDGE);
ac0860d8 4670 }
4671 else
4672 {
4673 dsp[0].fname = cstring_undefined; /* Current directory */
4674 }
4675
4676 dsp[0].got_name_map = 0;
4677 break;
4678 }
4679 }
4680 }
4681 else
4682 {
4683 ;
4684 }
4685 }
4686#ifdef VMS
4687 else if (token == CPP_NAME)
4688 {
4689 /*
4690 * Support '#include xyz' like VAX-C to allow for easy use of all the
4691 * decwindow include files. It defaults to '#include <xyz.h>' (so the
4692 * code from case '<' is repeated here) and generates a warning.
4693 */
4694 cppReader_warning (pfile,
4695 "VAX-C-style include specification found, use '#include <filename.h>' !");
4696 angle_brackets = 1;
4697 /* If -I-, start with the first -I dir after the -I-. */
4698 if (CPPOPTIONS (pfile)->first_bracket_include)
4699 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4700 fbeg = pfile->token_buffer + old_written;
3e3ec469 4701 fend = cpplib_getPWritten (pfile);
ac0860d8 4702 }
4703#endif
4704 else
4705 {
4706 cppReader_error (pfile,
4707 message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
4708 keyword->name));
4709
4710 cppReader_setWritten (pfile, old_written);
4711 cppReader_skipRestOfLine (pfile);
4712 return 0;
4713 }
4714
4715 *fend = 0;
4716
4717 token = get_directive_token (pfile);
4718 if (token != CPP_VSPACE)
4719 {
4720 cppReader_errorLit (pfile,
4721 cstring_makeLiteralTemp ("Junk at end of #include"));
4722
4723 while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
4724 {
4725 token = get_directive_token (pfile);
4726 }
4727 }
4728
4729 /*
4730 ** For #include_next, skip in the search path
4731 ** past the dir in which the containing file was found.
4732 */
4733
4734 if (skip_dirs)
4735 {
4736 cppBuffer *fp = CPPBUFFER (pfile);
4737
4738 for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4739 {
4740 llassert (fp != NULL);
4741
4742 if (fp->fname != NULL)
4743 {
4744 /* fp->dir is null if the containing file was specified with
4745 an absolute file name. In that case, don't skip anything. */
4746 if (fp->dir == SELF_DIR_DUMMY)
4747 {
4748 search_start = CPPOPTIONS (pfile)->include;
4749 }
4750 else if (fp->dir != NULL)
4751 {
4752 search_start = fp->dir->next;
4753 }
4754 else
4755 {
4756 ;
4757 }
4758
4759 break;
4760 }
4761 }
4762 }
abd7f895 4763
ac0860d8 4764 cppReader_setWritten (pfile, old_written);
4765
abd7f895 4766 flen = size_fromInt (fend - fbeg);
ac0860d8 4767
4768 DPRINTF (("fbeg: %s", fbeg));
4769
4770 if (flen == 0)
4771 {
4772 cppReader_error (pfile,
4773 message ("Empty file name in #%s", keyword->name));
4774 return 0;
4775 }
4776
4777 /*
4778 ** Allocate this permanently, because it gets stored in the definitions
4779 ** of macros.
4780 */
4781
4782 fname = cstring_undefined;
4783
4784 /* + 2 above for slash and terminating null. */
4785 /* + 2 added for '.h' on VMS (to support '#include filename') */
4786
4787 /* If specified file name is absolute, just open it. */
4788
4789 if (osd_isConnectChar (*fbeg)
4790# if defined (WIN32) || defined (OS2)
4791 || (*(fbeg + 1) == ':')
4792# endif
4793 )
4794 {
4795 fname = cstring_copyLength (fbeg, flen);
4796
4797 if (redundant_include_p (pfile, fname))
4798 {
4799 cstring_free (fname);
4800 return 0;
4801 }
4802
4803 f = open_include_file (pfile, fname, NULL);
4804
4805 if (f == IMPORT_FOUND)
4806 {
4807 return 0; /* Already included this file */
4808 }
4809 }
4810 else
4811 {
4812 /* Search directory path, trying to open the file.
4813 Copy each filename tried into FNAME. */
4814
4815 for (searchptr = search_start; searchptr != NULL;
4816 searchptr = searchptr->next)
4817 {
4818 if (!cstring_isEmpty (searchptr->fname))
4819 {
4820 /* The empty string in a search path is ignored.
4821 This makes it possible to turn off entirely
4822 a standard piece of the list. */
4823 if (cstring_isEmpty (searchptr->fname))
4824 continue;
4825
4826 fname = cstring_copy (searchptr->fname);
4827 fname = cstring_appendChar (fname, CONNECTCHAR);
4828 DPRINTF (("Here: %s", fname));
4829 }
4830 else
4831 {
4832 ;
4833 }
4834
4835 fname = cstring_concatLength (fname, fbeg, flen);
4836
4837 DPRINTF (("fname: %s", fname));
4838
4839 /* Win32 directory fix from Kay Buschner. */
4840#if defined (WIN32) || defined (OS2)
4841 /* Fix all unixdir slashes to win dir slashes */
4842 if (searchptr->fname && (searchptr->fname[0] != 0))
4843 {
4844 cstring_replaceAll (fname, '/', '\\');
4845 }
4846#endif /* WIN32 */
4847
4848#ifdef VMS
4849 /* Change this 1/2 Unix 1/2 VMS file specification into a
4850 full VMS file specification */
4851 if (searchptr->fname && (searchptr->fname[0] != 0)) {
4852 /* Fix up the filename */
4853 hack_vms_include_specification (fname);
4854 } else {
4855 /* This is a normal VMS filespec, so use it unchanged. */
4856 strncpy (fname, fbeg, flen);
4857 fname[flen] = 0;
4858 /* if it's '#include filename', add the missing .h */
4859 if (strchr (fname,'.') == NULL) {
4860 strcat (fname, ".h");
4861 }
4862 }
4863#endif /* VMS */
4864 /* ??? There are currently 3 separate mechanisms for avoiding processing
4865 of redundant include files: #import, #pragma once, and
4866 redundant_include_p. It would be nice if they were unified. */
4867
4868 if (redundant_include_p (pfile, fname))
4869 {
4870 cstring_free (fname);
4871 return 0;
4872 }
4873
4874 DPRINTF (("Trying: %s", fname));
4875
4876 f = open_include_file (pfile, fname, searchptr);
4877
4878 if (f == IMPORT_FOUND)
4879 {
b73d1009 4880 return 0; /* Already included this file */
ac0860d8 4881 }
4882#ifdef EACCES
4883 else if (f == IMPORT_NOT_FOUND && errno == EACCES)
4884 {
4885 cppReader_warning (pfile,
4886 message ("Header file %s exists, but is not readable", fname));
4887 }
4888#endif
4889
4890 if (f >= 0)
4891 {
4892 break;
4893 }
4894 }
4895 }
4896
4897 if (f < 0)
4898 {
4899 /* A file that was not found. */
4900 fname = cstring_copyLength (fbeg, flen);
4901
4902 if (search_start != NULL)
4903 {
4904 cppReader_error (pfile,
4905 message ("Cannot find include file %s on search path: %x",
4906 fname,
4907 searchPath_unparse (search_start)));
4908 }
4909 else
4910 {
4911 cppReader_error (pfile,
4912 message ("No include path in which to find %s", fname));
4913 }
4914 }
4915 else {
4916 /*
4917 ** Check to see if this include file is a once-only include file.
4918 ** If so, give up.
4919 */
4920
4921 struct file_name_list *ptr;
4922
4923 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
4924 {
4925 if (cstring_equal (ptr->fname, fname))
4926 {
4927 /* This file was included before. */
4928 break;
4929 }
4930 }
4931
4932 if (ptr == NULL)
4933 {
4934 /* This is the first time for this file. */
4935 /* Add it to list of files included. */
4936
4937 ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
4938 ptr->control_macro = NULL;
4939 ptr->c_system_include_path = NULL;
4940 ptr->next = pfile->all_include_files;
4941 ptr->fname = fname;
4942 ptr->got_name_map = NULL;
4943
4944 DPRINTF (("Including file: %s", fname));
4945 pfile->all_include_files = ptr;
4946 assertSet (pfile->all_include_files);
4947 }
4948
4949 if (angle_brackets != 0)
4950 {
4951 pfile->system_include_depth++;
4952 }
4953
4954 /* Actually process the file */
4955 if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
4956 {
4957 cstring_free (fname);
4958 return 0;
4959 }
4960
4961 if (finclude (pfile, f, fname, is_system_include (pfile, fname),
4962 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
4963 {
4964 output_line_command (pfile, 0, enter_file);
4965 pfile->only_seen_white = 2;
4966 }
4967
4968 if (angle_brackets)
4969 {
4970 pfile->system_include_depth--;
4971 }
4972 /*@-branchstate@*/
4973 } /*@=branchstate@*/
4974
4975 return 0;
4976}
4977
4978/* Return nonzero if there is no need to include file NAME
4979 because it has already been included and it contains a conditional
4980 to make a repeated include do nothing. */
4981
4982static bool
4983redundant_include_p (cppReader *pfile, cstring name)
4984{
4985 struct file_name_list *l = pfile->all_include_files;
4986
4987 for (; l != NULL; l = l->next)
4988 {
4989 if (cstring_equal (name, l->fname)
4990 && (l->control_macro != NULL)
3e3ec469 4991 && (cpphash_lookup (l->control_macro, -1, -1) != NULL))
ac0860d8 4992 {
4993 return TRUE;
4994 }
4995 }
4996
4997 return FALSE;
4998}
4999
5000/* Return nonzero if the given FILENAME is an absolute pathname which
5001 designates a file within one of the known "system" include file
5002 directories. We assume here that if the given FILENAME looks like
5003 it is the name of a file which resides either directly in a "system"
5004 include file directory, or within any subdirectory thereof, then the
5005 given file must be a "system" include file. This function tells us
5006 if we should suppress pedantic errors/warnings for the given FILENAME.
5007
5008 The value is 2 if the file is a C-language system header file
5009 for which C++ should (on most systems) assume `extern "C"'. */
5010
5011static bool
5012is_system_include (cppReader *pfile, cstring filename)
5013{
5014 struct file_name_list *searchptr;
5015
5016 for (searchptr = CPPOPTIONS (pfile)->first_system_include;
5017 searchptr != NULL;
5018 searchptr = searchptr->next)
5019 {
abd7f895 5020 if (!cstring_isEmpty (searchptr->fname))
5021 {
5022 cstring sys_dir = searchptr->fname;
5023 size_t length = cstring_length (sys_dir);
5024
5025 if (cstring_equalLen (sys_dir, filename, length)
5026 && osd_isConnectChar (cstring_getChar (filename, length)))
5027 {
5028 if (searchptr->c_system_include_path)
5029 return 2;
5030 else
5031 return 1;
5032 }
5033 }
ac0860d8 5034 }
abd7f895 5035
ac0860d8 5036 return 0;
5037}
5038
5039/* Convert a character string literal into a nul-terminated string.
5040 The input string is [IN ... LIMIT).
5041 The result is placed in RESULT. RESULT can be the same as IN.
5042 The value returned in the end of the string written to RESULT,
5043 or NULL on error. */
5044
5045static /*@null@*/ char *
5046convert_string (cppReader *pfile, /*@returned@*/ char *result,
5047 char *in, char *limit, int handle_escapes)
5048{
5049 char c;
5050 c = *in++;
5051
5052 if (c != '\"')
5053 {
5054 return NULL;
5055 }
5056
5057 while (in < limit)
5058 {
5059 c = *in++;
5060
5061 switch (c)
5062 {
5063 case '\0':
5064 return NULL;
5065 case '\"':
5066 limit = in;
5067 /*@switchbreak@*/ break;
5068 case '\\':
5069 if (handle_escapes)
5070 {
5071 char *bpc = (char *) in;
5072 int i = (char) cppReader_parseEscape (pfile, &bpc);
5073 in = (char *) bpc;
5074 if (i >= 0)
5075 *result++ = (char) c;
5076 /*@switchbreak@*/ break;
5077 }
5078
5079 /*@fallthrough@*/
5080 default:
5081 *result++ = c;
5082 }
5083 }
5084
5085 *result = 0;
5086 return result;
5087}
5088
5089/*
5090 * interpret #line command. Remembers previously seen fnames
5091 * in its very own hash table.
5092 */
5093
5094/*@constant int FNAME_HASHSIZE@*/
5095#define FNAME_HASHSIZE 37
5096
5097static int
5098do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
5099{
5100 cppBuffer *ip = cppReader_getBuffer (pfile);
5101 int new_lineno;
3e3ec469 5102 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5103 enum file_change_code file_change = same_file;
5104 enum cpp_token token;
5105
abd7f895 5106 llassert (ip != NULL);
ac0860d8 5107 token = get_directive_token (pfile);
5108
5109 if (token != CPP_NUMBER
5110 || !isdigit(pfile->token_buffer[old_written]))
5111 {
5112 cppReader_errorLit (pfile,
5113 cstring_makeLiteralTemp ("invalid format `#line' command"));
5114
5115 goto bad_line_directive;
5116 }
5117
5118 /* The Newline at the end of this line remains to be processed.
5119 To put the next line at the specified line number,
5120 we must store a line number now that is one less. */
5121 new_lineno = atoi (pfile->token_buffer + old_written) - 1;
5122 cppReader_setWritten (pfile, old_written);
5123
5124 /* NEW_LINENO is one less than the actual line number here. */
5125 if (cppReader_isPedantic (pfile) && new_lineno < 0)
5126 cppReader_pedwarnLit (pfile,
5127 cstring_makeLiteralTemp ("line number out of range in `#line' command"));
5128
5129 token = get_directive_token (pfile);
5130
5131 if (token == CPP_STRING) {
5132 char *fname = pfile->token_buffer + old_written;
5133 char *end_name;
5134 static hashNode fname_table[FNAME_HASHSIZE];
5135 hashNode hp;
5136 hashNode *hash_bucket;
5137 char *p;
5138 size_t num_start;
abd7f895 5139 size_t fname_length;
ac0860d8 5140
5141 /* Turn the file name, which is a character string literal,
5142 into a null-terminated string. Do this in place. */
3e3ec469 5143 end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
ac0860d8 5144 if (end_name == NULL)
5145 {
5146 cppReader_errorLit (pfile,
5147 cstring_makeLiteralTemp ("invalid format `#line' command"));
5148 goto bad_line_directive;
5149 }
5150
abd7f895 5151 fname_length = size_fromInt (end_name - fname);
3e3ec469 5152 num_start = cpplib_getWritten (pfile);
ac0860d8 5153
5154 token = get_directive_token (pfile);
5155 if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
5156 p = pfile->token_buffer + num_start;
5157 if (cppReader_isPedantic (pfile))
5158 cppReader_pedwarnLit (pfile,
5159 cstring_makeLiteralTemp ("garbage at end of `#line' command"));
5160
5161 if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
5162 {
5163 cppReader_errorLit (pfile,
5164 cstring_makeLiteralTemp ("invalid format `#line' command"));
5165 goto bad_line_directive;
5166 }
5167 if (*p == '1')
5168 file_change = enter_file;
5169 else if (*p == 2)
5170 file_change = leave_file;
5171 else if (*p == 3)
5172 ip->system_header_p = 1;
5173 else /* if (*p == 4) */
5174 ip->system_header_p = 2;
5175
5176 cppReader_setWritten (pfile, num_start);
5177 token = get_directive_token (pfile);
5178 p = pfile->token_buffer + num_start;
5179 if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
5180 ip->system_header_p = *p == 3 ? 1 : 2;
5181 token = get_directive_token (pfile);
5182 }
5183 if (token != CPP_VSPACE) {
5184 cppReader_errorLit (pfile,
5185 cstring_makeLiteralTemp ("invalid format `#line' command"));
5186
5187 goto bad_line_directive;
5188 }
5189 }
5190
5191 hash_bucket =
3e3ec469 5192 &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
abd7f895 5193
ac0860d8 5194 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
5195 {
abd7f895 5196 if (hp->length == fname_length)
5197 {
5198 llassert (hp->value.cpval != NULL);
5199
5200 if (strncmp (hp->value.cpval, fname, fname_length) == 0)
5201 {
5202 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5203 break;
5204 }
5205 }
ac0860d8 5206 }
abd7f895 5207
ac0860d8 5208 if (hp == 0) {
5209 /* Didn't find it; cons up a new one. */
5210 hp = (hashNode) dmalloc (sizeof (*hp));
5211
5212 hp->prev = NULL;
5213 hp->bucket_hdr = NULL;
5214 hp->type = T_NONE;
5215 hp->name = cstring_undefined;
5216 hp->next = *hash_bucket;
5217
5218 *hash_bucket = hp;
5219
5220 hp->length = fname_length;
5221 hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
abd7f895 5222 memcpy (hp->value.cpval, fname, fname_length);
ac0860d8 5223 hp->value.cpval[fname_length] = '\0';
5224 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5225 }
5226 }
5227 else if (token != CPP_VSPACE && token != CPP_EOF)
5228 {
5229 cppReader_errorLit (pfile,
5230 cstring_makeLiteralTemp ("invalid format `#line' command"));
5231 goto bad_line_directive;
5232 }
5233 else
5234 {
5235 ;
5236 }
5237
5238 ip->lineno = new_lineno;
5239bad_line_directive:
5240 cppReader_skipRestOfLine (pfile);
5241 cppReader_setWritten (pfile, old_written);
5242 output_line_command (pfile, 0, file_change);
5243 return 0;
5244}
5245
5246/*
5247 * remove the definition of a symbol from the symbol table.
5248 * according to un*x /lib/cpp, it is not an error to undef
5249 * something that has no definitions, so it isn't one here either.
5250 */
5251
5252static int
5253do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
5254{
5255
abd7f895 5256 size_t sym_length;
ac0860d8 5257 hashNode hp;
5258 char *orig_buf = buf;
5259
5260 SKIP_WHITE_SPACE (buf);
5261
5262 sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
5263
abd7f895 5264 while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL)
ac0860d8 5265 {
5266 /* If we are generating additional info for debugging (with -g) we
5267 need to pass through all effective #undef commands. */
5268 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
5269 {
5270 pass_thru_directive (orig_buf, limit, pfile, keyword);
5271 }
5272
5273 if (hp->type != T_MACRO)
5274 {
5275 cppReader_warning (pfile,
5276 message ("Undefining preprocessor builtin: %s",
5277 hp->name));
5278 }
5279
5280 cppReader_deleteMacro (hp);
5281 }
5282
5283 if (cppReader_isPedantic (pfile)) {
5284 buf += sym_length;
5285 SKIP_WHITE_SPACE (buf);
5286 if (buf != limit)
5287 {
5288 cppReader_pedwarnLit (pfile,
5289 cstring_makeLiteralTemp ("garbage after `#undef' directive"));
5290 }
5291 }
5292
5293 return 0;
5294}
5295
5296
5297/*
5298 * Report an error detected by the program we are processing.
5299 * Use the text of the line in the error message.
5300 * (We use error because it prints the filename & line#.)
5301 */
5302
5303static int
5304do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5305 char *buf, char *limit)
5306{
abd7f895 5307 size_t length = size_fromInt (limit - buf);
ac0860d8 5308 cstring copy = cstring_copyLength (buf, length);
5309 cstring adv = cstring_advanceWhiteSpace (copy);
5310
5311 cppReader_error (pfile, message ("#error %s", adv));
5312 cstring_free (copy);
5313 return 0;
5314}
5315
5316/*
5317 * Report a warning detected by the program we are processing.
5318 * Use the text of the line in the warning message, then continue.
5319 * (We use error because it prints the filename & line#.)
5320 */
5321
5322static int
5323do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5324 char *buf, char *limit)
5325{
abd7f895 5326 size_t length = size_fromInt (limit - buf);
ac0860d8 5327 cstring copy = cstring_copyLength (buf, length);
5328 cstring adv = cstring_advanceWhiteSpace (copy);
5329 cppReader_warning (pfile, message ("#warning %s", adv));
5330 cstring_free (copy);
5331 return 0;
5332}
5333
5334
5335/* #ident has already been copied to the output file, so just ignore it. */
5336
5337static int
5338do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5339 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5340{
5341 /* Allow #ident in system headers, since that's not user's fault. */
abd7f895 5342 if (cppReader_isPedantic (pfile)
5343 && !cppReader_getBufferSafe (pfile)->system_header_p)
ac0860d8 5344 cppReader_pedwarnLit (pfile,
5345 cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
5346
3e3ec469 5347 /* Leave rest of line to be read by later calls to cpplib_getToken. */
ac0860d8 5348
5349 return 0;
5350}
5351
5352/* #pragma and its argument line have already been copied to the output file.
5353 Just check for some recognized pragmas that need validation here. */
5354
5355static int
5356do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5357 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5358{
5359 while (*buf == ' ' || *buf == '\t')
5360 {
5361 buf++;
5362 }
5363
5364 if (!strncmp (buf, "implementation", 14)) {
5365 /* Be quiet about `#pragma implementation' for a file only if it hasn't
5366 been included yet. */
5367 struct file_name_list *ptr;
5368 char *p = buf + 14, *fname, *inc_fname;
abd7f895 5369 size_t fname_len;
ac0860d8 5370 SKIP_WHITE_SPACE (p);
5371 if (*p == '\n' || *p != '\"')
5372 return 0;
5373
5374 fname = p + 1;
5375 p = (char *) strchr (fname, '\"');
abd7f895 5376 fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
ac0860d8 5377
5378 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
5379 {
5380 inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
5381 inc_fname = (inc_fname != NULL)
5382 ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
5383
5384 if ((inc_fname != NULL)
abd7f895 5385 && (strncmp (inc_fname, fname, fname_len) == 0))
ac0860d8 5386 {
5387 cpp_setLocation (pfile);
5388
5389 ppllerror (message ("`#pragma implementation' for `%s' appears "
5390 "after file is included",
5391 cstring_fromChars (fname)));
5392 }
5393 }
5394 }
5395
5396 return 0;
5397}
5398
5399/*
5400 * handle #if command by
5401 * 1) inserting special `defined' keyword into the hash table
5402 * that gets turned into 0 or 1 by special_symbol (thus,
5403 * if the luser has a symbol called `defined' already, it won't
5404 * work inside the #if command)
5405 * 2) rescan the input into a temporary output buffer
5406 * 3) pass the output buffer to the yacc parser and collect a value
5407 * 4) clean up the mess left from steps 1 and 2.
5408 * 5) call conditional_skip to skip til the next #endif (etc.),
5409 * or not, depending on the value from step 3.
5410 */
5411
5412static int
5413do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5414 char *buf, char *limit)
5415{
3e3ec469 5416 HOST_WIDE_INT value;
5417 DPRINTF (("Do if: %s", buf));
5418 value = eval_if_expression (pfile, buf, limit - buf);
ac0860d8 5419 conditional_skip (pfile, value == 0, T_IF, NULL);
5420 return 0;
5421}
5422
5423/*
5424 * handle a #elif directive by not changing if_stack either.
5425 * see the comment above do_else.
5426 */
5427
5428static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5429 char *buf, char *limit)
5430{
abd7f895 5431 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5432 {
5433 cppReader_errorLit (pfile,
5434 cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
5435 return 0;
5436 }
5437 else
5438 {
5439 llassert (pfile->if_stack != NULL);
5440
5441 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5442 {
5443 cppReader_errorLit (pfile,
5444 cstring_makeLiteralTemp ("`#elif' after `#else'"));
5445
5446 if (pfile->if_stack->fname != NULL
abd7f895 5447 && cppReader_getBufferSafe (pfile)->fname != NULL
ac0860d8 5448 && !cstring_equal (pfile->if_stack->fname,
abd7f895 5449 cppReader_getBufferSafe (pfile)->nominal_fname))
ac0860d8 5450 fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
5451 fprintf (stderr, ")\n");
5452 }
5453 pfile->if_stack->type = T_ELIF;
5454 }
5455
5456 if (pfile->if_stack->if_succeeded)
5457 {
5458 skip_if_group (pfile, 0);
5459 }
5460 else
5461 {
5462 HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
5463 if (value == 0)
5464 skip_if_group (pfile, 0);
5465 else
5466 {
5467 ++pfile->if_stack->if_succeeded; /* continue processing input */
5468 output_line_command (pfile, 1, same_file);
5469 }
5470 }
5471
5472 return 0;
5473}
5474
5475/*
5476 * evaluate a #if expression in BUF, of length LENGTH,
5477 * then parse the result as a C expression and return the value as an int.
5478 */
5479
5480static HOST_WIDE_INT
5481eval_if_expression (cppReader *pfile,
5482 /*@unused@*/ char *buf,
5483 /*@unused@*/ int length)
5484{
5485 hashNode save_defined;
5486 HOST_WIDE_INT value;
3e3ec469 5487 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5488
3e3ec469 5489 DPRINTF (("Saving defined..."));
5490 save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
ac0860d8 5491 pfile->pcp_inside_if = 1;
5492
5493 value = cppReader_parseExpression (pfile);
5494 pfile->pcp_inside_if = 0;
5495
5496 /* Clean up special symbol */
3e3ec469 5497 DPRINTF (("Removing defined..."));
ac0860d8 5498 cppReader_deleteMacro (save_defined);
ac0860d8 5499 cppReader_setWritten (pfile, old_written); /* Pop */
5500
5501 return value;
5502}
5503
5504/*
5505 * routine to handle ifdef/ifndef. Try to look up the symbol,
5506 * then do or don't skip to the #endif/#else/#elif depending
5507 * on what directive is actually being processed.
5508 */
5509
5510static int
5511do_xifdef (cppReader *pfile, struct directive *keyword,
5512 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
5513{
5514 int skip;
abd7f895 5515 cppBuffer *ip = cppReader_getBufferSafe (pfile);
ac0860d8 5516 char *ident;
abd7f895 5517 size_t ident_length;
ac0860d8 5518 enum cpp_token token;
5519 int start_of_file = 0;
5520 char *control_macro = 0;
3e3ec469 5521 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5522
5523 DPRINTF (("do xifdef: %d",
5524 keyword->type == T_IFNDEF));
5525
5526 /* Detect a #ifndef at start of file (not counting comments). */
5527 if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
5528 {
5529 start_of_file = pfile->only_seen_white == 2;
5530 }
5531
5532 pfile->no_macro_expand++;
5533 token = get_directive_token (pfile);
5534 pfile->no_macro_expand--;
5535
5536 ident = pfile->token_buffer + old_written;
3e3ec469 5537 DPRINTF (("Ident: %s", ident));
5538
abd7f895 5539 ident_length = cpplib_getWritten (pfile) - old_written;
ac0860d8 5540 cppReader_setWritten (pfile, old_written); /* Pop */
5541
5542 if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
5543 {
5544 skip = (keyword->type == T_IFDEF);
5545 if (! cppReader_isTraditional (pfile))
5546 {
5547 cppReader_pedwarn (pfile,
3e3ec469 5548 message ("`#%s' with no argument", keyword->name));
ac0860d8 5549 }
5550 }
5551 else if (token == CPP_NAME)
5552 {
abd7f895 5553 hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1);
3e3ec469 5554
abd7f895 5555 skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
3e3ec469 5556
abd7f895 5557 DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
3e3ec469 5558
ac0860d8 5559 if (start_of_file && !skip)
5560 {
5561 DPRINTF (("Not skipping!"));
e5081f8c 5562 control_macro = (char *) dmalloc (ident_length + 1);
5563 memcpy (control_macro, ident, ident_length + 1);
ac0860d8 5564 }
5565 }
5566 else
5567 {
5568 skip = (keyword->type == T_IFDEF);
5569 if (! cppReader_isTraditional (pfile))
5570 {
5571 cppReader_error (pfile,
5572 message ("`#%s' with invalid argument", keyword->name));
5573 }
5574 }
5575
5576 if (!cppReader_isTraditional (pfile))
5577 {
5578 int c;
5579 cppSkipHspace (pfile);
5580 c = cppReader_peekC (pfile);
5581 if (c != EOF && c != '\n')
5582 {
5583 cppReader_pedwarn (pfile,
5584 message ("garbage at end of `#%s' argument", keyword->name));
5585 }
5586 }
5587
5588 cppReader_skipRestOfLine (pfile);
5589
5590 DPRINTF (("Conditional skip: %d", skip));
5591 conditional_skip (pfile, skip, T_IF, control_macro);
5592 return 0;
5593}
5594
5595/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
5596 If this is a #ifndef starting at the beginning of a file,
5597 CONTROL_MACRO is the macro name tested by the #ifndef.
5598 Otherwise, CONTROL_MACRO is 0. */
5599
5600static void
5601conditional_skip (cppReader *pfile, int skip,
5602 enum node_type type,
5603 /*@dependent@*/ char *control_macro)
5604{
5605 cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5606
abd7f895 5607 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 5608 temp->next = pfile->if_stack;
5609 temp->control_macro = control_macro;
5610 temp->lineno = 0;
5611 temp->if_succeeded = 0;
5612
5613 pfile->if_stack = temp;
5614 pfile->if_stack->type = type;
5615
5616 if (skip != 0)
5617 {
5618 skip_if_group (pfile, 0);
5619 return;
5620 }
5621 else
5622 {
5623 ++pfile->if_stack->if_succeeded;
5624 output_line_command (pfile, 1, same_file);
5625 }
5626}
5627
5628/*
5629 * skip to #endif, #else, or #elif. adjust line numbers, etc.
5630 * leaves input ptr at the sharp sign found.
5631 * If ANY is nonzero, return at next directive of any sort.
5632 */
5633
5634static void
5635skip_if_group (cppReader *pfile, int any)
5636{
5637 int c;
5638 struct directive *kt;
5639 cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
5640 register int ident_length;
5641 char *ident;
5642 struct parse_marker line_start_mark;
5643
5644 parseSetMark (&line_start_mark, pfile);
5645
5646 if (CPPOPTIONS (pfile)->output_conditionals) {
5647 static char failed[] = "#failed\n";
5648 cppReader_puts (pfile, failed, sizeof(failed)-1);
5649 pfile->lineno++;
5650 output_line_command (pfile, 1, same_file);
5651 }
5652
5653beg_of_line:
5654 if (CPPOPTIONS (pfile)->output_conditionals)
5655 {
abd7f895 5656 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 5657 char *start_line;
5658
5659 llassert (pbuf->buf != NULL);
5660
5661 start_line = pbuf->buf + line_start_mark.position;
5662 cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
5663 }
5664
5665 parseMoveMark (&line_start_mark, pfile);
5666
5667 if (!cppReader_isTraditional (pfile))
5668 {
5669 cppSkipHspace (pfile);
5670 }
5671
5672 c = cppReader_getC (pfile);
5673 if (c == '#')
5674 {
3e3ec469 5675 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5676 cppSkipHspace (pfile);
5677
5678 parse_name (pfile, cppReader_getC (pfile));
3e3ec469 5679 ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
ac0860d8 5680 ident = pfile->token_buffer + old_written;
5681 pfile->limit = ident;
5682
5683 for (kt = directive_table; kt->length >= 0; kt++)
5684 {
5685 cppIfStackFrame *temp;
5686 if (ident_length == kt->length
5687 && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
5688 {
5689 /* If we are asked to return on next directive, do so now. */
5690 if (any)
5691 {
5692 goto done;
5693 }
5694
5695 switch (kt->type)
5696 {
5697 case T_IF:
5698 case T_IFDEF:
5699 case T_IFNDEF:
5700 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5701 temp->next = pfile->if_stack;
abd7f895 5702 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 5703 temp->type = kt->type;
5704 temp->lineno = 0;
5705 temp->if_succeeded = 0;
5706 temp->control_macro = NULL;
5707
5708 pfile->if_stack = temp;
5709 /*@switchbreak@*/ break;
5710 case T_ELSE:
5711 case T_ENDIF:
5712 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
5713 validate_else (pfile,
5714 cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
5715 /*@fallthrough@*/
5716 case T_ELIF:
abd7f895 5717 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5718 {
5719 cppReader_error (pfile,
5720 message ("Preprocessor command #%s is not within a conditional", kt->name));
5721 /*@switchbreak@*/ break;
5722 }
5723 else if (pfile->if_stack == save_if_stack)
5724 {
5725 goto done; /* found what we came for */
5726 }
5727 else
5728 {
5729 ;
5730 }
5731
5732 if (kt->type != T_ENDIF)
5733 {
5734 llassert (pfile->if_stack != NULL);
5735
5736 if (pfile->if_stack->type == T_ELSE)
5737 {
5738 cppReader_errorLit (pfile,
5739 cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
5740 }
5741
5742 pfile->if_stack->type = kt->type;
5743 /*@switchbreak@*/ break;
5744 }
5745
5746 temp = pfile->if_stack;
5747 llassert (temp != NULL);
5748 pfile->if_stack = temp->next;
5749 sfree (temp);
5750 /*@switchbreak@*/ break;
5751 default: ;
5752 /*@-branchstate@*/
9622303f 5753#if defined (OS2) && defined (__IBMC__)
5754 /* Dummy code to eleminate optimization problems with icc */
5755 c = 0;
5756# endif
5757
ac0860d8 5758 }
5759 /*@=branchstate@*/
5760 break;
5761 }
5762
5763 /* Don't let erroneous code go by. */
5764
5765 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
5766 && cppReader_isPedantic (pfile))
5767 {
5768 cppReader_pedwarnLit (pfile,
5769 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
5770 }
5771 }
5772
5773 c = cppReader_getC (pfile);
5774 }
5775 /* We're in the middle of a line. Skip the rest of it. */
5776 for (;;) {
5777 size_t old;
5778
5779 switch (c)
5780 {
5781 case EOF:
5782 goto done;
5783 case '/': /* possible comment */
5784 c = skip_comment (pfile, NULL);
5785 if (c == EOF)
5786 goto done;
5787 /*@switchbreak@*/ break;
5788 case '\"':
5789 case '\'':
5790 cppReader_forward (pfile, -1);
3e3ec469 5791 old = cpplib_getWritten (pfile);
5792 (void) cpplib_getToken (pfile);
ac0860d8 5793 cppReader_setWritten (pfile, old);
5794 /*@switchbreak@*/ break;
5795 case '\\':
5796 /* Char after backslash loses its special meaning. */
5797 if (cppReader_peekC (pfile) == '\n')
5798 {
5799 cppReader_forward (pfile, 1);
5800 }
5801
5802 /*@switchbreak@*/ break;
5803 case '\n':
5804 goto beg_of_line;
5805 }
5806 c = cppReader_getC (pfile);
5807 }
5808done:
5809 if (CPPOPTIONS (pfile)->output_conditionals) {
5810 static char end_failed[] = "#endfailed\n";
5811 cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
5812 pfile->lineno++;
5813 }
5814 pfile->only_seen_white = 1;
5815
5816 parseGotoMark (&line_start_mark, pfile);
5817 parseClearMark (&line_start_mark);
5818}
5819
5820/*
5821 * handle a #else directive. Do this by just continuing processing
5822 * without changing if_stack ; this is so that the error message
5823 * for missing #endif's etc. will point to the original #if. It
5824 * is possible that something different would be better.
5825 */
5826
5827static int
5828do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5829 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5830{
5831 if (cppReader_isPedantic (pfile))
5832 {
5833 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5834 }
5835
5836 cppReader_skipRestOfLine (pfile);
5837
abd7f895 5838 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
ac0860d8 5839 cppReader_errorLit (pfile,
5840 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5841 return 0;
5842 } else {
5843 /* #ifndef can't have its special treatment for containing the whole file
5844 if it has a #else clause. */
5845
5846 llassert (pfile->if_stack != NULL);
5847
5848 pfile->if_stack->control_macro = 0;
5849
5850 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5851 {
5852 cpp_setLocation (pfile);
5853 genppllerrorhint (FLG_PREPROC,
5854 message ("Pre-processor directive #else after #else"),
5855 message ("%q: Location of match",
5856 fileloc_unparseRaw (pfile->if_stack->fname,
5857 pfile->if_stack->lineno)));
5858 }
5859
5860 pfile->if_stack->type = T_ELSE;
5861 }
5862
5863 if (pfile->if_stack->if_succeeded)
5864 skip_if_group (pfile, 0);
5865 else {
5866 ++pfile->if_stack->if_succeeded; /* continue processing input */
5867 output_line_command (pfile, 1, same_file);
5868 }
5869
5870 return 0;
5871}
5872
5873/*
5874 * unstack after #endif command
5875 */
5876
5877static int
5878do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5879 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5880{
5881 if (cppReader_isPedantic (pfile))
5882 {
5883 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5884 }
5885
5886 cppReader_skipRestOfLine (pfile);
5887
abd7f895 5888 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5889 {
5890 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5891 }
5892 else
5893 {
5894 cppIfStackFrame *temp = pfile->if_stack;
5895
5896 llassert (temp != NULL);
5897
5898 pfile->if_stack = temp->next;
5899 if (temp->control_macro != 0)
5900 {
5901 /* This #endif matched a #ifndef at the start of the file.
5902 See if it is at the end of the file. */
5903 struct parse_marker start_mark;
5904 int c;
5905
5906 parseSetMark (&start_mark, pfile);
5907
5908 for (;;)
5909 {
5910 cppSkipHspace (pfile);
5911 c = cppReader_getC (pfile);
5912
5913 if (c != '\n')
5914 break;
5915 }
5916
5917 parseGotoMark (&start_mark, pfile);
5918 parseClearMark (&start_mark);
5919
5920 if (c == EOF)
5921 {
5922 /* If we get here, this #endif ends a #ifndef
5923 that contains all of the file (aside from whitespace).
5924 Arrange not to include the file again
5925 if the macro that was tested is defined.
5926
5927 Do not do this for the top-level file in a -include or any
5928 file in a -imacros. */
5929 struct file_name_list *ifile = pfile->all_include_files;
5930
5931 for ( ; ifile != NULL; ifile = ifile->next)
5932 {
abd7f895 5933 if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
ac0860d8 5934 {
5935 ifile->control_macro = temp->control_macro;
5936 break;
5937 }
5938 }
5939 }
5940 }
5941
5942 sfree (temp);
5943 output_line_command (pfile, 1, same_file);
5944 }
5945 return 0;
5946}
5947
5948/* When an #else or #endif is found while skipping failed conditional,
5949 if -pedantic was specified, this is called to warn about text after
5950 the command name. P points to the first char after the command name. */
5951
5952static void
5953validate_else (cppReader *pfile, cstring directive)
5954{
5955 int c;
5956 cppSkipHspace (pfile);
5957 c = cppReader_peekC (pfile);
5958 if (c != EOF && c != '\n')
5959 {
5960 cppReader_pedwarn (pfile,
5961 message ("text following `%s' violates ANSI standard", directive));
5962 }
5963}
5964
5965/*
5966** Get the next token, and add it to the text in pfile->token_buffer.
5967** Return the kind of token we got.
5968*/
5969
5970enum cpp_token
3e3ec469 5971cpplib_getToken (cppReader *pfile)
5972{
5973 return cpplib_getTokenAux (pfile, FALSE);
5974}
5975
5976enum cpp_token
5977cpplib_getTokenForceExpand (cppReader *pfile)
5978{
5979 return cpplib_getTokenAux (pfile, TRUE);
5980}
5981
5982enum cpp_token
5983cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
ac0860d8 5984{
5985 int c, c2, c3;
5986 size_t old_written = 0;
5987 int start_line, start_column;
5988 enum cpp_token token;
5989 struct cppOptions *opts = CPPOPTIONS (pfile);
abd7f895 5990 cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
ac0860d8 5991
5992get_next:
5993 c = cppReader_getC (pfile);
3e3ec469 5994 DPRINTF (("Get next token: %c", c));
ac0860d8 5995
5996 if (c == EOF)
5997 {
5998 handle_eof:
abd7f895 5999 if (cppReader_getBufferSafe (pfile)->seen_eof)
ac0860d8 6000 {
6001 cppBuffer *buf = cppReader_popBuffer (pfile);
6002
6003 if (buf != cppReader_nullBuffer (pfile))
6004 {
6005 goto get_next;
6006 }
6007 else
6008 {
6009 return CPP_EOF;
6010 }
6011 }
6012 else
6013 {
abd7f895 6014 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6015 cppReader_getBufferSafe (pfile)->seen_eof = 1;
ac0860d8 6016
abd7f895 6017 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
ac0860d8 6018 && next_buf != cppReader_nullBuffer (pfile))
6019 {
6020 /* We're about to return from an #include file.
6021 Emit #line information now (as part of the CPP_POP) result.
6022 But the #line refers to the file we will pop to. */
6023 cppBuffer *cur_buffer = CPPBUFFER (pfile);
6024 CPPBUFFER (pfile) = next_buf;
6025 pfile->input_stack_listing_current = 0;
6026 output_line_command (pfile, 0, leave_file);
6027 CPPBUFFER (pfile) = cur_buffer;
6028 }
6029 return CPP_POP;
6030 }
6031 }
6032 else
6033 {
6034 long newlines;
6035 struct parse_marker start_mark;
6036
6037 switch (c)
6038 {
6039 case '/':
6040 if (cppReader_peekC (pfile) == '=')
6041 {
6042 goto op2;
6043 }
6044
6045 if (opts->put_out_comments)
6046 {
6047 parseSetMark (&start_mark, pfile);
6048 }
6049
6050 newlines = 0;
80489f0a 6051 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
ac0860d8 6052 &start_line, &start_column);
6053 c = skip_comment (pfile, &newlines);
ce7034f0 6054 DPRINTF (("c = %c", c));
ac0860d8 6055 if (opts->put_out_comments && (c == '/' || c == EOF))
6056 {
6057 assertSet (&start_mark);
6058 parseClearMark (&start_mark);
6059 }
6060
6061 if (c == '/')
6062 goto randomchar;
6063 if (c == EOF)
6064 {
6065 cppReader_errorWithLine (pfile, start_line, start_column,
6066 cstring_makeLiteral ("Unterminated comment"));
6067 goto handle_eof;
6068 }
6069 c = '/'; /* Initial letter of comment. */
6070 return_comment:
6071 /* Comments are equivalent to spaces.
6072 For -traditional, a comment is equivalent to nothing. */
6073
6074 if (opts->put_out_comments)
6075 {
6076 enum cpp_token res;
6077
6078 assertSet (&start_mark);
6079 res = cpp_handleComment (pfile, &start_mark);
6080 pfile->lineno += newlines;
6081 return res;
6082 }
6083 else if (cppReader_isTraditional (pfile))
6084 {
6085 return CPP_COMMENT;
6086 }
6087 else
6088 {
3e3ec469 6089 cpplib_reserve(pfile, 1);
ac0860d8 6090 cppReader_putCharQ (pfile, ' ');
6091 return CPP_HSPACE;
6092 }
6093
6094 case '#':
6095 if (!pfile->only_seen_white)
6096 {
6097 goto randomchar;
6098 }
6099
6100 if (cppReader_handleDirective (pfile))
6101 {
6102 return CPP_DIRECTIVE;
6103 }
6104
6105 pfile->only_seen_white = 0;
6106 return CPP_OTHER;
6107
6108 case '\"':
6109 case '\'':
6110 /* A single quoted string is treated like a double -- some
6111 programs (e.g., troff) are perverse this way */
80489f0a 6112 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
6113 &start_line, &start_column);
3e3ec469 6114 old_written = cpplib_getWritten (pfile);
ac0860d8 6115 string:
c09ebffe 6116 DPRINTF (("Reading string: %c", c));
ac0860d8 6117 cppReader_putChar (pfile, c);
6118 while (TRUE)
6119 {
c09ebffe 6120 /* evans-2003-06-07
6121 ** Because of ISO8859-1 characters in string literals, we need a special test here.
6122 */
6123
6124 if (cppReader_reachedEOF (pfile))
ac0860d8 6125 {
c09ebffe 6126
6127 DPRINTF (("Matches EOF!"));
ac0860d8 6128 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
6129 {
6130 /* try harder: this string crosses a macro expansion
6131 boundary. This can happen naturally if -traditional.
6132 Otherwise, only -D can make a macro with an unmatched
6133 quote. */
6134 cppBuffer *next_buf
abd7f895 6135 = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6136 (*cppReader_getBufferSafe (pfile)->cleanup)
6137 (cppReader_getBufferSafe (pfile), pfile);
ac0860d8 6138 CPPBUFFER (pfile) = next_buf;
6139 continue;
6140 }
c09ebffe 6141
ac0860d8 6142 if (!cppReader_isTraditional (pfile))
6143 {
6144 cpp_setLocation (pfile);
6145
6146 setLine (long_toInt (start_line));
6147 setColumn (long_toInt (start_column));
c09ebffe 6148
ac0860d8 6149 if (pfile->multiline_string_line != long_toInt (start_line)
6150 && pfile->multiline_string_line != 0)
6151 {
6152 genppllerrorhint
6153 (FLG_PREPROC,
6154 message ("Unterminated string or character constant"),
6155 message ("%q: Possible real start of unterminated constant",
6156 fileloc_unparseRaw
6157 (fileloc_filename (g_currentloc),
6158 pfile->multiline_string_line)));
6159 pfile->multiline_string_line = 0;
6160 }
6161 else
6162 {
6163 genppllerror
6164 (FLG_PREPROC,
6165 message ("Unterminated string or character constant"));
6166 }
6167 }
c09ebffe 6168 /*@loopbreak@*/ break;
6169 }
6170 else
ac0860d8 6171 {
c09ebffe 6172 int cc = cppReader_getC (pfile);
6173 DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF));
6174 DPRINTF (("putting char: %c", cc));
6175 cppReader_putChar (pfile, cc);
6176 switch (cc)
ac0860d8 6177 {
c09ebffe 6178 case '\n':
6179 /* Traditionally, end of line ends a string constant with
6180 no error. So exit the loop and record the new line. */
6181 if (cppReader_isTraditional (pfile))
6182 goto while2end;
6183 if (c == '\'')
6184 {
6185 goto while2end;
6186 }
6187 if (cppReader_isPedantic (pfile)
6188 && pfile->multiline_string_line == 0)
6189 {
6190 cppReader_pedwarnWithLine
6191 (pfile, long_toInt (start_line),
6192 long_toInt (start_column),
6193 cstring_makeLiteral ("String constant runs past end of line"));
6194 }
6195 if (pfile->multiline_string_line == 0)
6196 {
6197 pfile->multiline_string_line = start_line;
6198 }
6199
6200 /*@switchbreak@*/ break;
6201
6202 case '\\':
6203 cc = cppReader_getC (pfile);
6204 if (cc == '\n')
6205 {
6206 /* Backslash newline is replaced by nothing at all. */
6207 cppReader_adjustWritten (pfile, -1);
6208 pfile->lineno++;
6209 }
6210 else
6211 {
6212 /* ANSI stupidly requires that in \\ the second \
6213 is *not* prevented from combining with a newline. */
6214 NEWLINE_FIX1(cc);
6215 if (cc != EOF)
6216 cppReader_putChar (pfile, cc);
6217 }
6218 /*@switchbreak@*/ break;
6219
6220 case '\"':
6221 case '\'':
6222 if (cc == c)
6223 goto while2end;
6224 /*@switchbreak@*/ break;
ac0860d8 6225 }
ac0860d8 6226 }
6227 }
6228 while2end:
6229 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
3e3ec469 6230 cpplib_getPWritten (pfile));
ac0860d8 6231 pfile->only_seen_white = 0;
6232 return c == '\'' ? CPP_CHAR : CPP_STRING;
6233
6234 case '$':
6235 if (!opts->dollars_in_ident)
6236 goto randomchar;
6237 goto letter;
6238
6239 case ':':
6240 if (opts->cplusplus && cppReader_peekC (pfile) == ':')
6241 goto op2;
6242 goto randomchar;
6243
6244 case '&':
6245 case '+':
6246 case '|':
6247 NEWLINE_FIX;
6248 c2 = cppReader_peekC (pfile);
6249 if (c2 == c || c2 == '=')
6250 goto op2;
6251 goto randomchar;
6252
6253 case '*':
6254 case '!':
6255 case '%':
6256 case '=':
6257 case '^':
6258 NEWLINE_FIX;
6259 if (cppReader_peekC (pfile) == '=')
6260 goto op2;
6261 goto randomchar;
6262
6263 case '-':
6264 NEWLINE_FIX;
6265 c2 = cppReader_peekC (pfile);
6266 if (c2 == '-' && opts->chill)
6267 {
6268 /* Chill style comment */
6269 if (opts->put_out_comments)
6270 {
6271 parseSetMark (&start_mark, pfile);
6272 }
6273
6274 cppReader_forward (pfile, 1); /* Skip second '-'. */
6275
6276 for (;;)
6277 {
6278 c = cppReader_getC (pfile);
6279 if (c == EOF)
6280 /*@loopbreak@*/ break;
6281 if (c == '\n')
6282 {
6283 /* Don't consider final '\n' to be part of comment. */
6284 cppReader_forward (pfile, -1);
6285 /*@loopbreak@*/ break;
6286 }
6287 }
6288 c = '-';
6289 goto return_comment;
6290 }
6291 if (c2 == '-' || c2 == '=' || c2 == '>')
6292 goto op2;
6293 goto randomchar;
6294
6295 case '<':
6296 if (pfile->parsing_include_directive)
6297 {
6298 for (;;)
6299 {
6300 cppReader_putChar (pfile, c);
6301 if (c == '>')
6302 /*@loopbreak@*/ break;
6303 c = cppReader_getC (pfile);
6304 NEWLINE_FIX1 (c);
6305 if (c == '\n' || c == EOF)
6306 {
6307 cppReader_errorLit (pfile,
6308 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
6309 /*@loopbreak@*/ break;
6310 }
6311 }
6312 return CPP_STRING;
6313 }
6314 /*@fallthrough@*/
6315 case '>':
6316 NEWLINE_FIX;
6317 c2 = cppReader_peekC (pfile);
6318 if (c2 == '=')
6319 goto op2;
6320 if (c2 != c)
6321 goto randomchar;
6322 cppReader_forward (pfile, 1);
3e3ec469 6323 cpplib_reserve (pfile, 4);
ac0860d8 6324 cppReader_putChar (pfile, c);
6325 cppReader_putChar (pfile, c2);
6326 NEWLINE_FIX;
6327 c3 = cppReader_peekC (pfile);
6328 if (c3 == '=')
6329 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6330 cppReader_nullTerminateQ (pfile);
6331 pfile->only_seen_white = 0;
6332 return CPP_OTHER;
6333
6334 case '@':
ce7034f0 6335 DPRINTF (("Macro @!"));
abd7f895 6336 if (cppReader_getBufferSafe (pfile)->has_escapes)
ac0860d8 6337 {
6338 c = cppReader_getC (pfile);
ce7034f0 6339 DPRINTF (("got c: %c", c));
ac0860d8 6340 if (c == '-')
6341 {
6342 if (pfile->output_escapes)
6343 cppReader_puts (pfile, "@-", 2);
6344 parse_name (pfile, cppReader_getC (pfile));
6345 return CPP_NAME;
6346 }
6347 else if (is_space [c])
6348 {
3e3ec469 6349 cpplib_reserve (pfile, 2);
ac0860d8 6350 if (pfile->output_escapes)
6351 cppReader_putCharQ (pfile, '@');
6352 cppReader_putCharQ (pfile, c);
6353 return CPP_HSPACE;
6354 }
6355 else
6356 {
6357 ;
6358 }
6359 }
6360 if (pfile->output_escapes)
6361 {
6362 cppReader_puts (pfile, "@@", 2);
6363 return CPP_OTHER;
6364 }
6365 goto randomchar;
6366 case '.':
6367 NEWLINE_FIX;
6368 c2 = cppReader_peekC (pfile);
6369 if (isdigit(c2))
6370 {
3e3ec469 6371 cpplib_reserve(pfile, 2);
ac0860d8 6372 cppReader_putCharQ (pfile, '.');
6373 c = cppReader_getC (pfile);
6374 goto number;
6375 }
6376
6377 /* FIXME - misses the case "..\\\n." */
6378 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
6379 {
3e3ec469 6380 cpplib_reserve(pfile, 4);
ac0860d8 6381 cppReader_putCharQ (pfile, '.');
6382 cppReader_putCharQ (pfile, '.');
6383 cppReader_putCharQ (pfile, '.');
6384 cppReader_forward (pfile, 2);
6385 cppReader_nullTerminateQ (pfile);
6386 pfile->only_seen_white = 0;
6387 return CPP_3DOTS;
6388 }
6389 goto randomchar;
6390 op2:
6391 token = CPP_OTHER;
6392 pfile->only_seen_white = 0;
f4e355aa 6393 op2any: /* jumped to for \ continuations */
3e3ec469 6394 cpplib_reserve(pfile, 3);
ac0860d8 6395 cppReader_putCharQ (pfile, c);
f4e355aa 6396
6397 /* evans 2003-08-24: This is a hack to fix line output for \
6398 continuations. Someday I really should get a decent pre-processor!
6399 */
6400
6401 if (c == '\\') {
6402 (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */
6403 } else {
6404 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6405 }
6406
ac0860d8 6407 cppReader_nullTerminateQ (pfile);
6408 return token;
6409
6410 case 'L':
6411 NEWLINE_FIX;
6412 c2 = cppReader_peekC (pfile);
6413 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6414 {
6415 cppReader_putChar (pfile, c);
6416 c = cppReader_getC (pfile);
6417 goto string;
6418 }
6419 goto letter;
6420
6421 case '0': case '1': case '2': case '3': case '4':
6422 case '5': case '6': case '7': case '8': case '9':
6423 number:
6424 c2 = '.';
6425 for (;;)
6426 {
3e3ec469 6427 cpplib_reserve (pfile, 2);
ac0860d8 6428 cppReader_putCharQ (pfile, c);
6429 NEWLINE_FIX;
6430 c = cppReader_peekC (pfile);
6431 if (c == EOF)
6432 /*@loopbreak@*/ break;
6433 if (!is_idchar[c] && c != '.'
6434 && ((c2 != 'e' && c2 != 'E'
6435 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6436 || (c != '+' && c != '-')))
6437 /*@loopbreak@*/ break;
6438 cppReader_forward (pfile, 1);
6439 c2= c;
6440 }
6441
6442 cppReader_nullTerminateQ (pfile);
6443 pfile->only_seen_white = 0;
6444 return CPP_NUMBER;
6445
6446 case 'b': case 'c': case 'd': case 'h': case 'o':
6447 case 'B': case 'C': case 'D': case 'H': case 'O':
6448 if (opts->chill && cppReader_peekC (pfile) == '\'')
6449 {
6450 pfile->only_seen_white = 0;
3e3ec469 6451 cpplib_reserve (pfile, 2);
ac0860d8 6452 cppReader_putCharQ (pfile, c);
6453 cppReader_putCharQ (pfile, '\'');
6454 cppReader_forward (pfile, 1);
6455 for (;;)
6456 {
6457 c = cppReader_getC (pfile);
6458 if (c == EOF)
6459 goto chill_number_eof;
6460 if (!is_idchar[c])
6461 {
6462 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6463 {
6464 cppReader_forward (pfile, 2);
6465 continue;
6466 }
6467 /*@loopbreak@*/ break;
6468 }
6469 cppReader_putChar (pfile, c);
6470 }
6471 if (c == '\'')
6472 {
3e3ec469 6473 cpplib_reserve (pfile, 2);
ac0860d8 6474 cppReader_putCharQ (pfile, c);
6475 cppReader_nullTerminateQ (pfile);
6476 return CPP_STRING;
6477 }
6478 else
6479 {
6480 cppReader_forward (pfile, -1);
6481 chill_number_eof:
6482 cppReader_nullTerminate (pfile);
6483 return CPP_NUMBER;
6484 }
6485 }
6486 else
6487 goto letter;
6488 case '_':
6489 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
6490 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
6491 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
6492 case 'x': case 'y': case 'z':
6493 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
6494 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
6495 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6496 case 'Y': case 'Z':
6497 letter:
6498 {
6499 hashNode hp;
6500 char *ident;
3e3ec469 6501 size_t before_name_written = cpplib_getWritten (pfile);
abd7f895 6502 size_t ident_len;
ac0860d8 6503 parse_name (pfile, c);
6504 pfile->only_seen_white = 0;
3e3ec469 6505
ac0860d8 6506 if (pfile->no_macro_expand)
6507 {
3e3ec469 6508 DPRINTF (("Not expanding: %s", pfile->token_buffer));
ac0860d8 6509 return CPP_NAME;
6510 }
6511
6512 ident = pfile->token_buffer + before_name_written;
3e3ec469 6513 DPRINTF (("Ident: %s", ident));
6514
abd7f895 6515 ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
ac0860d8 6516
abd7f895 6517 hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand);
ac0860d8 6518
6519 if (hp == NULL)
6520 {
3e3ec469 6521 DPRINTF (("No expand: %s %d", ident, ident_len));
ac0860d8 6522 return CPP_NAME;
6523 }
6524
6525 if (hp->type == T_DISABLED)
6526 {
3e3ec469 6527 DPRINTF (("Disabled!"));
6528
ac0860d8 6529 if (pfile->output_escapes)
6530 { /* Return "@-IDENT", followed by '\0'. */
6531 int i;
3e3ec469 6532 cpplib_reserve (pfile, 3);
ac0860d8 6533 ident = pfile->token_buffer + before_name_written;
6534 cppReader_adjustWritten (pfile, 2);
6535
abd7f895 6536 for (i = size_toInt (ident_len); i >= 0; i--)
ac0860d8 6537 {
6538 ident[i+2] = ident[i];
6539 }
6540
6541 ident[0] = '@';
6542 ident[1] = '-';
6543 }
6544 return CPP_NAME;
6545 }
6546
3e3ec469 6547 /*
6548 ** If macro wants an arglist, verify that a '(' follows.
6549 ** first skip all whitespace, copying it to the output
6550 ** after the macro name. Then, if there is no '(',
6551 ** decide this is not a macro call and leave things that way.
6552 */
6553
ac0860d8 6554 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6555 {
6556 struct parse_marker macro_mark;
6557 int is_macro_call;
6558
ce7034f0 6559 DPRINTF (("Arglist macro!"));
6560
755ee3f6 6561 /*
6562 ** evans 2002-07-03: Moved this here (from below).
6563 ** This bug caused necessary whitespace to be lost
6564 ** when parsing parameterized macros without parameters.
6565 */
6566
ce7034f0 6567 parseSetMark (&macro_mark, pfile);
6568
ac0860d8 6569 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6570 {
6571 cppBuffer *next_buf;
6572 cppSkipHspace (pfile);
6573 if (cppReader_peekC (pfile) != EOF)
6574 {
ce7034f0 6575 DPRINTF (("Peeking!"));
ac0860d8 6576 /*@loopbreak@*/ break;
6577 }
6578
abd7f895 6579 next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6580 (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
ac0860d8 6581 CPPBUFFER (pfile) = next_buf;
6582 }
6583
ce7034f0 6584 /* parseSetMark (&macro_mark, pfile); */
ac0860d8 6585
6586 for (;;)
6587 {
6588 cppSkipHspace (pfile);
6589 c = cppReader_peekC (pfile);
ce7034f0 6590 DPRINTF (("c: %c", c));
ac0860d8 6591 is_macro_call = c == '(';
6592 if (c != '\n')
6593 /*@loopbreak@*/ break;
6594 cppReader_forward (pfile, 1);
6595 }
6596
6597 if (!is_macro_call)
6598 {
6599 parseGotoMark (&macro_mark, pfile);
6600 }
6601
6602 parseClearMark (&macro_mark);
6603
6604 if (!is_macro_call)
6605 {
ce7034f0 6606 DPRINTF (("not macro call!"));
ac0860d8 6607 return CPP_NAME;
6608 }
6609 }
ce7034f0 6610
ac0860d8 6611 /* This is now known to be a macro call. */
6612
6613 /* it might not actually be a macro. */
6614 if (hp->type != T_MACRO)
6615 {
6616 size_t xbuf_len;
6617 char *xbuf;
6618
6619 cppReader_setWritten (pfile, before_name_written);
6620 special_symbol (hp, pfile);
3e3ec469 6621 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
ac0860d8 6622 xbuf = (char *) dmalloc (xbuf_len + 1);
6623 cppReader_setWritten (pfile, before_name_written);
3e3ec469 6624 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
ac0860d8 6625 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6626 }
6627 else
6628 {
3e3ec469 6629 /*
6630 ** Expand the macro, reading arguments as needed,
6631 ** and push the expansion on the input stack.
6632 */
6633
6634 cpplib_macroExpand (pfile, hp);
ac0860d8 6635 cppReader_setWritten (pfile, before_name_written);
6636 }
6637
6638 /* An extra "@ " is added to the end of a macro expansion
6639 to prevent accidental token pasting. We prefer to avoid
6640 unneeded extra spaces (for the sake of cpp-using tools like
6641 imake). Here we remove the space if it is safe to do so. */
6642
6643 llassert (pfile->buffer->rlimit != NULL);
6644
6645 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6646 && pfile->buffer->rlimit[-2] == '@'
6647 && pfile->buffer->rlimit[-1] == ' ')
6648 {
6649 int c1 = pfile->buffer->rlimit[-3];
3e3ec469 6650 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
ac0860d8 6651
6652 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6653 pfile->buffer->rlimit -= 2;
6654 }
6655 }
6656 goto get_next;
6657
6658
6659 case ' ': case '\t': case '\v': case '\r':
6660 for (;;)
6661 {
6662 cppReader_putChar (pfile, c);
6663 c = cppReader_peekC (pfile);
6664 if (c == EOF || !is_hor_space[c])
6665 /*@loopbreak@*/ break;
6666 cppReader_forward (pfile, 1);
6667 }
6668 return CPP_HSPACE;
6669
6670 case '\\':
6671 c2 = cppReader_peekC (pfile);
f4e355aa 6672 //! allow other stuff here if a flag is set?
6673 DPRINTF (("Got continuation!"));
ac0860d8 6674 if (c2 != '\n')
6675 goto randomchar;
6676 token = CPP_HSPACE;
6677 goto op2any;
6678
6679 case '\n':
6680 cppReader_putChar (pfile, c);
6681 if (pfile->only_seen_white == 0)
6682 pfile->only_seen_white = 1;
6683 pfile->lineno++;
6684 output_line_command (pfile, 1, same_file);
6685 return CPP_VSPACE;
6686
6687 case '(': token = CPP_LPAREN; goto char1;
6688 case ')': token = CPP_RPAREN; goto char1;
6689 case '{': token = CPP_LBRACE; goto char1;
6690 case '}': token = CPP_RBRACE; goto char1;
6691 case ',': token = CPP_COMMA; goto char1;
6692 case ';': token = CPP_SEMICOLON; goto char1;
6693
6694 randomchar:
6695 default:
6696 token = CPP_OTHER;
6697 char1:
6698 pfile->only_seen_white = 0;
6699 cppReader_putChar (pfile, c);
6700 return token;
6701 }
6702 }
6703
6704 BADBRANCH;
6705 /*@notreached@*/
6706}
6707
6708/* Parse an identifier starting with C. */
6709
6710void
6711parse_name (cppReader *pfile, int c)
6712{
6713 for (;;)
6714 {
6715 if (!is_idchar[c])
6716 {
6717 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6718 {
6719 cppReader_forward (pfile, 2);
6720 continue;
6721 }
6722
6723 cppReader_forward (pfile, -1);
6724 break;
6725 }
6726
6727 if (c == '$' && cppReader_isPedantic (pfile))
6728 {
6729 cppReader_pedwarnLit (pfile,
6730 cstring_makeLiteralTemp ("`$' in identifier"));
6731 }
6732
3e3ec469 6733 cpplib_reserve(pfile, 2); /* One more for final NUL. */
ac0860d8 6734 cppReader_putCharQ (pfile, c);
6735 c = cppReader_getC (pfile);
6736
6737 if (c == EOF)
6738 break;
6739 }
6740
6741 cppReader_nullTerminateQ (pfile);
6742}
6743
6744/* The file_name_map structure holds a mapping of file names for a
6745 particular directory. This mapping is read from the file named
6746 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
6747 map filenames on a file system with severe filename restrictions,
6748 such as DOS. The format of the file name map file is just a series
6749 of lines with two tokens on each line. The first token is the name
6750 to map, and the second token is the actual name to use. */
6751
6752struct file_name_map
6753{
6754 struct file_name_map *map_next;
6755 cstring map_from;
6756 cstring map_to;
6757};
6758
6759/*@constant observer char *FILE_NAME_MAP_FILE*/
6760#define FILE_NAME_MAP_FILE "header.gcc"
6761
6762/* Read a space delimited string of unlimited length from a stdio
6763 file. */
6764
6765static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6766{
6767 char *alloc, *set;
6768 size_t len;
6769
6770 len = 20;
6771 set = alloc = dmalloc (len + 1);
6772
6773 if (!is_space[ch])
6774 {
6775 *set++ = ch;
6776 while ((ch = getc (f)) != EOF && ! is_space[ch])
6777 {
6778 if (set - alloc == size_toInt (len))
6779 {
6780 len *= 2;
6781 alloc = drealloc (alloc, len + 1);
6782 set = alloc + len / 2;
6783 /*@-branchstate@*/ }
6784
6785 *set++ = ch;
6786 } /*@=branchstate@*/
6787 }
6788 *set = '\0';
6789 check (ungetc (ch, f) != EOF);
6790
6791 return cstring_fromChars (alloc);
6792}
6793
6794/* This structure holds a linked list of file name maps, one per directory. */
6795
6796struct file_name_map_list
6797{
6fcd0b1e 6798 /*@only@*/ struct file_name_map_list *map_list_next;
6799 /*@only@*/ cstring map_list_name;
abd7f895 6800 /*@null@*/ struct file_name_map *map_list_map;
ac0860d8 6801};
6802
6803/* Read the file name map file for DIRNAME. */
6804
6805static struct file_name_map *
6806read_name_map (cppReader *pfile, cstring dirname)
6807{
6808 struct file_name_map_list *map_list_ptr;
6809 cstring name;
6810 FILE *f;
6811
6812 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6813 map_list_ptr != NULL;
6814 map_list_ptr = map_list_ptr->map_list_next)
6815 {
6816 if (cstring_equal (map_list_ptr->map_list_name, dirname))
6817 {
6818 return map_list_ptr->map_list_map;
6819 }
6820 }
6821
6822 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6823 map_list_ptr->map_list_name = cstring_copy (dirname);
6824 map_list_ptr->map_list_map = NULL;
6825
6826 name = cstring_copy (dirname);
6827
6828 if (cstring_length (dirname) > 0)
6829 {
6830 name = cstring_appendChar (name, CONNECTCHAR);
6831 }
6832
6833 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6834
d5047b91 6835 f = fileTable_openReadFile (context_fileTable (), name);
ac0860d8 6836 cstring_free (name);
6837
6838 if (f == NULL)
6839 {
6840 map_list_ptr->map_list_map = NULL;
6841 }
6842 else
6843 {
6844 int ch;
6845
6846 while ((ch = getc (f)) != EOF)
6847 {
6848 cstring from, to;
6849 struct file_name_map *ptr;
6850
6851 if (is_space[ch])
6852 {
6853 continue;
6854 }
6855
6856 from = read_filename_string (ch, f);
6857 while ((ch = getc (f)) != EOF && is_hor_space[ch])
6858 {
6859 ;
6860 }
6861
6862 to = read_filename_string (ch, f);
6863
6864 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6865 ptr->map_from = from;
6866
6867 /* Make the real filename absolute. */
6868 if (cstring_length (to) > 1
6869 && osd_isConnectChar (cstring_firstChar (to)))
6870 {
6871 ptr->map_to = to;
6872 }
6873 else
6874 {
6875 ptr->map_to = cstring_copy (dirname);
6876 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6877 ptr->map_to = cstring_concatFree (ptr->map_to, to);
6878 }
6879
6880 ptr->map_next = map_list_ptr->map_list_map;
6881 map_list_ptr->map_list_map = ptr;
6882
6883 while ((ch = getc (f)) != '\n')
6884 {
6885 if (ch == EOF)
6886 {
6887 /*@innerbreak@*/ break;
6888 }
6889 }
6890 }
6891
6892 assertSet (map_list_ptr->map_list_map);
6893 check (fileTable_closeFile (context_fileTable (),f) == 0);
6894 }
6895
6896 map_list_ptr->map_list_next = pfile->opts->map_list;
6897 pfile->opts->map_list = map_list_ptr;
6898
6899 return map_list_ptr->map_list_map;
6900}
6901
6902/* Try to open include file FILENAME. SEARCHPTR is the directory
6903 being tried from the include file search path. This function maps
6904 filenames on file systems based on information read by
6905 read_name_map. */
6906
6907static int
6908open_include_file (cppReader *pfile,
6909 cstring fname,
6910 struct file_name_list *searchptr)
6911{
6912 char *filename = cstring_toCharsSafe (fname);
6913 struct file_name_map *map;
6914 char *from;
6915 char *p, *dir;
6916
6917 cstring_markOwned (fname);
6918
6919 cpp_setLocation (pfile);
6920
6921 if (context_getFlag (FLG_NEVERINCLUDE))
6922 {
6923 if (isHeaderFile (fname))
6924 {
6925 return SKIP_INCLUDE;
6926 }
6927 }
6928
6929 if ((searchptr != NULL) && ! searchptr->got_name_map)
6930 {
6931 searchptr->name_map = read_name_map (pfile,
6932 !cstring_isEmpty (searchptr->fname)
6933 ? searchptr->fname :
6934 cstring_makeLiteralTemp ("."));
6935 searchptr->got_name_map = 1;
6936 }
6937
6938 /* First check the mapping for the directory we are using. */
6939
6940 if ((searchptr != NULL)
6941 && (searchptr->name_map != NULL))
6942 {
6943 from = filename;
6944
6945 if (!cstring_isEmpty (searchptr->fname))
6946 {
6947 from += cstring_length (searchptr->fname) + 1;
6948 }
6949
6950 for (map = searchptr->name_map;
6951 map != NULL;
6952 map = map->map_next)
6953 {
6954 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6955 {
6956 /*
6957 ** Found a match. Check if the file should be skipped
6958 */
6959
6960 if (cpp_skipIncludeFile (map->map_to))
6961 {
6962 return SKIP_INCLUDE;
6963 }
6964 else
6965 {
6966 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6967 }
6968 }
6969 }
6970 }
6971
6972 /*
6973 ** Try to find a mapping file for the particular directory we are
6974 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6975 ** in /usr/include/header.gcc and look up types.h in
6976 ** /usr/include/sys/header.gcc.
6977 */
6978
6979 p = strrchr (filename, CONNECTCHAR);
6980
6981 if (p == NULL)
6982 {
6983 p = filename;
6984 }
6985
6986 if ((searchptr != NULL)
6987 && (cstring_isDefined (searchptr->fname))
abd7f895 6988 && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
ac0860d8 6989 && !strncmp (cstring_toCharsSafe (searchptr->fname),
6990 filename,
6991 size_fromInt (p - filename)))
6992 {
6993 /* filename is in SEARCHPTR, which we've already checked. */
6994
6995 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6996 {
6997 return SKIP_INCLUDE;
6998 }
6999 else
7000 {
7001 return cpp_openIncludeFile (filename);
7002 }
7003 }
7004
7005 if (p == filename)
7006 {
7007 dir = mstring_copy (".");
7008 from = filename;
7009 }
7010 else
7011 {
7012 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
7013 memcpy (dir, filename, size_fromInt (p - filename));
7014 dir[p - filename] = '\0';
7015 from = p + 1;
7016 }
7017
7018 for (map = read_name_map (pfile, cstring_fromChars (dir));
7019 map != NULL;
7020 map = map->map_next)
7021 {
7022 if (cstring_equal (map->map_from, cstring_fromChars (from)))
7023 {
7024 sfree (dir);
7025
7026 if (cpp_skipIncludeFile (map->map_to))
7027 {
7028 return SKIP_INCLUDE;
7029 }
7030 else
7031 {
7032 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
7033 }
7034 }
7035 }
7036
7037 sfree (dir);
7038
7039 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7040 {
7041 return SKIP_INCLUDE;
7042 }
7043 else
7044 {
7045 return cpp_openIncludeFile (filename);
7046 }
7047}
7048
7049/* Process the contents of include file FNAME, already open on descriptor F,
7050 with output to OP.
7051 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
7052 "system" include directories (as decided by the `is_system_include'
7053 function above).
7054 DIRPTR is the link in the dir path through which this file was found,
7055 or 0 if the file name was absolute or via the current directory.
7056 Return 1 on success, 0 on failure.
7057
7058 The caller is responsible for the cppReader_pushBuffer. */
7059
7060static int
7061finclude (cppReader *pfile, int f,
7062 cstring fname,
7063 bool system_header_p,
7064 /*@dependent@*/ struct file_name_list *dirptr)
7065{
7066 mode_t st_mode;
7067 size_t st_size;
7068 long i;
7069 int length = 0;
7070 cppBuffer *fp; /* For input stack frame */
7071
7072 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
7073 {
7074 cppReader_perrorWithName (pfile, fname);
7075 check (close (f) == 0);
7076 (void) cppReader_popBuffer (pfile);
7077 /*@-mustfree@*/
7078 return 0;
7079 /*@=mustfree@*/
7080 }
7081
abd7f895 7082 fp = cppReader_getBufferSafe (pfile);
ac0860d8 7083
7084 /*@-temptrans@*/ /* fname shouldn't really be temp */
7085 fp->nominal_fname = fp->fname = fname;
7086 /*@=temptrans@*/
7087
7088 fp->dir = dirptr;
7089 fp->system_header_p = system_header_p;
7090 fp->lineno = 1;
7091 fp->colno = 1;
7092 fp->cleanup = cppReader_fileCleanup;
7093
7094 if (S_ISREG (st_mode))
7095 {
7096 sfree (fp->buf);
7097 fp->buf = (char *) dmalloc (st_size + 2);
7098 fp->alimit = fp->buf + st_size + 2;
7099 fp->cur = fp->buf;
7100
7101 /* Read the file contents, knowing that st_size is an upper bound
7102 on the number of bytes we can read. */
7103 length = safe_read (f, fp->buf, size_toInt (st_size));
7104 fp->rlimit = fp->buf + length;
7105 if (length < 0) goto nope;
7106 }
7107 else if (S_ISDIR (st_mode))
7108 {
7109 cppReader_error (pfile,
6fcd0b1e 7110 message ("Directory specified where file is expected: %s", fname));
ac0860d8 7111 check (close (f) == 0);
7112 return 0;
7113 }
7114 else
7115 {
7116 /*
7117 ** Cannot count its file size before reading.
7118 ** First read the entire file into heap and
7119 ** copy them into buffer on stack.
7120 */
7121
7122 size_t bsize = 2000;
7123
7124 st_size = 0;
7125
7126 sfree (fp->buf);
7127 fp->buf = (char *) dmalloc (bsize + 2);
7128
7129 for (;;) {
7130 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
7131
7132 if (i < 0)
7133 goto nope; /* error! */
7134 st_size += i;
7135
7136 if (st_size != bsize)
7137 {
7138 break; /* End of file */
7139 }
7140
7141 bsize *= 2;
7142 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
7143 }
7144
7145 fp->cur = fp->buf;
7146 length = size_toInt (st_size);
7147 }
7148
7149 if ((length > 0 && fp->buf[length - 1] != '\n')
7150 /* Backslash-newline at end is not good enough. */
7151 || (length > 1 && fp->buf[length - 2] == '\\')) {
7152 fp->buf[length++] = '\n';
7153 }
7154
7155 fp->buf[length] = '\0';
7156 fp->rlimit = fp->buf + length;
7157
7158 /* Close descriptor now, so nesting does not use lots of descriptors. */
7159 check (close (f) == 0);
7160
7161 /* Must do this before calling trigraph_pcp, so that the correct file name
7162 will be printed in warning messages. */
7163
7164 pfile->input_stack_listing_current = 0;
7165 return 1;
7166
7167 nope:
7168
7169 cppReader_perrorWithName (pfile, fname);
7170 check (close (f) == 0);
7171 sfree (fp->buf);
7172 return 1;
7173}
7174
7175void
3e3ec469 7176cpplib_init (cppReader *pfile)
ac0860d8 7177{
7178 memset ((char *) pfile, 0, sizeof (*pfile));
7179
3e3ec469 7180 pfile->get_token = cpplib_getToken;
ac0860d8 7181 pfile->token_buffer_size = 200;
7182 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
7183 pfile->all_include_files = NULL;
7184
7185 assertSet (pfile);
7186
7187 cppReader_setWritten (pfile, 0);
7188
7189 pfile->system_include_depth = 0;
7190 pfile->max_include_len = 0;
7191 pfile->timebuf = NULL;
7192 pfile->only_seen_white = 1;
7193
7194 pfile->buffer = cppReader_nullBuffer (pfile);
7195}
7196
7197void
7198cppReader_finish (/*@unused@*/ cppReader *pfile)
7199{
7200 ;
7201}
7202
7203/* Free resources used by PFILE.
7204 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
7205
7206void
6fcd0b1e 7207cppCleanup (/*@special@*/ cppReader *pfile)
7208 /*@uses pfile@*/
7209 /*@releases pfile@*/
ac0860d8 7210{
6fcd0b1e 7211 DPRINTF (("cppCleanup!"));
7212
ac0860d8 7213 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
7214 {
7215 (void) cppReader_popBuffer (pfile);
7216 }
7217
7218 if (pfile->token_buffer != NULL)
7219 {
7220 sfree (pfile->token_buffer);
7221 pfile->token_buffer = NULL;
7222 }
7223
7224 while (pfile->if_stack != NULL)
7225 {
7226 cppIfStackFrame *temp = pfile->if_stack;
7227 pfile->if_stack = temp->next;
7228 sfree (temp);
7229 }
7230
7231 while (pfile->all_include_files != NULL)
7232 {
7233 struct file_name_list *temp = pfile->all_include_files;
7234 pfile->all_include_files = temp->next;
7235 /*@-dependenttrans@*/
7236 cstring_free (temp->fname);
7237 /*@=dependenttrans@*/
7238 sfree (temp);
7239 }
7240
6fcd0b1e 7241 /* evans 2002-07-12 */
7242 while (pfile->opts->map_list != NULL)
7243 {
7244 struct file_name_map_list *temp = pfile->opts->map_list;
7245 pfile->opts->map_list = pfile->opts->map_list->map_list_next;
7246 cstring_free (temp->map_list_name);
7247 sfree (temp);
7248 }
7249
7250 while (pfile->opts->include != NULL)
7251 {
7252 struct file_name_list *temp = pfile->opts->include;
7253 pfile->opts->include = pfile->opts->include->next;
7254 /* cstring_free (temp->fname); */
7255 sfree (temp);
7256 }
7257
7258 sfree (pfile->opts);
7259 pfile->opts = NULL;
ac0860d8 7260 cppReader_hashCleanup ();
7261}
7262
7263/*
7264** Get the file-mode and data size of the file open on FD
7265** and store them in *MODE_POINTER and *SIZE_POINTER.
7266*/
7267
7268static int
7269file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
7270{
7271 struct stat sbuf;
7272
7273 if (fstat (fd, &sbuf) < 0) {
3e3ec469 7274 *mode_pointer = 0;
7275 *size_pointer = 0;
ac0860d8 7276 return (-1);
7277 }
7278
7279 if (mode_pointer != NULL)
7280 {
7281 *mode_pointer = sbuf.st_mode;
7282 }
7283
7284 if (size_pointer != NULL)
7285 {
7286 *size_pointer = (size_t) sbuf.st_size;
7287 }
7288
7289 return 0;
7290}
7291
7292/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
7293 retrying if necessary. Return a negative value if an error occurs,
7294 otherwise return the actual number of bytes read,
7295 which must be LEN unless end-of-file was reached. */
7296
7297static int safe_read (int desc, char *ptr, int len)
7298{
7299 int left = len;
7300
7301 while (left > 0)
7302 {
7303# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
7304 /*@-compdef@*/ /* ptr is an out parameter */
7305 int nchars = _read (desc, ptr, (unsigned) left);
7306 /*@=compdef@*/
7307# else
7308 ssize_t nchars = read (desc, ptr, size_fromInt (left));
7309# endif
7310
7311 if (nchars < 0)
7312 {
7313#ifdef EINTR
7314 if (errno == EINTR)
7315 continue;
7316#endif
7317 return (int) nchars;
7318 }
7319
7320 if (nchars == 0) {
7321 break;
7322 }
7323
7324 ptr += nchars;
7325 left -= nchars;
7326 }
7327
7328 return len - left;
7329}
7330
7331/* Initialize PMARK to remember the current position of PFILE. */
7332
7333void
7334parseSetMark (struct parse_marker *pmark, cppReader *pfile)
7335{
abd7f895 7336 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7337
7338 pmark->next = pbuf->marks;
7339 /*@-temptrans@*/
7340 pbuf->marks = pmark;
7341 /*@=temptrans@*/
7342
7343 pmark->buf = pbuf;
7344 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7345 DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7346}
7347
7348/* Cleanup PMARK - we no longer need it. */
7349
7350void parseClearMark (struct parse_marker *pmark)
7351{
7352 struct parse_marker **pp = &pmark->buf->marks;
7353
7354 for (; ; pp = &(*pp)->next)
7355 {
7356 llassert (*pp != NULL);
7357 if (*pp == pmark) break;
7358 }
7359
7360 *pp = pmark->next;
7361}
7362
7363/* Backup the current position of PFILE to that saved in PMARK. */
7364
7365void
7366parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
7367{
abd7f895 7368 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7369
7370 if (pbuf != pmark->buf)
7371 {
7372 cpp_setLocation (pfile);
7373 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
7374 }
7375
7376 llassert (pbuf->buf != NULL);
7377 pbuf->cur = pbuf->buf + pmark->position;
ce7034f0 7378 DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7379}
7380
7381/* Reset PMARK to point to the current position of PFILE. (Same
7382 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
7383
7384void
7385parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
7386{
abd7f895 7387 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7388
7389 if (pbuf != pmark->buf)
7390 {
7391 cpp_setLocation (pfile);
7392 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
7393 }
7394
7395 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7396 DPRINTF (("move mark: %s", pmark->position));
ac0860d8 7397}
7398
3e3ec469 7399void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
ac0860d8 7400{
7401 struct cppOptions *opts = CPPOPTIONS (pfile);
7402 cstring xp;
7403
7404 /* The code looks at the defaults through this pointer, rather than through
7405 the constant structure above. This pointer gets changed if an environment
7406 variable specifies other defaults. */
7407
7408 struct default_include *include_defaults = include_defaults_array;
7409
7410 /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */
7411 /* There seems to be confusion about what CPATH should do,
7412 so for the moment it is not documented. */
7413 /* Some people say that CPATH should replace the standard include dirs,
7414 but that seems pointless: it comes before them, so it overrides them
7415 anyway. */
7416
7417 xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
7418
7419 if (cstring_isDefined (xp) && !opts->no_standard_includes)
7420 {
7421 path_include (pfile, cstring_toCharsSafe (xp));
7422 }
7423
7424 /* Now that dollars_in_ident is known, initialize is_idchar. */
7425 initialize_char_syntax (opts);
7426
7427 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
7428 and option processing. */
7429
7430 initialize_builtins (pfile);
7431
7432 /* Do standard #defines and assertions
7433 that identify system and machine type. */
7434
7435 if (!opts->inhibit_predefs) {
7436 char *p = (char *) dmalloc (strlen (predefs) + 1);
7437 strcpy (p, predefs);
7438
7439 while (*p)
7440 {
7441 char *q;
7442
7443 while (*p == ' ' || *p == '\t')
7444 {
7445 p++;
7446 }
7447
7448 /* Handle -D options. */
7449 if (p[0] == '-' && p[1] == 'D')
7450 {
7451 q = &p[2];
7452
7453 while (*p && *p != ' ' && *p != '\t')
7454 {
7455 p++;
7456 }
7457
7458 if (*p != 0)
7459 {
7460 *p++= 0;
7461 }
7462
7463 if (opts->debug_output)
7464 {
7465 output_line_command (pfile, 0, same_file);
7466 }
7467
7468 cppReader_define (pfile, q);
7469
7470 while (*p == ' ' || *p == '\t')
7471 {
7472 p++;
7473 }
7474 }
7475 else
7476 {
7477 abort ();
7478 }
7479 }
7480
7481 sfree (p);
7482 }
7483
7484 opts->done_initializing = 1;
7485
7486 { /* Read the appropriate environment variable and if it exists
7487 replace include_defaults with the listed path. */
7488 char *epath = 0;
7489#ifdef __CYGWIN32__
7490 char *win32epath;
7491 int win32_buf_size = 0; /* memory we need to allocate */
7492#endif
7493
7494 if (opts->cplusplus)
7495 {
7496 epath = getenv ("CPLUS_INCLUDE_PATH");
7497 }
7498 else
7499 {
7500 epath = getenv ("C_INCLUDE_PATH");
7501 }
7502
7503 /*
7504 ** If the environment var for this language is set,
7505 ** add to the default list of include directories.
7506 */
7507
7508 if (epath != NULL) {
7509 char *nstore = (char *) dmalloc (strlen (epath) + 2);
7510 int num_dirs;
7511 char *startp, *endp;
7512
7513#ifdef __CYGWIN32__
7514 /* if we have a posix path list, convert to win32 path list */
7515 if (cygwin32_posix_path_list_p (epath))
7516 {
7517 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
7518 win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
7519 cygwin32_posix_to_win32_path_list (epath, win32epath);
7520 epath = win32epath;
7521 }
7522#endif
7523 for (num_dirs = 1, startp = epath; *startp; startp++)
7524 {
7525 if (*startp == PATH_SEPARATOR)
7526 num_dirs++;
7527 }
7528
7529 /*@-sizeoftype@*/
7530 include_defaults
7531 = (struct default_include *) dmalloc ((num_dirs
7532 * sizeof (struct default_include))
7533 + sizeof (include_defaults_array));
7534 /*@=sizeoftype@*/
7535
7536 startp = endp = epath;
7537 num_dirs = 0;
7538 while (1) {
7539 /* Handle cases like c:/usr/lib:d:/gcc/lib */
7540 if ((*endp == PATH_SEPARATOR) || *endp == 0)
7541 {
7542 strncpy (nstore, startp, size_fromInt (endp - startp));
7543 if (endp == startp)
7544 {
7545 strcpy (nstore, ".");
7546 }
7547 else
7548 {
7549 nstore[endp-startp] = '\0';
7550 }
7551
7552 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
7553 include_defaults[num_dirs].cplusplus = opts->cplusplus;
7554 include_defaults[num_dirs].cxx_aware = 1;
7555 num_dirs++;
7556
7557 if (*endp == '\0')
7558 {
7559 break;
7560 }
7561 endp = startp = endp + 1;
7562 }
7563 else
7564 {
7565 endp++;
7566 }
7567 }
7568 /* Put the usual defaults back in at the end. */
7569 memcpy ((char *) &include_defaults[num_dirs],
7570 (char *) include_defaults_array,
7571 sizeof (include_defaults_array));
7572
7573 sfree (nstore);
7574 /*@-branchstate@*/ } /*@=branchstate@*/
7575 }
7576
7577 cppReader_appendIncludeChain (pfile, opts->before_system,
7578 opts->last_before_system);
6fcd0b1e 7579
ac0860d8 7580 opts->first_system_include = opts->before_system;
7581
7582 /* Unless -fnostdinc,
7583 tack on the standard include file dirs to the specified list */
abd7f895 7584
ac0860d8 7585 if (!opts->no_standard_includes) {
7586 struct default_include *p = include_defaults;
7587 char *specd_prefix = opts->include_prefix;
7588 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
e5081f8c 7589 size_t default_len = 0;
abd7f895 7590
7591 /* Remove the `include' from /usr/local/lib/gcc.../include. */
7592 if (default_prefix != NULL) {
7593 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
7594 default_len = strlen (default_prefix) - 7;
7595 default_prefix[default_len] = 0;
7596 }
ac0860d8 7597 }
abd7f895 7598
ac0860d8 7599 /* Search "translated" versions of GNU directories.
7600 These have /usr/local/lib/gcc... replaced by specd_prefix. */
7601 if (specd_prefix != 0 && default_len != 0)
7602 for (p = include_defaults; p->fname != NULL; p++) {
7603 /* Some standard dirs are only for C++. */
7604 if (!p->cplusplus
7605 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
7606 /* Does this dir start with the prefix? */
abd7f895 7607 llassert (default_prefix != NULL);
7608
e5081f8c 7609 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
ac0860d8 7610 {
7611 /* Yes; change prefix and add to search list. */
7612 struct file_name_list *nlist
7613 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7614 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
7615 char *str = (char *) dmalloc (this_len + 1);
7616 strcpy (str, specd_prefix);
7617 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
7618
7619 nlist->next = NULL;
7620 nlist->fname = cstring_fromChars (str);
7621 nlist->control_macro = 0;
7622 nlist->c_system_include_path = !p->cxx_aware;
7623 nlist->got_name_map = 0;
7624
ac0860d8 7625 if (opts->first_system_include == 0)
7626 {
7627 opts->first_system_include = nlist;
7628 }
2f2892c2 7629
6fcd0b1e 7630 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7631 }
7632 }
7633 }
2f2892c2 7634
ac0860d8 7635 /* Search ordinary names for GNU include directories. */
7636
7637 for (p = include_defaults; p->fname != NULL; p++)
7638 {
7639 /* Some standard dirs are only for C++. */
7640 if (!p->cplusplus
7641 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
7642 {
7643 struct file_name_list *nlist
7644 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7645 nlist->control_macro = 0;
7646 nlist->c_system_include_path = !p->cxx_aware;
7647 nlist->fname = p->fname;
7648 nlist->got_name_map = 0;
7649 nlist->next = NULL;
7650
b73d1009 7651 /* Spurious warning reported for opts->first_system_include */
7652 /*@-usereleased@*/ if (opts->first_system_include == NULL)
ac0860d8 7653 {
2f2892c2 7654 opts->first_system_include = nlist;
ac0860d8 7655 }
b73d1009 7656 /*@=usereleased@*/
7657
6fcd0b1e 7658 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7659 }
7660 }
7661 sfree (default_prefix);
7662 }
7663
7664 /* Tack the after_include chain at the end of the include chain. */
7665 cppReader_appendIncludeChain (pfile, opts->after_include,
7666 opts->last_after_include);
7667
b73d1009 7668 /* Spurious warnings for opts->first_system_include */
7669 /*@-usereleased@*/
7670 if (opts->first_system_include == NULL)
ac0860d8 7671 {
7672 opts->first_system_include = opts->after_include;
7673 }
b73d1009 7674 /*@=usereleased@*/
7675
ac0860d8 7676 /* With -v, print the list of dirs to search. */
7677 if (opts->verbose) {
7678 struct file_name_list *p;
7679 fprintf (stderr, "#include \"...\" search starts here:\n");
7680
7681 for (p = opts->include; p != NULL; p = p->next) {
7682 if (p == opts->first_bracket_include)
7683 fprintf (stderr, "#include <...> search starts here:\n");
7684
7685 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7686 }
7687 fprintf (stderr, "End of search list.\n");
7688 }
7689}
7690
7691int cppReader_startProcess (cppReader *pfile, cstring fname)
7692{
7693 cppBuffer *fp;
7694 int f;
7695 struct cppOptions *opts = CPPOPTIONS (pfile);
7696
7697 fp = cppReader_pushBuffer (pfile, NULL, 0);
7698
7699 if (fp == NULL)
7700 {
7701 return 0;
7702 }
7703
7704 if (opts->in_fname == NULL)
7705 {
7706 opts->in_fname = cstring_makeLiteralTemp ("");
7707 }
7708
7709 fp->fname = opts->in_fname;
7710 fp->nominal_fname = fp->fname;
7711 fp->lineno = 0;
7712
7713 /* Copy the entire contents of the main input file into
7714 the stacked input buffer previously allocated for it. */
7715
7716 if (cstring_isEmpty (fname))
7717 {
7718 fname = cstring_makeLiteralTemp ("");
7719 f = 0;
7720 }
7721 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
7722 {
7723 cppReader_error (pfile,
7724 message ("Error opening %s for reading: %s",
7725 fname, lldecodeerror (errno)));
7726
7727 return 0;
7728 }
7729 else
7730 {
7731 ;
7732 }
7733
7734 if (finclude (pfile, f, fname, 0, NULL))
7735 {
7736 output_line_command (pfile, 0, same_file);
7737 }
7738
7739 return 1;
7740}
7741
7742static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7743{
7744 return pfile->buffer;
7745}
7746
7747/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7748{
7749 llassert (pfile->buffer != NULL);
7750 return pfile->buffer;
7751}
7752
7753/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7754{
7755 llassert (buf->buf != NULL);
7756 return (buf->buf + buf->line_base);
7757}
7758
3e3ec469 7759int cpplib_bufPeek (cppBuffer *buf)
ac0860d8 7760{
7761 if (buf->cur == NULL || buf->rlimit == NULL) {
7762 return EOF;
7763 }
7764
7765 if (buf->cur < buf->rlimit) {
7766 return *(buf->cur);
7767 }
7768
7769 return EOF;
7770}
7771
7772bool cppBuffer_isMacro (cppBuffer *buf)
7773{
7774 if (buf != NULL)
7775 {
7776 return (buf->cleanup == cppReader_macroCleanup);
7777 }
7778
7779 return FALSE;
7780}
7781
7782/*
7783** Returns true if the macro should be checked, false
7784** if it should be expanded normally.
7785*/
7786
7787static bool notparseable = FALSE; /* preceeded by @notparseable@ */
7788static bool notfunction = FALSE; /* preceeded by @notfunction@ */
7789static bool expectiter = FALSE; /* preceeded by @iter@ */
7790static bool expectenditer = FALSE; /* second after @iter@ */
7791static bool expectfunction = FALSE; /* preceeded by @function@ */
7792static bool expectconstant = FALSE; /* preceeded by @constant@ */
7793static bool expectmacro = FALSE; /* preceeded by notfunction or notparseable */
7794
7795static void cpp_setLocation (cppReader *pfile)
7796{
7797 fileId fid;
7798 int line;
7799
7800 if (pfile->buffer != NULL)
7801 {
abd7f895 7802 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
ac0860d8 7803 {
abd7f895 7804 cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 7805
7806 DPRINTF (("Looking up: %s", fname));
7807
7808 if (fileTable_exists (context_fileTable (), fname))
7809 {
7810 fid = fileTable_lookup (context_fileTable (), fname);
7811 }
7812 else
7813 {
7814 DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
7815
7816 fid = fileTable_lookup (context_fileTable (),
abd7f895 7817 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7818 }
7819 }
7820 else
7821 {
7822 fid = fileTable_lookup (context_fileTable (),
abd7f895 7823 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7824 }
7825
abd7f895 7826 line = cppReader_getBufferSafe (pfile)->lineno;
ac0860d8 7827 fileloc_free (g_currentloc);
7828
7829 if (fileId_isValid (fid))
7830 {
7831 g_currentloc = fileloc_create (fid, line, 1);
7832 }
7833 else
7834 {
7835 g_currentloc = fileloc_createBuiltin ();
7836 }
7837 }
7838 else
7839 {
7840 fileloc_free (g_currentloc);
7841 g_currentloc = fileloc_createBuiltin ();
7842 }
7843}
7844
2209bcb7 7845static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
ac0860d8 7846{
7847 bool checkmacro = FALSE;
7848 bool hasParams = FALSE;
7849 bool noexpand = FALSE;
7850 cstring sname;
7851 char c;
7852
7853 cpp_setLocation (pfile);
7854
7855 DPRINTF (("Should check macro? %s", p));
7856
7857 if (expectiter || expectconstant || expectenditer)
7858 {
7859 if (expectiter)
7860 {
7861 expectiter = FALSE;
7862 expectenditer = TRUE;
7863 }
7864 else
7865 {
7866 expectiter = FALSE;
7867 expectconstant = FALSE;
7868 expectenditer = FALSE;
7869 }
7870
7871 if (notfunction || notparseable)
7872 {
7873 notfunction = FALSE;
7874 notparseable = FALSE;
7875 return FALSE;
7876 }
7877 else
7878 {
7879 return TRUE;
7880 }
7881 }
7882
7883 llassert (*p == '#');
7884 p++;
7885
7886 while (*p == ' ' || *p == '\t')
7887 {
7888 p++;
7889 }
7890
7891 llassert (*p == 'd'); /* define starts */
7892
7893 p += 6;
7894
7895 while (*p == ' ' || *p == '\t')
7896 {
7897 p++;
7898 }
7899
7900 sname = cstring_fromChars (p);
7901 DPRINTF (("Check macro: %s", sname));
7902
7903 while (((c = *p) != ' ')
7904 && c != '\0' && c != '('
7905 && c != '\t' && c != '\\' && c != '\n'
7906 && !iscntrl (c))
7907 {
7908 p++;
7909 }
7910
7911 hasParams = (c == '(');
7912 *p = '\0';
7913
ac0860d8 7914 if (notparseable)
7915 {
7916 notparseable = FALSE;
7917 }
7918 else if (notfunction || fileloc_isStandardLib (g_currentloc))
7919 {
7920 DPRINTF (("Clear notfunction"));
7921 notfunction = FALSE;
7922 }
7923 else
7924 {
7925 if (noexpand)
7926 {
7927 checkmacro = TRUE;
7928
7929 if (!expectenditer)
7930 {
7931 noexpand = FALSE;
7932 }
7933 }
7934 else
7935 {
7936 if (usymtab_existsReal (sname))
7937 {
7938 uentry ue = usymtab_lookup (sname);
7939
7940 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7941
7942 if (fileloc_isPreproc (uentry_whereLast (ue)))
7943 {
7944 goto macroDne;
7945 }
7946 else
7947 {
7948 if (uentry_isSpecified (ue))
7949 {
7950 checkmacro = context_getFlag (FLG_SPECMACROS);
7951 }
7952 else
7953 {
7954 if (hasParams)
7955 {
7956 checkmacro = context_getFlag (FLG_LIBMACROS)
7957 || context_getFlag (FLG_FCNMACROS);
7958 }
7959 }
7960 }
7961 }
7962 else
7963 {
7964 macroDne:
7965 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7966
7967 if (fileloc_isSystemFile (g_currentloc)
7968 && context_getFlag (FLG_SYSTEMDIREXPAND))
7969 {
7970 ; /* don't check this macro */
7971 DPRINTF (("Don't check 1"));
7972 }
7973 else
7974 {
7975 uentry le;
7976
7977 if (hasParams)
7978 {
7979 DPRINTF (("Has params..."));
7980
7981 if (context_getFlag (FLG_FCNMACROS))
7982 {
7983 if (usymtab_exists (sname))
7984 {
7985 /*
7986 ** only get here is macro is redefined
7987 ** error reported elsewhere
7988 */
7989
7990 DPRINTF (("It exists!"));
7991 }
7992 else
7993 {
7994 /*
7995 ** We make it a forward function, since it might be declared elsewhere.
7996 ** After all headers have been processed, we should check the forward
7997 ** functions.
7998 */
7999
8000 fileloc loc = fileloc_makePreproc (g_currentloc);
8001
8002 /* the line is off-by-one, since the newline was already read */
8003 decLine ();
8004
8005 if (expectfunction)
8006 {
8007 expectfunction = FALSE;
8008 }
8009
8010 le = uentry_makeForwardFunction (sname,
8011 typeId_invalid, loc);
8012
8013 fileloc_free (loc);
8014
8015 incLine ();
8016
8017 /* Do not define here! */
8018
8019 (void) usymtab_addEntry (le);
8020 }
8021
8022 checkmacro = TRUE;
8023 DPRINTF (("Check: TRUE"));
8024 }
8025 else
8026 {
8027 DPRINTF (("Flag FCN_MACROS not set!"));
8028 }
8029 }
8030 else
8031 {
8032 DPRINTF (("No params"));
8033
8034 if (context_getFlag (FLG_CONSTMACROS))
8035 {
8036 bool nocontent = FALSE;
8037
8038 if (c == '\0')
8039 {
8040 nocontent = TRUE;
8041 }
8042 else
8043 {
8044 if (isspace (c))
8045 {
8046 char *rest = p + 1;
8047
8048 /*
8049 ** Check if there is nothing after the define.
8050 */
8051
8052 while ((*rest) != '\0' && isspace (*rest))
8053 {
8054 rest++;
8055 }
8056
8057 if (*rest == '\0')
8058 {
8059 nocontent = TRUE; /* empty macro, don't check */
8060 }
8061 }
8062 }
8063
8064 if (usymtab_exists (sname))
8065 {
8066 ;
8067 }
8068 else
8069 {
8070 fileloc loc = fileloc_makePreproc (g_currentloc);
8071 DPRINTF (("Make constant: %s", sname));
5e211f69 8072 le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
ac0860d8 8073 (void) usymtab_addEntry (le);
8074 }
8075
8076 checkmacro = !nocontent;
8077 }
8078 }
8079 }
8080
8081 if (checkmacro && usymtab_existsType (sname))
8082 {
8083 DPRINTF (("Making false..."));
8084 decLine ();
8085 ppllerror (message ("Specified type implemented as macro: %s", sname));
8086 checkmacro = FALSE;
8087 incLine ();
8088 }
8089 }
8090 }
8091 }
8092
8093 if (!checkmacro)
8094 {
8095 if (usymtab_exists (sname))
8096 {
8097 uentry ue = usymtab_lookupExpose (sname);
8098 fileloc tloc = fileloc_makePreproc (g_currentloc);
8099
8100 uentry_setDefined (ue, tloc);
8101 fileloc_free (tloc);
8102 uentry_setUsed (ue, fileloc_undefined);
8103 }
8104 else
8105 {
8106 fileloc tloc = fileloc_makePreproc (g_currentloc);
8107 uentry ue = uentry_makeExpandedMacro (sname, tloc);
8108 DPRINTF (("Make expanded macro: %s", sname));
8109 DPRINTF (("Not in symbol table: %s", sname));
8110
8111 (void) usymtab_addGlobalEntry (ue);
8112 fileloc_free (tloc);
8113 }
8114 }
8115
8116 *p = c;
8117 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
8118 return checkmacro;
8119}
8120
8121static enum cpp_token
8122cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
8123{
abd7f895 8124 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 8125 char *start;
8126 int len;
abd7f895 8127 fileloc loc;
ac0860d8 8128 bool eliminateComment = FALSE;
8129
8130 llassert (pbuf->buf != NULL);
8131
8132 start = pbuf->buf + smark->position;
8133
8134 llassert (pbuf->cur != NULL);
8135 len = pbuf->cur - start;
8136
8137 if (start[0] == '*'
8138 && start[1] == context_getCommentMarkerChar ())
8139 {
8140 int i;
8141 char c = ' ';
8142 char *scomment = start + 2;
8143 char savec = start[len];
abd7f895 8144
8145 cpp_setLocation (pfile);
8146 loc = fileloc_copy (g_currentloc);
ac0860d8 8147
8148 start[0] = BEFORE_COMMENT_MARKER[0];
8149 start[1] = BEFORE_COMMENT_MARKER[1];
8150
8151 llassert (start[len - 2] == '*');
8152 start[len - 2] = AFTER_COMMENT_MARKER[0];
8153
8154 llassert (start[len - 1] == '/');
8155 start[len - 1] = AFTER_COMMENT_MARKER[1];
8156
3e3ec469 8157 cpplib_reserve(pfile, size_fromInt (1 + len));
ac0860d8 8158 cppReader_putCharQ (pfile, c);
8159
8160 cpp_setLocation (pfile);
8161
8162 start[len] = '\0';
8163
8164 if (mstring_containsString (scomment, "/*"))
8165 {
8166 (void) cppoptgenerror
8167 (FLG_NESTCOMMENT,
8168 message ("Comment starts inside syntactic comment: %s",
8169 cstring_fromChars (scomment)),
8170 pfile);
8171 }
8172
8173 start[len] = savec;
8174
8175 if (mstring_equalPrefix (scomment, "ignore"))
8176 {
8177 if (!context_getFlag (FLG_NOCOMMENTS))
8178 {
abd7f895 8179 context_enterSuppressRegion (loc);
ac0860d8 8180 }
8181 }
8182 else if (mstring_equalPrefix (scomment, "end"))
8183 {
8184 if (!context_getFlag (FLG_NOCOMMENTS))
8185 {
abd7f895 8186 context_exitSuppressRegion (loc);
ac0860d8 8187 }
8188 }
8189 else if (mstring_equalPrefix (scomment, "notparseable"))
8190 {
8191 notparseable = TRUE;
8192 expectmacro = TRUE;
8193 eliminateComment = TRUE;
8194 }
8195 else if (mstring_equalPrefix (scomment, "notfunction"))
8196 {
8197 notfunction = TRUE;
8198 expectmacro = TRUE;
8199 eliminateComment = TRUE;
8200 }
8201 else if (mstring_equalPrefix (scomment, "iter"))
8202 {
8203 expectiter = TRUE;
8204 }
8205 else if (mstring_equalPrefix (scomment, "function"))
8206 {
8207 expectfunction = TRUE;
8208 }
8209 else if (mstring_equalPrefix (scomment, "constant"))
8210 {
8211 expectconstant = TRUE;
8212 }
8213 else
8214 {
8215 char sChar = *scomment;
8216
8217 if (sChar == '='
8218 || sChar == '-'
8219 || sChar == '+')
8220 {
8221 char *rest = scomment + 1;
8222
8223 if (mstring_equalPrefix (rest, "commentchar"))
8224 {
8225 eliminateComment = TRUE;
8226
8227 if (sChar == '=')
8228 {
8229 ppllerror (cstring_makeLiteral
8230 ("Cannot restore commentchar"));
8231 }
8232 else
8233 {
8234 char *next = scomment + 12; /* strlen commentchar = 12 */
8235
8236 if (*next != ' ' && *next != '\t' && *next != '\n')
8237 {
8238 ppllerror
8239 (message
8240 ("Syntactic commentchar comment is not followed by a "
8241 "whitespace character: %c",
8242 *next));
8243 }
8244 else
8245 {
8246 char cchar = *(next + 1);
8247
8248 if (cchar == '\0')
8249 {
8250 ppllerror
8251 (cstring_makeLiteral
8252 ("Cannot set commentchar to NUL"));
8253 }
8254 else
8255 {
8256 context_setCommentMarkerChar (cchar);
8257 /* setComment = TRUE; */
8258 }
8259 }
8260 }
8261 }
8262 else if (mstring_equalPrefix (scomment, "nestcomment"))
8263 {
8264 /* fix from Mike Miller <MikeM@xata.com> */
8265 context_fileSetFlag (FLG_NESTCOMMENT,
abd7f895 8266 ynm_fromCodeChar (sChar),
8267 loc);
ac0860d8 8268 }
8269 else if (mstring_equalPrefix (rest, "namechecks"))
8270 {
8271 context_fileSetFlag (FLG_NAMECHECKS,
abd7f895 8272 ynm_fromCodeChar (sChar),
8273 loc);
ac0860d8 8274 }
8275 else if (mstring_equalPrefix (rest, "macroredef"))
8276 {
8277 context_fileSetFlag (FLG_MACROREDEF,
abd7f895 8278 ynm_fromCodeChar (sChar),
8279 loc);
ac0860d8 8280 }
8281 else if (mstring_equalPrefix (rest, "usevarargs"))
8282 {
8283 context_fileSetFlag (FLG_USEVARARGS,
abd7f895 8284 ynm_fromCodeChar (sChar),
8285 loc);
ac0860d8 8286 }
8287 else if (mstring_equalPrefix (rest, "nextlinemacros"))
8288 {
8289 context_fileSetFlag (FLG_MACRONEXTLINE,
abd7f895 8290 ynm_fromCodeChar (sChar),
8291 loc);
ac0860d8 8292 }
8293 else if (mstring_equalPrefix (rest, "allmacros")
8294 || mstring_equalPrefix (rest, "fcnmacros")
8295 || mstring_equalPrefix (rest, "constmacros"))
8296 {
8297 flagcode fl;
8298
8299 if (mstring_equalPrefix (rest, "allmacros"))
8300 {
8301 fl = FLG_ALLMACROS;
8302 }
8303 else if (mstring_equalPrefix (rest, "fcnmacros"))
8304 {
8305 fl = FLG_FCNMACROS;
8306 }
8307 else
8308 {
8309 llassert (mstring_equalPrefix (rest, "constmacros"));
8310 fl = FLG_CONSTMACROS;
8311 }
8312
abd7f895 8313 context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
ac0860d8 8314 notfunction = FALSE;
8315 }
8316 else
8317 {
8318 ;
8319 }
8320 }
8321 else
8322 {
8323 ;
8324 }
8325 }
8326
8327 if (eliminateComment)
8328 {
8329 goto removeComment;
8330 }
8331
8332 /* Replaces comment char's in start with spaces */
8333
8334 for (i = 2; i < len - 2; i++)
8335 {
8336 if (start[i] == BEFORE_COMMENT_MARKER[0]
8337 || start[i] == BEFORE_COMMENT_MARKER[1]
8338 || start[i] == context_getCommentMarkerChar ())
8339 {
8340 start[i] = ' ';
8341 }
8342 }
8343
8344 cppReader_putStrN (pfile, start, size_fromInt (len));
8345 parseClearMark (smark);
8346 return CPP_COMMENT;
8347 }
8348 else
8349 {
8350 removeComment:
8351 {
8352 int i;
8353
8354 /*
8355 ** Output the comment as all spaces so line/column
8356 ** in output file is still correct.
8357 */
8358
8359 char c = ' ';
8360 cstring lintcomment = cstring_undefined;
8361
8362 if (context_getFlag (FLG_LINTCOMMENTS))
8363 {
8364 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
8365 {
8366 lintcomment = cstring_makeLiteralTemp ("l_notreach");
8367 }
8368 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
8369 {
8370 lintcomment = cstring_makeLiteralTemp ("l_printfli");
8371 }
8372 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
8373 {
8374 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
8375 }
8376 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
8377 {
8378 lintcomment = cstring_makeLiteralTemp ("l_argsus");
8379 }
8380 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
8381 {
8382 lintcomment = cstring_makeLiteralTemp ("l_fallth");
8383 }
8384 else
8385 {
8386 lintcomment = cstring_undefined;
8387 }
8388 }
8389 else
8390 {
8391 lintcomment = cstring_undefined;
8392 }
8393
8394 if (cstring_isDefined (lintcomment))
8395 {
8396 c = BEFORE_COMMENT_MARKER[0];
8397 start[0] = BEFORE_COMMENT_MARKER[1];
8398
abd7f895 8399 llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
ac0860d8 8400
8401 for (i = 1; i < len - 2; i++)
8402 {
abd7f895 8403 start[i] = cstring_getChar (lintcomment, size_fromInt (i));
ac0860d8 8404 }
8405
8406 start[len - 2] = AFTER_COMMENT_MARKER[0];
8407 start[len - 1] = AFTER_COMMENT_MARKER[1];
8408 }
8409 else
8410 {
8411 /* Replaces char's in start with spaces */
8412 for (i = 0; i < len; i++)
8413 {
8414 if (start[i] == '/'
8415 && i < len - 1
8416 && start[i + 1] == '*') {
abd7f895 8417 (void) cppoptgenerror
8418 (FLG_NESTCOMMENT,
8419 message ("Comment starts inside comment"),
8420 pfile);
ac0860d8 8421 }
8422
8423 if (start[i] != '\n')
8424 {
8425 start[i] = ' ';
8426 }
8427 }
8428 }
8429
3e3ec469 8430 cpplib_reserve (pfile, size_fromInt (1 + len));
ac0860d8 8431 cppReader_putCharQ (pfile, c);
8432 cppReader_putStrN (pfile, start, size_fromInt (len));
8433 parseClearMark (smark);
8434 return CPP_COMMENT;
8435 }
8436 }
8437}
8438
8439static int cpp_openIncludeFile (char *filename)
8440{
8441 int res = open (filename, O_RDONLY, 0666);
8442
8443 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
8444 if (res >= 0)
8445 {
8446 if (!fileTable_exists (context_fileTable (),
8447 cstring_fromChars (filename)))
8448 {
53a89507 8449 if (fileloc_isXHFile (g_currentloc))
8450 {
8451 /*
8452 ** Files includes by XH files are also XH files
8453 */
8454
8455 (void) fileTable_addXHFile (context_fileTable (),
ac0860d8 8456 cstring_fromChars (filename));
53a89507 8457 }
8458 else
8459 {
8460 (void) fileTable_addHeaderFile (context_fileTable (),
8461 cstring_fromChars (filename));
8462 }
ac0860d8 8463 }
8464 else
8465 {
8466 DPRINTF (("File already exists: %s", filename));
8467 }
8468 }
8469
8470 return res;
8471}
8472
8473static bool cpp_skipIncludeFile (cstring fname)
8474{
8475 if (context_isSystemDir (fname))
8476 {
8477 DPRINTF (("System dir: %s", fname));
8478
8479 if (lcllib_isSkipHeader (fname))
8480 {
8481 DPRINTF (("Skip include TRUE: %s", fname));
8482 return TRUE;
8483 }
8484
8485 if (context_getFlag (FLG_SKIPSYSHEADERS))
8486 {
d767066b 8487 /*
8488 ** 2003-04-18: Patch from Randal Parsons
8489 */
8490
8491 /*
8492 ** Don't skip include file unless the file actually exists.
8493 ** It may be in a different directory.
8494 */
8495
8496 int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666);
8497
8498 if (f >= 0)
8499 {
8500 check (close (f) == 0);
8501 DPRINTF (("Skip include TRUE: %s", fname));
8502 return TRUE;
8503 }
8504 else
8505 {
8506 /* Keep looking... */
8507 }
ac0860d8 8508 }
8509 }
8510
8511 if (context_getFlag (FLG_SINGLEINCLUDE))
8512 {
8513 fname = removePreDirs (fname);
8514
8515# if defined (WIN32) || defined (OS2)
8516 cstring_replaceAll (fname, '\\', '/');
8517# endif
8518
8519 if (fileTable_exists (context_fileTable (), fname))
8520 {
8521 DPRINTF (("Skip include TRUE: %s", fname));
8522 return TRUE;
8523 }
8524 }
8525
8526 DPRINTF (("Skip include FALSE: %s", fname));
8527 return FALSE;
8528}
8529
8530static int cpp_peekN (cppReader *pfile, int n)
8531{
abd7f895 8532 cppBuffer *buf = cppReader_getBufferSafe (pfile);
ac0860d8 8533
8534 llassert (buf->cur != NULL);
8535
8536 return (buf->rlimit - buf->cur >= (n)
8537 ? buf->cur[n]
8538 : EOF);
8539}
8540
8541cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
8542{
8543 return buf + 1;
8544}
8545
8546void cppBuffer_forward (cppBuffer *buf, int n)
8547{
8548 llassert (buf->cur != NULL);
8549 buf->cur += n;
8550}
f9264521 8551
8552/*@=bufferoverflowhigh@*/
0fe21ba7 8553/*@=bounds@*/
This page took 1.30287 seconds and 5 git commands to generate.