]> andersk Git - splint.git/blob - src/cpplib.c
4b4e1622b967d8918c902f724e5a1b2d7e85591b
[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   cpplib_installBuiltin ("__" TARGET_CPU, ctype_int, -1, T_CONST, 2, NULL, -1);
3761
3762   /*drl 1/2/2002  set some flags based on uname
3763     I'd like to be able to do this with autoconf macro instead...
3764    */
3765
3766   /*Thanks to Nelson Beebe for suggesting possible values for these */
3767   
3768   if (! strcmp (UNAME, "Linux"))
3769     {
3770 #ifdef __ppc
3771       cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3772 #endif
3773     }
3774   
3775   else if(! strcmp (UNAME, "Darwin"))
3776     {
3777       cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3778       cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3779     }
3780   else if(! strcmp (UNAME, "HP-UX"))
3781     {
3782       cpplib_installBuiltin ("PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3783       cpplib_installBuiltin ("_HIUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3784       cpplib_installBuiltin ("_HPUX_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3785       cpplib_installBuiltin ("_PA_RISC1_1", ctype_int, -1, T_CONST, 2, NULL, -1);
3786       cpplib_installBuiltin ("__PWB", ctype_int, -1, T_CONST, 2, NULL, -1);
3787       cpplib_installBuiltin ("__PWB__", ctype_int, -1, T_CONST, 2, NULL, -1);
3788       cpplib_installBuiltin ("__STDC_EXT__", ctype_int, -1, T_CONST, 2, NULL, -1);
3789       cpplib_installBuiltin ("__hp9000s700", ctype_int, -1, T_CONST, 2, NULL, -1);
3790       cpplib_installBuiltin ("__hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3791       cpplib_installBuiltin ("__hp9000s800__", ctype_int, -1, T_CONST, 2, NULL, -1);
3792       cpplib_installBuiltin ("__hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3793       cpplib_installBuiltin ("__hp9k8__", ctype_int, -1, T_CONST, 2, NULL, -1);
3794       cpplib_installBuiltin ("__hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3795       cpplib_installBuiltin ("__hppa__", ctype_int, -1, T_CONST, 2, NULL, -1);
3796       cpplib_installBuiltin ("__hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3797       cpplib_installBuiltin ("__hpux__", ctype_int, -1, T_CONST, 2, NULL, -1);
3798       cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3799       cpplib_installBuiltin ("__unix__", ctype_int, -1, T_CONST, 2, NULL, -1);
3800       cpplib_installBuiltin ("hp9000s800", ctype_int, -1, T_CONST, 2, NULL, -1);
3801       cpplib_installBuiltin ("hp9k8", ctype_int, -1, T_CONST, 2, NULL, -1);
3802       cpplib_installBuiltin ("hppa", ctype_int, -1, T_CONST, 2, NULL, -1);
3803       cpplib_installBuiltin ("hpux", ctype_int, -1, T_CONST, 2, NULL, -1);
3804       cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3805     }
3806   else if(! strcmp (UNAME, "IRIX64"))
3807     {
3808       cpplib_installBuiltin ("LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3809       cpplib_installBuiltin ("MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3810       cpplib_installBuiltin ("_ABIN32", ctype_int, -1, T_CONST, 2, NULL, -1);
3811       cpplib_installBuiltin ("_COMPILER_VERSION", ctype_int, -1, T_CONST, 730, NULL, -1);
3812       cpplib_installBuiltin ("_LANGUAGE_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3813       cpplib_installBuiltin ("_LONGLONG", ctype_int, -1, T_CONST, 2, NULL, -1);
3814       cpplib_installBuiltin ("_MIPSEB", ctype_int, -1, T_CONST, 2, NULL, -1);
3815       cpplib_installBuiltin ("_MIPS_FPSET", ctype_int, -1, T_CONST, 32, NULL, -1);
3816       cpplib_installBuiltin ("_MIPS_ISA", ctype_int, -1, T_CONST, 3, NULL, -1);
3817       /*_MIPS_SIM=_ABIN32*/
3818       cpplib_installBuiltin ("_MIPS_SIM", ctype_int, -1, T_CONST, 2, NULL , -1);
3819       cpplib_installBuiltin ("_MIPS_SZINT", ctype_int, -1, T_CONST, 32, NULL, -1);
3820       cpplib_installBuiltin ("_MIPS_SZLONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3821       cpplib_installBuiltin ("_MIPS_SZPTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3822       cpplib_installBuiltin ("_MODERN_C", ctype_int, -1, T_CONST, 2, NULL, -1);
3823       cpplib_installBuiltin ("_PIC", ctype_int, -1, T_CONST, 2, NULL, -1);
3824       cpplib_installBuiltin ("_SGI_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3825       cpplib_installBuiltin ("_SIZE_INT", ctype_int, -1, T_CONST, 32, NULL, -1);
3826       cpplib_installBuiltin ("_SIZE_LONG", ctype_int, -1, T_CONST, 32, NULL, -1);
3827       cpplib_installBuiltin ("_SIZE_PTR", ctype_int, -1, T_CONST, 32, NULL, -1);
3828       cpplib_installBuiltin ("_SVR4_SOURCE", ctype_int, -1, T_CONST, 2, NULL, -1);
3829       cpplib_installBuiltin ("_SYSTYPE_SVR4", ctype_int, -1, T_CONST, 2, NULL, -1);
3830       cpplib_installBuiltin ("__DSO__", ctype_int, -1, T_CONST, 2, NULL, -1);
3831       cpplib_installBuiltin ("__EXTENSIONS__", ctype_int, -1, T_CONST, 2, NULL, -1);
3832       cpplib_installBuiltin ("__INLINE_INTRINSICS", ctype_int, -1, T_CONST, 2, NULL, -1);
3833       cpplib_installBuiltin ("__MATH_HAS_NO_SIDE_EFFECTS", ctype_int, -1, T_CONST, 2, NULL, -1);
3834       cpplib_installBuiltin ("__host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3835       cpplib_installBuiltin ("__mips", ctype_int, -1, T_CONST, 3, NULL, -1);
3836       cpplib_installBuiltin ("__sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3837       cpplib_installBuiltin ("__unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3838       cpplib_installBuiltin ("host_mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3839       cpplib_installBuiltin ("mips", ctype_int, -1, T_CONST, 2, NULL, -1);
3840       cpplib_installBuiltin ("sgi", ctype_int, -1, T_CONST, 2, NULL, -1);
3841       cpplib_installBuiltin ("unix", ctype_int, -1, T_CONST, 2, NULL, -1);
3842     }
3843   else if(! strcmp (UNAME, "OSF1"))
3844     {
3845       cpplib_installBuiltin ("__alpha", ctype_int, -1, T_CONST, 2, NULL, -1);
3846     }
3847   else if (!strcmp (UNAME, "Rhapsody"))
3848     {
3849       cpplib_installBuiltin ("__ppc__", ctype_int, -1, T_CONST, 2, NULL, -1);
3850       cpplib_installBuiltin ("__BIG_ENDIAN__", ctype_int, -1, T_CONST, 2, NULL, -1);
3851     }
3852
3853   else if (!strcmp (UNAME, "SunOS"))
3854     {
3855       cpplib_installBuiltin ("__OPEN_MAX", ctype_int, -1, T_CONST, 20, NULL, -1);
3856       cpplib_installBuiltin ("__STDC__", ctype_int, -1, T_CONST, 2, NULL, -1);
3857       cpplib_installBuiltin ("__sparc", ctype_int, -1, T_CONST, 2, NULL, -1);
3858       /*       This define  "-Dfileno(f)=0" should be inserted but we're going to stick to deinfe constants for now...*/
3859     }
3860   else
3861     {
3862       /*
3863         types which we have not explictedly handled.
3864         AIX, FreeBSD, IRIX, Mach
3865        */
3866
3867     }
3868   
3869   if (CPPOPTIONS (pfile)->debug_output)
3870     {
3871       dump_special_to_buffer (pfile, "__BASE_FILE__");
3872       dump_special_to_buffer (pfile, "__VERSION__");
3873 #ifndef NO_BUILTIN_SIZE_TYPE
3874       dump_special_to_buffer (pfile, "__SIZE_TYPE__");
3875 #endif
3876 #ifndef NO_BUILTIN_PTRDIFF_TYPE
3877       dump_special_to_buffer (pfile, "__PTRDIFF_TYPE__");
3878 #endif
3879       dump_special_to_buffer (pfile, "__WCHAR_TYPE__");
3880       dump_special_to_buffer (pfile, "__DATE__");
3881       dump_special_to_buffer (pfile, "__TIME__");
3882       if (!cppReader_isTraditional (pfile))
3883         dump_special_to_buffer (pfile, "__STDC__");
3884     }
3885 }
3886
3887
3888 /* Return 1 iff a token ending in C1 followed directly by a token C2
3889    could cause mis-tokenization.  */
3890
3891 static bool
3892 unsafe_chars (char c1, char c2)
3893 {
3894   switch (c1)
3895     {
3896     case '+': case '-':
3897       if (c2 == c1 || c2 == '=')
3898         return 1;
3899       goto letter;
3900     case '.':
3901     case '0': case '1': case '2': case '3': case '4':
3902     case '5': case '6': case '7': case '8': case '9':
3903     case 'e': case 'E': case 'p': case 'P':
3904       if (c2 == '-' || c2 == '+')
3905         return 1; /* could extend a pre-processing number */
3906       goto letter;
3907     case 'L':
3908       if (c2 == '\'' || c2 == '\"')
3909         return 1;   /* Could turn into L"xxx" or L'xxx'.  */
3910       goto letter;
3911     letter:
3912     case '_':
3913     case 'a': case 'b': case 'c': case 'd':           case 'f':
3914     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
3915     case 'm': case 'n': case 'o':           case 'q': case 'r':
3916     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
3917     case 'y': case 'z':
3918     case 'A': case 'B': case 'C': case 'D':           case 'F':
3919     case 'G': case 'H': case 'I': case 'J': case 'K':
3920     case 'M': case 'N': case 'O':           case 'Q': case 'R':
3921     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
3922     case 'Y': case 'Z':
3923       /* We're in the middle of either a name or a pre-processing number.  */
3924       return (is_idchar[(int) c2] || c2 == '.');
3925     case '<': case '>': case '!': case '%': case '#': case ':':
3926     case '^': case '&': case '|': case '*': case '/': case '=':
3927       return (c2 == c1 || c2 == '=');
3928     }
3929   return 0;
3930 }
3931
3932 /* Expand a macro call.
3933    HP points to the symbol that is the macro being called.
3934    Put the result of expansion onto the input stack
3935    so that subsequent input by our caller will use it.
3936
3937    If macro wants arguments, caller has already verified that
3938    an argument list follows; arguments come from the input stack.  */
3939
3940 static void
3941 cpplib_macroExpand (cppReader *pfile, /*@dependent@*/ hashNode hp)
3942 {
3943   int nargs;
3944   DEFINITION *defn = hp->value.defn;
3945   char *xbuf;
3946   char *oxbuf = NULL;
3947   int start_line;
3948   int start_column;
3949   int end_line;
3950   int end_column;
3951   size_t xbuf_len;
3952   size_t old_written = cpplib_getWritten (pfile);
3953   int rest_args;
3954   int rest_zero = 0;
3955   int i;
3956   struct argdata *args = NULL;
3957
3958   pfile->output_escapes++;
3959   cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &start_line, &start_column);
3960   DPRINTF (("Expand macro: %d:%d", start_line, start_column));
3961
3962   nargs = defn->nargs;
3963
3964   if (nargs >= 0)
3965     {
3966       enum cpp_token token = CPP_EOF;
3967
3968       args = (struct argdata *) dmalloc ((nargs + 1) * sizeof (*args));
3969
3970       for (i = 0; i < nargs; i++)
3971         {
3972           args[i].expanded = 0;
3973           args[i].raw = 0;
3974           args[i].raw_length = 0;
3975           args[i].expand_length = args[i].stringified_length = -1;
3976           args[i].use_count = 0;
3977         }
3978
3979       /*
3980       ** Parse all the macro args that are supplied.  I counts them.
3981       ** The first NARGS args are stored in ARGS.
3982       ** The rest are discarded.  If rest_args is set then we assume
3983       ** macarg absorbed the rest of the args.
3984       */
3985
3986       i = 0;
3987       rest_args = 0;
3988
3989       cppReader_forward (pfile, 1); /* Discard the open-parenthesis before the first arg.  */
3990       do
3991         {
3992           if (rest_args != 0)
3993             {
3994               continue;
3995             }
3996
3997           if (i < nargs || (nargs == 0 && i == 0))
3998             {
3999               /* if we are working on last arg which absorbs rest of args... */
4000               if (i == nargs - 1 && defn->rest_args)
4001                 {
4002                   rest_args = 1;
4003                 }
4004
4005               args[i].raw = size_toLong (cpplib_getWritten (pfile));
4006               token = macarg (pfile, rest_args);
4007               args[i].raw_length = size_toInt (cpplib_getWritten (pfile) - args[i].raw);
4008               args[i].newlines = FALSE; /* FIXME */
4009             }
4010           else
4011             {
4012               token = macarg (pfile, 0);
4013             }
4014
4015           if (token == CPP_EOF || token == CPP_POP)
4016             {
4017               cppReader_errorWithLine (pfile, start_line, start_column,
4018                                    cstring_fromCharsNew ("unterminated macro call"));
4019               sfree (args);
4020               return;
4021             }
4022           i++;
4023         } while (token == CPP_COMMA);
4024
4025       /* If we got one arg but it was just whitespace, call that 0 args.  */
4026       if (i == 1)
4027         {
4028           char *bp;
4029           char *lim;
4030
4031           assertSet (args);
4032
4033           bp = ARG_BASE + args[0].raw;
4034           lim = bp + args[0].raw_length;
4035
4036           /* cpp.texi says for foo ( ) we provide one argument.
4037              However, if foo wants just 0 arguments, treat this as 0.  */
4038
4039           if (nargs == 0)
4040             {
4041               while (bp != lim && is_space[(int) *bp])
4042                 {
4043                   bp++;
4044                 }
4045             }
4046
4047           if (bp == lim)
4048             i = 0;
4049         }
4050
4051       /* Don't output an error message if we have already output one for
4052          a parse error above.  */
4053       rest_zero = 0;
4054
4055       if (nargs == 0 && i > 0)
4056         {
4057           cppReader_error (pfile,
4058                      message ("arguments given to macro `%s'", hp->name));
4059         }
4060       else if (i < nargs)
4061         {
4062           /* traditional C allows foo() if foo wants one argument.  */
4063           if (nargs == 1 && i == 0 && cppReader_isTraditional (pfile))
4064             {
4065               ;
4066             }
4067           /* the rest args token is allowed to absorb 0 tokens */
4068           else if (i == nargs - 1 && defn->rest_args)
4069             rest_zero = 1;
4070           else if (i == 0)
4071             cppReader_error (pfile,
4072                        message ("macro `%s' used without args", hp->name));
4073           else if (i == 1)
4074             cppReader_error (pfile,
4075                        message ("macro `%s' used with just one arg", hp->name));
4076           else
4077             {
4078               cppReader_error (pfile,
4079                          message ("macro `%s' used with only %d args",
4080                                   hp->name, i));
4081             }
4082         }
4083       else if (i > nargs)
4084         {
4085           cppReader_error (pfile,
4086                      message ("macro `%s' used with too many (%d) args", hp->name, i));
4087         }
4088       else
4089         {
4090           ;
4091         }
4092     }
4093
4094   /*
4095   ** If the agrument list was multiple lines, need to insert new lines to keep line
4096   ** numbers accurate.
4097   */
4098
4099   cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile), &end_line, &end_column);
4100   DPRINTF (("Expand macro: %d:%d", end_line, end_column));
4101   
4102   /* If macro wants zero args, we parsed the arglist for checking only.
4103      Read directly from the macro definition.  */
4104
4105   if (nargs <= 0)
4106     {
4107       xbuf = defn->expansion;
4108       xbuf_len = defn->length;
4109     }
4110   else
4111     {
4112       char *exp = defn->expansion;
4113       int offset;       /* offset in expansion,
4114                                    copied a piece at a time */
4115       size_t totlen;    /* total amount of exp buffer filled so far */
4116
4117       register struct reflist *ap, *last_ap;
4118       
4119       assertSet (args); /* args is defined since the nargs > 0 path was taken */
4120
4121       /* Macro really takes args.  Compute the expansion of this call.  */
4122
4123       /* Compute length in characters of the macro's expansion.
4124          Also count number of times each arg is used.  */
4125       xbuf_len = defn->length;
4126
4127       llassert (args != NULL);
4128
4129       for (ap = defn->pattern; ap != NULL; ap = ap->next)
4130         {
4131           if (ap->stringify)
4132             {
4133               struct argdata *arg = &args[ap->argno];
4134
4135               /* Stringify it it hasn't already been */
4136               assertSet (arg);
4137
4138               if (arg->stringified_length < 0)
4139                 {
4140                   int arglen = arg->raw_length;
4141                   bool escaped = FALSE;
4142                   char in_string = '\0';
4143                   char c;
4144
4145                   /* Initially need_space is -1.  Otherwise, 1 means the
4146                      previous character was a space, but we suppressed it;
4147                      0 means the previous character was a non-space.  */
4148                   int need_space = -1;
4149
4150                   i = 0;
4151                   arg->stringified = cpplib_getWritten (pfile);
4152                   if (!cppReader_isTraditional (pfile))
4153                     cppReader_putChar (pfile, '\"'); /* insert beginning quote */
4154                   for (; i < arglen; i++)
4155                     {
4156                       c = (ARG_BASE + arg->raw)[i];
4157
4158                       if (in_string == '\0')
4159                         {
4160                           /* Internal sequences of whitespace are replaced by
4161                              one space except within an string or char token.*/
4162                           if (is_space[(int) c])
4163                             {
4164                               if (cpplib_getWritten (pfile) > arg->stringified
4165                                   && (cpplib_getPWritten (pfile))[-1] == '@')
4166                                 {
4167                                   /* "@ " escape markers are removed */
4168                                   cppReader_adjustWritten (pfile, -1);
4169                                   /*@innercontinue@*/ continue;
4170                                 }
4171                               if (need_space == 0)
4172                                 need_space = 1;
4173                               /*@innercontinue@*/ continue;
4174                             }
4175                           else if (need_space > 0)
4176                             cppReader_putChar (pfile, ' ');
4177                           else
4178                             {
4179                               ;
4180                             }
4181
4182                           need_space = 0;
4183                         }
4184
4185                       if (escaped)
4186                         escaped = 0;
4187                       else
4188                         {
4189                           if (c == '\\')
4190                             escaped = 1;
4191
4192                           if (in_string != '\0')
4193                             {
4194                               if (c == in_string)
4195                                 in_string = '\0';
4196                             }
4197                           else if (c == '\"' || c == '\'')
4198                             {
4199                               in_string = c;
4200                             }
4201                           else
4202                             {
4203                               ;
4204                             }
4205                         }
4206
4207                       /* Escape these chars */
4208                       if (c == '\"' || (in_string != '\0' && c == '\\'))
4209                         cppReader_putChar (pfile, '\\');
4210                       if (isprint (c))
4211                         cppReader_putChar (pfile, c);
4212                       else
4213                         {
4214                           cpplib_reserve (pfile, 4);
4215                           sprintf (cpplib_getPWritten (pfile), "\\%03o",
4216                                    (unsigned int) c);
4217                           cppReader_adjustWritten (pfile, 4);
4218                         }
4219                     }
4220                   if (!cppReader_isTraditional (pfile))
4221                     cppReader_putChar (pfile, '\"'); /* insert ending quote */
4222                   arg->stringified_length
4223                     = size_toInt (cpplib_getWritten (pfile) - arg->stringified);
4224                 }
4225
4226               xbuf_len += args[ap->argno].stringified_length;
4227             }
4228           else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4229             {
4230               /* Add 4 for two newline-space markers to prevent token concatenation. */
4231               assertSet (args); /* Splint shouldn't need this */
4232               xbuf_len += args[ap->argno].raw_length + 4;
4233             }
4234           else
4235             {
4236               /* We have an ordinary (expanded) occurrence of the arg.
4237                  So compute its expansion, if we have not already.  */
4238
4239               assertSet (args); /* shouldn't need this */
4240
4241               if (args[ap->argno].expand_length < 0)
4242                 {
4243                   args[ap->argno].expanded = cpplib_getWritten (pfile);
4244                   cpp_expand_to_buffer (pfile,
4245                                         ARG_BASE + args[ap->argno].raw,
4246                                         size_fromInt (args[ap->argno].raw_length));
4247
4248                   args[ap->argno].expand_length
4249                     = size_toInt (cpplib_getWritten (pfile) - args[ap->argno].expanded);
4250                 }
4251
4252               /* Add 4 for two newline-space markers to prevent
4253                  token concatenation.  */
4254               xbuf_len += args[ap->argno].expand_length + 4;
4255            }
4256           if (args[ap->argno].use_count < 10)
4257             args[ap->argno].use_count++;
4258         }
4259
4260       xbuf = (char *) dmalloc (xbuf_len + 1);
4261       oxbuf = xbuf;
4262
4263       /*
4264       ** Generate in XBUF the complete expansion
4265       ** with arguments substituted in.
4266       ** TOTLEN is the total size generated so far.
4267       ** OFFSET is the index in the definition
4268       ** of where we are copying from.
4269       */
4270
4271       offset = 0;
4272       totlen = 0;
4273
4274       for (last_ap = NULL, ap = defn->pattern; ap != NULL;
4275            last_ap = ap, ap = ap->next)
4276         {
4277           register struct argdata *arg = &args[ap->argno];
4278           size_t count_before = totlen;
4279
4280           /* Add chars to XBUF.  */
4281           for (i = 0; i < ap->nchars; i++, offset++)
4282             {
4283               xbuf[totlen++] = exp[offset];
4284             }
4285
4286           /* If followed by an empty rest arg with concatenation,
4287              delete the last run of nonwhite chars.  */
4288           if (rest_zero && totlen > count_before
4289               && ((ap->rest_args && ap->raw_before)
4290                   || (last_ap != NULL && last_ap->rest_args
4291                       && last_ap->raw_after)))
4292             {
4293               /* Delete final whitespace.  */
4294               while (totlen > count_before && is_space[(int) xbuf[totlen - 1]])
4295                 {
4296                   totlen--;
4297                 }
4298
4299               /* Delete the nonwhites before them.  */
4300               while (totlen > count_before && ! is_space[(int) xbuf[totlen - 1]])
4301                 {
4302                   totlen--;
4303                 }
4304             }
4305
4306           if (ap->stringify != 0)
4307             {
4308               assertSet(arg);
4309               memcpy (xbuf + totlen,
4310                       ARG_BASE + arg->stringified,
4311                       size_fromInt (arg->stringified_length));
4312               totlen += arg->stringified_length;
4313             }
4314           else if (ap->raw_before || ap->raw_after || cppReader_isTraditional (pfile))
4315             {
4316               char *p1;
4317               char *l1;
4318
4319               assertSet (arg);
4320
4321               p1 = ARG_BASE + arg->raw;
4322               l1 = p1 + arg->raw_length;
4323
4324               if (ap->raw_before)
4325                 {
4326                   while (p1 != l1 && is_space[(int) *p1])
4327                     {
4328                       p1++;
4329                     }
4330
4331                   while (p1 != l1 && is_idchar[(int) *p1])
4332                     {
4333                       xbuf[totlen++] = *p1++;
4334                     }
4335
4336                   /* Delete any no-reexpansion marker that follows
4337                      an identifier at the beginning of the argument
4338                      if the argument is concatenated with what precedes it.  */
4339                   if (p1[0] == '@' && p1[1] == '-')
4340                     p1 += 2;
4341                 }
4342               if (ap->raw_after)
4343                 {
4344                   /* Arg is concatenated after: delete trailing whitespace,
4345                      whitespace markers, and no-reexpansion markers.  */
4346                   while (p1 != l1)
4347                     {
4348                       if (is_space[(int) l1[-1]]) l1--;
4349                       else if (l1[-1] == '-')
4350                         {
4351                           char *p2 = l1 - 1;
4352                           /* If a `-' is preceded by an odd number of newlines then it
4353                              and the last newline are a no-reexpansion marker.  */
4354                           while (p2 != p1 && p2[-1] == '\n')
4355                             {
4356                               p2--;
4357                             }
4358
4359                           if (((l1 - 1 - p2) & 1) != 0)
4360                             {
4361                               l1 -= 2;
4362                             }
4363                           else
4364                             {
4365                               /*@innerbreak@*/ break;
4366                             }
4367                         }
4368                       else
4369                         {
4370                           /*@innerbreak@*/ break;
4371                         }
4372                     }
4373                 }
4374
4375               memcpy (xbuf + totlen, p1, size_fromInt (l1 - p1));
4376               totlen += l1 - p1;
4377             }
4378           else
4379             {
4380               char *expanded;
4381
4382               assertSet (arg);
4383               expanded = ARG_BASE + arg->expanded;
4384
4385               if (!ap->raw_before && totlen > 0
4386                   && (arg->expand_length != 0)
4387                   && !cppReader_isTraditional(pfile)
4388                   && unsafe_chars (xbuf[totlen-1], expanded[0]))
4389                 {
4390                   xbuf[totlen++] = '@';
4391                   xbuf[totlen++] = ' ';
4392                 }
4393
4394               memcpy (xbuf + totlen, expanded,
4395                       size_fromInt (arg->expand_length));
4396               totlen += arg->expand_length;
4397
4398               if (!ap->raw_after && totlen > 0
4399                   && offset < size_toInt (defn->length)
4400                   && !cppReader_isTraditional(pfile)
4401                   && unsafe_chars (xbuf[totlen-1], exp[offset]))
4402                 {
4403                   xbuf[totlen++] = '@';
4404                   xbuf[totlen++] = ' ';
4405                 }
4406
4407               /* If a macro argument with newlines is used multiple times,
4408                  then only expand the newlines once.  This avoids creating
4409                  output lines which don't correspond to any input line,
4410                  which confuses gdb and gcov.  */
4411               if (arg->use_count > 1 && arg->newlines > 0)
4412                 {
4413                   /* Don't bother doing change_newlines for subsequent
4414                      uses of arg.  */
4415                   arg->use_count = 1;
4416                   arg->expand_length
4417                     = change_newlines (expanded, arg->expand_length);
4418                 }
4419             }
4420
4421           if (totlen > xbuf_len)
4422             abort ();
4423         }
4424
4425       /* if there is anything left of the definition
4426          after handling the arg list, copy that in too.  */
4427
4428       for (i = offset; i < size_toInt (defn->length); i++)
4429         {
4430           /* if we've reached the end of the macro */
4431           if (exp[i] == ')')
4432             rest_zero = 0;
4433           if (! (rest_zero && last_ap != NULL && last_ap->rest_args
4434                  && last_ap->raw_after))
4435             xbuf[totlen++] = exp[i];
4436         }
4437
4438       xbuf[totlen] = '\0';
4439       xbuf_len = totlen;
4440     }
4441
4442   pfile->output_escapes--;
4443
4444   /* Now put the expansion on the input stack
4445      so our caller will commence reading from it.  */
4446   DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4447   
4448   if (end_line != start_line)
4449     {
4450       /* xbuf must have enough newlines */
4451       int newlines = end_line - start_line;
4452       int foundnewlines = 0;
4453       char *xbufptr = xbuf;
4454
4455       while ((xbufptr = strchr (xbufptr, '\n')) != NULL && foundnewlines <= newlines)
4456         {
4457           foundnewlines++;
4458           xbufptr++;
4459
4460           if (*xbufptr == '\0') 
4461             {
4462               break;
4463             }
4464         }
4465           
4466       if (foundnewlines < newlines)
4467         {
4468           cstring newbuf = cstring_copyLength (xbuf, xbuf_len);
4469           
4470           while (foundnewlines < newlines)
4471             {
4472               newbuf = cstring_appendChar (newbuf, '\n');
4473               foundnewlines++;
4474             }
4475
4476           sfree (oxbuf);
4477           xbuf = cstring_toCharsSafe (newbuf);
4478           xbuf_len = cstring_length (newbuf);
4479           /*@-branchstate@*/ 
4480         } /*@=branchstate@*/ 
4481     }
4482   
4483   DPRINTF (("Pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4484
4485   push_macro_expansion (pfile, xbuf, xbuf_len, hp);
4486   DPRINTF (("After pushing expansion: %s", cstring_copyLength (xbuf, xbuf_len)));
4487   cppReader_getBufferSafe (pfile)->has_escapes = 1;
4488
4489   /* Pop the space we've used in the token_buffer for argument expansion.  */
4490   cppReader_setWritten (pfile, old_written);
4491   DPRINTF (("Done set written"));
4492   
4493   /* Recursive macro use sometimes works traditionally.
4494      #define foo(x,y) bar (x (y,0), y)
4495      foo (foo, baz)  */
4496
4497   if (!cppReader_isTraditional (pfile))
4498     hp->type = T_DISABLED;
4499
4500   sfree (args);
4501 }
4502
4503 static void
4504 push_macro_expansion (cppReader *pfile, char *xbuf, size_t xbuf_len,
4505                       /*@dependent@*/ hashNode hp)
4506 {
4507   cppBuffer *mbuf = cppReader_pushBuffer (pfile, xbuf, xbuf_len);
4508
4509   if (mbuf == NULL)
4510     {
4511       return;
4512     }
4513
4514   mbuf->cleanup = cppReader_macroCleanup;
4515
4516   llassert (mbuf->hnode == NULL);
4517   mbuf->hnode = hp;
4518
4519   /* The first chars of the expansion should be a "@ " added by
4520      collect_expansion.  This is to prevent accidental token-pasting
4521      between the text preceding the macro invocation, and the macro
4522      expansion text.
4523
4524      We would like to avoid adding unneeded spaces (for the sake of
4525      tools that use cpp, such as imake).  In some common cases we can
4526      tell that it is safe to omit the space.
4527
4528      The character before the macro invocation cannot have been an
4529      idchar (or else it would have been pasted with the idchars of
4530      the macro name).  Therefore, if the first non-space character
4531      of the expansion is an idchar, we do not need the extra space
4532      to prevent token pasting.
4533
4534      Also, we don't need the extra space if the first char is '(',
4535      or some other (less common) characters.  */
4536
4537   if (xbuf[0] == '@' && xbuf[1] == ' '
4538       && (is_idchar[(int) xbuf[2]] || xbuf[2] == '(' || xbuf[2] == '\''
4539           || xbuf[2] == '\"'))
4540   {
4541     llassert (mbuf->cur != NULL);
4542     DPRINTF (("Eating: %c", xbuf[2]));
4543     mbuf->cur += 2;
4544   }
4545   
4546 }
4547
4548
4549 /* Like cpplib_getToken, except that it does not read past end-of-line.
4550    Also, horizontal space is skipped, and macros are popped.  */
4551
4552 static enum cpp_token
4553 get_directive_token (cppReader *pfile)
4554 {
4555   for (;;)
4556     {
4557       size_t old_written = cpplib_getWritten (pfile);
4558       enum cpp_token token;
4559       cppSkipHspace (pfile);
4560       if (cppReader_peekC (pfile) == '\n')
4561         {
4562           return CPP_VSPACE;
4563         }
4564
4565       token = cpplib_getToken (pfile);
4566
4567       switch (token)
4568         {
4569         case CPP_POP:
4570           if (!cppBuffer_isMacro (cppReader_getBuffer (pfile)))
4571             return token;
4572           /*@fallthrough@*/
4573         case CPP_HSPACE:
4574         case CPP_COMMENT:
4575           cppReader_setWritten (pfile, old_written);
4576           /*@switchbreak@*/ break;
4577         default:
4578           return token;
4579         }
4580     }
4581 }
4582
4583
4584 /* Handle #include and #import.
4585    This function expects to see "fname" or <fname> on the input.
4586
4587    The input is normally in part of the output_buffer following
4588    cpplib_getWritten, and will get overwritten by output_line_command.
4589    I.e. in input file specification has been popped by cppReader_handleDirective.
4590    This is safe.  */
4591
4592 static int
4593 do_include (cppReader *pfile, struct directive *keyword,
4594             /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
4595 {
4596   bool skip_dirs = (keyword->type == T_INCLUDE_NEXT);
4597   cstring fname;
4598   char *fbeg, *fend;            /* Beginning and end of fname */
4599   enum cpp_token token;
4600
4601   /* Chain of dirs to search */
4602   struct file_name_list *search_start = CPPOPTIONS (pfile)->include;
4603   struct file_name_list dsp[1]; /* First in chain, if #include "..." */
4604   struct file_name_list *searchptr = NULL;
4605   size_t old_written = cpplib_getWritten (pfile);
4606   size_t flen;
4607
4608   int f;                        /* file number */
4609   int angle_brackets = 0;       /* 0 for "...", 1 for <...> */
4610   f= -1;                        /* JF we iz paranoid! */
4611
4612   pfile->parsing_include_directive++;
4613   token = get_directive_token (pfile);
4614   pfile->parsing_include_directive--;
4615
4616   if (token == CPP_STRING)
4617     {
4618       /* FIXME - check no trailing garbage */
4619       fbeg = pfile->token_buffer + old_written + 1;
4620       fend = cpplib_getPWritten (pfile) - 1;
4621       if (fbeg[-1] == '<')
4622         {
4623           angle_brackets = 1;
4624           /* If -I-, start with the first -I dir after the -I-.  */
4625           if (CPPOPTIONS (pfile)->first_bracket_include != NULL)
4626             search_start = CPPOPTIONS (pfile)->first_bracket_include;
4627         }
4628       /* If -I- was specified, don't search current dir, only spec'd ones.  */
4629       else if (!CPPOPTIONS (pfile)->ignore_srcdir)
4630         {
4631           cppBuffer *fp = CPPBUFFER (pfile);
4632           /* We have "filename".  Figure out directory this source
4633              file is coming from and put it on the front of the list.  */
4634
4635           for ( ; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4636             {
4637               int n;
4638               char *ep,*nam;
4639
4640               llassert (fp != NULL);
4641
4642               nam = NULL;
4643
4644               if (cstring_isDefined (fp->nominal_fname))
4645                 {
4646                   nam = cstring_toCharsSafe (fp->nominal_fname);
4647
4648                   /* Found a named file.  Figure out dir of the file,
4649                      and put it in front of the search list.  */
4650                   dsp[0].next = search_start;
4651                   search_start = dsp;
4652
4653 #ifndef VMS
4654                   ep = strrchr (nam, CONNECTCHAR);
4655 #else                           /* VMS */
4656                   ep = strrchr (nam, ']');
4657                   if (ep == NULL) ep = strrchr (nam, '>');
4658                   if (ep == NULL) ep = strrchr (nam, ':');
4659                   if (ep != NULL) ep++;
4660 #endif                          /* VMS */
4661                   if (ep != NULL)
4662                     {
4663                       char save;
4664
4665                       n = ep - nam;
4666                       save = nam[n];
4667                       nam[n] = '\0';
4668
4669                       /*@-onlytrans@*/ /* This looks like a memory leak... */ 
4670                       dsp[0].fname = cstring_fromCharsNew (nam); /* evs 2000-07-20: was fromChars */
4671                       /*@=onlytrans@*/
4672                       nam[n] = save;
4673
4674                       if (n + INCLUDE_LEN_FUDGE > size_toInt (pfile->max_include_len))
4675                         pfile->max_include_len = size_fromInt (n + INCLUDE_LEN_FUDGE);
4676                     }
4677                   else
4678                     {
4679                       dsp[0].fname = cstring_undefined; /* Current directory */
4680                     }
4681
4682                   dsp[0].got_name_map = 0;
4683                   break;
4684                 }
4685             }
4686         }
4687       else
4688         {
4689           ;
4690         }
4691     }
4692 #ifdef VMS
4693   else if (token == CPP_NAME)
4694     {
4695       /*
4696        * Support '#include xyz' like VAX-C to allow for easy use of all the
4697        * decwindow include files. It defaults to '#include <xyz.h>' (so the
4698        * code from case '<' is repeated here) and generates a warning.
4699        */
4700       cppReader_warning (pfile,
4701                    "VAX-C-style include specification found, use '#include <filename.h>' !");
4702       angle_brackets = 1;
4703       /* If -I-, start with the first -I dir after the -I-.  */
4704       if (CPPOPTIONS (pfile)->first_bracket_include)
4705         search_start = CPPOPTIONS (pfile)->first_bracket_include;
4706       fbeg = pfile->token_buffer + old_written;
4707       fend = cpplib_getPWritten (pfile);
4708     }
4709 #endif
4710   else
4711     {
4712       cppReader_error (pfile,
4713                  message ("Preprocessor command #%s expects \"FILENAME\" or <FILENAME>",
4714                           keyword->name));
4715
4716       cppReader_setWritten (pfile, old_written);
4717       cppReader_skipRestOfLine (pfile);
4718       return 0;
4719     }
4720
4721   *fend = 0;
4722
4723   token = get_directive_token (pfile);
4724   if (token != CPP_VSPACE)
4725     {
4726       cppReader_errorLit (pfile,
4727                     cstring_makeLiteralTemp ("Junk at end of #include"));
4728
4729       while (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP)
4730         {
4731           token = get_directive_token (pfile);
4732         }
4733     }
4734
4735   /*
4736   ** For #include_next, skip in the search path
4737   ** past the dir in which the containing file was found.
4738   */
4739
4740   if (skip_dirs)
4741     {
4742       cppBuffer *fp = CPPBUFFER (pfile);
4743
4744       for (; fp != cppReader_nullBuffer (pfile); fp = cppBuffer_prevBuffer (fp))
4745         {
4746           llassert (fp != NULL);
4747
4748           if (fp->fname != NULL)
4749             {
4750               /* fp->dir is null if the containing file was specified with
4751                  an absolute file name.  In that case, don't skip anything.  */
4752               if (fp->dir == SELF_DIR_DUMMY)
4753                 {
4754                   search_start = CPPOPTIONS (pfile)->include;
4755                 }
4756               else if (fp->dir != NULL)
4757                 {
4758                   search_start = fp->dir->next;
4759                 }
4760               else
4761                 {
4762                   ;
4763                 }
4764
4765               break;
4766             }
4767         }
4768     }
4769   
4770   cppReader_setWritten (pfile, old_written);
4771
4772   flen = size_fromInt (fend - fbeg);
4773
4774   DPRINTF (("fbeg: %s", fbeg));
4775
4776   if (flen == 0)
4777     {
4778       cppReader_error (pfile,
4779                  message ("Empty file name in #%s", keyword->name));
4780       return 0;
4781     }
4782
4783   /*
4784   ** Allocate this permanently, because it gets stored in the definitions
4785   ** of macros.
4786   */
4787
4788   fname = cstring_undefined;
4789
4790   /* + 2 above for slash and terminating null.  */
4791   /* + 2 added for '.h' on VMS (to support '#include filename') */
4792
4793   /* If specified file name is absolute, just open it.  */
4794
4795   if (osd_isConnectChar (*fbeg)
4796 # if defined (WIN32) || defined (OS2)
4797       || (*(fbeg + 1) == ':')
4798 # endif
4799       )
4800     {
4801       fname = cstring_copyLength (fbeg, flen);
4802       
4803       if (redundant_include_p (pfile, fname))
4804         {
4805           cstring_free (fname);
4806           return 0;
4807         }
4808       
4809       f = open_include_file (pfile, fname, NULL);
4810       
4811       if (f == IMPORT_FOUND)
4812         {
4813           return 0;             /* Already included this file */
4814         }
4815     } 
4816   else 
4817     {
4818       /* Search directory path, trying to open the file.
4819          Copy each filename tried into FNAME.  */
4820
4821       for (searchptr = search_start; searchptr != NULL;
4822            searchptr = searchptr->next)
4823         {
4824           if (!cstring_isEmpty (searchptr->fname))
4825             {
4826               /* The empty string in a search path is ignored.
4827                  This makes it possible to turn off entirely
4828                  a standard piece of the list.  */
4829               if (cstring_isEmpty (searchptr->fname))
4830                 continue;
4831               
4832               fname = cstring_copy (searchptr->fname);
4833               fname = cstring_appendChar (fname, CONNECTCHAR);
4834               DPRINTF (("Here: %s", fname));
4835             }
4836           else
4837             {
4838               ;
4839             }
4840           
4841           fname = cstring_concatLength (fname, fbeg, flen);
4842
4843           DPRINTF (("fname: %s", fname));
4844           
4845           /* Win32 directory fix from Kay Buschner. */
4846 #if defined (WIN32) || defined (OS2)
4847           /* Fix all unixdir slashes to win dir slashes */
4848           if (searchptr->fname && (searchptr->fname[0] != 0)) 
4849             {
4850               cstring_replaceAll (fname, '/', '\\');
4851             }
4852 #endif /* WIN32 */
4853
4854 #ifdef VMS
4855           /* Change this 1/2 Unix 1/2 VMS file specification into a
4856              full VMS file specification */
4857           if (searchptr->fname && (searchptr->fname[0] != 0)) {
4858             /* Fix up the filename */
4859             hack_vms_include_specification (fname);
4860           } else {
4861             /* This is a normal VMS filespec, so use it unchanged.  */
4862             strncpy (fname, fbeg, flen);
4863             fname[flen] = 0;
4864             /* if it's '#include filename', add the missing .h */
4865             if (strchr (fname,'.') == NULL) {
4866               strcat (fname, ".h");
4867             }
4868           }
4869 #endif /* VMS */
4870           /* ??? There are currently 3 separate mechanisms for avoiding processing
4871              of redundant include files: #import, #pragma once, and
4872              redundant_include_p.  It would be nice if they were unified.  */
4873           
4874           if (redundant_include_p (pfile, fname))
4875             {
4876               cstring_free (fname);
4877               return 0;
4878             }
4879
4880           DPRINTF (("Trying: %s", fname));
4881
4882           f = open_include_file (pfile, fname, searchptr);
4883           
4884           if (f == IMPORT_FOUND)
4885             {
4886               return 0; /* Already included this file */
4887             }
4888 #ifdef EACCES
4889           else if (f == IMPORT_NOT_FOUND && errno == EACCES)
4890             {
4891               cppReader_warning (pfile,
4892                                  message ("Header file %s exists, but is not readable", fname));
4893             }
4894 #endif
4895           
4896           if (f >= 0)
4897             {
4898               break;
4899             }
4900         }
4901     }
4902   
4903   if (f < 0)
4904     {
4905       /* A file that was not found.  */
4906       fname = cstring_copyLength (fbeg, flen);
4907
4908       if (search_start != NULL)
4909         {
4910           cppReader_error (pfile,
4911                            message ("Cannot find include file %s on search path: %x", 
4912                                     fname,
4913                                     searchPath_unparse (search_start)));
4914         }
4915       else
4916         {
4917           cppReader_error (pfile,
4918                            message ("No include path in which to find %s", fname));
4919         }
4920     }
4921   else {
4922     /*
4923     ** Check to see if this include file is a once-only include file.
4924     ** If so, give up.
4925     */
4926
4927     struct file_name_list *ptr;
4928
4929     for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
4930       {
4931         if (cstring_equal (ptr->fname, fname))
4932           {
4933             /* This file was included before.  */
4934             break;
4935           }
4936       }
4937
4938     if (ptr == NULL)
4939       {
4940         /* This is the first time for this file.  */
4941         /* Add it to list of files included.  */
4942
4943         ptr = (struct file_name_list *) dmalloc (sizeof (*ptr));
4944         ptr->control_macro = NULL;
4945         ptr->c_system_include_path = NULL;
4946         ptr->next = pfile->all_include_files;
4947         ptr->fname = fname;
4948         ptr->got_name_map = NULL;
4949
4950         DPRINTF (("Including file: %s", fname));
4951         pfile->all_include_files = ptr;
4952         assertSet (pfile->all_include_files);
4953       }
4954
4955     if (angle_brackets != 0)
4956       {
4957         pfile->system_include_depth++;
4958       }
4959
4960     /* Actually process the file */
4961     if (cppReader_pushBuffer (pfile, NULL, 0) == NULL)
4962       {
4963         cstring_free (fname);
4964         return 0;
4965       }
4966
4967     if (finclude (pfile, f, fname, is_system_include (pfile, fname),
4968                   searchptr != dsp ? searchptr : SELF_DIR_DUMMY))
4969       {
4970         output_line_command (pfile, 0, enter_file);
4971         pfile->only_seen_white = 2;
4972       }
4973
4974     if (angle_brackets)
4975       {
4976         pfile->system_include_depth--;
4977       }
4978     /*@-branchstate@*/
4979   } /*@=branchstate@*/ 
4980
4981   return 0;
4982 }
4983
4984 /* Return nonzero if there is no need to include file NAME
4985    because it has already been included and it contains a conditional
4986    to make a repeated include do nothing.  */
4987
4988 static bool
4989 redundant_include_p (cppReader *pfile, cstring name)
4990 {
4991   struct file_name_list *l = pfile->all_include_files;
4992
4993   for (; l != NULL; l = l->next)
4994     {
4995       if (cstring_equal (name, l->fname)
4996           && (l->control_macro != NULL)
4997           && (cpphash_lookup (l->control_macro, -1, -1) != NULL))
4998         {
4999           return TRUE;
5000         }
5001     }
5002
5003   return FALSE;
5004 }
5005
5006 /* Return nonzero if the given FILENAME is an absolute pathname which
5007    designates a file within one of the known "system" include file
5008    directories.  We assume here that if the given FILENAME looks like
5009    it is the name of a file which resides either directly in a "system"
5010    include file directory, or within any subdirectory thereof, then the
5011    given file must be a "system" include file.  This function tells us
5012    if we should suppress pedantic errors/warnings for the given FILENAME.
5013
5014    The value is 2 if the file is a C-language system header file
5015    for which C++ should (on most systems) assume `extern "C"'.  */
5016
5017 static bool
5018 is_system_include (cppReader *pfile, cstring filename)
5019 {
5020   struct file_name_list *searchptr;
5021
5022   for (searchptr = CPPOPTIONS (pfile)->first_system_include;
5023        searchptr != NULL;
5024        searchptr = searchptr->next)
5025     {
5026       if (!cstring_isEmpty (searchptr->fname)) 
5027         {
5028           cstring sys_dir = searchptr->fname;
5029           size_t length = cstring_length (sys_dir);
5030           
5031           if (cstring_equalLen (sys_dir, filename, length)
5032               && osd_isConnectChar (cstring_getChar (filename, length)))
5033             {
5034               if (searchptr->c_system_include_path)
5035                 return 2;
5036               else
5037                 return 1;
5038             }
5039         }
5040     }
5041   
5042   return 0;
5043 }
5044
5045 /* Convert a character string literal into a nul-terminated string.
5046    The input string is [IN ... LIMIT).
5047    The result is placed in RESULT.  RESULT can be the same as IN.
5048    The value returned in the end of the string written to RESULT,
5049    or NULL on error.  */
5050
5051 static /*@null@*/ char *
5052 convert_string (cppReader *pfile, /*@returned@*/ char *result,
5053                 char *in, char *limit, int handle_escapes)
5054 {
5055   char c;
5056   c = *in++;
5057
5058   if (c != '\"')
5059     {
5060       return NULL;
5061     }
5062
5063   while (in < limit)
5064     {
5065       c = *in++;
5066
5067       switch (c)
5068         {
5069         case '\0':
5070           return NULL;
5071         case '\"':
5072           limit = in;
5073           /*@switchbreak@*/ break;
5074         case '\\':
5075           if (handle_escapes)
5076             {
5077               char *bpc = (char *) in;
5078               int i = (char) cppReader_parseEscape (pfile, &bpc);
5079               in = (char *) bpc;
5080               if (i >= 0)
5081                 *result++ = (char) c;
5082               /*@switchbreak@*/ break;
5083             }
5084
5085           /*@fallthrough@*/
5086         default:
5087           *result++ = c;
5088         }
5089     }
5090
5091   *result = 0;
5092   return result;
5093 }
5094
5095 /*
5096  * interpret #line command.  Remembers previously seen fnames
5097  * in its very own hash table.
5098  */
5099
5100 /*@constant int FNAME_HASHSIZE@*/
5101 #define FNAME_HASHSIZE 37
5102
5103 static int
5104 do_line (cppReader *pfile, /*@unused@*/ struct directive *keyword)
5105 {
5106   cppBuffer *ip = cppReader_getBuffer (pfile);
5107   int new_lineno;
5108   size_t old_written = cpplib_getWritten (pfile);
5109   enum file_change_code file_change = same_file;
5110   enum cpp_token token;
5111
5112   llassert (ip != NULL);
5113   token = get_directive_token (pfile);
5114
5115   if (token != CPP_NUMBER
5116       || !isdigit(pfile->token_buffer[old_written]))
5117     {
5118       cppReader_errorLit (pfile,
5119                     cstring_makeLiteralTemp ("invalid format `#line' command"));
5120
5121       goto bad_line_directive;
5122     }
5123
5124   /* The Newline at the end of this line remains to be processed.
5125      To put the next line at the specified line number,
5126      we must store a line number now that is one less.  */
5127   new_lineno = atoi (pfile->token_buffer + old_written) - 1;
5128   cppReader_setWritten (pfile, old_written);
5129
5130   /* NEW_LINENO is one less than the actual line number here.  */
5131   if (cppReader_isPedantic (pfile) && new_lineno < 0)
5132     cppReader_pedwarnLit (pfile,
5133                     cstring_makeLiteralTemp ("line number out of range in `#line' command"));
5134
5135   token = get_directive_token (pfile);
5136
5137   if (token == CPP_STRING) {
5138     char *fname = pfile->token_buffer + old_written;
5139     char *end_name;
5140     static hashNode fname_table[FNAME_HASHSIZE];
5141     hashNode hp; 
5142     hashNode *hash_bucket;
5143     char *p;
5144     size_t num_start;
5145     size_t fname_length;
5146
5147     /* Turn the file name, which is a character string literal,
5148        into a null-terminated string.  Do this in place.  */
5149     end_name = convert_string (pfile, fname, fname, cpplib_getPWritten (pfile), 1);
5150     if (end_name == NULL)
5151       {
5152         cppReader_errorLit (pfile,
5153                       cstring_makeLiteralTemp ("invalid format `#line' command"));
5154         goto bad_line_directive;
5155       }
5156
5157     fname_length = size_fromInt (end_name - fname);
5158     num_start = cpplib_getWritten (pfile);
5159
5160     token = get_directive_token (pfile);
5161     if (token != CPP_VSPACE && token != CPP_EOF && token != CPP_POP) {
5162       p = pfile->token_buffer + num_start;
5163       if (cppReader_isPedantic (pfile))
5164         cppReader_pedwarnLit (pfile,
5165                         cstring_makeLiteralTemp ("garbage at end of `#line' command"));
5166
5167       if (token != CPP_NUMBER || *p < '0' || *p > '4' || p[1] != '\0')
5168         {
5169           cppReader_errorLit (pfile,
5170                         cstring_makeLiteralTemp ("invalid format `#line' command"));
5171           goto bad_line_directive;
5172         }
5173       if (*p == '1')
5174         file_change = enter_file;
5175       else if (*p == 2)
5176         file_change = leave_file;
5177       else if (*p == 3)
5178         ip->system_header_p = 1;
5179       else /* if (*p == 4) */
5180         ip->system_header_p = 2;
5181
5182       cppReader_setWritten (pfile, num_start);
5183       token = get_directive_token (pfile);
5184       p = pfile->token_buffer + num_start;
5185       if (token == CPP_NUMBER && p[1] == '\0' && (*p == '3' || *p== '4')) {
5186         ip->system_header_p = *p == 3 ? 1 : 2;
5187         token = get_directive_token (pfile);
5188       }
5189       if (token != CPP_VSPACE) {
5190         cppReader_errorLit (pfile,
5191                       cstring_makeLiteralTemp ("invalid format `#line' command"));
5192
5193         goto bad_line_directive;
5194       }
5195     }
5196
5197     hash_bucket =
5198       &fname_table[cpphash_hashCode (fname, fname_length, FNAME_HASHSIZE)];
5199
5200     for (hp = *hash_bucket; hp != NULL; hp = hp->next)
5201       {
5202         if (hp->length == fname_length)
5203           {
5204             llassert (hp->value.cpval != NULL);
5205             
5206             if (strncmp (hp->value.cpval, fname, fname_length) == 0) 
5207               {
5208                 ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5209                 break;
5210               }
5211           }
5212       }
5213     
5214     if (hp == 0) {
5215       /* Didn't find it; cons up a new one.  */
5216       hp = (hashNode) dmalloc (sizeof (*hp));
5217
5218       hp->prev = NULL;
5219       hp->bucket_hdr = NULL;
5220       hp->type = T_NONE;
5221       hp->name = cstring_undefined;
5222       hp->next = *hash_bucket;
5223
5224       *hash_bucket = hp;
5225
5226       hp->length = fname_length;
5227       hp->value.cpval = dmalloc (sizeof (*hp->value.cpval) * (fname_length + 1));
5228       memcpy (hp->value.cpval, fname, fname_length);
5229       hp->value.cpval[fname_length] = '\0';
5230       ip->nominal_fname = cstring_fromChars (hp->value.cpval);
5231     }
5232   }
5233   else if (token != CPP_VSPACE && token != CPP_EOF)
5234     {
5235       cppReader_errorLit (pfile,
5236                     cstring_makeLiteralTemp ("invalid format `#line' command"));
5237       goto bad_line_directive;
5238     }
5239   else
5240     {
5241       ;
5242     }
5243
5244   ip->lineno = new_lineno;
5245 bad_line_directive:
5246   cppReader_skipRestOfLine (pfile);
5247   cppReader_setWritten (pfile, old_written);
5248   output_line_command (pfile, 0, file_change);
5249   return 0;
5250 }
5251
5252 /*
5253  * remove the definition of a symbol from the symbol table.
5254  * according to un*x /lib/cpp, it is not an error to undef
5255  * something that has no definitions, so it isn't one here either.
5256  */
5257
5258 static int
5259 do_undef (cppReader *pfile, struct directive *keyword, char *buf, char *limit)
5260 {
5261
5262   size_t sym_length;
5263   hashNode hp;
5264   char *orig_buf = buf;
5265
5266   SKIP_WHITE_SPACE (buf);
5267
5268   sym_length = cppReader_checkMacroName (pfile, buf, cstring_makeLiteralTemp ("macro"));
5269
5270   while ((hp = cpphash_lookup (buf, size_toInt (sym_length), -1)) != NULL)
5271     {
5272       /* If we are generating additional info for debugging (with -g) we
5273          need to pass through all effective #undef commands.  */
5274       if (CPPOPTIONS (pfile)->debug_output && (keyword != NULL))
5275         {
5276           pass_thru_directive (orig_buf, limit, pfile, keyword);
5277         }
5278
5279       if (hp->type != T_MACRO)
5280         {
5281           cppReader_warning (pfile,
5282                        message ("Undefining preprocessor builtin: %s",
5283                                 hp->name));
5284         }
5285
5286       cppReader_deleteMacro (hp);
5287     }
5288
5289   if (cppReader_isPedantic (pfile)) {
5290     buf += sym_length;
5291     SKIP_WHITE_SPACE (buf);
5292     if (buf != limit)
5293       {
5294         cppReader_pedwarnLit (pfile,
5295                         cstring_makeLiteralTemp ("garbage after `#undef' directive"));
5296       }
5297   }
5298
5299   return 0;
5300 }
5301
5302
5303 /*
5304  * Report an error detected by the program we are processing.
5305  * Use the text of the line in the error message.
5306  * (We use error because it prints the filename & line#.)
5307  */
5308
5309 static int
5310 do_error (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5311           char *buf, char *limit)
5312 {
5313   size_t length = size_fromInt (limit - buf);
5314   cstring copy = cstring_copyLength (buf, length);
5315   cstring adv = cstring_advanceWhiteSpace (copy);
5316
5317   cppReader_error (pfile, message ("#error %s", adv));
5318   cstring_free (copy);
5319   return 0;
5320 }
5321
5322 /*
5323  * Report a warning detected by the program we are processing.
5324  * Use the text of the line in the warning message, then continue.
5325  * (We use error because it prints the filename & line#.)
5326  */
5327
5328 static int
5329 do_warning (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5330             char *buf, char *limit)
5331 {
5332   size_t length = size_fromInt (limit - buf);
5333   cstring copy = cstring_copyLength (buf, length);
5334   cstring adv = cstring_advanceWhiteSpace (copy);
5335   cppReader_warning (pfile, message ("#warning %s", adv));
5336   cstring_free (copy);
5337   return 0;
5338 }
5339
5340
5341 /* #ident has already been copied to the output file, so just ignore it.  */
5342
5343 static int
5344 do_ident (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5345           /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5346 {
5347   /* Allow #ident in system headers, since that's not user's fault.  */
5348   if (cppReader_isPedantic (pfile) 
5349       && !cppReader_getBufferSafe (pfile)->system_header_p)
5350     cppReader_pedwarnLit (pfile,
5351                     cstring_makeLiteralTemp ("ANSI C does not allow `#ident'"));
5352
5353   /* Leave rest of line to be read by later calls to cpplib_getToken.  */
5354
5355   return 0;
5356 }
5357
5358 /* #pragma and its argument line have already been copied to the output file.
5359    Just check for some recognized pragmas that need validation here.  */
5360
5361 static int
5362 do_pragma (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5363            /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5364 {
5365   while (*buf == ' ' || *buf == '\t')
5366     {
5367       buf++;
5368     }
5369
5370   if (!strncmp (buf, "implementation", 14)) {
5371     /* Be quiet about `#pragma implementation' for a file only if it hasn't
5372        been included yet.  */
5373     struct file_name_list *ptr;
5374     char *p = buf + 14, *fname, *inc_fname;
5375     size_t fname_len;
5376     SKIP_WHITE_SPACE (p);
5377     if (*p == '\n' || *p != '\"')
5378       return 0;
5379
5380     fname = p + 1;
5381     p = (char *) strchr (fname, '\"');
5382     fname_len = p != NULL ? size_fromInt (p - fname) : mstring_length (fname);
5383
5384     for (ptr = pfile->all_include_files; ptr != NULL; ptr = ptr->next)
5385       {
5386         inc_fname = (char *) strrchr (cstring_toCharsSafe (ptr->fname), CONNECTCHAR);
5387         inc_fname = (inc_fname != NULL)
5388           ? inc_fname + 1 : cstring_toCharsSafe (ptr->fname);
5389
5390         if ((inc_fname != NULL)
5391             && (strncmp (inc_fname, fname, fname_len) == 0))
5392           {
5393             cpp_setLocation (pfile);
5394
5395             ppllerror (message ("`#pragma implementation' for `%s' appears "
5396                                 "after file is included",
5397                                 cstring_fromChars (fname)));
5398           }
5399       }
5400   }
5401
5402   return 0;
5403 }
5404
5405 /*
5406  * handle #if command by
5407  *   1) inserting special `defined' keyword into the hash table
5408  *      that gets turned into 0 or 1 by special_symbol (thus,
5409  *      if the luser has a symbol called `defined' already, it won't
5410  *      work inside the #if command)
5411  *   2) rescan the input into a temporary output buffer
5412  *   3) pass the output buffer to the yacc parser and collect a value
5413  *   4) clean up the mess left from steps 1 and 2.
5414  *   5) call conditional_skip to skip til the next #endif (etc.),
5415  *      or not, depending on the value from step 3.
5416  */
5417
5418 static int
5419 do_if (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5420        char *buf, char *limit)
5421 {
5422   HOST_WIDE_INT value;
5423   DPRINTF (("Do if: %s", buf));
5424   value = eval_if_expression (pfile, buf, limit - buf);
5425   conditional_skip (pfile, value == 0, T_IF, NULL);
5426   return 0;
5427 }
5428
5429 /*
5430  * handle a #elif directive by not changing  if_stack  either.
5431  * see the comment above do_else.
5432  */
5433
5434 static int do_elif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5435                     char *buf, char *limit)
5436 {
5437   if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5438     {
5439       cppReader_errorLit (pfile,
5440                     cstring_makeLiteralTemp ("Preprocessor command #elif is not within a conditional"));
5441       return 0;
5442     }
5443   else
5444     {
5445       llassert (pfile->if_stack != NULL);
5446
5447       if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5448         {
5449           cppReader_errorLit (pfile,
5450                         cstring_makeLiteralTemp ("`#elif' after `#else'"));
5451
5452           if (pfile->if_stack->fname != NULL
5453               && cppReader_getBufferSafe (pfile)->fname != NULL
5454               && !cstring_equal (pfile->if_stack->fname,
5455                                  cppReader_getBufferSafe (pfile)->nominal_fname))
5456             fprintf (stderr, ", file %s", cstring_toCharsSafe (pfile->if_stack->fname));
5457           fprintf (stderr, ")\n");
5458         }
5459       pfile->if_stack->type = T_ELIF;
5460     }
5461
5462   if (pfile->if_stack->if_succeeded)
5463     {
5464       skip_if_group (pfile, 0);
5465     }
5466   else
5467     {
5468       HOST_WIDE_INT value = eval_if_expression (pfile, buf, limit - buf);
5469       if (value == 0)
5470         skip_if_group (pfile, 0);
5471       else
5472         {
5473           ++pfile->if_stack->if_succeeded;      /* continue processing input */
5474           output_line_command (pfile, 1, same_file);
5475         }
5476     }
5477
5478   return 0;
5479 }
5480
5481 /*
5482  * evaluate a #if expression in BUF, of length LENGTH,
5483  * then parse the result as a C expression and return the value as an int.
5484  */
5485
5486 static HOST_WIDE_INT
5487 eval_if_expression (cppReader *pfile,
5488                     /*@unused@*/ char *buf,
5489                     /*@unused@*/ int length)
5490 {
5491   hashNode save_defined;
5492   HOST_WIDE_INT value;
5493   size_t old_written = cpplib_getWritten (pfile);
5494
5495   DPRINTF (("Saving defined..."));
5496   save_defined = cpphash_install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
5497   pfile->pcp_inside_if = 1;
5498
5499   value = cppReader_parseExpression (pfile);
5500   pfile->pcp_inside_if = 0;
5501
5502   /* Clean up special symbol */
5503   DPRINTF (("Removing defined..."));
5504   cppReader_deleteMacro (save_defined);
5505   cppReader_setWritten (pfile, old_written); /* Pop */
5506
5507   return value;
5508 }
5509
5510 /*
5511  * routine to handle ifdef/ifndef.  Try to look up the symbol,
5512  * then do or don't skip to the #endif/#else/#elif depending
5513  * on what directive is actually being processed.
5514  */
5515
5516 static int
5517 do_xifdef (cppReader *pfile, struct directive *keyword,
5518            /*@unused@*/ char *unused1, /*@unused@*/ char *unused2)
5519 {
5520   int skip;
5521   cppBuffer *ip = cppReader_getBufferSafe (pfile);
5522   char *ident;
5523   size_t ident_length;
5524   enum cpp_token token;
5525   int start_of_file = 0;
5526   char *control_macro = 0;
5527   size_t old_written = cpplib_getWritten (pfile);
5528
5529   DPRINTF (("do xifdef: %d",
5530             keyword->type == T_IFNDEF));
5531
5532   /* Detect a #ifndef at start of file (not counting comments).  */
5533   if (cstring_isDefined (ip->fname) && keyword->type == T_IFNDEF)
5534     {
5535       start_of_file = pfile->only_seen_white == 2;
5536     }
5537
5538   pfile->no_macro_expand++;
5539   token = get_directive_token (pfile);
5540   pfile->no_macro_expand--;
5541
5542   ident = pfile->token_buffer + old_written;
5543   DPRINTF (("Ident: %s", ident));
5544
5545   ident_length = cpplib_getWritten (pfile) - old_written;
5546   cppReader_setWritten (pfile, old_written); /* Pop */
5547
5548   if (token == CPP_VSPACE || token == CPP_POP || token == CPP_EOF)
5549     {
5550       skip = (keyword->type == T_IFDEF);
5551       if (! cppReader_isTraditional (pfile))
5552         {
5553           cppReader_pedwarn (pfile,
5554                              message ("`#%s' with no argument", keyword->name));
5555         }
5556     }
5557   else if (token == CPP_NAME)
5558     {
5559       hashNode hp = cpphash_lookup (ident, size_toInt (ident_length), -1);
5560
5561       skip = (keyword->type == T_IFDEF) ? (hp == NULL) : (hp != NULL);
5562       
5563       DPRINTF (("hp null: %d / %d / %d", hp == NULL, keyword->type == T_IFNDEF, skip));
5564       
5565       if (start_of_file && !skip)
5566         {
5567           DPRINTF (("Not skipping!"));
5568           control_macro = (char *) dmalloc (ident_length + 1);
5569           memcpy (control_macro, ident, ident_length + 1);
5570         }
5571     }
5572   else
5573     {
5574       skip = (keyword->type == T_IFDEF);
5575       if (! cppReader_isTraditional (pfile))
5576         {
5577           cppReader_error (pfile,
5578                      message ("`#%s' with invalid argument", keyword->name));
5579         }
5580     }
5581
5582   if (!cppReader_isTraditional (pfile))
5583     {
5584       int c;
5585       cppSkipHspace (pfile);
5586       c = cppReader_peekC (pfile);
5587       if (c != EOF && c != '\n')
5588         {
5589           cppReader_pedwarn (pfile,
5590                              message ("garbage at end of `#%s' argument", keyword->name));
5591         }
5592     }
5593
5594   cppReader_skipRestOfLine (pfile);
5595
5596   DPRINTF (("Conditional skip: %d", skip));
5597   conditional_skip (pfile, skip, T_IF, control_macro);
5598   return 0;
5599 }
5600
5601 /* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
5602    If this is a #ifndef starting at the beginning of a file,
5603    CONTROL_MACRO is the macro name tested by the #ifndef.
5604    Otherwise, CONTROL_MACRO is 0.  */
5605
5606 static void
5607 conditional_skip (cppReader *pfile, int skip,
5608                   enum node_type type,
5609                   /*@dependent@*/ char *control_macro)
5610 {
5611   cppIfStackFrame *temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5612
5613   temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
5614   temp->next = pfile->if_stack;
5615   temp->control_macro = control_macro;
5616   temp->lineno = 0;
5617   temp->if_succeeded = 0;
5618
5619   pfile->if_stack = temp;
5620   pfile->if_stack->type = type;
5621
5622   if (skip != 0)
5623     {
5624       skip_if_group (pfile, 0);
5625       return;
5626     }
5627   else
5628     {
5629       ++pfile->if_stack->if_succeeded;
5630       output_line_command (pfile, 1, same_file);
5631     }
5632 }
5633
5634 /*
5635  * skip to #endif, #else, or #elif.  adjust line numbers, etc.
5636  * leaves input ptr at the sharp sign found.
5637  * If ANY is nonzero, return at next directive of any sort.
5638  */
5639
5640 static void
5641 skip_if_group (cppReader *pfile, int any)
5642 {
5643   int c;
5644   struct directive *kt;
5645   cppIfStackFrame *save_if_stack = pfile->if_stack; /* don't pop past here */
5646   register int ident_length;
5647   char *ident;
5648   struct parse_marker line_start_mark;
5649
5650   parseSetMark (&line_start_mark, pfile);
5651
5652   if (CPPOPTIONS (pfile)->output_conditionals) {
5653     static char failed[] = "#failed\n";
5654     cppReader_puts (pfile, failed, sizeof(failed)-1);
5655     pfile->lineno++;
5656     output_line_command (pfile, 1, same_file);
5657   }
5658
5659 beg_of_line:
5660   if (CPPOPTIONS (pfile)->output_conditionals)
5661     {
5662       cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
5663       char *start_line;
5664
5665       llassert (pbuf->buf != NULL);
5666
5667       start_line = pbuf->buf + line_start_mark.position;
5668       cppReader_puts (pfile, start_line, size_fromInt (pbuf->cur - start_line));
5669     }
5670
5671   parseMoveMark (&line_start_mark, pfile);
5672
5673   if (!cppReader_isTraditional (pfile))
5674     {
5675       cppSkipHspace (pfile);
5676     }
5677
5678   c  = cppReader_getC (pfile);
5679   if (c == '#')
5680     {
5681       size_t old_written = cpplib_getWritten (pfile);
5682       cppSkipHspace (pfile);
5683
5684       parse_name (pfile, cppReader_getC (pfile));
5685       ident_length = size_toInt (cpplib_getWritten (pfile) - old_written);
5686       ident = pfile->token_buffer + old_written;
5687       pfile->limit = ident;
5688
5689       for (kt = directive_table; kt->length >= 0; kt++)
5690         {
5691           cppIfStackFrame *temp;
5692           if (ident_length == kt->length
5693               && cstring_equalPrefix (kt->name, cstring_fromChars (ident)))
5694             {
5695               /* If we are asked to return on next directive, do so now.  */
5696               if (any)
5697                 {
5698                   goto done;
5699                 }
5700
5701               switch (kt->type)
5702                 {
5703                 case T_IF:
5704                 case T_IFDEF:
5705                 case T_IFNDEF:
5706                   temp = (cppIfStackFrame *) dmalloc (sizeof (*temp));
5707                   temp->next = pfile->if_stack;
5708                   temp->fname = cppReader_getBufferSafe (pfile)->nominal_fname;
5709                   temp->type = kt->type;
5710                   temp->lineno = 0;
5711                   temp->if_succeeded = 0;
5712                   temp->control_macro = NULL;
5713
5714                   pfile->if_stack = temp;
5715                   /*@switchbreak@*/ break;
5716                 case T_ELSE:
5717                 case T_ENDIF:
5718                   if (cppReader_isPedantic (pfile) && pfile->if_stack != save_if_stack)
5719                     validate_else (pfile,
5720                                    cstring_makeLiteralTemp (kt->type == T_ELSE ? "#else" : "#endif"));
5721                   /*@fallthrough@*/
5722                 case T_ELIF:
5723                   if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5724                     {
5725                       cppReader_error (pfile,
5726                                  message ("Preprocessor command #%s is not within a conditional", kt->name));
5727                       /*@switchbreak@*/ break;
5728                     }
5729                   else if (pfile->if_stack == save_if_stack)
5730                     {
5731                       goto done;                /* found what we came for */
5732                     }
5733                   else
5734                     {
5735                       ;
5736                     }
5737
5738                   if (kt->type != T_ENDIF)
5739                     {
5740                       llassert (pfile->if_stack != NULL);
5741
5742                       if (pfile->if_stack->type == T_ELSE)
5743                         {
5744                           cppReader_errorLit (pfile,
5745                                         cstring_makeLiteralTemp ("`#else' or `#elif' after `#else'"));
5746                         }
5747
5748                       pfile->if_stack->type = kt->type;
5749                       /*@switchbreak@*/ break;
5750                     }
5751
5752                   temp = pfile->if_stack;
5753                   llassert (temp != NULL);
5754                   pfile->if_stack = temp->next;
5755                   sfree (temp);
5756                   /*@switchbreak@*/ break;
5757                 default: ;
5758                   /*@-branchstate@*/ 
5759 #if defined (OS2) && defined (__IBMC__)
5760       /* Dummy code to eleminate optimization problems with icc */
5761       c = 0;
5762 # endif
5763
5764                 }
5765               /*@=branchstate@*/
5766               break;
5767             }
5768           
5769           /* Don't let erroneous code go by.  */
5770           
5771           if (kt->length < 0 && !CPPOPTIONS (pfile)->lang_asm
5772               && cppReader_isPedantic (pfile))
5773             {
5774               cppReader_pedwarnLit (pfile,
5775                                     cstring_makeLiteralTemp ("Invalid preprocessor directive name"));
5776             }
5777         }
5778
5779       c = cppReader_getC (pfile);
5780     }
5781   /* We're in the middle of a line.  Skip the rest of it.  */
5782   for (;;) {
5783     size_t old;
5784
5785     switch (c)
5786       {
5787       case EOF:
5788         goto done;
5789       case '/':                 /* possible comment */
5790         c = skip_comment (pfile, NULL);
5791         if (c == EOF)
5792           goto done;
5793         /*@switchbreak@*/ break;
5794       case '\"':
5795       case '\'':
5796         cppReader_forward (pfile, -1);
5797         old = cpplib_getWritten (pfile);
5798         (void) cpplib_getToken (pfile);
5799         cppReader_setWritten (pfile, old);
5800         /*@switchbreak@*/ break;
5801       case '\\':
5802         /* Char after backslash loses its special meaning.  */
5803         if (cppReader_peekC (pfile) == '\n')
5804           {
5805             cppReader_forward (pfile, 1);
5806           }
5807
5808         /*@switchbreak@*/ break;
5809       case '\n':
5810         goto beg_of_line;
5811       }
5812     c = cppReader_getC (pfile);
5813   }
5814 done:
5815   if (CPPOPTIONS (pfile)->output_conditionals) {
5816     static char end_failed[] = "#endfailed\n";
5817     cppReader_puts (pfile, end_failed, sizeof(end_failed)-1);
5818     pfile->lineno++;
5819   }
5820   pfile->only_seen_white = 1;
5821
5822   parseGotoMark (&line_start_mark, pfile);
5823   parseClearMark (&line_start_mark);
5824 }
5825
5826 /*
5827  * handle a #else directive.  Do this by just continuing processing
5828  * without changing  if_stack ;  this is so that the error message
5829  * for missing #endif's etc. will point to the original #if.  It
5830  * is possible that something different would be better.
5831  */
5832
5833 static int
5834 do_else (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5835         /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5836 {
5837   if (cppReader_isPedantic (pfile))
5838     {
5839       validate_else (pfile, cstring_makeLiteralTemp ("#else"));
5840     }
5841
5842   cppReader_skipRestOfLine (pfile);
5843
5844   if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack) {
5845     cppReader_errorLit (pfile,
5846                   cstring_makeLiteralTemp ("Preprocessor command #else is not within a conditional"));
5847     return 0;
5848   } else {
5849     /* #ifndef can't have its special treatment for containing the whole file
5850        if it has a #else clause.  */
5851
5852     llassert (pfile->if_stack != NULL);
5853
5854     pfile->if_stack->control_macro = 0;
5855
5856     if (pfile->if_stack->type != T_IF && pfile->if_stack->type != T_ELIF)
5857       {
5858         cpp_setLocation (pfile);
5859         genppllerrorhint (FLG_PREPROC,
5860                           message ("Pre-processor directive #else after #else"),
5861                           message ("%q: Location of match",
5862                                    fileloc_unparseRaw (pfile->if_stack->fname,
5863                                                        pfile->if_stack->lineno)));
5864       }
5865
5866     pfile->if_stack->type = T_ELSE;
5867   }
5868
5869   if (pfile->if_stack->if_succeeded)
5870     skip_if_group (pfile, 0);
5871   else {
5872     ++pfile->if_stack->if_succeeded;    /* continue processing input */
5873     output_line_command (pfile, 1, same_file);
5874   }
5875
5876   return 0;
5877 }
5878
5879 /*
5880  * unstack after #endif command
5881  */
5882
5883 static int
5884 do_endif (cppReader *pfile, /*@unused@*/ struct directive *keyword,
5885           /*@unused@*/ char *buf, /*@unused@*/ char *limit)
5886 {
5887   if (cppReader_isPedantic (pfile))
5888     {
5889       validate_else (pfile, cstring_makeLiteralTemp ("#endif"));
5890     }
5891
5892   cppReader_skipRestOfLine (pfile);
5893
5894   if (pfile->if_stack == cppReader_getBufferSafe (pfile)->if_stack)
5895     {
5896       cppReader_errorLit (pfile, cstring_makeLiteralTemp ("Unbalanced #endif"));
5897     }
5898   else
5899     {
5900       cppIfStackFrame *temp = pfile->if_stack;
5901
5902       llassert (temp != NULL);
5903
5904       pfile->if_stack = temp->next;
5905       if (temp->control_macro != 0)
5906         {
5907           /* This #endif matched a #ifndef at the start of the file.
5908              See if it is at the end of the file.  */
5909           struct parse_marker start_mark;
5910           int c;
5911
5912           parseSetMark (&start_mark, pfile);
5913
5914           for (;;)
5915             {
5916               cppSkipHspace (pfile);
5917               c = cppReader_getC (pfile);
5918
5919               if (c != '\n')
5920                 break;
5921             }
5922
5923           parseGotoMark (&start_mark, pfile);
5924           parseClearMark (&start_mark);
5925
5926           if (c == EOF)
5927             {
5928               /* If we get here, this #endif ends a #ifndef
5929                  that contains all of the file (aside from whitespace).
5930                  Arrange not to include the file again
5931                  if the macro that was tested is defined.
5932
5933                  Do not do this for the top-level file in a -include or any
5934                  file in a -imacros.  */
5935               struct file_name_list *ifile = pfile->all_include_files;
5936
5937               for ( ; ifile != NULL; ifile = ifile->next)
5938                 {
5939                   if (cstring_equal (ifile->fname, cppReader_getBufferSafe (pfile)->fname))
5940                     {
5941                       ifile->control_macro = temp->control_macro;
5942                       break;
5943                     }
5944                 }
5945             }
5946         }
5947
5948       sfree (temp);
5949       output_line_command (pfile, 1, same_file);
5950     }
5951   return 0;
5952 }
5953
5954 /* When an #else or #endif is found while skipping failed conditional,
5955    if -pedantic was specified, this is called to warn about text after
5956    the command name.  P points to the first char after the command name.  */
5957
5958 static void
5959 validate_else (cppReader *pfile, cstring directive)
5960 {
5961   int c;
5962   cppSkipHspace (pfile);
5963   c = cppReader_peekC (pfile);
5964   if (c != EOF && c != '\n')
5965     {
5966       cppReader_pedwarn (pfile,
5967                    message ("text following `%s' violates ANSI standard", directive));
5968     }
5969 }
5970
5971 /*
5972 ** Get the next token, and add it to the text in pfile->token_buffer.
5973 ** Return the kind of token we got.
5974 */
5975
5976 enum cpp_token
5977 cpplib_getToken (cppReader *pfile)
5978 {
5979   return cpplib_getTokenAux (pfile, FALSE);
5980 }
5981
5982 enum cpp_token
5983 cpplib_getTokenForceExpand (cppReader *pfile)
5984 {
5985   return cpplib_getTokenAux (pfile, TRUE);
5986 }
5987
5988 enum cpp_token
5989 cpplib_getTokenAux (cppReader *pfile, bool forceExpand)
5990 {
5991   int c, c2, c3;
5992   size_t old_written = 0;
5993   int start_line, start_column;
5994   enum cpp_token token;
5995   struct cppOptions *opts = CPPOPTIONS (pfile);
5996   cppReader_getBufferSafe (pfile)->prev = cppReader_getBufferSafe (pfile)->cur;
5997
5998 get_next:
5999   c = cppReader_getC (pfile);
6000   DPRINTF (("Get next token: %c", c));
6001
6002   if (c == EOF)
6003     {
6004     handle_eof:
6005       if (cppReader_getBufferSafe (pfile)->seen_eof)
6006         {
6007           cppBuffer *buf = cppReader_popBuffer (pfile);
6008
6009           if (buf != cppReader_nullBuffer (pfile))
6010             {
6011               goto get_next;
6012             }
6013           else
6014             {
6015               return CPP_EOF;
6016             }
6017         }
6018       else
6019         {
6020           cppBuffer *next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6021           cppReader_getBufferSafe (pfile)->seen_eof = 1;
6022
6023           if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname)
6024               && next_buf != cppReader_nullBuffer (pfile))
6025             {
6026               /* We're about to return from an #include file.
6027                  Emit #line information now (as part of the CPP_POP) result.
6028                  But the #line refers to the file we will pop to.  */
6029               cppBuffer *cur_buffer = CPPBUFFER (pfile);
6030               CPPBUFFER (pfile) = next_buf;
6031               pfile->input_stack_listing_current = 0;
6032               output_line_command (pfile, 0, leave_file);
6033               CPPBUFFER (pfile) = cur_buffer;
6034             }
6035           return CPP_POP;
6036         }
6037     }
6038   else
6039     {
6040       long newlines;
6041       struct parse_marker start_mark;
6042
6043       switch (c)
6044         {
6045         case '/':
6046           if (cppReader_peekC (pfile) == '=')
6047             {
6048               goto op2;
6049             }
6050
6051           if (opts->put_out_comments)
6052             {
6053               parseSetMark (&start_mark, pfile);
6054             }
6055
6056           newlines = 0;
6057           cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
6058                                    &start_line, &start_column);
6059           c = skip_comment (pfile, &newlines);
6060           DPRINTF (("c = %c", c));
6061           if (opts->put_out_comments && (c == '/' || c == EOF))
6062             {
6063               assertSet (&start_mark);
6064               parseClearMark (&start_mark);
6065             }
6066
6067           if (c == '/')
6068             goto randomchar;
6069           if (c == EOF)
6070             {
6071               cppReader_errorWithLine (pfile, start_line, start_column,
6072                                        cstring_makeLiteral ("Unterminated comment"));
6073               goto handle_eof;
6074             }
6075           c = '/';  /* Initial letter of comment.  */
6076         return_comment:
6077           /* Comments are equivalent to spaces.
6078              For -traditional, a comment is equivalent to nothing.  */
6079
6080           if (opts->put_out_comments)
6081             {
6082               enum cpp_token res;
6083
6084               assertSet (&start_mark);
6085               res = cpp_handleComment (pfile, &start_mark);
6086               pfile->lineno += newlines;
6087               return res;
6088             }
6089           else if (cppReader_isTraditional (pfile))
6090             {
6091               return CPP_COMMENT;
6092             }
6093           else
6094             {
6095               cpplib_reserve(pfile, 1);
6096               cppReader_putCharQ (pfile, ' ');
6097               return CPP_HSPACE;
6098             }
6099
6100         case '#':
6101           if (!pfile->only_seen_white)
6102             {
6103               goto randomchar;
6104             }
6105
6106           if (cppReader_handleDirective (pfile))
6107             {
6108               return CPP_DIRECTIVE;
6109             }
6110
6111           pfile->only_seen_white = 0;
6112           return CPP_OTHER;
6113
6114         case '\"':
6115         case '\'':
6116           /* A single quoted string is treated like a double -- some
6117              programs (e.g., troff) are perverse this way */
6118           cppBuffer_getLineAndColumn (cppReader_fileBuffer (pfile),
6119                                       &start_line, &start_column);
6120           old_written = cpplib_getWritten (pfile);
6121         string:
6122           DPRINTF (("Reading string: %c", c));
6123           cppReader_putChar (pfile, c);
6124           while (TRUE)
6125             {
6126               /* evans-2003-06-07
6127               ** Because of ISO8859-1 characters in string literals, we need a special test here.
6128               */
6129
6130               if (cppReader_reachedEOF (pfile)) 
6131                 {
6132                   
6133                   DPRINTF (("Matches EOF!"));
6134                   if (cppBuffer_isMacro (CPPBUFFER (pfile)))
6135                     {
6136                       /* try harder: this string crosses a macro expansion
6137                          boundary.  This can happen naturally if -traditional.
6138                          Otherwise, only -D can make a macro with an unmatched
6139                          quote.  */
6140                       cppBuffer *next_buf
6141                         = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6142                       (*cppReader_getBufferSafe (pfile)->cleanup)
6143                         (cppReader_getBufferSafe (pfile), pfile);
6144                       CPPBUFFER (pfile) = next_buf;
6145                       continue;
6146                     }
6147                   
6148                   if (!cppReader_isTraditional (pfile))
6149                     {
6150                       cpp_setLocation (pfile);
6151
6152                       setLine (long_toInt (start_line));
6153                       setColumn (long_toInt (start_column));
6154                       
6155                       if (pfile->multiline_string_line != long_toInt (start_line)
6156                           && pfile->multiline_string_line != 0)
6157                         {
6158                           genppllerrorhint
6159                             (FLG_PREPROC,
6160                              message ("Unterminated string or character constant"),
6161                              message ("%q: Possible real start of unterminated constant",
6162                                       fileloc_unparseRaw 
6163                                       (fileloc_filename (g_currentloc),
6164                                        pfile->multiline_string_line)));
6165                           pfile->multiline_string_line = 0;
6166                         }
6167                       else
6168                         {
6169                           genppllerror
6170                             (FLG_PREPROC,
6171                              message ("Unterminated string or character constant"));
6172                         }
6173                     }
6174                   /*@loopbreak@*/ break;                  
6175                 } 
6176               else
6177                 {
6178                   int cc = cppReader_getC (pfile); 
6179                   DPRINTF (("cc: %c [%d] [%d]", cc, cc, EOF));
6180                   DPRINTF (("putting char: %c", cc));
6181                   cppReader_putChar (pfile, cc);
6182                   switch (cc)
6183                     {
6184                     case '\n':
6185                       /* Traditionally, end of line ends a string constant with
6186                          no error.  So exit the loop and record the new line.  */
6187                       if (cppReader_isTraditional (pfile))
6188                         goto while2end;
6189                       if (c == '\'')
6190                         {
6191                           goto while2end;
6192                         }
6193                       if (cppReader_isPedantic (pfile)
6194                           && pfile->multiline_string_line == 0)
6195                         {
6196                           cppReader_pedwarnWithLine
6197                             (pfile, long_toInt (start_line),
6198                              long_toInt (start_column),
6199                              cstring_makeLiteral ("String constant runs past end of line"));
6200                         }
6201                       if (pfile->multiline_string_line == 0)
6202                         {
6203                           pfile->multiline_string_line = start_line;
6204                         }
6205                       
6206                       /*@switchbreak@*/ break;
6207                       
6208                     case '\\':
6209                       cc = cppReader_getC (pfile);
6210                       if (cc == '\n')
6211                         {
6212                           /* Backslash newline is replaced by nothing at all.  */
6213                           pfile->lineno++; /* 2003-11-03: AMiller suggested adding this, but
6214                                               its not clear why it is needed. */
6215                           cppReader_adjustWritten (pfile, -1);
6216                           pfile->lineno++;
6217                         }
6218                       else
6219                         {
6220                           /* ANSI stupidly requires that in \\ the second \
6221                              is *not* prevented from combining with a newline.  */
6222                           NEWLINE_FIX1(cc);
6223                           if (cc != EOF)
6224                             cppReader_putChar (pfile, cc);
6225                         }
6226                       /*@switchbreak@*/ break;
6227                       
6228                     case '\"':
6229                     case '\'':
6230                       if (cc == c)
6231                         goto while2end;
6232                       /*@switchbreak@*/ break;
6233                     }
6234                 }
6235             }
6236         while2end:
6237           pfile->lineno += count_newlines (pfile->token_buffer + old_written,
6238                                            cpplib_getPWritten (pfile));
6239           pfile->only_seen_white = 0;
6240           return c == '\'' ? CPP_CHAR : CPP_STRING;
6241
6242         case '$':
6243           if (!opts->dollars_in_ident)
6244             goto randomchar;
6245           goto letter;
6246
6247         case ':':
6248           if (opts->cplusplus && cppReader_peekC (pfile) == ':')
6249             goto op2;
6250           goto randomchar;
6251
6252         case '&':
6253         case '+':
6254         case '|':
6255           NEWLINE_FIX;
6256           c2 = cppReader_peekC (pfile);
6257           if (c2 == c || c2 == '=')
6258             goto op2;
6259           goto randomchar;
6260
6261         case '*':
6262         case '!':
6263         case '%':
6264         case '=':
6265         case '^':
6266           NEWLINE_FIX;
6267           if (cppReader_peekC (pfile) == '=')
6268             goto op2;
6269           goto randomchar;
6270
6271         case '-':
6272           NEWLINE_FIX;
6273           c2 = cppReader_peekC (pfile);
6274           if (c2 == '-' && opts->chill)
6275             {
6276               /* Chill style comment */
6277               if (opts->put_out_comments)
6278                 {
6279                   parseSetMark (&start_mark, pfile);
6280                 }
6281
6282               cppReader_forward (pfile, 1);  /* Skip second '-'.  */
6283
6284               for (;;)
6285                 {
6286                   c = cppReader_getC (pfile);
6287                   if (c == EOF)
6288                     /*@loopbreak@*/ break;
6289                   if (c == '\n')
6290                     {
6291                       /* Don't consider final '\n' to be part of comment.  */
6292                       cppReader_forward (pfile, -1);
6293                       /*@loopbreak@*/ break;
6294                     }
6295                 }
6296               c = '-';
6297               goto return_comment;
6298             }
6299           if (c2 == '-' || c2 == '=' || c2 == '>')
6300             goto op2;
6301           goto randomchar;
6302
6303         case '<':
6304           if (pfile->parsing_include_directive)
6305             {
6306               for (;;)
6307                 {
6308                   cppReader_putChar (pfile, c);
6309                   if (c == '>')
6310                     /*@loopbreak@*/ break;
6311                   c = cppReader_getC (pfile);
6312                   NEWLINE_FIX1 (c);
6313                   if (c == '\n' || c == EOF)
6314                     {
6315                       cppReader_errorLit (pfile,
6316                                     cstring_makeLiteralTemp ("Missing '>' in \"#include <FILENAME>\""));
6317                       /*@loopbreak@*/ break;
6318                     }
6319                 }
6320               return CPP_STRING;
6321             }
6322           /*@fallthrough@*/
6323         case '>':
6324           NEWLINE_FIX;
6325           c2 = cppReader_peekC (pfile);
6326           if (c2 == '=')
6327             goto op2;
6328           if (c2 != c)
6329             goto randomchar;
6330           cppReader_forward (pfile, 1);
6331           cpplib_reserve (pfile, 4);
6332           cppReader_putChar (pfile, c);
6333           cppReader_putChar (pfile, c2);
6334           NEWLINE_FIX;
6335           c3 = cppReader_peekC (pfile);
6336           if (c3 == '=')
6337             cppReader_putCharQ (pfile, cppReader_getC (pfile));
6338           cppReader_nullTerminateQ (pfile);
6339           pfile->only_seen_white = 0;
6340           return CPP_OTHER;
6341
6342         case '@':
6343           DPRINTF (("Macro @!"));
6344           if (cppReader_getBufferSafe (pfile)->has_escapes)
6345             {
6346               c = cppReader_getC (pfile);
6347               DPRINTF (("got c: %c", c));
6348               if (c == '-')
6349                 {
6350                   if (pfile->output_escapes)
6351                     cppReader_puts (pfile, "@-", 2);
6352                   parse_name (pfile, cppReader_getC (pfile));
6353                   return CPP_NAME;
6354                 }
6355               else if (is_space [c])
6356                 {
6357                   cpplib_reserve (pfile, 2);
6358                   if (pfile->output_escapes)
6359                     cppReader_putCharQ (pfile, '@');
6360                   cppReader_putCharQ (pfile, c);
6361                   return CPP_HSPACE;
6362                 }
6363               else
6364                 {
6365                   ;
6366                 }
6367             }
6368           if (pfile->output_escapes)
6369             {
6370               cppReader_puts (pfile, "@@", 2);
6371               return CPP_OTHER;
6372             }
6373           goto randomchar;
6374         case '.':
6375           NEWLINE_FIX;
6376           c2 = cppReader_peekC (pfile);
6377           if (isdigit(c2))
6378             {
6379               cpplib_reserve(pfile, 2);
6380               cppReader_putCharQ (pfile, '.');
6381               c = cppReader_getC (pfile);
6382               goto number;
6383             }
6384
6385           /* FIXME - misses the case "..\\\n." */
6386           if (c2 == '.' && cpp_peekN (pfile, 1) == '.')
6387             {
6388               cpplib_reserve(pfile, 4);
6389               cppReader_putCharQ (pfile, '.');
6390               cppReader_putCharQ (pfile, '.');
6391               cppReader_putCharQ (pfile, '.');
6392               cppReader_forward (pfile, 2);
6393               cppReader_nullTerminateQ (pfile);
6394               pfile->only_seen_white = 0;
6395               return CPP_3DOTS;
6396             }
6397           goto randomchar;
6398         op2:
6399           token = CPP_OTHER;
6400           pfile->only_seen_white = 0;
6401         op2any: /* jumped to for \ continuations */
6402           cpplib_reserve(pfile, 3);
6403           cppReader_putCharQ (pfile, c);
6404
6405           /* evans 2003-08-24: This is a hack to fix line output for \
6406              continuations.  Someday I really should get a decent pre-processor! 
6407           */
6408
6409           if (c == '\\') {
6410             (void) cppReader_getC (pfile); /* skip the newline to avoid extra lines */
6411           } else {
6412             cppReader_putCharQ (pfile, cppReader_getC (pfile)); 
6413           }
6414
6415           cppReader_nullTerminateQ (pfile);
6416           return token;
6417
6418         case 'L':
6419           NEWLINE_FIX;
6420           c2 = cppReader_peekC (pfile);
6421           if ((c2 == '\'' || c2 == '\"') && !cppReader_isTraditional (pfile))
6422             {
6423               cppReader_putChar (pfile, c);
6424               c = cppReader_getC (pfile);
6425               goto string;
6426             }
6427           goto letter;
6428
6429         case '0': case '1': case '2': case '3': case '4':
6430         case '5': case '6': case '7': case '8': case '9':
6431         number:
6432           c2  = '.';
6433           for (;;)
6434             {
6435               cpplib_reserve (pfile, 2);
6436               cppReader_putCharQ (pfile, c);
6437               NEWLINE_FIX;
6438               c = cppReader_peekC (pfile);
6439               if (c == EOF)
6440                 /*@loopbreak@*/ break;
6441               if (!is_idchar[c] && c != '.'
6442                   && ((c2 != 'e' && c2 != 'E'
6443                        && ((c2 != 'p' && c2 != 'P') || cppReader_isC89 (pfile)))
6444                       || (c != '+' && c != '-')))
6445                 /*@loopbreak@*/ break;
6446               cppReader_forward (pfile, 1);
6447               c2= c;
6448             }
6449
6450           cppReader_nullTerminateQ (pfile);
6451           pfile->only_seen_white = 0;
6452           return CPP_NUMBER;
6453
6454         case 'b': case 'c': case 'd': case 'h': case 'o':
6455         case 'B': case 'C': case 'D': case 'H': case 'O':
6456           if (opts->chill && cppReader_peekC (pfile) == '\'')
6457             {
6458               pfile->only_seen_white = 0;
6459               cpplib_reserve (pfile, 2);
6460               cppReader_putCharQ (pfile, c);
6461               cppReader_putCharQ (pfile, '\'');
6462               cppReader_forward (pfile, 1);
6463               for (;;)
6464                 {
6465                   c = cppReader_getC (pfile);
6466                   if (c == EOF)
6467                     goto chill_number_eof;
6468                   if (!is_idchar[c])
6469                     {
6470                       if (c == '\\' && cppReader_peekC (pfile) == '\n')
6471                         {
6472                           cppReader_forward (pfile, 2);
6473                           continue;
6474                         }
6475                       /*@loopbreak@*/ break;
6476                     }
6477                   cppReader_putChar (pfile, c);
6478                 }
6479               if (c == '\'')
6480                 {
6481                   cpplib_reserve (pfile, 2);
6482                   cppReader_putCharQ (pfile, c);
6483                   cppReader_nullTerminateQ (pfile);
6484                   return CPP_STRING;
6485                 }
6486               else
6487                 {
6488                   cppReader_forward (pfile, -1);
6489                 chill_number_eof:
6490                   cppReader_nullTerminate (pfile);
6491                   return CPP_NUMBER;
6492                 }
6493             }
6494           else
6495             goto letter;
6496         case '_':
6497         case 'a': case 'e': case 'f': case 'g': case 'i': case 'j':
6498         case 'k': case 'l': case 'm': case 'n': case 'p': case 'q':
6499         case 'r': case 's': case 't': case 'u': case 'v': case 'w':
6500         case 'x': case 'y': case 'z':
6501         case 'A': case 'E': case 'F': case 'G': case 'I': case 'J':
6502         case 'K': case 'M': case 'N': case 'P': case 'Q': case 'R':
6503         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
6504         case 'Y': case 'Z':
6505         letter:
6506           {
6507             hashNode hp;
6508             char *ident;
6509             size_t before_name_written = cpplib_getWritten (pfile);
6510             size_t ident_len;
6511             parse_name (pfile, c);
6512             pfile->only_seen_white = 0;
6513
6514             if (pfile->no_macro_expand)
6515               {
6516                 DPRINTF (("Not expanding: %s", pfile->token_buffer));
6517                 return CPP_NAME;
6518               }
6519
6520             ident = pfile->token_buffer + before_name_written;
6521             DPRINTF (("Ident: %s", ident));
6522
6523             ident_len = size_fromInt ((cpplib_getPWritten (pfile)) - ident);
6524
6525             hp = cpphash_lookupExpand (ident, size_toInt (ident_len), -1, forceExpand);
6526
6527             if (hp == NULL)
6528               {
6529                 DPRINTF (("No expand: %s %d", ident, ident_len));
6530                 return CPP_NAME;
6531               }
6532
6533             if (hp->type == T_DISABLED)
6534               {
6535                 DPRINTF (("Disabled!"));
6536
6537                 if (pfile->output_escapes)
6538                   { /* Return "@-IDENT", followed by '\0'.  */
6539                     int i;
6540                     cpplib_reserve (pfile, 3);
6541                     ident = pfile->token_buffer + before_name_written;
6542                     cppReader_adjustWritten (pfile, 2);
6543
6544                     for (i = size_toInt (ident_len); i >= 0; i--)
6545                       {
6546                         ident[i+2] = ident[i];
6547                       }
6548
6549                     ident[0] = '@';
6550                     ident[1] = '-';
6551                   }
6552                 return CPP_NAME;
6553               }
6554
6555             /* 
6556             ** If macro wants an arglist, verify that a '(' follows.
6557             ** first skip all whitespace, copying it to the output
6558             ** after the macro name.  Then, if there is no '(',
6559             ** decide this is not a macro call and leave things that way.  
6560             */
6561             
6562             if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
6563               {
6564                 struct parse_marker macro_mark;
6565                 int is_macro_call;
6566
6567                 DPRINTF (("Arglist macro!"));
6568
6569                 /*
6570                 ** evans 2002-07-03: Moved this here (from below).
6571                 **   This bug caused necessary whitespace to be lost
6572                 **   when parsing parameterized macros without parameters.
6573                 */
6574
6575                 parseSetMark (&macro_mark, pfile); 
6576
6577                 while (cppBuffer_isMacro (CPPBUFFER (pfile)))
6578                   {
6579                     cppBuffer *next_buf;
6580                     cppSkipHspace (pfile);
6581                     if (cppReader_peekC (pfile) != EOF)
6582                       {
6583                         DPRINTF (("Peeking!"));
6584                         /*@loopbreak@*/ break;
6585                       }
6586
6587                   next_buf = cppBuffer_prevBuffer (cppReader_getBufferSafe (pfile));
6588                   (*cppReader_getBufferSafe (pfile)->cleanup) (cppReader_getBufferSafe (pfile), pfile);
6589                   CPPBUFFER (pfile) = next_buf;
6590                   }
6591
6592                 /* parseSetMark (&macro_mark, pfile); */
6593
6594                 for (;;)
6595                   {
6596                     cppSkipHspace (pfile);
6597                     c = cppReader_peekC (pfile);
6598                     DPRINTF (("c: %c", c));
6599                     is_macro_call = c == '(';
6600                     if (c != '\n')
6601                       /*@loopbreak@*/ break;
6602                     cppReader_forward (pfile, 1);
6603                   }
6604
6605                 if (!is_macro_call)
6606                   {
6607                     parseGotoMark (&macro_mark, pfile);
6608                   }
6609
6610                 parseClearMark (&macro_mark);
6611
6612                 if (!is_macro_call)
6613                   {
6614                     DPRINTF (("not macro call!"));
6615                     return CPP_NAME;
6616                   }
6617               }
6618
6619             /* This is now known to be a macro call.  */
6620
6621             /* it might not actually be a macro.  */
6622             if (hp->type != T_MACRO)
6623               {
6624                 size_t xbuf_len;
6625                 char *xbuf;
6626
6627                 cppReader_setWritten (pfile, before_name_written);
6628                 special_symbol (hp, pfile);
6629                 xbuf_len = cpplib_getWritten (pfile) - before_name_written;
6630                 xbuf = (char *) dmalloc (xbuf_len + 1);
6631                 cppReader_setWritten (pfile, before_name_written);
6632                 memcpy (xbuf, cpplib_getPWritten (pfile), xbuf_len + 1);
6633                 push_macro_expansion (pfile, xbuf, xbuf_len, hp);
6634               }
6635             else
6636               {
6637                 /*
6638                 ** Expand the macro, reading arguments as needed,
6639                 ** and push the expansion on the input stack. 
6640                 */
6641
6642                 cpplib_macroExpand (pfile, hp);
6643                 cppReader_setWritten (pfile, before_name_written);
6644               }
6645
6646             /* An extra "@ " is added to the end of a macro expansion
6647                to prevent accidental token pasting.  We prefer to avoid
6648                unneeded extra spaces (for the sake of cpp-using tools like
6649                imake).  Here we remove the space if it is safe to do so.  */
6650
6651             llassert (pfile->buffer->rlimit != NULL);
6652
6653             if (pfile->buffer->rlimit - pfile->buffer->cur >= 3
6654                 && pfile->buffer->rlimit[-2] == '@'
6655                 && pfile->buffer->rlimit[-1] == ' ')
6656               {
6657                 int c1 = pfile->buffer->rlimit[-3];
6658                 int cl2 = cpplib_bufPeek (cppBuffer_prevBuffer (CPPBUFFER (pfile)));
6659
6660                 if (cl2 == EOF || !unsafe_chars ((char) c1, (char) cl2))
6661                   pfile->buffer->rlimit -= 2;
6662               }
6663           }
6664           goto get_next;
6665
6666
6667         case ' ':  case '\t':  case '\v':  case '\r':
6668           for (;;)
6669             {
6670               cppReader_putChar (pfile, c);
6671               c = cppReader_peekC (pfile);
6672               if (c == EOF || !is_hor_space[c])
6673                 /*@loopbreak@*/ break;
6674               cppReader_forward (pfile, 1);
6675             }
6676           return CPP_HSPACE;
6677
6678         case '\\':
6679           c2 = cppReader_peekC (pfile);
6680           /* allow other stuff here if a flag is set? */
6681           DPRINTF (("Got continuation!"));
6682           if (c2 != '\n')
6683             goto randomchar;
6684           token = CPP_HSPACE;
6685           goto op2any;
6686
6687         case '\n':
6688           cppReader_putChar (pfile, c);
6689           if (pfile->only_seen_white == 0)
6690             pfile->only_seen_white = 1;
6691           pfile->lineno++;
6692           output_line_command (pfile, 1, same_file);
6693           return CPP_VSPACE;
6694
6695         case '(': token = CPP_LPAREN;    goto char1;
6696         case ')': token = CPP_RPAREN;    goto char1;
6697         case '{': token = CPP_LBRACE;    goto char1;
6698         case '}': token = CPP_RBRACE;    goto char1;
6699         case ',': token = CPP_COMMA;     goto char1;
6700         case ';': token = CPP_SEMICOLON; goto char1;
6701
6702         randomchar:
6703         default:
6704           token = CPP_OTHER;
6705         char1:
6706           pfile->only_seen_white = 0;
6707           cppReader_putChar (pfile, c);
6708           return token;
6709         }
6710     }
6711
6712   BADBRANCH;
6713   /*@notreached@*/
6714 }
6715
6716 /* Parse an identifier starting with C.  */
6717
6718 void
6719 parse_name (cppReader *pfile, int c)
6720 {
6721   for (;;)
6722     {
6723       if (!is_idchar[c])
6724         {
6725           if (c == '\\' && cppReader_peekC (pfile) == '\n')
6726             {
6727               cppReader_forward (pfile, 2);
6728               continue;
6729             }
6730
6731           cppReader_forward (pfile, -1);
6732           break;
6733         }
6734
6735       if (c == '$' && cppReader_isPedantic (pfile))
6736         {
6737           cppReader_pedwarnLit (pfile,
6738                           cstring_makeLiteralTemp ("`$' in identifier"));
6739         }
6740
6741       cpplib_reserve(pfile, 2); /* One more for final NUL.  */
6742       cppReader_putCharQ (pfile, c);
6743       c = cppReader_getC (pfile);
6744
6745       if (c == EOF)
6746         break;
6747     }
6748
6749   cppReader_nullTerminateQ (pfile);
6750 }
6751
6752 /* The file_name_map structure holds a mapping of file names for a
6753    particular directory.  This mapping is read from the file named
6754    FILE_NAME_MAP_FILE in that directory.  Such a file can be used to
6755    map filenames on a file system with severe filename restrictions,
6756    such as DOS.  The format of the file name map file is just a series
6757    of lines with two tokens on each line.  The first token is the name
6758    to map, and the second token is the actual name to use.  */
6759
6760 struct file_name_map
6761 {
6762   struct file_name_map *map_next;
6763   cstring map_from;
6764   cstring map_to;
6765 };
6766
6767 /*@constant observer char *FILE_NAME_MAP_FILE*/
6768 #define FILE_NAME_MAP_FILE "header.gcc"
6769
6770 /* Read a space delimited string of unlimited length from a stdio
6771    file.  */
6772
6773 static cstring read_filename_string (int ch, /*:open:*/ FILE *f)
6774 {
6775   char *alloc, *set;
6776   size_t len;
6777
6778   len = 20;
6779   set = alloc = dmalloc (len + 1);
6780
6781   if (!is_space[ch])
6782     {
6783       *set++ = ch;
6784       while ((ch = getc (f)) != EOF && ! is_space[ch])
6785         {
6786           if (set - alloc == size_toInt (len))
6787             {
6788               len *= 2;
6789               alloc = drealloc (alloc, len + 1);
6790               set = alloc + len / 2;
6791               /*@-branchstate@*/ }
6792
6793           *set++ = ch;
6794         } /*@=branchstate@*/
6795     }
6796   *set = '\0';
6797   check (ungetc (ch, f) != EOF);
6798
6799   return cstring_fromChars (alloc);
6800 }
6801
6802 /* This structure holds a linked list of file name maps, one per directory.  */
6803
6804 struct file_name_map_list
6805 {
6806   /*@only@*/ struct file_name_map_list *map_list_next;
6807   /*@only@*/ cstring map_list_name;
6808   /*@null@*/ struct file_name_map *map_list_map;
6809 };
6810
6811 /* Read the file name map file for DIRNAME.  */
6812
6813 static struct file_name_map *
6814 read_name_map (cppReader *pfile, cstring dirname)
6815 {
6816   struct file_name_map_list *map_list_ptr;
6817   cstring name;
6818   FILE *f;
6819
6820   for (map_list_ptr = CPPOPTIONS (pfile)->map_list;
6821        map_list_ptr != NULL;
6822        map_list_ptr = map_list_ptr->map_list_next)
6823     {
6824       if (cstring_equal (map_list_ptr->map_list_name, dirname))
6825         {
6826           return map_list_ptr->map_list_map;
6827         }
6828     }
6829
6830   map_list_ptr = (struct file_name_map_list *) dmalloc (sizeof (*map_list_ptr));
6831   map_list_ptr->map_list_name = cstring_copy (dirname);
6832   map_list_ptr->map_list_map = NULL;
6833
6834   name = cstring_copy (dirname);
6835
6836   if (cstring_length (dirname) > 0)
6837     {
6838       name = cstring_appendChar (name, CONNECTCHAR);
6839     }
6840
6841   name = cstring_concatFree1 (name, cstring_makeLiteralTemp (FILE_NAME_MAP_FILE));
6842
6843   f = fileTable_openReadFile (context_fileTable (), name);
6844   cstring_free (name);
6845
6846   if (f == NULL)
6847     {
6848       map_list_ptr->map_list_map = NULL;
6849     }
6850   else
6851     {
6852       int ch;
6853
6854       while ((ch = getc (f)) != EOF)
6855         {
6856           cstring from, to;
6857           struct file_name_map *ptr;
6858
6859           if (is_space[ch])
6860             {
6861               continue;
6862             }
6863
6864           from = read_filename_string (ch, f);
6865           while ((ch = getc (f)) != EOF && is_hor_space[ch])
6866             {
6867               ;
6868             }
6869
6870           to = read_filename_string (ch, f);
6871
6872           ptr = (struct file_name_map *) dmalloc (sizeof (*ptr));
6873           ptr->map_from = from;
6874
6875           /* Make the real filename absolute.  */
6876           if (cstring_length (to) > 1 
6877               && osd_isConnectChar (cstring_firstChar (to)))
6878             {
6879               ptr->map_to = to;
6880             }
6881           else
6882             {
6883               ptr->map_to = cstring_copy (dirname);
6884               ptr->map_to = cstring_appendChar (ptr->map_to, CONNECTCHAR);
6885               ptr->map_to = cstring_concatFree (ptr->map_to, to);
6886             }
6887
6888           ptr->map_next = map_list_ptr->map_list_map;
6889           map_list_ptr->map_list_map = ptr;
6890
6891           while ((ch = getc (f)) != '\n')
6892             {
6893               if (ch == EOF)
6894                 {
6895                   /*@innerbreak@*/ break;
6896                 }
6897             }
6898         }
6899
6900       assertSet (map_list_ptr->map_list_map);
6901       check (fileTable_closeFile (context_fileTable (),f) == 0);
6902     }
6903
6904   map_list_ptr->map_list_next = pfile->opts->map_list;
6905   pfile->opts->map_list = map_list_ptr;
6906
6907   return map_list_ptr->map_list_map;
6908 }
6909
6910 /* Try to open include file FILENAME.  SEARCHPTR is the directory
6911    being tried from the include file search path.  This function maps
6912    filenames on file systems based on information read by
6913    read_name_map.  */
6914
6915 static int
6916 open_include_file (cppReader *pfile,
6917                    cstring fname,
6918                    struct file_name_list *searchptr)
6919 {
6920   char *filename = cstring_toCharsSafe (fname);
6921   struct file_name_map *map;
6922   char *from;
6923   char *p, *dir;
6924
6925   cstring_markOwned (fname);
6926
6927   cpp_setLocation (pfile);
6928
6929   if (context_getFlag (FLG_NEVERINCLUDE))
6930     {
6931       if (isHeaderFile (fname))
6932         {
6933           return SKIP_INCLUDE;
6934         }
6935     }
6936
6937   if ((searchptr != NULL) && ! searchptr->got_name_map)
6938     {
6939       searchptr->name_map = read_name_map (pfile,
6940                                            !cstring_isEmpty (searchptr->fname)
6941                                            ? searchptr->fname :
6942                                            cstring_makeLiteralTemp ("."));
6943       searchptr->got_name_map = 1;
6944     }
6945
6946   /* First check the mapping for the directory we are using.  */
6947
6948   if ((searchptr != NULL)
6949       && (searchptr->name_map != NULL))
6950     {
6951       from = filename;
6952
6953       if (!cstring_isEmpty (searchptr->fname))
6954         {
6955           from += cstring_length (searchptr->fname) + 1;
6956         }
6957
6958       for (map = searchptr->name_map;
6959            map != NULL;
6960            map = map->map_next)
6961         {
6962           if (cstring_equal (map->map_from, cstring_fromChars (from)))
6963             {
6964               /*
6965               ** Found a match.  Check if the file should be skipped
6966               */
6967               
6968               if (cpp_skipIncludeFile (map->map_to))
6969                 {
6970                   return SKIP_INCLUDE;
6971                 }
6972               else
6973                 {
6974                   return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
6975                 }
6976             }
6977         }
6978     }
6979
6980   /*
6981   ** Try to find a mapping file for the particular directory we are
6982   ** looking in.  Thus #include <sys/types.h> will look up sys/types.h
6983   ** in /usr/include/header.gcc and look up types.h in
6984   ** /usr/include/sys/header.gcc.
6985   */
6986
6987   p = strrchr (filename, CONNECTCHAR);
6988
6989   if (p == NULL)
6990     {
6991       p = filename;
6992     }
6993
6994   if ((searchptr != NULL)
6995       && (cstring_isDefined (searchptr->fname))
6996       && (size_toInt (cstring_length (searchptr->fname)) == p - filename)
6997       && !strncmp (cstring_toCharsSafe (searchptr->fname),
6998                    filename,
6999                    size_fromInt (p - filename)))
7000     {
7001       /* filename is in SEARCHPTR, which we've already checked.  */
7002
7003       if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7004         {
7005           return SKIP_INCLUDE;
7006         }
7007       else
7008         {
7009           return cpp_openIncludeFile (filename);
7010         }
7011     }
7012
7013   if (p == filename)
7014     {
7015       dir = mstring_copy (".");
7016       from = filename;
7017     }
7018   else
7019     {
7020       dir = (char *) dmalloc (size_fromInt (p - filename + 1));
7021       memcpy (dir, filename, size_fromInt (p - filename));
7022       dir[p - filename] = '\0';
7023       from = p + 1;
7024     }
7025
7026   for (map = read_name_map (pfile, cstring_fromChars (dir));
7027        map != NULL;
7028        map = map->map_next)
7029     {
7030       if (cstring_equal (map->map_from, cstring_fromChars (from)))
7031         {
7032           sfree (dir);
7033
7034           if (cpp_skipIncludeFile (map->map_to))
7035             {
7036               return SKIP_INCLUDE;
7037             }
7038           else
7039             {
7040               return cpp_openIncludeFile (cstring_toCharsSafe (map->map_to));
7041             }
7042         }
7043     }
7044
7045   sfree (dir);
7046
7047   if (cpp_skipIncludeFile (cstring_fromChars (filename)))
7048     {
7049       return SKIP_INCLUDE;
7050     }
7051   else
7052     {
7053       return cpp_openIncludeFile (filename);
7054     }
7055 }
7056
7057 /* Process the contents of include file FNAME, already open on descriptor F,
7058    with output to OP.
7059    SYSTEM_HEADER_P is 1 if this file resides in any one of the known
7060    "system" include directories (as decided by the `is_system_include'
7061    function above).
7062    DIRPTR is the link in the dir path through which this file was found,
7063    or 0 if the file name was absolute or via the current directory.
7064    Return 1 on success, 0 on failure.
7065
7066    The caller is responsible for the cppReader_pushBuffer.  */
7067
7068 static int
7069 finclude (cppReader *pfile, int f,
7070           cstring fname,
7071           bool system_header_p,
7072           /*@dependent@*/ struct file_name_list *dirptr)
7073 {
7074   mode_t st_mode;
7075   size_t st_size;
7076   long i;
7077   int length = 0;
7078   cppBuffer *fp;                        /* For input stack frame */
7079
7080   if (file_size_and_mode (f, &st_mode, &st_size) < 0)
7081     {
7082       cppReader_perrorWithName (pfile, fname);
7083       check (close (f) == 0);
7084       (void) cppReader_popBuffer (pfile);
7085       /*@-mustfree@*/
7086       return 0;
7087       /*@=mustfree@*/
7088     }
7089
7090   fp = cppReader_getBufferSafe (pfile);
7091
7092   /*@-temptrans@*/ /* fname shouldn't really be temp */
7093   fp->nominal_fname = fp->fname = fname;
7094   /*@=temptrans@*/
7095
7096   fp->dir = dirptr;
7097   fp->system_header_p = system_header_p;
7098   fp->lineno = 1;
7099   fp->colno = 1;
7100   fp->cleanup = cppReader_fileCleanup;
7101
7102   if (S_ISREG (st_mode))
7103     {
7104       sfree (fp->buf);
7105       fp->buf = (char *) dmalloc (st_size + 2);
7106       fp->alimit = fp->buf + st_size + 2;
7107       fp->cur = fp->buf;
7108
7109       /* Read the file contents, knowing that st_size is an upper bound
7110          on the number of bytes we can read.  */
7111       length = safe_read (f, fp->buf, size_toInt (st_size));
7112       fp->rlimit = fp->buf + length;
7113       if (length < 0) goto nope;
7114     }
7115   else if (S_ISDIR (st_mode))
7116     {
7117       cppReader_error (pfile,
7118                        message ("Directory specified where file is expected: %s", fname));
7119       check (close (f) == 0);
7120       return 0;
7121     }
7122   else
7123     {
7124       /*
7125       ** Cannot count its file size before reading.
7126       ** First read the entire file into heap and
7127       ** copy them into buffer on stack.
7128       */
7129
7130       size_t bsize = 2000;
7131
7132       st_size = 0;
7133
7134       sfree (fp->buf);
7135       fp->buf = (char *) dmalloc (bsize + 2);
7136
7137       for (;;) {
7138         i = safe_read (f, fp->buf + st_size, size_toInt (bsize - st_size));
7139
7140         if (i < 0)
7141           goto nope;      /* error! */
7142         st_size += i;
7143
7144         if (st_size != bsize)
7145           {
7146             break;      /* End of file */
7147           }
7148
7149         bsize *= 2;
7150         fp->buf = (char *) drealloc (fp->buf, bsize + 2);
7151       }
7152
7153       fp->cur = fp->buf;
7154       length = size_toInt (st_size);
7155     }
7156
7157   if ((length > 0 && fp->buf[length - 1] != '\n')
7158       /* Backslash-newline at end is not good enough.  */
7159       || (length > 1 && fp->buf[length - 2] == '\\')) {
7160     fp->buf[length++] = '\n';
7161   }
7162
7163   fp->buf[length] = '\0';
7164   fp->rlimit = fp->buf + length;
7165
7166   /* Close descriptor now, so nesting does not use lots of descriptors.  */
7167   check (close (f) == 0);
7168
7169   /* Must do this before calling trigraph_pcp, so that the correct file name
7170      will be printed in warning messages.  */
7171
7172   pfile->input_stack_listing_current = 0;
7173   return 1;
7174
7175  nope:
7176
7177   cppReader_perrorWithName (pfile, fname);
7178   check (close (f) == 0);
7179   sfree (fp->buf);
7180   return 1;
7181 }
7182
7183 void
7184 cpplib_init (cppReader *pfile)
7185 {
7186   memset ((char *) pfile, 0, sizeof (*pfile));
7187
7188   pfile->get_token = cpplib_getToken;
7189   pfile->token_buffer_size = 200;
7190   pfile->token_buffer = (char *) dmalloc (pfile->token_buffer_size);
7191   pfile->all_include_files = NULL;
7192
7193   assertSet (pfile);
7194
7195   cppReader_setWritten (pfile, 0);
7196
7197   pfile->system_include_depth = 0;
7198   pfile->max_include_len = 0;
7199   pfile->timebuf = NULL;
7200   pfile->only_seen_white = 1;
7201
7202   pfile->buffer = cppReader_nullBuffer (pfile);
7203 }
7204
7205 void
7206 cppReader_finish (/*@unused@*/ cppReader *pfile)
7207 {
7208   ;
7209 }
7210
7211 /* Free resources used by PFILE.
7212    This is the cppReader 'finalizer' or 'destructor' (in C++ terminology).  */
7213
7214 void
7215 cppCleanup (/*@special@*/ cppReader *pfile) 
7216      /*@uses pfile@*/
7217      /*@releases pfile@*/
7218 {
7219   DPRINTF (("cppCleanup!"));
7220
7221   while (CPPBUFFER (pfile) != cppReader_nullBuffer (pfile))
7222     {
7223       (void) cppReader_popBuffer (pfile);
7224     }
7225
7226   if (pfile->token_buffer != NULL)
7227     {
7228       sfree (pfile->token_buffer);
7229       pfile->token_buffer = NULL;
7230     }
7231
7232   while (pfile->if_stack != NULL)
7233     {
7234       cppIfStackFrame *temp = pfile->if_stack;
7235       pfile->if_stack = temp->next;
7236       sfree (temp);
7237     }
7238
7239   while (pfile->all_include_files != NULL)
7240     {
7241       struct file_name_list *temp = pfile->all_include_files;
7242       pfile->all_include_files = temp->next;
7243       /*@-dependenttrans@*/
7244       cstring_free (temp->fname);
7245       /*@=dependenttrans@*/
7246       sfree (temp);
7247     }
7248
7249   /* evans 2002-07-12 */
7250   while (pfile->opts->map_list != NULL)
7251     {
7252       struct file_name_map_list *temp = pfile->opts->map_list;
7253       pfile->opts->map_list = pfile->opts->map_list->map_list_next;
7254       cstring_free (temp->map_list_name);
7255       sfree (temp);
7256     }
7257
7258   while (pfile->opts->include != NULL)
7259     {
7260       struct file_name_list *temp = pfile->opts->include;
7261       pfile->opts->include = pfile->opts->include->next;
7262       /* cstring_free (temp->fname); */
7263       sfree (temp);
7264     }
7265
7266   sfree (pfile->opts);
7267   pfile->opts = NULL;
7268   cppReader_hashCleanup ();
7269 }
7270
7271 /*
7272 ** Get the file-mode and data size of the file open on FD
7273 ** and store them in *MODE_POINTER and *SIZE_POINTER.
7274 */
7275
7276 static int
7277 file_size_and_mode (int fd, mode_t *mode_pointer, size_t *size_pointer)
7278 {
7279   struct stat sbuf;
7280
7281   if (fstat (fd, &sbuf) < 0) {
7282     *mode_pointer = 0;
7283     *size_pointer = 0;
7284     return (-1);
7285   }
7286
7287   if (mode_pointer != NULL)
7288     {
7289       *mode_pointer = sbuf.st_mode;
7290     }
7291
7292   if (size_pointer != NULL)
7293     {
7294       *size_pointer = (size_t) sbuf.st_size;
7295     }
7296
7297   return 0;
7298 }
7299
7300 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
7301    retrying if necessary.  Return a negative value if an error occurs,
7302    otherwise return the actual number of bytes read,
7303    which must be LEN unless end-of-file was reached.  */
7304
7305 static int safe_read (int desc, char *ptr, int len)
7306 {
7307   int left = len;
7308
7309   while (left > 0)
7310     {
7311 # if defined (WIN32) || defined (OS2) && defined (__IBMC__)
7312           /*@-compdef@*/ /* ptr is an out parameter */
7313       int nchars = _read (desc, ptr, (unsigned) left);
7314           /*@=compdef@*/
7315 # else
7316       ssize_t nchars = read (desc, ptr, size_fromInt (left));
7317 # endif
7318
7319       if (nchars < 0)
7320         {
7321 #ifdef EINTR
7322           if (errno == EINTR)
7323             continue;
7324 #endif
7325           return (int) nchars;
7326         }
7327
7328       if (nchars == 0) {
7329         break;
7330       }
7331
7332       ptr += nchars;
7333       left -= nchars;
7334     }
7335
7336   return len - left;
7337 }
7338
7339 /* Initialize PMARK to remember the current position of PFILE.  */
7340
7341 void
7342 parseSetMark (struct parse_marker *pmark, cppReader *pfile)
7343 {
7344   cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
7345
7346   pmark->next = pbuf->marks;
7347   /*@-temptrans@*/
7348   pbuf->marks = pmark;
7349   /*@=temptrans@*/
7350
7351   pmark->buf = pbuf;
7352   pmark->position = pbuf->cur - pbuf->buf;
7353   DPRINTF (("set mark: %d / %s", pmark->position, pbuf->cur));
7354 }
7355
7356 /* Cleanup PMARK - we no longer need it.  */
7357
7358 void parseClearMark (struct parse_marker *pmark)
7359 {
7360   struct parse_marker **pp = &pmark->buf->marks;
7361
7362   for (; ; pp = &(*pp)->next)
7363     {
7364       llassert (*pp != NULL);
7365       if (*pp == pmark) break;
7366     }
7367
7368   *pp = pmark->next;
7369 }
7370
7371 /* Backup the current position of PFILE to that saved in PMARK.  */
7372
7373 void
7374 parseGotoMark (struct parse_marker *pmark, cppReader *pfile)
7375 {
7376   cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
7377
7378   if (pbuf != pmark->buf)
7379     {
7380       cpp_setLocation (pfile);
7381       llfatalbug (cstring_makeLiteral ("Internal error parseGotoMark"));
7382     }
7383
7384   llassert (pbuf->buf != NULL);
7385   pbuf->cur = pbuf->buf + pmark->position;
7386   DPRINTF (("goto mark: %d / %s", pmark->position, pbuf->cur));
7387 }
7388
7389 /* Reset PMARK to point to the current position of PFILE.  (Same
7390    as parseClearMark (PMARK), parseSetMark (PMARK, PFILE) but faster.  */
7391
7392 void
7393 parseMoveMark (struct parse_marker *pmark, cppReader *pfile)
7394 {
7395   cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
7396
7397   if (pbuf != pmark->buf)
7398     {
7399       cpp_setLocation (pfile);
7400       llfatalerror (cstring_makeLiteral ("Internal error parseMoveMark"));
7401     }
7402
7403   pmark->position = pbuf->cur - pbuf->buf;
7404   DPRINTF (("move mark: %s", pmark->position));
7405 }
7406
7407 void cpplib_initializeReader (cppReader *pfile) /* Must be done after library is loaded. */
7408 {
7409   struct cppOptions *opts = CPPOPTIONS (pfile);
7410   cstring xp;
7411
7412   /* The code looks at the defaults through this pointer, rather than through
7413      the constant structure above.  This pointer gets changed if an environment
7414      variable specifies other defaults.  */
7415
7416   struct default_include *include_defaults = include_defaults_array;
7417
7418   /* Add dirs from INCLUDEPATH_VAR after dirs from -I.  */
7419   /* There seems to be confusion about what CPATH should do,
7420      so for the moment it is not documented.  */
7421   /* Some people say that CPATH should replace the standard include dirs,
7422      but that seems pointless: it comes before them, so it overrides them
7423      anyway.  */
7424
7425   xp = osd_getEnvironmentVariable (INCLUDEPATH_VAR);
7426
7427   if (cstring_isDefined (xp) && !opts->no_standard_includes)
7428     {
7429       path_include (pfile, cstring_toCharsSafe (xp));
7430     }
7431
7432   /* Now that dollars_in_ident is known, initialize is_idchar.  */
7433   initialize_char_syntax (opts);
7434
7435   /* CppReader_Install __LINE__, etc.  Must follow initialize_char_syntax
7436      and option processing.  */
7437
7438   initialize_builtins (pfile);
7439
7440   /* Do standard #defines and assertions
7441      that identify system and machine type.  */
7442
7443   if (!opts->inhibit_predefs) {
7444     char *p = (char *) dmalloc (strlen (predefs) + 1);
7445     strcpy (p, predefs);
7446
7447     while (*p)
7448       {
7449         char *q;
7450
7451         while (*p == ' ' || *p == '\t')
7452           {
7453             p++;
7454           }
7455
7456         /* Handle -D options.  */
7457         if (p[0] == '-' && p[1] == 'D')
7458           {
7459             q = &p[2];
7460
7461             while (*p && *p != ' ' && *p != '\t')
7462               {
7463                 p++;
7464               }
7465
7466             if (*p != 0)
7467               {
7468                 *p++= 0;
7469               }
7470
7471             if (opts->debug_output)
7472               {
7473                 output_line_command (pfile, 0, same_file);
7474               }
7475
7476             cppReader_define (pfile, q);
7477
7478             while (*p == ' ' || *p == '\t')
7479               {
7480                 p++;
7481               }
7482           }
7483         else
7484           {
7485             abort ();
7486           }
7487       }
7488
7489     sfree (p);
7490   }
7491
7492   opts->done_initializing = 1;
7493
7494   { /* Read the appropriate environment variable and if it exists
7495        replace include_defaults with the listed path.  */
7496     char *epath = 0;
7497 #ifdef __CYGWIN32__
7498   char *win32epath;
7499   int win32_buf_size = 0; /* memory we need to allocate */
7500 #endif
7501
7502   if (opts->cplusplus)
7503     {
7504       epath = getenv ("CPLUS_INCLUDE_PATH");
7505     }
7506   else
7507     {
7508       epath = getenv ("C_INCLUDE_PATH");
7509     }
7510
7511   /*
7512   ** If the environment var for this language is set,
7513   ** add to the default list of include directories.
7514   */
7515
7516     if (epath != NULL) {
7517       char *nstore = (char *) dmalloc (strlen (epath) + 2);
7518       int num_dirs;
7519       char *startp, *endp;
7520
7521 #ifdef __CYGWIN32__
7522       /* if we have a posix path list, convert to win32 path list */
7523       if (cygwin32_posix_path_list_p (epath))
7524         {
7525           win32_buf_size = cygwin32_posix_to_win32_path_list_buf_size (epath);
7526           win32epath = (char *) dmalloc /*@i4@*/ (win32_buf_size);
7527           cygwin32_posix_to_win32_path_list (epath, win32epath);
7528           epath = win32epath;
7529         }
7530 #endif
7531       for (num_dirs = 1, startp = epath; *startp; startp++)
7532         {
7533           if (*startp == PATH_SEPARATOR)
7534             num_dirs++;
7535         }
7536
7537       /*@-sizeoftype@*/
7538       include_defaults
7539         = (struct default_include *) dmalloc ((num_dirs
7540                                                * sizeof (struct default_include))
7541                                               + sizeof (include_defaults_array));
7542       /*@=sizeoftype@*/
7543
7544       startp = endp = epath;
7545       num_dirs = 0;
7546       while (1) {
7547         /* Handle cases like c:/usr/lib:d:/gcc/lib */
7548         if ((*endp == PATH_SEPARATOR) || *endp == 0)
7549           {
7550             strncpy (nstore, startp, size_fromInt (endp - startp));
7551             if (endp == startp)
7552               {
7553                 strcpy (nstore, ".");
7554               }
7555             else
7556               {
7557                 nstore[endp-startp] = '\0';
7558               }
7559
7560             include_defaults[num_dirs].fname = cstring_fromCharsNew (nstore);
7561             include_defaults[num_dirs].cplusplus = opts->cplusplus;
7562             include_defaults[num_dirs].cxx_aware = 1;
7563             num_dirs++;
7564
7565             if (*endp == '\0')
7566               {
7567                 break;
7568               }
7569             endp = startp = endp + 1;
7570           }
7571         else
7572           {
7573             endp++;
7574           }
7575       }
7576       /* Put the usual defaults back in at the end.  */
7577       memcpy ((char *) &include_defaults[num_dirs],
7578               (char *) include_defaults_array,
7579               sizeof (include_defaults_array));
7580
7581       sfree (nstore);
7582       /*@-branchstate@*/ } /*@=branchstate@*/
7583   }
7584
7585   cppReader_appendIncludeChain (pfile, opts->before_system,
7586                                 opts->last_before_system);
7587
7588   opts->first_system_include = opts->before_system;
7589
7590   /* Unless -fnostdinc,
7591      tack on the standard include file dirs to the specified list */
7592
7593   if (!opts->no_standard_includes) {
7594     struct default_include *p = include_defaults;
7595     char *specd_prefix = opts->include_prefix;
7596     char *default_prefix = mstring_copy (GCC_INCLUDE_DIR);
7597     size_t default_len = 0;
7598     
7599     /* Remove the `include' from /usr/local/lib/gcc.../include.  */
7600     if (default_prefix != NULL) {
7601       if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
7602         default_len = strlen (default_prefix) - 7;
7603         default_prefix[default_len] = 0;
7604       }
7605     }
7606     
7607     /* Search "translated" versions of GNU directories.
7608        These have /usr/local/lib/gcc... replaced by specd_prefix.  */
7609     if (specd_prefix != 0 && default_len != 0)
7610       for (p = include_defaults; p->fname != NULL; p++) {
7611         /* Some standard dirs are only for C++.  */
7612         if (!p->cplusplus
7613             || (opts->cplusplus && !opts->no_standard_cplusplus_includes)) {
7614           /* Does this dir start with the prefix?  */
7615           llassert (default_prefix != NULL);
7616
7617           if (!strncmp (cstring_toCharsSafe (p->fname), default_prefix, default_len))
7618             {
7619               /* Yes; change prefix and add to search list.  */
7620               struct file_name_list *nlist
7621                 = (struct file_name_list *) dmalloc (sizeof (*nlist));
7622               size_t this_len = strlen (specd_prefix) + cstring_length (p->fname) - default_len;
7623               char *str = (char *) dmalloc (this_len + 1);
7624               strcpy (str, specd_prefix);
7625               strcat (str, cstring_toCharsSafe (p->fname) + default_len);
7626
7627               nlist->next = NULL;
7628               nlist->fname = cstring_fromChars (str);
7629               nlist->control_macro = 0;
7630               nlist->c_system_include_path = !p->cxx_aware;
7631               nlist->got_name_map = 0;
7632
7633               if (opts->first_system_include == 0)
7634                 {
7635                   opts->first_system_include = nlist;
7636                 }
7637          
7638               cppReader_addIncludeChain (pfile, nlist);
7639             }
7640         }
7641       }
7642     
7643     /* Search ordinary names for GNU include directories.  */
7644
7645     for (p = include_defaults; p->fname != NULL; p++)
7646       {
7647         /* Some standard dirs are only for C++.  */
7648         if (!p->cplusplus
7649             || (opts->cplusplus && !opts->no_standard_cplusplus_includes))
7650           {
7651             struct file_name_list *nlist
7652               = (struct file_name_list *) dmalloc (sizeof (*nlist));
7653             nlist->control_macro = 0;
7654             nlist->c_system_include_path = !p->cxx_aware;
7655             nlist->fname = p->fname;
7656             nlist->got_name_map = 0;
7657             nlist->next = NULL;
7658
7659             /* Spurious warning reported for opts->first_system_include */
7660             /*@-usereleased@*/ if (opts->first_system_include == NULL) 
7661               {
7662                 opts->first_system_include = nlist;
7663               }
7664             /*@=usereleased@*/
7665
7666             cppReader_addIncludeChain (pfile, nlist);
7667           }
7668       }
7669     sfree (default_prefix);
7670   }
7671
7672   /* Tack the after_include chain at the end of the include chain.  */
7673   cppReader_appendIncludeChain (pfile, opts->after_include,
7674                                 opts->last_after_include);
7675
7676   /* Spurious warnings for opts->first_system_include */
7677   /*@-usereleased@*/
7678   if (opts->first_system_include == NULL)
7679     {
7680       opts->first_system_include = opts->after_include;
7681     }
7682   /*@=usereleased@*/
7683   
7684   /* With -v, print the list of dirs to search.  */
7685   if (opts->verbose) {
7686     struct file_name_list *p;
7687     fprintf (stderr, "#include \"...\" search starts here:\n");
7688
7689     for (p = opts->include; p != NULL; p = p->next) {
7690       if (p == opts->first_bracket_include)
7691         fprintf (stderr, "#include <...> search starts here:\n");
7692
7693       fprintf (stderr, " %s\n", cstring_toCharsSafe (p->fname));
7694     }
7695     fprintf (stderr, "End of search list.\n");
7696   }
7697 }
7698
7699 int cppReader_startProcess (cppReader *pfile, cstring fname)
7700 {
7701   cppBuffer *fp;
7702   int f;
7703   struct cppOptions *opts = CPPOPTIONS (pfile);
7704
7705   fp = cppReader_pushBuffer (pfile, NULL, 0);
7706
7707   if (fp == NULL)
7708     {
7709       return 0;
7710     }
7711
7712   if (opts->in_fname == NULL)
7713     {
7714       opts->in_fname = cstring_makeLiteralTemp ("");
7715     }
7716
7717   fp->fname = opts->in_fname;
7718   fp->nominal_fname = fp->fname;
7719   fp->lineno = 0;
7720
7721   /* Copy the entire contents of the main input file into
7722      the stacked input buffer previously allocated for it.  */
7723
7724   if (cstring_isEmpty (fname))
7725     {
7726       fname = cstring_makeLiteralTemp ("");
7727       f = 0;
7728     }
7729   else if ((f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666)) < 0)
7730     {
7731       cppReader_error (pfile,
7732                        message ("Error opening %s for reading: %s",
7733                                 fname, lldecodeerror (errno)));
7734
7735       return 0;
7736     }
7737   else
7738     {
7739       ;
7740     }
7741
7742   if (finclude (pfile, f, fname, 0, NULL))
7743     {
7744       output_line_command (pfile, 0, same_file);
7745     }
7746
7747   return 1;
7748 }
7749
7750 static /*@exposed@*/ /*@null@*/ cppBuffer *cppReader_getBuffer (cppReader *pfile)
7751 {
7752   return pfile->buffer;
7753 }
7754
7755 /*@exposed@*/ cppBuffer *cppReader_getBufferSafe (cppReader *pfile)
7756 {
7757   llassert (pfile->buffer != NULL);
7758   return pfile->buffer;
7759 }
7760
7761 /*@exposed@*/ char *cppLineBase (cppBuffer *buf)
7762 {
7763   llassert (buf->buf != NULL);
7764   return (buf->buf + buf->line_base);
7765 }
7766
7767 int cpplib_bufPeek (cppBuffer *buf)
7768 {
7769   if (buf->cur == NULL || buf->rlimit == NULL) {
7770     return EOF;
7771   }
7772
7773   if (buf->cur < buf->rlimit) {
7774     return *(buf->cur);
7775   }
7776
7777   return EOF;
7778 }
7779
7780 bool cppBuffer_isMacro (cppBuffer *buf)
7781 {
7782   if (buf != NULL)
7783     {
7784       return (buf->cleanup == cppReader_macroCleanup);
7785     }
7786
7787   return FALSE;
7788 }
7789
7790 /*
7791 ** Returns true if the macro should be checked, false
7792 ** if it should be expanded normally.
7793 */
7794
7795 static bool notparseable = FALSE;  /* preceeded by @notparseable@ */
7796 static bool notfunction = FALSE;   /* preceeded by @notfunction@ */
7797 static bool expectiter = FALSE;    /* preceeded by @iter@ */
7798 static bool expectenditer = FALSE; /* second after @iter@ */
7799 static bool expectfunction = FALSE;    /* preceeded by @function@ */
7800 static bool expectconstant = FALSE;   /* preceeded by @constant@ */
7801 static bool expectmacro = FALSE;   /* preceeded by notfunction or notparseable */
7802
7803 static void cpp_setLocation (cppReader *pfile)
7804 {
7805   fileId fid;
7806   int line;
7807
7808   if (pfile->buffer != NULL)
7809     {
7810       if (cstring_isDefined (cppReader_getBufferSafe (pfile)->nominal_fname))
7811         {
7812           cstring fname = cppReader_getBufferSafe (pfile)->nominal_fname;
7813           
7814           DPRINTF (("Looking up: %s", fname));
7815           
7816           if (fileTable_exists (context_fileTable (), fname))
7817             {
7818               fid = fileTable_lookup (context_fileTable (), fname);
7819             }
7820           else
7821             {
7822               DPRINTF (("Trying %s", cppReader_getBuffer (pfile)->fname));
7823
7824               fid = fileTable_lookup (context_fileTable (),
7825                                       cppReader_getBufferSafe (pfile)->fname);
7826             }
7827         }
7828       else
7829         {
7830           fid = fileTable_lookup (context_fileTable (),
7831                                   cppReader_getBufferSafe (pfile)->fname);
7832         }
7833       
7834       line = cppReader_getBufferSafe (pfile)->lineno;
7835       fileloc_free (g_currentloc);
7836
7837       if (fileId_isValid (fid))
7838         {
7839           g_currentloc = fileloc_create (fid, line, 1);
7840         }
7841       else
7842         {
7843           g_currentloc = fileloc_createBuiltin ();
7844         }
7845     }
7846   else
7847     {
7848       fileloc_free (g_currentloc);
7849       g_currentloc = fileloc_createBuiltin ();
7850     }
7851 }
7852
7853 static bool cpp_shouldCheckMacro (cppReader *pfile, char *p) /*@modifies p*/
7854 {
7855   bool checkmacro = FALSE;
7856   bool hasParams = FALSE;
7857   bool noexpand = FALSE;
7858   cstring sname;
7859   char c;
7860
7861   cpp_setLocation (pfile);
7862
7863   DPRINTF (("Should check macro? %s", p));
7864
7865   if (expectiter || expectconstant || expectenditer)
7866     {
7867       if (expectiter)
7868         {
7869           expectiter = FALSE;
7870           expectenditer = TRUE;
7871         }
7872       else
7873         {
7874           expectiter = FALSE;
7875           expectconstant = FALSE;
7876           expectenditer = FALSE;
7877         }
7878
7879       if (notfunction || notparseable)
7880         {
7881           notfunction = FALSE;
7882           notparseable = FALSE;
7883           return FALSE;
7884         }
7885       else
7886         {
7887           return TRUE;
7888         }
7889     }
7890
7891   llassert (*p == '#');
7892   p++;
7893
7894   while (*p == ' ' || *p == '\t')
7895     {
7896       p++;
7897     }
7898
7899   llassert (*p == 'd'); /* define starts */
7900
7901   p += 6;
7902
7903   while (*p == ' ' || *p == '\t')
7904     {
7905       p++;
7906     }
7907
7908   sname = cstring_fromChars (p);
7909   DPRINTF (("Check macro: %s", sname));
7910
7911   while (((c = *p) != ' ')
7912          && c != '\0' && c != '('
7913          && c != '\t' && c != '\\' && c != '\n'
7914          && !iscntrl (c))
7915     {
7916       p++;
7917     }
7918
7919   hasParams = (c == '(');
7920   *p = '\0';
7921
7922   if (notparseable)
7923     {
7924       notparseable = FALSE;
7925     }
7926   else if (notfunction || fileloc_isStandardLib (g_currentloc))
7927     {
7928       DPRINTF (("Clear notfunction"));
7929       notfunction = FALSE;
7930     }
7931   else
7932     {
7933       if (noexpand)
7934         {
7935           checkmacro = TRUE;
7936
7937           if (!expectenditer)
7938             {
7939               noexpand = FALSE;
7940             }
7941         }
7942       else
7943         {
7944           if (usymtab_existsReal (sname))
7945             {
7946               uentry ue = usymtab_lookup (sname);
7947
7948               DPRINTF (("Lookup macro: %s", uentry_unparse (ue)));
7949
7950               if (fileloc_isPreproc (uentry_whereLast (ue)))
7951                 {
7952                   goto macroDne;
7953                 }
7954               else
7955                 {
7956                   if (uentry_isSpecified (ue))
7957                     {
7958                       checkmacro = context_getFlag (FLG_SPECMACROS);
7959                     }
7960                   else
7961                     {
7962                       if (hasParams)
7963                         {
7964                           checkmacro = context_getFlag (FLG_LIBMACROS)
7965                             || context_getFlag (FLG_FCNMACROS);
7966                         }
7967                     }
7968                 }
7969             }
7970           else
7971             {
7972             macroDne:
7973               DPRINTF (("Macro doesn't exist: %s", bool_unparse (checkmacro)));
7974
7975               if (fileloc_isSystemFile (g_currentloc)
7976                   && context_getFlag (FLG_SYSTEMDIREXPAND))
7977                 {
7978                   ; /* don't check this macro */
7979                   DPRINTF (("Don't check 1"));
7980                 }
7981               else
7982                 {
7983                   uentry le;
7984                   
7985                   if (hasParams)
7986                     {
7987                       DPRINTF (("Has params..."));
7988
7989                       if (context_getFlag (FLG_FCNMACROS))
7990                         {
7991                           if (usymtab_exists (sname))
7992                             {
7993                               /*
7994                               ** only get here is macro is redefined
7995                               ** error reported elsewhere
7996                               */
7997
7998                               DPRINTF (("It exists!"));
7999                             }
8000                           else
8001                             {
8002                               /*
8003                               ** We make it a forward function, since it might be declared elsewhere.
8004                               ** After all headers have been processed, we should check the forward
8005                               ** functions.
8006                               */
8007
8008                               fileloc loc = fileloc_makePreproc (g_currentloc);
8009
8010                               /* the line is off-by-one, since the newline was already read */
8011                               decLine ();
8012
8013                               if (expectfunction)
8014                                 {
8015                                   expectfunction = FALSE;
8016                                 }
8017
8018                               le = uentry_makeForwardFunction (sname,
8019                                                                typeId_invalid, loc);
8020
8021                               fileloc_free (loc);
8022
8023                               incLine ();
8024
8025                               /* Do not define here! */
8026
8027                               (void) usymtab_addEntry (le);
8028                             }
8029
8030                           checkmacro = TRUE;
8031                           DPRINTF (("Check: TRUE"));
8032                         }
8033                       else 
8034                         {
8035                           DPRINTF (("Flag FCN_MACROS not set!"));
8036                         }
8037                     }
8038                   else
8039                     {
8040                       DPRINTF (("No params"));
8041
8042                       if (context_getFlag (FLG_CONSTMACROS))
8043                         {
8044                           bool nocontent = FALSE;
8045
8046                           if (c == '\0')
8047                             {
8048                               nocontent = TRUE;
8049                             }
8050                           else
8051                             {
8052                               if (isspace (c))
8053                                 {
8054                                   char *rest = p + 1;
8055
8056                                   /*
8057                                   ** Check if there is nothing after the define.
8058                                   */
8059
8060                                   while ((*rest) != '\0' && isspace (*rest))
8061                                     {
8062                                       rest++;
8063                                     }
8064
8065                                   if (*rest == '\0')
8066                                     {
8067                                       nocontent = TRUE; /* empty macro, don't check */
8068                                     }
8069                                 }
8070                             }
8071
8072                           if (usymtab_exists (sname))
8073                             {
8074                               ;
8075                             }
8076                           else
8077                             {
8078                               fileloc loc = fileloc_makePreproc (g_currentloc);
8079                               DPRINTF (("Make constant: %s", sname));
8080                               le = uentry_makeMacroConstant (sname, ctype_unknown, loc);
8081                               (void) usymtab_addEntry (le);
8082                             }
8083
8084                           checkmacro = !nocontent;
8085                         }
8086                     }
8087                 }
8088
8089               if (checkmacro && usymtab_existsType (sname))
8090                 {
8091                   DPRINTF (("Making false..."));
8092                   decLine ();
8093                   ppllerror (message ("Specified type implemented as macro: %s", sname));
8094                   checkmacro = FALSE;
8095                   incLine ();
8096                 }
8097             }
8098         }
8099     }
8100
8101   if (!checkmacro)
8102     {
8103       if (usymtab_exists (sname))
8104         {
8105           uentry ue = usymtab_lookupExpose (sname);
8106           fileloc tloc = fileloc_makePreproc (g_currentloc);
8107
8108           uentry_setDefined (ue, tloc);
8109           fileloc_free (tloc);
8110           uentry_setUsed (ue, fileloc_undefined);
8111         }
8112       else
8113         {
8114           fileloc tloc = fileloc_makePreproc (g_currentloc);
8115           uentry ue = uentry_makeExpandedMacro (sname, tloc);
8116           DPRINTF (("Make expanded macro: %s", sname));
8117           DPRINTF (("Not in symbol table: %s", sname));
8118           
8119           (void) usymtab_addGlobalEntry (ue);
8120           fileloc_free (tloc);
8121         }
8122     }
8123
8124   *p = c;
8125   DPRINTF (("Returning: %s", bool_unparse (checkmacro)));
8126   return checkmacro;
8127 }
8128
8129 static enum cpp_token
8130 cpp_handleComment (cppReader *pfile, struct parse_marker *smark)
8131 {
8132   cppBuffer *pbuf = cppReader_getBufferSafe (pfile);
8133   char *start;
8134   int len;
8135   fileloc loc;
8136   bool eliminateComment = FALSE;
8137
8138   llassert (pbuf->buf != NULL);
8139
8140   start = pbuf->buf + smark->position;
8141
8142   llassert (pbuf->cur != NULL);
8143   len = pbuf->cur - start;
8144
8145   if (start[0] == '*'
8146       && start[1] == context_getCommentMarkerChar ())
8147     {
8148       int i;
8149       char c = ' ';
8150       char *scomment = start + 2;
8151       char savec = start[len];
8152       
8153       cpp_setLocation (pfile);
8154       loc = fileloc_copy (g_currentloc);
8155
8156       start[0] = BEFORE_COMMENT_MARKER[0];
8157       start[1] = BEFORE_COMMENT_MARKER[1];
8158
8159       llassert (start[len - 2] == '*');
8160       start[len - 2] = AFTER_COMMENT_MARKER[0];
8161
8162       llassert (start[len - 1] == '/');
8163       start[len - 1] = AFTER_COMMENT_MARKER[1];
8164
8165       cpplib_reserve(pfile, size_fromInt (1 + len));
8166       cppReader_putCharQ (pfile, c);
8167
8168       cpp_setLocation (pfile);
8169
8170       start[len] = '\0';
8171
8172       if (mstring_containsString (scomment, "/*"))
8173         {
8174           (void) cppoptgenerror 
8175             (FLG_NESTCOMMENT,
8176              message ("Comment starts inside syntactic comment: %s", 
8177                       cstring_fromChars (scomment)),
8178              pfile);
8179         }
8180
8181       start[len] = savec;
8182
8183       if (mstring_equalPrefix (scomment, "ignore"))
8184         {
8185           if (!context_getFlag (FLG_NOCOMMENTS))
8186             {
8187               context_enterSuppressRegion (loc);
8188             }
8189         }
8190       else if (mstring_equalPrefix (scomment, "end"))
8191         {
8192           if (!context_getFlag (FLG_NOCOMMENTS))
8193             {
8194               context_exitSuppressRegion (loc);
8195             }
8196         }
8197       else if (mstring_equalPrefix (scomment, "notparseable"))
8198         {
8199           notparseable = TRUE;
8200           expectmacro = TRUE;
8201           eliminateComment = TRUE;
8202         }
8203       else if (mstring_equalPrefix (scomment, "notfunction"))
8204         {
8205           notfunction = TRUE;
8206           expectmacro = TRUE;
8207           eliminateComment = TRUE;
8208         }
8209       else if (mstring_equalPrefix (scomment, "iter"))
8210         {
8211           expectiter = TRUE;
8212         }
8213       else if (mstring_equalPrefix (scomment, "function"))
8214         {
8215           expectfunction = TRUE;
8216         }
8217       else if (mstring_equalPrefix (scomment, "constant"))
8218         {
8219           expectconstant = TRUE;
8220         }
8221       else
8222         {
8223           char sChar = *scomment;
8224
8225           if (sChar == '='
8226               || sChar == '-'
8227               || sChar == '+')
8228             {
8229               char *rest = scomment + 1;
8230
8231               if (mstring_equalPrefix (rest, "commentchar"))
8232                 {
8233                   eliminateComment = TRUE;
8234
8235                   if (sChar == '=')
8236                     {
8237                       ppllerror (cstring_makeLiteral
8238                                  ("Cannot restore commentchar"));
8239                     }
8240                   else
8241                     {
8242                       char *next = scomment + 12; /* strlen commentchar = 12 */
8243
8244                       if (*next != ' ' && *next != '\t' && *next != '\n')
8245                         {
8246                           ppllerror
8247                             (message
8248                              ("Syntactic commentchar comment is not followed by a "
8249                               "whitespace character: %c",
8250                               *next));
8251                         }
8252                       else
8253                         {
8254                           char cchar = *(next + 1);
8255
8256                           if (cchar == '\0')
8257                             {
8258                               ppllerror
8259                                 (cstring_makeLiteral
8260                                  ("Cannot set commentchar to NUL"));
8261                             }
8262                           else
8263                             {
8264                               context_setCommentMarkerChar (cchar);
8265                               /* setComment = TRUE; */
8266                             }
8267                         }
8268                     }
8269                 }
8270               else if (mstring_equalPrefix (scomment, "nestcomment"))
8271                 {
8272                   /* fix from Mike Miller <MikeM@xata.com> */
8273                   context_fileSetFlag (FLG_NESTCOMMENT,
8274                                        ynm_fromCodeChar (sChar),
8275                                        loc);
8276                 }
8277               else if (mstring_equalPrefix (rest, "namechecks"))
8278                 {
8279                   context_fileSetFlag (FLG_NAMECHECKS,
8280                                        ynm_fromCodeChar (sChar),
8281                                        loc);
8282                 }
8283               else if (mstring_equalPrefix (rest, "macroredef"))
8284                 {
8285                   context_fileSetFlag (FLG_MACROREDEF,
8286                                        ynm_fromCodeChar (sChar),
8287                                        loc);
8288                 }
8289               else if (mstring_equalPrefix (rest, "usevarargs"))
8290                 {
8291                   context_fileSetFlag (FLG_USEVARARGS,
8292                                        ynm_fromCodeChar (sChar),
8293                                        loc);
8294                 }
8295               else if (mstring_equalPrefix (rest, "nextlinemacros"))
8296                 {
8297                   context_fileSetFlag (FLG_MACRONEXTLINE,
8298                                        ynm_fromCodeChar (sChar),
8299                                        loc);
8300                 }
8301               else if (mstring_equalPrefix (rest, "allmacros")
8302                        || mstring_equalPrefix (rest, "fcnmacros")
8303                        || mstring_equalPrefix (rest, "constmacros"))
8304                 {
8305                   flagcode fl;
8306
8307                   if (mstring_equalPrefix (rest, "allmacros"))
8308                     {
8309                       fl = FLG_ALLMACROS;
8310                     }
8311                   else if (mstring_equalPrefix (rest, "fcnmacros"))
8312                     {
8313                       fl = FLG_FCNMACROS;
8314                     }
8315                   else
8316                     {
8317                       llassert (mstring_equalPrefix (rest, "constmacros"));
8318                       fl = FLG_CONSTMACROS;
8319                     }
8320
8321                   context_fileSetFlag (fl, ynm_fromCodeChar (sChar), loc);
8322                   notfunction = FALSE;
8323                 }
8324               else
8325                 {
8326                   ;
8327                 }
8328             }
8329           else
8330             {
8331               ;
8332             }
8333         }
8334
8335       if (eliminateComment)
8336         {
8337           goto removeComment;
8338         }
8339
8340       /* Replaces comment char's in start with spaces */
8341
8342       for (i = 2; i < len - 2; i++)
8343         {
8344           if (start[i] == BEFORE_COMMENT_MARKER[0]
8345               || start[i] == BEFORE_COMMENT_MARKER[1]
8346               || start[i] == context_getCommentMarkerChar ())
8347             {
8348               start[i] = ' ';
8349             }
8350         }
8351
8352       cppReader_putStrN (pfile, start, size_fromInt (len));
8353       parseClearMark (smark);
8354       return CPP_COMMENT;
8355     }
8356   else
8357     {
8358     removeComment:
8359       {
8360         int i;
8361
8362         /*
8363         ** Output the comment as all spaces so line/column
8364         ** in output file is still correct.
8365         */
8366
8367         char c = ' ';
8368         cstring lintcomment = cstring_undefined;
8369
8370         if (context_getFlag (FLG_LINTCOMMENTS))
8371           {
8372             if (mstring_equalPrefix (start, "*NOTREACHED*/"))
8373               {
8374                 lintcomment = cstring_makeLiteralTemp ("l_notreach");
8375               }
8376             else if (mstring_equalPrefix (start, "*PRINTFLIKE*/"))
8377               {
8378                 lintcomment = cstring_makeLiteralTemp ("l_printfli");
8379               }
8380             else if (mstring_equalPrefix (start, "*FALLTHROUGH*/"))
8381               {
8382                 lintcomment = cstring_makeLiteralTemp ("l_fallthrou");
8383               }
8384             else if (mstring_equalPrefix (start, "*ARGSUSED*/"))
8385               {
8386                 lintcomment = cstring_makeLiteralTemp ("l_argsus");
8387               }
8388             else if (mstring_equalPrefix (start, "*FALLTHRU*/"))
8389               {
8390                 lintcomment = cstring_makeLiteralTemp ("l_fallth");
8391               }
8392             else
8393               {
8394                 lintcomment = cstring_undefined;
8395               }
8396           }
8397         else
8398           {
8399             lintcomment = cstring_undefined;
8400           }
8401
8402         if (cstring_isDefined (lintcomment))
8403           {
8404             c = BEFORE_COMMENT_MARKER[0];
8405             start[0] = BEFORE_COMMENT_MARKER[1];
8406
8407             llassert (size_toLong (cstring_length (lintcomment)) == len - 3);
8408
8409             for (i = 1; i < len - 2; i++)
8410               {
8411                 start[i] = cstring_getChar (lintcomment, size_fromInt (i));
8412               }
8413             
8414             start[len - 2] = AFTER_COMMENT_MARKER[0];
8415             start[len - 1] = AFTER_COMMENT_MARKER[1];
8416           }
8417         else
8418           {
8419             /* Replaces  char's in start with spaces */
8420             for (i = 0; i < len; i++)
8421               {
8422                 if (start[i] == '/'
8423                     && i < len - 1
8424                     && start[i + 1] == '*') {
8425                   (void) cppoptgenerror 
8426                     (FLG_NESTCOMMENT,
8427                      message ("Comment starts inside comment"),
8428                      pfile);
8429                 }
8430                 
8431                 if (start[i] != '\n')
8432                   {
8433                     start[i] = ' ';
8434                   }
8435               }
8436           }
8437
8438         cpplib_reserve (pfile, size_fromInt (1 + len));
8439         cppReader_putCharQ (pfile, c);
8440         cppReader_putStrN (pfile, start, size_fromInt (len));
8441         parseClearMark (smark);
8442         return CPP_COMMENT;
8443       }
8444     }
8445 }
8446
8447 static int cpp_openIncludeFile (char *filename)
8448 {
8449   int res = open (filename, O_RDONLY, 0666);
8450
8451   /* evans 2001-08-23: was (res) - open returns -1 on error! reported by Robin Watts */
8452   if (res >= 0)
8453     {
8454       if (!fileTable_exists (context_fileTable (),
8455                              cstring_fromChars (filename)))
8456         {
8457           if (fileloc_isXHFile (g_currentloc))
8458             {
8459               /*
8460               ** Files includes by XH files are also XH files
8461               */
8462
8463               (void) fileTable_addXHFile (context_fileTable (),
8464                                           cstring_fromChars (filename));
8465             }
8466           else
8467             {
8468               (void) fileTable_addHeaderFile (context_fileTable (),
8469                                               cstring_fromChars (filename));
8470             }
8471         }
8472       else
8473         {
8474           DPRINTF (("File already exists: %s", filename));
8475         }
8476     }
8477
8478   return res;
8479 }
8480
8481 static bool cpp_skipIncludeFile (cstring fname)
8482 {
8483   if (context_isSystemDir (fname))
8484     {
8485       DPRINTF (("System dir: %s", fname));
8486
8487       if (lcllib_isSkipHeader (fname))
8488         {
8489           DPRINTF (("Skip include TRUE: %s", fname));
8490           return TRUE;
8491         }
8492       
8493       if (context_getFlag (FLG_SKIPSYSHEADERS))
8494         {
8495           /*
8496           ** 2003-04-18: Patch from Randal Parsons
8497           */
8498
8499           /*
8500           ** Don't skip include file unless the file actually exists.  
8501           ** It may be in a different directory.
8502           */
8503
8504           int f = open (cstring_toCharsSafe (fname), O_RDONLY, 0666);
8505
8506           if (f >= 0)
8507             {
8508               check (close (f) == 0);
8509               DPRINTF (("Skip include TRUE: %s", fname));
8510               return TRUE;
8511             }
8512           else
8513             {
8514               /* Keep looking... */
8515             }
8516         }
8517     }
8518
8519   if (context_getFlag (FLG_SINGLEINCLUDE))
8520     {
8521       fname = removePreDirs (fname);
8522
8523 # if defined (WIN32) || defined (OS2)
8524       cstring_replaceAll (fname, '\\', '/');
8525 # endif
8526
8527       if (fileTable_exists (context_fileTable (), fname))
8528         {
8529           DPRINTF (("Skip include TRUE: %s", fname));
8530           return TRUE;
8531         }
8532     }
8533
8534   DPRINTF (("Skip include FALSE: %s", fname));
8535   return FALSE;
8536 }
8537
8538 static int cpp_peekN (cppReader *pfile, int n)
8539 {
8540   cppBuffer *buf = cppReader_getBufferSafe (pfile);
8541
8542   llassert (buf->cur != NULL);
8543
8544   return (buf->rlimit - buf->cur >= (n)
8545           ? buf->cur[n]
8546           : EOF);
8547 }
8548
8549 cppBuffer *cppBuffer_prevBuffer (cppBuffer *buf)
8550 {
8551   return buf + 1;
8552 }
8553
8554 void cppBuffer_forward (cppBuffer *buf, int n)
8555 {
8556   llassert (buf->cur != NULL);
8557   buf->cur += n;
8558 }
8559
8560 /*@=bufferoverflowhigh@*/
8561 /*@=bounds@*/
This page took 0.778278 seconds and 3 git commands to generate.