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