]> andersk Git - splint.git/blame - src/cpplib.c
splint now tried to define a symbol based on the current processor type.
[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
f7bbce9e 3706 /*drl 1/9/2001/ try to define the right symbol for the architecture
3707 We use autoconf to determine the target cpu
3708 */
3709 cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
3710
3711
ac0860d8 3712 if (CPPOPTIONS (pfile)->debug_output)
3713 {
3714 dump_special_to_buffer (pfile, "__BASE_FILE__");
3715 dump_special_to_buffer (pfile, "__VERSION__");
3716#ifndef NO_BUILTIN_SIZE_TYPE
3717 dump_special_to_buffer (pfile, "__SIZE_TYPE__");
3718#endif
3719#ifndef NO_BUILTIN_PTRDIFF_TYPE
3720 dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
3721#endif
3722 dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
3723 dump_special_to_buffer (pfile, "__DATE__");
3724 dump_special_to_buffer (pfile, "__TIME__");
3725 if (!cppReader_isTraditional (pfile))
3726 dump_special_to_buffer (pfile, "__STDC__");
3727 }
3728}
3729
3730
3731/* Return 1 iff a token ending in C1 followed directly by a token C2
3732 could cause mis-tokenization. */
3733
3734static bool
3735unsafe_chars (char c1, char c2)
3736{
3737 switch (c1)
3738 {
3739 case '+': case '-':
3740 if (c2 == c1 || c2 == '=')
3741 return 1;
3742 goto letter;
3743 case '.':
3744 case '0': case '1': case '2': case '3': case '4':
3745 case '5': case '6': case '7': case '8': case '9':
3746 case 'e': case 'E': case 'p': case 'P':
3747 if (c2 == '-' || c2 == '+')
3748 return 1; /* could extend a pre-processing number */
3749 goto letter;
3750 case 'L':
3751 if (c2 == '\'' || c2 == '\"')
3752 return 1; /* Could turn into L"xxx" or L'xxx'. */
3753 goto letter;
3754 letter:
3755 case '_':
3756 case 'a': case 'b': case 'c': case 'd': case 'f':
3757 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
3758 case 'm': case 'n': case 'o': case 'q': case 'r':
3759 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
3760 case 'y': case 'z':
3761 case 'A': case 'B': case 'C': case 'D': case 'F':
3762 case 'G': case 'H': case 'I': case 'J': case 'K':
3763 case 'M': case 'N': case 'O': case 'Q': case 'R':
3764 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
3765 case 'Y': case 'Z':
3766 /* We're in the middle of either a name or a pre-processing number. */
3767 return (is_idchar[(int) c2] || c2 == '.');
3768 case '<': case '>': case '!': case '%': case '#': case ':':
3769 case '^': case '&': case '|': case '*': case '/': case '=':
3770 return (c2 == c1 || c2 == '=');
3771 }
3772 return 0;
3773}
3774
3775/* Expand a macro call.
3776 HP points to the symbol that is the macro being called.
3777 Put the result of expansion onto the input stack
3778 so that subsequent input by our caller will use it.
3779
3780 If macro wants arguments, caller has already verified that
3781 an argument list follows; arguments come from the input stack. */
3782
3783static void
3e3ec469 3784cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
ac0860d8 3785{
3786 int nargs;
3787 DEFINITION *defn = hp->value.defn;
3788 char *xbuf;
3789 char *oxbuf = NULL;
3790 int start_line;
3791 int start_column;
3792 size_t xbuf_len;
3e3ec469 3793 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 3794 int rest_args;
3795 int rest_zero = 0;
3796 int i;
3797 struct argdata *args = NULL;
3798
3799 pfile->output_escapes++;
3800
3801 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
3802
3803 nargs = defn->nargs;
3804
3805 if (nargs >= 0)
3806 {
3807 enum cpp_token token = CPP_EOF;
3808
3809 args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
3810
3811 for (i = 0; i < nargs; i++)
3812 {
3813 args[i].expanded = 0;
3814 args[i].raw = 0;
3815 args[i].raw_length = 0;
3816 args[i].expand_length = args[i].stringified_length = -1;
3817 args[i].use_count = 0;
3818 }
3819
3820 /*
3821 ** Parse all the macro args that are supplied. I counts them.
3822 ** The first NARGS args are stored in ARGS.
3823 ** The rest are discarded. If rest_args is set then we assume
3824 ** macarg absorbed the rest of the args.
3825 */
3826
3827 i = 0;
3828 rest_args = 0;
3829
3830 cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg. */
3831 do
3832 {
3833 if (rest_args != 0)
3834 {
3835 continue;
3836 }
3837
3838 if (i < nargs || (nargs == 0 && i == 0))
3839 {
3840 /* if we are working on last arg which absorbs rest of args... */
3841 if (i == nargs - 1 && defn->rest_args)
3842 {
3843 rest_args = 1;
3844 }
3845
3e3ec469 3846 args[i].raw = size_toLong (cpplib_getWritten (pfile));
ac0860d8 3847 token = macarg (pfile, rest_args);
3e3ec469 3848 args[i].raw_length = cpplib_getWritten (pfile) - args[i].raw;
ac0860d8 3849 args[i].newlines = FALSE; /* FIXME */
3850 }
3851 else
3852 {
3853 token = macarg (pfile, 0);
3854 }
3855
3856 if (token == CPP_EOF || token == CPP_POP)
3857 {
3858 cppReader_errorWithLine (pfile, start_line, start_column,
3859 cstring_fromCharsNew ("unterminated macro call"));
3860 sfree (args);
3861 return;
3862 }
3863 i++;
3864 } while (token == CPP_COMMA);
3865
3866 /* If we got one arg but it was just whitespace, call that 0 args. */
3867 if (i == 1)
3868 {
3869 char *bp;
3870 char *lim;
3871
3872 assertSet (args);
3873
3874 bp = ARG_BASE + args[0].raw;
3875 lim = bp + args[0].raw_length;
3876
3877 /* cpp.texi says for foo ( ) we provide one argument.
3878 However, if foo wants just 0 arguments, treat this as 0. */
3879
3880 if (nargs == 0)
3881 {
3882 while (bp != lim && is_space[(int) *bp])
3883 {
3884 bp++;
3885 }
3886 }
3887
3888 if (bp == lim)
3889 i = 0;
3890 }
3891
3892 /* Don't output an error message if we have already output one for
3893 a parse error above. */
3894 rest_zero = 0;
3895
3896 if (nargs == 0 && i > 0)
3897 {
3898 cppReader_error (pfile,
3899 message ("arguments given to macro `%s'", hp->name));
3900 }
3901 else if (i < nargs)
3902 {
3903 /* traditional C allows foo() if foo wants one argument. */
3904 if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
3905 {
3906 ;
3907 }
3908 /* the rest args token is allowed to absorb 0 tokens */
3909 else if (i == nargs - 1 && defn->rest_args)
3910 rest_zero = 1;
3911 else if (i == 0)
3912 cppReader_error (pfile,
3913 message ("macro `%s' used without args", hp->name));
3914 else if (i == 1)
3915 cppReader_error (pfile,
3916 message ("macro `%s' used with just one arg", hp->name));
3917 else
3918 {
3919 cppReader_error (pfile,
3920 message ("macro `%s' used with only %d args",
3921 hp->name, i));
3922 }
3923 }
3924 else if (i > nargs)
3925 {
3926 cppReader_error (pfile,
3927 message ("macro `%s' used with too many (%d) args", hp->name, i));
3928 }
3929 else
3930 {
3931 ;
3932 }
3933 }
3934
3935 /* If macro wants zero args, we parsed the arglist for checking only.
3936 Read directly from the macro definition. */
3937
3938 if (nargs <= 0)
3939 {
3940 xbuf = defn->expansion;
3941 xbuf_len = defn->length;
3942 }
3943 else
3944 {
3945 char *exp = defn->expansion;
3946 int offset; /* offset in expansion,
3947 copied a piece at a time */
3948 size_t totlen; /* total amount of exp buffer filled so far */
3949
3950 register struct reflist *ap, *last_ap;
3951
3952 assertSet (args); /* args is defined since the nargs > 0 path was taken */
3953
3954 /* Macro really takes args. Compute the expansion of this call. */
3955
3956 /* Compute length in characters of the macro's expansion.
3957 Also count number of times each arg is used. */
3958 xbuf_len = defn->length;
3959
3960 llassert (args != NULL);
3961
3962 for (ap = defn->pattern; ap != NULL; ap = ap->next)
3963 {
3964 if (ap->stringify)
3965 {
3966 struct argdata *arg = &args[ap->argno];
3967
3968 /* Stringify it it hasn't already been */
3969 assertSet (arg);
3970
3971 if (arg->stringified_length < 0)
3972 {
3973 int arglen = arg->raw_length;
3974 bool escaped = FALSE;
3975 char in_string = '\0';
3976 char c;
3977
3978 /* Initially need_space is -1. Otherwise, 1 means the
3979 previous character was a space, but we suppressed it;
3980 0 means the previous character was a non-space. */
3981 int need_space = -1;
3982
3983 i = 0;
3e3ec469 3984 arg->stringified = cpplib_getWritten (pfile);
ac0860d8 3985 if (!cppReader_isTraditional (pfile))
3986 cppReader_putChar (pfile, '\"'); /* insert beginning quote */
3987 for (; i < arglen; i++)
3988 {
3989 c = (ARG_BASE + arg->raw)[i];
3990
3991 if (in_string == '\0')
3992 {
3993 /* Internal sequences of whitespace are replaced by
3994 one space except within an string or char token.*/
3995 if (is_space[(int) c])
3996 {
3e3ec469 3997 if (cpplib_getWritten (pfile) > arg->stringified
3998 && (cpplib_getPWritten (pfile))[-1] == '@')
ac0860d8 3999 {
4000 /* "@ " escape markers are removed */
4001 cppReader_adjustWritten (pfile, -1);
4002 /*@innercontinue@*/ continue;
4003 }
4004 if (need_space == 0)
4005 need_space = 1;
4006 /*@innercontinue@*/ continue;
4007 }
4008 else if (need_space > 0)
4009 cppReader_putChar (pfile, ' ');
4010 else
4011 {
4012 ;
4013 }
4014
4015 need_space = 0;
4016 }
4017
4018 if (escaped)
4019 escaped = 0;
4020 else
4021 {
4022 if (c == '\\')
4023 escaped = 1;
4024
4025 if (in_string != '\0')
4026 {
4027 if (c == in_string)
4028 in_string = '\0';
4029 }
4030 else if (c == '\"' || c == '\'')
4031 {
4032 in_string = c;
4033 }
4034 else
4035 {
4036 ;
4037 }
4038 }
4039
4040 /* Escape these chars */
4041 if (c == '\"' || (in_string != '\0' && c == '\\'))
4042 cppReader_putChar (pfile, '\\');
4043 if (isprint (c))
4044 cppReader_putChar (pfile, c);
4045 else
4046 {
3e3ec469 4047 cpplib_reserve (pfile, 4);
4048 sprintf (cpplib_getPWritten (pfile), "\\%03o",
ac0860d8 4049 (unsigned int) c);
4050 cppReader_adjustWritten (pfile, 4);
4051 }
4052 }
4053 if (!cppReader_isTraditional (pfile))
4054 cppReader_putChar (pfile, '\"'); /* insert ending quote */
4055 arg->stringified_length
3e3ec469 4056 = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
ac0860d8 4057 }
4058
4059 xbuf_len += args[ap->argno].stringified_length;
4060 }
4061 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4062 {
4063 /* Add 4 for two newline-space markers to prevent
4064 token concatenation. */
4065 assertSet (args); /*@i534 shouldn't need this */
4066 xbuf_len += args[ap->argno].raw_length + 4;
4067 }
4068 else
4069 {
4070 /* We have an ordinary (expanded) occurrence of the arg.
4071 So compute its expansion, if we have not already. */
4072
4073 assertSet (args); /*@i534 shouldn't need this */
4074
4075 if (args[ap->argno].expand_length < 0)
4076 {
3e3ec469 4077 args[ap->argno].expanded = cpplib_getWritten (pfile);
ac0860d8 4078 cpp_expand_to_buffer (pfile,
4079 ARG_BASE + args[ap->argno].raw,
4080 size_fromInt (args[ap->argno].raw_length));
4081
4082 args[ap->argno].expand_length
3e3ec469 4083 = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
ac0860d8 4084 }
4085
4086 /* Add 4 for two newline-space markers to prevent
4087 token concatenation. */
4088 xbuf_len += args[ap->argno].expand_length + 4;
4089 }
4090 if (args[ap->argno].use_count < 10)
4091 args[ap->argno].use_count++;
4092 }
4093
4094 xbuf = (char *) dmalloc (xbuf_len + 1);
4095 oxbuf = xbuf;
4096
4097 /*
4098 ** Generate in XBUF the complete expansion
4099 ** with arguments substituted in.
4100 ** TOTLEN is the total size generated so far.
4101 ** OFFSET is the index in the definition
4102 ** of where we are copying from.
4103 */
4104
4105 offset = 0;
4106 totlen = 0;
4107
4108 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
4109 last_ap = ap, ap = ap->next)
4110 {
4111 register struct argdata *arg = &args[ap->argno];
4112 size_t count_before = totlen;
4113
4114 /* Add chars to XBUF. */
4115 for (i = 0; i < ap->nchars; i++, offset++)
4116 {
4117 xbuf[totlen++] = exp[offset];
4118 }
4119
4120 /* If followed by an empty rest arg with concatenation,
4121 delete the last run of nonwhite chars. */
4122 if (rest_zero && totlen > count_before
4123 && ((ap->rest_args && ap->raw_before)
4124 || (last_ap != NULL && last_ap->rest_args
4125 && last_ap->raw_after)))
4126 {
4127 /* Delete final whitespace. */
4128 while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
4129 {
4130 totlen--;
4131 }
4132
4133 /* Delete the nonwhites before them. */
4134 while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
4135 {
4136 totlen--;
4137 }
4138 }
4139
4140 if (ap->stringify != 0)
4141 {
4142 assertSet(arg);
4143 memcpy (xbuf + totlen,
4144 ARG_BASE + arg->stringified,
4145 size_fromInt (arg->stringified_length));
4146 totlen += arg->stringified_length;
4147 }
4148 else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4149 {
4150 char *p1;
4151 char *l1;
4152
4153 assertSet (arg);
4154
4155 p1 = ARG_BASE + arg->raw;
4156 l1 = p1 + arg->raw_length;
4157
4158 if (ap->raw_before)
4159 {
4160 while (p1 != l1 && is_space[(int) *p1])
4161 {
4162 p1++;
4163 }
4164
4165 while (p1 != l1 && is_idchar[(int) *p1])
4166 {
4167 xbuf[totlen++] = *p1++;
4168 }
4169
4170 /* Delete any no-reexpansion marker that follows
4171 an identifier at the beginning of the argument
4172 if the argument is concatenated with what precedes it. */
4173 if (p1[0] == '@' && p1[1] == '-')
4174 p1 += 2;
4175 }
4176 if (ap->raw_after)
4177 {
4178 /* Arg is concatenated after: delete trailing whitespace,
4179 whitespace markers, and no-reexpansion markers. */
4180 while (p1 != l1)
4181 {
4182 if (is_space[(int) l1[-1]]) l1--;
4183 else if (l1[-1] == '-')
4184 {
4185 char *p2 = l1 - 1;
4186 /* If a `-' is preceded by an odd number of newlines then it
4187 and the last newline are a no-reexpansion marker. */
4188 while (p2 != p1 && p2[-1] == '\n')
4189 {
4190 p2--;
4191 }
4192
4193 if (((l1 - 1 - p2) & 1) != 0)
4194 {
4195 l1 -= 2;
4196 }
4197 else
4198 {
4199 /*@innerbreak@*/ break;
4200 }
4201 }
4202 else
4203 {
4204 /*@innerbreak@*/ break;
4205 }
4206 }
4207 }
4208
4209 memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
4210 totlen += l1 - p1;
4211 }
4212 else
4213 {
4214 char *expanded;
4215
4216 assertSet (arg);
4217 expanded = ARG_BASE + arg->expanded;
4218
4219 if (!ap->raw_before && totlen > 0
4220 && (arg->expand_length != 0)
4221 && !cppReader_isTraditional(pfile)
4222 && unsafe_chars (xbuf[totlen-1], expanded[0]))
4223 {
4224 xbuf[totlen++] = '@';
4225 xbuf[totlen++] = ' ';
4226 }
4227
4228 memcpy (xbuf + totlen, expanded,
4229 size_fromInt (arg->expand_length));
4230 totlen += arg->expand_length;
4231
4232 if (!ap->raw_after && totlen > 0
4233 && offset < size_toInt (defn->length)
4234 && !cppReader_isTraditional(pfile)
4235 && unsafe_chars (xbuf[totlen-1], exp[offset]))
4236 {
4237 xbuf[totlen++] = '@';
4238 xbuf[totlen++] = ' ';
4239 }
4240
4241 /* If a macro argument with newlines is used multiple times,
4242 then only expand the newlines once. This avoids creating
4243 output lines which don't correspond to any input line,
4244 which confuses gdb and gcov. */
4245 if (arg->use_count > 1 && arg->newlines > 0)
4246 {
4247 /* Don't bother doing change_newlines for subsequent
4248 uses of arg. */
4249 arg->use_count = 1;
4250 arg->expand_length
4251 = change_newlines (expanded, arg->expand_length);
4252 }
4253 }
4254
4255 if (totlen > xbuf_len)
4256 abort ();
4257 }
4258
4259 /* if there is anything left of the definition
4260 after handling the arg list, copy that in too. */
4261
4262 for (i = offset; i < size_toInt (defn->length); i++)
4263 {
4264 /* if we've reached the end of the macro */
4265 if (exp[i] == ')')
4266 rest_zero = 0;
4267 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
4268 && last_ap->raw_after))
4269 xbuf[totlen++] = exp[i];
4270 }
4271
4272 xbuf[totlen] = '\0';
4273 xbuf_len = totlen;
4274 }
4275
4276 pfile->output_escapes--;
4277
4278 /* Now put the expansion on the input stack
4279 so our caller will commence reading from it. */
4280 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
4281 cppReader_getBuffer (pfile)->has_escapes = 1;
4282
4283 /* Pop the space we've used in the token_buffer for argument expansion. */
4284 cppReader_setWritten (pfile, old_written);
4285
4286 /* Recursive macro use sometimes works traditionally.
4287 #define foo(x,y) bar (x (y,0), y)
4288 foo (foo, baz) */
4289
4290 if (!cppReader_isTraditional (pfile))
4291 hp->type = T_DISABLED;
4292
4293 sfree (args);
4294}
4295
4296static void
4297push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
4298 /*@dependent@*/ hashNode hp)
4299{
4300 cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
4301
4302 if (mbuf == NULL)
4303 {
4304 return;
4305 }
4306
4307 mbuf->cleanup = cppReader_macroCleanup;
4308
4309 llassert (mbuf->hnode == NULL);
4310 mbuf->hnode = hp;
4311
4312 /* The first chars of the expansion should be a "@ " added by
4313 collect_expansion. This is to prevent accidental token-pasting
4314 between the text preceding the macro invocation, and the macro
4315 expansion text.
4316
4317 We would like to avoid adding unneeded spaces (for the sake of
4318 tools that use cpp, such as imake). In some common cases we can
4319 tell that it is safe to omit the space.
4320
4321 The character before the macro invocation cannot have been an
4322 idchar (or else it would have been pasted with the idchars of
4323 the macro name). Therefore, if the first non-space character
4324 of the expansion is an idchar, we do not need the extra space
4325 to prevent token pasting.
4326
4327 Also, we don't need the extra space if the first char is '(',
4328 or some other (less common) characters. */
4329
4330 if (xbuf[0] == '@' && xbuf[1] == ' '
4331 && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
4332 || xbuf[2] == '\"'))
4333 {
4334 llassert (mbuf->cur != NULL);
4335 mbuf->cur += 2;
4336 }
4337}
4338
4339
3e3ec469 4340/* Like cpplib_getToken, except that it does not read past end-of-line.
ac0860d8 4341 Also, horizontal space is skipped, and macros are popped. */
4342
4343static enum cpp_token
4344get_directive_token (cppReader *pfile)
4345{
4346 for (;;)
4347 {
3e3ec469 4348 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 4349 enum cpp_token token;
4350 cppSkipHspace (pfile);
4351 if (cppReader_peekC (pfile) == '\n')
4352 {
4353 return CPP_VSPACE;
4354 }
4355
3e3ec469 4356 token = cpplib_getToken (pfile);
ac0860d8 4357
4358 switch (token)
4359 {
4360 case CPP_POP:
4361 if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
4362 return token;
4363 /*@fallthrough@*/
4364 case CPP_HSPACE:
4365 case CPP_COMMENT:
4366 cppReader_setWritten (pfile, old_written);
4367 /*@switchbreak@*/ break;
4368 default:
4369 return token;
4370 }
4371 }
4372}
4373
4374
4375/* Handle #include and #import.
4376 This function expects to see "fname" or <fname> on the input.
4377
4378 The input is normally in part of the output_buffer following
3e3ec469 4379 cpplib_getWritten, and will get overwritten by output_line_command.
ac0860d8 4380 I.e. in input file specification has been popped by cppReader_handleDirective.
4381 This is safe. */
4382
4383static int
4384do_include (cppReader *pfile, struct directive *keyword,
4385 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
4386{
4387 bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
4388 cstring fname;
4389 char *fbeg, *fend; /* Beginning and end of fname */
4390 enum cpp_token token;
4391
4392 /* Chain of dirs to search */
4393 struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
4394 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
4395 struct file_name_list *searchptr = NULL;
3e3ec469 4396 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 4397
4398 int flen;
4399
4400 int f; /* file number */
4401 int angle_brackets = 0; /* 0 for "...", 1 for <...> */
4402 f= -1; /* JF we iz paranoid! */
4403
4404 pfile->parsing_include_directive++;
4405 token = get_directive_token (pfile);
4406 pfile->parsing_include_directive--;
4407
4408 if (token == CPP_STRING)
4409 {
4410 /* FIXME - check no trailing garbage */
4411 fbeg = pfile->token_buffer + old_written + 1;
3e3ec469 4412 fend = cpplib_getPWritten (pfile) - 1;
ac0860d8 4413 if (fbeg[-1] == '<')
4414 {
4415 angle_brackets = 1;
4416 /* If -I-, start with the first -I dir after the -I-. */
4417 if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
4418 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4419 }
4420 /* If -I- was specified, don't search current dir, only spec'd ones. */
4421 else if (!CPPOPTIONS (pfile)->ignore_srcdir)
4422 {
4423 cppBuffer *fp = CPPBUFFER (pfile);
4424 /* We have "filename". Figure out directory this source
4425 file is coming from and put it on the front of the list. */
4426
4427 for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4428 {
4429 int n;
4430 char *ep,*nam;
4431
4432 llassert (fp != NULL);
4433
4434 nam = NULL;
4435
4436 if (cstring_isDefined (fp->nominal_fname))
4437 {
4438 nam = cstring_toCharsSafe (fp->nominal_fname);
4439
4440 /* Found a named file. Figure out dir of the file,
4441 and put it in front of the search list. */
4442 dsp[0].next = search_start;
4443 search_start = dsp;
4444
4445#ifndef VMS
4446 ep = strrchr (nam, CONNECTCHAR);
4447#else /* VMS */
4448 ep = strrchr (nam, ']');
4449 if (ep == NULL) ep = strrchr (nam, '>');
4450 if (ep == NULL) ep = strrchr (nam, ':');
4451 if (ep != NULL) ep++;
4452#endif /* VMS */
4453 if (ep != NULL)
4454 {
4455 char save;
4456
4457 n = ep - nam;
4458 save = nam[n];
4459 nam[n] = '\0';
4460
4461 /*@-onlytrans@*/ /* This looks like a memory leak... */
4462 dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
4463 /*@=onlytrans@*/
4464 nam[n] = save;
4465
4466 if (n + INCLUDE_LEN_FUDGE > pfile->max_include_len)
4467 pfile->max_include_len = n + INCLUDE_LEN_FUDGE;
4468 }
4469 else
4470 {
4471 dsp[0].fname = cstring_undefined; /* Current directory */
4472 }
4473
4474 dsp[0].got_name_map = 0;
4475 break;
4476 }
4477 }
4478 }
4479 else
4480 {
4481 ;
4482 }
4483 }
4484#ifdef VMS
4485 else if (token == CPP_NAME)
4486 {
4487 /*
4488 * Support '#include xyz' like VAX-C to allow for easy use of all the
4489 * decwindow include files. It defaults to '#include <xyz.h>' (so the
4490 * code from case '<' is repeated here) and generates a warning.
4491 */
4492 cppReader_warning (pfile,
4493 "VAX-C-style include specification found, use '#include <filename.h>' !");
4494 angle_brackets = 1;
4495 /* If -I-, start with the first -I dir after the -I-. */
4496 if (CPPOPTIONS (pfile)->first_bracket_include)
4497 search_start = CPPOPTIONS (pfile)->first_bracket_include;
4498 fbeg = pfile->token_buffer + old_written;
3e3ec469 4499 fend = cpplib_getPWritten (pfile);
ac0860d8 4500 }
4501#endif
4502 else
4503 {
4504 cppReader_error (pfile,
4505 message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
4506 keyword->name));
4507
4508 cppReader_setWritten (pfile, old_written);
4509 cppReader_skipRestOfLine (pfile);
4510 return 0;
4511 }
4512
4513 *fend = 0;
4514
4515 token = get_directive_token (pfile);
4516 if (token != CPP_VSPACE)
4517 {
4518 cppReader_errorLit (pfile,
4519 cstring_makeLiteralTemp ("Junk at end of #include"));
4520
4521 while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
4522 {
4523 token = get_directive_token (pfile);
4524 }
4525 }
4526
4527 /*
4528 ** For #include_next, skip in the search path
4529 ** past the dir in which the containing file was found.
4530 */
4531
4532 if (skip_dirs)
4533 {
4534 cppBuffer *fp = CPPBUFFER (pfile);
4535
4536 for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4537 {
4538 llassert (fp != NULL);
4539
4540 if (fp->fname != NULL)
4541 {
4542 /* fp->dir is null if the containing file was specified with
4543 an absolute file name. In that case, don't skip anything. */
4544 if (fp->dir == SELF_DIR_DUMMY)
4545 {
4546 search_start = CPPOPTIONS (pfile)->include;
4547 }
4548 else if (fp->dir != NULL)
4549 {
4550 search_start = fp->dir->next;
4551 }
4552 else
4553 {
4554 ;
4555 }
4556
4557 break;
4558 }
4559 }
4560 }
4561
4562 cppReader_setWritten (pfile, old_written);
4563
4564 flen = fend - fbeg;
4565
4566 DPRINTF (("fbeg: %s", fbeg));
4567
4568 if (flen == 0)
4569 {
4570 cppReader_error (pfile,
4571 message ("Empty file name in #%s", keyword->name));
4572 return 0;
4573 }
4574
4575 /*
4576 ** Allocate this permanently, because it gets stored in the definitions
4577 ** of macros.
4578 */
4579
4580 fname = cstring_undefined;
4581
4582 /* + 2 above for slash and terminating null. */
4583 /* + 2 added for '.h' on VMS (to support '#include filename') */
4584
4585 /* If specified file name is absolute, just open it. */
4586
4587 if (osd_isConnectChar (*fbeg)
4588# if defined (WIN32) || defined (OS2)
4589 || (*(fbeg + 1) == ':')
4590# endif
4591 )
4592 {
4593 fname = cstring_copyLength (fbeg, flen);
4594
4595 if (redundant_include_p (pfile, fname))
4596 {
4597 cstring_free (fname);
4598 return 0;
4599 }
4600
4601 f = open_include_file (pfile, fname, NULL);
4602
4603 if (f == IMPORT_FOUND)
4604 {
4605 return 0; /* Already included this file */
4606 }
4607 }
4608 else
4609 {
4610 /* Search directory path, trying to open the file.
4611 Copy each filename tried into FNAME. */
4612
4613 for (searchptr = search_start; searchptr != NULL;
4614 searchptr = searchptr->next)
4615 {
4616 if (!cstring_isEmpty (searchptr->fname))
4617 {
4618 /* The empty string in a search path is ignored.
4619 This makes it possible to turn off entirely
4620 a standard piece of the list. */
4621 if (cstring_isEmpty (searchptr->fname))
4622 continue;
4623
4624 fname = cstring_copy (searchptr->fname);
4625 fname = cstring_appendChar (fname, CONNECTCHAR);
4626 DPRINTF (("Here: %s", fname));
4627 }
4628 else
4629 {
4630 ;
4631 }
4632
4633 fname = cstring_concatLength (fname, fbeg, flen);
4634
4635 DPRINTF (("fname: %s", fname));
4636
4637 /* Win32 directory fix from Kay Buschner. */
4638#if defined (WIN32) || defined (OS2)
4639 /* Fix all unixdir slashes to win dir slashes */
4640 if (searchptr->fname && (searchptr->fname[0] != 0))
4641 {
4642 cstring_replaceAll (fname, '/', '\\');
4643 }
4644#endif /* WIN32 */
4645
4646#ifdef VMS
4647 /* Change this 1/2 Unix 1/2 VMS file specification into a
4648 full VMS file specification */
4649 if (searchptr->fname && (searchptr->fname[0] != 0)) {
4650 /* Fix up the filename */
4651 hack_vms_include_specification (fname);
4652 } else {
4653 /* This is a normal VMS filespec, so use it unchanged. */
4654 strncpy (fname, fbeg, flen);
4655 fname[flen] = 0;
4656 /* if it's '#include filename', add the missing .h */
4657 if (strchr (fname,'.') == NULL) {
4658 strcat (fname, ".h");
4659 }
4660 }
4661#endif /* VMS */
4662 /* ??? There are currently 3 separate mechanisms for avoiding processing
4663 of redundant include files: #import, #pragma once, and
4664 redundant_include_p. It would be nice if they were unified. */
4665
4666 if (redundant_include_p (pfile, fname))
4667 {
4668 cstring_free (fname);
4669 return 0;
4670 }
4671
4672 DPRINTF (("Trying: %s", fname));
4673
4674 f = open_include_file (pfile, fname, searchptr);
4675
4676 if (f == IMPORT_FOUND)
4677 {
4678 return 0; /* Already included this file */
4679 }
4680#ifdef EACCES
4681 else if (f == IMPORT_NOT_FOUND && errno == EACCES)
4682 {
4683 cppReader_warning (pfile,
4684 message ("Header file %s exists, but is not readable", fname));
4685 }
4686#endif
4687
4688 if (f >= 0)
4689 {
4690 break;
4691 }
4692 }
4693 }
4694
4695 if (f < 0)
4696 {
4697 /* A file that was not found. */
4698 fname = cstring_copyLength (fbeg, flen);
4699
4700 if (search_start != NULL)
4701 {
4702 cppReader_error (pfile,
4703 message ("Cannot find include file %s on search path: %x",
4704 fname,
4705 searchPath_unparse (search_start)));
4706 }
4707 else
4708 {
4709 cppReader_error (pfile,
4710 message ("No include path in which to find %s", fname));
4711 }
4712 }
4713 else {
4714 /*
4715 ** Check to see if this include file is a once-only include file.
4716 ** If so, give up.
4717 */
4718
4719 struct file_name_list *ptr;
4720
4721 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
4722 {
4723 if (cstring_equal (ptr->fname, fname))
4724 {
4725 /* This file was included before. */
4726 break;
4727 }
4728 }
4729
4730 if (ptr == NULL)
4731 {
4732 /* This is the first time for this file. */
4733 /* Add it to list of files included. */
4734
4735 ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
4736 ptr->control_macro = NULL;
4737 ptr->c_system_include_path = NULL;
4738 ptr->next = pfile->all_include_files;
4739 ptr->fname = fname;
4740 ptr->got_name_map = NULL;
4741
4742 DPRINTF (("Including file: %s", fname));
4743 pfile->all_include_files = ptr;
4744 assertSet (pfile->all_include_files);
4745 }
4746
4747 if (angle_brackets != 0)
4748 {
4749 pfile->system_include_depth++;
4750 }
4751
4752 /* Actually process the file */
4753 if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
4754 {
4755 cstring_free (fname);
4756 return 0;
4757 }
4758
4759 if (finclude (pfile, f, fname, is_system_include (pfile, fname),
4760 searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
4761 {
4762 output_line_command (pfile, 0, enter_file);
4763 pfile->only_seen_white = 2;
4764 }
4765
4766 if (angle_brackets)
4767 {
4768 pfile->system_include_depth--;
4769 }
4770 /*@-branchstate@*/
4771 } /*@=branchstate@*/
4772
4773 return 0;
4774}
4775
4776/* Return nonzero if there is no need to include file NAME
4777 because it has already been included and it contains a conditional
4778 to make a repeated include do nothing. */
4779
4780static bool
4781redundant_include_p (cppReader *pfile, cstring name)
4782{
4783 struct file_name_list *l = pfile->all_include_files;
4784
4785 for (; l != NULL; l = l->next)
4786 {
4787 if (cstring_equal (name, l->fname)
4788 && (l->control_macro != NULL)
3e3ec469 4789 && (cpphash_lookup (l->control_macro, -1, -1) != NULL))
ac0860d8 4790 {
4791 return TRUE;
4792 }
4793 }
4794
4795 return FALSE;
4796}
4797
4798/* Return nonzero if the given FILENAME is an absolute pathname which
4799 designates a file within one of the known "system" include file
4800 directories. We assume here that if the given FILENAME looks like
4801 it is the name of a file which resides either directly in a "system"
4802 include file directory, or within any subdirectory thereof, then the
4803 given file must be a "system" include file. This function tells us
4804 if we should suppress pedantic errors/warnings for the given FILENAME.
4805
4806 The value is 2 if the file is a C-language system header file
4807 for which C++ should (on most systems) assume `extern "C"'. */
4808
4809static bool
4810is_system_include (cppReader *pfile, cstring filename)
4811{
4812 struct file_name_list *searchptr;
4813
4814 for (searchptr = CPPOPTIONS (pfile)->first_system_include;
4815 searchptr != NULL;
4816 searchptr = searchptr->next)
4817 {
4818 if (!cstring_isEmpty (searchptr->fname)) {
4819 cstring sys_dir = searchptr->fname;
4820 int length = cstring_length (sys_dir);
4821
4822 if (cstring_equalLen (sys_dir, filename, length)
4823 && osd_isConnectChar (cstring_getChar (filename, length)))
4824 {
4825 if (searchptr->c_system_include_path)
4826 return 2;
4827 else
4828 return 1;
4829 }
4830 }
4831 }
4832
4833 return 0;
4834}
4835
4836/* Convert a character string literal into a nul-terminated string.
4837 The input string is [IN ... LIMIT).
4838 The result is placed in RESULT. RESULT can be the same as IN.
4839 The value returned in the end of the string written to RESULT,
4840 or NULL on error. */
4841
4842static /*@null@*/ char *
4843convert_string (cppReader *pfile, /*@returned@*/ char *result,
4844 char *in, char *limit, int handle_escapes)
4845{
4846 char c;
4847 c = *in++;
4848
4849 if (c != '\"')
4850 {
4851 return NULL;
4852 }
4853
4854 while (in < limit)
4855 {
4856 c = *in++;
4857
4858 switch (c)
4859 {
4860 case '\0':
4861 return NULL;
4862 case '\"':
4863 limit = in;
4864 /*@switchbreak@*/ break;
4865 case '\\':
4866 if (handle_escapes)
4867 {
4868 char *bpc = (char *) in;
4869 int i = (char) cppReader_parseEscape (pfile, &bpc);
4870 in = (char *) bpc;
4871 if (i >= 0)
4872 *result++ = (char) c;
4873 /*@switchbreak@*/ break;
4874 }
4875
4876 /*@fallthrough@*/
4877 default:
4878 *result++ = c;
4879 }
4880 }
4881
4882 *result = 0;
4883 return result;
4884}
4885
4886/*
4887 * interpret #line command. Remembers previously seen fnames
4888 * in its very own hash table.
4889 */
4890
4891/*@constant int FNAME_HASHSIZE@*/
4892#define FNAME_HASHSIZE 37
4893
4894static int
4895do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
4896{
4897 cppBuffer *ip = cppReader_getBuffer (pfile);
4898 int new_lineno;
3e3ec469 4899 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 4900 enum file_change_code file_change = same_file;
4901 enum cpp_token token;
4902
4903 token = get_directive_token (pfile);
4904
4905 if (token != CPP_NUMBER
4906 || !isdigit(pfile->token_buffer[old_written]))
4907 {
4908 cppReader_errorLit (pfile,
4909 cstring_makeLiteralTemp ("invalid format `#line' command"));
4910
4911 goto bad_line_directive;
4912 }
4913
4914 /* The Newline at the end of this line remains to be processed.
4915 To put the next line at the specified line number,
4916 we must store a line number now that is one less. */
4917 new_lineno = atoi (pfile->token_buffer + old_written) - 1;
4918 cppReader_setWritten (pfile, old_written);
4919
4920 /* NEW_LINENO is one less than the actual line number here. */
4921 if (cppReader_isPedantic (pfile) && new_lineno < 0)
4922 cppReader_pedwarnLit (pfile,
4923 cstring_makeLiteralTemp ("line number out of range in `#line' command"));
4924
4925 token = get_directive_token (pfile);
4926
4927 if (token == CPP_STRING) {
4928 char *fname = pfile->token_buffer + old_written;
4929 char *end_name;
4930 static hashNode fname_table[FNAME_HASHSIZE];
4931 hashNode hp;
4932 hashNode *hash_bucket;
4933 char *p;
4934 size_t num_start;
4935 int fname_length;
4936
4937 /* Turn the file name, which is a character string literal,
4938 into a null-terminated string. Do this in place. */
3e3ec469 4939 end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
ac0860d8 4940 if (end_name == NULL)
4941 {
4942 cppReader_errorLit (pfile,
4943 cstring_makeLiteralTemp ("invalid format `#line' command"));
4944 goto bad_line_directive;
4945 }
4946
4947 fname_length = end_name - fname;
3e3ec469 4948 num_start = cpplib_getWritten (pfile);
ac0860d8 4949
4950 token = get_directive_token (pfile);
4951 if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
4952 p = pfile->token_buffer + num_start;
4953 if (cppReader_isPedantic (pfile))
4954 cppReader_pedwarnLit (pfile,
4955 cstring_makeLiteralTemp ("garbage at end of `#line' command"));
4956
4957 if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
4958 {
4959 cppReader_errorLit (pfile,
4960 cstring_makeLiteralTemp ("invalid format `#line' command"));
4961 goto bad_line_directive;
4962 }
4963 if (*p == '1')
4964 file_change = enter_file;
4965 else if (*p == 2)
4966 file_change = leave_file;
4967 else if (*p == 3)
4968 ip->system_header_p = 1;
4969 else /* if (*p == 4) */
4970 ip->system_header_p = 2;
4971
4972 cppReader_setWritten (pfile, num_start);
4973 token = get_directive_token (pfile);
4974 p = pfile->token_buffer + num_start;
4975 if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
4976 ip->system_header_p = *p == 3 ? 1 : 2;
4977 token = get_directive_token (pfile);
4978 }
4979 if (token != CPP_VSPACE) {
4980 cppReader_errorLit (pfile,
4981 cstring_makeLiteralTemp ("invalid format `#line' command"));
4982
4983 goto bad_line_directive;
4984 }
4985 }
4986
4987 hash_bucket =
3e3ec469 4988 &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
ac0860d8 4989 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
4990 {
4991 if (hp->length == fname_length &&
4992 strncmp (hp->value.cpval, fname, size_fromInt (fname_length)) == 0) {
4993 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
4994 break;
4995 }
4996 }
4997
4998 if (hp == 0) {
4999 /* Didn't find it; cons up a new one. */
5000 hp = (hashNode) dmalloc (sizeof (*hp));
5001
5002 hp->prev = NULL;
5003 hp->bucket_hdr = NULL;
5004 hp->type = T_NONE;
5005 hp->name = cstring_undefined;
5006 hp->next = *hash_bucket;
5007
5008 *hash_bucket = hp;
5009
5010 hp->length = fname_length;
5011 hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
5012 memcpy (hp->value.cpval, fname, size_fromInt (fname_length));
5013 hp->value.cpval[fname_length] = '\0';
5014 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5015 }
5016 }
5017 else if (token != CPP_VSPACE && token != CPP_EOF)
5018 {
5019 cppReader_errorLit (pfile,
5020 cstring_makeLiteralTemp ("invalid format `#line' command"));
5021 goto bad_line_directive;
5022 }
5023 else
5024 {
5025 ;
5026 }
5027
5028 ip->lineno = new_lineno;
5029bad_line_directive:
5030 cppReader_skipRestOfLine (pfile);
5031 cppReader_setWritten (pfile, old_written);
5032 output_line_command (pfile, 0, file_change);
5033 return 0;
5034}
5035
5036/*
5037 * remove the definition of a symbol from the symbol table.
5038 * according to un*x /lib/cpp, it is not an error to undef
5039 * something that has no definitions, so it isn't one here either.
5040 */
5041
5042static int
5043do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
5044{
5045
5046 int sym_length;
5047 hashNode hp;
5048 char *orig_buf = buf;
5049
5050 SKIP_WHITE_SPACE (buf);
5051
5052 sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
5053
3e3ec469 5054 while ((hp = cpphash_lookup (buf, sym_length, -1)) != NULL)
ac0860d8 5055 {
5056 /* If we are generating additional info for debugging (with -g) we
5057 need to pass through all effective #undef commands. */
5058 if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
5059 {
5060 pass_thru_directive (orig_buf, limit, pfile, keyword);
5061 }
5062
5063 if (hp->type != T_MACRO)
5064 {
5065 cppReader_warning (pfile,
5066 message ("Undefining preprocessor builtin: %s",
5067 hp->name));
5068 }
5069
5070 cppReader_deleteMacro (hp);
5071 }
5072
5073 if (cppReader_isPedantic (pfile)) {
5074 buf += sym_length;
5075 SKIP_WHITE_SPACE (buf);
5076 if (buf != limit)
5077 {
5078 cppReader_pedwarnLit (pfile,
5079 cstring_makeLiteralTemp ("garbage after `#undef' directive"));
5080 }
5081 }
5082
5083 return 0;
5084}
5085
5086
5087/*
5088 * Report an error detected by the program we are processing.
5089 * Use the text of the line in the error message.
5090 * (We use error because it prints the filename & line#.)
5091 */
5092
5093static int
5094do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5095 char *buf, char *limit)
5096{
5097 int length = limit - buf;
5098 cstring copy = cstring_copyLength (buf, length);
5099 cstring adv = cstring_advanceWhiteSpace (copy);
5100
5101 cppReader_error (pfile, message ("#error %s", adv));
5102 cstring_free (copy);
5103 return 0;
5104}
5105
5106/*
5107 * Report a warning detected by the program we are processing.
5108 * Use the text of the line in the warning message, then continue.
5109 * (We use error because it prints the filename & line#.)
5110 */
5111
5112static int
5113do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5114 char *buf, char *limit)
5115{
5116 int length = limit - buf;
5117 cstring copy = cstring_copyLength (buf, length);
5118 cstring adv = cstring_advanceWhiteSpace (copy);
5119 cppReader_warning (pfile, message ("#warning %s", adv));
5120 cstring_free (copy);
5121 return 0;
5122}
5123
5124
5125/* #ident has already been copied to the output file, so just ignore it. */
5126
5127static int
5128do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5129 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5130{
5131 /* Allow #ident in system headers, since that's not user's fault. */
5132 if (cppReader_isPedantic (pfile) && !cppReader_getBuffer (pfile)->system_header_p)
5133 cppReader_pedwarnLit (pfile,
5134 cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
5135
3e3ec469 5136 /* Leave rest of line to be read by later calls to cpplib_getToken. */
ac0860d8 5137
5138 return 0;
5139}
5140
5141/* #pragma and its argument line have already been copied to the output file.
5142 Just check for some recognized pragmas that need validation here. */
5143
5144static int
5145do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5146 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5147{
5148 while (*buf == ' ' || *buf == '\t')
5149 {
5150 buf++;
5151 }
5152
5153 if (!strncmp (buf, "implementation", 14)) {
5154 /* Be quiet about `#pragma implementation' for a file only if it hasn't
5155 been included yet. */
5156 struct file_name_list *ptr;
5157 char *p = buf + 14, *fname, *inc_fname;
5158 int fname_len;
5159 SKIP_WHITE_SPACE (p);
5160 if (*p == '\n' || *p != '\"')
5161 return 0;
5162
5163 fname = p + 1;
5164 p = (char *) strchr (fname, '\"');
5165 fname_len = p != NULL ? p - fname : mstring_length (fname);
5166
5167 for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
5168 {
5169 inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
5170 inc_fname = (inc_fname != NULL)
5171 ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
5172
5173 if ((inc_fname != NULL)
5174 && (strncmp (inc_fname, fname, size_fromInt (fname_len)) == 0))
5175 {
5176 cpp_setLocation (pfile);
5177
5178 ppllerror (message ("`#pragma implementation' for `%s' appears "
5179 "after file is included",
5180 cstring_fromChars (fname)));
5181 }
5182 }
5183 }
5184
5185 return 0;
5186}
5187
5188/*
5189 * handle #if command by
5190 * 1) inserting special `defined' keyword into the hash table
5191 * that gets turned into 0 or 1 by special_symbol (thus,
5192 * if the luser has a symbol called `defined' already, it won't
5193 * work inside the #if command)
5194 * 2) rescan the input into a temporary output buffer
5195 * 3) pass the output buffer to the yacc parser and collect a value
5196 * 4) clean up the mess left from steps 1 and 2.
5197 * 5) call conditional_skip to skip til the next #endif (etc.),
5198 * or not, depending on the value from step 3.
5199 */
5200
5201static int
5202do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5203 char *buf, char *limit)
5204{
3e3ec469 5205 HOST_WIDE_INT value;
5206 DPRINTF (("Do if: %s", buf));
5207 value = eval_if_expression (pfile, buf, limit - buf);
ac0860d8 5208 conditional_skip (pfile, value == 0, T_IF, NULL);
5209 return 0;
5210}
5211
5212/*
5213 * handle a #elif directive by not changing if_stack either.
5214 * see the comment above do_else.
5215 */
5216
5217static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5218 char *buf, char *limit)
5219{
5220 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
5221 {
5222 cppReader_errorLit (pfile,
5223 cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
5224 return 0;
5225 }
5226 else
5227 {
5228 llassert (pfile->if_stack != NULL);
5229
5230 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5231 {
5232 cppReader_errorLit (pfile,
5233 cstring_makeLiteralTemp ("`#elif' after `#else'"));
5234
5235 if (pfile->if_stack->fname != NULL
5236 && cppReader_getBuffer (pfile)->fname != NULL
5237 && !cstring_equal (pfile->if_stack->fname,
5238 cppReader_getBuffer (pfile)->nominal_fname))
5239 fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
5240 fprintf (stderr, ")\n");
5241 }
5242 pfile->if_stack->type = T_ELIF;
5243 }
5244
5245 if (pfile->if_stack->if_succeeded)
5246 {
5247 skip_if_group (pfile, 0);
5248 }
5249 else
5250 {
5251 HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
5252 if (value == 0)
5253 skip_if_group (pfile, 0);
5254 else
5255 {
5256 ++pfile->if_stack->if_succeeded; /* continue processing input */
5257 output_line_command (pfile, 1, same_file);
5258 }
5259 }
5260
5261 return 0;
5262}
5263
5264/*
5265 * evaluate a #if expression in BUF, of length LENGTH,
5266 * then parse the result as a C expression and return the value as an int.
5267 */
5268
5269static HOST_WIDE_INT
5270eval_if_expression (cppReader *pfile,
5271 /*@unused@*/ char *buf,
5272 /*@unused@*/ int length)
5273{
5274 hashNode save_defined;
5275 HOST_WIDE_INT value;
3e3ec469 5276 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5277
3e3ec469 5278 DPRINTF (("Saving defined..."));
5279 save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
ac0860d8 5280 pfile->pcp_inside_if = 1;
5281
5282 value = cppReader_parseExpression (pfile);
5283 pfile->pcp_inside_if = 0;
5284
5285 /* Clean up special symbol */
3e3ec469 5286 DPRINTF (("Removing defined..."));
ac0860d8 5287 cppReader_deleteMacro (save_defined);
ac0860d8 5288 cppReader_setWritten (pfile, old_written); /* Pop */
5289
5290 return value;
5291}
5292
5293/*
5294 * routine to handle ifdef/ifndef. Try to look up the symbol,
5295 * then do or don't skip to the #endif/#else/#elif depending
5296 * on what directive is actually being processed.
5297 */
5298
5299static int
5300do_xifdef (cppReader *pfile, struct directive *keyword,
5301 /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
5302{
5303 int skip;
5304 cppBuffer *ip = cppReader_getBuffer (pfile);
5305 char *ident;
5306 int ident_length;
5307 enum cpp_token token;
5308 int start_of_file = 0;
5309 char *control_macro = 0;
3e3ec469 5310 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5311
5312 DPRINTF (("do xifdef: %d",
5313 keyword->type == T_IFNDEF));
5314
5315 /* Detect a #ifndef at start of file (not counting comments). */
5316 if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
5317 {
5318 start_of_file = pfile->only_seen_white == 2;
5319 }
5320
5321 pfile->no_macro_expand++;
5322 token = get_directive_token (pfile);
5323 pfile->no_macro_expand--;
5324
5325 ident = pfile->token_buffer + old_written;
3e3ec469 5326 DPRINTF (("Ident: %s", ident));
5327
5328 ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
ac0860d8 5329 cppReader_setWritten (pfile, old_written); /* Pop */
5330
5331 if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
5332 {
5333 skip = (keyword->type == T_IFDEF);
5334 if (! cppReader_isTraditional (pfile))
5335 {
5336 cppReader_pedwarn (pfile,
3e3ec469 5337 message ("`#%s' with no argument", keyword->name));
ac0860d8 5338 }
5339 }
5340 else if (token == CPP_NAME)
5341 {
3e3ec469 5342 hashNode hp = cpphash_lookup (ident, ident_length, -1);
5343
5344 DPRINTF (("Lookup: %s %d", ident, ident_length));
5345
ac0860d8 5346 skip = (keyword->type == T_IFDEF)
5347 ? (hp == NULL) : (hp != NULL);
3e3ec469 5348
ac0860d8 5349 DPRINTF (("hp null: %d / %d / %d",
5350 (hp == NULL),
5351 (keyword->type == T_IFNDEF),
5352 skip));
3e3ec469 5353
ac0860d8 5354 if (start_of_file && !skip)
5355 {
5356 DPRINTF (("Not skipping!"));
5357 control_macro = (char *) dmalloc (size_fromInt (ident_length + 1));
5358 memcpy (control_macro, ident, size_fromInt (ident_length + 1));
5359 }
5360 }
5361 else
5362 {
5363 skip = (keyword->type == T_IFDEF);
5364 if (! cppReader_isTraditional (pfile))
5365 {
5366 cppReader_error (pfile,
5367 message ("`#%s' with invalid argument", keyword->name));
5368 }
5369 }
5370
5371 if (!cppReader_isTraditional (pfile))
5372 {
5373 int c;
5374 cppSkipHspace (pfile);
5375 c = cppReader_peekC (pfile);
5376 if (c != EOF && c != '\n')
5377 {
5378 cppReader_pedwarn (pfile,
5379 message ("garbage at end of `#%s' argument", keyword->name));
5380 }
5381 }
5382
5383 cppReader_skipRestOfLine (pfile);
5384
5385 DPRINTF (("Conditional skip: %d", skip));
5386 conditional_skip (pfile, skip, T_IF, control_macro);
5387 return 0;
5388}
5389
5390/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
5391 If this is a #ifndef starting at the beginning of a file,
5392 CONTROL_MACRO is the macro name tested by the #ifndef.
5393 Otherwise, CONTROL_MACRO is 0. */
5394
5395static void
5396conditional_skip (cppReader *pfile, int skip,
5397 enum node_type type,
5398 /*@dependent@*/ char *control_macro)
5399{
5400 cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5401
5402 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
5403 temp->next = pfile->if_stack;
5404 temp->control_macro = control_macro;
5405 temp->lineno = 0;
5406 temp->if_succeeded = 0;
5407
5408 pfile->if_stack = temp;
5409 pfile->if_stack->type = type;
5410
5411 if (skip != 0)
5412 {
5413 skip_if_group (pfile, 0);
5414 return;
5415 }
5416 else
5417 {
5418 ++pfile->if_stack->if_succeeded;
5419 output_line_command (pfile, 1, same_file);
5420 }
5421}
5422
5423/*
5424 * skip to #endif, #else, or #elif. adjust line numbers, etc.
5425 * leaves input ptr at the sharp sign found.
5426 * If ANY is nonzero, return at next directive of any sort.
5427 */
5428
5429static void
5430skip_if_group (cppReader *pfile, int any)
5431{
5432 int c;
5433 struct directive *kt;
5434 cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
5435 register int ident_length;
5436 char *ident;
5437 struct parse_marker line_start_mark;
5438
5439 parseSetMark (&line_start_mark, pfile);
5440
5441 if (CPPOPTIONS (pfile)->output_conditionals) {
5442 static char failed[] = "#failed\n";
5443 cppReader_puts (pfile, failed, sizeof(failed)-1);
5444 pfile->lineno++;
5445 output_line_command (pfile, 1, same_file);
5446 }
5447
5448beg_of_line:
5449 if (CPPOPTIONS (pfile)->output_conditionals)
5450 {
5451 cppBuffer *pbuf = cppReader_getBuffer (pfile);
5452 char *start_line;
5453
5454 llassert (pbuf->buf != NULL);
5455
5456 start_line = pbuf->buf + line_start_mark.position;
5457 cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
5458 }
5459
5460 parseMoveMark (&line_start_mark, pfile);
5461
5462 if (!cppReader_isTraditional (pfile))
5463 {
5464 cppSkipHspace (pfile);
5465 }
5466
5467 c = cppReader_getC (pfile);
5468 if (c == '#')
5469 {
3e3ec469 5470 size_t old_written = cpplib_getWritten (pfile);
ac0860d8 5471 cppSkipHspace (pfile);
5472
5473 parse_name (pfile, cppReader_getC (pfile));
3e3ec469 5474 ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
ac0860d8 5475 ident = pfile->token_buffer + old_written;
5476 pfile->limit = ident;
5477
5478 for (kt = directive_table; kt->length >= 0; kt++)
5479 {
5480 cppIfStackFrame *temp;
5481 if (ident_length == kt->length
5482 && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
5483 {
5484 /* If we are asked to return on next directive, do so now. */
5485 if (any)
5486 {
5487 goto done;
5488 }
5489
5490 switch (kt->type)
5491 {
5492 case T_IF:
5493 case T_IFDEF:
5494 case T_IFNDEF:
5495 temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5496 temp->next = pfile->if_stack;
5497 temp->fname = cppReader_getBuffer (pfile)->nominal_fname;
5498 temp->type = kt->type;
5499 temp->lineno = 0;
5500 temp->if_succeeded = 0;
5501 temp->control_macro = NULL;
5502
5503 pfile->if_stack = temp;
5504 /*@switchbreak@*/ break;
5505 case T_ELSE:
5506 case T_ENDIF:
5507 if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
5508 validate_else (pfile,
5509 cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
5510 /*@fallthrough@*/
5511 case T_ELIF:
5512 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
5513 {
5514 cppReader_error (pfile,
5515 message ("Preprocessor command #%s is not within a conditional", kt->name));
5516 /*@switchbreak@*/ break;
5517 }
5518 else if (pfile->if_stack == save_if_stack)
5519 {
5520 goto done; /* found what we came for */
5521 }
5522 else
5523 {
5524 ;
5525 }
5526
5527 if (kt->type != T_ENDIF)
5528 {
5529 llassert (pfile->if_stack != NULL);
5530
5531 if (pfile->if_stack->type == T_ELSE)
5532 {
5533 cppReader_errorLit (pfile,
5534 cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
5535 }
5536
5537 pfile->if_stack->type = kt->type;
5538 /*@switchbreak@*/ break;
5539 }
5540
5541 temp = pfile->if_stack;
5542 llassert (temp != NULL);
5543 pfile->if_stack = temp->next;
5544 sfree (temp);
5545 /*@switchbreak@*/ break;
5546 default: ;
5547 /*@-branchstate@*/
9622303f 5548#if defined (OS2) && defined (__IBMC__)
5549 /* Dummy code to eleminate optimization problems with icc */
5550 c = 0;
5551# endif
5552
ac0860d8 5553 }
5554 /*@=branchstate@*/
5555 break;
5556 }
5557
5558 /* Don't let erroneous code go by. */
5559
5560 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
5561 && cppReader_isPedantic (pfile))
5562 {
5563 cppReader_pedwarnLit (pfile,
5564 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
5565 }
5566 }
5567
5568 c = cppReader_getC (pfile);
5569 }
5570 /* We're in the middle of a line. Skip the rest of it. */
5571 for (;;) {
5572 size_t old;
5573
5574 switch (c)
5575 {
5576 case EOF:
5577 goto done;
5578 case '/': /* possible comment */
5579 c = skip_comment (pfile, NULL);
5580 if (c == EOF)
5581 goto done;
5582 /*@switchbreak@*/ break;
5583 case '\"':
5584 case '\'':
5585 cppReader_forward (pfile, -1);
3e3ec469 5586 old = cpplib_getWritten (pfile);
5587 (void) cpplib_getToken (pfile);
ac0860d8 5588 cppReader_setWritten (pfile, old);
5589 /*@switchbreak@*/ break;
5590 case '\\':
5591 /* Char after backslash loses its special meaning. */
5592 if (cppReader_peekC (pfile) == '\n')
5593 {
5594 cppReader_forward (pfile, 1);
5595 }
5596
5597 /*@switchbreak@*/ break;
5598 case '\n':
5599 goto beg_of_line;
5600 }
5601 c = cppReader_getC (pfile);
5602 }
5603done:
5604 if (CPPOPTIONS (pfile)->output_conditionals) {
5605 static char end_failed[] = "#endfailed\n";
5606 cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
5607 pfile->lineno++;
5608 }
5609 pfile->only_seen_white = 1;
5610
5611 parseGotoMark (&line_start_mark, pfile);
5612 parseClearMark (&line_start_mark);
5613}
5614
5615/*
5616 * handle a #else directive. Do this by just continuing processing
5617 * without changing if_stack ; this is so that the error message
5618 * for missing #endif's etc. will point to the original #if. It
5619 * is possible that something different would be better.
5620 */
5621
5622static int
5623do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5624 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5625{
5626 if (cppReader_isPedantic (pfile))
5627 {
5628 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5629 }
5630
5631 cppReader_skipRestOfLine (pfile);
5632
5633 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
5634 cppReader_errorLit (pfile,
5635 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5636 return 0;
5637 } else {
5638 /* #ifndef can't have its special treatment for containing the whole file
5639 if it has a #else clause. */
5640
5641 llassert (pfile->if_stack != NULL);
5642
5643 pfile->if_stack->control_macro = 0;
5644
5645 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5646 {
5647 cpp_setLocation (pfile);
5648 genppllerrorhint (FLG_PREPROC,
5649 message ("Pre-processor directive #else after #else"),
5650 message ("%q: Location of match",
5651 fileloc_unparseRaw (pfile->if_stack->fname,
5652 pfile->if_stack->lineno)));
5653 }
5654
5655 pfile->if_stack->type = T_ELSE;
5656 }
5657
5658 if (pfile->if_stack->if_succeeded)
5659 skip_if_group (pfile, 0);
5660 else {
5661 ++pfile->if_stack->if_succeeded; /* continue processing input */
5662 output_line_command (pfile, 1, same_file);
5663 }
5664
5665 return 0;
5666}
5667
5668/*
5669 * unstack after #endif command
5670 */
5671
5672static int
5673do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5674 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5675{
5676 if (cppReader_isPedantic (pfile))
5677 {
5678 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5679 }
5680
5681 cppReader_skipRestOfLine (pfile);
5682
5683 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
5684 {
5685 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5686 }
5687 else
5688 {
5689 cppIfStackFrame *temp = pfile->if_stack;
5690
5691 llassert (temp != NULL);
5692
5693 pfile->if_stack = temp->next;
5694 if (temp->control_macro != 0)
5695 {
5696 /* This #endif matched a #ifndef at the start of the file.
5697 See if it is at the end of the file. */
5698 struct parse_marker start_mark;
5699 int c;
5700
5701 parseSetMark (&start_mark, pfile);
5702
5703 for (;;)
5704 {
5705 cppSkipHspace (pfile);
5706 c = cppReader_getC (pfile);
5707
5708 if (c != '\n')
5709 break;
5710 }
5711
5712 parseGotoMark (&start_mark, pfile);
5713 parseClearMark (&start_mark);
5714
5715 if (c == EOF)
5716 {
5717 /* If we get here, this #endif ends a #ifndef
5718 that contains all of the file (aside from whitespace).
5719 Arrange not to include the file again
5720 if the macro that was tested is defined.
5721
5722 Do not do this for the top-level file in a -include or any
5723 file in a -imacros. */
5724 struct file_name_list *ifile = pfile->all_include_files;
5725
5726 for ( ; ifile != NULL; ifile = ifile->next)
5727 {
5728 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
5729 {
5730 ifile->control_macro = temp->control_macro;
5731 break;
5732 }
5733 }
5734 }
5735 }
5736
5737 sfree (temp);
5738 output_line_command (pfile, 1, same_file);
5739 }
5740 return 0;
5741}
5742
5743/* When an #else or #endif is found while skipping failed conditional,
5744 if -pedantic was specified, this is called to warn about text after
5745 the command name. P points to the first char after the command name. */
5746
5747static void
5748validate_else (cppReader *pfile, cstring directive)
5749{
5750 int c;
5751 cppSkipHspace (pfile);
5752 c = cppReader_peekC (pfile);
5753 if (c != EOF && c != '\n')
5754 {
5755 cppReader_pedwarn (pfile,
5756 message ("text following `%s' violates ANSI standard", directive));
5757 }
5758}
5759
5760/*
5761** Get the next token, and add it to the text in pfile->token_buffer.
5762** Return the kind of token we got.
5763*/
5764
5765enum cpp_token
3e3ec469 5766cpplib_getToken (cppReader *pfile)
5767{
5768 return cpplib_getTokenAux (pfile, FALSE);
5769}
5770
5771enum cpp_token
5772cpplib_getTokenForceExpand (cppReader *pfile)
5773{
5774 return cpplib_getTokenAux (pfile, TRUE);
5775}
5776
5777enum cpp_token
5778cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
ac0860d8 5779{
5780 int c, c2, c3;
5781 size_t old_written = 0;
5782 int start_line, start_column;
5783 enum cpp_token token;
5784 struct cppOptions *opts = CPPOPTIONS (pfile);
5785 cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
5786
5787get_next:
5788 c = cppReader_getC (pfile);
3e3ec469 5789 DPRINTF (("Get next token: %c", c));
ac0860d8 5790
5791 if (c == EOF)
5792 {
5793 handle_eof:
5794 if (cppReader_getBuffer (pfile)->seen_eof)
5795 {
5796 cppBuffer *buf = cppReader_popBuffer (pfile);
5797
5798 if (buf != cppReader_nullBuffer (pfile))
5799 {
5800 goto get_next;
5801 }
5802 else
5803 {
5804 return CPP_EOF;
5805 }
5806 }
5807 else
5808 {
5809 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
5810 cppReader_getBuffer (pfile)->seen_eof = 1;
5811
5812 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
5813 && next_buf != cppReader_nullBuffer (pfile))
5814 {
5815 /* We're about to return from an #include file.
5816 Emit #line information now (as part of the CPP_POP) result.
5817 But the #line refers to the file we will pop to. */
5818 cppBuffer *cur_buffer = CPPBUFFER (pfile);
5819 CPPBUFFER (pfile) = next_buf;
5820 pfile->input_stack_listing_current = 0;
5821 output_line_command (pfile, 0, leave_file);
5822 CPPBUFFER (pfile) = cur_buffer;
5823 }
5824 return CPP_POP;
5825 }
5826 }
5827 else
5828 {
5829 long newlines;
5830 struct parse_marker start_mark;
5831
5832 switch (c)
5833 {
5834 case '/':
5835 if (cppReader_peekC (pfile) == '=')
5836 {
5837 goto op2;
5838 }
5839
5840 if (opts->put_out_comments)
5841 {
5842 parseSetMark (&start_mark, pfile);
5843 }
5844
5845 newlines = 0;
5846 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
5847 &start_line, &start_column);
5848 c = skip_comment (pfile, &newlines);
5849
5850 if (opts->put_out_comments && (c == '/' || c == EOF))
5851 {
5852 assertSet (&start_mark);
5853 parseClearMark (&start_mark);
5854 }
5855
5856 if (c == '/')
5857 goto randomchar;
5858 if (c == EOF)
5859 {
5860 cppReader_errorWithLine (pfile, start_line, start_column,
5861 cstring_makeLiteral ("Unterminated comment"));
5862 goto handle_eof;
5863 }
5864 c = '/'; /* Initial letter of comment. */
5865 return_comment:
5866 /* Comments are equivalent to spaces.
5867 For -traditional, a comment is equivalent to nothing. */
5868
5869 if (opts->put_out_comments)
5870 {
5871 enum cpp_token res;
5872
5873 assertSet (&start_mark);
5874 res = cpp_handleComment (pfile, &start_mark);
5875 pfile->lineno += newlines;
5876 return res;
5877 }
5878 else if (cppReader_isTraditional (pfile))
5879 {
5880 return CPP_COMMENT;
5881 }
5882 else
5883 {
3e3ec469 5884 cpplib_reserve(pfile, 1);
ac0860d8 5885 cppReader_putCharQ (pfile, ' ');
5886 return CPP_HSPACE;
5887 }
5888
5889 case '#':
5890 if (!pfile->only_seen_white)
5891 {
5892 goto randomchar;
5893 }
5894
5895 if (cppReader_handleDirective (pfile))
5896 {
5897 return CPP_DIRECTIVE;
5898 }
5899
5900 pfile->only_seen_white = 0;
5901 return CPP_OTHER;
5902
5903 case '\"':
5904 case '\'':
5905 /* A single quoted string is treated like a double -- some
5906 programs (e.g., troff) are perverse this way */
5907 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
5908 &start_line, &start_column);
3e3ec469 5909 old_written = cpplib_getWritten (pfile);
ac0860d8 5910 string:
5911 cppReader_putChar (pfile, c);
5912 while (TRUE)
5913 {
5914 int cc = cppReader_getC (pfile);
5915 if (cc == EOF)
5916 {
5917 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
5918 {
5919 /* try harder: this string crosses a macro expansion
5920 boundary. This can happen naturally if -traditional.
5921 Otherwise, only -D can make a macro with an unmatched
5922 quote. */
5923 cppBuffer *next_buf
5924 = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
5925 (*cppReader_getBuffer (pfile)->cleanup)
5926 (cppReader_getBuffer (pfile), pfile);
5927 CPPBUFFER (pfile) = next_buf;
5928 continue;
5929 }
5930 if (!cppReader_isTraditional (pfile))
5931 {
5932 cpp_setLocation (pfile);
5933
5934 setLine (long_toInt (start_line));
5935 setColumn (long_toInt (start_column));
5936
5937 if (pfile->multiline_string_line != long_toInt (start_line)
5938 && pfile->multiline_string_line != 0)
5939 {
5940 genppllerrorhint
5941 (FLG_PREPROC,
5942 message ("Unterminated string or character constant"),
5943 message ("%q: Possible real start of unterminated constant",
5944 fileloc_unparseRaw
5945 (fileloc_filename (g_currentloc),
5946 pfile->multiline_string_line)));
5947 pfile->multiline_string_line = 0;
5948 }
5949 else
5950 {
5951 genppllerror
5952 (FLG_PREPROC,
5953 message ("Unterminated string or character constant"));
5954 }
5955 }
5956 /*@loopbreak@*/ break;
5957 }
5958 cppReader_putChar (pfile, cc);
5959 switch (cc)
5960 {
5961 case '\n':
5962 /* Traditionally, end of line ends a string constant with
5963 no error. So exit the loop and record the new line. */
5964 if (cppReader_isTraditional (pfile))
5965 goto while2end;
5966 if (c == '\'')
5967 {
5968 goto while2end;
5969 }
5970 if (cppReader_isPedantic (pfile)
5971 && pfile->multiline_string_line == 0)
5972 {
5973 cppReader_pedwarnWithLine
5974 (pfile, long_toInt (start_line),
5975 long_toInt (start_column),
5976 cstring_makeLiteral ("String constant runs past end of line"));
5977 }
5978 if (pfile->multiline_string_line == 0)
5979 {
5980 pfile->multiline_string_line = start_line;
5981 }
5982
5983 /*@switchbreak@*/ break;
5984
5985 case '\\':
5986 cc = cppReader_getC (pfile);
5987 if (cc == '\n')
5988 {
5989 /* Backslash newline is replaced by nothing at all. */
5990 cppReader_adjustWritten (pfile, -1);
5991 pfile->lineno++;
5992 }
5993 else
5994 {
5995 /* ANSI stupidly requires that in \\ the second \
5996 is *not* prevented from combining with a newline. */
5997 NEWLINE_FIX1(cc);
5998 if (cc != EOF)
5999 cppReader_putChar (pfile, cc);
6000 }
6001 /*@switchbreak@*/ break;
6002
6003 case '\"':
6004 case '\'':
6005 if (cc == c)
6006 goto while2end;
6007 /*@switchbreak@*/ break;
6008 }
6009 }
6010 while2end:
6011 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
3e3ec469 6012 cpplib_getPWritten (pfile));
ac0860d8 6013 pfile->only_seen_white = 0;
6014 return c == '\'' ? CPP_CHAR : CPP_STRING;
6015
6016 case '$':
6017 if (!opts->dollars_in_ident)
6018 goto randomchar;
6019 goto letter;
6020
6021 case ':':
6022 if (opts->cplusplus && cppReader_peekC (pfile) == ':')
6023 goto op2;
6024 goto randomchar;
6025
6026 case '&':
6027 case '+':
6028 case '|':
6029 NEWLINE_FIX;
6030 c2 = cppReader_peekC (pfile);
6031 if (c2 == c || c2 == '=')
6032 goto op2;
6033 goto randomchar;
6034
6035 case '*':
6036 case '!':
6037 case '%':
6038 case '=':
6039 case '^':
6040 NEWLINE_FIX;
6041 if (cppReader_peekC (pfile) == '=')
6042 goto op2;
6043 goto randomchar;
6044
6045 case '-':
6046 NEWLINE_FIX;
6047 c2 = cppReader_peekC (pfile);
6048 if (c2 == '-' && opts->chill)
6049 {
6050 /* Chill style comment */
6051 if (opts->put_out_comments)
6052 {
6053 parseSetMark (&start_mark, pfile);
6054 }
6055
6056 cppReader_forward (pfile, 1); /* Skip second '-'. */
6057
6058 for (;;)
6059 {
6060 c = cppReader_getC (pfile);
6061 if (c == EOF)
6062 /*@loopbreak@*/ break;
6063 if (c == '\n')
6064 {
6065 /* Don't consider final '\n' to be part of comment. */
6066 cppReader_forward (pfile, -1);
6067 /*@loopbreak@*/ break;
6068 }
6069 }
6070 c = '-';
6071 goto return_comment;
6072 }
6073 if (c2 == '-' || c2 == '=' || c2 == '>')
6074 goto op2;
6075 goto randomchar;
6076
6077 case '<':
6078 if (pfile->parsing_include_directive)
6079 {
6080 for (;;)
6081 {
6082 cppReader_putChar (pfile, c);
6083 if (c == '>')
6084 /*@loopbreak@*/ break;
6085 c = cppReader_getC (pfile);
6086 NEWLINE_FIX1 (c);
6087 if (c == '\n' || c == EOF)
6088 {
6089 cppReader_errorLit (pfile,
6090 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
6091 /*@loopbreak@*/ break;
6092 }
6093 }
6094 return CPP_STRING;
6095 }
6096 /*@fallthrough@*/
6097 case '>':
6098 NEWLINE_FIX;
6099 c2 = cppReader_peekC (pfile);
6100 if (c2 == '=')
6101 goto op2;
6102 if (c2 != c)
6103 goto randomchar;
6104 cppReader_forward (pfile, 1);
3e3ec469 6105 cpplib_reserve (pfile, 4);
ac0860d8 6106 cppReader_putChar (pfile, c);
6107 cppReader_putChar (pfile, c2);
6108 NEWLINE_FIX;
6109 c3 = cppReader_peekC (pfile);
6110 if (c3 == '=')
6111 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6112 cppReader_nullTerminateQ (pfile);
6113 pfile->only_seen_white = 0;
6114 return CPP_OTHER;
6115
6116 case '@':
6117 if (cppReader_getBuffer (pfile)->has_escapes)
6118 {
6119 c = cppReader_getC (pfile);
6120 if (c == '-')
6121 {
6122 if (pfile->output_escapes)
6123 cppReader_puts (pfile, "@-", 2);
6124 parse_name (pfile, cppReader_getC (pfile));
6125 return CPP_NAME;
6126 }
6127 else if (is_space [c])
6128 {
3e3ec469 6129 cpplib_reserve (pfile, 2);
ac0860d8 6130 if (pfile->output_escapes)
6131 cppReader_putCharQ (pfile, '@');
6132 cppReader_putCharQ (pfile, c);
6133 return CPP_HSPACE;
6134 }
6135 else
6136 {
6137 ;
6138 }
6139 }
6140 if (pfile->output_escapes)
6141 {
6142 cppReader_puts (pfile, "@@", 2);
6143 return CPP_OTHER;
6144 }
6145 goto randomchar;
6146 case '.':
6147 NEWLINE_FIX;
6148 c2 = cppReader_peekC (pfile);
6149 if (isdigit(c2))
6150 {
3e3ec469 6151 cpplib_reserve(pfile, 2);
ac0860d8 6152 cppReader_putCharQ (pfile, '.');
6153 c = cppReader_getC (pfile);
6154 goto number;
6155 }
6156
6157 /* FIXME - misses the case "..\\\n." */
6158 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
6159 {
3e3ec469 6160 cpplib_reserve(pfile, 4);
ac0860d8 6161 cppReader_putCharQ (pfile, '.');
6162 cppReader_putCharQ (pfile, '.');
6163 cppReader_putCharQ (pfile, '.');
6164 cppReader_forward (pfile, 2);
6165 cppReader_nullTerminateQ (pfile);
6166 pfile->only_seen_white = 0;
6167 return CPP_3DOTS;
6168 }
6169 goto randomchar;
6170 op2:
6171 token = CPP_OTHER;
6172 pfile->only_seen_white = 0;
6173 op2any:
3e3ec469 6174 cpplib_reserve(pfile, 3);
ac0860d8 6175 cppReader_putCharQ (pfile, c);
6176 cppReader_putCharQ (pfile, cppReader_getC (pfile));
6177 cppReader_nullTerminateQ (pfile);
6178 return token;
6179
6180 case 'L':
6181 NEWLINE_FIX;
6182 c2 = cppReader_peekC (pfile);
6183 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6184 {
6185 cppReader_putChar (pfile, c);
6186 c = cppReader_getC (pfile);
6187 goto string;
6188 }
6189 goto letter;
6190
6191 case '0': case '1': case '2': case '3': case '4':
6192 case '5': case '6': case '7': case '8': case '9':
6193 number:
6194 c2 = '.';
6195 for (;;)
6196 {
3e3ec469 6197 cpplib_reserve (pfile, 2);
ac0860d8 6198 cppReader_putCharQ (pfile, c);
6199 NEWLINE_FIX;
6200 c = cppReader_peekC (pfile);
6201 if (c == EOF)
6202 /*@loopbreak@*/ break;
6203 if (!is_idchar[c] && c != '.'
6204 && ((c2 != 'e' && c2 != 'E'
6205 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6206 || (c != '+' && c != '-')))
6207 /*@loopbreak@*/ break;
6208 cppReader_forward (pfile, 1);
6209 c2= c;
6210 }
6211
6212 cppReader_nullTerminateQ (pfile);
6213 pfile->only_seen_white = 0;
6214 return CPP_NUMBER;
6215
6216 case 'b': case 'c': case 'd': case 'h': case 'o':
6217 case 'B': case 'C': case 'D': case 'H': case 'O':
6218 if (opts->chill && cppReader_peekC (pfile) == '\'')
6219 {
6220 pfile->only_seen_white = 0;
3e3ec469 6221 cpplib_reserve (pfile, 2);
ac0860d8 6222 cppReader_putCharQ (pfile, c);
6223 cppReader_putCharQ (pfile, '\'');
6224 cppReader_forward (pfile, 1);
6225 for (;;)
6226 {
6227 c = cppReader_getC (pfile);
6228 if (c == EOF)
6229 goto chill_number_eof;
6230 if (!is_idchar[c])
6231 {
6232 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6233 {
6234 cppReader_forward (pfile, 2);
6235 continue;
6236 }
6237 /*@loopbreak@*/ break;
6238 }
6239 cppReader_putChar (pfile, c);
6240 }
6241 if (c == '\'')
6242 {
3e3ec469 6243 cpplib_reserve (pfile, 2);
ac0860d8 6244 cppReader_putCharQ (pfile, c);
6245 cppReader_nullTerminateQ (pfile);
6246 return CPP_STRING;
6247 }
6248 else
6249 {
6250 cppReader_forward (pfile, -1);
6251 chill_number_eof:
6252 cppReader_nullTerminate (pfile);
6253 return CPP_NUMBER;
6254 }
6255 }
6256 else
6257 goto letter;
6258 case '_':
6259 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
6260 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
6261 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
6262 case 'x': case 'y': case 'z':
6263 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
6264 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
6265 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6266 case 'Y': case 'Z':
6267 letter:
6268 {
6269 hashNode hp;
6270 char *ident;
3e3ec469 6271 size_t before_name_written = cpplib_getWritten (pfile);
ac0860d8 6272 int ident_len;
6273 parse_name (pfile, c);
6274 pfile->only_seen_white = 0;
3e3ec469 6275
ac0860d8 6276 if (pfile->no_macro_expand)
6277 {
3e3ec469 6278 DPRINTF (("Not expanding: %s", pfile->token_buffer));
ac0860d8 6279 return CPP_NAME;
6280 }
6281
6282 ident = pfile->token_buffer + before_name_written;
3e3ec469 6283 DPRINTF (("Ident: %s", ident));
6284
6285 ident_len = (cpplib_getPWritten (pfile)) - ident;
ac0860d8 6286
3e3ec469 6287 hp = cpphash_lookupExpand (ident, ident_len, -1, forceExpand);
ac0860d8 6288
6289 if (hp == NULL)
6290 {
3e3ec469 6291 DPRINTF (("No expand: %s %d", ident, ident_len));
ac0860d8 6292 return CPP_NAME;
6293 }
6294
6295 if (hp->type == T_DISABLED)
6296 {
3e3ec469 6297 DPRINTF (("Disabled!"));
6298
ac0860d8 6299 if (pfile->output_escapes)
6300 { /* Return "@-IDENT", followed by '\0'. */
6301 int i;
3e3ec469 6302 cpplib_reserve (pfile, 3);
ac0860d8 6303 ident = pfile->token_buffer + before_name_written;
6304 cppReader_adjustWritten (pfile, 2);
6305
6306 for (i = ident_len; i >= 0; i--)
6307 {
6308 ident[i+2] = ident[i];
6309 }
6310
6311 ident[0] = '@';
6312 ident[1] = '-';
6313 }
6314 return CPP_NAME;
6315 }
6316
3e3ec469 6317 /*
6318 ** If macro wants an arglist, verify that a '(' follows.
6319 ** first skip all whitespace, copying it to the output
6320 ** after the macro name. Then, if there is no '(',
6321 ** decide this is not a macro call and leave things that way.
6322 */
6323
ac0860d8 6324 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6325 {
6326 struct parse_marker macro_mark;
6327 int is_macro_call;
6328
6329 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6330 {
6331 cppBuffer *next_buf;
6332 cppSkipHspace (pfile);
6333 if (cppReader_peekC (pfile) != EOF)
6334 {
6335 /*@loopbreak@*/ break;
6336 }
6337
6338 next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
6339 (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);
6340 CPPBUFFER (pfile) = next_buf;
6341 }
6342
6343 parseSetMark (&macro_mark, pfile);
6344
6345 for (;;)
6346 {
6347 cppSkipHspace (pfile);
6348 c = cppReader_peekC (pfile);
6349 is_macro_call = c == '(';
6350 if (c != '\n')
6351 /*@loopbreak@*/ break;
6352 cppReader_forward (pfile, 1);
6353 }
6354
6355 if (!is_macro_call)
6356 {
6357 parseGotoMark (&macro_mark, pfile);
6358 }
6359
6360 parseClearMark (&macro_mark);
6361
6362 if (!is_macro_call)
6363 {
6364 return CPP_NAME;
6365 }
6366 }
6367 /* This is now known to be a macro call. */
6368
6369 /* it might not actually be a macro. */
6370 if (hp->type != T_MACRO)
6371 {
6372 size_t xbuf_len;
6373 char *xbuf;
6374
6375 cppReader_setWritten (pfile, before_name_written);
6376 special_symbol (hp, pfile);
3e3ec469 6377 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
ac0860d8 6378 xbuf = (char *) dmalloc (xbuf_len + 1);
6379 cppReader_setWritten (pfile, before_name_written);
3e3ec469 6380 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
ac0860d8 6381 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6382 }
6383 else
6384 {
3e3ec469 6385 /*
6386 ** Expand the macro, reading arguments as needed,
6387 ** and push the expansion on the input stack.
6388 */
6389
6390 cpplib_macroExpand (pfile, hp);
ac0860d8 6391 cppReader_setWritten (pfile, before_name_written);
6392 }
6393
6394 /* An extra "@ " is added to the end of a macro expansion
6395 to prevent accidental token pasting. We prefer to avoid
6396 unneeded extra spaces (for the sake of cpp-using tools like
6397 imake). Here we remove the space if it is safe to do so. */
6398
6399 llassert (pfile->buffer->rlimit != NULL);
6400
6401 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6402 && pfile->buffer->rlimit[-2] == '@'
6403 && pfile->buffer->rlimit[-1] == ' ')
6404 {
6405 int c1 = pfile->buffer->rlimit[-3];
3e3ec469 6406 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
ac0860d8 6407
6408 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6409 pfile->buffer->rlimit -= 2;
6410 }
6411 }
6412 goto get_next;
6413
6414
6415 case ' ': case '\t': case '\v': case '\r':
6416 for (;;)
6417 {
6418 cppReader_putChar (pfile, c);
6419 c = cppReader_peekC (pfile);
6420 if (c == EOF || !is_hor_space[c])
6421 /*@loopbreak@*/ break;
6422 cppReader_forward (pfile, 1);
6423 }
6424 return CPP_HSPACE;
6425
6426 case '\\':
6427 c2 = cppReader_peekC (pfile);
6428 if (c2 != '\n')
6429 goto randomchar;
6430 token = CPP_HSPACE;
6431 goto op2any;
6432
6433 case '\n':
6434 cppReader_putChar (pfile, c);
6435 if (pfile->only_seen_white == 0)
6436 pfile->only_seen_white = 1;
6437 pfile->lineno++;
6438 output_line_command (pfile, 1, same_file);
6439 return CPP_VSPACE;
6440
6441 case '(': token = CPP_LPAREN; goto char1;
6442 case ')': token = CPP_RPAREN; goto char1;
6443 case '{': token = CPP_LBRACE; goto char1;
6444 case '}': token = CPP_RBRACE; goto char1;
6445 case ',': token = CPP_COMMA; goto char1;
6446 case ';': token = CPP_SEMICOLON; goto char1;
6447
6448 randomchar:
6449 default:
6450 token = CPP_OTHER;
6451 char1:
6452 pfile->only_seen_white = 0;
6453 cppReader_putChar (pfile, c);
6454 return token;
6455 }
6456 }
6457
6458 BADBRANCH;
6459 /*@notreached@*/
6460}
6461
6462/* Parse an identifier starting with C. */
6463
6464void
6465parse_name (cppReader *pfile, int c)
6466{
6467 for (;;)
6468 {
6469 if (!is_idchar[c])
6470 {
6471 if (c == '\\' && cppReader_peekC (pfile) == '\n')
6472 {
6473 cppReader_forward (pfile, 2);
6474 continue;
6475 }
6476
6477 cppReader_forward (pfile, -1);
6478 break;
6479 }
6480
6481 if (c == '$' && cppReader_isPedantic (pfile))
6482 {
6483 cppReader_pedwarnLit (pfile,
6484 cstring_makeLiteralTemp ("`$' in identifier"));
6485 }
6486
3e3ec469 6487 cpplib_reserve(pfile, 2); /* One more for final NUL. */
ac0860d8 6488 cppReader_putCharQ (pfile, c);
6489 c = cppReader_getC (pfile);
6490
6491 if (c == EOF)
6492 break;
6493 }
6494
6495 cppReader_nullTerminateQ (pfile);
6496}
6497
6498/* The file_name_map structure holds a mapping of file names for a
6499 particular directory. This mapping is read from the file named
6500 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
6501 map filenames on a file system with severe filename restrictions,
6502 such as DOS. The format of the file name map file is just a series
6503 of lines with two tokens on each line. The first token is the name
6504 to map, and the second token is the actual name to use. */
6505
6506struct file_name_map
6507{
6508 struct file_name_map *map_next;
6509 cstring map_from;
6510 cstring map_to;
6511};
6512
6513/*@constant observer char *FILE_NAME_MAP_FILE*/
6514#define FILE_NAME_MAP_FILE "header.gcc"
6515
6516/* Read a space delimited string of unlimited length from a stdio
6517 file. */
6518
6519static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6520{
6521 char *alloc, *set;
6522 size_t len;
6523
6524 len = 20;
6525 set = alloc = dmalloc (len + 1);
6526
6527 if (!is_space[ch])
6528 {
6529 *set++ = ch;
6530 while ((ch = getc (f)) != EOF && ! is_space[ch])
6531 {
6532 if (set - alloc == size_toInt (len))
6533 {
6534 len *= 2;
6535 alloc = drealloc (alloc, len + 1);
6536 set = alloc + len / 2;
6537 /*@-branchstate@*/ }
6538
6539 *set++ = ch;
6540 } /*@=branchstate@*/
6541 }
6542 *set = '\0';
6543 check (ungetc (ch, f) != EOF);
6544
6545 return cstring_fromChars (alloc);
6546}
6547
6548/* This structure holds a linked list of file name maps, one per directory. */
6549
6550struct file_name_map_list
6551{
6552 struct file_name_map_list *map_list_next;
6553 cstring map_list_name;
6554 struct file_name_map *map_list_map;
6555};
6556
6557/* Read the file name map file for DIRNAME. */
6558
6559static struct file_name_map *
6560read_name_map (cppReader *pfile, cstring dirname)
6561{
6562 struct file_name_map_list *map_list_ptr;
6563 cstring name;
6564 FILE *f;
6565
6566 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6567 map_list_ptr != NULL;
6568 map_list_ptr = map_list_ptr->map_list_next)
6569 {
6570 if (cstring_equal (map_list_ptr->map_list_name, dirname))
6571 {
6572 return map_list_ptr->map_list_map;
6573 }
6574 }
6575
6576 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6577 map_list_ptr->map_list_name = cstring_copy (dirname);
6578 map_list_ptr->map_list_map = NULL;
6579
6580 name = cstring_copy (dirname);
6581
6582 if (cstring_length (dirname) > 0)
6583 {
6584 name = cstring_appendChar (name, CONNECTCHAR);
6585 }
6586
6587 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6588
6589 f = fileTable_openFile (context_fileTable (), name, "r");
6590 cstring_free (name);
6591
6592 if (f == NULL)
6593 {
6594 map_list_ptr->map_list_map = NULL;
6595 }
6596 else
6597 {
6598 int ch;
6599
6600 while ((ch = getc (f)) != EOF)
6601 {
6602 cstring from, to;
6603 struct file_name_map *ptr;
6604
6605 if (is_space[ch])
6606 {
6607 continue;
6608 }
6609
6610 from = read_filename_string (ch, f);
6611 while ((ch = getc (f)) != EOF && is_hor_space[ch])
6612 {
6613 ;
6614 }
6615
6616 to = read_filename_string (ch, f);
6617
6618 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6619 ptr->map_from = from;
6620
6621 /* Make the real filename absolute. */
6622 if (cstring_length (to) > 1
6623 && osd_isConnectChar (cstring_firstChar (to)))
6624 {
6625 ptr->map_to = to;
6626 }
6627 else
6628 {
6629 ptr->map_to = cstring_copy (dirname);
6630 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6631 ptr->map_to = cstring_concatFree (ptr->map_to, to);
6632 }
6633
6634 ptr->map_next = map_list_ptr->map_list_map;
6635 map_list_ptr->map_list_map = ptr;
6636
6637 while ((ch = getc (f)) != '\n')
6638 {
6639 if (ch == EOF)
6640 {
6641 /*@innerbreak@*/ break;
6642 }
6643 }
6644 }
6645
6646 assertSet (map_list_ptr->map_list_map);
6647 check (fileTable_closeFile (context_fileTable (),f) == 0);
6648 }
6649
6650 map_list_ptr->map_list_next = pfile->opts->map_list;
6651 pfile->opts->map_list = map_list_ptr;
6652
6653 return map_list_ptr->map_list_map;
6654}
6655
6656/* Try to open include file FILENAME. SEARCHPTR is the directory
6657 being tried from the include file search path. This function maps
6658 filenames on file systems based on information read by
6659 read_name_map. */
6660
6661static int
6662open_include_file (cppReader *pfile,
6663 cstring fname,
6664 struct file_name_list *searchptr)
6665{
6666 char *filename = cstring_toCharsSafe (fname);
6667 struct file_name_map *map;
6668 char *from;
6669 char *p, *dir;
6670
6671 cstring_markOwned (fname);
6672
6673 cpp_setLocation (pfile);
6674
6675 if (context_getFlag (FLG_NEVERINCLUDE))
6676 {
6677 if (isHeaderFile (fname))
6678 {
6679 return SKIP_INCLUDE;
6680 }
6681 }
6682
6683 if ((searchptr != NULL) && ! searchptr->got_name_map)
6684 {
6685 searchptr->name_map = read_name_map (pfile,
6686 !cstring_isEmpty (searchptr->fname)
6687 ? searchptr->fname :
6688 cstring_makeLiteralTemp ("."));
6689 searchptr->got_name_map = 1;
6690 }
6691
6692 /* First check the mapping for the directory we are using. */
6693
6694 if ((searchptr != NULL)
6695 && (searchptr->name_map != NULL))
6696 {
6697 from = filename;
6698
6699 if (!cstring_isEmpty (searchptr->fname))
6700 {
6701 from += cstring_length (searchptr->fname) + 1;
6702 }
6703
6704 for (map = searchptr->name_map;
6705 map != NULL;
6706 map = map->map_next)
6707 {
6708 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6709 {
6710 /*
6711 ** Found a match. Check if the file should be skipped
6712 */
6713
6714 if (cpp_skipIncludeFile (map->map_to))
6715 {
6716 return SKIP_INCLUDE;
6717 }
6718 else
6719 {
6720 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6721 }
6722 }
6723 }
6724 }
6725
6726 /*
6727 ** Try to find a mapping file for the particular directory we are
6728 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6729 ** in /usr/include/header.gcc and look up types.h in
6730 ** /usr/include/sys/header.gcc.
6731 */
6732
6733 p = strrchr (filename, CONNECTCHAR);
6734
6735 if (p == NULL)
6736 {
6737 p = filename;
6738 }
6739
6740 if ((searchptr != NULL)
6741 && (cstring_isDefined (searchptr->fname))
6742 && (cstring_length (searchptr->fname) == p - filename)
6743 && !strncmp (cstring_toCharsSafe (searchptr->fname),
6744 filename,
6745 size_fromInt (p - filename)))
6746 {
6747 /* filename is in SEARCHPTR, which we've already checked. */
6748
6749 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6750 {
6751 return SKIP_INCLUDE;
6752 }
6753 else
6754 {
6755 return cpp_openIncludeFile (filename);
6756 }
6757 }
6758
6759 if (p == filename)
6760 {
6761 dir = mstring_copy (".");
6762 from = filename;
6763 }
6764 else
6765 {
6766 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
6767 memcpy (dir, filename, size_fromInt (p - filename));
6768 dir[p - filename] = '\0';
6769 from = p + 1;
6770 }
6771
6772 for (map = read_name_map (pfile, cstring_fromChars (dir));
6773 map != NULL;
6774 map = map->map_next)
6775 {
6776 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6777 {
6778 sfree (dir);
6779
6780 if (cpp_skipIncludeFile (map->map_to))
6781 {
6782 return SKIP_INCLUDE;
6783 }
6784 else
6785 {
6786 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6787 }
6788 }
6789 }
6790
6791 sfree (dir);
6792
6793 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6794 {
6795 return SKIP_INCLUDE;
6796 }
6797 else
6798 {
6799 return cpp_openIncludeFile (filename);
6800 }
6801}
6802
6803/* Process the contents of include file FNAME, already open on descriptor F,
6804 with output to OP.
6805 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
6806 "system" include directories (as decided by the `is_system_include'
6807 function above).
6808 DIRPTR is the link in the dir path through which this file was found,
6809 or 0 if the file name was absolute or via the current directory.
6810 Return 1 on success, 0 on failure.
6811
6812 The caller is responsible for the cppReader_pushBuffer. */
6813
6814static int
6815finclude (cppReader *pfile, int f,
6816 cstring fname,
6817 bool system_header_p,
6818 /*@dependent@*/ struct file_name_list *dirptr)
6819{
6820 mode_t st_mode;
6821 size_t st_size;
6822 long i;
6823 int length = 0;
6824 cppBuffer *fp; /* For input stack frame */
6825
6826 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
6827 {
6828 cppReader_perrorWithName (pfile, fname);
6829 check (close (f) == 0);
6830 (void) cppReader_popBuffer (pfile);
6831 /*@-mustfree@*/
6832 return 0;
6833 /*@=mustfree@*/
6834 }
6835
6836 fp = cppReader_getBuffer (pfile);
6837
6838 /*@-temptrans@*/ /* fname shouldn't really be temp */
6839 fp->nominal_fname = fp->fname = fname;
6840 /*@=temptrans@*/
6841
6842 fp->dir = dirptr;
6843 fp->system_header_p = system_header_p;
6844 fp->lineno = 1;
6845 fp->colno = 1;
6846 fp->cleanup = cppReader_fileCleanup;
6847
6848 if (S_ISREG (st_mode))
6849 {
6850 sfree (fp->buf);
6851 fp->buf = (char *) dmalloc (st_size + 2);
6852 fp->alimit = fp->buf + st_size + 2;
6853 fp->cur = fp->buf;
6854
6855 /* Read the file contents, knowing that st_size is an upper bound
6856 on the number of bytes we can read. */
6857 length = safe_read (f, fp->buf, size_toInt (st_size));
6858 fp->rlimit = fp->buf + length;
6859 if (length < 0) goto nope;
6860 }
6861 else if (S_ISDIR (st_mode))
6862 {
6863 cppReader_error (pfile,
6864 message ("Directory specified in #include: %s", fname));
6865 check (close (f) == 0);
6866 return 0;
6867 }
6868 else
6869 {
6870 /*
6871 ** Cannot count its file size before reading.
6872 ** First read the entire file into heap and
6873 ** copy them into buffer on stack.
6874 */
6875
6876 size_t bsize = 2000;
6877
6878 st_size = 0;
6879
6880 sfree (fp->buf);
6881 fp->buf = (char *) dmalloc (bsize + 2);
6882
6883 for (;;) {
6884 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
6885
6886 if (i < 0)
6887 goto nope; /* error! */
6888 st_size += i;
6889
6890 if (st_size != bsize)
6891 {
6892 break; /* End of file */
6893 }
6894
6895 bsize *= 2;
6896 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
6897 }
6898
6899 fp->cur = fp->buf;
6900 length = size_toInt (st_size);
6901 }
6902
6903 if ((length > 0 && fp->buf[length - 1] != '\n')
6904 /* Backslash-newline at end is not good enough. */
6905 || (length > 1 && fp->buf[length - 2] == '\\')) {
6906 fp->buf[length++] = '\n';
6907 }
6908
6909 fp->buf[length] = '\0';
6910 fp->rlimit = fp->buf + length;
6911
6912 /* Close descriptor now, so nesting does not use lots of descriptors. */
6913 check (close (f) == 0);
6914
6915 /* Must do this before calling trigraph_pcp, so that the correct file name
6916 will be printed in warning messages. */
6917
6918 pfile->input_stack_listing_current = 0;
6919 return 1;
6920
6921 nope:
6922
6923 cppReader_perrorWithName (pfile, fname);
6924 check (close (f) == 0);
6925 sfree (fp->buf);
6926 return 1;
6927}
6928
6929void
3e3ec469 6930cpplib_init (cppReader *pfile)
ac0860d8 6931{
6932 memset ((char *) pfile, 0, sizeof (*pfile));
6933
3e3ec469 6934 pfile->get_token = cpplib_getToken;
ac0860d8 6935 pfile->token_buffer_size = 200;
6936 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
6937 pfile->all_include_files = NULL;
6938
6939 assertSet (pfile);
6940
6941 cppReader_setWritten (pfile, 0);
6942
6943 pfile->system_include_depth = 0;
6944 pfile->max_include_len = 0;
6945 pfile->timebuf = NULL;
6946 pfile->only_seen_white = 1;
6947
6948 pfile->buffer = cppReader_nullBuffer (pfile);
6949}
6950
6951void
6952cppReader_finish (/*@unused@*/ cppReader *pfile)
6953{
6954 ;
6955}
6956
6957/* Free resources used by PFILE.
6958 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
6959
6960void
6961cppCleanup (cppReader *pfile)
6962{
6963 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
6964 {
6965 (void) cppReader_popBuffer (pfile);
6966 }
6967
6968 if (pfile->token_buffer != NULL)
6969 {
6970 sfree (pfile->token_buffer);
6971 pfile->token_buffer = NULL;
6972 }
6973
6974 while (pfile->if_stack != NULL)
6975 {
6976 cppIfStackFrame *temp = pfile->if_stack;
6977 pfile->if_stack = temp->next;
6978 sfree (temp);
6979 }
6980
6981 while (pfile->all_include_files != NULL)
6982 {
6983 struct file_name_list *temp = pfile->all_include_files;
6984 pfile->all_include_files = temp->next;
6985 /*@-dependenttrans@*/
6986 cstring_free (temp->fname);
6987 /*@=dependenttrans@*/
6988 sfree (temp);
6989 }
6990
6991 cppReader_hashCleanup ();
6992}
6993
6994/*
6995** Get the file-mode and data size of the file open on FD
6996** and store them in *MODE_POINTER and *SIZE_POINTER.
6997*/
6998
6999static int
7000file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
7001{
7002 struct stat sbuf;
7003
7004 if (fstat (fd, &sbuf) < 0) {
3e3ec469 7005 *mode_pointer = 0;
7006 *size_pointer = 0;
ac0860d8 7007 return (-1);
7008 }
7009
7010 if (mode_pointer != NULL)
7011 {
7012 *mode_pointer = sbuf.st_mode;
7013 }
7014
7015 if (size_pointer != NULL)
7016 {
7017 *size_pointer = (size_t) sbuf.st_size;
7018 }
7019
7020 return 0;
7021}
7022
7023/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
7024 retrying if necessary. Return a negative value if an error occurs,
7025 otherwise return the actual number of bytes read,
7026 which must be LEN unless end-of-file was reached. */
7027
7028static int safe_read (int desc, char *ptr, int len)
7029{
7030 int left = len;
7031
7032 while (left > 0)
7033 {
7034# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
7035 /*@-compdef@*/ /* ptr is an out parameter */
7036 int nchars = _read (desc, ptr, (unsigned) left);
7037 /*@=compdef@*/
7038# else
7039 ssize_t nchars = read (desc, ptr, size_fromInt (left));
7040# endif
7041
7042 if (nchars < 0)
7043 {
7044#ifdef EINTR
7045 if (errno == EINTR)
7046 continue;
7047#endif
7048 return (int) nchars;
7049 }
7050
7051 if (nchars == 0) {
7052 break;
7053 }
7054
7055 ptr += nchars;
7056 left -= nchars;
7057 }
7058
7059 return len - left;
7060}
7061
7062/* Initialize PMARK to remember the current position of PFILE. */
7063
7064void
7065parseSetMark (struct parse_marker *pmark, cppReader *pfile)
7066{
7067 cppBuffer *pbuf = cppReader_getBuffer (pfile);
7068
7069 pmark->next = pbuf->marks;
7070 /*@-temptrans@*/
7071 pbuf->marks = pmark;
7072 /*@=temptrans@*/
7073
7074 pmark->buf = pbuf;
7075 pmark->position = pbuf->cur - pbuf->buf;
7076}
7077
7078/* Cleanup PMARK - we no longer need it. */
7079
7080void parseClearMark (struct parse_marker *pmark)
7081{
7082 struct parse_marker **pp = &pmark->buf->marks;
7083
7084 for (; ; pp = &(*pp)->next)
7085 {
7086 llassert (*pp != NULL);
7087 if (*pp == pmark) break;
7088 }
7089
7090 *pp = pmark->next;
7091}
7092
7093/* Backup the current position of PFILE to that saved in PMARK. */
7094
7095void
7096parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
7097{
7098 cppBuffer *pbuf = cppReader_getBuffer (pfile);
7099
7100 if (pbuf != pmark->buf)
7101 {
7102 cpp_setLocation (pfile);
7103 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
7104 }
7105
7106 llassert (pbuf->buf != NULL);
7107 pbuf->cur = pbuf->buf + pmark->position;
7108}
7109
7110/* Reset PMARK to point to the current position of PFILE. (Same
7111 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
7112
7113void
7114parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
7115{
7116 cppBuffer *pbuf = cppReader_getBuffer (pfile);
7117
7118 if (pbuf != pmark->buf)
7119 {
7120 cpp_setLocation (pfile);
7121 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
7122 }
7123
7124 pmark->position = pbuf->cur - pbuf->buf;
7125}
7126
3e3ec469 7127void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
ac0860d8 7128{
7129 struct cppOptions *opts = CPPOPTIONS (pfile);
7130 cstring xp;
7131
7132 /* The code looks at the defaults through this pointer, rather than through
7133 the constant structure above. This pointer gets changed if an environment
7134 variable specifies other defaults. */
7135
7136 struct default_include *include_defaults = include_defaults_array;
7137
7138 /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */
7139 /* There seems to be confusion about what CPATH should do,
7140 so for the moment it is not documented. */
7141 /* Some people say that CPATH should replace the standard include dirs,
7142 but that seems pointless: it comes before them, so it overrides them
7143 anyway. */
7144
7145 xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
7146
7147 if (cstring_isDefined (xp) && !opts->no_standard_includes)
7148 {
7149 path_include (pfile, cstring_toCharsSafe (xp));
7150 }
7151
7152 /* Now that dollars_in_ident is known, initialize is_idchar. */
7153 initialize_char_syntax (opts);
7154
7155 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
7156 and option processing. */
7157
7158 initialize_builtins (pfile);
7159
7160 /* Do standard #defines and assertions
7161 that identify system and machine type. */
7162
7163 if (!opts->inhibit_predefs) {
7164 char *p = (char *) dmalloc (strlen (predefs) + 1);
7165 strcpy (p, predefs);
7166
7167 while (*p)
7168 {
7169 char *q;
7170
7171 while (*p == ' ' || *p == '\t')
7172 {
7173 p++;
7174 }
7175
7176 /* Handle -D options. */
7177 if (p[0] == '-' && p[1] == 'D')
7178 {
7179 q = &p[2];
7180
7181 while (*p && *p != ' ' && *p != '\t')
7182 {
7183 p++;
7184 }
7185
7186 if (*p != 0)
7187 {
7188 *p++= 0;
7189 }
7190
7191 if (opts->debug_output)
7192 {
7193 output_line_command (pfile, 0, same_file);
7194 }
7195
7196 cppReader_define (pfile, q);
7197
7198 while (*p == ' ' || *p == '\t')
7199 {
7200 p++;
7201 }
7202 }
7203 else
7204 {
7205 abort ();
7206 }
7207 }
7208
7209 sfree (p);
7210 }
7211
7212 opts->done_initializing = 1;
7213
7214 { /* Read the appropriate environment variable and if it exists
7215 replace include_defaults with the listed path. */
7216 char *epath = 0;
7217#ifdef __CYGWIN32__
7218 char *win32epath;
7219 int win32_buf_size = 0; /* memory we need to allocate */
7220#endif
7221
7222 if (opts->cplusplus)
7223 {
7224 epath = getenv ("CPLUS_INCLUDE_PATH");
7225 }
7226 else
7227 {
7228 epath = getenv ("C_INCLUDE_PATH");
7229 }
7230
7231 /*
7232 ** If the environment var for this language is set,
7233 ** add to the default list of include directories.
7234 */
7235
7236 if (epath != NULL) {
7237 char *nstore = (char *) dmalloc (strlen (epath) + 2);
7238 int num_dirs;
7239 char *startp, *endp;
7240
7241#ifdef __CYGWIN32__
7242 /* if we have a posix path list, convert to win32 path list */
7243 if (cygwin32_posix_path_list_p (epath))
7244 {
7245 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
7246 win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
7247 cygwin32_posix_to_win32_path_list (epath, win32epath);
7248 epath = win32epath;
7249 }
7250#endif
7251 for (num_dirs = 1, startp = epath; *startp; startp++)
7252 {
7253 if (*startp == PATH_SEPARATOR)
7254 num_dirs++;
7255 }
7256
7257 /*@-sizeoftype@*/
7258 include_defaults
7259 = (struct default_include *) dmalloc ((num_dirs
7260 * sizeof (struct default_include))
7261 + sizeof (include_defaults_array));
7262 /*@=sizeoftype@*/
7263
7264 startp = endp = epath;
7265 num_dirs = 0;
7266 while (1) {
7267 /* Handle cases like c:/usr/lib:d:/gcc/lib */
7268 if ((*endp == PATH_SEPARATOR) || *endp == 0)
7269 {
7270 strncpy (nstore, startp, size_fromInt (endp - startp));
7271 if (endp == startp)
7272 {
7273 strcpy (nstore, ".");
7274 }
7275 else
7276 {
7277 nstore[endp-startp] = '\0';
7278 }
7279
7280 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
7281 include_defaults[num_dirs].cplusplus = opts->cplusplus;
7282 include_defaults[num_dirs].cxx_aware = 1;
7283 num_dirs++;
7284
7285 if (*endp == '\0')
7286 {
7287 break;
7288 }
7289 endp = startp = endp + 1;
7290 }
7291 else
7292 {
7293 endp++;
7294 }
7295 }
7296 /* Put the usual defaults back in at the end. */
7297 memcpy ((char *) &include_defaults[num_dirs],
7298 (char *) include_defaults_array,
7299 sizeof (include_defaults_array));
7300
7301 sfree (nstore);
7302 /*@-branchstate@*/ } /*@=branchstate@*/
7303 }
7304
7305 cppReader_appendIncludeChain (pfile, opts->before_system,
7306 opts->last_before_system);
7307 opts->first_system_include = opts->before_system;
7308
7309 /* Unless -fnostdinc,
7310 tack on the standard include file dirs to the specified list */
7311 if (!opts->no_standard_includes) {
7312 struct default_include *p = include_defaults;
7313 char *specd_prefix = opts->include_prefix;
7314 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
7315 int default_len = 0;
7316
7317 /* Remove the `include' from /usr/local/lib/gcc.../include. */
7318 if (default_prefix != NULL) {
7319 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
7320 default_len = strlen (default_prefix) - 7;
7321 default_prefix[default_len] = 0;
7322 }
7323 }
7324
7325 /* Search "translated" versions of GNU directories.
7326 These have /usr/local/lib/gcc... replaced by specd_prefix. */
7327 if (specd_prefix != 0 && default_len != 0)
7328 for (p = include_defaults; p->fname != NULL; p++) {
7329 /* Some standard dirs are only for C++. */
7330 if (!p->cplusplus
7331 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
7332 /* Does this dir start with the prefix? */
7333 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
7334 size_fromInt (default_len)))
7335 {
7336 /* Yes; change prefix and add to search list. */
7337 struct file_name_list *nlist
7338 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7339 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
7340 char *str = (char *) dmalloc (this_len + 1);
7341 strcpy (str, specd_prefix);
7342 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
7343
7344 nlist->next = NULL;
7345 nlist->fname = cstring_fromChars (str);
7346 nlist->control_macro = 0;
7347 nlist->c_system_include_path = !p->cxx_aware;
7348 nlist->got_name_map = 0;
7349
7350 cppReader_addIncludeChain (pfile, nlist);
7351 if (opts->first_system_include == 0)
7352 {
7353 opts->first_system_include = nlist;
7354 }
7355 }
7356 }
7357 }
7358
7359 /* Search ordinary names for GNU include directories. */
7360
7361 for (p = include_defaults; p->fname != NULL; p++)
7362 {
7363 /* Some standard dirs are only for C++. */
7364 if (!p->cplusplus
7365 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
7366 {
7367 struct file_name_list *nlist
7368 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7369 nlist->control_macro = 0;
7370 nlist->c_system_include_path = !p->cxx_aware;
7371 nlist->fname = p->fname;
7372 nlist->got_name_map = 0;
7373 nlist->next = NULL;
7374
7375 cppReader_addIncludeChain (pfile, nlist);
7376
7377 if (opts->first_system_include == 0)
7378 {
7379 opts->first_system_include = nlist;
7380 }
7381 }
7382 }
7383 sfree (default_prefix);
7384 }
7385
7386 /* Tack the after_include chain at the end of the include chain. */
7387 cppReader_appendIncludeChain (pfile, opts->after_include,
7388 opts->last_after_include);
7389
7390 if (opts->first_system_include == 0)
7391 {
7392 opts->first_system_include = opts->after_include;
7393 }
7394
7395 /* With -v, print the list of dirs to search. */
7396 if (opts->verbose) {
7397 struct file_name_list *p;
7398 fprintf (stderr, "#include \"...\" search starts here:\n");
7399
7400 for (p = opts->include; p != NULL; p = p->next) {
7401 if (p == opts->first_bracket_include)
7402 fprintf (stderr, "#include <...> search starts here:\n");
7403
7404 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7405 }
7406 fprintf (stderr, "End of search list.\n");
7407 }
7408}
7409
7410int cppReader_startProcess (cppReader *pfile, cstring fname)
7411{
7412 cppBuffer *fp;
7413 int f;
7414 struct cppOptions *opts = CPPOPTIONS (pfile);
7415
7416 fp = cppReader_pushBuffer (pfile, NULL, 0);
7417
7418 if (fp == NULL)
7419 {
7420 return 0;
7421 }
7422
7423 if (opts->in_fname == NULL)
7424 {
7425 opts->in_fname = cstring_makeLiteralTemp ("");
7426 }
7427
7428 fp->fname = opts->in_fname;
7429 fp->nominal_fname = fp->fname;
7430 fp->lineno = 0;
7431
7432 /* Copy the entire contents of the main input file into
7433 the stacked input buffer previously allocated for it. */
7434
7435 if (cstring_isEmpty (fname))
7436 {
7437 fname = cstring_makeLiteralTemp ("");
7438 f = 0;
7439 }
7440 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
7441 {
7442 cppReader_error (pfile,
7443 message ("Error opening %s for reading: %s",
7444 fname, lldecodeerror (errno)));
7445
7446 return 0;
7447 }
7448 else
7449 {
7450 ;
7451 }
7452
7453 if (finclude (pfile, f, fname, 0, NULL))
7454 {
7455 output_line_command (pfile, 0, same_file);
7456 }
7457
7458 return 1;
7459}
7460
7461static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7462{
7463 return pfile->buffer;
7464}
7465
7466/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7467{
7468 llassert (pfile->buffer != NULL);
7469 return pfile->buffer;
7470}
7471
7472/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7473{
7474 llassert (buf->buf != NULL);
7475 return (buf->buf + buf->line_base);
7476}
7477
3e3ec469 7478int cpplib_bufPeek (cppBuffer *buf)
ac0860d8 7479{
7480 if (buf->cur == NULL || buf->rlimit == NULL) {
7481 return EOF;
7482 }
7483
7484 if (buf->cur < buf->rlimit) {
7485 return *(buf->cur);
7486 }
7487
7488 return EOF;
7489}
7490
7491bool cppBuffer_isMacro (cppBuffer *buf)
7492{
7493 if (buf != NULL)
7494 {
7495 return (buf->cleanup == cppReader_macroCleanup);
7496 }
7497
7498 return FALSE;
7499}
7500
7501/*
7502** Returns true if the macro should be checked, false
7503** if it should be expanded normally.
7504*/
7505
7506static bool notparseable = FALSE; /* preceeded by @notparseable@ */
7507static bool notfunction = FALSE; /* preceeded by @notfunction@ */
7508static bool expectiter = FALSE; /* preceeded by @iter@ */
7509static bool expectenditer = FALSE; /* second after @iter@ */
7510static bool expectfunction = FALSE; /* preceeded by @function@ */
7511static bool expectconstant = FALSE; /* preceeded by @constant@ */
7512static bool expectmacro = FALSE; /* preceeded by notfunction or notparseable */
7513
7514static void cpp_setLocation (cppReader *pfile)
7515{
7516 fileId fid;
7517 int line;
7518
7519 if (pfile->buffer != NULL)
7520 {
7521 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
7522 {
7523 cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
7524
7525 DPRINTF (("Looking up: %s", fname));
7526
7527 if (fileTable_exists (context_fileTable (), fname))
7528 {
7529 fid = fileTable_lookup (context_fileTable (), fname);
7530 }
7531 else
7532 {
7533 DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
7534
7535 fid = fileTable_lookup (context_fileTable (),
7536 cppReader_getBuffer (pfile)->fname);
7537 }
7538 }
7539 else
7540 {
7541 fid = fileTable_lookup (context_fileTable (),
7542 cppReader_getBuffer (pfile)->fname);
7543 }
7544
7545 line = cppReader_getBuffer (pfile)->lineno;
7546 fileloc_free (g_currentloc);
7547
7548 if (fileId_isValid (fid))
7549 {
7550 g_currentloc = fileloc_create (fid, line, 1);
7551 }
7552 else
7553 {
7554 g_currentloc = fileloc_createBuiltin ();
7555 }
7556 }
7557 else
7558 {
7559 fileloc_free (g_currentloc);
7560 g_currentloc = fileloc_createBuiltin ();
7561 }
7562}
7563
2209bcb7 7564static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
ac0860d8 7565{
7566 bool checkmacro = FALSE;
7567 bool hasParams = FALSE;
7568 bool noexpand = FALSE;
7569 cstring sname;
7570 char c;
7571
7572 cpp_setLocation (pfile);
7573
7574 DPRINTF (("Should check macro? %s", p));
7575
7576 if (expectiter || expectconstant || expectenditer)
7577 {
7578 if (expectiter)
7579 {
7580 expectiter = FALSE;
7581 expectenditer = TRUE;
7582 }
7583 else
7584 {
7585 expectiter = FALSE;
7586 expectconstant = FALSE;
7587 expectenditer = FALSE;
7588 }
7589
7590 if (notfunction || notparseable)
7591 {
7592 notfunction = FALSE;
7593 notparseable = FALSE;
7594 return FALSE;
7595 }
7596 else
7597 {
7598 return TRUE;
7599 }
7600 }
7601
7602 llassert (*p == '#');
7603 p++;
7604
7605 while (*p == ' ' || *p == '\t')
7606 {
7607 p++;
7608 }
7609
7610 llassert (*p == 'd'); /* define starts */
7611
7612 p += 6;
7613
7614 while (*p == ' ' || *p == '\t')
7615 {
7616 p++;
7617 }
7618
7619 sname = cstring_fromChars (p);
7620 DPRINTF (("Check macro: %s", sname));
7621
7622 while (((c = *p) != ' ')
7623 && c != '\0' && c != '('
7624 && c != '\t' && c != '\\' && c != '\n'
7625 && !iscntrl (c))
7626 {
7627 p++;
7628 }
7629
7630 hasParams = (c == '(');
7631 *p = '\0';
7632
ac0860d8 7633 if (notparseable)
7634 {
7635 notparseable = FALSE;
7636 }
7637 else if (notfunction || fileloc_isStandardLib (g_currentloc))
7638 {
7639 DPRINTF (("Clear notfunction"));
7640 notfunction = FALSE;
7641 }
7642 else
7643 {
7644 if (noexpand)
7645 {
7646 checkmacro = TRUE;
7647
7648 if (!expectenditer)
7649 {
7650 noexpand = FALSE;
7651 }
7652 }
7653 else
7654 {
7655 if (usymtab_existsReal (sname))
7656 {
7657 uentry ue = usymtab_lookup (sname);
7658
7659 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7660
7661 if (fileloc_isPreproc (uentry_whereLast (ue)))
7662 {
7663 goto macroDne;
7664 }
7665 else
7666 {
7667 if (uentry_isSpecified (ue))
7668 {
7669 checkmacro = context_getFlag (FLG_SPECMACROS);
7670 }
7671 else
7672 {
7673 if (hasParams)
7674 {
7675 checkmacro = context_getFlag (FLG_LIBMACROS)
7676 || context_getFlag (FLG_FCNMACROS);
7677 }
7678 }
7679 }
7680 }
7681 else
7682 {
7683 macroDne:
7684 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7685
7686 if (fileloc_isSystemFile (g_currentloc)
7687 && context_getFlag (FLG_SYSTEMDIREXPAND))
7688 {
7689 ; /* don't check this macro */
7690 DPRINTF (("Don't check 1"));
7691 }
7692 else
7693 {
7694 uentry le;
7695
7696 if (hasParams)
7697 {
7698 DPRINTF (("Has params..."));
7699
7700 if (context_getFlag (FLG_FCNMACROS))
7701 {
7702 if (usymtab_exists (sname))
7703 {
7704 /*
7705 ** only get here is macro is redefined
7706 ** error reported elsewhere
7707 */
7708
7709 DPRINTF (("It exists!"));
7710 }
7711 else
7712 {
7713 /*
7714 ** We make it a forward function, since it might be declared elsewhere.
7715 ** After all headers have been processed, we should check the forward
7716 ** functions.
7717 */
7718
7719 fileloc loc = fileloc_makePreproc (g_currentloc);
7720
7721 /* the line is off-by-one, since the newline was already read */
7722 decLine ();
7723
7724 if (expectfunction)
7725 {
7726 expectfunction = FALSE;
7727 }
7728
7729 le = uentry_makeForwardFunction (sname,
7730 typeId_invalid, loc);
7731
7732 fileloc_free (loc);
7733
7734 incLine ();
7735
7736 /* Do not define here! */
7737
7738 (void) usymtab_addEntry (le);
7739 }
7740
7741 checkmacro = TRUE;
7742 DPRINTF (("Check: TRUE"));
7743 }
7744 else
7745 {
7746 DPRINTF (("Flag FCN_MACROS not set!"));
7747 }
7748 }
7749 else
7750 {
7751 DPRINTF (("No params"));
7752
7753 if (context_getFlag (FLG_CONSTMACROS))
7754 {
7755 bool nocontent = FALSE;
7756
7757 if (c == '\0')
7758 {
7759 nocontent = TRUE;
7760 }
7761 else
7762 {
7763 if (isspace (c))
7764 {
7765 char *rest = p + 1;
7766
7767 /*
7768 ** Check if there is nothing after the define.
7769 */
7770
7771 while ((*rest) != '\0' && isspace (*rest))
7772 {
7773 rest++;
7774 }
7775
7776 if (*rest == '\0')
7777 {
7778 nocontent = TRUE; /* empty macro, don't check */
7779 }
7780 }
7781 }
7782
7783 if (usymtab_exists (sname))
7784 {
7785 ;
7786 }
7787 else
7788 {
7789 fileloc loc = fileloc_makePreproc (g_currentloc);
7790 DPRINTF (("Make constant: %s", sname));
5e211f69 7791 le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
ac0860d8 7792 (void) usymtab_addEntry (le);
7793 }
7794
7795 checkmacro = !nocontent;
7796 }
7797 }
7798 }
7799
7800 if (checkmacro && usymtab_existsType (sname))
7801 {
7802 DPRINTF (("Making false..."));
7803 decLine ();
7804 ppllerror (message ("Specified type implemented as macro: %s", sname));
7805 checkmacro = FALSE;
7806 incLine ();
7807 }
7808 }
7809 }
7810 }
7811
7812 if (!checkmacro)
7813 {
7814 if (usymtab_exists (sname))
7815 {
7816 uentry ue = usymtab_lookupExpose (sname);
7817 fileloc tloc = fileloc_makePreproc (g_currentloc);
7818
7819 uentry_setDefined (ue, tloc);
7820 fileloc_free (tloc);
7821 uentry_setUsed (ue, fileloc_undefined);
7822 }
7823 else
7824 {
7825 fileloc tloc = fileloc_makePreproc (g_currentloc);
7826 uentry ue = uentry_makeExpandedMacro (sname, tloc);
7827 DPRINTF (("Make expanded macro: %s", sname));
7828 DPRINTF (("Not in symbol table: %s", sname));
7829
7830 (void) usymtab_addGlobalEntry (ue);
7831 fileloc_free (tloc);
7832 }
7833 }
7834
7835 *p = c;
7836 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
7837 return checkmacro;
7838}
7839
7840static enum cpp_token
7841cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
7842{
7843 cppBuffer *pbuf = cppReader_getBuffer (pfile);
7844 char *start;
7845 int len;
7846 bool eliminateComment = FALSE;
7847
7848 llassert (pbuf->buf != NULL);
7849
7850 start = pbuf->buf + smark->position;
7851
7852 llassert (pbuf->cur != NULL);
7853 len = pbuf->cur - start;
7854
7855 if (start[0] == '*'
7856 && start[1] == context_getCommentMarkerChar ())
7857 {
7858 int i;
7859 char c = ' ';
7860 char *scomment = start + 2;
7861 char savec = start[len];
7862
7863 start[0] = BEFORE_COMMENT_MARKER[0];
7864 start[1] = BEFORE_COMMENT_MARKER[1];
7865
7866 llassert (start[len - 2] == '*');
7867 start[len - 2] = AFTER_COMMENT_MARKER[0];
7868
7869 llassert (start[len - 1] == '/');
7870 start[len - 1] = AFTER_COMMENT_MARKER[1];
7871
3e3ec469 7872 cpplib_reserve(pfile, size_fromInt (1 + len));
ac0860d8 7873 cppReader_putCharQ (pfile, c);
7874
7875 cpp_setLocation (pfile);
7876
7877 start[len] = '\0';
7878
7879 if (mstring_containsString (scomment, "/*"))
7880 {
7881 (void) cppoptgenerror
7882 (FLG_NESTCOMMENT,
7883 message ("Comment starts inside syntactic comment: %s",
7884 cstring_fromChars (scomment)),
7885 pfile);
7886 }
7887
7888 start[len] = savec;
7889
7890 if (mstring_equalPrefix (scomment, "ignore"))
7891 {
7892 if (!context_getFlag (FLG_NOCOMMENTS))
7893 {
7894 context_enterSuppressRegion ();
7895 }
7896 }
7897 else if (mstring_equalPrefix (scomment, "end"))
7898 {
7899 if (!context_getFlag (FLG_NOCOMMENTS))
7900 {
7901 context_exitSuppressRegion ();
7902 }
7903 }
7904 else if (mstring_equalPrefix (scomment, "notparseable"))
7905 {
7906 notparseable = TRUE;
7907 expectmacro = TRUE;
7908 eliminateComment = TRUE;
7909 }
7910 else if (mstring_equalPrefix (scomment, "notfunction"))
7911 {
7912 notfunction = TRUE;
7913 expectmacro = TRUE;
7914 eliminateComment = TRUE;
7915 }
7916 else if (mstring_equalPrefix (scomment, "iter"))
7917 {
7918 expectiter = TRUE;
7919 }
7920 else if (mstring_equalPrefix (scomment, "function"))
7921 {
7922 expectfunction = TRUE;
7923 }
7924 else if (mstring_equalPrefix (scomment, "constant"))
7925 {
7926 expectconstant = TRUE;
7927 }
7928 else
7929 {
7930 char sChar = *scomment;
7931
7932 if (sChar == '='
7933 || sChar == '-'
7934 || sChar == '+')
7935 {
7936 char *rest = scomment + 1;
7937
7938 if (mstring_equalPrefix (rest, "commentchar"))
7939 {
7940 eliminateComment = TRUE;
7941
7942 if (sChar == '=')
7943 {
7944 ppllerror (cstring_makeLiteral
7945 ("Cannot restore commentchar"));
7946 }
7947 else
7948 {
7949 char *next = scomment + 12; /* strlen commentchar = 12 */
7950
7951 if (*next != ' ' && *next != '\t' && *next != '\n')
7952 {
7953 ppllerror
7954 (message
7955 ("Syntactic commentchar comment is not followed by a "
7956 "whitespace character: %c",
7957 *next));
7958 }
7959 else
7960 {
7961 char cchar = *(next + 1);
7962
7963 if (cchar == '\0')
7964 {
7965 ppllerror
7966 (cstring_makeLiteral
7967 ("Cannot set commentchar to NUL"));
7968 }
7969 else
7970 {
7971 context_setCommentMarkerChar (cchar);
7972 /* setComment = TRUE; */
7973 }
7974 }
7975 }
7976 }
7977 else if (mstring_equalPrefix (scomment, "nestcomment"))
7978 {
7979 /* fix from Mike Miller <MikeM@xata.com> */
7980 context_fileSetFlag (FLG_NESTCOMMENT,
7981 ynm_fromCodeChar (sChar));
7982 }
7983 else if (mstring_equalPrefix (rest, "namechecks"))
7984 {
7985 context_fileSetFlag (FLG_NAMECHECKS,
7986 ynm_fromCodeChar (sChar));
7987 }
7988 else if (mstring_equalPrefix (rest, "macroredef"))
7989 {
7990 context_fileSetFlag (FLG_MACROREDEF,
7991 ynm_fromCodeChar (sChar));
7992 }
7993 else if (mstring_equalPrefix (rest, "usevarargs"))
7994 {
7995 context_fileSetFlag (FLG_USEVARARGS,
7996 ynm_fromCodeChar (sChar));
7997 }
7998 else if (mstring_equalPrefix (rest, "nextlinemacros"))
7999 {
8000 context_fileSetFlag (FLG_MACRONEXTLINE,
8001 ynm_fromCodeChar (sChar));
8002 }
8003 else if (mstring_equalPrefix (rest, "allmacros")
8004 || mstring_equalPrefix (rest, "fcnmacros")
8005 || mstring_equalPrefix (rest, "constmacros"))
8006 {
8007 flagcode fl;
8008
8009 if (mstring_equalPrefix (rest, "allmacros"))
8010 {
8011 fl = FLG_ALLMACROS;
8012 }
8013 else if (mstring_equalPrefix (rest, "fcnmacros"))
8014 {
8015 fl = FLG_FCNMACROS;
8016 }
8017 else
8018 {
8019 llassert (mstring_equalPrefix (rest, "constmacros"));
8020 fl = FLG_CONSTMACROS;
8021 }
8022
8023
8024 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
8025 notfunction = FALSE;
8026 }
8027 else
8028 {
8029 ;
8030 }
8031 }
8032 else
8033 {
8034 ;
8035 }
8036 }
8037
8038 if (eliminateComment)
8039 {
8040 goto removeComment;
8041 }
8042
8043 /* Replaces comment char's in start with spaces */
8044
8045 for (i = 2; i < len - 2; i++)
8046 {
8047 if (start[i] == BEFORE_COMMENT_MARKER[0]
8048 || start[i] == BEFORE_COMMENT_MARKER[1]
8049 || start[i] == context_getCommentMarkerChar ())
8050 {
8051 start[i] = ' ';
8052 }
8053 }
8054
8055 cppReader_putStrN (pfile, start, size_fromInt (len));
8056 parseClearMark (smark);
8057 return CPP_COMMENT;
8058 }
8059 else
8060 {
8061 removeComment:
8062 {
8063 int i;
8064
8065 /*
8066 ** Output the comment as all spaces so line/column
8067 ** in output file is still correct.
8068 */
8069
8070 char c = ' ';
8071 cstring lintcomment = cstring_undefined;
8072
8073 if (context_getFlag (FLG_LINTCOMMENTS))
8074 {
8075 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
8076 {
8077 lintcomment = cstring_makeLiteralTemp ("l_notreach");
8078 }
8079 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
8080 {
8081 lintcomment = cstring_makeLiteralTemp ("l_printfli");
8082 }
8083 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
8084 {
8085 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
8086 }
8087 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
8088 {
8089 lintcomment = cstring_makeLiteralTemp ("l_argsus");
8090 }
8091 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
8092 {
8093 lintcomment = cstring_makeLiteralTemp ("l_fallth");
8094 }
8095 else
8096 {
8097 lintcomment = cstring_undefined;
8098 }
8099 }
8100 else
8101 {
8102 lintcomment = cstring_undefined;
8103 }
8104
8105 if (cstring_isDefined (lintcomment))
8106 {
8107 c = BEFORE_COMMENT_MARKER[0];
8108 start[0] = BEFORE_COMMENT_MARKER[1];
8109
8110 llassert (cstring_length (lintcomment) == len - 3);
8111
8112 for (i = 1; i < len - 2; i++)
8113 {
8114 start[i] = cstring_getChar (lintcomment, i);
8115 }
8116
8117 start[len - 2] = AFTER_COMMENT_MARKER[0];
8118 start[len - 1] = AFTER_COMMENT_MARKER[1];
8119 }
8120 else
8121 {
8122 /* Replaces char's in start with spaces */
8123 for (i = 0; i < len; i++)
8124 {
8125 if (start[i] == '/'
8126 && i < len - 1
8127 && start[i + 1] == '*') {
8128 (void) cppoptgenerror (FLG_NESTCOMMENT,
8129 message ("Comment starts inside comment"),
8130 pfile);
8131 }
8132
8133 if (start[i] != '\n')
8134 {
8135 start[i] = ' ';
8136 }
8137 }
8138 }
8139
3e3ec469 8140 cpplib_reserve (pfile, size_fromInt (1 + len));
ac0860d8 8141 cppReader_putCharQ (pfile, c);
8142 cppReader_putStrN (pfile, start, size_fromInt (len));
8143 parseClearMark (smark);
8144 return CPP_COMMENT;
8145 }
8146 }
8147}
8148
8149static int cpp_openIncludeFile (char *filename)
8150{
8151 int res = open (filename, O_RDONLY, 0666);
8152
8153 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
8154 if (res >= 0)
8155 {
8156 if (!fileTable_exists (context_fileTable (),
8157 cstring_fromChars (filename)))
8158 {
53a89507 8159 if (fileloc_isXHFile (g_currentloc))
8160 {
8161 /*
8162 ** Files includes by XH files are also XH files
8163 */
8164
8165 (void) fileTable_addXHFile (context_fileTable (),
ac0860d8 8166 cstring_fromChars (filename));
53a89507 8167 }
8168 else
8169 {
8170 (void) fileTable_addHeaderFile (context_fileTable (),
8171 cstring_fromChars (filename));
8172 }
ac0860d8 8173 }
8174 else
8175 {
8176 DPRINTF (("File already exists: %s", filename));
8177 }
8178 }
8179
8180 return res;
8181}
8182
8183static bool cpp_skipIncludeFile (cstring fname)
8184{
8185 if (context_isSystemDir (fname))
8186 {
8187 DPRINTF (("System dir: %s", fname));
8188
8189 if (lcllib_isSkipHeader (fname))
8190 {
8191 DPRINTF (("Skip include TRUE: %s", fname));
8192 return TRUE;
8193 }
8194
8195 if (context_getFlag (FLG_SKIPSYSHEADERS))
8196 {
8197 DPRINTF (("Skip include TRUE: %s", fname));
8198 return TRUE;
8199 }
8200 }
8201
8202 if (context_getFlag (FLG_SINGLEINCLUDE))
8203 {
8204 fname = removePreDirs (fname);
8205
8206# if defined (WIN32) || defined (OS2)
8207 cstring_replaceAll (fname, '\\', '/');
8208# endif
8209
8210 if (fileTable_exists (context_fileTable (), fname))
8211 {
8212 DPRINTF (("Skip include TRUE: %s", fname));
8213 return TRUE;
8214 }
8215 }
8216
8217 DPRINTF (("Skip include FALSE: %s", fname));
8218 return FALSE;
8219}
8220
8221static int cpp_peekN (cppReader *pfile, int n)
8222{
8223 cppBuffer *buf = cppReader_getBuffer (pfile);
8224
8225 llassert (buf->cur != NULL);
8226
8227 return (buf->rlimit - buf->cur >= (n)
8228 ? buf->cur[n]
8229 : EOF);
8230}
8231
8232cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
8233{
8234 return buf + 1;
8235}
8236
8237void cppBuffer_forward (cppBuffer *buf, int n)
8238{
8239 llassert (buf->cur != NULL);
8240 buf->cur += n;
8241}
This page took 1.333929 seconds and 5 git commands to generate.