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