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