]> andersk Git - splint.git/blame - src/cpplib.c
Some work on the files in os2/, removed unnecessary
[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@*/
9622303f 4934#if defined (OS2) && defined (__IBMC__)
4935 /* Dummy code to eleminate optimization problems with icc */
4936 c = 0;
4937# endif
4938
ac0860d8 4939 }
4940 /*@=branchstate@*/
4941 break;
4942 }
4943
4944 /* Don't let erroneous code go by. */
4945
4946 if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
4947 && cppReader_isPedantic (pfile))
4948 {
4949 cppReader_pedwarnLit (pfile,
4950 cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
4951 }
4952 }
4953
4954 c = cppReader_getC (pfile);
4955 }
4956 /* We're in the middle of a line. Skip the rest of it. */
4957 for (;;) {
4958 size_t old;
4959
4960 switch (c)
4961 {
4962 case EOF:
4963 goto done;
4964 case '/': /* possible comment */
4965 c = skip_comment (pfile, NULL);
4966 if (c == EOF)
4967 goto done;
4968 /*@switchbreak@*/ break;
4969 case '\"':
4970 case '\'':
4971 cppReader_forward (pfile, -1);
4972 old = cppReader_getWritten (pfile);
4973 (void) cppGetToken (pfile);
4974 cppReader_setWritten (pfile, old);
4975 /*@switchbreak@*/ break;
4976 case '\\':
4977 /* Char after backslash loses its special meaning. */
4978 if (cppReader_peekC (pfile) == '\n')
4979 {
4980 cppReader_forward (pfile, 1);
4981 }
4982
4983 /*@switchbreak@*/ break;
4984 case '\n':
4985 goto beg_of_line;
4986 }
4987 c = cppReader_getC (pfile);
4988 }
4989done:
4990 if (CPPOPTIONS (pfile)->output_conditionals) {
4991 static char end_failed[] = "#endfailed\n";
4992 cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
4993 pfile->lineno++;
4994 }
4995 pfile->only_seen_white = 1;
4996
4997 parseGotoMark (&line_start_mark, pfile);
4998 parseClearMark (&line_start_mark);
4999}
5000
5001/*
5002 * handle a #else directive. Do this by just continuing processing
5003 * without changing if_stack ; this is so that the error message
5004 * for missing #endif's etc. will point to the original #if. It
5005 * is possible that something different would be better.
5006 */
5007
5008static int
5009do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5010 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5011{
5012 if (cppReader_isPedantic (pfile))
5013 {
5014 validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5015 }
5016
5017 cppReader_skipRestOfLine (pfile);
5018
5019 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack) {
5020 cppReader_errorLit (pfile,
5021 cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5022 return 0;
5023 } else {
5024 /* #ifndef can't have its special treatment for containing the whole file
5025 if it has a #else clause. */
5026
5027 llassert (pfile->if_stack != NULL);
5028
5029 pfile->if_stack->control_macro = 0;
5030
5031 if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5032 {
5033 cpp_setLocation (pfile);
5034 genppllerrorhint (FLG_PREPROC,
5035 message ("Pre-processor directive #else after #else"),
5036 message ("%q: Location of match",
5037 fileloc_unparseRaw (pfile->if_stack->fname,
5038 pfile->if_stack->lineno)));
5039 }
5040
5041 pfile->if_stack->type = T_ELSE;
5042 }
5043
5044 if (pfile->if_stack->if_succeeded)
5045 skip_if_group (pfile, 0);
5046 else {
5047 ++pfile->if_stack->if_succeeded; /* continue processing input */
5048 output_line_command (pfile, 1, same_file);
5049 }
5050
5051 return 0;
5052}
5053
5054/*
5055 * unstack after #endif command
5056 */
5057
5058static int
5059do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5060 /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5061{
5062 if (cppReader_isPedantic (pfile))
5063 {
5064 validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5065 }
5066
5067 cppReader_skipRestOfLine (pfile);
5068
5069 if (pfile->if_stack == cppReader_getBuffer (pfile)->if_stack)
5070 {
5071 cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5072 }
5073 else
5074 {
5075 cppIfStackFrame *temp = pfile->if_stack;
5076
5077 llassert (temp != NULL);
5078
5079 pfile->if_stack = temp->next;
5080 if (temp->control_macro != 0)
5081 {
5082 /* This #endif matched a #ifndef at the start of the file.
5083 See if it is at the end of the file. */
5084 struct parse_marker start_mark;
5085 int c;
5086
5087 parseSetMark (&start_mark, pfile);
5088
5089 for (;;)
5090 {
5091 cppSkipHspace (pfile);
5092 c = cppReader_getC (pfile);
5093
5094 if (c != '\n')
5095 break;
5096 }
5097
5098 parseGotoMark (&start_mark, pfile);
5099 parseClearMark (&start_mark);
5100
5101 if (c == EOF)
5102 {
5103 /* If we get here, this #endif ends a #ifndef
5104 that contains all of the file (aside from whitespace).
5105 Arrange not to include the file again
5106 if the macro that was tested is defined.
5107
5108 Do not do this for the top-level file in a -include or any
5109 file in a -imacros. */
5110 struct file_name_list *ifile = pfile->all_include_files;
5111
5112 for ( ; ifile != NULL; ifile = ifile->next)
5113 {
5114 if (cstring_equal (ifile->fname, cppReader_getBuffer (pfile)->fname))
5115 {
5116 ifile->control_macro = temp->control_macro;
5117 break;
5118 }
5119 }
5120 }
5121 }
5122
5123 sfree (temp);
5124 output_line_command (pfile, 1, same_file);
5125 }
5126 return 0;
5127}
5128
5129/* When an #else or #endif is found while skipping failed conditional,
5130 if -pedantic was specified, this is called to warn about text after
5131 the command name. P points to the first char after the command name. */
5132
5133static void
5134validate_else (cppReader *pfile, cstring directive)
5135{
5136 int c;
5137 cppSkipHspace (pfile);
5138 c = cppReader_peekC (pfile);
5139 if (c != EOF && c != '\n')
5140 {
5141 cppReader_pedwarn (pfile,
5142 message ("text following `%s' violates ANSI standard", directive));
5143 }
5144}
5145
5146/*
5147** Get the next token, and add it to the text in pfile->token_buffer.
5148** Return the kind of token we got.
5149*/
5150
5151enum cpp_token
5152cppGetToken (cppReader *pfile)
5153{
5154 int c, c2, c3;
5155 size_t old_written = 0;
5156 int start_line, start_column;
5157 enum cpp_token token;
5158 struct cppOptions *opts = CPPOPTIONS (pfile);
5159 cppReader_getBuffer (pfile)->prev = cppReader_getBuffer (pfile)->cur;
5160
5161get_next:
5162 c = cppReader_getC (pfile);
5163
5164 if (c == EOF)
5165 {
5166 handle_eof:
5167 if (cppReader_getBuffer (pfile)->seen_eof)
5168 {
5169 cppBuffer *buf = cppReader_popBuffer (pfile);
5170
5171 if (buf != cppReader_nullBuffer (pfile))
5172 {
5173 goto get_next;
5174 }
5175 else
5176 {
5177 return CPP_EOF;
5178 }
5179 }
5180 else
5181 {
5182 cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
5183 cppReader_getBuffer (pfile)->seen_eof = 1;
5184
5185 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname)
5186 && next_buf != cppReader_nullBuffer (pfile))
5187 {
5188 /* We're about to return from an #include file.
5189 Emit #line information now (as part of the CPP_POP) result.
5190 But the #line refers to the file we will pop to. */
5191 cppBuffer *cur_buffer = CPPBUFFER (pfile);
5192 CPPBUFFER (pfile) = next_buf;
5193 pfile->input_stack_listing_current = 0;
5194 output_line_command (pfile, 0, leave_file);
5195 CPPBUFFER (pfile) = cur_buffer;
5196 }
5197 return CPP_POP;
5198 }
5199 }
5200 else
5201 {
5202 long newlines;
5203 struct parse_marker start_mark;
5204
5205 switch (c)
5206 {
5207 case '/':
5208 if (cppReader_peekC (pfile) == '=')
5209 {
5210 goto op2;
5211 }
5212
5213 if (opts->put_out_comments)
5214 {
5215 parseSetMark (&start_mark, pfile);
5216 }
5217
5218 newlines = 0;
5219 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
5220 &start_line, &start_column);
5221 c = skip_comment (pfile, &newlines);
5222
5223 if (opts->put_out_comments && (c == '/' || c == EOF))
5224 {
5225 assertSet (&start_mark);
5226 parseClearMark (&start_mark);
5227 }
5228
5229 if (c == '/')
5230 goto randomchar;
5231 if (c == EOF)
5232 {
5233 cppReader_errorWithLine (pfile, start_line, start_column,
5234 cstring_makeLiteral ("Unterminated comment"));
5235 goto handle_eof;
5236 }
5237 c = '/'; /* Initial letter of comment. */
5238 return_comment:
5239 /* Comments are equivalent to spaces.
5240 For -traditional, a comment is equivalent to nothing. */
5241
5242 if (opts->put_out_comments)
5243 {
5244 enum cpp_token res;
5245
5246 assertSet (&start_mark);
5247 res = cpp_handleComment (pfile, &start_mark);
5248 pfile->lineno += newlines;
5249 return res;
5250 }
5251 else if (cppReader_isTraditional (pfile))
5252 {
5253 return CPP_COMMENT;
5254 }
5255 else
5256 {
5257 cppReader_reserve(pfile, 1);
5258 cppReader_putCharQ (pfile, ' ');
5259 return CPP_HSPACE;
5260 }
5261
5262 case '#':
5263 if (!pfile->only_seen_white)
5264 {
5265 goto randomchar;
5266 }
5267
5268 if (cppReader_handleDirective (pfile))
5269 {
5270 return CPP_DIRECTIVE;
5271 }
5272
5273 pfile->only_seen_white = 0;
5274 return CPP_OTHER;
5275
5276 case '\"':
5277 case '\'':
5278 /* A single quoted string is treated like a double -- some
5279 programs (e.g., troff) are perverse this way */
5280 cppBuffer_lineAndColumn (cppReader_fileBuffer (pfile),
5281 &start_line, &start_column);
5282 old_written = cppReader_getWritten (pfile);
5283 string:
5284 cppReader_putChar (pfile, c);
5285 while (TRUE)
5286 {
5287 int cc = cppReader_getC (pfile);
5288 if (cc == EOF)
5289 {
5290 if (cppBuffer_isMacro (CPPBUFFER (pfile)))
5291 {
5292 /* try harder: this string crosses a macro expansion
5293 boundary. This can happen naturally if -traditional.
5294 Otherwise, only -D can make a macro with an unmatched
5295 quote. */
5296 cppBuffer *next_buf
5297 = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
5298 (*cppReader_getBuffer (pfile)->cleanup)
5299 (cppReader_getBuffer (pfile), pfile);
5300 CPPBUFFER (pfile) = next_buf;
5301 continue;
5302 }
5303 if (!cppReader_isTraditional (pfile))
5304 {
5305 cpp_setLocation (pfile);
5306
5307 setLine (long_toInt (start_line));
5308 setColumn (long_toInt (start_column));
5309
5310 if (pfile->multiline_string_line != long_toInt (start_line)
5311 && pfile->multiline_string_line != 0)
5312 {
5313 genppllerrorhint
5314 (FLG_PREPROC,
5315 message ("Unterminated string or character constant"),
5316 message ("%q: Possible real start of unterminated constant",
5317 fileloc_unparseRaw
5318 (fileloc_filename (g_currentloc),
5319 pfile->multiline_string_line)));
5320 pfile->multiline_string_line = 0;
5321 }
5322 else
5323 {
5324 genppllerror
5325 (FLG_PREPROC,
5326 message ("Unterminated string or character constant"));
5327 }
5328 }
5329 /*@loopbreak@*/ break;
5330 }
5331 cppReader_putChar (pfile, cc);
5332 switch (cc)
5333 {
5334 case '\n':
5335 /* Traditionally, end of line ends a string constant with
5336 no error. So exit the loop and record the new line. */
5337 if (cppReader_isTraditional (pfile))
5338 goto while2end;
5339 if (c == '\'')
5340 {
5341 goto while2end;
5342 }
5343 if (cppReader_isPedantic (pfile)
5344 && pfile->multiline_string_line == 0)
5345 {
5346 cppReader_pedwarnWithLine
5347 (pfile, long_toInt (start_line),
5348 long_toInt (start_column),
5349 cstring_makeLiteral ("String constant runs past end of line"));
5350 }
5351 if (pfile->multiline_string_line == 0)
5352 {
5353 pfile->multiline_string_line = start_line;
5354 }
5355
5356 /*@switchbreak@*/ break;
5357
5358 case '\\':
5359 cc = cppReader_getC (pfile);
5360 if (cc == '\n')
5361 {
5362 /* Backslash newline is replaced by nothing at all. */
5363 cppReader_adjustWritten (pfile, -1);
5364 pfile->lineno++;
5365 }
5366 else
5367 {
5368 /* ANSI stupidly requires that in \\ the second \
5369 is *not* prevented from combining with a newline. */
5370 NEWLINE_FIX1(cc);
5371 if (cc != EOF)
5372 cppReader_putChar (pfile, cc);
5373 }
5374 /*@switchbreak@*/ break;
5375
5376 case '\"':
5377 case '\'':
5378 if (cc == c)
5379 goto while2end;
5380 /*@switchbreak@*/ break;
5381 }
5382 }
5383 while2end:
5384 pfile->lineno += count_newlines (pfile->token_buffer + old_written,
5385 cppReader_getPWritten (pfile));
5386 pfile->only_seen_white = 0;
5387 return c == '\'' ? CPP_CHAR : CPP_STRING;
5388
5389 case '$':
5390 if (!opts->dollars_in_ident)
5391 goto randomchar;
5392 goto letter;
5393
5394 case ':':
5395 if (opts->cplusplus && cppReader_peekC (pfile) == ':')
5396 goto op2;
5397 goto randomchar;
5398
5399 case '&':
5400 case '+':
5401 case '|':
5402 NEWLINE_FIX;
5403 c2 = cppReader_peekC (pfile);
5404 if (c2 == c || c2 == '=')
5405 goto op2;
5406 goto randomchar;
5407
5408 case '*':
5409 case '!':
5410 case '%':
5411 case '=':
5412 case '^':
5413 NEWLINE_FIX;
5414 if (cppReader_peekC (pfile) == '=')
5415 goto op2;
5416 goto randomchar;
5417
5418 case '-':
5419 NEWLINE_FIX;
5420 c2 = cppReader_peekC (pfile);
5421 if (c2 == '-' && opts->chill)
5422 {
5423 /* Chill style comment */
5424 if (opts->put_out_comments)
5425 {
5426 parseSetMark (&start_mark, pfile);
5427 }
5428
5429 cppReader_forward (pfile, 1); /* Skip second '-'. */
5430
5431 for (;;)
5432 {
5433 c = cppReader_getC (pfile);
5434 if (c == EOF)
5435 /*@loopbreak@*/ break;
5436 if (c == '\n')
5437 {
5438 /* Don't consider final '\n' to be part of comment. */
5439 cppReader_forward (pfile, -1);
5440 /*@loopbreak@*/ break;
5441 }
5442 }
5443 c = '-';
5444 goto return_comment;
5445 }
5446 if (c2 == '-' || c2 == '=' || c2 == '>')
5447 goto op2;
5448 goto randomchar;
5449
5450 case '<':
5451 if (pfile->parsing_include_directive)
5452 {
5453 for (;;)
5454 {
5455 cppReader_putChar (pfile, c);
5456 if (c == '>')
5457 /*@loopbreak@*/ break;
5458 c = cppReader_getC (pfile);
5459 NEWLINE_FIX1 (c);
5460 if (c == '\n' || c == EOF)
5461 {
5462 cppReader_errorLit (pfile,
5463 cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
5464 /*@loopbreak@*/ break;
5465 }
5466 }
5467 return CPP_STRING;
5468 }
5469 /*@fallthrough@*/
5470 case '>':
5471 NEWLINE_FIX;
5472 c2 = cppReader_peekC (pfile);
5473 if (c2 == '=')
5474 goto op2;
5475 if (c2 != c)
5476 goto randomchar;
5477 cppReader_forward (pfile, 1);
5478 cppReader_reserve (pfile, 4);
5479 cppReader_putChar (pfile, c);
5480 cppReader_putChar (pfile, c2);
5481 NEWLINE_FIX;
5482 c3 = cppReader_peekC (pfile);
5483 if (c3 == '=')
5484 cppReader_putCharQ (pfile, cppReader_getC (pfile));
5485 cppReader_nullTerminateQ (pfile);
5486 pfile->only_seen_white = 0;
5487 return CPP_OTHER;
5488
5489 case '@':
5490 if (cppReader_getBuffer (pfile)->has_escapes)
5491 {
5492 c = cppReader_getC (pfile);
5493 if (c == '-')
5494 {
5495 if (pfile->output_escapes)
5496 cppReader_puts (pfile, "@-", 2);
5497 parse_name (pfile, cppReader_getC (pfile));
5498 return CPP_NAME;
5499 }
5500 else if (is_space [c])
5501 {
5502 cppReader_reserve (pfile, 2);
5503 if (pfile->output_escapes)
5504 cppReader_putCharQ (pfile, '@');
5505 cppReader_putCharQ (pfile, c);
5506 return CPP_HSPACE;
5507 }
5508 else
5509 {
5510 ;
5511 }
5512 }
5513 if (pfile->output_escapes)
5514 {
5515 cppReader_puts (pfile, "@@", 2);
5516 return CPP_OTHER;
5517 }
5518 goto randomchar;
5519 case '.':
5520 NEWLINE_FIX;
5521 c2 = cppReader_peekC (pfile);
5522 if (isdigit(c2))
5523 {
5524 cppReader_reserve(pfile, 2);
5525 cppReader_putCharQ (pfile, '.');
5526 c = cppReader_getC (pfile);
5527 goto number;
5528 }
5529
5530 /* FIXME - misses the case "..\\\n." */
5531 if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
5532 {
5533 cppReader_reserve(pfile, 4);
5534 cppReader_putCharQ (pfile, '.');
5535 cppReader_putCharQ (pfile, '.');
5536 cppReader_putCharQ (pfile, '.');
5537 cppReader_forward (pfile, 2);
5538 cppReader_nullTerminateQ (pfile);
5539 pfile->only_seen_white = 0;
5540 return CPP_3DOTS;
5541 }
5542 goto randomchar;
5543 op2:
5544 token = CPP_OTHER;
5545 pfile->only_seen_white = 0;
5546 op2any:
5547 cppReader_reserve(pfile, 3);
5548 cppReader_putCharQ (pfile, c);
5549 cppReader_putCharQ (pfile, cppReader_getC (pfile));
5550 cppReader_nullTerminateQ (pfile);
5551 return token;
5552
5553 case 'L':
5554 NEWLINE_FIX;
5555 c2 = cppReader_peekC (pfile);
5556 if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
5557 {
5558 cppReader_putChar (pfile, c);
5559 c = cppReader_getC (pfile);
5560 goto string;
5561 }
5562 goto letter;
5563
5564 case '0': case '1': case '2': case '3': case '4':
5565 case '5': case '6': case '7': case '8': case '9':
5566 number:
5567 c2 = '.';
5568 for (;;)
5569 {
5570 cppReader_reserve (pfile, 2);
5571 cppReader_putCharQ (pfile, c);
5572 NEWLINE_FIX;
5573 c = cppReader_peekC (pfile);
5574 if (c == EOF)
5575 /*@loopbreak@*/ break;
5576 if (!is_idchar[c] && c != '.'
5577 && ((c2 != 'e' && c2 != 'E'
5578 && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
5579 || (c != '+' && c != '-')))
5580 /*@loopbreak@*/ break;
5581 cppReader_forward (pfile, 1);
5582 c2= c;
5583 }
5584
5585 cppReader_nullTerminateQ (pfile);
5586 pfile->only_seen_white = 0;
5587 return CPP_NUMBER;
5588
5589 case 'b': case 'c': case 'd': case 'h': case 'o':
5590 case 'B': case 'C': case 'D': case 'H': case 'O':
5591 if (opts->chill && cppReader_peekC (pfile) == '\'')
5592 {
5593 pfile->only_seen_white = 0;
5594 cppReader_reserve (pfile, 2);
5595 cppReader_putCharQ (pfile, c);
5596 cppReader_putCharQ (pfile, '\'');
5597 cppReader_forward (pfile, 1);
5598 for (;;)
5599 {
5600 c = cppReader_getC (pfile);
5601 if (c == EOF)
5602 goto chill_number_eof;
5603 if (!is_idchar[c])
5604 {
5605 if (c == '\\' && cppReader_peekC (pfile) == '\n')
5606 {
5607 cppReader_forward (pfile, 2);
5608 continue;
5609 }
5610 /*@loopbreak@*/ break;
5611 }
5612 cppReader_putChar (pfile, c);
5613 }
5614 if (c == '\'')
5615 {
5616 cppReader_reserve (pfile, 2);
5617 cppReader_putCharQ (pfile, c);
5618 cppReader_nullTerminateQ (pfile);
5619 return CPP_STRING;
5620 }
5621 else
5622 {
5623 cppReader_forward (pfile, -1);
5624 chill_number_eof:
5625 cppReader_nullTerminate (pfile);
5626 return CPP_NUMBER;
5627 }
5628 }
5629 else
5630 goto letter;
5631 case '_':
5632 case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
5633 case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
5634 case 'r': case 's': case 't': case 'u': case 'v': case 'w':
5635 case 'x': case 'y': case 'z':
5636 case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
5637 case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
5638 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
5639 case 'Y': case 'Z':
5640 letter:
5641 {
5642 hashNode hp;
5643 char *ident;
5644 size_t before_name_written = cppReader_getWritten (pfile);
5645 int ident_len;
5646 parse_name (pfile, c);
5647 pfile->only_seen_white = 0;
5648 if (pfile->no_macro_expand)
5649 {
5650 return CPP_NAME;
5651 }
5652
5653 ident = pfile->token_buffer + before_name_written;
5654 ident_len = (cppReader_getPWritten (pfile)) - ident;
5655
5656 hp = cppReader_lookupExpand (ident, ident_len, -1);
5657
5658 if (hp == NULL)
5659 {
5660 return CPP_NAME;
5661 }
5662
5663 if (hp->type == T_DISABLED)
5664 {
5665 if (pfile->output_escapes)
5666 { /* Return "@-IDENT", followed by '\0'. */
5667 int i;
5668 cppReader_reserve (pfile, 3);
5669 ident = pfile->token_buffer + before_name_written;
5670 cppReader_adjustWritten (pfile, 2);
5671
5672 for (i = ident_len; i >= 0; i--)
5673 {
5674 ident[i+2] = ident[i];
5675 }
5676
5677 ident[0] = '@';
5678 ident[1] = '-';
5679 }
5680 return CPP_NAME;
5681 }
5682
5683 /* If macro wants an arglist, verify that a '(' follows.
5684 first skip all whitespace, copying it to the output
5685 after the macro name. Then, if there is no '(',
5686 decide this is not a macro call and leave things that way. */
5687
5688 if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
5689 {
5690 struct parse_marker macro_mark;
5691 int is_macro_call;
5692
5693 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
5694 {
5695 cppBuffer *next_buf;
5696 cppSkipHspace (pfile);
5697 if (cppReader_peekC (pfile) != EOF)
5698 {
5699 /*@loopbreak@*/ break;
5700 }
5701
5702 next_buf = cppBuffer_prevBuffer (cppReader_getBuffer (pfile));
5703 (*cppReader_getBuffer (pfile)->cleanup) (cppReader_getBuffer (pfile), pfile);
5704 CPPBUFFER (pfile) = next_buf;
5705 }
5706
5707 parseSetMark (&macro_mark, pfile);
5708
5709 for (;;)
5710 {
5711 cppSkipHspace (pfile);
5712 c = cppReader_peekC (pfile);
5713 is_macro_call = c == '(';
5714 if (c != '\n')
5715 /*@loopbreak@*/ break;
5716 cppReader_forward (pfile, 1);
5717 }
5718
5719 if (!is_macro_call)
5720 {
5721 parseGotoMark (&macro_mark, pfile);
5722 }
5723
5724 parseClearMark (&macro_mark);
5725
5726 if (!is_macro_call)
5727 {
5728 return CPP_NAME;
5729 }
5730 }
5731 /* This is now known to be a macro call. */
5732
5733 /* it might not actually be a macro. */
5734 if (hp->type != T_MACRO)
5735 {
5736 size_t xbuf_len;
5737 char *xbuf;
5738
5739 cppReader_setWritten (pfile, before_name_written);
5740 special_symbol (hp, pfile);
5741 xbuf_len = cppReader_getWritten (pfile) - before_name_written;
5742 xbuf = (char *) dmalloc (xbuf_len + 1);
5743 cppReader_setWritten (pfile, before_name_written);
5744 memcpy (xbuf, cppReader_getPWritten (pfile), xbuf_len + 1);
5745 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
5746 }
5747 else
5748 {
5749 /* Expand the macro, reading arguments as needed,
5750 and push the expansion on the input stack. */
5751 macroexpand (pfile, hp);
5752 cppReader_setWritten (pfile, before_name_written);
5753 }
5754
5755 /* An extra "@ " is added to the end of a macro expansion
5756 to prevent accidental token pasting. We prefer to avoid
5757 unneeded extra spaces (for the sake of cpp-using tools like
5758 imake). Here we remove the space if it is safe to do so. */
5759
5760 llassert (pfile->buffer->rlimit != NULL);
5761
5762 if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
5763 && pfile->buffer->rlimit[-2] == '@'
5764 && pfile->buffer->rlimit[-1] == ' ')
5765 {
5766 int c1 = pfile->buffer->rlimit[-3];
5767 int cl2 = cppBufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
5768
5769 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
5770 pfile->buffer->rlimit -= 2;
5771 }
5772 }
5773 goto get_next;
5774
5775
5776 case ' ': case '\t': case '\v': case '\r':
5777 for (;;)
5778 {
5779 cppReader_putChar (pfile, c);
5780 c = cppReader_peekC (pfile);
5781 if (c == EOF || !is_hor_space[c])
5782 /*@loopbreak@*/ break;
5783 cppReader_forward (pfile, 1);
5784 }
5785 return CPP_HSPACE;
5786
5787 case '\\':
5788 c2 = cppReader_peekC (pfile);
5789 if (c2 != '\n')
5790 goto randomchar;
5791 token = CPP_HSPACE;
5792 goto op2any;
5793
5794 case '\n':
5795 cppReader_putChar (pfile, c);
5796 if (pfile->only_seen_white == 0)
5797 pfile->only_seen_white = 1;
5798 pfile->lineno++;
5799 output_line_command (pfile, 1, same_file);
5800 return CPP_VSPACE;
5801
5802 case '(': token = CPP_LPAREN; goto char1;
5803 case ')': token = CPP_RPAREN; goto char1;
5804 case '{': token = CPP_LBRACE; goto char1;
5805 case '}': token = CPP_RBRACE; goto char1;
5806 case ',': token = CPP_COMMA; goto char1;
5807 case ';': token = CPP_SEMICOLON; goto char1;
5808
5809 randomchar:
5810 default:
5811 token = CPP_OTHER;
5812 char1:
5813 pfile->only_seen_white = 0;
5814 cppReader_putChar (pfile, c);
5815 return token;
5816 }
5817 }
5818
5819 BADBRANCH;
5820 /*@notreached@*/
5821}
5822
5823/* Parse an identifier starting with C. */
5824
5825void
5826parse_name (cppReader *pfile, int c)
5827{
5828 for (;;)
5829 {
5830 if (!is_idchar[c])
5831 {
5832 if (c == '\\' && cppReader_peekC (pfile) == '\n')
5833 {
5834 cppReader_forward (pfile, 2);
5835 continue;
5836 }
5837
5838 cppReader_forward (pfile, -1);
5839 break;
5840 }
5841
5842 if (c == '$' && cppReader_isPedantic (pfile))
5843 {
5844 cppReader_pedwarnLit (pfile,
5845 cstring_makeLiteralTemp ("`$' in identifier"));
5846 }
5847
5848 cppReader_reserve(pfile, 2); /* One more for final NUL. */
5849 cppReader_putCharQ (pfile, c);
5850 c = cppReader_getC (pfile);
5851
5852 if (c == EOF)
5853 break;
5854 }
5855
5856 cppReader_nullTerminateQ (pfile);
5857}
5858
5859/* The file_name_map structure holds a mapping of file names for a
5860 particular directory. This mapping is read from the file named
5861 FILE_NAME_MAP_FILE in that directory. Such a file can be used to
5862 map filenames on a file system with severe filename restrictions,
5863 such as DOS. The format of the file name map file is just a series
5864 of lines with two tokens on each line. The first token is the name
5865 to map, and the second token is the actual name to use. */
5866
5867struct file_name_map
5868{
5869 struct file_name_map *map_next;
5870 cstring map_from;
5871 cstring map_to;
5872};
5873
5874/*@constant observer char *FILE_NAME_MAP_FILE*/
5875#define FILE_NAME_MAP_FILE "header.gcc"
5876
5877/* Read a space delimited string of unlimited length from a stdio
5878 file. */
5879
5880static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
5881{
5882 char *alloc, *set;
5883 size_t len;
5884
5885 len = 20;
5886 set = alloc = dmalloc (len + 1);
5887
5888 if (!is_space[ch])
5889 {
5890 *set++ = ch;
5891 while ((ch = getc (f)) != EOF && ! is_space[ch])
5892 {
5893 if (set - alloc == size_toInt (len))
5894 {
5895 len *= 2;
5896 alloc = drealloc (alloc, len + 1);
5897 set = alloc + len / 2;
5898 /*@-branchstate@*/ }
5899
5900 *set++ = ch;
5901 } /*@=branchstate@*/
5902 }
5903 *set = '\0';
5904 check (ungetc (ch, f) != EOF);
5905
5906 return cstring_fromChars (alloc);
5907}
5908
5909/* This structure holds a linked list of file name maps, one per directory. */
5910
5911struct file_name_map_list
5912{
5913 struct file_name_map_list *map_list_next;
5914 cstring map_list_name;
5915 struct file_name_map *map_list_map;
5916};
5917
5918/* Read the file name map file for DIRNAME. */
5919
5920static struct file_name_map *
5921read_name_map (cppReader *pfile, cstring dirname)
5922{
5923 struct file_name_map_list *map_list_ptr;
5924 cstring name;
5925 FILE *f;
5926
5927 for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
5928 map_list_ptr != NULL;
5929 map_list_ptr = map_list_ptr->map_list_next)
5930 {
5931 if (cstring_equal (map_list_ptr->map_list_name, dirname))
5932 {
5933 return map_list_ptr->map_list_map;
5934 }
5935 }
5936
5937 map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
5938 map_list_ptr->map_list_name = cstring_copy (dirname);
5939 map_list_ptr->map_list_map = NULL;
5940
5941 name = cstring_copy (dirname);
5942
5943 if (cstring_length (dirname) > 0)
5944 {
5945 name = cstring_appendChar (name, CONNECTCHAR);
5946 }
5947
5948 name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
5949
5950 f = fileTable_openFile (context_fileTable (), name, "r");
5951 cstring_free (name);
5952
5953 if (f == NULL)
5954 {
5955 map_list_ptr->map_list_map = NULL;
5956 }
5957 else
5958 {
5959 int ch;
5960
5961 while ((ch = getc (f)) != EOF)
5962 {
5963 cstring from, to;
5964 struct file_name_map *ptr;
5965
5966 if (is_space[ch])
5967 {
5968 continue;
5969 }
5970
5971 from = read_filename_string (ch, f);
5972 while ((ch = getc (f)) != EOF && is_hor_space[ch])
5973 {
5974 ;
5975 }
5976
5977 to = read_filename_string (ch, f);
5978
5979 ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
5980 ptr->map_from = from;
5981
5982 /* Make the real filename absolute. */
5983 if (cstring_length (to) > 1
5984 && osd_isConnectChar (cstring_firstChar (to)))
5985 {
5986 ptr->map_to = to;
5987 }
5988 else
5989 {
5990 ptr->map_to = cstring_copy (dirname);
5991 ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
5992 ptr->map_to = cstring_concatFree (ptr->map_to, to);
5993 }
5994
5995 ptr->map_next = map_list_ptr->map_list_map;
5996 map_list_ptr->map_list_map = ptr;
5997
5998 while ((ch = getc (f)) != '\n')
5999 {
6000 if (ch == EOF)
6001 {
6002 /*@innerbreak@*/ break;
6003 }
6004 }
6005 }
6006
6007 assertSet (map_list_ptr->map_list_map);
6008 check (fileTable_closeFile (context_fileTable (),f) == 0);
6009 }
6010
6011 map_list_ptr->map_list_next = pfile->opts->map_list;
6012 pfile->opts->map_list = map_list_ptr;
6013
6014 return map_list_ptr->map_list_map;
6015}
6016
6017/* Try to open include file FILENAME. SEARCHPTR is the directory
6018 being tried from the include file search path. This function maps
6019 filenames on file systems based on information read by
6020 read_name_map. */
6021
6022static int
6023open_include_file (cppReader *pfile,
6024 cstring fname,
6025 struct file_name_list *searchptr)
6026{
6027 char *filename = cstring_toCharsSafe (fname);
6028 struct file_name_map *map;
6029 char *from;
6030 char *p, *dir;
6031
6032 cstring_markOwned (fname);
6033
6034 cpp_setLocation (pfile);
6035
6036 if (context_getFlag (FLG_NEVERINCLUDE))
6037 {
6038 if (isHeaderFile (fname))
6039 {
6040 return SKIP_INCLUDE;
6041 }
6042 }
6043
6044 if ((searchptr != NULL) && ! searchptr->got_name_map)
6045 {
6046 searchptr->name_map = read_name_map (pfile,
6047 !cstring_isEmpty (searchptr->fname)
6048 ? searchptr->fname :
6049 cstring_makeLiteralTemp ("."));
6050 searchptr->got_name_map = 1;
6051 }
6052
6053 /* First check the mapping for the directory we are using. */
6054
6055 if ((searchptr != NULL)
6056 && (searchptr->name_map != NULL))
6057 {
6058 from = filename;
6059
6060 if (!cstring_isEmpty (searchptr->fname))
6061 {
6062 from += cstring_length (searchptr->fname) + 1;
6063 }
6064
6065 for (map = searchptr->name_map;
6066 map != NULL;
6067 map = map->map_next)
6068 {
6069 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6070 {
6071 /*
6072 ** Found a match. Check if the file should be skipped
6073 */
6074
6075 if (cpp_skipIncludeFile (map->map_to))
6076 {
6077 return SKIP_INCLUDE;
6078 }
6079 else
6080 {
6081 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6082 }
6083 }
6084 }
6085 }
6086
6087 /*
6088 ** Try to find a mapping file for the particular directory we are
6089 ** looking in. Thus #include <sys/types.h> will look up sys/types.h
6090 ** in /usr/include/header.gcc and look up types.h in
6091 ** /usr/include/sys/header.gcc.
6092 */
6093
6094 p = strrchr (filename, CONNECTCHAR);
6095
6096 if (p == NULL)
6097 {
6098 p = filename;
6099 }
6100
6101 if ((searchptr != NULL)
6102 && (cstring_isDefined (searchptr->fname))
6103 && (cstring_length (searchptr->fname) == p - filename)
6104 && !strncmp (cstring_toCharsSafe (searchptr->fname),
6105 filename,
6106 size_fromInt (p - filename)))
6107 {
6108 /* filename is in SEARCHPTR, which we've already checked. */
6109
6110 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6111 {
6112 return SKIP_INCLUDE;
6113 }
6114 else
6115 {
6116 return cpp_openIncludeFile (filename);
6117 }
6118 }
6119
6120 if (p == filename)
6121 {
6122 dir = mstring_copy (".");
6123 from = filename;
6124 }
6125 else
6126 {
6127 dir = (char *) dmalloc (size_fromInt (p - filename + 1));
6128 memcpy (dir, filename, size_fromInt (p - filename));
6129 dir[p - filename] = '\0';
6130 from = p + 1;
6131 }
6132
6133 for (map = read_name_map (pfile, cstring_fromChars (dir));
6134 map != NULL;
6135 map = map->map_next)
6136 {
6137 if (cstring_equal (map->map_from, cstring_fromChars (from)))
6138 {
6139 sfree (dir);
6140
6141 if (cpp_skipIncludeFile (map->map_to))
6142 {
6143 return SKIP_INCLUDE;
6144 }
6145 else
6146 {
6147 return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6148 }
6149 }
6150 }
6151
6152 sfree (dir);
6153
6154 if (cpp_skipIncludeFile (cstring_fromChars (filename)))
6155 {
6156 return SKIP_INCLUDE;
6157 }
6158 else
6159 {
6160 return cpp_openIncludeFile (filename);
6161 }
6162}
6163
6164/* Process the contents of include file FNAME, already open on descriptor F,
6165 with output to OP.
6166 SYSTEM_HEADER_P is 1 if this file resides in any one of the known
6167 "system" include directories (as decided by the `is_system_include'
6168 function above).
6169 DIRPTR is the link in the dir path through which this file was found,
6170 or 0 if the file name was absolute or via the current directory.
6171 Return 1 on success, 0 on failure.
6172
6173 The caller is responsible for the cppReader_pushBuffer. */
6174
6175static int
6176finclude (cppReader *pfile, int f,
6177 cstring fname,
6178 bool system_header_p,
6179 /*@dependent@*/ struct file_name_list *dirptr)
6180{
6181 mode_t st_mode;
6182 size_t st_size;
6183 long i;
6184 int length = 0;
6185 cppBuffer *fp; /* For input stack frame */
6186
6187 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
6188 {
6189 cppReader_perrorWithName (pfile, fname);
6190 check (close (f) == 0);
6191 (void) cppReader_popBuffer (pfile);
6192 /*@-mustfree@*/
6193 return 0;
6194 /*@=mustfree@*/
6195 }
6196
6197 fp = cppReader_getBuffer (pfile);
6198
6199 /*@-temptrans@*/ /* fname shouldn't really be temp */
6200 fp->nominal_fname = fp->fname = fname;
6201 /*@=temptrans@*/
6202
6203 fp->dir = dirptr;
6204 fp->system_header_p = system_header_p;
6205 fp->lineno = 1;
6206 fp->colno = 1;
6207 fp->cleanup = cppReader_fileCleanup;
6208
6209 if (S_ISREG (st_mode))
6210 {
6211 sfree (fp->buf);
6212 fp->buf = (char *) dmalloc (st_size + 2);
6213 fp->alimit = fp->buf + st_size + 2;
6214 fp->cur = fp->buf;
6215
6216 /* Read the file contents, knowing that st_size is an upper bound
6217 on the number of bytes we can read. */
6218 length = safe_read (f, fp->buf, size_toInt (st_size));
6219 fp->rlimit = fp->buf + length;
6220 if (length < 0) goto nope;
6221 }
6222 else if (S_ISDIR (st_mode))
6223 {
6224 cppReader_error (pfile,
6225 message ("Directory specified in #include: %s", fname));
6226 check (close (f) == 0);
6227 return 0;
6228 }
6229 else
6230 {
6231 /*
6232 ** Cannot count its file size before reading.
6233 ** First read the entire file into heap and
6234 ** copy them into buffer on stack.
6235 */
6236
6237 size_t bsize = 2000;
6238
6239 st_size = 0;
6240
6241 sfree (fp->buf);
6242 fp->buf = (char *) dmalloc (bsize + 2);
6243
6244 for (;;) {
6245 i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
6246
6247 if (i < 0)
6248 goto nope; /* error! */
6249 st_size += i;
6250
6251 if (st_size != bsize)
6252 {
6253 break; /* End of file */
6254 }
6255
6256 bsize *= 2;
6257 fp->buf = (char *) drealloc (fp->buf, bsize + 2);
6258 }
6259
6260 fp->cur = fp->buf;
6261 length = size_toInt (st_size);
6262 }
6263
6264 if ((length > 0 && fp->buf[length - 1] != '\n')
6265 /* Backslash-newline at end is not good enough. */
6266 || (length > 1 && fp->buf[length - 2] == '\\')) {
6267 fp->buf[length++] = '\n';
6268 }
6269
6270 fp->buf[length] = '\0';
6271 fp->rlimit = fp->buf + length;
6272
6273 /* Close descriptor now, so nesting does not use lots of descriptors. */
6274 check (close (f) == 0);
6275
6276 /* Must do this before calling trigraph_pcp, so that the correct file name
6277 will be printed in warning messages. */
6278
6279 pfile->input_stack_listing_current = 0;
6280 return 1;
6281
6282 nope:
6283
6284 cppReader_perrorWithName (pfile, fname);
6285 check (close (f) == 0);
6286 sfree (fp->buf);
6287 return 1;
6288}
6289
6290void
6291cppReader_init (cppReader *pfile)
6292{
6293 memset ((char *) pfile, 0, sizeof (*pfile));
6294
6295 pfile->get_token = cppGetToken;
6296 pfile->token_buffer_size = 200;
6297 pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
6298 pfile->all_include_files = NULL;
6299
6300 assertSet (pfile);
6301
6302 cppReader_setWritten (pfile, 0);
6303
6304 pfile->system_include_depth = 0;
6305 pfile->max_include_len = 0;
6306 pfile->timebuf = NULL;
6307 pfile->only_seen_white = 1;
6308
6309 pfile->buffer = cppReader_nullBuffer (pfile);
6310}
6311
6312void
6313cppReader_finish (/*@unused@*/ cppReader *pfile)
6314{
6315 ;
6316}
6317
6318/* Free resources used by PFILE.
6319 This is the cppReader 'finalizer' or 'destructor' (in C++ terminology). */
6320
6321void
6322cppCleanup (cppReader *pfile)
6323{
6324 while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
6325 {
6326 (void) cppReader_popBuffer (pfile);
6327 }
6328
6329 if (pfile->token_buffer != NULL)
6330 {
6331 sfree (pfile->token_buffer);
6332 pfile->token_buffer = NULL;
6333 }
6334
6335 while (pfile->if_stack != NULL)
6336 {
6337 cppIfStackFrame *temp = pfile->if_stack;
6338 pfile->if_stack = temp->next;
6339 sfree (temp);
6340 }
6341
6342 while (pfile->all_include_files != NULL)
6343 {
6344 struct file_name_list *temp = pfile->all_include_files;
6345 pfile->all_include_files = temp->next;
6346 /*@-dependenttrans@*/
6347 cstring_free (temp->fname);
6348 /*@=dependenttrans@*/
6349 sfree (temp);
6350 }
6351
6352 cppReader_hashCleanup ();
6353}
6354
6355/*
6356** Get the file-mode and data size of the file open on FD
6357** and store them in *MODE_POINTER and *SIZE_POINTER.
6358*/
6359
6360static int
6361file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
6362{
6363 struct stat sbuf;
6364
6365 if (fstat (fd, &sbuf) < 0) {
6366 return (-1);
6367 }
6368
6369 if (mode_pointer != NULL)
6370 {
6371 *mode_pointer = sbuf.st_mode;
6372 }
6373
6374 if (size_pointer != NULL)
6375 {
6376 *size_pointer = (size_t) sbuf.st_size;
6377 }
6378
6379 return 0;
6380}
6381
6382/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
6383 retrying if necessary. Return a negative value if an error occurs,
6384 otherwise return the actual number of bytes read,
6385 which must be LEN unless end-of-file was reached. */
6386
6387static int safe_read (int desc, char *ptr, int len)
6388{
6389 int left = len;
6390
6391 while (left > 0)
6392 {
6393# if defined (WIN32) || defined (OS2) && defined (__IBMC__)
6394 /*@-compdef@*/ /* ptr is an out parameter */
6395 int nchars = _read (desc, ptr, (unsigned) left);
6396 /*@=compdef@*/
6397# else
6398 ssize_t nchars = read (desc, ptr, size_fromInt (left));
6399# endif
6400
6401 if (nchars < 0)
6402 {
6403#ifdef EINTR
6404 if (errno == EINTR)
6405 continue;
6406#endif
6407 return (int) nchars;
6408 }
6409
6410 if (nchars == 0) {
6411 break;
6412 }
6413
6414 ptr += nchars;
6415 left -= nchars;
6416 }
6417
6418 return len - left;
6419}
6420
6421/* Initialize PMARK to remember the current position of PFILE. */
6422
6423void
6424parseSetMark (struct parse_marker *pmark, cppReader *pfile)
6425{
6426 cppBuffer *pbuf = cppReader_getBuffer (pfile);
6427
6428 pmark->next = pbuf->marks;
6429 /*@-temptrans@*/
6430 pbuf->marks = pmark;
6431 /*@=temptrans@*/
6432
6433 pmark->buf = pbuf;
6434 pmark->position = pbuf->cur - pbuf->buf;
6435}
6436
6437/* Cleanup PMARK - we no longer need it. */
6438
6439void parseClearMark (struct parse_marker *pmark)
6440{
6441 struct parse_marker **pp = &pmark->buf->marks;
6442
6443 for (; ; pp = &(*pp)->next)
6444 {
6445 llassert (*pp != NULL);
6446 if (*pp == pmark) break;
6447 }
6448
6449 *pp = pmark->next;
6450}
6451
6452/* Backup the current position of PFILE to that saved in PMARK. */
6453
6454void
6455parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
6456{
6457 cppBuffer *pbuf = cppReader_getBuffer (pfile);
6458
6459 if (pbuf != pmark->buf)
6460 {
6461 cpp_setLocation (pfile);
6462 llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
6463 }
6464
6465 llassert (pbuf->buf != NULL);
6466 pbuf->cur = pbuf->buf + pmark->position;
6467}
6468
6469/* Reset PMARK to point to the current position of PFILE. (Same
6470 as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster. */
6471
6472void
6473parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
6474{
6475 cppBuffer *pbuf = cppReader_getBuffer (pfile);
6476
6477 if (pbuf != pmark->buf)
6478 {
6479 cpp_setLocation (pfile);
6480 llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
6481 }
6482
6483 pmark->position = pbuf->cur - pbuf->buf;
6484}
6485
6486void cppReader_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
6487{
6488 struct cppOptions *opts = CPPOPTIONS (pfile);
6489 cstring xp;
6490
6491 /* The code looks at the defaults through this pointer, rather than through
6492 the constant structure above. This pointer gets changed if an environment
6493 variable specifies other defaults. */
6494
6495 struct default_include *include_defaults = include_defaults_array;
6496
6497 /* Add dirs from INCLUDEPATH_VAR after dirs from -I. */
6498 /* There seems to be confusion about what CPATH should do,
6499 so for the moment it is not documented. */
6500 /* Some people say that CPATH should replace the standard include dirs,
6501 but that seems pointless: it comes before them, so it overrides them
6502 anyway. */
6503
6504 xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
6505
6506 if (cstring_isDefined (xp) && !opts->no_standard_includes)
6507 {
6508 path_include (pfile, cstring_toCharsSafe (xp));
6509 }
6510
6511 /* Now that dollars_in_ident is known, initialize is_idchar. */
6512 initialize_char_syntax (opts);
6513
6514 /* CppReader_Install __LINE__, etc. Must follow initialize_char_syntax
6515 and option processing. */
6516
6517 initialize_builtins (pfile);
6518
6519 /* Do standard #defines and assertions
6520 that identify system and machine type. */
6521
6522 if (!opts->inhibit_predefs) {
6523 char *p = (char *) dmalloc (strlen (predefs) + 1);
6524 strcpy (p, predefs);
6525
6526 while (*p)
6527 {
6528 char *q;
6529
6530 while (*p == ' ' || *p == '\t')
6531 {
6532 p++;
6533 }
6534
6535 /* Handle -D options. */
6536 if (p[0] == '-' && p[1] == 'D')
6537 {
6538 q = &p[2];
6539
6540 while (*p && *p != ' ' && *p != '\t')
6541 {
6542 p++;
6543 }
6544
6545 if (*p != 0)
6546 {
6547 *p++= 0;
6548 }
6549
6550 if (opts->debug_output)
6551 {
6552 output_line_command (pfile, 0, same_file);
6553 }
6554
6555 cppReader_define (pfile, q);
6556
6557 while (*p == ' ' || *p == '\t')
6558 {
6559 p++;
6560 }
6561 }
6562 else
6563 {
6564 abort ();
6565 }
6566 }
6567
6568 sfree (p);
6569 }
6570
6571 opts->done_initializing = 1;
6572
6573 { /* Read the appropriate environment variable and if it exists
6574 replace include_defaults with the listed path. */
6575 char *epath = 0;
6576#ifdef __CYGWIN32__
6577 char *win32epath;
6578 int win32_buf_size = 0; /* memory we need to allocate */
6579#endif
6580
6581 if (opts->cplusplus)
6582 {
6583 epath = getenv ("CPLUS_INCLUDE_PATH");
6584 }
6585 else
6586 {
6587 epath = getenv ("C_INCLUDE_PATH");
6588 }
6589
6590 /*
6591 ** If the environment var for this language is set,
6592 ** add to the default list of include directories.
6593 */
6594
6595 if (epath != NULL) {
6596 char *nstore = (char *) dmalloc (strlen (epath) + 2);
6597 int num_dirs;
6598 char *startp, *endp;
6599
6600#ifdef __CYGWIN32__
6601 /* if we have a posix path list, convert to win32 path list */
6602 if (cygwin32_posix_path_list_p (epath))
6603 {
6604 win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
6605 win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
6606 cygwin32_posix_to_win32_path_list (epath, win32epath);
6607 epath = win32epath;
6608 }
6609#endif
6610 for (num_dirs = 1, startp = epath; *startp; startp++)
6611 {
6612 if (*startp == PATH_SEPARATOR)
6613 num_dirs++;
6614 }
6615
6616 /*@-sizeoftype@*/
6617 include_defaults
6618 = (struct default_include *) dmalloc ((num_dirs
6619 * sizeof (struct default_include))
6620 + sizeof (include_defaults_array));
6621 /*@=sizeoftype@*/
6622
6623 startp = endp = epath;
6624 num_dirs = 0;
6625 while (1) {
6626 /* Handle cases like c:/usr/lib:d:/gcc/lib */
6627 if ((*endp == PATH_SEPARATOR) || *endp == 0)
6628 {
6629 strncpy (nstore, startp, size_fromInt (endp - startp));
6630 if (endp == startp)
6631 {
6632 strcpy (nstore, ".");
6633 }
6634 else
6635 {
6636 nstore[endp-startp] = '\0';
6637 }
6638
6639 include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
6640 include_defaults[num_dirs].cplusplus = opts->cplusplus;
6641 include_defaults[num_dirs].cxx_aware = 1;
6642 num_dirs++;
6643
6644 if (*endp == '\0')
6645 {
6646 break;
6647 }
6648 endp = startp = endp + 1;
6649 }
6650 else
6651 {
6652 endp++;
6653 }
6654 }
6655 /* Put the usual defaults back in at the end. */
6656 memcpy ((char *) &include_defaults[num_dirs],
6657 (char *) include_defaults_array,
6658 sizeof (include_defaults_array));
6659
6660 sfree (nstore);
6661 /*@-branchstate@*/ } /*@=branchstate@*/
6662 }
6663
6664 cppReader_appendIncludeChain (pfile, opts->before_system,
6665 opts->last_before_system);
6666 opts->first_system_include = opts->before_system;
6667
6668 /* Unless -fnostdinc,
6669 tack on the standard include file dirs to the specified list */
6670 if (!opts->no_standard_includes) {
6671 struct default_include *p = include_defaults;
6672 char *specd_prefix = opts->include_prefix;
6673 char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
6674 int default_len = 0;
6675
6676 /* Remove the `include' from /usr/local/lib/gcc.../include. */
6677 if (default_prefix != NULL) {
6678 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
6679 default_len = strlen (default_prefix) - 7;
6680 default_prefix[default_len] = 0;
6681 }
6682 }
6683
6684 /* Search "translated" versions of GNU directories.
6685 These have /usr/local/lib/gcc... replaced by specd_prefix. */
6686 if (specd_prefix != 0 && default_len != 0)
6687 for (p = include_defaults; p->fname != NULL; p++) {
6688 /* Some standard dirs are only for C++. */
6689 if (!p->cplusplus
6690 || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
6691 /* Does this dir start with the prefix? */
6692 if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix,
6693 size_fromInt (default_len)))
6694 {
6695 /* Yes; change prefix and add to search list. */
6696 struct file_name_list *nlist
6697 = (struct file_name_list *) dmalloc (sizeof (*nlist));
6698 size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
6699 char *str = (char *) dmalloc (this_len + 1);
6700 strcpy (str, specd_prefix);
6701 strcat (str, cstring_toCharsSafe (p->fname) + default_len);
6702
6703 nlist->next = NULL;
6704 nlist->fname = cstring_fromChars (str);
6705 nlist->control_macro = 0;
6706 nlist->c_system_include_path = !p->cxx_aware;
6707 nlist->got_name_map = 0;
6708
6709 cppReader_addIncludeChain (pfile, nlist);
6710 if (opts->first_system_include == 0)
6711 {
6712 opts->first_system_include = nlist;
6713 }
6714 }
6715 }
6716 }
6717
6718 /* Search ordinary names for GNU include directories. */
6719
6720 for (p = include_defaults; p->fname != NULL; p++)
6721 {
6722 /* Some standard dirs are only for C++. */
6723 if (!p->cplusplus
6724 || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
6725 {
6726 struct file_name_list *nlist
6727 = (struct file_name_list *) dmalloc (sizeof (*nlist));
6728 nlist->control_macro = 0;
6729 nlist->c_system_include_path = !p->cxx_aware;
6730 nlist->fname = p->fname;
6731 nlist->got_name_map = 0;
6732 nlist->next = NULL;
6733
6734 cppReader_addIncludeChain (pfile, nlist);
6735
6736 if (opts->first_system_include == 0)
6737 {
6738 opts->first_system_include = nlist;
6739 }
6740 }
6741 }
6742 sfree (default_prefix);
6743 }
6744
6745 /* Tack the after_include chain at the end of the include chain. */
6746 cppReader_appendIncludeChain (pfile, opts->after_include,
6747 opts->last_after_include);
6748
6749 if (opts->first_system_include == 0)
6750 {
6751 opts->first_system_include = opts->after_include;
6752 }
6753
6754 /* With -v, print the list of dirs to search. */
6755 if (opts->verbose) {
6756 struct file_name_list *p;
6757 fprintf (stderr, "#include \"...\" search starts here:\n");
6758
6759 for (p = opts->include; p != NULL; p = p->next) {
6760 if (p == opts->first_bracket_include)
6761 fprintf (stderr, "#include <...> search starts here:\n");
6762
6763 fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
6764 }
6765 fprintf (stderr, "End of search list.\n");
6766 }
6767}
6768
6769int cppReader_startProcess (cppReader *pfile, cstring fname)
6770{
6771 cppBuffer *fp;
6772 int f;
6773 struct cppOptions *opts = CPPOPTIONS (pfile);
6774
6775 fp = cppReader_pushBuffer (pfile, NULL, 0);
6776
6777 if (fp == NULL)
6778 {
6779 return 0;
6780 }
6781
6782 if (opts->in_fname == NULL)
6783 {
6784 opts->in_fname = cstring_makeLiteralTemp ("");
6785 }
6786
6787 fp->fname = opts->in_fname;
6788 fp->nominal_fname = fp->fname;
6789 fp->lineno = 0;
6790
6791 /* Copy the entire contents of the main input file into
6792 the stacked input buffer previously allocated for it. */
6793
6794 if (cstring_isEmpty (fname))
6795 {
6796 fname = cstring_makeLiteralTemp ("");
6797 f = 0;
6798 }
6799 else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
6800 {
6801 cppReader_error (pfile,
6802 message ("Error opening %s for reading: %s",
6803 fname, lldecodeerror (errno)));
6804
6805 return 0;
6806 }
6807 else
6808 {
6809 ;
6810 }
6811
6812 if (finclude (pfile, f, fname, 0, NULL))
6813 {
6814 output_line_command (pfile, 0, same_file);
6815 }
6816
6817 return 1;
6818}
6819
6820static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
6821{
6822 return pfile->buffer;
6823}
6824
6825/*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
6826{
6827 llassert (pfile->buffer != NULL);
6828 return pfile->buffer;
6829}
6830
6831/*@exposed@*/ char *cppLineBase (cppBuffer *buf)
6832{
6833 llassert (buf->buf != NULL);
6834 return (buf->buf + buf->line_base);
6835}
6836
6837int cppBufPeek (cppBuffer *buf)
6838{
6839 if (buf->cur == NULL || buf->rlimit == NULL) {
6840 return EOF;
6841 }
6842
6843 if (buf->cur < buf->rlimit) {
6844 return *(buf->cur);
6845 }
6846
6847 return EOF;
6848}
6849
6850bool cppBuffer_isMacro (cppBuffer *buf)
6851{
6852 if (buf != NULL)
6853 {
6854 return (buf->cleanup == cppReader_macroCleanup);
6855 }
6856
6857 return FALSE;
6858}
6859
6860/*
6861** Returns true if the macro should be checked, false
6862** if it should be expanded normally.
6863*/
6864
6865static bool notparseable = FALSE; /* preceeded by @notparseable@ */
6866static bool notfunction = FALSE; /* preceeded by @notfunction@ */
6867static bool expectiter = FALSE; /* preceeded by @iter@ */
6868static bool expectenditer = FALSE; /* second after @iter@ */
6869static bool expectfunction = FALSE; /* preceeded by @function@ */
6870static bool expectconstant = FALSE; /* preceeded by @constant@ */
6871static bool expectmacro = FALSE; /* preceeded by notfunction or notparseable */
6872
6873static void cpp_setLocation (cppReader *pfile)
6874{
6875 fileId fid;
6876 int line;
6877
6878 if (pfile->buffer != NULL)
6879 {
6880 if (cstring_isDefined (cppReader_getBuffer (pfile)->nominal_fname))
6881 {
6882 cstring fname = cppReader_getBuffer (pfile)->nominal_fname;
6883
6884 DPRINTF (("Looking up: %s", fname));
6885
6886 if (fileTable_exists (context_fileTable (), fname))
6887 {
6888 fid = fileTable_lookup (context_fileTable (), fname);
6889 }
6890 else
6891 {
6892 DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
6893
6894 fid = fileTable_lookup (context_fileTable (),
6895 cppReader_getBuffer (pfile)->fname);
6896 }
6897 }
6898 else
6899 {
6900 fid = fileTable_lookup (context_fileTable (),
6901 cppReader_getBuffer (pfile)->fname);
6902 }
6903
6904 line = cppReader_getBuffer (pfile)->lineno;
6905 fileloc_free (g_currentloc);
6906
6907 if (fileId_isValid (fid))
6908 {
6909 g_currentloc = fileloc_create (fid, line, 1);
6910 }
6911 else
6912 {
6913 g_currentloc = fileloc_createBuiltin ();
6914 }
6915 }
6916 else
6917 {
6918 fileloc_free (g_currentloc);
6919 g_currentloc = fileloc_createBuiltin ();
6920 }
6921}
6922
6923static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@*/
6924{
6925 bool checkmacro = FALSE;
6926 bool hasParams = FALSE;
6927 bool noexpand = FALSE;
6928 cstring sname;
6929 char c;
6930
6931 cpp_setLocation (pfile);
6932
6933 DPRINTF (("Should check macro? %s", p));
6934
6935 if (expectiter || expectconstant || expectenditer)
6936 {
6937 if (expectiter)
6938 {
6939 expectiter = FALSE;
6940 expectenditer = TRUE;
6941 }
6942 else
6943 {
6944 expectiter = FALSE;
6945 expectconstant = FALSE;
6946 expectenditer = FALSE;
6947 }
6948
6949 if (notfunction || notparseable)
6950 {
6951 notfunction = FALSE;
6952 notparseable = FALSE;
6953 return FALSE;
6954 }
6955 else
6956 {
6957 return TRUE;
6958 }
6959 }
6960
6961 llassert (*p == '#');
6962 p++;
6963
6964 while (*p == ' ' || *p == '\t')
6965 {
6966 p++;
6967 }
6968
6969 llassert (*p == 'd'); /* define starts */
6970
6971 p += 6;
6972
6973 while (*p == ' ' || *p == '\t')
6974 {
6975 p++;
6976 }
6977
6978 sname = cstring_fromChars (p);
6979 DPRINTF (("Check macro: %s", sname));
6980
6981 while (((c = *p) != ' ')
6982 && c != '\0' && c != '('
6983 && c != '\t' && c != '\\' && c != '\n'
6984 && !iscntrl (c))
6985 {
6986 p++;
6987 }
6988
6989 hasParams = (c == '(');
6990 *p = '\0';
6991
6992
6993 if (notparseable)
6994 {
6995 notparseable = FALSE;
6996 }
6997 else if (notfunction || fileloc_isStandardLib (g_currentloc))
6998 {
6999 DPRINTF (("Clear notfunction"));
7000 notfunction = FALSE;
7001 }
7002 else
7003 {
7004 if (noexpand)
7005 {
7006 checkmacro = TRUE;
7007
7008 if (!expectenditer)
7009 {
7010 noexpand = FALSE;
7011 }
7012 }
7013 else
7014 {
7015 if (usymtab_existsReal (sname))
7016 {
7017 uentry ue = usymtab_lookup (sname);
7018
7019 DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7020
7021 if (fileloc_isPreproc (uentry_whereLast (ue)))
7022 {
7023 goto macroDne;
7024 }
7025 else
7026 {
7027 if (uentry_isSpecified (ue))
7028 {
7029 checkmacro = context_getFlag (FLG_SPECMACROS);
7030 }
7031 else
7032 {
7033 if (hasParams)
7034 {
7035 checkmacro = context_getFlag (FLG_LIBMACROS)
7036 || context_getFlag (FLG_FCNMACROS);
7037 }
7038 }
7039 }
7040 }
7041 else
7042 {
7043 macroDne:
7044 DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7045
7046 if (fileloc_isSystemFile (g_currentloc)
7047 && context_getFlag (FLG_SYSTEMDIREXPAND))
7048 {
7049 ; /* don't check this macro */
7050 DPRINTF (("Don't check 1"));
7051 }
7052 else
7053 {
7054 uentry le;
7055
7056 if (hasParams)
7057 {
7058 DPRINTF (("Has params..."));
7059
7060 if (context_getFlag (FLG_FCNMACROS))
7061 {
7062 if (usymtab_exists (sname))
7063 {
7064 /*
7065 ** only get here is macro is redefined
7066 ** error reported elsewhere
7067 */
7068
7069 DPRINTF (("It exists!"));
7070 }
7071 else
7072 {
7073 /*
7074 ** We make it a forward function, since it might be declared elsewhere.
7075 ** After all headers have been processed, we should check the forward
7076 ** functions.
7077 */
7078
7079 fileloc loc = fileloc_makePreproc (g_currentloc);
7080
7081 /* the line is off-by-one, since the newline was already read */
7082 decLine ();
7083
7084 if (expectfunction)
7085 {
7086 expectfunction = FALSE;
7087 }
7088
7089 le = uentry_makeForwardFunction (sname,
7090 typeId_invalid, loc);
7091
7092 fileloc_free (loc);
7093
7094 incLine ();
7095
7096 /* Do not define here! */
7097
7098 (void) usymtab_addEntry (le);
7099 }
7100
7101 checkmacro = TRUE;
7102 DPRINTF (("Check: TRUE"));
7103 }
7104 else
7105 {
7106 DPRINTF (("Flag FCN_MACROS not set!"));
7107 }
7108 }
7109 else
7110 {
7111 DPRINTF (("No params"));
7112
7113 if (context_getFlag (FLG_CONSTMACROS))
7114 {
7115 bool nocontent = FALSE;
7116
7117 if (c == '\0')
7118 {
7119 nocontent = TRUE;
7120 }
7121 else
7122 {
7123 if (isspace (c))
7124 {
7125 char *rest = p + 1;
7126
7127 /*
7128 ** Check if there is nothing after the define.
7129 */
7130
7131 while ((*rest) != '\0' && isspace (*rest))
7132 {
7133 rest++;
7134 }
7135
7136 if (*rest == '\0')
7137 {
7138 nocontent = TRUE; /* empty macro, don't check */
7139 }
7140 }
7141 }
7142
7143 if (usymtab_exists (sname))
7144 {
7145 ;
7146 }
7147 else
7148 {
7149 fileloc loc = fileloc_makePreproc (g_currentloc);
7150 DPRINTF (("Make constant: %s", sname));
7151 le = uentry_makeConstant (sname,
7152 ctype_unknown, loc);
7153 (void) usymtab_addEntry (le);
7154 }
7155
7156 checkmacro = !nocontent;
7157 }
7158 }
7159 }
7160
7161 if (checkmacro && usymtab_existsType (sname))
7162 {
7163 DPRINTF (("Making false..."));
7164 decLine ();
7165 ppllerror (message ("Specified type implemented as macro: %s", sname));
7166 checkmacro = FALSE;
7167 incLine ();
7168 }
7169 }
7170 }
7171 }
7172
7173 if (!checkmacro)
7174 {
7175 if (usymtab_exists (sname))
7176 {
7177 uentry ue = usymtab_lookupExpose (sname);
7178 fileloc tloc = fileloc_makePreproc (g_currentloc);
7179
7180 uentry_setDefined (ue, tloc);
7181 fileloc_free (tloc);
7182 uentry_setUsed (ue, fileloc_undefined);
7183 }
7184 else
7185 {
7186 fileloc tloc = fileloc_makePreproc (g_currentloc);
7187 uentry ue = uentry_makeExpandedMacro (sname, tloc);
7188 DPRINTF (("Make expanded macro: %s", sname));
7189 DPRINTF (("Not in symbol table: %s", sname));
7190
7191 (void) usymtab_addGlobalEntry (ue);
7192 fileloc_free (tloc);
7193 }
7194 }
7195
7196 *p = c;
7197 DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
7198 return checkmacro;
7199}
7200
7201static enum cpp_token
7202cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
7203{
7204 cppBuffer *pbuf = cppReader_getBuffer (pfile);
7205 char *start;
7206 int len;
7207 bool eliminateComment = FALSE;
7208
7209 llassert (pbuf->buf != NULL);
7210
7211 start = pbuf->buf + smark->position;
7212
7213 llassert (pbuf->cur != NULL);
7214 len = pbuf->cur - start;
7215
7216 if (start[0] == '*'
7217 && start[1] == context_getCommentMarkerChar ())
7218 {
7219 int i;
7220 char c = ' ';
7221 char *scomment = start + 2;
7222 char savec = start[len];
7223
7224 start[0] = BEFORE_COMMENT_MARKER[0];
7225 start[1] = BEFORE_COMMENT_MARKER[1];
7226
7227 llassert (start[len - 2] == '*');
7228 start[len - 2] = AFTER_COMMENT_MARKER[0];
7229
7230 llassert (start[len - 1] == '/');
7231 start[len - 1] = AFTER_COMMENT_MARKER[1];
7232
7233 cppReader_reserve(pfile, size_fromInt (1 + len));
7234 cppReader_putCharQ (pfile, c);
7235
7236 cpp_setLocation (pfile);
7237
7238 start[len] = '\0';
7239
7240 if (mstring_containsString (scomment, "/*"))
7241 {
7242 (void) cppoptgenerror
7243 (FLG_NESTCOMMENT,
7244 message ("Comment starts inside syntactic comment: %s",
7245 cstring_fromChars (scomment)),
7246 pfile);
7247 }
7248
7249 start[len] = savec;
7250
7251 if (mstring_equalPrefix (scomment, "ignore"))
7252 {
7253 if (!context_getFlag (FLG_NOCOMMENTS))
7254 {
7255 context_enterSuppressRegion ();
7256 }
7257 }
7258 else if (mstring_equalPrefix (scomment, "end"))
7259 {
7260 if (!context_getFlag (FLG_NOCOMMENTS))
7261 {
7262 context_exitSuppressRegion ();
7263 }
7264 }
7265 else if (mstring_equalPrefix (scomment, "notparseable"))
7266 {
7267 notparseable = TRUE;
7268 expectmacro = TRUE;
7269 eliminateComment = TRUE;
7270 }
7271 else if (mstring_equalPrefix (scomment, "notfunction"))
7272 {
7273 notfunction = TRUE;
7274 expectmacro = TRUE;
7275 eliminateComment = TRUE;
7276 }
7277 else if (mstring_equalPrefix (scomment, "iter"))
7278 {
7279 expectiter = TRUE;
7280 }
7281 else if (mstring_equalPrefix (scomment, "function"))
7282 {
7283 expectfunction = TRUE;
7284 }
7285 else if (mstring_equalPrefix (scomment, "constant"))
7286 {
7287 expectconstant = TRUE;
7288 }
7289 else
7290 {
7291 char sChar = *scomment;
7292
7293 if (sChar == '='
7294 || sChar == '-'
7295 || sChar == '+')
7296 {
7297 char *rest = scomment + 1;
7298
7299 if (mstring_equalPrefix (rest, "commentchar"))
7300 {
7301 eliminateComment = TRUE;
7302
7303 if (sChar == '=')
7304 {
7305 ppllerror (cstring_makeLiteral
7306 ("Cannot restore commentchar"));
7307 }
7308 else
7309 {
7310 char *next = scomment + 12; /* strlen commentchar = 12 */
7311
7312 if (*next != ' ' && *next != '\t' && *next != '\n')
7313 {
7314 ppllerror
7315 (message
7316 ("Syntactic commentchar comment is not followed by a "
7317 "whitespace character: %c",
7318 *next));
7319 }
7320 else
7321 {
7322 char cchar = *(next + 1);
7323
7324 if (cchar == '\0')
7325 {
7326 ppllerror
7327 (cstring_makeLiteral
7328 ("Cannot set commentchar to NUL"));
7329 }
7330 else
7331 {
7332 context_setCommentMarkerChar (cchar);
7333 /* setComment = TRUE; */
7334 }
7335 }
7336 }
7337 }
7338 else if (mstring_equalPrefix (scomment, "nestcomment"))
7339 {
7340 /* fix from Mike Miller <MikeM@xata.com> */
7341 context_fileSetFlag (FLG_NESTCOMMENT,
7342 ynm_fromCodeChar (sChar));
7343 }
7344 else if (mstring_equalPrefix (rest, "namechecks"))
7345 {
7346 context_fileSetFlag (FLG_NAMECHECKS,
7347 ynm_fromCodeChar (sChar));
7348 }
7349 else if (mstring_equalPrefix (rest, "macroredef"))
7350 {
7351 context_fileSetFlag (FLG_MACROREDEF,
7352 ynm_fromCodeChar (sChar));
7353 }
7354 else if (mstring_equalPrefix (rest, "usevarargs"))
7355 {
7356 context_fileSetFlag (FLG_USEVARARGS,
7357 ynm_fromCodeChar (sChar));
7358 }
7359 else if (mstring_equalPrefix (rest, "nextlinemacros"))
7360 {
7361 context_fileSetFlag (FLG_MACRONEXTLINE,
7362 ynm_fromCodeChar (sChar));
7363 }
7364 else if (mstring_equalPrefix (rest, "allmacros")
7365 || mstring_equalPrefix (rest, "fcnmacros")
7366 || mstring_equalPrefix (rest, "constmacros"))
7367 {
7368 flagcode fl;
7369
7370 if (mstring_equalPrefix (rest, "allmacros"))
7371 {
7372 fl = FLG_ALLMACROS;
7373 }
7374 else if (mstring_equalPrefix (rest, "fcnmacros"))
7375 {
7376 fl = FLG_FCNMACROS;
7377 }
7378 else
7379 {
7380 llassert (mstring_equalPrefix (rest, "constmacros"));
7381 fl = FLG_CONSTMACROS;
7382 }
7383
7384
7385 context_fileSetFlag (fl, ynm_fromCodeChar (sChar));
7386 notfunction = FALSE;
7387 }
7388 else
7389 {
7390 ;
7391 }
7392 }
7393 else
7394 {
7395 ;
7396 }
7397 }
7398
7399 if (eliminateComment)
7400 {
7401 goto removeComment;
7402 }
7403
7404 /* Replaces comment char's in start with spaces */
7405
7406 for (i = 2; i < len - 2; i++)
7407 {
7408 if (start[i] == BEFORE_COMMENT_MARKER[0]
7409 || start[i] == BEFORE_COMMENT_MARKER[1]
7410 || start[i] == context_getCommentMarkerChar ())
7411 {
7412 start[i] = ' ';
7413 }
7414 }
7415
7416 cppReader_putStrN (pfile, start, size_fromInt (len));
7417 parseClearMark (smark);
7418 return CPP_COMMENT;
7419 }
7420 else
7421 {
7422 removeComment:
7423 {
7424 int i;
7425
7426 /*
7427 ** Output the comment as all spaces so line/column
7428 ** in output file is still correct.
7429 */
7430
7431 char c = ' ';
7432 cstring lintcomment = cstring_undefined;
7433
7434 if (context_getFlag (FLG_LINTCOMMENTS))
7435 {
7436 if (mstring_equalPrefix (start, "*NOTREACHED*/"))
7437 {
7438 lintcomment = cstring_makeLiteralTemp ("l_notreach");
7439 }
7440 else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
7441 {
7442 lintcomment = cstring_makeLiteralTemp ("l_printfli");
7443 }
7444 else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
7445 {
7446 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
7447 }
7448 else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
7449 {
7450 lintcomment = cstring_makeLiteralTemp ("l_argsus");
7451 }
7452 else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
7453 {
7454 lintcomment = cstring_makeLiteralTemp ("l_fallth");
7455 }
7456 else
7457 {
7458 lintcomment = cstring_undefined;
7459 }
7460 }
7461 else
7462 {
7463 lintcomment = cstring_undefined;
7464 }
7465
7466 if (cstring_isDefined (lintcomment))
7467 {
7468 c = BEFORE_COMMENT_MARKER[0];
7469 start[0] = BEFORE_COMMENT_MARKER[1];
7470
7471 llassert (cstring_length (lintcomment) == len - 3);
7472
7473 for (i = 1; i < len - 2; i++)
7474 {
7475 start[i] = cstring_getChar (lintcomment, i);
7476 }
7477
7478 start[len - 2] = AFTER_COMMENT_MARKER[0];
7479 start[len - 1] = AFTER_COMMENT_MARKER[1];
7480 }
7481 else
7482 {
7483 /* Replaces char's in start with spaces */
7484 for (i = 0; i < len; i++)
7485 {
7486 if (start[i] == '/'
7487 && i < len - 1
7488 && start[i + 1] == '*') {
7489 (void) cppoptgenerror (FLG_NESTCOMMENT,
7490 message ("Comment starts inside comment"),
7491 pfile);
7492 }
7493
7494 if (start[i] != '\n')
7495 {
7496 start[i] = ' ';
7497 }
7498 }
7499 }
7500
7501 cppReader_reserve (pfile, size_fromInt (1 + len));
7502 cppReader_putCharQ (pfile, c);
7503 cppReader_putStrN (pfile, start, size_fromInt (len));
7504 parseClearMark (smark);
7505 return CPP_COMMENT;
7506 }
7507 }
7508}
7509
7510static int cpp_openIncludeFile (char *filename)
7511{
7512 int res = open (filename, O_RDONLY, 0666);
7513
7514 /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
7515 if (res >= 0)
7516 {
7517 if (!fileTable_exists (context_fileTable (),
7518 cstring_fromChars (filename)))
7519 {
7520 (void) fileTable_addHeaderFile (context_fileTable (),
7521 cstring_fromChars (filename));
7522 }
7523 else
7524 {
7525 DPRINTF (("File already exists: %s", filename));
7526 }
7527 }
7528
7529 return res;
7530}
7531
7532static bool cpp_skipIncludeFile (cstring fname)
7533{
7534 if (context_isSystemDir (fname))
7535 {
7536 DPRINTF (("System dir: %s", fname));
7537
7538 if (lcllib_isSkipHeader (fname))
7539 {
7540 DPRINTF (("Skip include TRUE: %s", fname));
7541 return TRUE;
7542 }
7543
7544 if (context_getFlag (FLG_SKIPSYSHEADERS))
7545 {
7546 DPRINTF (("Skip include TRUE: %s", fname));
7547 return TRUE;
7548 }
7549 }
7550
7551 if (context_getFlag (FLG_SINGLEINCLUDE))
7552 {
7553 fname = removePreDirs (fname);
7554
7555# if defined (WIN32) || defined (OS2)
7556 cstring_replaceAll (fname, '\\', '/');
7557# endif
7558
7559 if (fileTable_exists (context_fileTable (), fname))
7560 {
7561 DPRINTF (("Skip include TRUE: %s", fname));
7562 return TRUE;
7563 }
7564 }
7565
7566 DPRINTF (("Skip include FALSE: %s", fname));
7567 return FALSE;
7568}
7569
7570static int cpp_peekN (cppReader *pfile, int n)
7571{
7572 cppBuffer *buf = cppReader_getBuffer (pfile);
7573
7574 llassert (buf->cur != NULL);
7575
7576 return (buf->rlimit - buf->cur >= (n)
7577 ? buf->cur[n]
7578 : EOF);
7579}
7580
7581cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
7582{
7583 return buf + 1;
7584}
7585
7586void cppBuffer_forward (cppBuffer *buf, int n)
7587{
7588 llassert (buf->cur != NULL);
7589 buf->cur += n;
7590}
This page took 1.32321 seconds and 5 git commands to generate.