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