]> andersk Git - splint.git/blame - src/cpplib.c
Fixed problem with global struct assignments.
[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;
6393 op2any:
3e3ec469 6394 cpplib_reserve(pfile, 3);
ac0860d8 6395 cppReader_putCharQ (pfile, c);
6396 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6397 cppReader_nullTerminateQ (pfile);
6398 return token;
6399
6400 case 'L':
6401 NEWLINE_FIX;
6402 c2 = cppReader_peekC (pfile);
6403 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6404 {
6405 cppReader_putChar (pfile, c);
6406 c = cppReader_getC (pfile);
6407 goto string;
6408 }
6409 goto letter;
6410
6411 case '0': case '1': case '2': case '3': case '4':
6412 case '5': case '6': case '7': case '8': case '9':
6413 number:
6414 c2 = '.';
6415 for (;;)
6416 {
3e3ec469 6417 cpplib_reserve (pfile, 2);
ac0860d8 6418 cppReader_putCharQ (pfile, c);
6419 NEWLINE_FIX;
6420 c = cppReader_peekC (pfile);
6421 if (c == EOF)
6422 /*@loopbreak@*/ break;
6423 if (!is_idchar[c] && c != '.'
6424 && ((c2 != 'e' && c2 != 'E'
6425 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6426 || (c != '+' && c != '-')))
6427 /*@loopbreak@*/ break;
6428 cppReader_forward (pfile, 1);
6429 c2= c;
6430 }
6431
6432 cppReader_nullTerminateQ (pfile);
6433 pfile->only_seen_white = 0;
6434 return CPP_NUMBER;
6435
6436 case 'b': case 'c': case 'd': case 'h': case 'o':
6437 case 'B': case 'C': case 'D': case 'H': case 'O':
6438 if (opts->chill && cppReader_peekC (pfile) == '\'')
6439 {
6440 pfile->only_seen_white = 0;
3e3ec469 6441 cpplib_reserve (pfile, 2);
ac0860d8 6442 cppReader_putCharQ (pfile, c);
6443 cppReader_putCharQ (pfile, '\'');
6444 cppReader_forward (pfile, 1);
6445 for (;;)
6446 {
6447 c = cppReader_getC (pfile);
6448 if (c == EOF)
6449 goto chill_number_eof;
6450 if (!is_idchar[c])
6451 {
6452 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6453 {
6454 cppReader_forward (pfile, 2);
6455 continue;
6456 }
6457 /*@loopbreak@*/ break;
6458 }
6459 cppReader_putChar (pfile, c);
6460 }
6461 if (c == '\'')
6462 {
3e3ec469 6463 cpplib_reserve (pfile, 2);
ac0860d8 6464 cppReader_putCharQ (pfile, c);
6465 cppReader_nullTerminateQ (pfile);
6466 return CPP_STRING;
6467 }
6468 else
6469 {
6470 cppReader_forward (pfile, -1);
6471 chill_number_eof:
6472 cppReader_nullTerminate (pfile);
6473 return CPP_NUMBER;
6474 }
6475 }
6476 else
6477 goto letter;
6478 case '_':
6479 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
6480 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
6481 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
6482 case 'x': case 'y': case 'z':
6483 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
6484 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
6485 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6486 case 'Y': case 'Z':
6487 letter:
6488 {
6489 hashNode hp;
6490 char *ident;
3e3ec469 6491 size_t before_name_written = cpplib_getWritten (pfile);
abd7f895 6492 size_t ident_len;
ac0860d8 6493 parse_name (pfile, c);
6494 pfile->only_seen_white = 0;
3e3ec469 6495
ac0860d8 6496 if (pfile->no_macro_expand)
6497 {
3e3ec469 6498 DPRINTF (("Not expanding: %s", pfile->token_buffer));
ac0860d8 6499 return CPP_NAME;
6500 }
6501
6502 ident = pfile->token_buffer + before_name_written;
3e3ec469 6503 DPRINTF (("Ident: %s", ident));
6504
abd7f895 6505 ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
ac0860d8 6506
abd7f895 6507 hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand);
ac0860d8 6508
6509 if (hp == NULL)
6510 {
3e3ec469 6511 DPRINTF (("No expand: %s %d", ident, ident_len));
ac0860d8 6512 return CPP_NAME;
6513 }
6514
6515 if (hp->type == T_DISABLED)
6516 {
3e3ec469 6517 DPRINTF (("Disabled!"));
6518
ac0860d8 6519 if (pfile->output_escapes)
6520 { /* Return "@-IDENT", followed by '\0'. */
6521 int i;
3e3ec469 6522 cpplib_reserve (pfile, 3);
ac0860d8 6523 ident = pfile->token_buffer + before_name_written;
6524 cppReader_adjustWritten (pfile, 2);
6525
abd7f895 6526 for (i = size_toInt (ident_len); i >= 0; i--)
ac0860d8 6527 {
6528 ident[i+2] = ident[i];
6529 }
6530
6531 ident[0] = '@';
6532 ident[1] = '-';
6533 }
6534 return CPP_NAME;
6535 }
6536
3e3ec469 6537 /*
6538 ** If macro wants an arglist, verify that a '(' follows.
6539 ** first skip all whitespace, copying it to the output
6540 ** after the macro name. Then, if there is no '(',
6541 ** decide this is not a macro call and leave things that way.
6542 */
6543
ac0860d8 6544 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6545 {
6546 struct parse_marker macro_mark;
6547 int is_macro_call;
6548
ce7034f0 6549 DPRINTF (("Arglist macro!"));
6550
755ee3f6 6551 /*
6552 ** evans 2002-07-03: Moved this here (from below).
6553 ** This bug caused necessary whitespace to be lost
6554 ** when parsing parameterized macros without parameters.
6555 */
6556
ce7034f0 6557 parseSetMark (&macro_mark, pfile);
6558
ac0860d8 6559 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6560 {
6561 cppBuffer *next_buf;
6562 cppSkipHspace (pfile);
6563 if (cppReader_peekC (pfile) != EOF)
6564 {
ce7034f0 6565 DPRINTF (("Peeking!"));
ac0860d8 6566 /*@loopbreak@*/ break;
6567 }
6568
abd7f895 6569 next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6570 (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
ac0860d8 6571 CPPBUFFER (pfile) = next_buf;
6572 }
6573
ce7034f0 6574 /* parseSetMark (&macro_mark, pfile); */
ac0860d8 6575
6576 for (;;)
6577 {
6578 cppSkipHspace (pfile);
6579 c = cppReader_peekC (pfile);
ce7034f0 6580 DPRINTF (("c: %c", c));
ac0860d8 6581 is_macro_call = c == '(';
6582 if (c != '\n')
6583 /*@loopbreak@*/ break;
6584 cppReader_forward (pfile, 1);
6585 }
6586
6587 if (!is_macro_call)
6588 {
6589 parseGotoMark (&macro_mark, pfile);
6590 }
6591
6592 parseClearMark (&macro_mark);
6593
6594 if (!is_macro_call)
6595 {
ce7034f0 6596 DPRINTF (("not macro call!"));
ac0860d8 6597 return CPP_NAME;
6598 }
6599 }
ce7034f0 6600
ac0860d8 6601 /* This is now known to be a macro call. */
6602
6603 /* it might not actually be a macro. */
6604 if (hp->type != T_MACRO)
6605 {
6606 size_t xbuf_len;
6607 char *xbuf;
6608
6609 cppReader_setWritten (pfile, before_name_written);
6610 special_symbol (hp, pfile);
3e3ec469 6611 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
ac0860d8 6612 xbuf = (char *) dmalloc (xbuf_len + 1);
6613 cppReader_setWritten (pfile, before_name_written);
3e3ec469 6614 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
ac0860d8 6615 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6616 }
6617 else
6618 {
3e3ec469 6619 /*
6620 ** Expand the macro, reading arguments as needed,
6621 ** and push the expansion on the input stack.
6622 */
6623
6624 cpplib_macroExpand (pfile, hp);
ac0860d8 6625 cppReader_setWritten (pfile, before_name_written);
6626 }
6627
6628 /* An extra "@ " is added to the end of a macro expansion
6629 to prevent accidental token pasting. We prefer to avoid
6630 unneeded extra spaces (for the sake of cpp-using tools like
6631 imake). Here we remove the space if it is safe to do so. */
6632
6633 llassert (pfile->buffer->rlimit != NULL);
6634
6635 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6636 && pfile->buffer->rlimit[-2] == '@'
6637 && pfile->buffer->rlimit[-1] == ' ')
6638 {
6639 int c1 = pfile->buffer->rlimit[-3];
3e3ec469 6640 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
ac0860d8 6641
6642 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6643 pfile->buffer->rlimit -= 2;
6644 }
6645 }
6646 goto get_next;
6647
6648
6649 case ' ': case '\t': case '\v': case '\r':
6650 for (;;)
6651 {
6652 cppReader_putChar (pfile, c);
6653 c = cppReader_peekC (pfile);
6654 if (c == EOF || !is_hor_space[c])
6655 /*@loopbreak@*/ break;
6656 cppReader_forward (pfile, 1);
6657 }
6658 return CPP_HSPACE;
6659
6660 case '\\':
6661 c2 = cppReader_peekC (pfile);
6662 if (c2 != '\n')
6663 goto randomchar;
6664 token = CPP_HSPACE;
6665 goto op2any;
6666
6667 case '\n':
6668 cppReader_putChar (pfile, c);
6669 if (pfile->only_seen_white == 0)
6670 pfile->only_seen_white = 1;
6671 pfile->lineno++;
6672 output_line_command (pfile, 1, same_file);
6673 return CPP_VSPACE;
6674
6675 case '(': token = CPP_LPAREN; goto char1;
6676 case ')': token = CPP_RPAREN; goto char1;
6677 case '{': token = CPP_LBRACE; goto char1;
6678 case '}': token = CPP_RBRACE; goto char1;
6679 case ',': token = CPP_COMMA; goto char1;
6680 case ';': token = CPP_SEMICOLON; goto char1;
6681
6682 randomchar:
6683 default:
6684 token = CPP_OTHER;
6685 char1:
6686 pfile->only_seen_white = 0;
6687 cppReader_putChar (pfile, c);
6688 return token;
6689 }
6690 }
6691
6692 BADBRANCH;
6693 /*@notreached@*/
6694}
6695
6696/* Parse an identifier starting with C. */
6697
6698void
6699parse_name (cppReader *pfile, int c)
6700{
6701 for (;;)
6702 {
6703 if (!is_idchar[c])
6704 {
6705 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6706 {
6707 cppReader_forward (pfile, 2);
6708 continue;
6709 }
6710
6711 cppReader_forward (pfile, -1);
6712 break;
6713 }
6714
6715 if (c == '$' && cppReader_isPedantic (pfile))
6716 {
6717 cppReader_pedwarnLit (pfile,
6718 cstring_makeLiteralTemp ("`$' in identifier"));
6719 }
6720
3e3ec469 6721 cpplib_reserve(pfile, 2); /* One more for final NUL. */
ac0860d8 6722 cppReader_putCharQ (pfile, c);
6723 c = cppReader_getC (pfile);
6724
6725 if (c == EOF)
6726 break;
6727 }
6728
6729 cppReader_nullTerminateQ (pfile);
6730}
6731
6732/* The file_name_map structure holds a mapping of file names for a
6733 particular directory. This mapping is read from the file named
6734 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
6735 map filenames on a file system with severe filename restrictions,
6736 such as DOS. The format of the file name map file is just a series
6737 of lines with two tokens on each line. The first token is the name
6738 to map, and the second token is the actual name to use. */
6739
6740struct file_name_map
6741{
6742 struct file_name_map *map_next;
6743 cstring map_from;
6744 cstring map_to;
6745};
6746
6747/*@constant observer char *FILE_NAME_MAP_FILE*/
6748#define FILE_NAME_MAP_FILE "header.gcc"
6749
6750/* Read a space delimited string of unlimited length from a stdio
6751 file. */
6752
6753static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6754{
6755 char *alloc, *set;
6756 size_t len;
6757
6758 len = 20;
6759 set = alloc = dmalloc (len + 1);
6760
6761 if (!is_space[ch])
6762 {
6763 *set++ = ch;
6764 while ((ch = getc (f)) != EOF && ! is_space[ch])
6765 {
6766 if (set - alloc == size_toInt (len))
6767 {
6768 len *= 2;
6769 alloc = drealloc (alloc, len + 1);
6770 set = alloc + len / 2;
6771 /*@-branchstate@*/ }
6772
6773 *set++ = ch;
6774 } /*@=branchstate@*/
6775 }
6776 *set = '\0';
6777 check (ungetc (ch, f) != EOF);
6778
6779 return cstring_fromChars (alloc);
6780}
6781
6782/* This structure holds a linked list of file name maps, one per directory. */
6783
6784struct file_name_map_list
6785{
6fcd0b1e 6786 /*@only@*/ struct file_name_map_list *map_list_next;
6787 /*@only@*/ cstring map_list_name;
abd7f895 6788 /*@null@*/ struct file_name_map *map_list_map;
ac0860d8 6789};
6790
6791/* Read the file name map file for DIRNAME. */
6792
6793static struct file_name_map *
6794read_name_map (cppReader *pfile, cstring dirname)
6795{
6796 struct file_name_map_list *map_list_ptr;
6797 cstring name;
6798 FILE *f;
6799
6800 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6801 map_list_ptr != NULL;
6802 map_list_ptr = map_list_ptr->map_list_next)
6803 {
6804 if (cstring_equal (map_list_ptr->map_list_name, dirname))
6805 {
6806 return map_list_ptr->map_list_map;
6807 }
6808 }
6809
6810 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6811 map_list_ptr->map_list_name = cstring_copy (dirname);
6812 map_list_ptr->map_list_map = NULL;
6813
6814 name = cstring_copy (dirname);
6815
6816 if (cstring_length (dirname) > 0)
6817 {
6818 name = cstring_appendChar (name, CONNECTCHAR);
6819 }
6820
6821 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6822
d5047b91 6823 f = fileTable_openReadFile (context_fileTable (), name);
ac0860d8 6824 cstring_free (name);
6825
6826 if (f == NULL)
6827 {
6828 map_list_ptr->map_list_map = NULL;
6829 }
6830 else
6831 {
6832 int ch;
6833
6834 while ((ch = getc (f)) != EOF)
6835 {
6836 cstring from, to;
6837 struct file_name_map *ptr;
6838
6839 if (is_space[ch])
6840 {
6841 continue;
6842 }
6843
6844 from = read_filename_string (ch, f);
6845 while ((ch = getc (f)) != EOF && is_hor_space[ch])
6846 {
6847 ;
6848 }
6849
6850 to = read_filename_string (ch, f);
6851
6852 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6853 ptr->map_from = from;
6854
6855 /* Make the real filename absolute. */
6856 if (cstring_length (to) > 1
6857 && osd_isConnectChar (cstring_firstChar (to)))
6858 {
6859 ptr->map_to = to;
6860 }
6861 else
6862 {
6863 ptr->map_to = cstring_copy (dirname);
6864 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6865 ptr->map_to = cstring_concatFree (ptr->map_to, to);
6866 }
6867
6868 ptr->map_next = map_list_ptr->map_list_map;
6869 map_list_ptr->map_list_map = ptr;
6870
6871 while ((ch = getc (f)) != '\n')
6872 {
6873 if (ch == EOF)
6874 {
6875 /*@innerbreak@*/ break;
6876 }
6877 }
6878 }
6879
6880 assertSet (map_list_ptr->map_list_map);
6881 check (fileTable_closeFile (context_fileTable (),f) == 0);
6882 }
6883
6884 map_list_ptr->map_list_next = pfile->opts->map_list;
6885 pfile->opts->map_list = map_list_ptr;
6886
6887 return map_list_ptr->map_list_map;
6888}
6889
6890/* Try to open include file FILENAME. SEARCHPTR is the directory
6891 being tried from the include file search path. This function maps
6892 filenames on file systems based on information read by
6893 read_name_map. */
6894
6895static int
6896open_include_file (cppReader *pfile,
6897 cstring fname,
6898 struct file_name_list *searchptr)
6899{
6900 char *filename = cstring_toCharsSafe (fname);
6901 struct file_name_map *map;
6902 char *from;
6903 char *p, *dir;
6904
6905 cstring_markOwned (fname);
6906
6907 cpp_setLocation (pfile);
6908
6909 if (context_getFlag (FLG_NEVERINCLUDE))
6910 {
6911 if (isHeaderFile (fname))
6912 {
6913 return SKIP_INCLUDE;
6914 }
6915 }
6916
6917 if ((searchptr != NULL) && ! searchptr->got_name_map)
6918 {
6919 searchptr->name_map = read_name_map (pfile,
6920 !cstring_isEmpty (searchptr->fname)
6921 ? searchptr->fname :
6922 cstring_makeLiteralTemp ("."));
6923 searchptr->got_name_map = 1;
6924 }
6925
6926 /* First check the mapping for the directory we are using. */
6927
6928 if ((searchptr != NULL)
6929 && (searchptr->name_map != NULL))
6930 {
6931 from = filename;
6932
6933 if (!cstring_isEmpty (searchptr->fname))
6934 {
6935 from += cstring_length (searchptr->fname) + 1;
6936 }
6937
6938 for (map = searchptr->name_map;
6939 map != NULL;
6940 map = map->map_next)
6941 {
6942 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6943 {
6944 /*
6945 ** Found a match. Check if the file should be skipped
6946 */
6947
6948 if (cpp_skipIncludeFile (map->map_to))
6949 {
6950 return SKIP_INCLUDE;
6951 }
6952 else
6953 {
6954 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6955 }
6956 }
6957 }
6958 }
6959
6960 /*
6961 ** Try to find a mapping file for the particular directory we are
6962 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6963 ** in /usr/include/header.gcc and look up types.h in
6964 ** /usr/include/sys/header.gcc.
6965 */
6966
6967 p = strrchr (filename, CONNECTCHAR);
6968
6969 if (p == NULL)
6970 {
6971 p = filename;
6972 }
6973
6974 if ((searchptr != NULL)
6975 && (cstring_isDefined (searchptr->fname))
abd7f895 6976 && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
ac0860d8 6977 && !strncmp (cstring_toCharsSafe (searchptr->fname),
6978 filename,
6979 size_fromInt (p - filename)))
6980 {
6981 /* filename is in SEARCHPTR, which we've already checked. */
6982
6983 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6984 {
6985 return SKIP_INCLUDE;
6986 }
6987 else
6988 {
6989 return cpp_openIncludeFile (filename);
6990 }
6991 }
6992
6993 if (p == filename)
6994 {
6995 dir = mstring_copy (".");
6996 from = filename;
6997 }
6998 else
6999 {
7000 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
7001 memcpy (dir, filename, size_fromInt (p - filename));
7002 dir[p - filename] = '\0';
7003 from = p + 1;
7004 }
7005
7006 for (map = read_name_map (pfile, cstring_fromChars (dir));
7007 map != NULL;
7008 map = map->map_next)
7009 {
7010 if (cstring_equal (map->map_from, cstring_fromChars (from)))
7011 {
7012 sfree (dir);
7013
7014 if (cpp_skipIncludeFile (map->map_to))
7015 {
7016 return SKIP_INCLUDE;
7017 }
7018 else
7019 {
7020 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
7021 }
7022 }
7023 }
7024
7025 sfree (dir);
7026
7027 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7028 {
7029 return SKIP_INCLUDE;
7030 }
7031 else
7032 {
7033 return cpp_openIncludeFile (filename);
7034 }
7035}
7036
7037/* Process the contents of include file FNAME, already open on descriptor F,
7038 with output to OP.
7039 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
7040 "system" include directories (as decided by the `is_system_include'
7041 function above).
7042 DIRPTR is the link in the dir path through which this file was found,
7043 or 0 if the file name was absolute or via the current directory.
7044 Return 1 on success, 0 on failure.
7045
7046 The caller is responsible for the cppReader_pushBuffer. */
7047
7048static int
7049finclude (cppReader *pfile, int f,
7050 cstring fname,
7051 bool system_header_p,
7052 /*@dependent@*/ struct file_name_list *dirptr)
7053{
7054 mode_t st_mode;
7055 size_t st_size;
7056 long i;
7057 int length = 0;
7058 cppBuffer *fp; /* For input stack frame */
7059
7060 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
7061 {
7062 cppReader_perrorWithName (pfile, fname);
7063 check (close (f) == 0);
7064 (void) cppReader_popBuffer (pfile);
7065 /*@-mustfree@*/
7066 return 0;
7067 /*@=mustfree@*/
7068 }
7069
abd7f895 7070 fp = cppReader_getBufferSafe (pfile);
ac0860d8 7071
7072 /*@-temptrans@*/ /* fname shouldn't really be temp */
7073 fp->nominal_fname = fp->fname = fname;
7074 /*@=temptrans@*/
7075
7076 fp->dir = dirptr;
7077 fp->system_header_p = system_header_p;
7078 fp->lineno = 1;
7079 fp->colno = 1;
7080 fp->cleanup = cppReader_fileCleanup;
7081
7082 if (S_ISREG (st_mode))
7083 {
7084 sfree (fp->buf);
7085 fp->buf = (char *) dmalloc (st_size + 2);
7086 fp->alimit = fp->buf + st_size + 2;
7087 fp->cur = fp->buf;
7088
7089 /* Read the file contents, knowing that st_size is an upper bound
7090 on the number of bytes we can read. */
7091 length = safe_read (f, fp->buf, size_toInt (st_size));
7092 fp->rlimit = fp->buf + length;
7093 if (length < 0) goto nope;
7094 }
7095 else if (S_ISDIR (st_mode))
7096 {
7097 cppReader_error (pfile,
6fcd0b1e 7098 message ("Directory specified where file is expected: %s", fname));
ac0860d8 7099 check (close (f) == 0);
7100 return 0;
7101 }
7102 else
7103 {
7104 /*
7105 ** Cannot count its file size before reading.
7106 ** First read the entire file into heap and
7107 ** copy them into buffer on stack.
7108 */
7109
7110 size_t bsize = 2000;
7111
7112 st_size = 0;
7113
7114 sfree (fp->buf);
7115 fp->buf = (char *) dmalloc (bsize + 2);
7116
7117 for (;;) {
7118 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
7119
7120 if (i < 0)
7121 goto nope; /* error! */
7122 st_size += i;
7123
7124 if (st_size != bsize)
7125 {
7126 break; /* End of file */
7127 }
7128
7129 bsize *= 2;
7130 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
7131 }
7132
7133 fp->cur = fp->buf;
7134 length = size_toInt (st_size);
7135 }
7136
7137 if ((length > 0 && fp->buf[length - 1] != '\n')
7138 /* Backslash-newline at end is not good enough. */
7139 || (length > 1 && fp->buf[length - 2] == '\\')) {
7140 fp->buf[length++] = '\n';
7141 }
7142
7143 fp->buf[length] = '\0';
7144 fp->rlimit = fp->buf + length;
7145
7146 /* Close descriptor now, so nesting does not use lots of descriptors. */
7147 check (close (f) == 0);
7148
7149 /* Must do this before calling trigraph_pcp, so that the correct file name
7150 will be printed in warning messages. */
7151
7152 pfile->input_stack_listing_current = 0;
7153 return 1;
7154
7155 nope:
7156
7157 cppReader_perrorWithName (pfile, fname);
7158 check (close (f) == 0);
7159 sfree (fp->buf);
7160 return 1;
7161}
7162
7163void
3e3ec469 7164cpplib_init (cppReader *pfile)
ac0860d8 7165{
7166 memset ((char *) pfile, 0, sizeof (*pfile));
7167
3e3ec469 7168 pfile->get_token = cpplib_getToken;
ac0860d8 7169 pfile->token_buffer_size = 200;
7170 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
7171 pfile->all_include_files = NULL;
7172
7173 assertSet (pfile);
7174
7175 cppReader_setWritten (pfile, 0);
7176
7177 pfile->system_include_depth = 0;
7178 pfile->max_include_len = 0;
7179 pfile->timebuf = NULL;
7180 pfile->only_seen_white = 1;
7181
7182 pfile->buffer = cppReader_nullBuffer (pfile);
7183}
7184
7185void
7186cppReader_finish (/*@unused@*/ cppReader *pfile)
7187{
7188 ;
7189}
7190
7191/* Free resources used by PFILE.
7192 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
7193
7194void
6fcd0b1e 7195cppCleanup (/*@special@*/ cppReader *pfile)
7196 /*@uses pfile@*/
7197 /*@releases pfile@*/
ac0860d8 7198{
6fcd0b1e 7199 DPRINTF (("cppCleanup!"));
7200
ac0860d8 7201 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
7202 {
7203 (void) cppReader_popBuffer (pfile);
7204 }
7205
7206 if (pfile->token_buffer != NULL)
7207 {
7208 sfree (pfile->token_buffer);
7209 pfile->token_buffer = NULL;
7210 }
7211
7212 while (pfile->if_stack != NULL)
7213 {
7214 cppIfStackFrame *temp = pfile->if_stack;
7215 pfile->if_stack = temp->next;
7216 sfree (temp);
7217 }
7218
7219 while (pfile->all_include_files != NULL)
7220 {
7221 struct file_name_list *temp = pfile->all_include_files;
7222 pfile->all_include_files = temp->next;
7223 /*@-dependenttrans@*/
7224 cstring_free (temp->fname);
7225 /*@=dependenttrans@*/
7226 sfree (temp);
7227 }
7228
6fcd0b1e 7229 /* evans 2002-07-12 */
7230 while (pfile->opts->map_list != NULL)
7231 {
7232 struct file_name_map_list *temp = pfile->opts->map_list;
7233 pfile->opts->map_list = pfile->opts->map_list->map_list_next;
7234 cstring_free (temp->map_list_name);
7235 sfree (temp);
7236 }
7237
7238 while (pfile->opts->include != NULL)
7239 {
7240 struct file_name_list *temp = pfile->opts->include;
7241 pfile->opts->include = pfile->opts->include->next;
7242 /* cstring_free (temp->fname); */
7243 sfree (temp);
7244 }
7245
7246 sfree (pfile->opts);
7247 pfile->opts = NULL;
ac0860d8 7248 cppReader_hashCleanup ();
7249}
7250
7251/*
7252** Get the file-mode and data size of the file open on FD
7253** and store them in *MODE_POINTER and *SIZE_POINTER.
7254*/
7255
7256static int
7257file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
7258{
7259 struct stat sbuf;
7260
7261 if (fstat (fd, &sbuf) < 0) {
3e3ec469 7262 *mode_pointer = 0;
7263 *size_pointer = 0;
ac0860d8 7264 return (-1);
7265 }
7266
7267 if (mode_pointer != NULL)
7268 {
7269 *mode_pointer = sbuf.st_mode;
7270 }
7271
7272 if (size_pointer != NULL)
7273 {
7274 *size_pointer = (size_t) sbuf.st_size;
7275 }
7276
7277 return 0;
7278}
7279
7280/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
7281 retrying if necessary. Return a negative value if an error occurs,
7282 otherwise return the actual number of bytes read,
7283 which must be LEN unless end-of-file was reached. */
7284
7285static int safe_read (int desc, char *ptr, int len)
7286{
7287 int left = len;
7288
7289 while (left > 0)
7290 {
7291# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
7292 /*@-compdef@*/ /* ptr is an out parameter */
7293 int nchars = _read (desc, ptr, (unsigned) left);
7294 /*@=compdef@*/
7295# else
7296 ssize_t nchars = read (desc, ptr, size_fromInt (left));
7297# endif
7298
7299 if (nchars < 0)
7300 {
7301#ifdef EINTR
7302 if (errno == EINTR)
7303 continue;
7304#endif
7305 return (int) nchars;
7306 }
7307
7308 if (nchars == 0) {
7309 break;
7310 }
7311
7312 ptr += nchars;
7313 left -= nchars;
7314 }
7315
7316 return len - left;
7317}
7318
7319/* Initialize PMARK to remember the current position of PFILE. */
7320
7321void
7322parseSetMark (struct parse_marker *pmark, cppReader *pfile)
7323{
abd7f895 7324 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7325
7326 pmark->next = pbuf->marks;
7327 /*@-temptrans@*/
7328 pbuf->marks = pmark;
7329 /*@=temptrans@*/
7330
7331 pmark->buf = pbuf;
7332 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7333 DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7334}
7335
7336/* Cleanup PMARK - we no longer need it. */
7337
7338void parseClearMark (struct parse_marker *pmark)
7339{
7340 struct parse_marker **pp = &pmark->buf->marks;
7341
7342 for (; ; pp = &(*pp)->next)
7343 {
7344 llassert (*pp != NULL);
7345 if (*pp == pmark) break;
7346 }
7347
7348 *pp = pmark->next;
7349}
7350
7351/* Backup the current position of PFILE to that saved in PMARK. */
7352
7353void
7354parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
7355{
abd7f895 7356 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7357
7358 if (pbuf != pmark->buf)
7359 {
7360 cpp_setLocation (pfile);
7361 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
7362 }
7363
7364 llassert (pbuf->buf != NULL);
7365 pbuf->cur = pbuf->buf + pmark->position;
ce7034f0 7366 DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7367}
7368
7369/* Reset PMARK to point to the current position of PFILE. (Same
7370 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
7371
7372void
7373parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
7374{
abd7f895 7375 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7376
7377 if (pbuf != pmark->buf)
7378 {
7379 cpp_setLocation (pfile);
7380 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
7381 }
7382
7383 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7384 DPRINTF (("move mark: %s", pmark->position));
ac0860d8 7385}
7386
3e3ec469 7387void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
ac0860d8 7388{
7389 struct cppOptions *opts = CPPOPTIONS (pfile);
7390 cstring xp;
7391
7392 /* The code looks at the defaults through this pointer, rather than through
7393 the constant structure above. This pointer gets changed if an environment
7394 variable specifies other defaults. */
7395
7396 struct default_include *include_defaults = include_defaults_array;
7397
7398 /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */
7399 /* There seems to be confusion about what CPATH should do,
7400 so for the moment it is not documented. */
7401 /* Some people say that CPATH should replace the standard include dirs,
7402 but that seems pointless: it comes before them, so it overrides them
7403 anyway. */
7404
7405 xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
7406
7407 if (cstring_isDefined (xp) && !opts->no_standard_includes)
7408 {
7409 path_include (pfile, cstring_toCharsSafe (xp));
7410 }
7411
7412 /* Now that dollars_in_ident is known, initialize is_idchar. */
7413 initialize_char_syntax (opts);
7414
7415 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
7416 and option processing. */
7417
7418 initialize_builtins (pfile);
7419
7420 /* Do standard #defines and assertions
7421 that identify system and machine type. */
7422
7423 if (!opts->inhibit_predefs) {
7424 char *p = (char *) dmalloc (strlen (predefs) + 1);
7425 strcpy (p, predefs);
7426
7427 while (*p)
7428 {
7429 char *q;
7430
7431 while (*p == ' ' || *p == '\t')
7432 {
7433 p++;
7434 }
7435
7436 /* Handle -D options. */
7437 if (p[0] == '-' && p[1] == 'D')
7438 {
7439 q = &p[2];
7440
7441 while (*p && *p != ' ' && *p != '\t')
7442 {
7443 p++;
7444 }
7445
7446 if (*p != 0)
7447 {
7448 *p++= 0;
7449 }
7450
7451 if (opts->debug_output)
7452 {
7453 output_line_command (pfile, 0, same_file);
7454 }
7455
7456 cppReader_define (pfile, q);
7457
7458 while (*p == ' ' || *p == '\t')
7459 {
7460 p++;
7461 }
7462 }
7463 else
7464 {
7465 abort ();
7466 }
7467 }
7468
7469 sfree (p);
7470 }
7471
7472 opts->done_initializing = 1;
7473
7474 { /* Read the appropriate environment variable and if it exists
7475 replace include_defaults with the listed path. */
7476 char *epath = 0;
7477#ifdef __CYGWIN32__
7478 char *win32epath;
7479 int win32_buf_size = 0; /* memory we need to allocate */
7480#endif
7481
7482 if (opts->cplusplus)
7483 {
7484 epath = getenv ("CPLUS_INCLUDE_PATH");
7485 }
7486 else
7487 {
7488 epath = getenv ("C_INCLUDE_PATH");
7489 }
7490
7491 /*
7492 ** If the environment var for this language is set,
7493 ** add to the default list of include directories.
7494 */
7495
7496 if (epath != NULL) {
7497 char *nstore = (char *) dmalloc (strlen (epath) + 2);
7498 int num_dirs;
7499 char *startp, *endp;
7500
7501#ifdef __CYGWIN32__
7502 /* if we have a posix path list, convert to win32 path list */
7503 if (cygwin32_posix_path_list_p (epath))
7504 {
7505 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
7506 win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
7507 cygwin32_posix_to_win32_path_list (epath, win32epath);
7508 epath = win32epath;
7509 }
7510#endif
7511 for (num_dirs = 1, startp = epath; *startp; startp++)
7512 {
7513 if (*startp == PATH_SEPARATOR)
7514 num_dirs++;
7515 }
7516
7517 /*@-sizeoftype@*/
7518 include_defaults
7519 = (struct default_include *) dmalloc ((num_dirs
7520 * sizeof (struct default_include))
7521 + sizeof (include_defaults_array));
7522 /*@=sizeoftype@*/
7523
7524 startp = endp = epath;
7525 num_dirs = 0;
7526 while (1) {
7527 /* Handle cases like c:/usr/lib:d:/gcc/lib */
7528 if ((*endp == PATH_SEPARATOR) || *endp == 0)
7529 {
7530 strncpy (nstore, startp, size_fromInt (endp - startp));
7531 if (endp == startp)
7532 {
7533 strcpy (nstore, ".");
7534 }
7535 else
7536 {
7537 nstore[endp-startp] = '\0';
7538 }
7539
7540 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
7541 include_defaults[num_dirs].cplusplus = opts->cplusplus;
7542 include_defaults[num_dirs].cxx_aware = 1;
7543 num_dirs++;
7544
7545 if (*endp == '\0')
7546 {
7547 break;
7548 }
7549 endp = startp = endp + 1;
7550 }
7551 else
7552 {
7553 endp++;
7554 }
7555 }
7556 /* Put the usual defaults back in at the end. */
7557 memcpy ((char *) &include_defaults[num_dirs],
7558 (char *) include_defaults_array,
7559 sizeof (include_defaults_array));
7560
7561 sfree (nstore);
7562 /*@-branchstate@*/ } /*@=branchstate@*/
7563 }
7564
7565 cppReader_appendIncludeChain (pfile, opts->before_system,
7566 opts->last_before_system);
6fcd0b1e 7567
ac0860d8 7568 opts->first_system_include = opts->before_system;
7569
7570 /* Unless -fnostdinc,
7571 tack on the standard include file dirs to the specified list */
abd7f895 7572
ac0860d8 7573 if (!opts->no_standard_includes) {
7574 struct default_include *p = include_defaults;
7575 char *specd_prefix = opts->include_prefix;
7576 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
e5081f8c 7577 size_t default_len = 0;
abd7f895 7578
7579 /* Remove the `include' from /usr/local/lib/gcc.../include. */
7580 if (default_prefix != NULL) {
7581 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
7582 default_len = strlen (default_prefix) - 7;
7583 default_prefix[default_len] = 0;
7584 }
ac0860d8 7585 }
abd7f895 7586
ac0860d8 7587 /* Search "translated" versions of GNU directories.
7588 These have /usr/local/lib/gcc... replaced by specd_prefix. */
7589 if (specd_prefix != 0 && default_len != 0)
7590 for (p = include_defaults; p->fname != NULL; p++) {
7591 /* Some standard dirs are only for C++. */
7592 if (!p->cplusplus
7593 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
7594 /* Does this dir start with the prefix? */
abd7f895 7595 llassert (default_prefix != NULL);
7596
e5081f8c 7597 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
ac0860d8 7598 {
7599 /* Yes; change prefix and add to search list. */
7600 struct file_name_list *nlist
7601 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7602 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
7603 char *str = (char *) dmalloc (this_len + 1);
7604 strcpy (str, specd_prefix);
7605 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
7606
7607 nlist->next = NULL;
7608 nlist->fname = cstring_fromChars (str);
7609 nlist->control_macro = 0;
7610 nlist->c_system_include_path = !p->cxx_aware;
7611 nlist->got_name_map = 0;
7612
ac0860d8 7613 if (opts->first_system_include == 0)
7614 {
7615 opts->first_system_include = nlist;
7616 }
2f2892c2 7617
6fcd0b1e 7618 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7619 }
7620 }
7621 }
2f2892c2 7622
ac0860d8 7623 /* Search ordinary names for GNU include directories. */
7624
7625 for (p = include_defaults; p->fname != NULL; p++)
7626 {
7627 /* Some standard dirs are only for C++. */
7628 if (!p->cplusplus
7629 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
7630 {
7631 struct file_name_list *nlist
7632 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7633 nlist->control_macro = 0;
7634 nlist->c_system_include_path = !p->cxx_aware;
7635 nlist->fname = p->fname;
7636 nlist->got_name_map = 0;
7637 nlist->next = NULL;
7638
b73d1009 7639 /* Spurious warning reported for opts->first_system_include */
7640 /*@-usereleased@*/ if (opts->first_system_include == NULL)
ac0860d8 7641 {
2f2892c2 7642 opts->first_system_include = nlist;
ac0860d8 7643 }
b73d1009 7644 /*@=usereleased@*/
7645
6fcd0b1e 7646 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7647 }
7648 }
7649 sfree (default_prefix);
7650 }
7651
7652 /* Tack the after_include chain at the end of the include chain. */
7653 cppReader_appendIncludeChain (pfile, opts->after_include,
7654 opts->last_after_include);
7655
b73d1009 7656 /* Spurious warnings for opts->first_system_include */
7657 /*@-usereleased@*/
7658 if (opts->first_system_include == NULL)
ac0860d8 7659 {
7660 opts->first_system_include = opts->after_include;
7661 }
b73d1009 7662 /*@=usereleased@*/
7663
ac0860d8 7664 /* With -v, print the list of dirs to search. */
7665 if (opts->verbose) {
7666 struct file_name_list *p;
7667 fprintf (stderr, "#include \"...\" search starts here:\n");
7668
7669 for (p = opts->include; p != NULL; p = p->next) {
7670 if (p == opts->first_bracket_include)
7671 fprintf (stderr, "#include <...> search starts here:\n");
7672
7673 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7674 }
7675 fprintf (stderr, "End of search list.\n");
7676 }
7677}
7678
7679int cppReader_startProcess (cppReader *pfile, cstring fname)
7680{
7681 cppBuffer *fp;
7682 int f;
7683 struct cppOptions *opts = CPPOPTIONS (pfile);
7684
7685 fp = cppReader_pushBuffer (pfile, NULL, 0);
7686
7687 if (fp == NULL)
7688 {
7689 return 0;
7690 }
7691
7692 if (opts->in_fname == NULL)
7693 {
7694 opts->in_fname = cstring_makeLiteralTemp ("");
7695 }
7696
7697 fp->fname = opts->in_fname;
7698 fp->nominal_fname = fp->fname;
7699 fp->lineno = 0;
7700
7701 /* Copy the entire contents of the main input file into
7702 the stacked input buffer previously allocated for it. */
7703
7704 if (cstring_isEmpty (fname))
7705 {
7706 fname = cstring_makeLiteralTemp ("");
7707 f = 0;
7708 }
7709 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
7710 {
7711 cppReader_error (pfile,
7712 message ("Error opening %s for reading: %s",
7713 fname, lldecodeerror (errno)));
7714
7715 return 0;
7716 }
7717 else
7718 {
7719 ;
7720 }
7721
7722 if (finclude (pfile, f, fname, 0, NULL))
7723 {
7724 output_line_command (pfile, 0, same_file);
7725 }
7726
7727 return 1;
7728}
7729
7730static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7731{
7732 return pfile->buffer;
7733}
7734
7735/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7736{
7737 llassert (pfile->buffer != NULL);
7738 return pfile->buffer;
7739}
7740
7741/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7742{
7743 llassert (buf->buf != NULL);
7744 return (buf->buf + buf->line_base);
7745}
7746
3e3ec469 7747int cpplib_bufPeek (cppBuffer *buf)
ac0860d8 7748{
7749 if (buf->cur == NULL || buf->rlimit == NULL) {
7750 return EOF;
7751 }
7752
7753 if (buf->cur < buf->rlimit) {
7754 return *(buf->cur);
7755 }
7756
7757 return EOF;
7758}
7759
7760bool cppBuffer_isMacro (cppBuffer *buf)
7761{
7762 if (buf != NULL)
7763 {
7764 return (buf->cleanup == cppReader_macroCleanup);
7765 }
7766
7767 return FALSE;
7768}
7769
7770/*
7771** Returns true if the macro should be checked, false
7772** if it should be expanded normally.
7773*/
7774
7775static bool notparseable = FALSE; /* preceeded by @notparseable@ */
7776static bool notfunction = FALSE; /* preceeded by @notfunction@ */
7777static bool expectiter = FALSE; /* preceeded by @iter@ */
7778static bool expectenditer = FALSE; /* second after @iter@ */
7779static bool expectfunction = FALSE; /* preceeded by @function@ */
7780static bool expectconstant = FALSE; /* preceeded by @constant@ */
7781static bool expectmacro = FALSE; /* preceeded by notfunction or notparseable */
7782
7783static void cpp_setLocation (cppReader *pfile)
7784{
7785 fileId fid;
7786 int line;
7787
7788 if (pfile->buffer != NULL)
7789 {
abd7f895 7790 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
ac0860d8 7791 {
abd7f895 7792 cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 7793
7794 DPRINTF (("Looking up: %s", fname));
7795
7796 if (fileTable_exists (context_fileTable (), fname))
7797 {
7798 fid = fileTable_lookup (context_fileTable (), fname);
7799 }
7800 else
7801 {
7802 DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
7803
7804 fid = fileTable_lookup (context_fileTable (),
abd7f895 7805 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7806 }
7807 }
7808 else
7809 {
7810 fid = fileTable_lookup (context_fileTable (),
abd7f895 7811 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7812 }
7813
abd7f895 7814 line = cppReader_getBufferSafe (pfile)->lineno;
ac0860d8 7815 fileloc_free (g_currentloc);
7816
7817 if (fileId_isValid (fid))
7818 {
7819 g_currentloc = fileloc_create (fid, line, 1);
7820 }
7821 else
7822 {
7823 g_currentloc = fileloc_createBuiltin ();
7824 }
7825 }
7826 else
7827 {
7828 fileloc_free (g_currentloc);
7829 g_currentloc = fileloc_createBuiltin ();
7830 }
7831}
7832
2209bcb7 7833static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
ac0860d8 7834{
7835 bool checkmacro = FALSE;
7836 bool hasParams = FALSE;
7837 bool noexpand = FALSE;
7838 cstring sname;
7839 char c;
7840
7841 cpp_setLocation (pfile);
7842
7843 DPRINTF (("Should check macro? %s", p));
7844
7845 if (expectiter || expectconstant || expectenditer)
7846 {
7847 if (expectiter)
7848 {
7849 expectiter = FALSE;
7850 expectenditer = TRUE;
7851 }
7852 else
7853 {
7854 expectiter = FALSE;
7855 expectconstant = FALSE;
7856 expectenditer = FALSE;
7857 }
7858
7859 if (notfunction || notparseable)
7860 {
7861 notfunction = FALSE;
7862 notparseable = FALSE;
7863 return FALSE;
7864 }
7865 else
7866 {
7867 return TRUE;
7868 }
7869 }
7870
7871 llassert (*p == '#');
7872 p++;
7873
7874 while (*p == ' ' || *p == '\t')
7875 {
7876 p++;
7877 }
7878
7879 llassert (*p == 'd'); /* define starts */
7880
7881 p += 6;
7882
7883 while (*p == ' ' || *p == '\t')
7884 {
7885 p++;
7886 }
7887
7888 sname = cstring_fromChars (p);
7889 DPRINTF (("Check macro: %s", sname));
7890
7891 while (((c = *p) != ' ')
7892 && c != '\0' && c != '('
7893 && c != '\t' && c != '\\' && c != '\n'
7894 && !iscntrl (c))
7895 {
7896 p++;
7897 }
7898
7899 hasParams = (c == '(');
7900 *p = '\0';
7901
ac0860d8 7902 if (notparseable)
7903 {
7904 notparseable = FALSE;
7905 }
7906 else if (notfunction || fileloc_isStandardLib (g_currentloc))
7907 {
7908 DPRINTF (("Clear notfunction"));
7909 notfunction = FALSE;
7910 }
7911 else
7912 {
7913 if (noexpand)
7914 {
7915 checkmacro = TRUE;
7916
7917 if (!expectenditer)
7918 {
7919 noexpand = FALSE;
7920 }
7921 }
7922 else
7923 {
7924 if (usymtab_existsReal (sname))
7925 {
7926 uentry ue = usymtab_lookup (sname);
7927
7928 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7929
7930 if (fileloc_isPreproc (uentry_whereLast (ue)))
7931 {
7932 goto macroDne;
7933 }
7934 else
7935 {
7936 if (uentry_isSpecified (ue))
7937 {
7938 checkmacro = context_getFlag (FLG_SPECMACROS);
7939 }
7940 else
7941 {
7942 if (hasParams)
7943 {
7944 checkmacro = context_getFlag (FLG_LIBMACROS)
7945 || context_getFlag (FLG_FCNMACROS);
7946 }
7947 }
7948 }
7949 }
7950 else
7951 {
7952 macroDne:
7953 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7954
7955 if (fileloc_isSystemFile (g_currentloc)
7956 && context_getFlag (FLG_SYSTEMDIREXPAND))
7957 {
7958 ; /* don't check this macro */
7959 DPRINTF (("Don't check 1"));
7960 }
7961 else
7962 {
7963 uentry le;
7964
7965 if (hasParams)
7966 {
7967 DPRINTF (("Has params..."));
7968
7969 if (context_getFlag (FLG_FCNMACROS))
7970 {
7971 if (usymtab_exists (sname))
7972 {
7973 /*
7974 ** only get here is macro is redefined
7975 ** error reported elsewhere
7976 */
7977
7978 DPRINTF (("It exists!"));
7979 }
7980 else
7981 {
7982 /*
7983 ** We make it a forward function, since it might be declared elsewhere.
7984 ** After all headers have been processed, we should check the forward
7985 ** functions.
7986 */
7987
7988 fileloc loc = fileloc_makePreproc (g_currentloc);
7989
7990 /* the line is off-by-one, since the newline was already read */
7991 decLine ();
7992
7993 if (expectfunction)
7994 {
7995 expectfunction = FALSE;
7996 }
7997
7998 le = uentry_makeForwardFunction (sname,
7999 typeId_invalid, loc);
8000
8001 fileloc_free (loc);
8002
8003 incLine ();
8004
8005 /* Do not define here! */
8006
8007 (void) usymtab_addEntry (le);
8008 }
8009
8010 checkmacro = TRUE;
8011 DPRINTF (("Check: TRUE"));
8012 }
8013 else
8014 {
8015 DPRINTF (("Flag FCN_MACROS not set!"));
8016 }
8017 }
8018 else
8019 {
8020 DPRINTF (("No params"));
8021
8022 if (context_getFlag (FLG_CONSTMACROS))
8023 {
8024 bool nocontent = FALSE;
8025
8026 if (c == '\0')
8027 {
8028 nocontent = TRUE;
8029 }
8030 else
8031 {
8032 if (isspace (c))
8033 {
8034 char *rest = p + 1;
8035
8036 /*
8037 ** Check if there is nothing after the define.
8038 */
8039
8040 while ((*rest) != '\0' && isspace (*rest))
8041 {
8042 rest++;
8043 }
8044
8045 if (*rest == '\0')
8046 {
8047 nocontent = TRUE; /* empty macro, don't check */
8048 }
8049 }
8050 }
8051
8052 if (usymtab_exists (sname))
8053 {
8054 ;
8055 }
8056 else
8057 {
8058 fileloc loc = fileloc_makePreproc (g_currentloc);
8059 DPRINTF (("Make constant: %s", sname));
5e211f69 8060 le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
ac0860d8 8061 (void) usymtab_addEntry (le);
8062 }
8063
8064 checkmacro = !nocontent;
8065 }
8066 }
8067 }
8068
8069 if (checkmacro && usymtab_existsType (sname))
8070 {
8071 DPRINTF (("Making false..."));
8072 decLine ();
8073 ppllerror (message ("Specified type implemented as macro: %s", sname));
8074 checkmacro = FALSE;
8075 incLine ();
8076 }
8077 }
8078 }
8079 }
8080
8081 if (!checkmacro)
8082 {
8083 if (usymtab_exists (sname))
8084 {
8085 uentry ue = usymtab_lookupExpose (sname);
8086 fileloc tloc = fileloc_makePreproc (g_currentloc);
8087
8088 uentry_setDefined (ue, tloc);
8089 fileloc_free (tloc);
8090 uentry_setUsed (ue, fileloc_undefined);
8091 }
8092 else
8093 {
8094 fileloc tloc = fileloc_makePreproc (g_currentloc);
8095 uentry ue = uentry_makeExpandedMacro (sname, tloc);
8096 DPRINTF (("Make expanded macro: %s", sname));
8097 DPRINTF (("Not in symbol table: %s", sname));
8098
8099 (void) usymtab_addGlobalEntry (ue);
8100 fileloc_free (tloc);
8101 }
8102 }
8103
8104 *p = c;
8105 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
8106 return checkmacro;
8107}
8108
8109static enum cpp_token
8110cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
8111{
abd7f895 8112 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 8113 char *start;
8114 int len;
abd7f895 8115 fileloc loc;
ac0860d8 8116 bool eliminateComment = FALSE;
8117
8118 llassert (pbuf->buf != NULL);
8119
8120 start = pbuf->buf + smark->position;
8121
8122 llassert (pbuf->cur != NULL);
8123 len = pbuf->cur - start;
8124
8125 if (start[0] == '*'
8126 && start[1] == context_getCommentMarkerChar ())
8127 {
8128 int i;
8129 char c = ' ';
8130 char *scomment = start + 2;
8131 char savec = start[len];
abd7f895 8132
8133 cpp_setLocation (pfile);
8134 loc = fileloc_copy (g_currentloc);
ac0860d8 8135
8136 start[0] = BEFORE_COMMENT_MARKER[0];
8137 start[1] = BEFORE_COMMENT_MARKER[1];
8138
8139 llassert (start[len - 2] == '*');
8140 start[len - 2] = AFTER_COMMENT_MARKER[0];
8141
8142 llassert (start[len - 1] == '/');
8143 start[len - 1] = AFTER_COMMENT_MARKER[1];
8144
3e3ec469 8145 cpplib_reserve(pfile, size_fromInt (1 + len));
ac0860d8 8146 cppReader_putCharQ (pfile, c);
8147
8148 cpp_setLocation (pfile);
8149
8150 start[len] = '\0';
8151
8152 if (mstring_containsString (scomment, "/*"))
8153 {
8154 (void) cppoptgenerror
8155 (FLG_NESTCOMMENT,
8156 message ("Comment starts inside syntactic comment: %s",
8157 cstring_fromChars (scomment)),
8158 pfile);
8159 }
8160
8161 start[len] = savec;
8162
8163 if (mstring_equalPrefix (scomment, "ignore"))
8164 {
8165 if (!context_getFlag (FLG_NOCOMMENTS))
8166 {
abd7f895 8167 context_enterSuppressRegion (loc);
ac0860d8 8168 }
8169 }
8170 else if (mstring_equalPrefix (scomment, "end"))
8171 {
8172 if (!context_getFlag (FLG_NOCOMMENTS))
8173 {
abd7f895 8174 context_exitSuppressRegion (loc);
ac0860d8 8175 }
8176 }
8177 else if (mstring_equalPrefix (scomment, "notparseable"))
8178 {
8179 notparseable = TRUE;
8180 expectmacro = TRUE;
8181 eliminateComment = TRUE;
8182 }
8183 else if (mstring_equalPrefix (scomment, "notfunction"))
8184 {
8185 notfunction = TRUE;
8186 expectmacro = TRUE;
8187 eliminateComment = TRUE;
8188 }
8189 else if (mstring_equalPrefix (scomment, "iter"))
8190 {
8191 expectiter = TRUE;
8192 }
8193 else if (mstring_equalPrefix (scomment, "function"))
8194 {
8195 expectfunction = TRUE;
8196 }
8197 else if (mstring_equalPrefix (scomment, "constant"))
8198 {
8199 expectconstant = TRUE;
8200 }
8201 else
8202 {
8203 char sChar = *scomment;
8204
8205 if (sChar == '='
8206 || sChar == '-'
8207 || sChar == '+')
8208 {
8209 char *rest = scomment + 1;
8210
8211 if (mstring_equalPrefix (rest, "commentchar"))
8212 {
8213 eliminateComment = TRUE;
8214
8215 if (sChar == '=')
8216 {
8217 ppllerror (cstring_makeLiteral
8218 ("Cannot restore commentchar"));
8219 }
8220 else
8221 {
8222 char *next = scomment + 12; /* strlen commentchar = 12 */
8223
8224 if (*next != ' ' && *next != '\t' && *next != '\n')
8225 {
8226 ppllerror
8227 (message
8228 ("Syntactic commentchar comment is not followed by a "
8229 "whitespace character: %c",
8230 *next));
8231 }
8232 else
8233 {
8234 char cchar = *(next + 1);
8235
8236 if (cchar == '\0')
8237 {
8238 ppllerror
8239 (cstring_makeLiteral
8240 ("Cannot set commentchar to NUL"));
8241 }
8242 else
8243 {
8244 context_setCommentMarkerChar (cchar);
8245 /* setComment = TRUE; */
8246 }
8247 }
8248 }
8249 }
8250 else if (mstring_equalPrefix (scomment, "nestcomment"))
8251 {
8252 /* fix from Mike Miller <MikeM@xata.com> */
8253 context_fileSetFlag (FLG_NESTCOMMENT,
abd7f895 8254 ynm_fromCodeChar (sChar),
8255 loc);
ac0860d8 8256 }
8257 else if (mstring_equalPrefix (rest, "namechecks"))
8258 {
8259 context_fileSetFlag (FLG_NAMECHECKS,
abd7f895 8260 ynm_fromCodeChar (sChar),
8261 loc);
ac0860d8 8262 }
8263 else if (mstring_equalPrefix (rest, "macroredef"))
8264 {
8265 context_fileSetFlag (FLG_MACROREDEF,
abd7f895 8266 ynm_fromCodeChar (sChar),
8267 loc);
ac0860d8 8268 }
8269 else if (mstring_equalPrefix (rest, "usevarargs"))
8270 {
8271 context_fileSetFlag (FLG_USEVARARGS,
abd7f895 8272 ynm_fromCodeChar (sChar),
8273 loc);
ac0860d8 8274 }
8275 else if (mstring_equalPrefix (rest, "nextlinemacros"))
8276 {
8277 context_fileSetFlag (FLG_MACRONEXTLINE,
abd7f895 8278 ynm_fromCodeChar (sChar),
8279 loc);
ac0860d8 8280 }
8281 else if (mstring_equalPrefix (rest, "allmacros")
8282 || mstring_equalPrefix (rest, "fcnmacros")
8283 || mstring_equalPrefix (rest, "constmacros"))
8284 {
8285 flagcode fl;
8286
8287 if (mstring_equalPrefix (rest, "allmacros"))
8288 {
8289 fl = FLG_ALLMACROS;
8290 }
8291 else if (mstring_equalPrefix (rest, "fcnmacros"))
8292 {
8293 fl = FLG_FCNMACROS;
8294 }
8295 else
8296 {
8297 llassert (mstring_equalPrefix (rest, "constmacros"));
8298 fl = FLG_CONSTMACROS;
8299 }
8300
abd7f895 8301 context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
ac0860d8 8302 notfunction = FALSE;
8303 }
8304 else
8305 {
8306 ;
8307 }
8308 }
8309 else
8310 {
8311 ;
8312 }
8313 }
8314
8315 if (eliminateComment)
8316 {
8317 goto removeComment;
8318 }
8319
8320 /* Replaces comment char's in start with spaces */
8321
8322 for (i = 2; i < len - 2; i++)
8323 {
8324 if (start[i] == BEFORE_COMMENT_MARKER[0]
8325 || start[i] == BEFORE_COMMENT_MARKER[1]
8326 || start[i] == context_getCommentMarkerChar ())
8327 {
8328 start[i] = ' ';
8329 }
8330 }
8331
8332 cppReader_putStrN (pfile, start, size_fromInt (len));
8333 parseClearMark (smark);
8334 return CPP_COMMENT;
8335 }
8336 else
8337 {
8338 removeComment:
8339 {
8340 int i;
8341
8342 /*
8343 ** Output the comment as all spaces so line/column
8344 ** in output file is still correct.
8345 */
8346
8347 char c = ' ';
8348 cstring lintcomment = cstring_undefined;
8349
8350 if (context_getFlag (FLG_LINTCOMMENTS))
8351 {
8352 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
8353 {
8354 lintcomment = cstring_makeLiteralTemp ("l_notreach");
8355 }
8356 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
8357 {
8358 lintcomment = cstring_makeLiteralTemp ("l_printfli");
8359 }
8360 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
8361 {
8362 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
8363 }
8364 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
8365 {
8366 lintcomment = cstring_makeLiteralTemp ("l_argsus");
8367 }
8368 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
8369 {
8370 lintcomment = cstring_makeLiteralTemp ("l_fallth");
8371 }
8372 else
8373 {
8374 lintcomment = cstring_undefined;
8375 }
8376 }
8377 else
8378 {
8379 lintcomment = cstring_undefined;
8380 }
8381
8382 if (cstring_isDefined (lintcomment))
8383 {
8384 c = BEFORE_COMMENT_MARKER[0];
8385 start[0] = BEFORE_COMMENT_MARKER[1];
8386
abd7f895 8387 llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
ac0860d8 8388
8389 for (i = 1; i < len - 2; i++)
8390 {
abd7f895 8391 start[i] = cstring_getChar (lintcomment, size_fromInt (i));
ac0860d8 8392 }
8393
8394 start[len - 2] = AFTER_COMMENT_MARKER[0];
8395 start[len - 1] = AFTER_COMMENT_MARKER[1];
8396 }
8397 else
8398 {
8399 /* Replaces char's in start with spaces */
8400 for (i = 0; i < len; i++)
8401 {
8402 if (start[i] == '/'
8403 && i < len - 1
8404 && start[i + 1] == '*') {
abd7f895 8405 (void) cppoptgenerror
8406 (FLG_NESTCOMMENT,
8407 message ("Comment starts inside comment"),
8408 pfile);
ac0860d8 8409 }
8410
8411 if (start[i] != '\n')
8412 {
8413 start[i] = ' ';
8414 }
8415 }
8416 }
8417
3e3ec469 8418 cpplib_reserve (pfile, size_fromInt (1 + len));
ac0860d8 8419 cppReader_putCharQ (pfile, c);
8420 cppReader_putStrN (pfile, start, size_fromInt (len));
8421 parseClearMark (smark);
8422 return CPP_COMMENT;
8423 }
8424 }
8425}
8426
8427static int cpp_openIncludeFile (char *filename)
8428{
8429 int res = open (filename, O_RDONLY, 0666);
8430
8431 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
8432 if (res >= 0)
8433 {
8434 if (!fileTable_exists (context_fileTable (),
8435 cstring_fromChars (filename)))
8436 {
53a89507 8437 if (fileloc_isXHFile (g_currentloc))
8438 {
8439 /*
8440 ** Files includes by XH files are also XH files
8441 */
8442
8443 (void) fileTable_addXHFile (context_fileTable (),
ac0860d8 8444 cstring_fromChars (filename));
53a89507 8445 }
8446 else
8447 {
8448 (void) fileTable_addHeaderFile (context_fileTable (),
8449 cstring_fromChars (filename));
8450 }
ac0860d8 8451 }
8452 else
8453 {
8454 DPRINTF (("File already exists: %s", filename));
8455 }
8456 }
8457
8458 return res;
8459}
8460
8461static bool cpp_skipIncludeFile (cstring fname)
8462{
8463 if (context_isSystemDir (fname))
8464 {
8465 DPRINTF (("System dir: %s", fname));
8466
8467 if (lcllib_isSkipHeader (fname))
8468 {
8469 DPRINTF (("Skip include TRUE: %s", fname));
8470 return TRUE;
8471 }
8472
8473 if (context_getFlag (FLG_SKIPSYSHEADERS))
8474 {
d767066b 8475 /*
8476 ** 2003-04-18: Patch from Randal Parsons
8477 */
8478
8479 /*
8480 ** Don't skip include file unless the file actually exists.
8481 ** It may be in a different directory.
8482 */
8483
8484 int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666);
8485
8486 if (f >= 0)
8487 {
8488 check (close (f) == 0);
8489 DPRINTF (("Skip include TRUE: %s", fname));
8490 return TRUE;
8491 }
8492 else
8493 {
8494 /* Keep looking... */
8495 }
ac0860d8 8496 }
8497 }
8498
8499 if (context_getFlag (FLG_SINGLEINCLUDE))
8500 {
8501 fname = removePreDirs (fname);
8502
8503# if defined (WIN32) || defined (OS2)
8504 cstring_replaceAll (fname, '\\', '/');
8505# endif
8506
8507 if (fileTable_exists (context_fileTable (), fname))
8508 {
8509 DPRINTF (("Skip include TRUE: %s", fname));
8510 return TRUE;
8511 }
8512 }
8513
8514 DPRINTF (("Skip include FALSE: %s", fname));
8515 return FALSE;
8516}
8517
8518static int cpp_peekN (cppReader *pfile, int n)
8519{
abd7f895 8520 cppBuffer *buf = cppReader_getBufferSafe (pfile);
ac0860d8 8521
8522 llassert (buf->cur != NULL);
8523
8524 return (buf->rlimit - buf->cur >= (n)
8525 ? buf->cur[n]
8526 : EOF);
8527}
8528
8529cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
8530{
8531 return buf + 1;
8532}
8533
8534void cppBuffer_forward (cppBuffer *buf, int n)
8535{
8536 llassert (buf->cur != NULL);
8537 buf->cur += n;
8538}
f9264521 8539
8540/*@=bufferoverflowhigh@*/
0fe21ba7 8541/*@=bounds@*/
This page took 1.338251 seconds and 5 git commands to generate.