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