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