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