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