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