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