]> andersk Git - splint.git/blame - src/cpplib.c
Fixed problem with NULL being changed.
[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
210066f9 376static int file_size_and_mode (int p_fd, /*@out@*/ __mode_t *p_mode_pointer,
ac0860d8 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 */
b8dce3c7 3760# ifndef S_SPLINT_S
f7bbce9e 3761 cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
b8dce3c7 3762# endif
f7bbce9e 3763
9882c722 3764 /*drl 1/2/2002 set some flags based on uname
3765 I'd like to be able to do this with autoconf macro instead...
3766 */
3767
3768 /*Thanks to Nelson Beebe for suggesting possible values for these */
3769
3770 if (! strcmp (UNAME, "Linux"))
3771 {
3772#ifdef __ppc
3773 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3774#endif
3775 }
3776
3777 else if(! strcmp (UNAME, "Darwin"))
3778 {
3779 cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3780 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3781 }
3782 else if(! strcmp (UNAME, "HP-UX"))
3783 {
3784 cpplib_installBuiltin ("PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3785 cpplib_installBuiltin ("_HIUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3786 cpplib_installBuiltin ("_HPUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3787 cpplib_installBuiltin ("_PA_RISC1_1", ctype_int, -1, T_CONST, 2, NULL, -1);
3788 cpplib_installBuiltin ("__PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3789 cpplib_installBuiltin ("__PWB__", ctype_int, -1, T_CONST, 2, NULL, -1);
3790 cpplib_installBuiltin ("__STDC_EXT__", ctype_int, -1, T_CONST, 2, NULL, -1);
3791 cpplib_installBuiltin ("__hp9000s700", ctype_int, -1, T_CONST, 2, NULL, -1);
3792 cpplib_installBuiltin ("__hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3793 cpplib_installBuiltin ("__hp9000s800__", ctype_int, -1, T_CONST, 2, NULL, -1);
3794 cpplib_installBuiltin ("__hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3795 cpplib_installBuiltin ("__hp9k8__", ctype_int, -1, T_CONST, 2, NULL, -1);
3796 cpplib_installBuiltin ("__hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3797 cpplib_installBuiltin ("__hppa__", ctype_int, -1, T_CONST, 2, NULL, -1);
3798 cpplib_installBuiltin ("__hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3799 cpplib_installBuiltin ("__hpux__", ctype_int, -1, T_CONST, 2, NULL, -1);
3800 cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3801 cpplib_installBuiltin ("__unix__", ctype_int, -1, T_CONST, 2, NULL, -1);
3802 cpplib_installBuiltin ("hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3803 cpplib_installBuiltin ("hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3804 cpplib_installBuiltin ("hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3805 cpplib_installBuiltin ("hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3806 cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3807 }
3808 else if(! strcmp (UNAME, "IRIX64"))
3809 {
3810 cpplib_installBuiltin ("LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3811 cpplib_installBuiltin ("MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3812 cpplib_installBuiltin ("_ABIN32", ctype_int, -1, T_CONST, 2, NULL, -1);
3813 cpplib_installBuiltin ("_COMPILER_VERSION", ctype_int, -1, T_CONST, 730, NULL, -1);
3814 cpplib_installBuiltin ("_LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3815 cpplib_installBuiltin ("_LONGLONG", ctype_int, -1, T_CONST, 2, NULL, -1);
3816 cpplib_installBuiltin ("_MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3817 cpplib_installBuiltin ("_MIPS_FPSET", ctype_int, -1, T_CONST, 32, NULL, -1);
3818 cpplib_installBuiltin ("_MIPS_ISA", ctype_int, -1, T_CONST, 3, NULL, -1);
3819 /*_MIPS_SIM=_ABIN32*/
3820 cpplib_installBuiltin ("_MIPS_SIM", ctype_int, -1, T_CONST, 2, NULL , -1);
3821 cpplib_installBuiltin ("_MIPS_SZINT", ctype_int, -1, T_CONST, 32, NULL, -1);
3822 cpplib_installBuiltin ("_MIPS_SZLONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3823 cpplib_installBuiltin ("_MIPS_SZPTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3824 cpplib_installBuiltin ("_MODERN_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3825 cpplib_installBuiltin ("_PIC", ctype_int, -1, T_CONST, 2, NULL, -1);
3826 cpplib_installBuiltin ("_SGI_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3827 cpplib_installBuiltin ("_SIZE_INT", ctype_int, -1, T_CONST, 32, NULL, -1);
3828 cpplib_installBuiltin ("_SIZE_LONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3829 cpplib_installBuiltin ("_SIZE_PTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3830 cpplib_installBuiltin ("_SVR4_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3831 cpplib_installBuiltin ("_SYSTYPE_SVR4", ctype_int, -1, T_CONST, 2, NULL, -1);
3832 cpplib_installBuiltin ("__DSO__", ctype_int, -1, T_CONST, 2, NULL, -1);
3833 cpplib_installBuiltin ("__EXTENSIONS__", ctype_int, -1, T_CONST, 2, NULL, -1);
3834 cpplib_installBuiltin ("__INLINE_INTRINSICS", ctype_int, -1, T_CONST, 2, NULL, -1);
3835 cpplib_installBuiltin ("__MATH_HAS_NO_SIDE_EFFECTS", ctype_int, -1, T_CONST, 2, NULL, -1);
3836 cpplib_installBuiltin ("__host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3837 cpplib_installBuiltin ("__mips", ctype_int, -1, T_CONST, 3, NULL, -1);
3838 cpplib_installBuiltin ("__sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3839 cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3840 cpplib_installBuiltin ("host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3841 cpplib_installBuiltin ("mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3842 cpplib_installBuiltin ("sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3843 cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3844 }
3845 else if(! strcmp (UNAME, "OSF1"))
3846 {
3847 cpplib_installBuiltin ("__alpha", ctype_int, -1, T_CONST, 2, NULL, -1);
3848 }
3849 else if (!strcmp (UNAME, "Rhapsody"))
3850 {
3851 cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3852 cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3853 }
3854
3855 else if (!strcmp (UNAME, "SunOS"))
3856 {
3857 cpplib_installBuiltin ("__OPEN_MAX", ctype_int, -1, T_CONST, 20, NULL, -1);
3858 cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, 2, NULL, -1);
3859 cpplib_installBuiltin ("__sparc", ctype_int, -1, T_CONST, 2, NULL, -1);
3860 /* This define "-Dfileno(f)=0" should be inserted but we're going to stick to deinfe constants for now...*/
3861 }
3862 else
3863 {
3864 /*
3865 types which we have not explictedly handled.
3866 AIX, FreeBSD, IRIX, Mach
3867 */
3868
3869 }
f7bbce9e 3870
ac0860d8 3871 if (CPPOPTIONS (pfile)->debug_output)
3872 {
3873 dump_special_to_buffer (pfile, "__BASE_FILE__");
3874 dump_special_to_buffer (pfile, "__VERSION__");
3875#ifndef NO_BUILTIN_SIZE_TYPE
3876 dump_special_to_buffer (pfile, "__SIZE_TYPE__");
3877#endif
3878#ifndef NO_BUILTIN_PTRDIFF_TYPE
3879 dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
3880#endif
3881 dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
3882 dump_special_to_buffer (pfile, "__DATE__");
3883 dump_special_to_buffer (pfile, "__TIME__");
3884 if (!cppReader_isTraditional (pfile))
3885 dump_special_to_buffer (pfile, "__STDC__");
3886 }
3887}
3888
3889
3890/* Return 1 iff a token ending in C1 followed directly by a token C2
3891 could cause mis-tokenization. */
3892
3893static bool
3894unsafe_chars (char c1, char c2)
3895{
3896 switch (c1)
3897 {
3898 case '+': case '-':
3899 if (c2 == c1 || c2 == '=')
3900 return 1;
3901 goto letter;
3902 case '.':
3903 case '0': case '1': case '2': case '3': case '4':
3904 case '5': case '6': case '7': case '8': case '9':
3905 case 'e': case 'E': case 'p': case 'P':
3906 if (c2 == '-' || c2 == '+')
3907 return 1; /* could extend a pre-processing number */
3908 goto letter;
3909 case 'L':
3910 if (c2 == '\'' || c2 == '\"')
3911 return 1; /* Could turn into L"xxx" or L'xxx'. */
3912 goto letter;
3913 letter:
3914 case '_':
3915 case 'a': case 'b': case 'c': case 'd': case 'f':
3916 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
3917 case 'm': case 'n': case 'o': case 'q': case 'r':
3918 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
3919 case 'y': case 'z':
3920 case 'A': case 'B': case 'C': case 'D': case 'F':
3921 case 'G': case 'H': case 'I': case 'J': case 'K':
3922 case 'M': case 'N': case 'O': case 'Q': case 'R':
3923 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
3924 case 'Y': case 'Z':
3925 /* We're in the middle of either a name or a pre-processing number. */
3926 return (is_idchar[(int) c2] || c2 == '.');
3927 case '<': case '>': case '!': case '%': case '#': case ':':
3928 case '^': case '&': case '|': case '*': case '/': case '=':
3929 return (c2 == c1 || c2 == '=');
3930 }
3931 return 0;
3932}
3933
3934/* Expand a macro call.
3935 HP points to the symbol that is the macro being called.
3936 Put the result of expansion onto the input stack
3937 so that subsequent input by our caller will use it.
3938
3939 If macro wants arguments, caller has already verified that
3940 an argument list follows; arguments come from the input stack. */
3941
3942static void
3e3ec469 3943cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
ac0860d8 3944{
3945 int nargs;
3946 DEFINITION *defn = hp->value.defn;
3947 char *xbuf;
3948 char *oxbuf = NULL;
3949 int start_line;
3950 int start_column;
abd7f895 3951 int end_line;
3952 int end_column;
ac0860d8 3953 size_t xbuf_len;
3e3ec469 3954 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 3955 int rest_args;
3956 int rest_zero = 0;
3957 int i;
3958 struct argdata *args = NULL;
3959
3960 pfile->output_escapes++;
80489f0a 3961 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
abd7f895 3962 DPRINTF (("Expand macro: %d:%d", start_line, start_column));
ac0860d8 3963
3964 nargs = defn->nargs;
3965
3966 if (nargs >= 0)
3967 {
3968 enum cpp_token token = CPP_EOF;
3969
3970 args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
3971
3972 for (i = 0; i < nargs; i++)
3973 {
3974 args[i].expanded = 0;
3975 args[i].raw = 0;
3976 args[i].raw_length = 0;
3977 args[i].expand_length = args[i].stringified_length = -1;
3978 args[i].use_count = 0;
3979 }
3980
3981 /*
3982 ** Parse all the macro args that are supplied. I counts them.
3983 ** The first NARGS args are stored in ARGS.
3984 ** The rest are discarded. If rest_args is set then we assume
3985 ** macarg absorbed the rest of the args.
3986 */
3987
3988 i = 0;
3989 rest_args = 0;
3990
3991 cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg. */
3992 do
3993 {
3994 if (rest_args != 0)
3995 {
3996 continue;
3997 }
3998
3999 if (i < nargs || (nargs == 0 && i == 0))
4000 {
4001 /* if we are working on last arg which absorbs rest of args... */
4002 if (i == nargs - 1 && defn->rest_args)
4003 {
4004 rest_args = 1;
4005 }
4006
3e3ec469 4007 args[i].raw = size_toLong (cpplib_getWritten (pfile));
ac0860d8 4008 token = macarg (pfile, rest_args);
e5081f8c 4009 args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
ac0860d8 4010 args[i].newlines = FALSE; /* FIXME */
4011 }
4012 else
4013 {
4014 token = macarg (pfile, 0);
4015 }
4016
4017 if (token == CPP_EOF || token == CPP_POP)
4018 {
4019 cppReader_errorWithLine (pfile, start_line, start_column,
4020 cstring_fromCharsNew ("unterminated macro call"));
4021 sfree (args);
4022 return;
4023 }
4024 i++;
4025 } while (token == CPP_COMMA);
4026
4027 /* If we got one arg but it was just whitespace, call that 0 args. */
4028 if (i == 1)
4029 {
4030 char *bp;
4031 char *lim;
4032
4033 assertSet (args);
4034
4035 bp = ARG_BASE + args[0].raw;
4036 lim = bp + args[0].raw_length;
4037
4038 /* cpp.texi says for foo ( ) we provide one argument.
4039 However, if foo wants just 0 arguments, treat this as 0. */
4040
4041 if (nargs == 0)
4042 {
4043 while (bp != lim && is_space[(int) *bp])
4044 {
4045 bp++;
4046 }
4047 }
4048
4049 if (bp == lim)
4050 i = 0;
4051 }
4052
4053 /* Don't output an error message if we have already output one for
4054 a parse error above. */
4055 rest_zero = 0;
4056
4057 if (nargs == 0 && i > 0)
4058 {
4059 cppReader_error (pfile,
4060 message ("arguments given to macro `%s'", hp->name));
4061 }
4062 else if (i < nargs)
4063 {
4064 /* traditional C allows foo() if foo wants one argument. */
4065 if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
4066 {
4067 ;
4068 }
4069 /* the rest args token is allowed to absorb 0 tokens */
4070 else if (i == nargs - 1 && defn->rest_args)
4071 rest_zero = 1;
4072 else if (i == 0)
4073 cppReader_error (pfile,
4074 message ("macro `%s' used without args", hp->name));
4075 else if (i == 1)
4076 cppReader_error (pfile,
4077 message ("macro `%s' used with just one arg", hp->name));
4078 else
4079 {
4080 cppReader_error (pfile,
4081 message ("macro `%s' used with only %d args",
4082 hp->name, i));
4083 }
4084 }
4085 else if (i > nargs)
4086 {
4087 cppReader_error (pfile,
4088 message ("macro `%s' used with too many (%d) args", hp->name, i));
4089 }
4090 else
4091 {
4092 ;
4093 }
4094 }
4095
abd7f895 4096 /*
4097 ** If the agrument list was multiple lines, need to insert new lines to keep line
4098 ** numbers accurate.
4099 */
4100
80489f0a 4101 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
abd7f895 4102 DPRINTF (("Expand macro: %d:%d", end_line, end_column));
ce7034f0 4103
ac0860d8 4104 /* If macro wants zero args, we parsed the arglist for checking only.
4105 Read directly from the macro definition. */
4106
4107 if (nargs <= 0)
4108 {
4109 xbuf = defn->expansion;
4110 xbuf_len = defn->length;
4111 }
4112 else
4113 {
4114 char *exp = defn->expansion;
4115 int offset; /* offset in expansion,
4116 copied a piece at a time */
4117 size_t totlen; /* total amount of exp buffer filled so far */
4118
4119 register struct reflist *ap, *last_ap;
4120
4121 assertSet (args); /* args is defined since the nargs > 0 path was taken */
4122
4123 /* Macro really takes args. Compute the expansion of this call. */
4124
4125 /* Compute length in characters of the macro's expansion.
4126 Also count number of times each arg is used. */
4127 xbuf_len = defn->length;
4128
4129 llassert (args != NULL);
4130
4131 for (ap = defn->pattern; ap != NULL; ap = ap->next)
4132 {
4133 if (ap->stringify)
4134 {
4135 struct argdata *arg = &args[ap->argno];
4136
4137 /* Stringify it it hasn't already been */
4138 assertSet (arg);
4139
4140 if (arg->stringified_length < 0)
4141 {
4142 int arglen = arg->raw_length;
4143 bool escaped = FALSE;
4144 char in_string = '\0';
4145 char c;
4146
4147 /* Initially need_space is -1. Otherwise, 1 means the
4148 previous character was a space, but we suppressed it;
4149 0 means the previous character was a non-space. */
4150 int need_space = -1;
4151
4152 i = 0;
3e3ec469 4153 arg->stringified = cpplib_getWritten (pfile);
ac0860d8 4154 if (!cppReader_isTraditional (pfile))
4155 cppReader_putChar (pfile, '\"'); /* insert beginning quote */
4156 for (; i < arglen; i++)
4157 {
4158 c = (ARG_BASE + arg->raw)[i];
4159
4160 if (in_string == '\0')
4161 {
4162 /* Internal sequences of whitespace are replaced by
4163 one space except within an string or char token.*/
4164 if (is_space[(int) c])
4165 {
3e3ec469 4166 if (cpplib_getWritten (pfile) > arg->stringified
4167 && (cpplib_getPWritten (pfile))[-1] == '@')
ac0860d8 4168 {
4169 /* "@ " escape markers are removed */
4170 cppReader_adjustWritten (pfile, -1);
4171 /*@innercontinue@*/ continue;
4172 }
4173 if (need_space == 0)
4174 need_space = 1;
4175 /*@innercontinue@*/ continue;
4176 }
4177 else if (need_space > 0)
4178 cppReader_putChar (pfile, ' ');
4179 else
4180 {
4181 ;
4182 }
4183
4184 need_space = 0;
4185 }
4186
4187 if (escaped)
4188 escaped = 0;
4189 else
4190 {
4191 if (c == '\\')
4192 escaped = 1;
4193
4194 if (in_string != '\0')
4195 {
4196 if (c == in_string)
4197 in_string = '\0';
4198 }
4199 else if (c == '\"' || c == '\'')
4200 {
4201 in_string = c;
4202 }
4203 else
4204 {
4205 ;
4206 }
4207 }
4208
4209 /* Escape these chars */
4210 if (c == '\"' || (in_string != '\0' && c == '\\'))
4211 cppReader_putChar (pfile, '\\');
4212 if (isprint (c))
4213 cppReader_putChar (pfile, c);
4214 else
4215 {
3e3ec469 4216 cpplib_reserve (pfile, 4);
4217 sprintf (cpplib_getPWritten (pfile), "\\%03o",
ac0860d8 4218 (unsigned int) c);
4219 cppReader_adjustWritten (pfile, 4);
4220 }
4221 }
4222 if (!cppReader_isTraditional (pfile))
4223 cppReader_putChar (pfile, '\"'); /* insert ending quote */
4224 arg->stringified_length
3e3ec469 4225 = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
ac0860d8 4226 }
4227
4228 xbuf_len += args[ap->argno].stringified_length;
4229 }
4230 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4231 {
b73d1009 4232 /* Add 4 for two newline-space markers to prevent token concatenation. */
4233 assertSet (args); /* Splint shouldn't need this */
ac0860d8 4234 xbuf_len += args[ap->argno].raw_length + 4;
4235 }
4236 else
4237 {
4238 /* We have an ordinary (expanded) occurrence of the arg.
4239 So compute its expansion, if we have not already. */
4240
b73d1009 4241 assertSet (args); /* shouldn't need this */
ac0860d8 4242
4243 if (args[ap->argno].expand_length < 0)
4244 {
3e3ec469 4245 args[ap->argno].expanded = cpplib_getWritten (pfile);
ac0860d8 4246 cpp_expand_to_buffer (pfile,
4247 ARG_BASE + args[ap->argno].raw,
4248 size_fromInt (args[ap->argno].raw_length));
4249
4250 args[ap->argno].expand_length
3e3ec469 4251 = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
ac0860d8 4252 }
4253
4254 /* Add 4 for two newline-space markers to prevent
4255 token concatenation. */
4256 xbuf_len += args[ap->argno].expand_length + 4;
4257 }
4258 if (args[ap->argno].use_count < 10)
4259 args[ap->argno].use_count++;
4260 }
4261
4262 xbuf = (char *) dmalloc (xbuf_len + 1);
4263 oxbuf = xbuf;
4264
4265 /*
4266 ** Generate in XBUF the complete expansion
4267 ** with arguments substituted in.
4268 ** TOTLEN is the total size generated so far.
4269 ** OFFSET is the index in the definition
4270 ** of where we are copying from.
4271 */
4272
4273 offset = 0;
4274 totlen = 0;
4275
4276 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
4277 last_ap = ap, ap = ap->next)
4278 {
4279 register struct argdata *arg = &args[ap->argno];
4280 size_t count_before = totlen;
4281
4282 /* Add chars to XBUF. */
4283 for (i = 0; i < ap->nchars; i++, offset++)
4284 {
4285 xbuf[totlen++] = exp[offset];
4286 }
4287
4288 /* If followed by an empty rest arg with concatenation,
4289 delete the last run of nonwhite chars. */
4290 if (rest_zero && totlen > count_before
4291 && ((ap->rest_args && ap->raw_before)
4292 || (last_ap != NULL && last_ap->rest_args
4293 && last_ap->raw_after)))
4294 {
4295 /* Delete final whitespace. */
4296 while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
4297 {
4298 totlen--;
4299 }
4300
4301 /* Delete the nonwhites before them. */
4302 while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
4303 {
4304 totlen--;
4305 }
4306 }
4307
4308 if (ap->stringify != 0)
4309 {
4310 assertSet(arg);
4311 memcpy (xbuf + totlen,
4312 ARG_BASE + arg->stringified,
4313 size_fromInt (arg->stringified_length));
4314 totlen += arg->stringified_length;
4315 }
4316 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4317 {
4318 char *p1;
4319 char *l1;
4320
4321 assertSet (arg);
4322
4323 p1 = ARG_BASE + arg->raw;
4324 l1 = p1 + arg->raw_length;
4325
4326 if (ap->raw_before)
4327 {
4328 while (p1 != l1 && is_space[(int) *p1])
4329 {
4330 p1++;
4331 }
4332
4333 while (p1 != l1 && is_idchar[(int) *p1])
4334 {
4335 xbuf[totlen++] = *p1++;
4336 }
4337
4338 /* Delete any no-reexpansion marker that follows
4339 an identifier at the beginning of the argument
4340 if the argument is concatenated with what precedes it. */
4341 if (p1[0] == '@' && p1[1] == '-')
4342 p1 += 2;
4343 }
4344 if (ap->raw_after)
4345 {
4346 /* Arg is concatenated after: delete trailing whitespace,
4347 whitespace markers, and no-reexpansion markers. */
4348 while (p1 != l1)
4349 {
4350 if (is_space[(int) l1[-1]]) l1--;
4351 else if (l1[-1] == '-')
4352 {
4353 char *p2 = l1 - 1;
4354 /* If a `-' is preceded by an odd number of newlines then it
4355 and the last newline are a no-reexpansion marker. */
4356 while (p2 != p1 && p2[-1] == '\n')
4357 {
4358 p2--;
4359 }
4360
4361 if (((l1 - 1 - p2) & 1) != 0)
4362 {
4363 l1 -= 2;
4364 }
4365 else
4366 {
4367 /*@innerbreak@*/ break;
4368 }
4369 }
4370 else
4371 {
4372 /*@innerbreak@*/ break;
4373 }
4374 }
4375 }
4376
4377 memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
4378 totlen += l1 - p1;
4379 }
4380 else
4381 {
4382 char *expanded;
4383
4384 assertSet (arg);
4385 expanded = ARG_BASE + arg->expanded;
4386
4387 if (!ap->raw_before && totlen > 0
4388 && (arg->expand_length != 0)
4389 && !cppReader_isTraditional(pfile)
4390 && unsafe_chars (xbuf[totlen-1], expanded[0]))
4391 {
4392 xbuf[totlen++] = '@';
4393 xbuf[totlen++] = ' ';
4394 }
4395
4396 memcpy (xbuf + totlen, expanded,
4397 size_fromInt (arg->expand_length));
4398 totlen += arg->expand_length;
4399
4400 if (!ap->raw_after && totlen > 0
4401 && offset < size_toInt (defn->length)
4402 && !cppReader_isTraditional(pfile)
4403 && unsafe_chars (xbuf[totlen-1], exp[offset]))
4404 {
4405 xbuf[totlen++] = '@';
4406 xbuf[totlen++] = ' ';
4407 }
4408
4409 /* If a macro argument with newlines is used multiple times,
4410 then only expand the newlines once. This avoids creating
4411 output lines which don't correspond to any input line,
4412 which confuses gdb and gcov. */
4413 if (arg->use_count > 1 && arg->newlines > 0)
4414 {
4415 /* Don't bother doing change_newlines for subsequent
4416 uses of arg. */
4417 arg->use_count = 1;
4418 arg->expand_length
4419 = change_newlines (expanded, arg->expand_length);
4420 }
4421 }
4422
4423 if (totlen > xbuf_len)
4424 abort ();
4425 }
4426
4427 /* if there is anything left of the definition
4428 after handling the arg list, copy that in too. */
4429
4430 for (i = offset; i < size_toInt (defn->length); i++)
4431 {
4432 /* if we've reached the end of the macro */
4433 if (exp[i] == ')')
4434 rest_zero = 0;
4435 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
4436 && last_ap->raw_after))
4437 xbuf[totlen++] = exp[i];
4438 }
4439
4440 xbuf[totlen] = '\0';
4441 xbuf_len = totlen;
4442 }
4443
4444 pfile->output_escapes--;
4445
4446 /* Now put the expansion on the input stack
4447 so our caller will commence reading from it. */
abd7f895 4448 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
ce7034f0 4449
abd7f895 4450 if (end_line != start_line)
4451 {
4452 /* xbuf must have enough newlines */
4453 int newlines = end_line - start_line;
4454 int foundnewlines = 0;
4455 char *xbufptr = xbuf;
4456
4457 while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
4458 {
4459 foundnewlines++;
4460 xbufptr++;
4461
4462 if (*xbufptr == '\0')
4463 {
4464 break;
4465 }
4466 }
4467
4468 if (foundnewlines < newlines)
4469 {
4470 cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
4471
4472 while (foundnewlines < newlines)
4473 {
4474 newbuf = cstring_appendChar (newbuf, '\n');
4475 foundnewlines++;
4476 }
4477
4478 sfree (oxbuf);
4479 xbuf = cstring_toCharsSafe (newbuf);
4480 xbuf_len = cstring_length (newbuf);
4481 /*@-branchstate@*/
4482 } /*@=branchstate@*/
4483 }
4484
4485 DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4486
ac0860d8 4487 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
ce7034f0 4488 DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
abd7f895 4489 cppReader_getBufferSafe (pfile)->has_escapes = 1;
ac0860d8 4490
4491 /* Pop the space we've used in the token_buffer for argument expansion. */
4492 cppReader_setWritten (pfile, old_written);
ce7034f0 4493 DPRINTF (("Done set written"));
4494
ac0860d8 4495 /* Recursive macro use sometimes works traditionally.
4496 #define foo(x,y) bar (x (y,0), y)
4497 foo (foo, baz) */
4498
4499 if (!cppReader_isTraditional (pfile))
4500 hp->type = T_DISABLED;
4501
4502 sfree (args);
4503}
4504
4505static void
4506push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
4507 /*@dependent@*/ hashNode hp)
4508{
4509 cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
4510
4511 if (mbuf == NULL)
4512 {
4513 return;
4514 }
4515
4516 mbuf->cleanup = cppReader_macroCleanup;
4517
4518 llassert (mbuf->hnode == NULL);
4519 mbuf->hnode = hp;
4520
4521 /* The first chars of the expansion should be a "@ " added by
4522 collect_expansion. This is to prevent accidental token-pasting
4523 between the text preceding the macro invocation, and the macro
4524 expansion text.
4525
4526 We would like to avoid adding unneeded spaces (for the sake of
4527 tools that use cpp, such as imake). In some common cases we can
4528 tell that it is safe to omit the space.
4529
4530 The character before the macro invocation cannot have been an
4531 idchar (or else it would have been pasted with the idchars of
4532 the macro name). Therefore, if the first non-space character
4533 of the expansion is an idchar, we do not need the extra space
4534 to prevent token pasting.
4535
4536 Also, we don't need the extra space if the first char is '(',
4537 or some other (less common) characters. */
4538
4539 if (xbuf[0] == '@' && xbuf[1] == ' '
4540 && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
4541 || xbuf[2] == '\"'))
4542 {
4543 llassert (mbuf->cur != NULL);
ce7034f0 4544 DPRINTF (("Eating: %c", xbuf[2]));
ac0860d8 4545 mbuf->cur += 2;
4546 }
ce7034f0 4547
ac0860d8 4548}
4549
4550
3e3ec469 4551/* Like cpplib_getToken, except that it does not read past end-of-line.
ac0860d8 4552 Also, horizontal space is skipped, and macros are popped. */
4553
4554static enum cpp_token
4555get_directive_token (cppReader *pfile)
4556{
4557 for (;;)
4558 {
3e3ec469 4559 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 4560 enum cpp_token token;
4561 cppSkipHspace (pfile);
4562 if (cppReader_peekC (pfile) == '\n')
4563 {
4564 return CPP_VSPACE;
4565 }
4566
3e3ec469 4567 token = cpplib_getToken (pfile);
ac0860d8 4568
4569 switch (token)
4570 {
4571 case CPP_POP:
4572 if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
4573 return token;
4574 /*@fallthrough@*/
4575 case CPP_HSPACE:
4576 case CPP_COMMENT:
4577 cppReader_setWritten (pfile, old_written);
4578 /*@switchbreak@*/ break;
4579 default:
4580 return token;
4581 }
4582 }
4583}
4584
4585
4586/* Handle #include and #import.
4587 This function expects to see "fname" or <fname> on the input.
4588
4589 The input is normally in part of the output_buffer following
3e3ec469 4590 cpplib_getWritten, and will get overwritten by output_line_command.
ac0860d8 4591 I.e. in input file specification has been popped by cppReader_handleDirective.
4592 This is safe. */
4593
4594static int
4595do_include (cppReader *pfile, struct directive *keyword,
4596 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
4597{
4598 bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
4599 cstring fname;
4600 char *fbeg, *fend; /* Beginning and end of fname */
4601 enum cpp_token token;
4602
4603 /* Chain of dirs to search */
4604 struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
4605 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
4606 struct file_name_list *searchptr = NULL;
3e3ec469 4607 size_t old_written = cpplib_getWritten (pfile);
abd7f895 4608 size_t flen;
ac0860d8 4609
4610 int f; /* file number */
4611 int angle_brackets = 0; /* 0 for "...", 1 for <...> */
4612 f= -1; /* JF we iz paranoid! */
4613
4614 pfile->parsing_include_directive++;
4615 token = get_directive_token (pfile);
4616 pfile->parsing_include_directive--;
4617
4618 if (token == CPP_STRING)
4619 {
4620 /* FIXME - check no trailing garbage */
4621 fbeg = pfile->token_buffer + old_written + 1;
3e3ec469 4622 fend = cpplib_getPWritten (pfile) - 1;
ac0860d8 4623 if (fbeg[-1] == '<')
4624 {
4625 angle_brackets = 1;
4626 /* If -I-, start with the first -I dir after the -I-. */
4627 if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
4628 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4629 }
4630 /* If -I- was specified, don't search current dir, only spec'd ones. */
4631 else if (!CPPOPTIONS (pfile)->ignore_srcdir)
4632 {
4633 cppBuffer *fp = CPPBUFFER (pfile);
4634 /* We have "filename". Figure out directory this source
4635 file is coming from and put it on the front of the list. */
4636
4637 for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4638 {
4639 int n;
4640 char *ep,*nam;
4641
4642 llassert (fp != NULL);
4643
4644 nam = NULL;
4645
4646 if (cstring_isDefined (fp->nominal_fname))
4647 {
4648 nam = cstring_toCharsSafe (fp->nominal_fname);
4649
4650 /* Found a named file. Figure out dir of the file,
4651 and put it in front of the search list. */
4652 dsp[0].next = search_start;
4653 search_start = dsp;
4654
4655#ifndef VMS
4656 ep = strrchr (nam, CONNECTCHAR);
4657#else /* VMS */
4658 ep = strrchr (nam, ']');
4659 if (ep == NULL) ep = strrchr (nam, '>');
4660 if (ep == NULL) ep = strrchr (nam, ':');
4661 if (ep != NULL) ep++;
4662#endif /* VMS */
4663 if (ep != NULL)
4664 {
4665 char save;
4666
4667 n = ep - nam;
4668 save = nam[n];
4669 nam[n] = '\0';
4670
4671 /*@-onlytrans@*/ /* This looks like a memory leak... */
4672 dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
4673 /*@=onlytrans@*/
4674 nam[n] = save;
4675
e5081f8c 4676 if (n + INCLUDE_LEN_FUDGE > size_toInt (pfile->max_include_len))
4677 pfile->max_include_len = size_fromInt (n + INCLUDE_LEN_FUDGE);
ac0860d8 4678 }
4679 else
4680 {
4681 dsp[0].fname = cstring_undefined; /* Current directory */
4682 }
4683
4684 dsp[0].got_name_map = 0;
4685 break;
4686 }
4687 }
4688 }
4689 else
4690 {
4691 ;
4692 }
4693 }
4694#ifdef VMS
4695 else if (token == CPP_NAME)
4696 {
4697 /*
4698 * Support '#include xyz' like VAX-C to allow for easy use of all the
4699 * decwindow include files. It defaults to '#include <xyz.h>' (so the
4700 * code from case '<' is repeated here) and generates a warning.
4701 */
4702 cppReader_warning (pfile,
4703 "VAX-C-style include specification found, use '#include <filename.h>' !");
4704 angle_brackets = 1;
4705 /* If -I-, start with the first -I dir after the -I-. */
4706 if (CPPOPTIONS (pfile)->first_bracket_include)
4707 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4708 fbeg = pfile->token_buffer + old_written;
3e3ec469 4709 fend = cpplib_getPWritten (pfile);
ac0860d8 4710 }
4711#endif
4712 else
4713 {
4714 cppReader_error (pfile,
4715 message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
4716 keyword->name));
4717
4718 cppReader_setWritten (pfile, old_written);
4719 cppReader_skipRestOfLine (pfile);
4720 return 0;
4721 }
4722
4723 *fend = 0;
4724
4725 token = get_directive_token (pfile);
4726 if (token != CPP_VSPACE)
4727 {
4728 cppReader_errorLit (pfile,
4729 cstring_makeLiteralTemp ("Junk at end of #include"));
4730
4731 while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
4732 {
4733 token = get_directive_token (pfile);
4734 }
4735 }
4736
4737 /*
4738 ** For #include_next, skip in the search path
4739 ** past the dir in which the containing file was found.
4740 */
4741
4742 if (skip_dirs)
4743 {
4744 cppBuffer *fp = CPPBUFFER (pfile);
4745
4746 for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4747 {
4748 llassert (fp != NULL);
4749
4750 if (fp->fname != NULL)
4751 {
4752 /* fp->dir is null if the containing file was specified with
4753 an absolute file name. In that case, don't skip anything. */
4754 if (fp->dir == SELF_DIR_DUMMY)
4755 {
4756 search_start = CPPOPTIONS (pfile)->include;
4757 }
4758 else if (fp->dir != NULL)
4759 {
4760 search_start = fp->dir->next;
4761 }
4762 else
4763 {
4764 ;
4765 }
4766
4767 break;
4768 }
4769 }
4770 }
abd7f895 4771
ac0860d8 4772 cppReader_setWritten (pfile, old_written);
4773
abd7f895 4774 flen = size_fromInt (fend - fbeg);
ac0860d8 4775
4776 DPRINTF (("fbeg: %s", fbeg));
4777
4778 if (flen == 0)
4779 {
4780 cppReader_error (pfile,
4781 message ("Empty file name in #%s", keyword->name));
4782 return 0;
4783 }
4784
4785 /*
4786 ** Allocate this permanently, because it gets stored in the definitions
4787 ** of macros.
4788 */
4789
4790 fname = cstring_undefined;
4791
4792 /* + 2 above for slash and terminating null. */
4793 /* + 2 added for '.h' on VMS (to support '#include filename') */
4794
4795 /* If specified file name is absolute, just open it. */
4796
4797 if (osd_isConnectChar (*fbeg)
4798# if defined (WIN32) || defined (OS2)
4799 || (*(fbeg + 1) == ':')
4800# endif
4801 )
4802 {
4803 fname = cstring_copyLength (fbeg, flen);
4804
4805 if (redundant_include_p (pfile, fname))
4806 {
4807 cstring_free (fname);
4808 return 0;
4809 }
4810
4811 f = open_include_file (pfile, fname, NULL);
4812
4813 if (f == IMPORT_FOUND)
4814 {
4815 return 0; /* Already included this file */
4816 }
4817 }
4818 else
4819 {
4820 /* Search directory path, trying to open the file.
4821 Copy each filename tried into FNAME. */
4822
4823 for (searchptr = search_start; searchptr != NULL;
4824 searchptr = searchptr->next)
4825 {
4826 if (!cstring_isEmpty (searchptr->fname))
4827 {
4828 /* The empty string in a search path is ignored.
4829 This makes it possible to turn off entirely
4830 a standard piece of the list. */
4831 if (cstring_isEmpty (searchptr->fname))
4832 continue;
4833
4834 fname = cstring_copy (searchptr->fname);
4835 fname = cstring_appendChar (fname, CONNECTCHAR);
4836 DPRINTF (("Here: %s", fname));
4837 }
4838 else
4839 {
4840 ;
4841 }
4842
4843 fname = cstring_concatLength (fname, fbeg, flen);
4844
4845 DPRINTF (("fname: %s", fname));
4846
4847 /* Win32 directory fix from Kay Buschner. */
4848#if defined (WIN32) || defined (OS2)
4849 /* Fix all unixdir slashes to win dir slashes */
4850 if (searchptr->fname && (searchptr->fname[0] != 0))
4851 {
4852 cstring_replaceAll (fname, '/', '\\');
4853 }
4854#endif /* WIN32 */
4855
4856#ifdef VMS
4857 /* Change this 1/2 Unix 1/2 VMS file specification into a
4858 full VMS file specification */
4859 if (searchptr->fname && (searchptr->fname[0] != 0)) {
4860 /* Fix up the filename */
4861 hack_vms_include_specification (fname);
4862 } else {
4863 /* This is a normal VMS filespec, so use it unchanged. */
4864 strncpy (fname, fbeg, flen);
4865 fname[flen] = 0;
4866 /* if it's '#include filename', add the missing .h */
4867 if (strchr (fname,'.') == NULL) {
4868 strcat (fname, ".h");
4869 }
4870 }
4871#endif /* VMS */
4872 /* ??? There are currently 3 separate mechanisms for avoiding processing
4873 of redundant include files: #import, #pragma once, and
4874 redundant_include_p. It would be nice if they were unified. */
4875
4876 if (redundant_include_p (pfile, fname))
4877 {
4878 cstring_free (fname);
4879 return 0;
4880 }
4881
4882 DPRINTF (("Trying: %s", fname));
4883
4884 f = open_include_file (pfile, fname, searchptr);
4885
4886 if (f == IMPORT_FOUND)
4887 {
b73d1009 4888 return 0; /* Already included this file */
ac0860d8 4889 }
4890#ifdef EACCES
4891 else if (f == IMPORT_NOT_FOUND && errno == EACCES)
4892 {
4893 cppReader_warning (pfile,
4894 message ("Header file %s exists, but is not readable", fname));
4895 }
4896#endif
4897
4898 if (f >= 0)
4899 {
4900 break;
4901 }
4902 }
4903 }
4904
4905 if (f < 0)
4906 {
4907 /* A file that was not found. */
4908 fname = cstring_copyLength (fbeg, flen);
4909
4910 if (search_start != NULL)
4911 {
4912 cppReader_error (pfile,
4913 message ("Cannot find include file %s on search path: %x",
4914 fname,
4915 searchPath_unparse (search_start)));
4916 }
4917 else
4918 {
4919 cppReader_error (pfile,
4920 message ("No include path in which to find %s", fname));
4921 }
4922 }
4923 else {
4924 /*
4925 ** Check to see if this include file is a once-only include file.
4926 ** If so, give up.
4927 */
4928
4929 struct file_name_list *ptr;
4930
4931 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
4932 {
4933 if (cstring_equal (ptr->fname, fname))
4934 {
4935 /* This file was included before. */
4936 break;
4937 }
4938 }
4939
4940 if (ptr == NULL)
4941 {
4942 /* This is the first time for this file. */
4943 /* Add it to list of files included. */
4944
4945 ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
4946 ptr->control_macro = NULL;
4947 ptr->c_system_include_path = NULL;
4948 ptr->next = pfile->all_include_files;
4949 ptr->fname = fname;
4950 ptr->got_name_map = NULL;
4951
4952 DPRINTF (("Including file: %s", fname));
4953 pfile->all_include_files = ptr;
4954 assertSet (pfile->all_include_files);
4955 }
4956
4957 if (angle_brackets != 0)
4958 {
4959 pfile->system_include_depth++;
4960 }
4961
4962 /* Actually process the file */
4963 if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
4964 {
4965 cstring_free (fname);
4966 return 0;
4967 }
4968
4969 if (finclude (pfile, f, fname, is_system_include (pfile, fname),
4970 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
4971 {
4972 output_line_command (pfile, 0, enter_file);
4973 pfile->only_seen_white = 2;
4974 }
4975
4976 if (angle_brackets)
4977 {
4978 pfile->system_include_depth--;
4979 }
4980 /*@-branchstate@*/
4981 } /*@=branchstate@*/
4982
4983 return 0;
4984}
4985
4986/* Return nonzero if there is no need to include file NAME
4987 because it has already been included and it contains a conditional
4988 to make a repeated include do nothing. */
4989
4990static bool
4991redundant_include_p (cppReader *pfile, cstring name)
4992{
4993 struct file_name_list *l = pfile->all_include_files;
4994
4995 for (; l != NULL; l = l->next)
4996 {
4997 if (cstring_equal (name, l->fname)
4998 && (l->control_macro != NULL)
3e3ec469 4999 && (cpphash_lookup (l->control_macro, -1, -1) != NULL))
ac0860d8 5000 {
5001 return TRUE;
5002 }
5003 }
5004
5005 return FALSE;
5006}
5007
5008/* Return nonzero if the given FILENAME is an absolute pathname which
5009 designates a file within one of the known "system" include file
5010 directories. We assume here that if the given FILENAME looks like
5011 it is the name of a file which resides either directly in a "system"
5012 include file directory, or within any subdirectory thereof, then the
5013 given file must be a "system" include file. This function tells us
5014 if we should suppress pedantic errors/warnings for the given FILENAME.
5015
5016 The value is 2 if the file is a C-language system header file
5017 for which C++ should (on most systems) assume `extern "C"'. */
5018
5019static bool
5020is_system_include (cppReader *pfile, cstring filename)
5021{
5022 struct file_name_list *searchptr;
5023
5024 for (searchptr = CPPOPTIONS (pfile)->first_system_include;
5025 searchptr != NULL;
5026 searchptr = searchptr->next)
5027 {
abd7f895 5028 if (!cstring_isEmpty (searchptr->fname))
5029 {
5030 cstring sys_dir = searchptr->fname;
5031 size_t length = cstring_length (sys_dir);
5032
5033 if (cstring_equalLen (sys_dir, filename, length)
5034 && osd_isConnectChar (cstring_getChar (filename, length)))
5035 {
5036 if (searchptr->c_system_include_path)
5037 return 2;
5038 else
5039 return 1;
5040 }
5041 }
ac0860d8 5042 }
abd7f895 5043
ac0860d8 5044 return 0;
5045}
5046
5047/* Convert a character string literal into a nul-terminated string.
5048 The input string is [IN ... LIMIT).
5049 The result is placed in RESULT. RESULT can be the same as IN.
5050 The value returned in the end of the string written to RESULT,
5051 or NULL on error. */
5052
5053static /*@null@*/ char *
5054convert_string (cppReader *pfile, /*@returned@*/ char *result,
5055 char *in, char *limit, int handle_escapes)
5056{
5057 char c;
5058 c = *in++;
5059
5060 if (c != '\"')
5061 {
5062 return NULL;
5063 }
5064
5065 while (in < limit)
5066 {
5067 c = *in++;
5068
5069 switch (c)
5070 {
5071 case '\0':
5072 return NULL;
5073 case '\"':
5074 limit = in;
5075 /*@switchbreak@*/ break;
5076 case '\\':
5077 if (handle_escapes)
5078 {
5079 char *bpc = (char *) in;
5080 int i = (char) cppReader_parseEscape (pfile, &bpc);
5081 in = (char *) bpc;
5082 if (i >= 0)
5083 *result++ = (char) c;
5084 /*@switchbreak@*/ break;
5085 }
5086
5087 /*@fallthrough@*/
5088 default:
5089 *result++ = c;
5090 }
5091 }
5092
5093 *result = 0;
5094 return result;
5095}
5096
5097/*
5098 * interpret #line command. Remembers previously seen fnames
5099 * in its very own hash table.
5100 */
5101
5102/*@constant int FNAME_HASHSIZE@*/
5103#define FNAME_HASHSIZE 37
5104
5105static int
5106do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
5107{
5108 cppBuffer *ip = cppReader_getBuffer (pfile);
5109 int new_lineno;
3e3ec469 5110 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5111 enum file_change_code file_change = same_file;
5112 enum cpp_token token;
5113
abd7f895 5114 llassert (ip != NULL);
ac0860d8 5115 token = get_directive_token (pfile);
5116
5117 if (token != CPP_NUMBER
5118 || !isdigit(pfile->token_buffer[old_written]))
5119 {
5120 cppReader_errorLit (pfile,
5121 cstring_makeLiteralTemp ("invalid format `#line' command"));
5122
5123 goto bad_line_directive;
5124 }
5125
5126 /* The Newline at the end of this line remains to be processed.
5127 To put the next line at the specified line number,
5128 we must store a line number now that is one less. */
5129 new_lineno = atoi (pfile->token_buffer + old_written) - 1;
5130 cppReader_setWritten (pfile, old_written);
5131
5132 /* NEW_LINENO is one less than the actual line number here. */
5133 if (cppReader_isPedantic (pfile) && new_lineno < 0)
5134 cppReader_pedwarnLit (pfile,
5135 cstring_makeLiteralTemp ("line number out of range in `#line' command"));
5136
5137 token = get_directive_token (pfile);
5138
5139 if (token == CPP_STRING) {
5140 char *fname = pfile->token_buffer + old_written;
5141 char *end_name;
5142 static hashNode fname_table[FNAME_HASHSIZE];
5143 hashNode hp;
5144 hashNode *hash_bucket;
5145 char *p;
5146 size_t num_start;
abd7f895 5147 size_t fname_length;
ac0860d8 5148
5149 /* Turn the file name, which is a character string literal,
5150 into a null-terminated string. Do this in place. */
3e3ec469 5151 end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
ac0860d8 5152 if (end_name == NULL)
5153 {
5154 cppReader_errorLit (pfile,
5155 cstring_makeLiteralTemp ("invalid format `#line' command"));
5156 goto bad_line_directive;
5157 }
5158
abd7f895 5159 fname_length = size_fromInt (end_name - fname);
3e3ec469 5160 num_start = cpplib_getWritten (pfile);
ac0860d8 5161
5162 token = get_directive_token (pfile);
5163 if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
5164 p = pfile->token_buffer + num_start;
5165 if (cppReader_isPedantic (pfile))
5166 cppReader_pedwarnLit (pfile,
5167 cstring_makeLiteralTemp ("garbage at end of `#line' command"));
5168
5169 if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
5170 {
5171 cppReader_errorLit (pfile,
5172 cstring_makeLiteralTemp ("invalid format `#line' command"));
5173 goto bad_line_directive;
5174 }
5175 if (*p == '1')
5176 file_change = enter_file;
5177 else if (*p == 2)
5178 file_change = leave_file;
5179 else if (*p == 3)
5180 ip->system_header_p = 1;
5181 else /* if (*p == 4) */
5182 ip->system_header_p = 2;
5183
5184 cppReader_setWritten (pfile, num_start);
5185 token = get_directive_token (pfile);
5186 p = pfile->token_buffer + num_start;
5187 if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
5188 ip->system_header_p = *p == 3 ? 1 : 2;
5189 token = get_directive_token (pfile);
5190 }
5191 if (token != CPP_VSPACE) {
5192 cppReader_errorLit (pfile,
5193 cstring_makeLiteralTemp ("invalid format `#line' command"));
5194
5195 goto bad_line_directive;
5196 }
5197 }
5198
5199 hash_bucket =
3e3ec469 5200 &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
abd7f895 5201
ac0860d8 5202 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
5203 {
abd7f895 5204 if (hp->length == fname_length)
5205 {
5206 llassert (hp->value.cpval != NULL);
5207
5208 if (strncmp (hp->value.cpval, fname, fname_length) == 0)
5209 {
5210 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5211 break;
5212 }
5213 }
ac0860d8 5214 }
abd7f895 5215
ac0860d8 5216 if (hp == 0) {
5217 /* Didn't find it; cons up a new one. */
5218 hp = (hashNode) dmalloc (sizeof (*hp));
5219
5220 hp->prev = NULL;
5221 hp->bucket_hdr = NULL;
5222 hp->type = T_NONE;
5223 hp->name = cstring_undefined;
5224 hp->next = *hash_bucket;
5225
5226 *hash_bucket = hp;
5227
5228 hp->length = fname_length;
5229 hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
abd7f895 5230 memcpy (hp->value.cpval, fname, fname_length);
ac0860d8 5231 hp->value.cpval[fname_length] = '\0';
5232 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5233 }
5234 }
5235 else if (token != CPP_VSPACE && token != CPP_EOF)
5236 {
5237 cppReader_errorLit (pfile,
5238 cstring_makeLiteralTemp ("invalid format `#line' command"));
5239 goto bad_line_directive;
5240 }
5241 else
5242 {
5243 ;
5244 }
5245
5246 ip->lineno = new_lineno;
5247bad_line_directive:
5248 cppReader_skipRestOfLine (pfile);
5249 cppReader_setWritten (pfile, old_written);
5250 output_line_command (pfile, 0, file_change);
5251 return 0;
5252}
5253
5254/*
5255 * remove the definition of a symbol from the symbol table.
5256 * according to un*x /lib/cpp, it is not an error to undef
5257 * something that has no definitions, so it isn't one here either.
5258 */
5259
5260static int
5261do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
5262{
5263
abd7f895 5264 size_t sym_length;
ac0860d8 5265 hashNode hp;
5266 char *orig_buf = buf;
5267
5268 SKIP_WHITE_SPACE (buf);
5269
5270 sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
5271
abd7f895 5272 while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL)
ac0860d8 5273 {
5274 /* If we are generating additional info for debugging (with -g) we
5275 need to pass through all effective #undef commands. */
5276 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
5277 {
5278 pass_thru_directive (orig_buf, limit, pfile, keyword);
5279 }
5280
5281 if (hp->type != T_MACRO)
5282 {
5283 cppReader_warning (pfile,
5284 message ("Undefining preprocessor builtin: %s",
5285 hp->name));
5286 }
5287
5288 cppReader_deleteMacro (hp);
5289 }
5290
5291 if (cppReader_isPedantic (pfile)) {
5292 buf += sym_length;
5293 SKIP_WHITE_SPACE (buf);
5294 if (buf != limit)
5295 {
5296 cppReader_pedwarnLit (pfile,
5297 cstring_makeLiteralTemp ("garbage after `#undef' directive"));
5298 }
5299 }
5300
5301 return 0;
5302}
5303
5304
5305/*
5306 * Report an error detected by the program we are processing.
5307 * Use the text of the line in the error message.
5308 * (We use error because it prints the filename & line#.)
5309 */
5310
5311static int
5312do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5313 char *buf, char *limit)
5314{
abd7f895 5315 size_t length = size_fromInt (limit - buf);
ac0860d8 5316 cstring copy = cstring_copyLength (buf, length);
5317 cstring adv = cstring_advanceWhiteSpace (copy);
5318
5319 cppReader_error (pfile, message ("#error %s", adv));
5320 cstring_free (copy);
5321 return 0;
5322}
5323
5324/*
5325 * Report a warning detected by the program we are processing.
5326 * Use the text of the line in the warning message, then continue.
5327 * (We use error because it prints the filename & line#.)
5328 */
5329
5330static int
5331do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5332 char *buf, char *limit)
5333{
abd7f895 5334 size_t length = size_fromInt (limit - buf);
ac0860d8 5335 cstring copy = cstring_copyLength (buf, length);
5336 cstring adv = cstring_advanceWhiteSpace (copy);
5337 cppReader_warning (pfile, message ("#warning %s", adv));
5338 cstring_free (copy);
5339 return 0;
5340}
5341
5342
5343/* #ident has already been copied to the output file, so just ignore it. */
5344
5345static int
5346do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5347 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5348{
5349 /* Allow #ident in system headers, since that's not user's fault. */
abd7f895 5350 if (cppReader_isPedantic (pfile)
5351 && !cppReader_getBufferSafe (pfile)->system_header_p)
ac0860d8 5352 cppReader_pedwarnLit (pfile,
5353 cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
5354
3e3ec469 5355 /* Leave rest of line to be read by later calls to cpplib_getToken. */
ac0860d8 5356
5357 return 0;
5358}
5359
5360/* #pragma and its argument line have already been copied to the output file.
5361 Just check for some recognized pragmas that need validation here. */
5362
5363static int
5364do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5365 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5366{
5367 while (*buf == ' ' || *buf == '\t')
5368 {
5369 buf++;
5370 }
5371
5372 if (!strncmp (buf, "implementation", 14)) {
5373 /* Be quiet about `#pragma implementation' for a file only if it hasn't
5374 been included yet. */
5375 struct file_name_list *ptr;
5376 char *p = buf + 14, *fname, *inc_fname;
abd7f895 5377 size_t fname_len;
ac0860d8 5378 SKIP_WHITE_SPACE (p);
5379 if (*p == '\n' || *p != '\"')
5380 return 0;
5381
5382 fname = p + 1;
5383 p = (char *) strchr (fname, '\"');
abd7f895 5384 fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
ac0860d8 5385
5386 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
5387 {
5388 inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
5389 inc_fname = (inc_fname != NULL)
5390 ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
5391
5392 if ((inc_fname != NULL)
abd7f895 5393 && (strncmp (inc_fname, fname, fname_len) == 0))
ac0860d8 5394 {
5395 cpp_setLocation (pfile);
5396
5397 ppllerror (message ("`#pragma implementation' for `%s' appears "
5398 "after file is included",
5399 cstring_fromChars (fname)));
5400 }
5401 }
5402 }
5403
5404 return 0;
5405}
5406
5407/*
5408 * handle #if command by
5409 * 1) inserting special `defined' keyword into the hash table
5410 * that gets turned into 0 or 1 by special_symbol (thus,
5411 * if the luser has a symbol called `defined' already, it won't
5412 * work inside the #if command)
5413 * 2) rescan the input into a temporary output buffer
5414 * 3) pass the output buffer to the yacc parser and collect a value
5415 * 4) clean up the mess left from steps 1 and 2.
5416 * 5) call conditional_skip to skip til the next #endif (etc.),
5417 * or not, depending on the value from step 3.
5418 */
5419
5420static int
5421do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5422 char *buf, char *limit)
5423{
3e3ec469 5424 HOST_WIDE_INT value;
5425 DPRINTF (("Do if: %s", buf));
5426 value = eval_if_expression (pfile, buf, limit - buf);
ac0860d8 5427 conditional_skip (pfile, value == 0, T_IF, NULL);
5428 return 0;
5429}
5430
5431/*
5432 * handle a #elif directive by not changing if_stack either.
5433 * see the comment above do_else.
5434 */
5435
5436static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5437 char *buf, char *limit)
5438{
abd7f895 5439 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5440 {
5441 cppReader_errorLit (pfile,
5442 cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
5443 return 0;
5444 }
5445 else
5446 {
5447 llassert (pfile->if_stack != NULL);
5448
5449 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5450 {
5451 cppReader_errorLit (pfile,
5452 cstring_makeLiteralTemp ("`#elif' after `#else'"));
5453
5454 if (pfile->if_stack->fname != NULL
abd7f895 5455 && cppReader_getBufferSafe (pfile)->fname != NULL
ac0860d8 5456 && !cstring_equal (pfile->if_stack->fname,
abd7f895 5457 cppReader_getBufferSafe (pfile)->nominal_fname))
ac0860d8 5458 fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
5459 fprintf (stderr, ")\n");
5460 }
5461 pfile->if_stack->type = T_ELIF;
5462 }
5463
5464 if (pfile->if_stack->if_succeeded)
5465 {
5466 skip_if_group (pfile, 0);
5467 }
5468 else
5469 {
5470 HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
5471 if (value == 0)
5472 skip_if_group (pfile, 0);
5473 else
5474 {
5475 ++pfile->if_stack->if_succeeded; /* continue processing input */
5476 output_line_command (pfile, 1, same_file);
5477 }
5478 }
5479
5480 return 0;
5481}
5482
5483/*
5484 * evaluate a #if expression in BUF, of length LENGTH,
5485 * then parse the result as a C expression and return the value as an int.
5486 */
5487
5488static HOST_WIDE_INT
5489eval_if_expression (cppReader *pfile,
5490 /*@unused@*/ char *buf,
5491 /*@unused@*/ int length)
5492{
5493 hashNode save_defined;
5494 HOST_WIDE_INT value;
3e3ec469 5495 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5496
3e3ec469 5497 DPRINTF (("Saving defined..."));
5498 save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
ac0860d8 5499 pfile->pcp_inside_if = 1;
5500
5501 value = cppReader_parseExpression (pfile);
5502 pfile->pcp_inside_if = 0;
5503
5504 /* Clean up special symbol */
3e3ec469 5505 DPRINTF (("Removing defined..."));
ac0860d8 5506 cppReader_deleteMacro (save_defined);
ac0860d8 5507 cppReader_setWritten (pfile, old_written); /* Pop */
5508
5509 return value;
5510}
5511
5512/*
5513 * routine to handle ifdef/ifndef. Try to look up the symbol,
5514 * then do or don't skip to the #endif/#else/#elif depending
5515 * on what directive is actually being processed.
5516 */
5517
5518static int
5519do_xifdef (cppReader *pfile, struct directive *keyword,
5520 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
5521{
5522 int skip;
abd7f895 5523 cppBuffer *ip = cppReader_getBufferSafe (pfile);
ac0860d8 5524 char *ident;
abd7f895 5525 size_t ident_length;
ac0860d8 5526 enum cpp_token token;
5527 int start_of_file = 0;
5528 char *control_macro = 0;
3e3ec469 5529 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5530
5531 DPRINTF (("do xifdef: %d",
5532 keyword->type == T_IFNDEF));
5533
5534 /* Detect a #ifndef at start of file (not counting comments). */
5535 if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
5536 {
5537 start_of_file = pfile->only_seen_white == 2;
5538 }
5539
5540 pfile->no_macro_expand++;
5541 token = get_directive_token (pfile);
5542 pfile->no_macro_expand--;
5543
5544 ident = pfile->token_buffer + old_written;
3e3ec469 5545 DPRINTF (("Ident: %s", ident));
5546
abd7f895 5547 ident_length = cpplib_getWritten (pfile) - old_written;
ac0860d8 5548 cppReader_setWritten (pfile, old_written); /* Pop */
5549
5550 if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
5551 {
5552 skip = (keyword->type == T_IFDEF);
5553 if (! cppReader_isTraditional (pfile))
5554 {
5555 cppReader_pedwarn (pfile,
3e3ec469 5556 message ("`#%s' with no argument", keyword->name));
ac0860d8 5557 }
5558 }
5559 else if (token == CPP_NAME)
5560 {
abd7f895 5561 hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1);
3e3ec469 5562
abd7f895 5563 skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
3e3ec469 5564
abd7f895 5565 DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
3e3ec469 5566
ac0860d8 5567 if (start_of_file && !skip)
5568 {
5569 DPRINTF (("Not skipping!"));
e5081f8c 5570 control_macro = (char *) dmalloc (ident_length + 1);
5571 memcpy (control_macro, ident, ident_length + 1);
ac0860d8 5572 }
5573 }
5574 else
5575 {
5576 skip = (keyword->type == T_IFDEF);
5577 if (! cppReader_isTraditional (pfile))
5578 {
5579 cppReader_error (pfile,
5580 message ("`#%s' with invalid argument", keyword->name));
5581 }
5582 }
5583
5584 if (!cppReader_isTraditional (pfile))
5585 {
5586 int c;
5587 cppSkipHspace (pfile);
5588 c = cppReader_peekC (pfile);
5589 if (c != EOF && c != '\n')
5590 {
5591 cppReader_pedwarn (pfile,
5592 message ("garbage at end of `#%s' argument", keyword->name));
5593 }
5594 }
5595
5596 cppReader_skipRestOfLine (pfile);
5597
5598 DPRINTF (("Conditional skip: %d", skip));
5599 conditional_skip (pfile, skip, T_IF, control_macro);
5600 return 0;
5601}
5602
5603/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
5604 If this is a #ifndef starting at the beginning of a file,
5605 CONTROL_MACRO is the macro name tested by the #ifndef.
5606 Otherwise, CONTROL_MACRO is 0. */
5607
5608static void
5609conditional_skip (cppReader *pfile, int skip,
5610 enum node_type type,
5611 /*@dependent@*/ char *control_macro)
5612{
5613 cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5614
abd7f895 5615 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 5616 temp->next = pfile->if_stack;
5617 temp->control_macro = control_macro;
5618 temp->lineno = 0;
5619 temp->if_succeeded = 0;
5620
5621 pfile->if_stack = temp;
5622 pfile->if_stack->type = type;
5623
5624 if (skip != 0)
5625 {
5626 skip_if_group (pfile, 0);
5627 return;
5628 }
5629 else
5630 {
5631 ++pfile->if_stack->if_succeeded;
5632 output_line_command (pfile, 1, same_file);
5633 }
5634}
5635
5636/*
5637 * skip to #endif, #else, or #elif. adjust line numbers, etc.
5638 * leaves input ptr at the sharp sign found.
5639 * If ANY is nonzero, return at next directive of any sort.
5640 */
5641
5642static void
5643skip_if_group (cppReader *pfile, int any)
5644{
5645 int c;
5646 struct directive *kt;
5647 cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
5648 register int ident_length;
5649 char *ident;
5650 struct parse_marker line_start_mark;
5651
5652 parseSetMark (&line_start_mark, pfile);
5653
5654 if (CPPOPTIONS (pfile)->output_conditionals) {
5655 static char failed[] = "#failed\n";
5656 cppReader_puts (pfile, failed, sizeof(failed)-1);
5657 pfile->lineno++;
5658 output_line_command (pfile, 1, same_file);
5659 }
5660
5661beg_of_line:
5662 if (CPPOPTIONS (pfile)->output_conditionals)
5663 {
abd7f895 5664 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 5665 char *start_line;
5666
5667 llassert (pbuf->buf != NULL);
5668
5669 start_line = pbuf->buf + line_start_mark.position;
5670 cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
5671 }
5672
5673 parseMoveMark (&line_start_mark, pfile);
5674
5675 if (!cppReader_isTraditional (pfile))
5676 {
5677 cppSkipHspace (pfile);
5678 }
5679
5680 c = cppReader_getC (pfile);
5681 if (c == '#')
5682 {
3e3ec469 5683 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5684 cppSkipHspace (pfile);
5685
5686 parse_name (pfile, cppReader_getC (pfile));
3e3ec469 5687 ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
ac0860d8 5688 ident = pfile->token_buffer + old_written;
5689 pfile->limit = ident;
5690
5691 for (kt = directive_table; kt->length >= 0; kt++)
5692 {
5693 cppIfStackFrame *temp;
5694 if (ident_length == kt->length
5695 && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
5696 {
5697 /* If we are asked to return on next directive, do so now. */
5698 if (any)
5699 {
5700 goto done;
5701 }
5702
5703 switch (kt->type)
5704 {
5705 case T_IF:
5706 case T_IFDEF:
5707 case T_IFNDEF:
5708 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5709 temp->next = pfile->if_stack;
abd7f895 5710 temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 5711 temp->type = kt->type;
5712 temp->lineno = 0;
5713 temp->if_succeeded = 0;
5714 temp->control_macro = NULL;
5715
5716 pfile->if_stack = temp;
5717 /*@switchbreak@*/ break;
5718 case T_ELSE:
5719 case T_ENDIF:
5720 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
5721 validate_else (pfile,
5722 cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
5723 /*@fallthrough@*/
5724 case T_ELIF:
abd7f895 5725 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5726 {
5727 cppReader_error (pfile,
5728 message ("Preprocessor command #%s is not within a conditional", kt->name));
5729 /*@switchbreak@*/ break;
5730 }
5731 else if (pfile->if_stack == save_if_stack)
5732 {
5733 goto done; /* found what we came for */
5734 }
5735 else
5736 {
5737 ;
5738 }
5739
5740 if (kt->type != T_ENDIF)
5741 {
5742 llassert (pfile->if_stack != NULL);
5743
5744 if (pfile->if_stack->type == T_ELSE)
5745 {
5746 cppReader_errorLit (pfile,
5747 cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
5748 }
5749
5750 pfile->if_stack->type = kt->type;
5751 /*@switchbreak@*/ break;
5752 }
5753
5754 temp = pfile->if_stack;
5755 llassert (temp != NULL);
5756 pfile->if_stack = temp->next;
5757 sfree (temp);
5758 /*@switchbreak@*/ break;
5759 default: ;
5760 /*@-branchstate@*/
9622303f 5761#if defined (OS2) && defined (__IBMC__)
5762 /* Dummy code to eleminate optimization problems with icc */
5763 c = 0;
5764# endif
5765
ac0860d8 5766 }
5767 /*@=branchstate@*/
5768 break;
5769 }
5770
5771 /* Don't let erroneous code go by. */
5772
5773 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
5774 && cppReader_isPedantic (pfile))
5775 {
5776 cppReader_pedwarnLit (pfile,
5777 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
5778 }
5779 }
5780
5781 c = cppReader_getC (pfile);
5782 }
5783 /* We're in the middle of a line. Skip the rest of it. */
5784 for (;;) {
5785 size_t old;
5786
5787 switch (c)
5788 {
5789 case EOF:
5790 goto done;
5791 case '/': /* possible comment */
5792 c = skip_comment (pfile, NULL);
5793 if (c == EOF)
5794 goto done;
5795 /*@switchbreak@*/ break;
5796 case '\"':
5797 case '\'':
5798 cppReader_forward (pfile, -1);
3e3ec469 5799 old = cpplib_getWritten (pfile);
5800 (void) cpplib_getToken (pfile);
ac0860d8 5801 cppReader_setWritten (pfile, old);
5802 /*@switchbreak@*/ break;
5803 case '\\':
5804 /* Char after backslash loses its special meaning. */
5805 if (cppReader_peekC (pfile) == '\n')
5806 {
5807 cppReader_forward (pfile, 1);
5808 }
5809
5810 /*@switchbreak@*/ break;
5811 case '\n':
5812 goto beg_of_line;
5813 }
5814 c = cppReader_getC (pfile);
5815 }
5816done:
5817 if (CPPOPTIONS (pfile)->output_conditionals) {
5818 static char end_failed[] = "#endfailed\n";
5819 cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
5820 pfile->lineno++;
5821 }
5822 pfile->only_seen_white = 1;
5823
5824 parseGotoMark (&line_start_mark, pfile);
5825 parseClearMark (&line_start_mark);
5826}
5827
5828/*
5829 * handle a #else directive. Do this by just continuing processing
5830 * without changing if_stack ; this is so that the error message
5831 * for missing #endif's etc. will point to the original #if. It
5832 * is possible that something different would be better.
5833 */
5834
5835static int
5836do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5837 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5838{
5839 if (cppReader_isPedantic (pfile))
5840 {
5841 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5842 }
5843
5844 cppReader_skipRestOfLine (pfile);
5845
abd7f895 5846 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
ac0860d8 5847 cppReader_errorLit (pfile,
5848 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5849 return 0;
5850 } else {
5851 /* #ifndef can't have its special treatment for containing the whole file
5852 if it has a #else clause. */
5853
5854 llassert (pfile->if_stack != NULL);
5855
5856 pfile->if_stack->control_macro = 0;
5857
5858 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5859 {
5860 cpp_setLocation (pfile);
5861 genppllerrorhint (FLG_PREPROC,
5862 message ("Pre-processor directive #else after #else"),
5863 message ("%q: Location of match",
5864 fileloc_unparseRaw (pfile->if_stack->fname,
5865 pfile->if_stack->lineno)));
5866 }
5867
5868 pfile->if_stack->type = T_ELSE;
5869 }
5870
5871 if (pfile->if_stack->if_succeeded)
5872 skip_if_group (pfile, 0);
5873 else {
5874 ++pfile->if_stack->if_succeeded; /* continue processing input */
5875 output_line_command (pfile, 1, same_file);
5876 }
5877
5878 return 0;
5879}
5880
5881/*
5882 * unstack after #endif command
5883 */
5884
5885static int
5886do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5887 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5888{
5889 if (cppReader_isPedantic (pfile))
5890 {
5891 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5892 }
5893
5894 cppReader_skipRestOfLine (pfile);
5895
abd7f895 5896 if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
ac0860d8 5897 {
5898 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5899 }
5900 else
5901 {
5902 cppIfStackFrame *temp = pfile->if_stack;
5903
5904 llassert (temp != NULL);
5905
5906 pfile->if_stack = temp->next;
5907 if (temp->control_macro != 0)
5908 {
5909 /* This #endif matched a #ifndef at the start of the file.
5910 See if it is at the end of the file. */
5911 struct parse_marker start_mark;
5912 int c;
5913
5914 parseSetMark (&start_mark, pfile);
5915
5916 for (;;)
5917 {
5918 cppSkipHspace (pfile);
5919 c = cppReader_getC (pfile);
5920
5921 if (c != '\n')
5922 break;
5923 }
5924
5925 parseGotoMark (&start_mark, pfile);
5926 parseClearMark (&start_mark);
5927
5928 if (c == EOF)
5929 {
5930 /* If we get here, this #endif ends a #ifndef
5931 that contains all of the file (aside from whitespace).
5932 Arrange not to include the file again
5933 if the macro that was tested is defined.
5934
5935 Do not do this for the top-level file in a -include or any
5936 file in a -imacros. */
5937 struct file_name_list *ifile = pfile->all_include_files;
5938
5939 for ( ; ifile != NULL; ifile = ifile->next)
5940 {
abd7f895 5941 if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
ac0860d8 5942 {
5943 ifile->control_macro = temp->control_macro;
5944 break;
5945 }
5946 }
5947 }
5948 }
5949
5950 sfree (temp);
5951 output_line_command (pfile, 1, same_file);
5952 }
5953 return 0;
5954}
5955
5956/* When an #else or #endif is found while skipping failed conditional,
5957 if -pedantic was specified, this is called to warn about text after
5958 the command name. P points to the first char after the command name. */
5959
5960static void
5961validate_else (cppReader *pfile, cstring directive)
5962{
5963 int c;
5964 cppSkipHspace (pfile);
5965 c = cppReader_peekC (pfile);
5966 if (c != EOF && c != '\n')
5967 {
5968 cppReader_pedwarn (pfile,
5969 message ("text following `%s' violates ANSI standard", directive));
5970 }
5971}
5972
5973/*
5974** Get the next token, and add it to the text in pfile->token_buffer.
5975** Return the kind of token we got.
5976*/
5977
5978enum cpp_token
3e3ec469 5979cpplib_getToken (cppReader *pfile)
5980{
5981 return cpplib_getTokenAux (pfile, FALSE);
5982}
5983
5984enum cpp_token
5985cpplib_getTokenForceExpand (cppReader *pfile)
5986{
5987 return cpplib_getTokenAux (pfile, TRUE);
5988}
5989
5990enum cpp_token
5991cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
ac0860d8 5992{
5993 int c, c2, c3;
5994 size_t old_written = 0;
5995 int start_line, start_column;
5996 enum cpp_token token;
5997 struct cppOptions *opts = CPPOPTIONS (pfile);
abd7f895 5998 cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
ac0860d8 5999
6000get_next:
6001 c = cppReader_getC (pfile);
3e3ec469 6002 DPRINTF (("Get next token: %c", c));
ac0860d8 6003
6004 if (c == EOF)
6005 {
6006 handle_eof:
abd7f895 6007 if (cppReader_getBufferSafe (pfile)->seen_eof)
ac0860d8 6008 {
6009 cppBuffer *buf = cppReader_popBuffer (pfile);
6010
6011 if (buf != cppReader_nullBuffer (pfile))
6012 {
6013 goto get_next;
6014 }
6015 else
6016 {
6017 return CPP_EOF;
6018 }
6019 }
6020 else
6021 {
abd7f895 6022 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6023 cppReader_getBufferSafe (pfile)->seen_eof = 1;
ac0860d8 6024
abd7f895 6025 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
ac0860d8 6026 && next_buf != cppReader_nullBuffer (pfile))
6027 {
6028 /* We're about to return from an #include file.
6029 Emit #line information now (as part of the CPP_POP) result.
6030 But the #line refers to the file we will pop to. */
6031 cppBuffer *cur_buffer = CPPBUFFER (pfile);
6032 CPPBUFFER (pfile) = next_buf;
6033 pfile->input_stack_listing_current = 0;
6034 output_line_command (pfile, 0, leave_file);
6035 CPPBUFFER (pfile) = cur_buffer;
6036 }
6037 return CPP_POP;
6038 }
6039 }
6040 else
6041 {
6042 long newlines;
6043 struct parse_marker start_mark;
6044
6045 switch (c)
6046 {
6047 case '/':
6048 if (cppReader_peekC (pfile) == '=')
6049 {
6050 goto op2;
6051 }
6052
6053 if (opts->put_out_comments)
6054 {
6055 parseSetMark (&start_mark, pfile);
6056 }
6057
6058 newlines = 0;
80489f0a 6059 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
ac0860d8 6060 &start_line, &start_column);
6061 c = skip_comment (pfile, &newlines);
ce7034f0 6062 DPRINTF (("c = %c", c));
ac0860d8 6063 if (opts->put_out_comments && (c == '/' || c == EOF))
6064 {
6065 assertSet (&start_mark);
6066 parseClearMark (&start_mark);
6067 }
6068
6069 if (c == '/')
6070 goto randomchar;
6071 if (c == EOF)
6072 {
6073 cppReader_errorWithLine (pfile, start_line, start_column,
6074 cstring_makeLiteral ("Unterminated comment"));
6075 goto handle_eof;
6076 }
6077 c = '/'; /* Initial letter of comment. */
6078 return_comment:
6079 /* Comments are equivalent to spaces.
6080 For -traditional, a comment is equivalent to nothing. */
6081
6082 if (opts->put_out_comments)
6083 {
6084 enum cpp_token res;
6085
6086 assertSet (&start_mark);
6087 res = cpp_handleComment (pfile, &start_mark);
6088 pfile->lineno += newlines;
6089 return res;
6090 }
6091 else if (cppReader_isTraditional (pfile))
6092 {
6093 return CPP_COMMENT;
6094 }
6095 else
6096 {
3e3ec469 6097 cpplib_reserve(pfile, 1);
ac0860d8 6098 cppReader_putCharQ (pfile, ' ');
6099 return CPP_HSPACE;
6100 }
6101
6102 case '#':
6103 if (!pfile->only_seen_white)
6104 {
6105 goto randomchar;
6106 }
6107
6108 if (cppReader_handleDirective (pfile))
6109 {
6110 return CPP_DIRECTIVE;
6111 }
6112
6113 pfile->only_seen_white = 0;
6114 return CPP_OTHER;
6115
6116 case '\"':
6117 case '\'':
6118 /* A single quoted string is treated like a double -- some
6119 programs (e.g., troff) are perverse this way */
80489f0a 6120 cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
6121 &start_line, &start_column);
3e3ec469 6122 old_written = cpplib_getWritten (pfile);
ac0860d8 6123 string:
c09ebffe 6124 DPRINTF (("Reading string: %c", c));
ac0860d8 6125 cppReader_putChar (pfile, c);
6126 while (TRUE)
6127 {
c09ebffe 6128 /* evans-2003-06-07
6129 ** Because of ISO8859-1 characters in string literals, we need a special test here.
6130 */
6131
6132 if (cppReader_reachedEOF (pfile))
ac0860d8 6133 {
c09ebffe 6134
6135 DPRINTF (("Matches EOF!"));
ac0860d8 6136 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
6137 {
6138 /* try harder: this string crosses a macro expansion
6139 boundary. This can happen naturally if -traditional.
6140 Otherwise, only -D can make a macro with an unmatched
6141 quote. */
6142 cppBuffer *next_buf
abd7f895 6143 = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6144 (*cppReader_getBufferSafe (pfile)->cleanup)
6145 (cppReader_getBufferSafe (pfile), pfile);
ac0860d8 6146 CPPBUFFER (pfile) = next_buf;
6147 continue;
6148 }
c09ebffe 6149
ac0860d8 6150 if (!cppReader_isTraditional (pfile))
6151 {
6152 cpp_setLocation (pfile);
6153
6154 setLine (long_toInt (start_line));
6155 setColumn (long_toInt (start_column));
c09ebffe 6156
ac0860d8 6157 if (pfile->multiline_string_line != long_toInt (start_line)
6158 && pfile->multiline_string_line != 0)
6159 {
6160 genppllerrorhint
6161 (FLG_PREPROC,
6162 message ("Unterminated string or character constant"),
6163 message ("%q: Possible real start of unterminated constant",
6164 fileloc_unparseRaw
6165 (fileloc_filename (g_currentloc),
6166 pfile->multiline_string_line)));
6167 pfile->multiline_string_line = 0;
6168 }
6169 else
6170 {
6171 genppllerror
6172 (FLG_PREPROC,
6173 message ("Unterminated string or character constant"));
6174 }
6175 }
c09ebffe 6176 /*@loopbreak@*/ break;
6177 }
6178 else
ac0860d8 6179 {
c09ebffe 6180 int cc = cppReader_getC (pfile);
6181 DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF));
6182 DPRINTF (("putting char: %c", cc));
6183 cppReader_putChar (pfile, cc);
6184 switch (cc)
ac0860d8 6185 {
c09ebffe 6186 case '\n':
6187 /* Traditionally, end of line ends a string constant with
6188 no error. So exit the loop and record the new line. */
6189 if (cppReader_isTraditional (pfile))
6190 goto while2end;
6191 if (c == '\'')
6192 {
6193 goto while2end;
6194 }
6195 if (cppReader_isPedantic (pfile)
6196 && pfile->multiline_string_line == 0)
6197 {
6198 cppReader_pedwarnWithLine
6199 (pfile, long_toInt (start_line),
6200 long_toInt (start_column),
6201 cstring_makeLiteral ("String constant runs past end of line"));
6202 }
6203 if (pfile->multiline_string_line == 0)
6204 {
6205 pfile->multiline_string_line = start_line;
6206 }
6207
6208 /*@switchbreak@*/ break;
6209
6210 case '\\':
6211 cc = cppReader_getC (pfile);
6212 if (cc == '\n')
6213 {
6214 /* Backslash newline is replaced by nothing at all. */
419f7a7a 6215 pfile->lineno++; /* 2003-11-03: AMiller suggested adding this, but
6216 its not clear why it is needed. */
c09ebffe 6217 cppReader_adjustWritten (pfile, -1);
6218 pfile->lineno++;
6219 }
6220 else
6221 {
6222 /* ANSI stupidly requires that in \\ the second \
6223 is *not* prevented from combining with a newline. */
6224 NEWLINE_FIX1(cc);
6225 if (cc != EOF)
6226 cppReader_putChar (pfile, cc);
6227 }
6228 /*@switchbreak@*/ break;
6229
6230 case '\"':
6231 case '\'':
6232 if (cc == c)
6233 goto while2end;
6234 /*@switchbreak@*/ break;
ac0860d8 6235 }
ac0860d8 6236 }
6237 }
6238 while2end:
6239 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
3e3ec469 6240 cpplib_getPWritten (pfile));
ac0860d8 6241 pfile->only_seen_white = 0;
6242 return c == '\'' ? CPP_CHAR : CPP_STRING;
6243
6244 case '$':
6245 if (!opts->dollars_in_ident)
6246 goto randomchar;
6247 goto letter;
6248
6249 case ':':
6250 if (opts->cplusplus && cppReader_peekC (pfile) == ':')
6251 goto op2;
6252 goto randomchar;
6253
6254 case '&':
6255 case '+':
6256 case '|':
6257 NEWLINE_FIX;
6258 c2 = cppReader_peekC (pfile);
6259 if (c2 == c || c2 == '=')
6260 goto op2;
6261 goto randomchar;
6262
6263 case '*':
6264 case '!':
6265 case '%':
6266 case '=':
6267 case '^':
6268 NEWLINE_FIX;
6269 if (cppReader_peekC (pfile) == '=')
6270 goto op2;
6271 goto randomchar;
6272
6273 case '-':
6274 NEWLINE_FIX;
6275 c2 = cppReader_peekC (pfile);
6276 if (c2 == '-' && opts->chill)
6277 {
6278 /* Chill style comment */
6279 if (opts->put_out_comments)
6280 {
6281 parseSetMark (&start_mark, pfile);
6282 }
6283
6284 cppReader_forward (pfile, 1); /* Skip second '-'. */
6285
6286 for (;;)
6287 {
6288 c = cppReader_getC (pfile);
6289 if (c == EOF)
6290 /*@loopbreak@*/ break;
6291 if (c == '\n')
6292 {
6293 /* Don't consider final '\n' to be part of comment. */
6294 cppReader_forward (pfile, -1);
6295 /*@loopbreak@*/ break;
6296 }
6297 }
6298 c = '-';
6299 goto return_comment;
6300 }
6301 if (c2 == '-' || c2 == '=' || c2 == '>')
6302 goto op2;
6303 goto randomchar;
6304
6305 case '<':
6306 if (pfile->parsing_include_directive)
6307 {
6308 for (;;)
6309 {
6310 cppReader_putChar (pfile, c);
6311 if (c == '>')
6312 /*@loopbreak@*/ break;
6313 c = cppReader_getC (pfile);
6314 NEWLINE_FIX1 (c);
6315 if (c == '\n' || c == EOF)
6316 {
6317 cppReader_errorLit (pfile,
6318 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
6319 /*@loopbreak@*/ break;
6320 }
6321 }
6322 return CPP_STRING;
6323 }
6324 /*@fallthrough@*/
6325 case '>':
6326 NEWLINE_FIX;
6327 c2 = cppReader_peekC (pfile);
6328 if (c2 == '=')
6329 goto op2;
6330 if (c2 != c)
6331 goto randomchar;
6332 cppReader_forward (pfile, 1);
3e3ec469 6333 cpplib_reserve (pfile, 4);
ac0860d8 6334 cppReader_putChar (pfile, c);
6335 cppReader_putChar (pfile, c2);
6336 NEWLINE_FIX;
6337 c3 = cppReader_peekC (pfile);
6338 if (c3 == '=')
6339 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6340 cppReader_nullTerminateQ (pfile);
6341 pfile->only_seen_white = 0;
6342 return CPP_OTHER;
6343
6344 case '@':
ce7034f0 6345 DPRINTF (("Macro @!"));
abd7f895 6346 if (cppReader_getBufferSafe (pfile)->has_escapes)
ac0860d8 6347 {
6348 c = cppReader_getC (pfile);
ce7034f0 6349 DPRINTF (("got c: %c", c));
ac0860d8 6350 if (c == '-')
6351 {
6352 if (pfile->output_escapes)
6353 cppReader_puts (pfile, "@-", 2);
6354 parse_name (pfile, cppReader_getC (pfile));
6355 return CPP_NAME;
6356 }
6357 else if (is_space [c])
6358 {
3e3ec469 6359 cpplib_reserve (pfile, 2);
ac0860d8 6360 if (pfile->output_escapes)
6361 cppReader_putCharQ (pfile, '@');
6362 cppReader_putCharQ (pfile, c);
6363 return CPP_HSPACE;
6364 }
6365 else
6366 {
6367 ;
6368 }
6369 }
6370 if (pfile->output_escapes)
6371 {
6372 cppReader_puts (pfile, "@@", 2);
6373 return CPP_OTHER;
6374 }
6375 goto randomchar;
6376 case '.':
6377 NEWLINE_FIX;
6378 c2 = cppReader_peekC (pfile);
6379 if (isdigit(c2))
6380 {
3e3ec469 6381 cpplib_reserve(pfile, 2);
ac0860d8 6382 cppReader_putCharQ (pfile, '.');
6383 c = cppReader_getC (pfile);
6384 goto number;
6385 }
6386
6387 /* FIXME - misses the case "..\\\n." */
6388 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
6389 {
3e3ec469 6390 cpplib_reserve(pfile, 4);
ac0860d8 6391 cppReader_putCharQ (pfile, '.');
6392 cppReader_putCharQ (pfile, '.');
6393 cppReader_putCharQ (pfile, '.');
6394 cppReader_forward (pfile, 2);
6395 cppReader_nullTerminateQ (pfile);
6396 pfile->only_seen_white = 0;
6397 return CPP_3DOTS;
6398 }
6399 goto randomchar;
6400 op2:
6401 token = CPP_OTHER;
6402 pfile->only_seen_white = 0;
f4e355aa 6403 op2any: /* jumped to for \ continuations */
3e3ec469 6404 cpplib_reserve(pfile, 3);
ac0860d8 6405 cppReader_putCharQ (pfile, c);
f4e355aa 6406
6407 /* evans 2003-08-24: This is a hack to fix line output for \
6408 continuations. Someday I really should get a decent pre-processor!
6409 */
6410
6411 if (c == '\\') {
6412 (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */
6413 } else {
6414 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6415 }
6416
ac0860d8 6417 cppReader_nullTerminateQ (pfile);
6418 return token;
6419
6420 case 'L':
6421 NEWLINE_FIX;
6422 c2 = cppReader_peekC (pfile);
6423 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6424 {
6425 cppReader_putChar (pfile, c);
6426 c = cppReader_getC (pfile);
6427 goto string;
6428 }
6429 goto letter;
6430
6431 case '0': case '1': case '2': case '3': case '4':
6432 case '5': case '6': case '7': case '8': case '9':
6433 number:
6434 c2 = '.';
6435 for (;;)
6436 {
3e3ec469 6437 cpplib_reserve (pfile, 2);
ac0860d8 6438 cppReader_putCharQ (pfile, c);
6439 NEWLINE_FIX;
6440 c = cppReader_peekC (pfile);
6441 if (c == EOF)
6442 /*@loopbreak@*/ break;
6443 if (!is_idchar[c] && c != '.'
6444 && ((c2 != 'e' && c2 != 'E'
6445 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6446 || (c != '+' && c != '-')))
6447 /*@loopbreak@*/ break;
6448 cppReader_forward (pfile, 1);
6449 c2= c;
6450 }
6451
6452 cppReader_nullTerminateQ (pfile);
6453 pfile->only_seen_white = 0;
6454 return CPP_NUMBER;
6455
6456 case 'b': case 'c': case 'd': case 'h': case 'o':
6457 case 'B': case 'C': case 'D': case 'H': case 'O':
6458 if (opts->chill && cppReader_peekC (pfile) == '\'')
6459 {
6460 pfile->only_seen_white = 0;
3e3ec469 6461 cpplib_reserve (pfile, 2);
ac0860d8 6462 cppReader_putCharQ (pfile, c);
6463 cppReader_putCharQ (pfile, '\'');
6464 cppReader_forward (pfile, 1);
6465 for (;;)
6466 {
6467 c = cppReader_getC (pfile);
6468 if (c == EOF)
6469 goto chill_number_eof;
6470 if (!is_idchar[c])
6471 {
6472 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6473 {
6474 cppReader_forward (pfile, 2);
6475 continue;
6476 }
6477 /*@loopbreak@*/ break;
6478 }
6479 cppReader_putChar (pfile, c);
6480 }
6481 if (c == '\'')
6482 {
3e3ec469 6483 cpplib_reserve (pfile, 2);
ac0860d8 6484 cppReader_putCharQ (pfile, c);
6485 cppReader_nullTerminateQ (pfile);
6486 return CPP_STRING;
6487 }
6488 else
6489 {
6490 cppReader_forward (pfile, -1);
6491 chill_number_eof:
6492 cppReader_nullTerminate (pfile);
6493 return CPP_NUMBER;
6494 }
6495 }
6496 else
6497 goto letter;
6498 case '_':
6499 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
6500 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
6501 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
6502 case 'x': case 'y': case 'z':
6503 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
6504 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
6505 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6506 case 'Y': case 'Z':
6507 letter:
6508 {
6509 hashNode hp;
6510 char *ident;
3e3ec469 6511 size_t before_name_written = cpplib_getWritten (pfile);
abd7f895 6512 size_t ident_len;
ac0860d8 6513 parse_name (pfile, c);
6514 pfile->only_seen_white = 0;
3e3ec469 6515
ac0860d8 6516 if (pfile->no_macro_expand)
6517 {
3e3ec469 6518 DPRINTF (("Not expanding: %s", pfile->token_buffer));
ac0860d8 6519 return CPP_NAME;
6520 }
6521
6522 ident = pfile->token_buffer + before_name_written;
3e3ec469 6523 DPRINTF (("Ident: %s", ident));
6524
abd7f895 6525 ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
ac0860d8 6526
abd7f895 6527 hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand);
ac0860d8 6528
6529 if (hp == NULL)
6530 {
3e3ec469 6531 DPRINTF (("No expand: %s %d", ident, ident_len));
ac0860d8 6532 return CPP_NAME;
6533 }
6534
6535 if (hp->type == T_DISABLED)
6536 {
3e3ec469 6537 DPRINTF (("Disabled!"));
6538
ac0860d8 6539 if (pfile->output_escapes)
6540 { /* Return "@-IDENT", followed by '\0'. */
6541 int i;
3e3ec469 6542 cpplib_reserve (pfile, 3);
ac0860d8 6543 ident = pfile->token_buffer + before_name_written;
6544 cppReader_adjustWritten (pfile, 2);
6545
abd7f895 6546 for (i = size_toInt (ident_len); i >= 0; i--)
ac0860d8 6547 {
6548 ident[i+2] = ident[i];
6549 }
6550
6551 ident[0] = '@';
6552 ident[1] = '-';
6553 }
6554 return CPP_NAME;
6555 }
6556
3e3ec469 6557 /*
6558 ** If macro wants an arglist, verify that a '(' follows.
6559 ** first skip all whitespace, copying it to the output
6560 ** after the macro name. Then, if there is no '(',
6561 ** decide this is not a macro call and leave things that way.
6562 */
6563
ac0860d8 6564 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6565 {
6566 struct parse_marker macro_mark;
6567 int is_macro_call;
6568
ce7034f0 6569 DPRINTF (("Arglist macro!"));
6570
755ee3f6 6571 /*
6572 ** evans 2002-07-03: Moved this here (from below).
6573 ** This bug caused necessary whitespace to be lost
6574 ** when parsing parameterized macros without parameters.
6575 */
6576
ce7034f0 6577 parseSetMark (&macro_mark, pfile);
6578
ac0860d8 6579 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6580 {
6581 cppBuffer *next_buf;
6582 cppSkipHspace (pfile);
6583 if (cppReader_peekC (pfile) != EOF)
6584 {
ce7034f0 6585 DPRINTF (("Peeking!"));
ac0860d8 6586 /*@loopbreak@*/ break;
6587 }
6588
abd7f895 6589 next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6590 (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
ac0860d8 6591 CPPBUFFER (pfile) = next_buf;
6592 }
6593
ce7034f0 6594 /* parseSetMark (&macro_mark, pfile); */
ac0860d8 6595
6596 for (;;)
6597 {
6598 cppSkipHspace (pfile);
6599 c = cppReader_peekC (pfile);
ce7034f0 6600 DPRINTF (("c: %c", c));
ac0860d8 6601 is_macro_call = c == '(';
6602 if (c != '\n')
6603 /*@loopbreak@*/ break;
6604 cppReader_forward (pfile, 1);
6605 }
6606
6607 if (!is_macro_call)
6608 {
6609 parseGotoMark (&macro_mark, pfile);
6610 }
6611
6612 parseClearMark (&macro_mark);
6613
6614 if (!is_macro_call)
6615 {
ce7034f0 6616 DPRINTF (("not macro call!"));
ac0860d8 6617 return CPP_NAME;
6618 }
6619 }
ce7034f0 6620
ac0860d8 6621 /* This is now known to be a macro call. */
6622
6623 /* it might not actually be a macro. */
6624 if (hp->type != T_MACRO)
6625 {
6626 size_t xbuf_len;
6627 char *xbuf;
6628
6629 cppReader_setWritten (pfile, before_name_written);
6630 special_symbol (hp, pfile);
3e3ec469 6631 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
ac0860d8 6632 xbuf = (char *) dmalloc (xbuf_len + 1);
6633 cppReader_setWritten (pfile, before_name_written);
3e3ec469 6634 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
ac0860d8 6635 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6636 }
6637 else
6638 {
3e3ec469 6639 /*
6640 ** Expand the macro, reading arguments as needed,
6641 ** and push the expansion on the input stack.
6642 */
6643
6644 cpplib_macroExpand (pfile, hp);
ac0860d8 6645 cppReader_setWritten (pfile, before_name_written);
6646 }
6647
6648 /* An extra "@ " is added to the end of a macro expansion
6649 to prevent accidental token pasting. We prefer to avoid
6650 unneeded extra spaces (for the sake of cpp-using tools like
6651 imake). Here we remove the space if it is safe to do so. */
6652
6653 llassert (pfile->buffer->rlimit != NULL);
6654
6655 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6656 && pfile->buffer->rlimit[-2] == '@'
6657 && pfile->buffer->rlimit[-1] == ' ')
6658 {
6659 int c1 = pfile->buffer->rlimit[-3];
3e3ec469 6660 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
ac0860d8 6661
6662 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6663 pfile->buffer->rlimit -= 2;
6664 }
6665 }
6666 goto get_next;
6667
6668
6669 case ' ': case '\t': case '\v': case '\r':
6670 for (;;)
6671 {
6672 cppReader_putChar (pfile, c);
6673 c = cppReader_peekC (pfile);
6674 if (c == EOF || !is_hor_space[c])
6675 /*@loopbreak@*/ break;
6676 cppReader_forward (pfile, 1);
6677 }
6678 return CPP_HSPACE;
6679
6680 case '\\':
6681 c2 = cppReader_peekC (pfile);
f9e62f40 6682 /* allow other stuff here if a flag is set? */
f4e355aa 6683 DPRINTF (("Got continuation!"));
ac0860d8 6684 if (c2 != '\n')
6685 goto randomchar;
6686 token = CPP_HSPACE;
6687 goto op2any;
6688
6689 case '\n':
6690 cppReader_putChar (pfile, c);
6691 if (pfile->only_seen_white == 0)
6692 pfile->only_seen_white = 1;
6693 pfile->lineno++;
6694 output_line_command (pfile, 1, same_file);
6695 return CPP_VSPACE;
6696
6697 case '(': token = CPP_LPAREN; goto char1;
6698 case ')': token = CPP_RPAREN; goto char1;
6699 case '{': token = CPP_LBRACE; goto char1;
6700 case '}': token = CPP_RBRACE; goto char1;
6701 case ',': token = CPP_COMMA; goto char1;
6702 case ';': token = CPP_SEMICOLON; goto char1;
6703
6704 randomchar:
6705 default:
6706 token = CPP_OTHER;
6707 char1:
6708 pfile->only_seen_white = 0;
6709 cppReader_putChar (pfile, c);
6710 return token;
6711 }
6712 }
6713
6714 BADBRANCH;
6715 /*@notreached@*/
6716}
6717
6718/* Parse an identifier starting with C. */
6719
6720void
6721parse_name (cppReader *pfile, int c)
6722{
6723 for (;;)
6724 {
6725 if (!is_idchar[c])
6726 {
6727 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6728 {
6729 cppReader_forward (pfile, 2);
6730 continue;
6731 }
6732
6733 cppReader_forward (pfile, -1);
6734 break;
6735 }
6736
6737 if (c == '$' && cppReader_isPedantic (pfile))
6738 {
6739 cppReader_pedwarnLit (pfile,
6740 cstring_makeLiteralTemp ("`$' in identifier"));
6741 }
6742
3e3ec469 6743 cpplib_reserve(pfile, 2); /* One more for final NUL. */
ac0860d8 6744 cppReader_putCharQ (pfile, c);
6745 c = cppReader_getC (pfile);
6746
6747 if (c == EOF)
6748 break;
6749 }
6750
6751 cppReader_nullTerminateQ (pfile);
6752}
6753
6754/* The file_name_map structure holds a mapping of file names for a
6755 particular directory. This mapping is read from the file named
6756 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
6757 map filenames on a file system with severe filename restrictions,
6758 such as DOS. The format of the file name map file is just a series
6759 of lines with two tokens on each line. The first token is the name
6760 to map, and the second token is the actual name to use. */
6761
6762struct file_name_map
6763{
6764 struct file_name_map *map_next;
6765 cstring map_from;
6766 cstring map_to;
6767};
6768
6769/*@constant observer char *FILE_NAME_MAP_FILE*/
6770#define FILE_NAME_MAP_FILE "header.gcc"
6771
6772/* Read a space delimited string of unlimited length from a stdio
6773 file. */
6774
6775static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6776{
6777 char *alloc, *set;
6778 size_t len;
6779
6780 len = 20;
6781 set = alloc = dmalloc (len + 1);
6782
6783 if (!is_space[ch])
6784 {
6785 *set++ = ch;
6786 while ((ch = getc (f)) != EOF && ! is_space[ch])
6787 {
6788 if (set - alloc == size_toInt (len))
6789 {
6790 len *= 2;
6791 alloc = drealloc (alloc, len + 1);
6792 set = alloc + len / 2;
6793 /*@-branchstate@*/ }
6794
6795 *set++ = ch;
6796 } /*@=branchstate@*/
6797 }
6798 *set = '\0';
6799 check (ungetc (ch, f) != EOF);
6800
6801 return cstring_fromChars (alloc);
6802}
6803
6804/* This structure holds a linked list of file name maps, one per directory. */
6805
6806struct file_name_map_list
6807{
6fcd0b1e 6808 /*@only@*/ struct file_name_map_list *map_list_next;
6809 /*@only@*/ cstring map_list_name;
abd7f895 6810 /*@null@*/ struct file_name_map *map_list_map;
ac0860d8 6811};
6812
6813/* Read the file name map file for DIRNAME. */
6814
6815static struct file_name_map *
6816read_name_map (cppReader *pfile, cstring dirname)
6817{
6818 struct file_name_map_list *map_list_ptr;
6819 cstring name;
6820 FILE *f;
6821
6822 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6823 map_list_ptr != NULL;
6824 map_list_ptr = map_list_ptr->map_list_next)
6825 {
6826 if (cstring_equal (map_list_ptr->map_list_name, dirname))
6827 {
6828 return map_list_ptr->map_list_map;
6829 }
6830 }
6831
6832 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6833 map_list_ptr->map_list_name = cstring_copy (dirname);
6834 map_list_ptr->map_list_map = NULL;
6835
6836 name = cstring_copy (dirname);
6837
6838 if (cstring_length (dirname) > 0)
6839 {
6840 name = cstring_appendChar (name, CONNECTCHAR);
6841 }
6842
6843 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6844
d5047b91 6845 f = fileTable_openReadFile (context_fileTable (), name);
ac0860d8 6846 cstring_free (name);
6847
6848 if (f == NULL)
6849 {
6850 map_list_ptr->map_list_map = NULL;
6851 }
6852 else
6853 {
6854 int ch;
6855
6856 while ((ch = getc (f)) != EOF)
6857 {
6858 cstring from, to;
6859 struct file_name_map *ptr;
6860
6861 if (is_space[ch])
6862 {
6863 continue;
6864 }
6865
6866 from = read_filename_string (ch, f);
6867 while ((ch = getc (f)) != EOF && is_hor_space[ch])
6868 {
6869 ;
6870 }
6871
6872 to = read_filename_string (ch, f);
6873
6874 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6875 ptr->map_from = from;
6876
6877 /* Make the real filename absolute. */
6878 if (cstring_length (to) > 1
6879 && osd_isConnectChar (cstring_firstChar (to)))
6880 {
6881 ptr->map_to = to;
6882 }
6883 else
6884 {
6885 ptr->map_to = cstring_copy (dirname);
6886 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6887 ptr->map_to = cstring_concatFree (ptr->map_to, to);
6888 }
6889
6890 ptr->map_next = map_list_ptr->map_list_map;
6891 map_list_ptr->map_list_map = ptr;
6892
6893 while ((ch = getc (f)) != '\n')
6894 {
6895 if (ch == EOF)
6896 {
6897 /*@innerbreak@*/ break;
6898 }
6899 }
6900 }
6901
6902 assertSet (map_list_ptr->map_list_map);
6903 check (fileTable_closeFile (context_fileTable (),f) == 0);
6904 }
6905
6906 map_list_ptr->map_list_next = pfile->opts->map_list;
6907 pfile->opts->map_list = map_list_ptr;
6908
6909 return map_list_ptr->map_list_map;
6910}
6911
6912/* Try to open include file FILENAME. SEARCHPTR is the directory
6913 being tried from the include file search path. This function maps
6914 filenames on file systems based on information read by
6915 read_name_map. */
6916
6917static int
6918open_include_file (cppReader *pfile,
6919 cstring fname,
6920 struct file_name_list *searchptr)
6921{
6922 char *filename = cstring_toCharsSafe (fname);
6923 struct file_name_map *map;
6924 char *from;
6925 char *p, *dir;
6926
6927 cstring_markOwned (fname);
6928
6929 cpp_setLocation (pfile);
6930
6931 if (context_getFlag (FLG_NEVERINCLUDE))
6932 {
6933 if (isHeaderFile (fname))
6934 {
6935 return SKIP_INCLUDE;
6936 }
6937 }
6938
6939 if ((searchptr != NULL) && ! searchptr->got_name_map)
6940 {
6941 searchptr->name_map = read_name_map (pfile,
6942 !cstring_isEmpty (searchptr->fname)
6943 ? searchptr->fname :
6944 cstring_makeLiteralTemp ("."));
6945 searchptr->got_name_map = 1;
6946 }
6947
6948 /* First check the mapping for the directory we are using. */
6949
6950 if ((searchptr != NULL)
6951 && (searchptr->name_map != NULL))
6952 {
6953 from = filename;
6954
6955 if (!cstring_isEmpty (searchptr->fname))
6956 {
6957 from += cstring_length (searchptr->fname) + 1;
6958 }
6959
6960 for (map = searchptr->name_map;
6961 map != NULL;
6962 map = map->map_next)
6963 {
6964 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6965 {
6966 /*
6967 ** Found a match. Check if the file should be skipped
6968 */
6969
6970 if (cpp_skipIncludeFile (map->map_to))
6971 {
6972 return SKIP_INCLUDE;
6973 }
6974 else
6975 {
6976 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6977 }
6978 }
6979 }
6980 }
6981
6982 /*
6983 ** Try to find a mapping file for the particular directory we are
6984 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6985 ** in /usr/include/header.gcc and look up types.h in
6986 ** /usr/include/sys/header.gcc.
6987 */
6988
6989 p = strrchr (filename, CONNECTCHAR);
6990
6991 if (p == NULL)
6992 {
6993 p = filename;
6994 }
6995
6996 if ((searchptr != NULL)
6997 && (cstring_isDefined (searchptr->fname))
abd7f895 6998 && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
ac0860d8 6999 && !strncmp (cstring_toCharsSafe (searchptr->fname),
7000 filename,
7001 size_fromInt (p - filename)))
7002 {
7003 /* filename is in SEARCHPTR, which we've already checked. */
7004
7005 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7006 {
7007 return SKIP_INCLUDE;
7008 }
7009 else
7010 {
7011 return cpp_openIncludeFile (filename);
7012 }
7013 }
7014
7015 if (p == filename)
7016 {
7017 dir = mstring_copy (".");
7018 from = filename;
7019 }
7020 else
7021 {
7022 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
7023 memcpy (dir, filename, size_fromInt (p - filename));
7024 dir[p - filename] = '\0';
7025 from = p + 1;
7026 }
7027
7028 for (map = read_name_map (pfile, cstring_fromChars (dir));
7029 map != NULL;
7030 map = map->map_next)
7031 {
7032 if (cstring_equal (map->map_from, cstring_fromChars (from)))
7033 {
7034 sfree (dir);
7035
7036 if (cpp_skipIncludeFile (map->map_to))
7037 {
7038 return SKIP_INCLUDE;
7039 }
7040 else
7041 {
7042 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
7043 }
7044 }
7045 }
7046
7047 sfree (dir);
7048
7049 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7050 {
7051 return SKIP_INCLUDE;
7052 }
7053 else
7054 {
7055 return cpp_openIncludeFile (filename);
7056 }
7057}
7058
7059/* Process the contents of include file FNAME, already open on descriptor F,
7060 with output to OP.
7061 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
7062 "system" include directories (as decided by the `is_system_include'
7063 function above).
7064 DIRPTR is the link in the dir path through which this file was found,
7065 or 0 if the file name was absolute or via the current directory.
7066 Return 1 on success, 0 on failure.
7067
7068 The caller is responsible for the cppReader_pushBuffer. */
7069
7070static int
7071finclude (cppReader *pfile, int f,
7072 cstring fname,
7073 bool system_header_p,
7074 /*@dependent@*/ struct file_name_list *dirptr)
7075{
210066f9 7076 __mode_t st_mode;
ac0860d8 7077 size_t st_size;
7078 long i;
7079 int length = 0;
7080 cppBuffer *fp; /* For input stack frame */
7081
7082 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
7083 {
7084 cppReader_perrorWithName (pfile, fname);
7085 check (close (f) == 0);
7086 (void) cppReader_popBuffer (pfile);
7087 /*@-mustfree@*/
7088 return 0;
7089 /*@=mustfree@*/
7090 }
7091
abd7f895 7092 fp = cppReader_getBufferSafe (pfile);
ac0860d8 7093
7094 /*@-temptrans@*/ /* fname shouldn't really be temp */
7095 fp->nominal_fname = fp->fname = fname;
7096 /*@=temptrans@*/
7097
7098 fp->dir = dirptr;
7099 fp->system_header_p = system_header_p;
7100 fp->lineno = 1;
7101 fp->colno = 1;
7102 fp->cleanup = cppReader_fileCleanup;
7103
7104 if (S_ISREG (st_mode))
7105 {
7106 sfree (fp->buf);
7107 fp->buf = (char *) dmalloc (st_size + 2);
7108 fp->alimit = fp->buf + st_size + 2;
7109 fp->cur = fp->buf;
7110
7111 /* Read the file contents, knowing that st_size is an upper bound
7112 on the number of bytes we can read. */
7113 length = safe_read (f, fp->buf, size_toInt (st_size));
7114 fp->rlimit = fp->buf + length;
7115 if (length < 0) goto nope;
7116 }
7117 else if (S_ISDIR (st_mode))
7118 {
7119 cppReader_error (pfile,
6fcd0b1e 7120 message ("Directory specified where file is expected: %s", fname));
ac0860d8 7121 check (close (f) == 0);
7122 return 0;
7123 }
7124 else
7125 {
7126 /*
7127 ** Cannot count its file size before reading.
7128 ** First read the entire file into heap and
7129 ** copy them into buffer on stack.
7130 */
7131
7132 size_t bsize = 2000;
7133
7134 st_size = 0;
7135
7136 sfree (fp->buf);
7137 fp->buf = (char *) dmalloc (bsize + 2);
7138
7139 for (;;) {
7140 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
7141
7142 if (i < 0)
7143 goto nope; /* error! */
7144 st_size += i;
7145
7146 if (st_size != bsize)
7147 {
7148 break; /* End of file */
7149 }
7150
7151 bsize *= 2;
7152 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
7153 }
7154
7155 fp->cur = fp->buf;
7156 length = size_toInt (st_size);
7157 }
7158
7159 if ((length > 0 && fp->buf[length - 1] != '\n')
7160 /* Backslash-newline at end is not good enough. */
7161 || (length > 1 && fp->buf[length - 2] == '\\')) {
7162 fp->buf[length++] = '\n';
7163 }
7164
7165 fp->buf[length] = '\0';
7166 fp->rlimit = fp->buf + length;
7167
7168 /* Close descriptor now, so nesting does not use lots of descriptors. */
7169 check (close (f) == 0);
7170
7171 /* Must do this before calling trigraph_pcp, so that the correct file name
7172 will be printed in warning messages. */
7173
7174 pfile->input_stack_listing_current = 0;
7175 return 1;
7176
7177 nope:
7178
7179 cppReader_perrorWithName (pfile, fname);
7180 check (close (f) == 0);
7181 sfree (fp->buf);
7182 return 1;
7183}
7184
7185void
3e3ec469 7186cpplib_init (cppReader *pfile)
ac0860d8 7187{
7188 memset ((char *) pfile, 0, sizeof (*pfile));
7189
3e3ec469 7190 pfile->get_token = cpplib_getToken;
ac0860d8 7191 pfile->token_buffer_size = 200;
7192 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
7193 pfile->all_include_files = NULL;
7194
7195 assertSet (pfile);
7196
7197 cppReader_setWritten (pfile, 0);
7198
7199 pfile->system_include_depth = 0;
7200 pfile->max_include_len = 0;
7201 pfile->timebuf = NULL;
7202 pfile->only_seen_white = 1;
7203
7204 pfile->buffer = cppReader_nullBuffer (pfile);
7205}
7206
7207void
7208cppReader_finish (/*@unused@*/ cppReader *pfile)
7209{
7210 ;
7211}
7212
7213/* Free resources used by PFILE.
7214 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
7215
7216void
6fcd0b1e 7217cppCleanup (/*@special@*/ cppReader *pfile)
7218 /*@uses pfile@*/
7219 /*@releases pfile@*/
ac0860d8 7220{
6fcd0b1e 7221 DPRINTF (("cppCleanup!"));
7222
ac0860d8 7223 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
7224 {
7225 (void) cppReader_popBuffer (pfile);
7226 }
7227
7228 if (pfile->token_buffer != NULL)
7229 {
7230 sfree (pfile->token_buffer);
7231 pfile->token_buffer = NULL;
7232 }
7233
7234 while (pfile->if_stack != NULL)
7235 {
7236 cppIfStackFrame *temp = pfile->if_stack;
7237 pfile->if_stack = temp->next;
7238 sfree (temp);
7239 }
7240
7241 while (pfile->all_include_files != NULL)
7242 {
7243 struct file_name_list *temp = pfile->all_include_files;
7244 pfile->all_include_files = temp->next;
7245 /*@-dependenttrans@*/
7246 cstring_free (temp->fname);
7247 /*@=dependenttrans@*/
7248 sfree (temp);
7249 }
7250
6fcd0b1e 7251 /* evans 2002-07-12 */
7252 while (pfile->opts->map_list != NULL)
7253 {
7254 struct file_name_map_list *temp = pfile->opts->map_list;
7255 pfile->opts->map_list = pfile->opts->map_list->map_list_next;
7256 cstring_free (temp->map_list_name);
7257 sfree (temp);
7258 }
7259
7260 while (pfile->opts->include != NULL)
7261 {
7262 struct file_name_list *temp = pfile->opts->include;
7263 pfile->opts->include = pfile->opts->include->next;
7264 /* cstring_free (temp->fname); */
7265 sfree (temp);
7266 }
7267
7268 sfree (pfile->opts);
7269 pfile->opts = NULL;
ac0860d8 7270 cppReader_hashCleanup ();
7271}
7272
7273/*
7274** Get the file-mode and data size of the file open on FD
7275** and store them in *MODE_POINTER and *SIZE_POINTER.
7276*/
7277
7278static int
210066f9 7279file_size_and_mode (int fd, __mode_t *mode_pointer, size_t *size_pointer)
ac0860d8 7280{
7281 struct stat sbuf;
7282
7283 if (fstat (fd, &sbuf) < 0) {
3e3ec469 7284 *mode_pointer = 0;
7285 *size_pointer = 0;
210066f9 7286 /*@i2@*/ return (-1); /* Spurious warnings! */
ac0860d8 7287 }
7288
7289 if (mode_pointer != NULL)
7290 {
7291 *mode_pointer = sbuf.st_mode;
7292 }
7293
7294 if (size_pointer != NULL)
7295 {
7296 *size_pointer = (size_t) sbuf.st_size;
7297 }
7298
210066f9 7299 /*@i4@*/ return 0; /* spurious warnings here */
ac0860d8 7300}
7301
7302/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
7303 retrying if necessary. Return a negative value if an error occurs,
7304 otherwise return the actual number of bytes read,
7305 which must be LEN unless end-of-file was reached. */
7306
7307static int safe_read (int desc, char *ptr, int len)
7308{
7309 int left = len;
7310
7311 while (left > 0)
7312 {
7313# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
7314 /*@-compdef@*/ /* ptr is an out parameter */
7315 int nchars = _read (desc, ptr, (unsigned) left);
7316 /*@=compdef@*/
7317# else
7318 ssize_t nchars = read (desc, ptr, size_fromInt (left));
7319# endif
7320
7321 if (nchars < 0)
7322 {
7323#ifdef EINTR
7324 if (errno == EINTR)
7325 continue;
7326#endif
7327 return (int) nchars;
7328 }
7329
7330 if (nchars == 0) {
7331 break;
7332 }
7333
7334 ptr += nchars;
7335 left -= nchars;
7336 }
7337
7338 return len - left;
7339}
7340
7341/* Initialize PMARK to remember the current position of PFILE. */
7342
7343void
7344parseSetMark (struct parse_marker *pmark, cppReader *pfile)
7345{
abd7f895 7346 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7347
7348 pmark->next = pbuf->marks;
7349 /*@-temptrans@*/
7350 pbuf->marks = pmark;
7351 /*@=temptrans@*/
7352
7353 pmark->buf = pbuf;
7354 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7355 DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7356}
7357
7358/* Cleanup PMARK - we no longer need it. */
7359
7360void parseClearMark (struct parse_marker *pmark)
7361{
7362 struct parse_marker **pp = &pmark->buf->marks;
7363
7364 for (; ; pp = &(*pp)->next)
7365 {
7366 llassert (*pp != NULL);
7367 if (*pp == pmark) break;
7368 }
7369
7370 *pp = pmark->next;
7371}
7372
7373/* Backup the current position of PFILE to that saved in PMARK. */
7374
7375void
7376parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
7377{
abd7f895 7378 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7379
7380 if (pbuf != pmark->buf)
7381 {
7382 cpp_setLocation (pfile);
7383 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
7384 }
7385
7386 llassert (pbuf->buf != NULL);
7387 pbuf->cur = pbuf->buf + pmark->position;
ce7034f0 7388 DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
ac0860d8 7389}
7390
7391/* Reset PMARK to point to the current position of PFILE. (Same
7392 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
7393
7394void
7395parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
7396{
abd7f895 7397 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 7398
7399 if (pbuf != pmark->buf)
7400 {
7401 cpp_setLocation (pfile);
7402 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
7403 }
7404
7405 pmark->position = pbuf->cur - pbuf->buf;
ce7034f0 7406 DPRINTF (("move mark: %s", pmark->position));
ac0860d8 7407}
7408
3e3ec469 7409void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
ac0860d8 7410{
7411 struct cppOptions *opts = CPPOPTIONS (pfile);
7412 cstring xp;
7413
7414 /* The code looks at the defaults through this pointer, rather than through
7415 the constant structure above. This pointer gets changed if an environment
7416 variable specifies other defaults. */
7417
7418 struct default_include *include_defaults = include_defaults_array;
7419
7420 /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */
7421 /* There seems to be confusion about what CPATH should do,
7422 so for the moment it is not documented. */
7423 /* Some people say that CPATH should replace the standard include dirs,
7424 but that seems pointless: it comes before them, so it overrides them
7425 anyway. */
7426
7427 xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
7428
7429 if (cstring_isDefined (xp) && !opts->no_standard_includes)
7430 {
7431 path_include (pfile, cstring_toCharsSafe (xp));
7432 }
7433
7434 /* Now that dollars_in_ident is known, initialize is_idchar. */
7435 initialize_char_syntax (opts);
7436
7437 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
7438 and option processing. */
7439
7440 initialize_builtins (pfile);
7441
7442 /* Do standard #defines and assertions
7443 that identify system and machine type. */
7444
7445 if (!opts->inhibit_predefs) {
7446 char *p = (char *) dmalloc (strlen (predefs) + 1);
7447 strcpy (p, predefs);
7448
7449 while (*p)
7450 {
7451 char *q;
7452
7453 while (*p == ' ' || *p == '\t')
7454 {
7455 p++;
7456 }
7457
7458 /* Handle -D options. */
7459 if (p[0] == '-' && p[1] == 'D')
7460 {
7461 q = &p[2];
7462
7463 while (*p && *p != ' ' && *p != '\t')
7464 {
7465 p++;
7466 }
7467
7468 if (*p != 0)
7469 {
7470 *p++= 0;
7471 }
7472
7473 if (opts->debug_output)
7474 {
7475 output_line_command (pfile, 0, same_file);
7476 }
7477
7478 cppReader_define (pfile, q);
7479
7480 while (*p == ' ' || *p == '\t')
7481 {
7482 p++;
7483 }
7484 }
7485 else
7486 {
7487 abort ();
7488 }
7489 }
7490
7491 sfree (p);
7492 }
7493
7494 opts->done_initializing = 1;
7495
7496 { /* Read the appropriate environment variable and if it exists
7497 replace include_defaults with the listed path. */
7498 char *epath = 0;
7499#ifdef __CYGWIN32__
7500 char *win32epath;
7501 int win32_buf_size = 0; /* memory we need to allocate */
7502#endif
7503
7504 if (opts->cplusplus)
7505 {
7506 epath = getenv ("CPLUS_INCLUDE_PATH");
7507 }
7508 else
7509 {
7510 epath = getenv ("C_INCLUDE_PATH");
7511 }
7512
7513 /*
7514 ** If the environment var for this language is set,
7515 ** add to the default list of include directories.
7516 */
7517
7518 if (epath != NULL) {
7519 char *nstore = (char *) dmalloc (strlen (epath) + 2);
7520 int num_dirs;
7521 char *startp, *endp;
7522
7523#ifdef __CYGWIN32__
7524 /* if we have a posix path list, convert to win32 path list */
7525 if (cygwin32_posix_path_list_p (epath))
7526 {
7527 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
7528 win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
7529 cygwin32_posix_to_win32_path_list (epath, win32epath);
7530 epath = win32epath;
7531 }
7532#endif
7533 for (num_dirs = 1, startp = epath; *startp; startp++)
7534 {
7535 if (*startp == PATH_SEPARATOR)
7536 num_dirs++;
7537 }
7538
7539 /*@-sizeoftype@*/
7540 include_defaults
7541 = (struct default_include *) dmalloc ((num_dirs
7542 * sizeof (struct default_include))
7543 + sizeof (include_defaults_array));
7544 /*@=sizeoftype@*/
7545
7546 startp = endp = epath;
7547 num_dirs = 0;
7548 while (1) {
7549 /* Handle cases like c:/usr/lib:d:/gcc/lib */
7550 if ((*endp == PATH_SEPARATOR) || *endp == 0)
7551 {
7552 strncpy (nstore, startp, size_fromInt (endp - startp));
7553 if (endp == startp)
7554 {
7555 strcpy (nstore, ".");
7556 }
7557 else
7558 {
7559 nstore[endp-startp] = '\0';
7560 }
7561
7562 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
7563 include_defaults[num_dirs].cplusplus = opts->cplusplus;
7564 include_defaults[num_dirs].cxx_aware = 1;
7565 num_dirs++;
7566
7567 if (*endp == '\0')
7568 {
7569 break;
7570 }
7571 endp = startp = endp + 1;
7572 }
7573 else
7574 {
7575 endp++;
7576 }
7577 }
7578 /* Put the usual defaults back in at the end. */
7579 memcpy ((char *) &include_defaults[num_dirs],
7580 (char *) include_defaults_array,
7581 sizeof (include_defaults_array));
7582
7583 sfree (nstore);
7584 /*@-branchstate@*/ } /*@=branchstate@*/
7585 }
7586
7587 cppReader_appendIncludeChain (pfile, opts->before_system,
7588 opts->last_before_system);
6fcd0b1e 7589
ac0860d8 7590 opts->first_system_include = opts->before_system;
7591
7592 /* Unless -fnostdinc,
7593 tack on the standard include file dirs to the specified list */
abd7f895 7594
ac0860d8 7595 if (!opts->no_standard_includes) {
7596 struct default_include *p = include_defaults;
7597 char *specd_prefix = opts->include_prefix;
7598 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
e5081f8c 7599 size_t default_len = 0;
abd7f895 7600
7601 /* Remove the `include' from /usr/local/lib/gcc.../include. */
7602 if (default_prefix != NULL) {
7603 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
7604 default_len = strlen (default_prefix) - 7;
7605 default_prefix[default_len] = 0;
7606 }
ac0860d8 7607 }
abd7f895 7608
ac0860d8 7609 /* Search "translated" versions of GNU directories.
7610 These have /usr/local/lib/gcc... replaced by specd_prefix. */
7611 if (specd_prefix != 0 && default_len != 0)
7612 for (p = include_defaults; p->fname != NULL; p++) {
7613 /* Some standard dirs are only for C++. */
7614 if (!p->cplusplus
7615 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
7616 /* Does this dir start with the prefix? */
abd7f895 7617 llassert (default_prefix != NULL);
7618
e5081f8c 7619 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
ac0860d8 7620 {
7621 /* Yes; change prefix and add to search list. */
7622 struct file_name_list *nlist
7623 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7624 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
7625 char *str = (char *) dmalloc (this_len + 1);
7626 strcpy (str, specd_prefix);
7627 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
7628
7629 nlist->next = NULL;
7630 nlist->fname = cstring_fromChars (str);
7631 nlist->control_macro = 0;
7632 nlist->c_system_include_path = !p->cxx_aware;
7633 nlist->got_name_map = 0;
7634
ac0860d8 7635 if (opts->first_system_include == 0)
7636 {
7637 opts->first_system_include = nlist;
7638 }
2f2892c2 7639
6fcd0b1e 7640 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7641 }
7642 }
7643 }
2f2892c2 7644
ac0860d8 7645 /* Search ordinary names for GNU include directories. */
7646
7647 for (p = include_defaults; p->fname != NULL; p++)
7648 {
7649 /* Some standard dirs are only for C++. */
7650 if (!p->cplusplus
7651 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
7652 {
7653 struct file_name_list *nlist
7654 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7655 nlist->control_macro = 0;
7656 nlist->c_system_include_path = !p->cxx_aware;
7657 nlist->fname = p->fname;
7658 nlist->got_name_map = 0;
7659 nlist->next = NULL;
7660
b73d1009 7661 /* Spurious warning reported for opts->first_system_include */
7662 /*@-usereleased@*/ if (opts->first_system_include == NULL)
ac0860d8 7663 {
2f2892c2 7664 opts->first_system_include = nlist;
ac0860d8 7665 }
b73d1009 7666 /*@=usereleased@*/
7667
6fcd0b1e 7668 cppReader_addIncludeChain (pfile, nlist);
ac0860d8 7669 }
7670 }
7671 sfree (default_prefix);
7672 }
7673
7674 /* Tack the after_include chain at the end of the include chain. */
7675 cppReader_appendIncludeChain (pfile, opts->after_include,
7676 opts->last_after_include);
7677
b73d1009 7678 /* Spurious warnings for opts->first_system_include */
7679 /*@-usereleased@*/
7680 if (opts->first_system_include == NULL)
ac0860d8 7681 {
7682 opts->first_system_include = opts->after_include;
7683 }
b73d1009 7684 /*@=usereleased@*/
7685
ac0860d8 7686 /* With -v, print the list of dirs to search. */
7687 if (opts->verbose) {
7688 struct file_name_list *p;
7689 fprintf (stderr, "#include \"...\" search starts here:\n");
7690
7691 for (p = opts->include; p != NULL; p = p->next) {
7692 if (p == opts->first_bracket_include)
7693 fprintf (stderr, "#include <...> search starts here:\n");
7694
7695 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7696 }
7697 fprintf (stderr, "End of search list.\n");
7698 }
7699}
7700
7701int cppReader_startProcess (cppReader *pfile, cstring fname)
7702{
7703 cppBuffer *fp;
7704 int f;
7705 struct cppOptions *opts = CPPOPTIONS (pfile);
7706
7707 fp = cppReader_pushBuffer (pfile, NULL, 0);
7708
7709 if (fp == NULL)
7710 {
7711 return 0;
7712 }
7713
7714 if (opts->in_fname == NULL)
7715 {
7716 opts->in_fname = cstring_makeLiteralTemp ("");
7717 }
7718
7719 fp->fname = opts->in_fname;
7720 fp->nominal_fname = fp->fname;
7721 fp->lineno = 0;
7722
7723 /* Copy the entire contents of the main input file into
7724 the stacked input buffer previously allocated for it. */
7725
7726 if (cstring_isEmpty (fname))
7727 {
7728 fname = cstring_makeLiteralTemp ("");
7729 f = 0;
7730 }
7731 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
7732 {
7733 cppReader_error (pfile,
7734 message ("Error opening %s for reading: %s",
7735 fname, lldecodeerror (errno)));
7736
7737 return 0;
7738 }
7739 else
7740 {
7741 ;
7742 }
7743
7744 if (finclude (pfile, f, fname, 0, NULL))
7745 {
7746 output_line_command (pfile, 0, same_file);
7747 }
7748
7749 return 1;
7750}
7751
7752static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7753{
7754 return pfile->buffer;
7755}
7756
7757/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7758{
7759 llassert (pfile->buffer != NULL);
7760 return pfile->buffer;
7761}
7762
7763/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7764{
7765 llassert (buf->buf != NULL);
7766 return (buf->buf + buf->line_base);
7767}
7768
3e3ec469 7769int cpplib_bufPeek (cppBuffer *buf)
ac0860d8 7770{
7771 if (buf->cur == NULL || buf->rlimit == NULL) {
7772 return EOF;
7773 }
7774
7775 if (buf->cur < buf->rlimit) {
7776 return *(buf->cur);
7777 }
7778
7779 return EOF;
7780}
7781
7782bool cppBuffer_isMacro (cppBuffer *buf)
7783{
7784 if (buf != NULL)
7785 {
7786 return (buf->cleanup == cppReader_macroCleanup);
7787 }
7788
7789 return FALSE;
7790}
7791
7792/*
7793** Returns true if the macro should be checked, false
7794** if it should be expanded normally.
7795*/
7796
7797static bool notparseable = FALSE; /* preceeded by @notparseable@ */
7798static bool notfunction = FALSE; /* preceeded by @notfunction@ */
7799static bool expectiter = FALSE; /* preceeded by @iter@ */
7800static bool expectenditer = FALSE; /* second after @iter@ */
7801static bool expectfunction = FALSE; /* preceeded by @function@ */
7802static bool expectconstant = FALSE; /* preceeded by @constant@ */
7803static bool expectmacro = FALSE; /* preceeded by notfunction or notparseable */
7804
7805static void cpp_setLocation (cppReader *pfile)
7806{
7807 fileId fid;
7808 int line;
7809
7810 if (pfile->buffer != NULL)
7811 {
abd7f895 7812 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
ac0860d8 7813 {
abd7f895 7814 cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
ac0860d8 7815
7816 DPRINTF (("Looking up: %s", fname));
7817
7818 if (fileTable_exists (context_fileTable (), fname))
7819 {
7820 fid = fileTable_lookup (context_fileTable (), fname);
7821 }
7822 else
7823 {
7824 DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
7825
7826 fid = fileTable_lookup (context_fileTable (),
abd7f895 7827 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7828 }
7829 }
7830 else
7831 {
7832 fid = fileTable_lookup (context_fileTable (),
abd7f895 7833 cppReader_getBufferSafe (pfile)->fname);
ac0860d8 7834 }
7835
abd7f895 7836 line = cppReader_getBufferSafe (pfile)->lineno;
ac0860d8 7837 fileloc_free (g_currentloc);
7838
7839 if (fileId_isValid (fid))
7840 {
7841 g_currentloc = fileloc_create (fid, line, 1);
7842 }
7843 else
7844 {
7845 g_currentloc = fileloc_createBuiltin ();
7846 }
7847 }
7848 else
7849 {
7850 fileloc_free (g_currentloc);
7851 g_currentloc = fileloc_createBuiltin ();
7852 }
7853}
7854
2209bcb7 7855static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
ac0860d8 7856{
7857 bool checkmacro = FALSE;
7858 bool hasParams = FALSE;
7859 bool noexpand = FALSE;
7860 cstring sname;
7861 char c;
7862
7863 cpp_setLocation (pfile);
7864
7865 DPRINTF (("Should check macro? %s", p));
7866
7867 if (expectiter || expectconstant || expectenditer)
7868 {
7869 if (expectiter)
7870 {
7871 expectiter = FALSE;
7872 expectenditer = TRUE;
7873 }
7874 else
7875 {
7876 expectiter = FALSE;
7877 expectconstant = FALSE;
7878 expectenditer = FALSE;
7879 }
7880
7881 if (notfunction || notparseable)
7882 {
7883 notfunction = FALSE;
7884 notparseable = FALSE;
7885 return FALSE;
7886 }
7887 else
7888 {
7889 return TRUE;
7890 }
7891 }
7892
7893 llassert (*p == '#');
7894 p++;
7895
7896 while (*p == ' ' || *p == '\t')
7897 {
7898 p++;
7899 }
7900
7901 llassert (*p == 'd'); /* define starts */
7902
7903 p += 6;
7904
7905 while (*p == ' ' || *p == '\t')
7906 {
7907 p++;
7908 }
7909
7910 sname = cstring_fromChars (p);
7911 DPRINTF (("Check macro: %s", sname));
7912
7913 while (((c = *p) != ' ')
7914 && c != '\0' && c != '('
7915 && c != '\t' && c != '\\' && c != '\n'
7916 && !iscntrl (c))
7917 {
7918 p++;
7919 }
7920
7921 hasParams = (c == '(');
7922 *p = '\0';
7923
ac0860d8 7924 if (notparseable)
7925 {
7926 notparseable = FALSE;
7927 }
7928 else if (notfunction || fileloc_isStandardLib (g_currentloc))
7929 {
7930 DPRINTF (("Clear notfunction"));
7931 notfunction = FALSE;
7932 }
7933 else
7934 {
7935 if (noexpand)
7936 {
7937 checkmacro = TRUE;
7938
7939 if (!expectenditer)
7940 {
7941 noexpand = FALSE;
7942 }
7943 }
7944 else
7945 {
7946 if (usymtab_existsReal (sname))
7947 {
7948 uentry ue = usymtab_lookup (sname);
7949
7950 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7951
7952 if (fileloc_isPreproc (uentry_whereLast (ue)))
7953 {
7954 goto macroDne;
7955 }
7956 else
7957 {
7958 if (uentry_isSpecified (ue))
7959 {
7960 checkmacro = context_getFlag (FLG_SPECMACROS);
7961 }
7962 else
7963 {
7964 if (hasParams)
7965 {
7966 checkmacro = context_getFlag (FLG_LIBMACROS)
7967 || context_getFlag (FLG_FCNMACROS);
7968 }
7969 }
7970 }
7971 }
7972 else
7973 {
7974 macroDne:
7975 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7976
7977 if (fileloc_isSystemFile (g_currentloc)
7978 && context_getFlag (FLG_SYSTEMDIREXPAND))
7979 {
7980 ; /* don't check this macro */
7981 DPRINTF (("Don't check 1"));
7982 }
7983 else
7984 {
7985 uentry le;
7986
7987 if (hasParams)
7988 {
7989 DPRINTF (("Has params..."));
7990
7991 if (context_getFlag (FLG_FCNMACROS))
7992 {
7993 if (usymtab_exists (sname))
7994 {
7995 /*
7996 ** only get here is macro is redefined
7997 ** error reported elsewhere
7998 */
7999
8000 DPRINTF (("It exists!"));
8001 }
8002 else
8003 {
8004 /*
8005 ** We make it a forward function, since it might be declared elsewhere.
8006 ** After all headers have been processed, we should check the forward
8007 ** functions.
8008 */
8009
8010 fileloc loc = fileloc_makePreproc (g_currentloc);
8011
8012 /* the line is off-by-one, since the newline was already read */
8013 decLine ();
8014
8015 if (expectfunction)
8016 {
8017 expectfunction = FALSE;
8018 }
8019
8020 le = uentry_makeForwardFunction (sname,
8021 typeId_invalid, loc);
8022
8023 fileloc_free (loc);
8024
8025 incLine ();
8026
8027 /* Do not define here! */
8028
8029 (void) usymtab_addEntry (le);
8030 }
8031
8032 checkmacro = TRUE;
8033 DPRINTF (("Check: TRUE"));
8034 }
8035 else
8036 {
8037 DPRINTF (("Flag FCN_MACROS not set!"));
8038 }
8039 }
8040 else
8041 {
8042 DPRINTF (("No params"));
8043
8044 if (context_getFlag (FLG_CONSTMACROS))
8045 {
8046 bool nocontent = FALSE;
8047
8048 if (c == '\0')
8049 {
8050 nocontent = TRUE;
8051 }
8052 else
8053 {
8054 if (isspace (c))
8055 {
8056 char *rest = p + 1;
8057
8058 /*
8059 ** Check if there is nothing after the define.
8060 */
8061
8062 while ((*rest) != '\0' && isspace (*rest))
8063 {
8064 rest++;
8065 }
8066
8067 if (*rest == '\0')
8068 {
8069 nocontent = TRUE; /* empty macro, don't check */
8070 }
8071 }
8072 }
8073
8074 if (usymtab_exists (sname))
8075 {
8076 ;
8077 }
8078 else
8079 {
8080 fileloc loc = fileloc_makePreproc (g_currentloc);
8081 DPRINTF (("Make constant: %s", sname));
5e211f69 8082 le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
ac0860d8 8083 (void) usymtab_addEntry (le);
8084 }
8085
8086 checkmacro = !nocontent;
8087 }
8088 }
8089 }
8090
8091 if (checkmacro && usymtab_existsType (sname))
8092 {
8093 DPRINTF (("Making false..."));
8094 decLine ();
8095 ppllerror (message ("Specified type implemented as macro: %s", sname));
8096 checkmacro = FALSE;
8097 incLine ();
8098 }
8099 }
8100 }
8101 }
8102
8103 if (!checkmacro)
8104 {
8105 if (usymtab_exists (sname))
8106 {
8107 uentry ue = usymtab_lookupExpose (sname);
8108 fileloc tloc = fileloc_makePreproc (g_currentloc);
8109
8110 uentry_setDefined (ue, tloc);
8111 fileloc_free (tloc);
8112 uentry_setUsed (ue, fileloc_undefined);
8113 }
8114 else
8115 {
8116 fileloc tloc = fileloc_makePreproc (g_currentloc);
8117 uentry ue = uentry_makeExpandedMacro (sname, tloc);
8118 DPRINTF (("Make expanded macro: %s", sname));
8119 DPRINTF (("Not in symbol table: %s", sname));
8120
8121 (void) usymtab_addGlobalEntry (ue);
8122 fileloc_free (tloc);
8123 }
8124 }
8125
8126 *p = c;
8127 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
8128 return checkmacro;
8129}
8130
8131static enum cpp_token
8132cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
8133{
abd7f895 8134 cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
ac0860d8 8135 char *start;
8136 int len;
abd7f895 8137 fileloc loc;
ac0860d8 8138 bool eliminateComment = FALSE;
8139
8140 llassert (pbuf->buf != NULL);
8141
8142 start = pbuf->buf + smark->position;
8143
8144 llassert (pbuf->cur != NULL);
8145 len = pbuf->cur - start;
8146
8147 if (start[0] == '*'
8148 && start[1] == context_getCommentMarkerChar ())
8149 {
8150 int i;
8151 char c = ' ';
8152 char *scomment = start + 2;
8153 char savec = start[len];
abd7f895 8154
8155 cpp_setLocation (pfile);
8156 loc = fileloc_copy (g_currentloc);
ac0860d8 8157
8158 start[0] = BEFORE_COMMENT_MARKER[0];
8159 start[1] = BEFORE_COMMENT_MARKER[1];
8160
8161 llassert (start[len - 2] == '*');
8162 start[len - 2] = AFTER_COMMENT_MARKER[0];
8163
8164 llassert (start[len - 1] == '/');
8165 start[len - 1] = AFTER_COMMENT_MARKER[1];
8166
3e3ec469 8167 cpplib_reserve(pfile, size_fromInt (1 + len));
ac0860d8 8168 cppReader_putCharQ (pfile, c);
8169
8170 cpp_setLocation (pfile);
8171
8172 start[len] = '\0';
8173
8174 if (mstring_containsString (scomment, "/*"))
8175 {
8176 (void) cppoptgenerror
8177 (FLG_NESTCOMMENT,
8178 message ("Comment starts inside syntactic comment: %s",
8179 cstring_fromChars (scomment)),
8180 pfile);
8181 }
8182
8183 start[len] = savec;
8184
8185 if (mstring_equalPrefix (scomment, "ignore"))
8186 {
8187 if (!context_getFlag (FLG_NOCOMMENTS))
8188 {
abd7f895 8189 context_enterSuppressRegion (loc);
ac0860d8 8190 }
8191 }
8192 else if (mstring_equalPrefix (scomment, "end"))
8193 {
8194 if (!context_getFlag (FLG_NOCOMMENTS))
8195 {
abd7f895 8196 context_exitSuppressRegion (loc);
ac0860d8 8197 }
8198 }
8199 else if (mstring_equalPrefix (scomment, "notparseable"))
8200 {
8201 notparseable = TRUE;
8202 expectmacro = TRUE;
8203 eliminateComment = TRUE;
8204 }
8205 else if (mstring_equalPrefix (scomment, "notfunction"))
8206 {
8207 notfunction = TRUE;
8208 expectmacro = TRUE;
8209 eliminateComment = TRUE;
8210 }
8211 else if (mstring_equalPrefix (scomment, "iter"))
8212 {
8213 expectiter = TRUE;
8214 }
8215 else if (mstring_equalPrefix (scomment, "function"))
8216 {
8217 expectfunction = TRUE;
8218 }
8219 else if (mstring_equalPrefix (scomment, "constant"))
8220 {
8221 expectconstant = TRUE;
8222 }
8223 else
8224 {
8225 char sChar = *scomment;
8226
8227 if (sChar == '='
8228 || sChar == '-'
8229 || sChar == '+')
8230 {
8231 char *rest = scomment + 1;
8232
8233 if (mstring_equalPrefix (rest, "commentchar"))
8234 {
8235 eliminateComment = TRUE;
8236
8237 if (sChar == '=')
8238 {
8239 ppllerror (cstring_makeLiteral
8240 ("Cannot restore commentchar"));
8241 }
8242 else
8243 {
8244 char *next = scomment + 12; /* strlen commentchar = 12 */
8245
8246 if (*next != ' ' && *next != '\t' && *next != '\n')
8247 {
8248 ppllerror
8249 (message
8250 ("Syntactic commentchar comment is not followed by a "
8251 "whitespace character: %c",
8252 *next));
8253 }
8254 else
8255 {
8256 char cchar = *(next + 1);
8257
8258 if (cchar == '\0')
8259 {
8260 ppllerror
8261 (cstring_makeLiteral
8262 ("Cannot set commentchar to NUL"));
8263 }
8264 else
8265 {
8266 context_setCommentMarkerChar (cchar);
8267 /* setComment = TRUE; */
8268 }
8269 }
8270 }
8271 }
8272 else if (mstring_equalPrefix (scomment, "nestcomment"))
8273 {
8274 /* fix from Mike Miller <MikeM@xata.com> */
8275 context_fileSetFlag (FLG_NESTCOMMENT,
abd7f895 8276 ynm_fromCodeChar (sChar),
8277 loc);
ac0860d8 8278 }
8279 else if (mstring_equalPrefix (rest, "namechecks"))
8280 {
8281 context_fileSetFlag (FLG_NAMECHECKS,
abd7f895 8282 ynm_fromCodeChar (sChar),
8283 loc);
ac0860d8 8284 }
8285 else if (mstring_equalPrefix (rest, "macroredef"))
8286 {
8287 context_fileSetFlag (FLG_MACROREDEF,
abd7f895 8288 ynm_fromCodeChar (sChar),
8289 loc);
ac0860d8 8290 }
8291 else if (mstring_equalPrefix (rest, "usevarargs"))
8292 {
8293 context_fileSetFlag (FLG_USEVARARGS,
abd7f895 8294 ynm_fromCodeChar (sChar),
8295 loc);
ac0860d8 8296 }
8297 else if (mstring_equalPrefix (rest, "nextlinemacros"))
8298 {
8299 context_fileSetFlag (FLG_MACRONEXTLINE,
abd7f895 8300 ynm_fromCodeChar (sChar),
8301 loc);
ac0860d8 8302 }
8303 else if (mstring_equalPrefix (rest, "allmacros")
8304 || mstring_equalPrefix (rest, "fcnmacros")
8305 || mstring_equalPrefix (rest, "constmacros"))
8306 {
8307 flagcode fl;
8308
8309 if (mstring_equalPrefix (rest, "allmacros"))
8310 {
8311 fl = FLG_ALLMACROS;
8312 }
8313 else if (mstring_equalPrefix (rest, "fcnmacros"))
8314 {
8315 fl = FLG_FCNMACROS;
8316 }
8317 else
8318 {
8319 llassert (mstring_equalPrefix (rest, "constmacros"));
8320 fl = FLG_CONSTMACROS;
8321 }
8322
abd7f895 8323 context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
ac0860d8 8324 notfunction = FALSE;
8325 }
8326 else
8327 {
8328 ;
8329 }
8330 }
8331 else
8332 {
8333 ;
8334 }
8335 }
8336
8337 if (eliminateComment)
8338 {
8339 goto removeComment;
8340 }
8341
8342 /* Replaces comment char's in start with spaces */
8343
8344 for (i = 2; i < len - 2; i++)
8345 {
8346 if (start[i] == BEFORE_COMMENT_MARKER[0]
8347 || start[i] == BEFORE_COMMENT_MARKER[1]
8348 || start[i] == context_getCommentMarkerChar ())
8349 {
8350 start[i] = ' ';
8351 }
8352 }
8353
8354 cppReader_putStrN (pfile, start, size_fromInt (len));
8355 parseClearMark (smark);
8356 return CPP_COMMENT;
8357 }
8358 else
8359 {
8360 removeComment:
8361 {
8362 int i;
8363
8364 /*
8365 ** Output the comment as all spaces so line/column
8366 ** in output file is still correct.
8367 */
8368
8369 char c = ' ';
8370 cstring lintcomment = cstring_undefined;
8371
8372 if (context_getFlag (FLG_LINTCOMMENTS))
8373 {
8374 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
8375 {
8376 lintcomment = cstring_makeLiteralTemp ("l_notreach");
8377 }
8378 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
8379 {
8380 lintcomment = cstring_makeLiteralTemp ("l_printfli");
8381 }
8382 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
8383 {
8384 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
8385 }
8386 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
8387 {
8388 lintcomment = cstring_makeLiteralTemp ("l_argsus");
8389 }
8390 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
8391 {
8392 lintcomment = cstring_makeLiteralTemp ("l_fallth");
8393 }
8394 else
8395 {
8396 lintcomment = cstring_undefined;
8397 }
8398 }
8399 else
8400 {
8401 lintcomment = cstring_undefined;
8402 }
8403
8404 if (cstring_isDefined (lintcomment))
8405 {
8406 c = BEFORE_COMMENT_MARKER[0];
8407 start[0] = BEFORE_COMMENT_MARKER[1];
8408
abd7f895 8409 llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
ac0860d8 8410
8411 for (i = 1; i < len - 2; i++)
8412 {
abd7f895 8413 start[i] = cstring_getChar (lintcomment, size_fromInt (i));
ac0860d8 8414 }
8415
8416 start[len - 2] = AFTER_COMMENT_MARKER[0];
8417 start[len - 1] = AFTER_COMMENT_MARKER[1];
8418 }
8419 else
8420 {
8421 /* Replaces char's in start with spaces */
8422 for (i = 0; i < len; i++)
8423 {
8424 if (start[i] == '/'
8425 && i < len - 1
8426 && start[i + 1] == '*') {
abd7f895 8427 (void) cppoptgenerror
8428 (FLG_NESTCOMMENT,
8429 message ("Comment starts inside comment"),
8430 pfile);
ac0860d8 8431 }
8432
8433 if (start[i] != '\n')
8434 {
8435 start[i] = ' ';
8436 }
8437 }
8438 }
8439
3e3ec469 8440 cpplib_reserve (pfile, size_fromInt (1 + len));
ac0860d8 8441 cppReader_putCharQ (pfile, c);
8442 cppReader_putStrN (pfile, start, size_fromInt (len));
8443 parseClearMark (smark);
8444 return CPP_COMMENT;
8445 }
8446 }
8447}
8448
8449static int cpp_openIncludeFile (char *filename)
8450{
8451 int res = open (filename, O_RDONLY, 0666);
8452
8453 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
8454 if (res >= 0)
8455 {
8456 if (!fileTable_exists (context_fileTable (),
8457 cstring_fromChars (filename)))
8458 {
53a89507 8459 if (fileloc_isXHFile (g_currentloc))
8460 {
8461 /*
8462 ** Files includes by XH files are also XH files
8463 */
8464
8465 (void) fileTable_addXHFile (context_fileTable (),
ac0860d8 8466 cstring_fromChars (filename));
53a89507 8467 }
8468 else
8469 {
8470 (void) fileTable_addHeaderFile (context_fileTable (),
8471 cstring_fromChars (filename));
8472 }
ac0860d8 8473 }
8474 else
8475 {
8476 DPRINTF (("File already exists: %s", filename));
8477 }
8478 }
8479
8480 return res;
8481}
8482
8483static bool cpp_skipIncludeFile (cstring fname)
8484{
8485 if (context_isSystemDir (fname))
8486 {
8487 DPRINTF (("System dir: %s", fname));
8488
8489 if (lcllib_isSkipHeader (fname))
8490 {
8491 DPRINTF (("Skip include TRUE: %s", fname));
8492 return TRUE;
8493 }
8494
8495 if (context_getFlag (FLG_SKIPSYSHEADERS))
8496 {
d767066b 8497 /*
8498 ** 2003-04-18: Patch from Randal Parsons
8499 */
8500
8501 /*
8502 ** Don't skip include file unless the file actually exists.
8503 ** It may be in a different directory.
8504 */
8505
8506 int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666);
8507
8508 if (f >= 0)
8509 {
8510 check (close (f) == 0);
8511 DPRINTF (("Skip include TRUE: %s", fname));
8512 return TRUE;
8513 }
8514 else
8515 {
8516 /* Keep looking... */
8517 }
ac0860d8 8518 }
8519 }
8520
8521 if (context_getFlag (FLG_SINGLEINCLUDE))
8522 {
8523 fname = removePreDirs (fname);
8524
8525# if defined (WIN32) || defined (OS2)
8526 cstring_replaceAll (fname, '\\', '/');
8527# endif
8528
8529 if (fileTable_exists (context_fileTable (), fname))
8530 {
8531 DPRINTF (("Skip include TRUE: %s", fname));
8532 return TRUE;
8533 }
8534 }
8535
8536 DPRINTF (("Skip include FALSE: %s", fname));
8537 return FALSE;
8538}
8539
8540static int cpp_peekN (cppReader *pfile, int n)
8541{
abd7f895 8542 cppBuffer *buf = cppReader_getBufferSafe (pfile);
ac0860d8 8543
8544 llassert (buf->cur != NULL);
8545
8546 return (buf->rlimit - buf->cur >= (n)
8547 ? buf->cur[n]
8548 : EOF);
8549}
8550
8551cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
8552{
8553 return buf + 1;
8554}
8555
8556void cppBuffer_forward (cppBuffer *buf, int n)
8557{
8558 llassert (buf->cur != NULL);
8559 buf->cur += n;
8560}
f9264521 8561
8562/*@=bufferoverflowhigh@*/
0fe21ba7 8563/*@=bounds@*/
This page took 1.449264 seconds and 5 git commands to generate.