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