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