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