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