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