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