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