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