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