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