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