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