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