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