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