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