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