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