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