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