4.4BSD snapshot (revision 8.1)
[unix-history] / usr / src / contrib / gcc-2.3.3 / cccp.c
CommitLineData
96f57f70
EA
1/* C Compatible Compiler Preprocessor (CCCP)
2Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
3 Written by Paul Rubin, June 1986
4 Adapted to ANSI C, Richard Stallman, Jan 1987
5
6This program is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding! */
23\f
24typedef unsigned char U_CHAR;
25
26#ifdef EMACS
27#define NO_SHORTNAMES
28#include "../src/config.h"
29#ifdef open
30#undef open
31#undef read
32#undef write
33#endif /* open */
34#endif /* EMACS */
35
36/* The macro EMACS is defined when cpp is distributed as part of Emacs,
37 for the sake of machines with limited C compilers. */
38#ifndef EMACS
39#include "config.h"
40#endif /* not EMACS */
41
42#ifndef STANDARD_INCLUDE_DIR
43#define STANDARD_INCLUDE_DIR "/usr/include"
44#endif
45
46#ifndef LOCAL_INCLUDE_DIR
47#define LOCAL_INCLUDE_DIR "/usr/local/include"
48#endif
49
50#if 0 /* We can't get ptrdiff_t, so I arranged not to need PTR_INT_TYPE. */
51#ifdef __STDC__
52#define PTR_INT_TYPE ptrdiff_t
53#else
54#define PTR_INT_TYPE long
55#endif
56#endif /* 0 */
57
58#include "pcp.h"
59
60#ifndef STDC_VALUE
61#define STDC_VALUE 1
62#endif
63
64/* By default, colon separates directories in a path. */
65#ifndef PATH_SEPARATOR
66#define PATH_SEPARATOR ':'
67#endif
68
69/* In case config.h defines these. */
70#undef bcopy
71#undef bzero
72#undef bcmp
73
74#include <sys/types.h>
75#include <sys/stat.h>
76#include <ctype.h>
77#include <stdio.h>
78
79#ifndef VMS
80#ifndef USG
81#include <sys/time.h> /* for __DATE__ and __TIME__ */
82#include <sys/resource.h>
83#else
84#include <time.h>
85#include <fcntl.h>
86#endif /* USG */
87#endif /* not VMS */
88
89/* VMS-specific definitions */
90#ifdef VMS
91#include <time.h>
92#include <errno.h> /* This defines "errno" properly */
93#include <perror.h> /* This defines sys_errlist/sys_nerr properly */
94#include <descrip.h>
95#define O_RDONLY 0 /* Open arg for Read/Only */
96#define O_WRONLY 1 /* Open arg for Write/Only */
97#define read(fd,buf,size) VMS_read(fd,buf,size)
98#define write(fd,buf,size) VMS_write(fd,buf,size)
99#define open(fname,mode,prot) VMS_open(fname,mode,prot)
100#define fopen(fname,mode) VMS_fopen(fname,mode)
101#define freopen(fname,mode,ofile) VMS_freopen(fname,mode,ofile)
102#define strncat(dst,src,cnt) VMS_strncat(dst,src,cnt)
103static char * VMS_strncat ();
104static int VMS_read ();
105static int VMS_write ();
106static int VMS_open ();
107static FILE * VMS_fopen ();
108static FILE * VMS_freopen ();
109static void hack_vms_include_specification ();
110typedef struct { unsigned :16, :16, :16; } vms_ino_t;
111#define ino_t vms_ino_t
112#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */
113#ifdef __GNUC__
114#define BSTRING /* VMS/GCC supplies the bstring routines */
115#endif /* __GNUC__ */
116#endif /* VMS */
117
118extern char *index ();
119extern char *rindex ();
120
121#ifndef O_RDONLY
122#define O_RDONLY 0
123#endif
124
125#undef MIN
126#undef MAX
127#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
128#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
129
130/* Find the largest host integer type and set its size and type. */
131
132#ifndef HOST_BITS_PER_WIDE_INT
133
134#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
135#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
136#define HOST_WIDE_INT long
137#else
138#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
139#define HOST_WIDE_INT int
140#endif
141
142#endif
143
144#ifndef S_ISREG
145#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
146#endif
147
148/* Define a generic NULL if one hasn't already been defined. */
149
150#ifndef NULL
151#define NULL 0
152#endif
153
154#ifndef GENERIC_PTR
155#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
156#define GENERIC_PTR void *
157#else
158#define GENERIC_PTR char *
159#endif
160#endif
161
162#ifndef NULL_PTR
163#define NULL_PTR ((GENERIC_PTR)0)
164#endif
165
166#ifndef INCLUDE_LEN_FUDGE
167#define INCLUDE_LEN_FUDGE 0
168#endif
169
170/* Forward declarations. */
171
172char *xmalloc ();
173void error ();
174void warning ();
175
176/* External declarations. */
177
178extern char *getenv ();
179extern FILE *fdopen ();
180extern char *version_string;
181extern struct tm *localtime ();
182extern int sys_nerr;
b8422c67 183extern const char *const sys_errlist[];
96f57f70
EA
184
185#ifndef errno
186extern int errno;
187#endif
188
189/* Forward declarations. */
190
191struct directive;
192struct file_buf;
193struct arglist;
194struct argdata;
195
196#if defined(USG) || defined(VMS)
197#ifndef BSTRING
198void bcopy ();
199void bzero ();
200int bcmp ();
201#endif
202#endif
203
204/* These functions are declared to return int instead of void since they
205 are going to be placed in a table and some old compilers have trouble with
206 pointers to functions returning void. */
207
208static int do_define ();
209static int do_line ();
210static int do_include ();
211static int do_undef ();
212static int do_error ();
213static int do_pragma ();
214static int do_ident ();
215static int do_if ();
216static int do_xifdef ();
217static int do_else ();
218static int do_elif ();
219static int do_endif ();
220static int do_sccs ();
221static int do_once ();
222static int do_assert ();
223static int do_unassert ();
224static int do_warning ();
225
226static void add_import ();
227static void append_include_chain ();
228static void deps_output ();
229static void make_undef ();
230static void make_definition ();
231static void make_assertion ();
232static void path_include ();
233static void initialize_builtins ();
234static void initialize_char_syntax ();
235static void dump_arg_n ();
236static void dump_defn_1 ();
237static void delete_macro ();
238static void trigraph_pcp ();
239static void rescan ();
240static void finclude ();
241static void validate_else ();
242static int comp_def_part ();
243static void error_from_errno ();
244static void error_with_line ();
245void pedwarn ();
246static void pedwarn_with_file_and_line ();
247static void fatal ();
248void fancy_abort ();
249static void pfatal_with_name ();
250static void perror_with_name ();
251static void print_containing_files ();
252static int lookup_import ();
253static int redundant_include_p ();
254static is_system_include ();
255static int check_preconditions ();
256static void pcfinclude ();
257static void pcstring_used ();
258static void write_output ();
259static int check_macro_name ();
260static int compare_defs ();
261static int compare_token_lists ();
262static int eval_if_expression ();
263static int discard_comments ();
264static int delete_newlines ();
265static int line_for_error ();
266static int hashf ();
267static int file_size_and_mode ();
268
269static struct arglist *read_token_list ();
270static void free_token_list ();
271
272static struct hashnode *install ();
273struct hashnode *lookup ();
274
275static struct assertion_hashnode *assertion_install ();
276static struct assertion_hashnode *assertion_lookup ();
277
278static char *xrealloc ();
279static char *xcalloc ();
280static char *savestring ();
281
282static void delete_assertion ();
283static void macroexpand ();
284static void dump_all_macros ();
285static void conditional_skip ();
286static void skip_if_group ();
287static void output_line_command ();
288
289/* Last arg to output_line_command. */
290enum file_change_code {same_file, enter_file, leave_file};
291
292static int grow_outbuf ();
293static int handle_directive ();
294static void memory_full ();
295
296static U_CHAR *macarg1 ();
297static char *macarg ();
298
299static U_CHAR *skip_to_end_of_comment ();
300static U_CHAR *skip_quoted_string ();
301static U_CHAR *skip_paren_group ();
302
303static char *check_precompiled ();
304/* static struct macrodef create_definition (); [moved below] */
305static void dump_single_macro ();
306\f
307#ifndef FAILURE_EXIT_CODE
308#define FAILURE_EXIT_CODE 33 /* gnu cc command understands this */
309#endif
310
311#ifndef SUCCESS_EXIT_CODE
312#define SUCCESS_EXIT_CODE 0 /* 0 means success on Unix. */
313#endif
314
315/* Name under which this program was invoked. */
316
317static char *progname;
318
319/* Nonzero means use extra default include directories for C++. */
320
321static int cplusplus;
322
323/* Nonzero means handle cplusplus style comments */
324
325static int cplusplus_comments;
326
327/* Nonzero means handle #import, for objective C. */
328
329static int objc;
330
331/* Nonzero means this is an assembly file, and allow
332 unknown directives, which could be comments. */
333
334static int lang_asm;
335
336/* Current maximum length of directory names in the search path
337 for include files. (Altered as we get more of them.) */
338
339static int max_include_len;
340
341/* Nonzero means turn NOTREACHED into #pragma NOTREACHED etc */
342
343static int lint = 0;
344
345/* Nonzero means copy comments into the output file. */
346
347static int put_out_comments = 0;
348
349/* Nonzero means don't process the ANSI trigraph sequences. */
350
351static int no_trigraphs = 0;
352
353/* Nonzero means print the names of included files rather than
354 the preprocessed output. 1 means just the #include "...",
355 2 means #include <...> as well. */
356
357static int print_deps = 0;
358
359/* Nonzero means print names of header files (-H). */
360
361static int print_include_names = 0;
362
363/* Nonzero means don't output line number information. */
364
365static int no_line_commands;
366
367/* dump_only means inhibit output of the preprocessed text
368 and instead output the definitions of all user-defined
369 macros in a form suitable for use as input to cccp.
370 dump_names means pass #define and the macro name through to output.
371 dump_definitions means pass the whole definition (plus #define) through
372*/
373
374static enum {dump_none, dump_only, dump_names, dump_definitions}
375 dump_macros = dump_none;
376
377/* Nonzero means pass all #define and #undef directives which we actually
378 process through to the output stream. This feature is used primarily
379 to allow cc1 to record the #defines and #undefs for the sake of
380 debuggers which understand about preprocessor macros, but it may
381 also be useful with -E to figure out how symbols are defined, and
382 where they are defined. */
383static int debug_output = 0;
384
385/* Nonzero indicates special processing used by the pcp program. The
386 special effects of this mode are:
387
388 Inhibit all macro expansion, except those inside #if directives.
389
390 Process #define directives normally, and output their contents
391 to the output file.
392
393 Output preconditions to pcp_outfile indicating all the relevant
394 preconditions for use of this file in a later cpp run.
395*/
396static FILE *pcp_outfile;
397
398/* Nonzero means we are inside an IF during a -pcp run. In this mode
399 macro expansion is done, and preconditions are output for all macro
400 uses requiring them. */
401static int pcp_inside_if;
402
403/* Nonzero means never to include precompiled files. */
404static int no_precomp;
405
406/* Nonzero means give all the error messages the ANSI standard requires. */
407
408int pedantic;
409
410/* Nonzero means try to make failure to fit ANSI C an error. */
411
412static int pedantic_errors;
413
414/* Nonzero means don't print warning messages. -w. */
415
416static int inhibit_warnings = 0;
417
418/* Nonzero means warn if slash-star appears in a comment. */
419
420static int warn_comments;
421
422/* Nonzero means warn if a macro argument is (or would be)
423 stringified with -traditional. */
424
425static int warn_stringify;
426
427/* Nonzero means warn if there are any trigraphs. */
428
429static int warn_trigraphs;
430
431/* Nonzero means warn if #import is used. */
432
433static int warn_import = 1;
434
435/* Nonzero means turn warnings into errors. */
436
437static int warnings_are_errors;
438
439/* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
440
441int traditional;
442
443/* Nonzero causes output not to be done,
444 but directives such as #define that have side effects
445 are still obeyed. */
446
447static int no_output;
448
449/* Nonzero means that we have finished processing the command line options.
450 This flag is used to decide whether or not to issue certain errors
451 and/or warnings. */
452
453static int done_initializing = 0;
454\f
455/* I/O buffer structure.
456 The `fname' field is nonzero for source files and #include files
457 and for the dummy text used for -D and -U.
458 It is zero for rescanning results of macro expansion
459 and for expanding macro arguments. */
460#define INPUT_STACK_MAX 200
461static struct file_buf {
462 char *fname;
463 /* Filename specified with #line command. */
464 char *nominal_fname;
465 /* Record where in the search path this file was found.
466 For #include_next. */
467 struct file_name_list *dir;
468 int lineno;
469 int length;
470 U_CHAR *buf;
471 U_CHAR *bufp;
472 /* Macro that this level is the expansion of.
473 Included so that we can reenable the macro
474 at the end of this level. */
475 struct hashnode *macro;
476 /* Value of if_stack at start of this file.
477 Used to prohibit unmatched #endif (etc) in an include file. */
478 struct if_stack *if_stack;
479 /* Object to be freed at end of input at this level. */
480 U_CHAR *free_ptr;
481 /* True if this is a header file included using <FILENAME>. */
482 char system_header_p;
483} instack[INPUT_STACK_MAX];
484
485static int last_error_tick; /* Incremented each time we print it. */
486static int input_file_stack_tick; /* Incremented when the status changes. */
487
488/* Current nesting level of input sources.
489 `instack[indepth]' is the level currently being read. */
490static int indepth = -1;
491#define CHECK_DEPTH(code) \
492 if (indepth >= (INPUT_STACK_MAX - 1)) \
493 { \
494 error_with_line (line_for_error (instack[indepth].lineno), \
495 "macro or `#include' recursion too deep"); \
496 code; \
497 }
498
499/* Current depth in #include directives that use <...>. */
500static int system_include_depth = 0;
501
502typedef struct file_buf FILE_BUF;
503
504/* The output buffer. Its LENGTH field is the amount of room allocated
505 for the buffer, not the number of chars actually present. To get
506 that, subtract outbuf.buf from outbuf.bufp. */
507
508#define OUTBUF_SIZE 10 /* initial size of output buffer */
509static FILE_BUF outbuf;
510
511/* Grow output buffer OBUF points at
512 so it can hold at least NEEDED more chars. */
513
514#define check_expand(OBUF, NEEDED) \
515 (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \
516 ? grow_outbuf ((OBUF), (NEEDED)) : 0)
517
518struct file_name_list
519 {
520 struct file_name_list *next;
521 char *fname;
522 /* If the following is nonzero, it is a macro name.
523 Don't include the file again if that macro is defined. */
524 U_CHAR *control_macro;
525 };
526
527/* #include "file" looks in source file dir, then stack. */
528/* #include <file> just looks in the stack. */
529/* -I directories are added to the end, then the defaults are added. */
530static struct default_include { char *fname; int cplusplus; } include_defaults_array[]
531#ifdef INCLUDE_DEFAULTS
532 = INCLUDE_DEFAULTS;
533#else
534 = {
535 /* Pick up GNU C++ specific include files. */
536 { GPLUSPLUS_INCLUDE_DIR, 1},
537 { GCC_INCLUDE_DIR, 0},
538#ifdef CROSS_COMPILE
539 /* For cross-compilation, this dir name is generated
540 automatically in Makefile.in. */
541 { CROSS_INCLUDE_DIR, 0 },
542#else /* not CROSS_COMPILE */
543 { LOCAL_INCLUDE_DIR, 0},
544 /* Some systems have an extra dir of include files. */
545#ifdef SYSTEM_INCLUDE_DIR
546 { SYSTEM_INCLUDE_DIR, 0},
547#endif
548 { STANDARD_INCLUDE_DIR, 0},
549#endif /* not CROSS_COMPILE */
550 { 0, 0}
551 };
552#endif /* no INCLUDE_DEFAULTS */
553
554/* The code looks at the defaults through this pointer, rather than through
555 the constant structure above. This pointer gets changed if an environment
556 variable specifies other defaults. */
557static struct default_include *include_defaults = include_defaults_array;
558
559static struct file_name_list *include = 0; /* First dir to search */
560 /* First dir to search for <file> */
561/* This is the first element to use for #include <...>.
562 If it is 0, use the entire chain for such includes. */
563static struct file_name_list *first_bracket_include = 0;
564/* This is the first element in the chain that corresponds to
565 a directory of system header files. */
566static struct file_name_list *first_system_include = 0;
567static struct file_name_list *last_include = 0; /* Last in chain */
568
569/* Chain of include directories to put at the end of the other chain. */
570static struct file_name_list *after_include = 0;
571static struct file_name_list *last_after_include = 0; /* Last in chain */
572
573/* List of included files that contained #pragma once. */
574static struct file_name_list *dont_repeat_files = 0;
575
576/* List of other included files.
577 If ->control_macro if nonzero, the file had a #ifndef
578 around the entire contents, and ->control_macro gives the macro name. */
579static struct file_name_list *all_include_files = 0;
580
581/* Directory prefix that should replace `/usr' in the standard
582 include file directories. */
583static char *include_prefix;
584
585/* Global list of strings read in from precompiled files. This list
586 is kept in the order the strings are read in, with new strings being
587 added at the end through stringlist_tailp. We use this list to output
588 the strings at the end of the run.
589*/
590static STRINGDEF *stringlist;
591static STRINGDEF **stringlist_tailp = &stringlist;
592
593
594/* Structure returned by create_definition */
595typedef struct macrodef MACRODEF;
596struct macrodef
597{
598 struct definition *defn;
599 U_CHAR *symnam;
600 int symlen;
601};
602
603static struct macrodef create_definition ();
604
605\f
606/* Structure allocated for every #define. For a simple replacement
607 such as
608 #define foo bar ,
609 nargs = -1, the `pattern' list is null, and the expansion is just
610 the replacement text. Nargs = 0 means a functionlike macro with no args,
611 e.g.,
612 #define getchar() getc (stdin) .
613 When there are args, the expansion is the replacement text with the
614 args squashed out, and the reflist is a list describing how to
615 build the output from the input: e.g., "3 chars, then the 1st arg,
616 then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
617 The chars here come from the expansion. Whatever is left of the
618 expansion after the last arg-occurrence is copied after that arg.
619 Note that the reflist can be arbitrarily long---
620 its length depends on the number of times the arguments appear in
621 the replacement text, not how many args there are. Example:
622 #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
623 pattern list
624 { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
625 where (x, y) means (nchars, argno). */
626
627typedef struct definition DEFINITION;
628struct definition {
629 int nargs;
630 int length; /* length of expansion string */
631 int predefined; /* True if the macro was builtin or */
632 /* came from the command line */
633 U_CHAR *expansion;
634 int line; /* Line number of definition */
635 char *file; /* File of definition */
636 char rest_args; /* Nonzero if last arg. absorbs the rest */
637 struct reflist {
638 struct reflist *next;
639 char stringify; /* nonzero if this arg was preceded by a
640 # operator. */
641 char raw_before; /* Nonzero if a ## operator before arg. */
642 char raw_after; /* Nonzero if a ## operator after arg. */
643 char rest_args; /* Nonzero if this arg. absorbs the rest */
644 int nchars; /* Number of literal chars to copy before
645 this arg occurrence. */
646 int argno; /* Number of arg to substitute (origin-0) */
647 } *pattern;
648 union {
649 /* Names of macro args, concatenated in reverse order
650 with comma-space between them.
651 The only use of this is that we warn on redefinition
652 if this differs between the old and new definitions. */
653 U_CHAR *argnames;
654 } args;
655};
656
657/* different kinds of things that can appear in the value field
658 of a hash node. Actually, this may be useless now. */
659union hashval {
660 int ival;
661 char *cpval;
662 DEFINITION *defn;
663 KEYDEF *keydef;
664};
665
666/*
667 * special extension string that can be added to the last macro argument to
668 * allow it to absorb the "rest" of the arguments when expanded. Ex:
669 * #define wow(a, b...) process(b, a, b)
670 * { wow(1, 2, 3); } -> { process( 2, 3, 1, 2, 3); }
671 * { wow(one, two); } -> { process( two, one, two); }
672 * if this "rest_arg" is used with the concat token '##' and if it is not
673 * supplied then the token attached to with ## will not be outputted. Ex:
674 * #define wow(a, b...) process(b ## , a, ## b)
675 * { wow(1, 2); } -> { process( 2, 1,2); }
676 * { wow(one); } -> { process( one); {
677 */
678static char rest_extension[] = "...";
679#define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1)
680
681/* The structure of a node in the hash table. The hash table
682 has entries for all tokens defined by #define commands (type T_MACRO),
683 plus some special tokens like __LINE__ (these each have their own
684 type, and the appropriate code is run when that type of node is seen.
685 It does not contain control words like "#define", which are recognized
686 by a separate piece of code. */
687
688/* different flavors of hash nodes --- also used in keyword table */
689enum node_type {
690 T_DEFINE = 1, /* the `#define' keyword */
691 T_INCLUDE, /* the `#include' keyword */
692 T_INCLUDE_NEXT, /* the `#include_next' keyword */
693 T_IMPORT, /* the `#import' keyword */
694 T_IFDEF, /* the `#ifdef' keyword */
695 T_IFNDEF, /* the `#ifndef' keyword */
696 T_IF, /* the `#if' keyword */
697 T_ELSE, /* `#else' */
698 T_PRAGMA, /* `#pragma' */
699 T_ELIF, /* `#elif' */
700 T_UNDEF, /* `#undef' */
701 T_LINE, /* `#line' */
702 T_ERROR, /* `#error' */
703 T_WARNING, /* `#warning' */
704 T_ENDIF, /* `#endif' */
705 T_SCCS, /* `#sccs', used on system V. */
706 T_IDENT, /* `#ident', used on system V. */
707 T_ASSERT, /* `#assert', taken from system V. */
708 T_UNASSERT, /* `#unassert', taken from system V. */
709 T_SPECLINE, /* special symbol `__LINE__' */
710 T_DATE, /* `__DATE__' */
711 T_FILE, /* `__FILE__' */
712 T_BASE_FILE, /* `__BASE_FILE__' */
713 T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
714 T_VERSION, /* `__VERSION__' */
715 T_SIZE_TYPE, /* `__SIZE_TYPE__' */
716 T_PTRDIFF_TYPE, /* `__PTRDIFF_TYPE__' */
717 T_WCHAR_TYPE, /* `__WCHAR_TYPE__' */
718 T_TIME, /* `__TIME__' */
719 T_CONST, /* Constant value, used by `__STDC__' */
720 T_MACRO, /* macro defined by `#define' */
721 T_DISABLED, /* macro temporarily turned off for rescan */
722 T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
723 T_PCSTRING, /* precompiled string (hashval is KEYDEF *) */
724 T_UNUSED /* Used for something not defined. */
725 };
726
727struct hashnode {
728 struct hashnode *next; /* double links for easy deletion */
729 struct hashnode *prev;
730 struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
731 chain is kept, in case the node is the head
732 of the chain and gets deleted. */
733 enum node_type type; /* type of special token */
734 int length; /* length of token, for quick comparison */
735 U_CHAR *name; /* the actual name */
736 union hashval value; /* pointer to expansion, or whatever */
737};
738
739typedef struct hashnode HASHNODE;
740
741/* Some definitions for the hash table. The hash function MUST be
742 computed as shown in hashf () below. That is because the rescan
743 loop computes the hash value `on the fly' for most tokens,
744 in order to avoid the overhead of a lot of procedure calls to
745 the hashf () function. Hashf () only exists for the sake of
746 politeness, for use when speed isn't so important. */
747
748#define HASHSIZE 1403
749static HASHNODE *hashtab[HASHSIZE];
750#define HASHSTEP(old, c) ((old << 2) + c)
751#define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */
752
753/* Symbols to predefine. */
754
755#ifdef CPP_PREDEFINES
756static char *predefs = CPP_PREDEFINES;
757#else
758static char *predefs = "";
759#endif
760\f
761/* We let tm.h override the types used here, to handle trivial differences
762 such as the choice of unsigned int or long unsigned int for size_t.
763 When machines start needing nontrivial differences in the size type,
764 it would be best to do something here to figure out automatically
765 from other information what type to use. */
766
767/* The string value for __size_type__. */
768
769#ifndef SIZE_TYPE
770#define SIZE_TYPE "long unsigned int"
771#endif
772
773/* The string value for __ptrdiff_type__. */
774
775#ifndef PTRDIFF_TYPE
776#define PTRDIFF_TYPE "long int"
777#endif
778
779/* The string value for __wchar_type__. */
780
781#ifndef WCHAR_TYPE
782#define WCHAR_TYPE "int"
783#endif
784\f
785/* In the definition of a #assert name, this structure forms
786 a list of the individual values asserted.
787 Each value is itself a list of "tokens".
788 These are strings that are compared by name. */
789
790struct tokenlist_list {
791 struct tokenlist_list *next;
792 struct arglist *tokens;
793};
794
795struct assertion_hashnode {
796 struct assertion_hashnode *next; /* double links for easy deletion */
797 struct assertion_hashnode *prev;
798 /* also, a back pointer to this node's hash
799 chain is kept, in case the node is the head
800 of the chain and gets deleted. */
801 struct assertion_hashnode **bucket_hdr;
802 int length; /* length of token, for quick comparison */
803 U_CHAR *name; /* the actual name */
804 /* List of token-sequences. */
805 struct tokenlist_list *value;
806};
807
808typedef struct assertion_hashnode ASSERTION_HASHNODE;
809
810/* Some definitions for the hash table. The hash function MUST be
811 computed as shown in hashf below. That is because the rescan
812 loop computes the hash value `on the fly' for most tokens,
813 in order to avoid the overhead of a lot of procedure calls to
814 the hashf function. hashf only exists for the sake of
815 politeness, for use when speed isn't so important. */
816
817#define ASSERTION_HASHSIZE 37
818static ASSERTION_HASHNODE *assertion_hashtab[ASSERTION_HASHSIZE];
819
820/* Nonzero means inhibit macroexpansion of what seem to be
821 assertion tests, in rescan. For #if. */
822static int assertions_flag;
823\f
824/* `struct directive' defines one #-directive, including how to handle it. */
825
826struct directive {
827 int length; /* Length of name */
828 int (*func)(); /* Function to handle directive */
829 char *name; /* Name of directive */
830 enum node_type type; /* Code which describes which directive. */
831 char angle_brackets; /* Nonzero => <...> is special. */
832 char traditional_comments; /* Nonzero: keep comments if -traditional. */
833 char pass_thru; /* Copy preprocessed directive to output file. */
834};
835
836/* Here is the actual list of #-directives, most-often-used first. */
837
838static struct directive directive_table[] = {
839 { 6, do_define, "define", T_DEFINE, 0, 1},
840 { 2, do_if, "if", T_IF},
841 { 5, do_xifdef, "ifdef", T_IFDEF},
842 { 6, do_xifdef, "ifndef", T_IFNDEF},
843 { 5, do_endif, "endif", T_ENDIF},
844 { 4, do_else, "else", T_ELSE},
845 { 4, do_elif, "elif", T_ELIF},
846 { 4, do_line, "line", T_LINE},
847 { 7, do_include, "include", T_INCLUDE, 1},
848 { 12, do_include, "include_next", T_INCLUDE_NEXT, 1},
849 { 6, do_include, "import", T_IMPORT, 1},
850 { 5, do_undef, "undef", T_UNDEF},
851 { 5, do_error, "error", T_ERROR},
852 { 7, do_warning, "warning", T_WARNING},
853#ifdef SCCS_DIRECTIVE
854 { 4, do_sccs, "sccs", T_SCCS},
855#endif
856 { 6, do_pragma, "pragma", T_PRAGMA, 0, 0, 1},
857 { 5, do_ident, "ident", T_IDENT, 0, 0, 1},
858 { 6, do_assert, "assert", T_ASSERT},
859 { 8, do_unassert, "unassert", T_UNASSERT},
860 { -1, 0, "", T_UNUSED},
861};
862
863/* When a directive handler is called,
864 this points to the # that started the directive. */
865U_CHAR *directive_start;
866
867/* table to tell if char can be part of a C identifier. */
868U_CHAR is_idchar[256];
869/* table to tell if char can be first char of a c identifier. */
870U_CHAR is_idstart[256];
871/* table to tell if c is horizontal space. */
872U_CHAR is_hor_space[256];
873/* table to tell if c is horizontal or vertical space. */
874static U_CHAR is_space[256];
875
876#define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
877#define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
878
879static int errors = 0; /* Error counter for exit code */
880
881/* Zero means dollar signs are punctuation.
882 -$ stores 0; -traditional may store 1. Default is 1 for VMS, 0 otherwise.
883 This must be 0 for correct processing of this ANSI C program:
884 #define foo(a) #a
885 #define lose(b) foo(b)
886 #define test$
887 lose(test) */
888static int dollars_in_ident;
889#ifndef DOLLARS_IN_IDENTIFIERS
890#define DOLLARS_IN_IDENTIFIERS 1
891#endif
892
893static FILE_BUF expand_to_temp_buffer ();
894
895static DEFINITION *collect_expansion ();
896
897/* Stack of conditionals currently in progress
898 (including both successful and failing conditionals). */
899
900struct if_stack {
901 struct if_stack *next; /* for chaining to the next stack frame */
902 char *fname; /* copied from input when frame is made */
903 int lineno; /* similarly */
904 int if_succeeded; /* true if a leg of this if-group
905 has been passed through rescan */
906 U_CHAR *control_macro; /* For #ifndef at start of file,
907 this is the macro name tested. */
908 enum node_type type; /* type of last directive seen in this group */
909};
910typedef struct if_stack IF_STACK_FRAME;
911static IF_STACK_FRAME *if_stack = NULL;
912
913/* Buffer of -M output. */
914static char *deps_buffer;
915
916/* Number of bytes allocated in above. */
917static int deps_allocated_size;
918
919/* Number of bytes used. */
920static int deps_size;
921
922/* Number of bytes since the last newline. */
923static int deps_column;
924
925/* Nonzero means -I- has been seen,
926 so don't look for #include "foo" the source-file directory. */
927static int ignore_srcdir;
928\f
929int
930main (argc, argv)
931 int argc;
932 char **argv;
933{
934 int st_mode;
935 long st_size;
936 char *in_fname, *out_fname;
937 char *p;
938 int f, i;
939 FILE_BUF *fp;
940 char **pend_files = (char **) xmalloc (argc * sizeof (char *));
941 char **pend_defs = (char **) xmalloc (argc * sizeof (char *));
942 char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
943 char **pend_assertions = (char **) xmalloc (argc * sizeof (char *));
944 char **pend_includes = (char **) xmalloc (argc * sizeof (char *));
945
946 /* Record the option used with each element of pend_assertions.
947 This is preparation for supporting more than one option for making
948 an assertion. */
949 char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *));
950 int inhibit_predefs = 0;
951 int no_standard_includes = 0;
952 int no_standard_cplusplus_includes = 0;
953 int missing_newline = 0;
954
955 /* Non-0 means don't output the preprocessed program. */
956 int inhibit_output = 0;
957
958 /* File name which deps are being written to.
959 This is 0 if deps are being written to stdout. */
960 char *deps_file = 0;
961 /* Stream on which to print the dependency information. */
962 FILE *deps_stream = 0;
963 /* Target-name to write with the dependency information. */
964 char *deps_target = 0;
965
966#ifdef RLIMIT_STACK
967 /* Get rid of any avoidable limit on stack size. */
968 {
969 struct rlimit rlim;
970
971 /* Set the stack limit huge so that alloca (particularly stringtab
972 * in dbxread.c) does not fail. */
973 getrlimit (RLIMIT_STACK, &rlim);
974 rlim.rlim_cur = rlim.rlim_max;
975 setrlimit (RLIMIT_STACK, &rlim);
976 }
977#endif /* RLIMIT_STACK defined */
978
979 progname = argv[0];
980#ifdef VMS
981 {
982 /* Remove directories from PROGNAME. */
983 char *s;
984
985 progname = savestring (argv[0]);
986
987 if (!(s = rindex (progname, ']')))
988 s = rindex (progname, ':');
989 if (s)
990 strcpy (progname, s+1);
991 if (s = rindex (progname, '.'))
992 *s = '\0';
993 }
994#endif
995
996 in_fname = NULL;
997 out_fname = NULL;
998
999 /* Initialize is_idchar to allow $. */
1000 dollars_in_ident = 1;
1001 initialize_char_syntax ();
1002 dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0;
1003
1004 no_line_commands = 0;
1005 no_trigraphs = 1;
1006 dump_macros = dump_none;
1007 no_output = 0;
1008 cplusplus = 0;
1009 cplusplus_comments = 0;
1010
1011 bzero (pend_files, argc * sizeof (char *));
1012 bzero (pend_defs, argc * sizeof (char *));
1013 bzero (pend_undefs, argc * sizeof (char *));
1014 bzero (pend_assertions, argc * sizeof (char *));
1015 bzero (pend_includes, argc * sizeof (char *));
1016
1017 /* Process switches and find input file name. */
1018
1019 for (i = 1; i < argc; i++) {
1020 if (argv[i][0] != '-') {
1021 if (out_fname != NULL)
1022 fatal ("Usage: %s [switches] input output", argv[0]);
1023 else if (in_fname != NULL)
1024 out_fname = argv[i];
1025 else
1026 in_fname = argv[i];
1027 } else {
1028 switch (argv[i][1]) {
1029
1030 case 'i':
1031 if (!strcmp (argv[i], "-include")) {
1032 if (i + 1 == argc)
1033 fatal ("Filename missing after -include option");
1034 else
1035 pend_includes[i] = argv[i+1], i++;
1036 }
1037 if (!strcmp (argv[i], "-imacros")) {
1038 if (i + 1 == argc)
1039 fatal ("Filename missing after -imacros option");
1040 else
1041 pend_files[i] = argv[i+1], i++;
1042 }
1043 if (!strcmp (argv[i], "-iprefix")) {
1044 if (i + 1 == argc)
1045 fatal ("Filename missing after -iprefix option");
1046 else
1047 include_prefix = argv[++i];
1048 }
1049 /* Add directory to end of path for includes. */
1050 if (!strcmp (argv[i], "-idirafter")) {
1051 struct file_name_list *dirtmp;
1052
1053 dirtmp = (struct file_name_list *)
1054 xmalloc (sizeof (struct file_name_list));
1055 dirtmp->next = 0; /* New one goes on the end */
1056 dirtmp->control_macro = 0;
1057 if (i + 1 == argc)
1058 fatal ("Directory name missing after -idirafter option");
1059 else
1060 dirtmp->fname = argv[++i];
1061
1062 if (after_include == 0)
1063 after_include = dirtmp;
1064 else
1065 last_after_include->next = dirtmp;
1066 last_after_include = dirtmp; /* Tail follows the last one */
1067 }
1068 break;
1069
1070 case 'o':
1071 if (out_fname != NULL)
1072 fatal ("Output filename specified twice");
1073 if (i + 1 == argc)
1074 fatal ("Filename missing after -o option");
1075 out_fname = argv[++i];
1076 if (!strcmp (out_fname, "-"))
1077 out_fname = "";
1078 break;
1079
1080 case 'p':
1081 if (!strcmp (argv[i], "-pedantic"))
1082 pedantic = 1;
1083 else if (!strcmp (argv[i], "-pedantic-errors")) {
1084 pedantic = 1;
1085 pedantic_errors = 1;
1086 } else if (!strcmp (argv[i], "-pcp")) {
1087 char *pcp_fname = argv[++i];
1088 pcp_outfile =
1089 ((pcp_fname[0] != '-' || pcp_fname[1] != '\0')
1090 ? fopen (pcp_fname, "w")
1091 : fdopen (dup (fileno (stdout)), "w"));
1092 if (pcp_outfile == 0)
1093 pfatal_with_name (pcp_fname);
1094 no_precomp = 1;
1095 }
1096 break;
1097
1098 case 't':
1099 if (!strcmp (argv[i], "-traditional")) {
1100 traditional = 1;
1101 if (dollars_in_ident > 0)
1102 dollars_in_ident = 1;
1103 } else if (!strcmp (argv[i], "-trigraphs")) {
1104 no_trigraphs = 0;
1105 }
1106 break;
1107
1108 case 'l':
1109 if (! strcmp (argv[i], "-lang-c"))
1110 cplusplus = 0, cplusplus_comments = 0, objc = 0;
1111 if (! strcmp (argv[i], "-lang-c++"))
1112 cplusplus = 1, cplusplus_comments = 1, objc = 0;
1113 if (! strcmp (argv[i], "-lang-objc"))
1114 objc = 1, cplusplus = 0, cplusplus_comments = 1;
1115 if (! strcmp (argv[i], "-lang-objc++"))
1116 objc = 1, cplusplus = 1, cplusplus_comments = 1;
1117 if (! strcmp (argv[i], "-lang-asm"))
1118 lang_asm = 1;
1119 if (! strcmp (argv[i], "-lint"))
1120 lint = 1;
1121 break;
1122
1123 case '+':
1124 cplusplus = 1, cplusplus_comments = 1;
1125 break;
1126
1127 case 'w':
1128 inhibit_warnings = 1;
1129 break;
1130
1131 case 'W':
1132 if (!strcmp (argv[i], "-Wtrigraphs"))
1133 warn_trigraphs = 1;
1134 else if (!strcmp (argv[i], "-Wno-trigraphs"))
1135 warn_trigraphs = 0;
1136 else if (!strcmp (argv[i], "-Wcomment"))
1137 warn_comments = 1;
1138 else if (!strcmp (argv[i], "-Wno-comment"))
1139 warn_comments = 0;
1140 else if (!strcmp (argv[i], "-Wcomments"))
1141 warn_comments = 1;
1142 else if (!strcmp (argv[i], "-Wno-comments"))
1143 warn_comments = 0;
1144 else if (!strcmp (argv[i], "-Wtraditional"))
1145 warn_stringify = 1;
1146 else if (!strcmp (argv[i], "-Wno-traditional"))
1147 warn_stringify = 0;
1148 else if (!strcmp (argv[i], "-Wimport"))
1149 warn_import = 1;
1150 else if (!strcmp (argv[i], "-Wno-import"))
1151 warn_import = 0;
1152 else if (!strcmp (argv[i], "-Werror"))
1153 warnings_are_errors = 1;
1154 else if (!strcmp (argv[i], "-Wno-error"))
1155 warnings_are_errors = 0;
1156 else if (!strcmp (argv[i], "-Wall"))
1157 {
1158 warn_trigraphs = 1;
1159 warn_comments = 1;
1160 }
1161 break;
1162
1163 case 'M':
1164 if (!strcmp (argv[i], "-M"))
1165 print_deps = 2;
1166 else if (!strcmp (argv[i], "-MM"))
1167 print_deps = 1;
1168 else if (!strcmp (argv[i], "-MD"))
1169 print_deps = 2;
1170 else if (!strcmp (argv[i], "-MMD"))
1171 print_deps = 1;
1172 /* For -MD and -MMD options, write deps on file named by next arg. */
1173 if (!strcmp (argv[i], "-MD")
1174 || !strcmp (argv[i], "-MMD")) {
1175 i++;
1176 deps_file = argv[i];
1177 } else {
1178 /* For -M and -MM, write deps on standard output
1179 and suppress the usual output. */
1180 deps_stream = stdout;
1181 inhibit_output = 1;
1182 }
1183 break;
1184
1185 case 'd':
1186 {
1187 char *p = argv[i] + 2;
1188 char c;
1189 while (c = *p++) {
1190 /* Arg to -d specifies what parts of macros to dump */
1191 switch (c) {
1192 case 'M':
1193 dump_macros = dump_only;
1194 no_output = 1;
1195 break;
1196 case 'N':
1197 dump_macros = dump_names;
1198 break;
1199 case 'D':
1200 dump_macros = dump_definitions;
1201 break;
1202 }
1203 }
1204 }
1205 break;
1206
1207 case 'g':
1208 if (argv[i][2] == '3')
1209 debug_output = 1;
1210 break;
1211
1212 case 'v':
1213 fprintf (stderr, "GNU CPP version %s", version_string);
1214#ifdef TARGET_VERSION
1215 TARGET_VERSION;
1216#endif
1217 fprintf (stderr, "\n");
1218 break;
1219
1220 case 'H':
1221 print_include_names = 1;
1222 break;
1223
1224 case 'D':
1225 {
1226 char *p, *p1;
1227
1228 if (argv[i][2] != 0)
1229 p = argv[i] + 2;
1230 else if (i + 1 == argc)
1231 fatal ("Macro name missing after -D option");
1232 else
1233 p = argv[++i];
1234
1235 pend_defs[i] = p;
1236 }
1237 break;
1238
1239 case 'A':
1240 {
1241 char *p, *p1;
1242
1243 if (argv[i][2] != 0)
1244 p = argv[i] + 2;
1245 else if (i + 1 == argc)
1246 fatal ("Assertion missing after -A option");
1247 else
1248 p = argv[++i];
1249
1250 if (!strcmp (p, "-")) {
1251 /* -A- eliminates all predefined macros and assertions.
1252 Let's include also any that were specified earlier
1253 on the command line. That way we can get rid of any
1254 that were passed automatically in from GCC. */
1255 int j;
1256 inhibit_predefs = 1;
1257 for (j = 0; j < i; j++)
1258 pend_defs[j] = pend_assertions[j] = 0;
1259 } else {
1260 pend_assertions[i] = p;
1261 pend_assertion_options[i] = "-A";
1262 }
1263 }
1264 break;
1265
1266 case 'U': /* JF #undef something */
1267 if (argv[i][2] != 0)
1268 pend_undefs[i] = argv[i] + 2;
1269 else if (i + 1 == argc)
1270 fatal ("Macro name missing after -U option");
1271 else
1272 pend_undefs[i] = argv[i+1], i++;
1273 break;
1274
1275 case 'C':
1276 put_out_comments = 1;
1277 break;
1278
1279 case 'E': /* -E comes from cc -E; ignore it. */
1280 break;
1281
1282 case 'P':
1283 no_line_commands = 1;
1284 break;
1285
1286 case '$': /* Don't include $ in identifiers. */
1287 dollars_in_ident = 0;
1288 break;
1289
1290 case 'I': /* Add directory to path for includes. */
1291 {
1292 struct file_name_list *dirtmp;
1293
1294 if (! ignore_srcdir && !strcmp (argv[i] + 2, "-")) {
1295 ignore_srcdir = 1;
1296 /* Don't use any preceding -I directories for #include <...>. */
1297 first_bracket_include = 0;
1298 }
1299 else {
1300 dirtmp = (struct file_name_list *)
1301 xmalloc (sizeof (struct file_name_list));
1302 dirtmp->next = 0; /* New one goes on the end */
1303 dirtmp->control_macro = 0;
1304 if (argv[i][2] != 0)
1305 dirtmp->fname = argv[i] + 2;
1306 else if (i + 1 == argc)
1307 fatal ("Directory name missing after -I option");
1308 else
1309 dirtmp->fname = argv[++i];
1310 append_include_chain (dirtmp, dirtmp);
1311 }
1312 }
1313 break;
1314
1315 case 'n':
1316 if (!strcmp (argv[i], "-nostdinc"))
1317 /* -nostdinc causes no default include directories.
1318 You must specify all include-file directories with -I. */
1319 no_standard_includes = 1;
1320 else if (!strcmp (argv[i], "-nostdinc++"))
1321 /* -nostdinc++ causes no default C++-specific include directories. */
1322 no_standard_cplusplus_includes = 1;
1323 else if (!strcmp (argv[i], "-noprecomp"))
1324 no_precomp = 1;
1325 break;
1326
1327 case 'u':
1328 /* Sun compiler passes undocumented switch "-undef".
1329 Let's assume it means to inhibit the predefined symbols. */
1330 inhibit_predefs = 1;
1331 break;
1332
1333 case '\0': /* JF handle '-' as file name meaning stdin or stdout */
1334 if (in_fname == NULL) {
1335 in_fname = "";
1336 break;
1337 } else if (out_fname == NULL) {
1338 out_fname = "";
1339 break;
1340 } /* else fall through into error */
1341
1342 default:
1343 fatal ("Invalid option `%s'", argv[i]);
1344 }
1345 }
1346 }
1347
1348 /* Add dirs from CPATH after dirs from -I. */
1349 /* There seems to be confusion about what CPATH should do,
1350 so for the moment it is not documented. */
1351 /* Some people say that CPATH should replace the standard include dirs,
1352 but that seems pointless: it comes before them, so it overrides them
1353 anyway. */
1354 p = (char *) getenv ("CPATH");
1355 if (p != 0 && ! no_standard_includes)
1356 path_include (p);
1357
1358 /* Now that dollars_in_ident is known, initialize is_idchar. */
1359 initialize_char_syntax ();
1360
1361 /* Initialize output buffer */
1362
1363 outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
1364 outbuf.bufp = outbuf.buf;
1365 outbuf.length = OUTBUF_SIZE;
1366
1367 /* Do partial setup of input buffer for the sake of generating
1368 early #line directives (when -g is in effect). */
1369
1370 fp = &instack[++indepth];
1371 if (in_fname == NULL)
1372 in_fname = "";
1373 fp->nominal_fname = fp->fname = in_fname;
1374 fp->lineno = 0;
1375
1376 /* Install __LINE__, etc. Must follow initialize_char_syntax
1377 and option processing. */
1378 initialize_builtins (fp, &outbuf);
1379
1380 /* Do standard #defines and assertions
1381 that identify system and machine type. */
1382
1383 if (!inhibit_predefs) {
1384 char *p = (char *) alloca (strlen (predefs) + 1);
1385 strcpy (p, predefs);
1386 while (*p) {
1387 char *q;
1388 while (*p == ' ' || *p == '\t')
1389 p++;
1390 /* Handle -D options. */
1391 if (p[0] == '-' && p[1] == 'D') {
1392 q = &p[2];
1393 while (*p && *p != ' ' && *p != '\t')
1394 p++;
1395 if (*p != 0)
1396 *p++= 0;
1397 if (debug_output)
1398 output_line_command (fp, &outbuf, 0, same_file);
1399 make_definition (q, &outbuf);
1400 while (*p == ' ' || *p == '\t')
1401 p++;
1402 } else if (p[0] == '-' && p[1] == 'A') {
1403 /* Handle -A options (assertions). */
1404 char *assertion;
1405 char *past_name;
1406 char *value;
1407 char *past_value;
1408 char *termination;
1409 int save_char;
1410
1411 assertion = &p[2];
1412 past_name = assertion;
1413 /* Locate end of name. */
1414 while (*past_name && *past_name != ' '
1415 && *past_name != '\t' && *past_name != '(')
1416 past_name++;
1417 /* Locate `(' at start of value. */
1418 value = past_name;
1419 while (*value && (*value == ' ' || *value == '\t'))
1420 value++;
1421 if (*value++ != '(')
1422 abort ();
1423 while (*value && (*value == ' ' || *value == '\t'))
1424 value++;
1425 past_value = value;
1426 /* Locate end of value. */
1427 while (*past_value && *past_value != ' '
1428 && *past_value != '\t' && *past_value != ')')
1429 past_value++;
1430 termination = past_value;
1431 while (*termination && (*termination == ' ' || *termination == '\t'))
1432 termination++;
1433 if (*termination++ != ')')
1434 abort ();
1435 if (*termination && *termination != ' ' && *termination != '\t')
1436 abort ();
1437 /* Temporarily null-terminate the value. */
1438 save_char = *termination;
1439 *termination = '\0';
1440 /* Install the assertion. */
1441 make_assertion ("-A", assertion);
1442 *termination = (char) save_char;
1443 p = termination;
1444 while (*p == ' ' || *p == '\t')
1445 p++;
1446 } else {
1447 abort ();
1448 }
1449 }
1450 }
1451
1452 /* Now handle the command line options. */
1453
1454 /* Do -U's, -D's and -A's in the order they were seen. */
1455 for (i = 1; i < argc; i++) {
1456 if (pend_undefs[i]) {
1457 if (debug_output)
1458 output_line_command (fp, &outbuf, 0, same_file);
1459 make_undef (pend_undefs[i], &outbuf);
1460 }
1461 if (pend_defs[i]) {
1462 if (debug_output)
1463 output_line_command (fp, &outbuf, 0, same_file);
1464 make_definition (pend_defs[i], &outbuf);
1465 }
1466 if (pend_assertions[i])
1467 make_assertion (pend_assertion_options[i], pend_assertions[i]);
1468 }
1469
1470 done_initializing = 1;
1471
1472 { /* read the appropriate environment variable and if it exists
1473 replace include_defaults with the listed path. */
1474 char *epath = 0;
1475 switch ((objc << 1) + cplusplus)
1476 {
1477 case 0:
1478 epath = getenv ("C_INCLUDE_PATH");
1479 break;
1480 case 1:
1481 epath = getenv ("CPLUS_INCLUDE_PATH");
1482 break;
1483 case 2:
1484 epath = getenv ("OBJC_INCLUDE_PATH");
1485 break;
1486 case 3:
1487 epath = getenv ("OBJCPLUS_INCLUDE_PATH");
1488 break;
1489 }
1490 /* If the environment var for this language is set,
1491 add to the default list of include directories. */
1492 if (epath) {
1493 char *nstore = (char *) alloca (strlen (epath) + 2);
1494 int num_dirs;
1495 char *startp, *endp;
1496
1497 for (num_dirs = 1, startp = epath; *startp; startp++)
1498 if (*startp == PATH_SEPARATOR)
1499 num_dirs++;
1500 include_defaults
1501 = (struct default_include *) xmalloc ((num_dirs
1502 * sizeof (struct default_include))
1503 + sizeof (include_defaults_array));
1504 startp = endp = epath;
1505 num_dirs = 0;
1506 while (1) {
1507 /* Handle cases like c:/usr/lib:d:/gcc/lib */
1508 if ((*endp == PATH_SEPARATOR
1509#if 0 /* Obsolete, now that we use semicolons as the path separator. */
1510#ifdef __MSDOS__
1511 && (endp-startp != 1 || !isalpha (*startp))
1512#endif
1513#endif
1514 )
1515 || *endp == 0) {
1516 strncpy (nstore, startp, endp-startp);
1517 if (endp == startp)
1518 strcpy (nstore, ".");
1519 else
1520 nstore[endp-startp] = '\0';
1521
1522 include_defaults[num_dirs].fname = savestring (nstore);
1523 include_defaults[num_dirs].cplusplus = cplusplus;
1524 num_dirs++;
1525 if (*endp == '\0')
1526 break;
1527 endp = startp = endp + 1;
1528 } else
1529 endp++;
1530 }
1531 /* Put the usual defaults back in at the end. */
1532 bcopy (include_defaults_array, &include_defaults[num_dirs],
1533 sizeof (include_defaults_array));
1534 }
1535 }
1536
1537 first_system_include = 0;
1538 /* Unless -fnostdinc,
1539 tack on the standard include file dirs to the specified list */
1540 if (!no_standard_includes) {
1541 struct default_include *p = include_defaults;
1542 char *specd_prefix = include_prefix;
1543 char *default_prefix = savestring (GCC_INCLUDE_DIR);
1544 int default_len = 0;
1545 /* Remove the `include' from /usr/local/lib/gcc.../include. */
1546 if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) {
1547 default_len = strlen (default_prefix) - 7;
1548 default_prefix[default_len] = 0;
1549 }
1550 /* Search "translated" versions of GNU directories.
1551 These have /usr/local/lib/gcc... replaced by specd_prefix. */
1552 if (specd_prefix != 0 && default_len != 0)
1553 for (p = include_defaults; p->fname; p++) {
1554 /* Some standard dirs are only for C++. */
1555 if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
1556 /* Does this dir start with the prefix? */
1557 if (!strncmp (p->fname, default_prefix, default_len)) {
1558 /* Yes; change prefix and add to search list. */
1559 struct file_name_list *new
1560 = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
1561 int this_len = strlen (specd_prefix) + strlen (p->fname) - default_len;
1562 char *str = (char *) xmalloc (this_len + 1);
1563 strcpy (str, specd_prefix);
1564 strcat (str, p->fname + default_len);
1565 new->fname = str;
1566 new->control_macro = 0;
1567 append_include_chain (new, new);
1568 if (first_system_include == 0)
1569 first_system_include = new;
1570 }
1571 }
1572 }
1573 /* Search ordinary names for GNU include directories. */
1574 for (p = include_defaults; p->fname; p++) {
1575 /* Some standard dirs are only for C++. */
1576 if (!p->cplusplus || (cplusplus && !no_standard_cplusplus_includes)) {
1577 struct file_name_list *new
1578 = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
1579 new->control_macro = 0;
1580 new->fname = p->fname;
1581 append_include_chain (new, new);
1582 if (first_system_include == 0)
1583 first_system_include = new;
1584 }
1585 }
1586 }
1587
1588 /* Tack the after_include chain at the end of the include chain. */
1589 append_include_chain (after_include, last_after_include);
1590 if (first_system_include == 0)
1591 first_system_include = after_include;
1592
1593 /* Scan the -imacros files before the main input.
1594 Much like #including them, but with no_output set
1595 so that only their macro definitions matter. */
1596
1597 no_output++;
1598 for (i = 1; i < argc; i++)
1599 if (pend_files[i]) {
1600 int fd = open (pend_files[i], O_RDONLY, 0666);
1601 if (fd < 0) {
1602 perror_with_name (pend_files[i]);
1603 return FAILURE_EXIT_CODE;
1604 }
1605 finclude (fd, pend_files[i], &outbuf, 0, NULL_PTR);
1606 }
1607 no_output--;
1608
1609 /* Copy the entire contents of the main input file into
1610 the stacked input buffer previously allocated for it. */
1611
1612 /* JF check for stdin */
1613 if (in_fname == NULL || *in_fname == 0) {
1614 in_fname = "";
1615 f = 0;
1616 } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
1617 goto perror;
1618
1619 /* Either of two environment variables can specify output of deps.
1620 Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
1621 where OUTPUT_FILE is the file to write deps info to
1622 and DEPS_TARGET is the target to mention in the deps. */
1623
1624 if (print_deps == 0
1625 && (getenv ("SUNPRO_DEPENDENCIES") != 0
1626 || getenv ("DEPENDENCIES_OUTPUT") != 0)) {
1627 char *spec = getenv ("DEPENDENCIES_OUTPUT");
1628 char *s;
1629 char *output_file;
1630
1631 if (spec == 0) {
1632 spec = getenv ("SUNPRO_DEPENDENCIES");
1633 print_deps = 2;
1634 }
1635 else
1636 print_deps = 1;
1637
1638 s = spec;
1639 /* Find the space before the DEPS_TARGET, if there is one. */
1640 /* This should use index. (mrs) */
1641 while (*s != 0 && *s != ' ') s++;
1642 if (*s != 0) {
1643 deps_target = s + 1;
1644 output_file = (char *) xmalloc (s - spec + 1);
1645 bcopy (spec, output_file, s - spec);
1646 output_file[s - spec] = 0;
1647 }
1648 else {
1649 deps_target = 0;
1650 output_file = spec;
1651 }
1652
1653 deps_file = output_file;
1654 }
1655
1656 /* For -M, print the expected object file name
1657 as the target of this Make-rule. */
1658 if (print_deps) {
1659 deps_allocated_size = 200;
1660 deps_buffer = (char *) xmalloc (deps_allocated_size);
1661 deps_buffer[0] = 0;
1662 deps_size = 0;
1663 deps_column = 0;
1664
1665 if (deps_target) {
1666 deps_output (deps_target, 0);
1667 deps_output (":", 0);
1668 } else if (*in_fname == 0)
1669 deps_output ("-: ", 0);
1670 else {
1671 int len;
1672 char *p = in_fname;
1673 char *p1 = p;
1674 /* Discard all directory prefixes from P. */
1675 while (*p1) {
1676 if (*p1 == '/')
1677 p = p1 + 1;
1678 p1++;
1679 }
1680 /* Output P, but remove known suffixes. */
1681 len = strlen (p);
1682 if (p[len - 2] == '.' && p[len - 1] == 'c')
1683 deps_output (p, len - 2);
1684 else if (p[len - 2] == '.' && p[len - 1] == 'C')
1685 deps_output (p, len - 2);
1686 else if (p[len - 3] == '.'
1687 && p[len - 2] == 'c'
1688 && p[len - 1] == 'c')
1689 deps_output (p, len - 3);
1690 else if (p[len - 2] == '.' && p[len - 1] == 's')
1691 deps_output (p, len - 2);
1692 else if (p[len - 2] == '.' && p[len - 1] == 'S')
1693 deps_output (p, len - 2);
1694 else if (p[len - 2] == '.' && p[len - 1] == 'm')
1695 deps_output (p, len - 2);
1696 else
1697 deps_output (p, 0);
1698 /* Supply our own suffix. */
1699#ifndef VMS
1700 deps_output (".o : ", 0);
1701#else
1702 deps_output (".obj : ", 0);
1703#endif
1704 deps_output (in_fname, 0);
1705 deps_output (" ", 0);
1706 }
1707 }
1708
1709 file_size_and_mode (f, &st_mode, &st_size);
1710 fp->nominal_fname = fp->fname = in_fname;
1711 fp->lineno = 1;
1712 fp->system_header_p = 0;
1713 /* JF all this is mine about reading pipes and ttys */
1714 if (! S_ISREG (st_mode)) {
1715 /* Read input from a file that is not a normal disk file.
1716 We cannot preallocate a buffer with the correct size,
1717 so we must read in the file a piece at the time and make it bigger. */
1718 int size;
1719 int bsize;
1720 int cnt;
1721 U_CHAR *bufp;
1722
1723 bsize = 2000;
1724 size = 0;
1725 fp->buf = (U_CHAR *) xmalloc (bsize + 2);
1726 bufp = fp->buf;
1727 for (;;) {
1728 cnt = read (f, bufp, bsize - size);
1729 if (cnt < 0) goto perror; /* error! */
1730 if (cnt == 0) break; /* End of file */
1731 size += cnt;
1732 bufp += cnt;
1733 if (bsize == size) { /* Buffer is full! */
1734 bsize *= 2;
1735 fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
1736 bufp = fp->buf + size; /* May have moved */
1737 }
1738 }
1739 fp->length = size;
1740 } else {
1741 /* Read a file whose size we can determine in advance.
1742 For the sake of VMS, st_size is just an upper bound. */
1743 long i;
1744 fp->length = 0;
1745 fp->buf = (U_CHAR *) xmalloc (st_size + 2);
1746
1747 while (st_size > 0) {
1748 i = read (f, fp->buf + fp->length, st_size);
1749 if (i <= 0) {
1750 if (i == 0) break;
1751 goto perror;
1752 }
1753 fp->length += i;
1754 st_size -= i;
1755 }
1756 }
1757 fp->bufp = fp->buf;
1758 fp->if_stack = if_stack;
1759
1760 /* Make sure data ends with a newline. And put a null after it. */
1761
1762 if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
1763 /* Backslash-newline at end is not good enough. */
1764 || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
1765 fp->buf[fp->length++] = '\n';
1766 missing_newline = 1;
1767 }
1768 fp->buf[fp->length] = '\0';
1769
1770 /* Unless inhibited, convert trigraphs in the input. */
1771
1772 if (!no_trigraphs)
1773 trigraph_pcp (fp);
1774
1775 /* Now that we know the input file is valid, open the output. */
1776
1777 if (!out_fname || !strcmp (out_fname, ""))
1778 out_fname = "stdout";
1779 else if (! freopen (out_fname, "w", stdout))
1780 pfatal_with_name (out_fname);
1781
1782 output_line_command (fp, &outbuf, 0, same_file);
1783
1784 /* Scan the -include files before the main input. */
1785
1786 for (i = 1; i < argc; i++)
1787 if (pend_includes[i]) {
1788 int fd = open (pend_includes[i], O_RDONLY, 0666);
1789 if (fd < 0) {
1790 perror_with_name (pend_includes[i]);
1791 return FAILURE_EXIT_CODE;
1792 }
1793 finclude (fd, pend_includes[i], &outbuf, 0, NULL_PTR);
1794 }
1795
1796 /* Scan the input, processing macros and directives. */
1797
1798 rescan (&outbuf, 0);
1799
1800 if (pedantic && missing_newline)
1801 pedwarn ("file does not end in newline");
1802
1803 /* Now we have processed the entire input
1804 Write whichever kind of output has been requested. */
1805
1806 if (dump_macros == dump_only)
1807 dump_all_macros ();
1808 else if (! inhibit_output) {
1809 write_output ();
1810 }
1811
1812 if (print_deps) {
1813 /* Don't actually write the deps file if compilation has failed. */
1814 if (errors == 0) {
1815 if (deps_file && ! (deps_stream = fopen (deps_file, "a")))
1816 pfatal_with_name (deps_file);
1817 fputs (deps_buffer, deps_stream);
1818 putc ('\n', deps_stream);
1819 if (deps_file) {
1820 if (ferror (deps_stream) || fclose (deps_stream) != 0)
1821 fatal ("I/O error on output");
1822 }
1823 }
1824 }
1825
1826 if (ferror (stdout) || fclose (stdout) != 0)
1827 fatal ("I/O error on output");
1828
1829 if (errors)
1830 exit (FAILURE_EXIT_CODE);
1831 exit (SUCCESS_EXIT_CODE);
1832
1833 perror:
1834 pfatal_with_name (in_fname);
1835 return 0;
1836}
1837\f
1838/* Given a colon-separated list of file names PATH,
1839 add all the names to the search path for include files. */
1840
1841static void
1842path_include (path)
1843 char *path;
1844{
1845 char *p;
1846
1847 p = path;
1848
1849 if (*p)
1850 while (1) {
1851 char *q = p;
1852 char *name;
1853 struct file_name_list *dirtmp;
1854
1855 /* Find the end of this name. */
1856 while (*q != 0 && *q != PATH_SEPARATOR) q++;
1857 if (p == q) {
1858 /* An empty name in the path stands for the current directory. */
1859 name = (char *) xmalloc (2);
1860 name[0] = '.';
1861 name[1] = 0;
1862 } else {
1863 /* Otherwise use the directory that is named. */
1864 name = (char *) xmalloc (q - p + 1);
1865 bcopy (p, name, q - p);
1866 name[q - p] = 0;
1867 }
1868
1869 dirtmp = (struct file_name_list *)
1870 xmalloc (sizeof (struct file_name_list));
1871 dirtmp->next = 0; /* New one goes on the end */
1872 dirtmp->control_macro = 0;
1873 dirtmp->fname = name;
1874 append_include_chain (dirtmp, dirtmp);
1875
1876 /* Advance past this name. */
1877 p = q;
1878 if (*p == 0)
1879 break;
1880 /* Skip the colon. */
1881 p++;
1882 }
1883}
1884\f
1885/* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF
1886 before main CCCP processing. Name `pcp' is also in honor of the
1887 drugs the trigraph designers must have been on.
1888
1889 Using an extra pass through the buffer takes a little extra time,
1890 but is infinitely less hairy than trying to handle trigraphs inside
1891 strings, etc. everywhere, and also makes sure that trigraphs are
1892 only translated in the top level of processing. */
1893
1894static void
1895trigraph_pcp (buf)
1896 FILE_BUF *buf;
1897{
1898 register U_CHAR c, *fptr, *bptr, *sptr;
1899 int len;
1900
1901 fptr = bptr = sptr = buf->buf;
1902 while ((sptr = (U_CHAR *) index (sptr, '?')) != NULL) {
1903 if (*++sptr != '?')
1904 continue;
1905 switch (*++sptr) {
1906 case '=':
1907 c = '#';
1908 break;
1909 case '(':
1910 c = '[';
1911 break;
1912 case '/':
1913 c = '\\';
1914 break;
1915 case ')':
1916 c = ']';
1917 break;
1918 case '\'':
1919 c = '^';
1920 break;
1921 case '<':
1922 c = '{';
1923 break;
1924 case '!':
1925 c = '|';
1926 break;
1927 case '>':
1928 c = '}';
1929 break;
1930 case '-':
1931 c = '~';
1932 break;
1933 case '?':
1934 sptr--;
1935 continue;
1936 default:
1937 continue;
1938 }
1939 len = sptr - fptr - 2;
1940 if (bptr != fptr && len > 0)
1941 bcopy (fptr, bptr, len); /* BSD doc says bcopy () works right
1942 for overlapping strings. In ANSI
1943 C, this will be memmove (). */
1944 bptr += len;
1945 *bptr++ = c;
1946 fptr = ++sptr;
1947 }
1948 len = buf->length - (fptr - buf->buf);
1949 if (bptr != fptr && len > 0)
1950 bcopy (fptr, bptr, len);
1951 buf->length -= fptr - bptr;
1952 buf->buf[buf->length] = '\0';
1953 if (warn_trigraphs && fptr != bptr)
1954 warning ("%d trigraph(s) encountered", (fptr - bptr) / 2);
1955}
1956\f
1957/* Move all backslash-newline pairs out of embarrassing places.
1958 Exchange all such pairs following BP
1959 with any potentially-embarrassing characters that follow them.
1960 Potentially-embarrassing characters are / and *
1961 (because a backslash-newline inside a comment delimiter
1962 would cause it not to be recognized). */
1963
1964static void
1965newline_fix (bp)
1966 U_CHAR *bp;
1967{
1968 register U_CHAR *p = bp;
1969 register int count = 0;
1970
1971 /* First count the backslash-newline pairs here. */
1972
1973 while (1) {
1974 if (p[0] == '\\') {
1975 if (p[1] == '\n')
1976 p += 2, count++;
1977 else if (p[1] == '\r' && p[2] == '\n')
1978 p += 3, count++;
1979 else
1980 break;
1981 } else
1982 break;
1983 }
1984
1985 /* What follows the backslash-newlines is not embarrassing. */
1986
1987 if (count == 0 || (*p != '/' && *p != '*'))
1988 return;
1989
1990 /* Copy all potentially embarrassing characters
1991 that follow the backslash-newline pairs
1992 down to where the pairs originally started. */
1993
1994 while (*p == '*' || *p == '/')
1995 *bp++ = *p++;
1996
1997 /* Now write the same number of pairs after the embarrassing chars. */
1998 while (count-- > 0) {
1999 *bp++ = '\\';
2000 *bp++ = '\n';
2001 }
2002}
2003
2004/* Like newline_fix but for use within a directive-name.
2005 Move any backslash-newlines up past any following symbol constituents. */
2006
2007static void
2008name_newline_fix (bp)
2009 U_CHAR *bp;
2010{
2011 register U_CHAR *p = bp;
2012 register int count = 0;
2013
2014 /* First count the backslash-newline pairs here. */
2015 while (1) {
2016 if (p[0] == '\\') {
2017 if (p[1] == '\n')
2018 p += 2, count++;
2019 else if (p[1] == '\r' && p[2] == '\n')
2020 p += 3, count++;
2021 else
2022 break;
2023 } else
2024 break;
2025 }
2026
2027 /* What follows the backslash-newlines is not embarrassing. */
2028
2029 if (count == 0 || !is_idchar[*p])
2030 return;
2031
2032 /* Copy all potentially embarrassing characters
2033 that follow the backslash-newline pairs
2034 down to where the pairs originally started. */
2035
2036 while (is_idchar[*p])
2037 *bp++ = *p++;
2038
2039 /* Now write the same number of pairs after the embarrassing chars. */
2040 while (count-- > 0) {
2041 *bp++ = '\\';
2042 *bp++ = '\n';
2043 }
2044}
2045\f
2046/* Look for lint commands in comments.
2047
2048 When we come in here, ibp points into a comment. Limit is as one expects.
2049 scan within the comment -- it should start, after lwsp, with a lint command.
2050 If so that command is returned as a (constant) string.
2051
2052 Upon return, any arg will be pointed to with argstart and will be
2053 arglen long. Note that we don't parse that arg since it will just
2054 be printed out again.
2055*/
2056
2057static char *
2058get_lintcmd (ibp, limit, argstart, arglen, cmdlen)
2059 register U_CHAR *ibp;
2060 register U_CHAR *limit;
2061 U_CHAR **argstart; /* point to command arg */
2062 int *arglen, *cmdlen; /* how long they are */
2063{
2064 long linsize;
2065 register U_CHAR *numptr; /* temp for arg parsing */
2066
2067 *arglen = 0;
2068
2069 SKIP_WHITE_SPACE (ibp);
2070
2071 if (ibp >= limit) return NULL;
2072
2073 linsize = limit - ibp;
2074
2075 /* Oh, I wish C had lexical functions... hell, I'll just open-code the set */
2076 if ((linsize >= 10) && !strncmp (ibp, "NOTREACHED", 10)) {
2077 *cmdlen = 10;
2078 return "NOTREACHED";
2079 }
2080 if ((linsize >= 8) && !strncmp (ibp, "ARGSUSED", 8)) {
2081 *cmdlen = 8;
2082 return "ARGSUSED";
2083 }
2084 if ((linsize >= 11) && !strncmp (ibp, "LINTLIBRARY", 11)) {
2085 *cmdlen = 11;
2086 return "LINTLIBRARY";
2087 }
2088 if ((linsize >= 7) && !strncmp (ibp, "VARARGS", 7)) {
2089 *cmdlen = 7;
2090 ibp += 7; linsize -= 7;
2091 if ((linsize == 0) || ! isdigit (*ibp)) return "VARARGS";
2092
2093 /* OK, read a number */
2094 for (numptr = *argstart = ibp; (numptr < limit) && isdigit (*numptr);
2095 numptr++);
2096 *arglen = numptr - *argstart;
2097 return "VARARGS";
2098 }
2099 return NULL;
2100}
2101\f
2102/*
2103 * The main loop of the program.
2104 *
2105 * Read characters from the input stack, transferring them to the
2106 * output buffer OP.
2107 *
2108 * Macros are expanded and push levels on the input stack.
2109 * At the end of such a level it is popped off and we keep reading.
2110 * At the end of any other kind of level, we return.
2111 * #-directives are handled, except within macros.
2112 *
2113 * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
2114 * and insert them when appropriate. This is set while scanning macro
2115 * arguments before substitution. It is zero when scanning for final output.
2116 * There are three types of Newline markers:
2117 * * Newline - follows a macro name that was not expanded
2118 * because it appeared inside an expansion of the same macro.
2119 * This marker prevents future expansion of that identifier.
2120 * When the input is rescanned into the final output, these are deleted.
2121 * These are also deleted by ## concatenation.
2122 * * Newline Space (or Newline and any other whitespace character)
2123 * stands for a place that tokens must be separated or whitespace
2124 * is otherwise desirable, but where the ANSI standard specifies there
2125 * is no whitespace. This marker turns into a Space (or whichever other
2126 * whitespace char appears in the marker) in the final output,
2127 * but it turns into nothing in an argument that is stringified with #.
2128 * Such stringified arguments are the only place where the ANSI standard
2129 * specifies with precision that whitespace may not appear.
2130 *
2131 * During this function, IP->bufp is kept cached in IBP for speed of access.
2132 * Likewise, OP->bufp is kept in OBP. Before calling a subroutine
2133 * IBP, IP and OBP must be copied back to memory. IP and IBP are
2134 * copied back with the RECACHE macro. OBP must be copied back from OP->bufp
2135 * explicitly, and before RECACHE, since RECACHE uses OBP.
2136 */
2137
2138static void
2139rescan (op, output_marks)
2140 FILE_BUF *op;
2141 int output_marks;
2142{
2143 /* Character being scanned in main loop. */
2144 register U_CHAR c;
2145
2146 /* Length of pending accumulated identifier. */
2147 register int ident_length = 0;
2148
2149 /* Hash code of pending accumulated identifier. */
2150 register int hash = 0;
2151
2152 /* Current input level (&instack[indepth]). */
2153 FILE_BUF *ip;
2154
2155 /* Pointer for scanning input. */
2156 register U_CHAR *ibp;
2157
2158 /* Pointer to end of input. End of scan is controlled by LIMIT. */
2159 register U_CHAR *limit;
2160
2161 /* Pointer for storing output. */
2162 register U_CHAR *obp;
2163
2164 /* REDO_CHAR is nonzero if we are processing an identifier
2165 after backing up over the terminating character.
2166 Sometimes we process an identifier without backing up over
2167 the terminating character, if the terminating character
2168 is not special. Backing up is done so that the terminating character
2169 will be dispatched on again once the identifier is dealt with. */
2170 int redo_char = 0;
2171
2172 /* 1 if within an identifier inside of which a concatenation
2173 marker (Newline -) has been seen. */
2174 int concatenated = 0;
2175
2176 /* While scanning a comment or a string constant,
2177 this records the line it started on, for error messages. */
2178 int start_line;
2179
2180 /* Line where a newline was first seen in a string constant. */
2181 int multiline_string_line = 0;
2182
2183 /* Record position of last `real' newline. */
2184 U_CHAR *beg_of_line;
2185
2186/* Pop the innermost input stack level, assuming it is a macro expansion. */
2187
2188#define POPMACRO \
2189do { ip->macro->type = T_MACRO; \
2190 if (ip->free_ptr) free (ip->free_ptr); \
2191 --indepth; } while (0)
2192
2193/* Reload `rescan's local variables that describe the current
2194 level of the input stack. */
2195
2196#define RECACHE \
2197do { ip = &instack[indepth]; \
2198 ibp = ip->bufp; \
2199 limit = ip->buf + ip->length; \
2200 op->bufp = obp; \
2201 check_expand (op, limit - ibp); \
2202 beg_of_line = 0; \
2203 obp = op->bufp; } while (0)
2204
2205 if (no_output && instack[indepth].fname != 0)
2206 skip_if_group (&instack[indepth], 1);
2207
2208 obp = op->bufp;
2209 RECACHE;
2210
2211 beg_of_line = ibp;
2212
2213 /* Our caller must always put a null after the end of
2214 the input at each input stack level. */
2215 if (*limit != 0)
2216 abort ();
2217
2218 while (1) {
2219 c = *ibp++;
2220 *obp++ = c;
2221
2222 switch (c) {
2223 case '\\':
2224 if (ibp >= limit)
2225 break;
2226 if (*ibp == '\n') {
2227 /* Always merge lines ending with backslash-newline,
2228 even in middle of identifier. */
2229 ++ibp;
2230 ++ip->lineno;
2231 --obp; /* remove backslash from obuf */
2232 break;
2233 }
2234 /* Otherwise, backslash suppresses specialness of following char,
2235 so copy it here to prevent the switch from seeing it.
2236 But first get any pending identifier processed. */
2237 if (ident_length > 0)
2238 goto specialchar;
2239 *obp++ = *ibp++;
2240 break;
2241
2242 case '#':
2243 if (assertions_flag) {
2244 /* Copy #foo (bar lose) without macro expansion. */
2245 SKIP_WHITE_SPACE (ibp);
2246 while (is_idchar[*ibp])
2247 *obp++ = *ibp++;
2248 SKIP_WHITE_SPACE (ibp);
2249 if (*ibp == '(') {
2250 ip->bufp = ibp;
2251 skip_paren_group (ip);
2252 bcopy (ibp, obp, ip->bufp - ibp);
2253 obp += ip->bufp - ibp;
2254 ibp = ip->bufp;
2255 }
2256 }
2257
2258 /* If this is expanding a macro definition, don't recognize
2259 preprocessor directives. */
2260 if (ip->macro != 0)
2261 goto randomchar;
2262 /* If this is expand_into_temp_buffer, recognize them
2263 only after an actual newline at this level,
2264 not at the beginning of the input level. */
2265 if (ip->fname == 0 && beg_of_line == ip->buf)
2266 goto randomchar;
2267 if (ident_length)
2268 goto specialchar;
2269
2270
2271 /* # keyword: a # must be first nonblank char on the line */
2272 if (beg_of_line == 0)
2273 goto randomchar;
2274 {
2275 U_CHAR *bp;
2276
2277 /* Scan from start of line, skipping whitespace, comments
2278 and backslash-newlines, and see if we reach this #.
2279 If not, this # is not special. */
2280 bp = beg_of_line;
2281 /* If -traditional, require # to be at beginning of line. */
2282 if (!traditional)
2283 while (1) {
2284 if (is_hor_space[*bp])
2285 bp++;
2286 else if (*bp == '\\' && bp[1] == '\n')
2287 bp += 2;
2288 else if (*bp == '/' && bp[1] == '*') {
2289 bp += 2;
2290 while (!(*bp == '*' && bp[1] == '/'))
2291 bp++;
2292 bp += 2;
2293 }
2294 else if (cplusplus_comments && *bp == '/' && bp[1] == '/') {
2295 bp += 2;
2296 while (*bp++ != '\n') ;
2297 }
2298 else break;
2299 }
2300 if (bp + 1 != ibp)
2301 goto randomchar;
2302 }
2303
2304 /* This # can start a directive. */
2305
2306 --obp; /* Don't copy the '#' */
2307
2308 ip->bufp = ibp;
2309 op->bufp = obp;
2310 if (! handle_directive (ip, op)) {
2311#ifdef USE_C_ALLOCA
2312 alloca (0);
2313#endif
2314 /* Not a known directive: treat it as ordinary text.
2315 IP, OP, IBP, etc. have not been changed. */
2316 if (no_output && instack[indepth].fname) {
2317 /* If not generating expanded output,
2318 what we do with ordinary text is skip it.
2319 Discard everything until next # directive. */
2320 skip_if_group (&instack[indepth], 1);
2321 RECACHE;
2322 beg_of_line = ibp;
2323 break;
2324 }
2325 ++obp; /* Copy the '#' after all */
2326 goto randomchar;
2327 }
2328#ifdef USE_C_ALLOCA
2329 alloca (0);
2330#endif
2331 /* A # directive has been successfully processed. */
2332 /* If not generating expanded output, ignore everything until
2333 next # directive. */
2334 if (no_output && instack[indepth].fname)
2335 skip_if_group (&instack[indepth], 1);
2336 obp = op->bufp;
2337 RECACHE;
2338 beg_of_line = ibp;
2339 break;
2340
2341 case '\"': /* skip quoted string */
2342 case '\'':
2343 /* A single quoted string is treated like a double -- some
2344 programs (e.g., troff) are perverse this way */
2345
2346 if (ident_length)
2347 goto specialchar;
2348
2349 start_line = ip->lineno;
2350
2351 /* Skip ahead to a matching quote. */
2352
2353 while (1) {
2354 if (ibp >= limit) {
2355 if (ip->macro != 0) {
2356 /* try harder: this string crosses a macro expansion boundary.
2357 This can happen naturally if -traditional.
2358 Otherwise, only -D can make a macro with an unmatched quote. */
2359 POPMACRO;
2360 RECACHE;
2361 continue;
2362 }
2363 if (!traditional) {
2364 error_with_line (line_for_error (start_line),
2365 "unterminated string or character constant");
2366 error_with_line (multiline_string_line,
2367 "possible real start of unterminated constant");
2368 multiline_string_line = 0;
2369 }
2370 break;
2371 }
2372 *obp++ = *ibp;
2373 switch (*ibp++) {
2374 case '\n':
2375 ++ip->lineno;
2376 ++op->lineno;
2377 /* Traditionally, end of line ends a string constant with no error.
2378 So exit the loop and record the new line. */
2379 if (traditional) {
2380 beg_of_line = ibp;
2381 goto while2end;
2382 }
2383 if (pedantic || c == '\'') {
2384 error_with_line (line_for_error (start_line),
2385 "unterminated string or character constant");
2386 goto while2end;
2387 }
2388 if (multiline_string_line == 0)
2389 multiline_string_line = ip->lineno - 1;
2390 break;
2391
2392 case '\\':
2393 if (ibp >= limit)
2394 break;
2395 if (*ibp == '\n') {
2396 /* Backslash newline is replaced by nothing at all,
2397 but keep the line counts correct. */
2398 --obp;
2399 ++ibp;
2400 ++ip->lineno;
2401 } else {
2402 /* ANSI stupidly requires that in \\ the second \
2403 is *not* prevented from combining with a newline. */
2404 while (*ibp == '\\' && ibp[1] == '\n') {
2405 ibp += 2;
2406 ++ip->lineno;
2407 }
2408 *obp++ = *ibp++;
2409 }
2410 break;
2411
2412 case '\"':
2413 case '\'':
2414 if (ibp[-1] == c)
2415 goto while2end;
2416 break;
2417 }
2418 }
2419 while2end:
2420 break;
2421
2422 case '/':
2423 if (*ibp == '\\' && ibp[1] == '\n')
2424 newline_fix (ibp);
2425
2426 if (*ibp != '*'
2427 && !(cplusplus_comments && *ibp == '/'))
2428 goto randomchar;
2429 if (ip->macro != 0)
2430 goto randomchar;
2431 if (ident_length)
2432 goto specialchar;
2433
2434 if (*ibp == '/') {
2435 /* C++ style comment... */
2436 start_line = ip->lineno;
2437
2438 --ibp; /* Back over the slash */
2439 --obp;
2440
2441 /* Comments are equivalent to spaces. */
2442 if (! put_out_comments)
2443 *obp++ = ' ';
2444 else {
2445 /* must fake up a comment here */
2446 *obp++ = '/';
2447 *obp++ = '/';
2448 }
2449 {
2450 U_CHAR *before_bp = ibp+2;
2451
2452 while (ibp < limit) {
2453 if (*ibp++ == '\n') {
2454 ibp--;
2455 if (put_out_comments) {
2456 bcopy (before_bp, obp, ibp - before_bp);
2457 obp += ibp - before_bp;
2458 }
2459 break;
2460 }
2461 }
2462 break;
2463 }
2464 }
2465
2466 /* Ordinary C comment. Skip it, optionally copying it to output. */
2467
2468 start_line = ip->lineno;
2469
2470 ++ibp; /* Skip the star. */
2471
2472 /* If this cpp is for lint, we peek inside the comments: */
2473 if (lint) {
2474 U_CHAR *argbp;
2475 int cmdlen, arglen;
2476 char *lintcmd = get_lintcmd (ibp, limit, &argbp, &arglen, &cmdlen);
2477
2478 if (lintcmd != NULL) {
2479 /* I believe it is always safe to emit this newline: */
2480 obp[-1] = '\n';
2481 bcopy ("#pragma lint ", obp, 13);
2482 obp += 13;
2483 bcopy (lintcmd, obp, cmdlen);
2484 obp += cmdlen;
2485
2486 if (arglen != 0) {
2487 *(obp++) = ' ';
2488 bcopy (argbp, obp, arglen);
2489 obp += arglen;
2490 }
2491
2492 /* OK, now bring us back to the state we were in before we entered
2493 this branch. We need #line b/c the newline for the pragma
2494 could fuck things up. */
2495 output_line_command (ip, op, 0, same_file);
2496 *(obp++) = ' '; /* just in case, if comments are copied thru */
2497 *(obp++) = '/';
2498 }
2499 }
2500
2501 /* Comments are equivalent to spaces.
2502 Note that we already output the slash; we might not want it.
2503 For -traditional, a comment is equivalent to nothing. */
2504 if (! put_out_comments) {
2505 if (traditional)
2506 obp--;
2507 else
2508 obp[-1] = ' ';
2509 }
2510 else
2511 *obp++ = '*';
2512
2513 {
2514 U_CHAR *before_bp = ibp;
2515
2516 while (ibp < limit) {
2517 switch (*ibp++) {
2518 case '/':
2519 if (warn_comments && ibp < limit && *ibp == '*')
2520 warning("`/*' within comment");
2521 break;
2522 case '*':
2523 if (*ibp == '\\' && ibp[1] == '\n')
2524 newline_fix (ibp);
2525 if (ibp >= limit || *ibp == '/')
2526 goto comment_end;
2527 break;
2528 case '\n':
2529 ++ip->lineno;
2530 /* Copy the newline into the output buffer, in order to
2531 avoid the pain of a #line every time a multiline comment
2532 is seen. */
2533 if (!put_out_comments)
2534 *obp++ = '\n';
2535 ++op->lineno;
2536 }
2537 }
2538 comment_end:
2539
2540 if (ibp >= limit)
2541 error_with_line (line_for_error (start_line),
2542 "unterminated comment");
2543 else {
2544 ibp++;
2545 if (put_out_comments) {
2546 bcopy (before_bp, obp, ibp - before_bp);
2547 obp += ibp - before_bp;
2548 }
2549 }
2550 }
2551 break;
2552
2553 case '$':
2554 if (!dollars_in_ident)
2555 goto randomchar;
2556 goto letter;
2557
2558 case '0': case '1': case '2': case '3': case '4':
2559 case '5': case '6': case '7': case '8': case '9':
2560 /* If digit is not part of identifier, it starts a number,
2561 which means that following letters are not an identifier.
2562 "0x5" does not refer to an identifier "x5".
2563 So copy all alphanumerics that follow without accumulating
2564 as an identifier. Periods also, for sake of "3.e7". */
2565
2566 if (ident_length == 0) {
2567 while (ibp < limit) {
2568 while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
2569 ++ip->lineno;
2570 ibp += 2;
2571 }
2572 c = *ibp++;
2573 /* ".." terminates a preprocessing number. This is useless for C
2574 code but useful for preprocessing other things. */
2575 if (!isalnum (c) && (c != '.' || *ibp == '.') && c != '_') {
2576 --ibp;
2577 break;
2578 }
2579 *obp++ = c;
2580 /* A sign can be part of a preprocessing number
2581 if it follows an e. */
2582 if (c == 'e' || c == 'E') {
2583 while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {
2584 ++ip->lineno;
2585 ibp += 2;
2586 }
2587 if (ibp < limit && (*ibp == '+' || *ibp == '-')) {
2588 *obp++ = *ibp++;
2589 /* But traditional C does not let the token go past the sign. */
2590 if (traditional)
2591 break;
2592 }
2593 }
2594 }
2595 break;
2596 }
2597 /* fall through */
2598
2599 case '_':
2600 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
2601 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
2602 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
2603 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
2604 case 'y': case 'z':
2605 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
2606 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
2607 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
2608 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
2609 case 'Y': case 'Z':
2610 letter:
2611 ident_length++;
2612 /* Compute step of hash function, to avoid a proc call on every token */
2613 hash = HASHSTEP (hash, c);
2614 break;
2615
2616 case '\n':
2617 /* If reprocessing a macro expansion, newline is a special marker. */
2618 if (ip->macro != 0) {
2619 /* Newline White is a "funny space" to separate tokens that are
2620 supposed to be separate but without space between.
2621 Here White means any whitespace character.
2622 Newline - marks a recursive macro use that is not
2623 supposed to be expandable. */
2624
2625 if (*ibp == '-') {
2626 /* Newline - inhibits expansion of preceding token.
2627 If expanding a macro arg, we keep the newline -.
2628 In final output, it is deleted. */
2629 if (! concatenated) {
2630 ident_length = 0;
2631 hash = 0;
2632 }
2633 ibp++;
2634 if (!output_marks) {
2635 obp--;
2636 } else {
2637 /* If expanding a macro arg, keep the newline -. */
2638 *obp++ = '-';
2639 }
2640 } else if (is_space[*ibp]) {
2641 /* Newline Space does not prevent expansion of preceding token
2642 so expand the preceding token and then come back. */
2643 if (ident_length > 0)
2644 goto specialchar;
2645
2646 /* If generating final output, newline space makes a space. */
2647 if (!output_marks) {
2648 obp[-1] = *ibp++;
2649 /* And Newline Newline makes a newline, so count it. */
2650 if (obp[-1] == '\n')
2651 op->lineno++;
2652 } else {
2653 /* If expanding a macro arg, keep the newline space.
2654 If the arg gets stringified, newline space makes nothing. */
2655 *obp++ = *ibp++;
2656 }
2657 } else abort (); /* Newline followed by something random? */
2658 break;
2659 }
2660
2661 /* If there is a pending identifier, handle it and come back here. */
2662 if (ident_length > 0)
2663 goto specialchar;
2664
2665 beg_of_line = ibp;
2666
2667 /* Update the line counts and output a #line if necessary. */
2668 ++ip->lineno;
2669 ++op->lineno;
2670 if (ip->lineno != op->lineno) {
2671 op->bufp = obp;
2672 output_line_command (ip, op, 1, same_file);
2673 check_expand (op, ip->length - (ip->bufp - ip->buf));
2674 obp = op->bufp;
2675 }
2676 break;
2677
2678 /* Come here either after (1) a null character that is part of the input
2679 or (2) at the end of the input, because there is a null there. */
2680 case 0:
2681 if (ibp <= limit)
2682 /* Our input really contains a null character. */
2683 goto randomchar;
2684
2685 /* At end of a macro-expansion level, pop it and read next level. */
2686 if (ip->macro != 0) {
2687 obp--;
2688 ibp--;
2689 /* If traditional, and we have an identifier that ends here,
2690 process it now, so we get the right error for recursion. */
2691 if (traditional && ident_length
2692 && ! is_idchar[*instack[indepth - 1].bufp]) {
2693 redo_char = 1;
2694 goto randomchar;
2695 }
2696 POPMACRO;
2697 RECACHE;
2698 break;
2699 }
2700
2701 /* If we don't have a pending identifier,
2702 return at end of input. */
2703 if (ident_length == 0) {
2704 obp--;
2705 ibp--;
2706 op->bufp = obp;
2707 ip->bufp = ibp;
2708 goto ending;
2709 }
2710
2711 /* If we do have a pending identifier, just consider this null
2712 a special character and arrange to dispatch on it again.
2713 The second time, IDENT_LENGTH will be zero so we will return. */
2714
2715 /* Fall through */
2716
2717specialchar:
2718
2719 /* Handle the case of a character such as /, ', " or null
2720 seen following an identifier. Back over it so that
2721 after the identifier is processed the special char
2722 will be dispatched on again. */
2723
2724 ibp--;
2725 obp--;
2726 redo_char = 1;
2727
2728 default:
2729
2730randomchar:
2731
2732 if (ident_length > 0) {
2733 register HASHNODE *hp;
2734
2735 /* We have just seen an identifier end. If it's a macro, expand it.
2736
2737 IDENT_LENGTH is the length of the identifier
2738 and HASH is its hash code.
2739
2740 The identifier has already been copied to the output,
2741 so if it is a macro we must remove it.
2742
2743 If REDO_CHAR is 0, the char that terminated the identifier
2744 has been skipped in the output and the input.
2745 OBP-IDENT_LENGTH-1 points to the identifier.
2746 If the identifier is a macro, we must back over the terminator.
2747
2748 If REDO_CHAR is 1, the terminating char has already been
2749 backed over. OBP-IDENT_LENGTH points to the identifier. */
2750
2751 if (!pcp_outfile || pcp_inside_if) {
2752startagain:
2753 for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
2754 hp = hp->next) {
2755
2756 if (hp->length == ident_length) {
2757 int obufp_before_macroname;
2758 int op_lineno_before_macroname;
2759 register int i = ident_length;
2760 register U_CHAR *p = hp->name;
2761 register U_CHAR *q = obp - i;
2762 int disabled;
2763
2764 if (! redo_char)
2765 q--;
2766
2767 do { /* All this to avoid a strncmp () */
2768 if (*p++ != *q++)
2769 goto hashcollision;
2770 } while (--i);
2771
2772 /* We found a use of a macro name.
2773 see if the context shows it is a macro call. */
2774
2775 /* Back up over terminating character if not already done. */
2776 if (! redo_char) {
2777 ibp--;
2778 obp--;
2779 }
2780
2781 /* Save this as a displacement from the beginning of the output
2782 buffer. We can not save this as a position in the output
2783 buffer, because it may get realloc'ed by RECACHE. */
2784 obufp_before_macroname = (obp - op->buf) - ident_length;
2785 op_lineno_before_macroname = op->lineno;
2786
2787 if (hp->type == T_PCSTRING) {
2788 pcstring_used (hp); /* Mark the definition of this key
2789 as needed, ensuring that it
2790 will be output. */
2791 break; /* Exit loop, since the key cannot have a
2792 definition any longer. */
2793 }
2794
2795 /* Record whether the macro is disabled. */
2796 disabled = hp->type == T_DISABLED;
2797
2798 /* This looks like a macro ref, but if the macro was disabled,
2799 just copy its name and put in a marker if requested. */
2800
2801 if (disabled) {
2802#if 0
2803 /* This error check caught useful cases such as
2804 #define foo(x,y) bar(x(y,0), y)
2805 foo(foo, baz) */
2806 if (traditional)
2807 error ("recursive use of macro `%s'", hp->name);
2808#endif
2809
2810 if (output_marks) {
2811 check_expand (op, limit - ibp + 2);
2812 *obp++ = '\n';
2813 *obp++ = '-';
2814 }
2815 break;
2816 }
2817
2818 /* If macro wants an arglist, verify that a '(' follows.
2819 first skip all whitespace, copying it to the output
2820 after the macro name. Then, if there is no '(',
2821 decide this is not a macro call and leave things that way. */
2822 if ((hp->type == T_MACRO || hp->type == T_DISABLED)
2823 && hp->value.defn->nargs >= 0)
2824 {
2825 U_CHAR *old_ibp = ibp;
2826 U_CHAR *old_obp = obp;
2827 int old_iln = ip->lineno;
2828 int old_oln = op->lineno;
2829
2830 while (1) {
2831 /* Scan forward over whitespace, copying it to the output. */
2832 if (ibp == limit && ip->macro != 0) {
2833 POPMACRO;
2834 RECACHE;
2835 old_ibp = ibp;
2836 old_obp = obp;
2837 old_iln = ip->lineno;
2838 old_oln = op->lineno;
2839 }
2840 /* A comment: copy it unchanged or discard it. */
2841 else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') {
2842 if (put_out_comments) {
2843 *obp++ = '/';
2844 *obp++ = '*';
2845 } else if (! traditional) {
2846 *obp++ = ' ';
2847 }
2848 ibp += 2;
2849 while (ibp + 1 != limit
2850 && !(ibp[0] == '*' && ibp[1] == '/')) {
2851 /* We need not worry about newline-marks,
2852 since they are never found in comments. */
2853 if (*ibp == '\n') {
2854 /* Newline in a file. Count it. */
2855 ++ip->lineno;
2856 ++op->lineno;
2857 }
2858 if (put_out_comments)
2859 *obp++ = *ibp++;
2860 else
2861 ibp++;
2862 }
2863 ibp += 2;
2864 if (put_out_comments) {
2865 *obp++ = '*';
2866 *obp++ = '/';
2867 }
2868 }
2869 else if (is_space[*ibp]) {
2870 *obp++ = *ibp++;
2871 if (ibp[-1] == '\n') {
2872 if (ip->macro == 0) {
2873 /* Newline in a file. Count it. */
2874 ++ip->lineno;
2875 ++op->lineno;
2876 } else if (!output_marks) {
2877 /* A newline mark, and we don't want marks
2878 in the output. If it is newline-hyphen,
2879 discard it entirely. Otherwise, it is
2880 newline-whitechar, so keep the whitechar. */
2881 obp--;
2882 if (*ibp == '-')
2883 ibp++;
2884 else {
2885 if (*ibp == '\n')
2886 ++op->lineno;
2887 *obp++ = *ibp++;
2888 }
2889 } else {
2890 /* A newline mark; copy both chars to the output. */
2891 *obp++ = *ibp++;
2892 }
2893 }
2894 }
2895 else break;
2896 }
2897 if (*ibp != '(') {
2898 /* It isn't a macro call.
2899 Put back the space that we just skipped. */
2900 ibp = old_ibp;
2901 obp = old_obp;
2902 ip->lineno = old_iln;
2903 op->lineno = old_oln;
2904 /* Exit the for loop. */
2905 break;
2906 }
2907 }
2908
2909 /* This is now known to be a macro call.
2910 Discard the macro name from the output,
2911 along with any following whitespace just copied. */
2912 obp = op->buf + obufp_before_macroname;
2913 op->lineno = op_lineno_before_macroname;
2914
2915 /* Expand the macro, reading arguments as needed,
2916 and push the expansion on the input stack. */
2917 ip->bufp = ibp;
2918 op->bufp = obp;
2919 macroexpand (hp, op);
2920
2921 /* Reexamine input stack, since macroexpand has pushed
2922 a new level on it. */
2923 obp = op->bufp;
2924 RECACHE;
2925 break;
2926 }
2927hashcollision:
2928 ;
2929 } /* End hash-table-search loop */
2930 }
2931 ident_length = hash = 0; /* Stop collecting identifier */
2932 redo_char = 0;
2933 concatenated = 0;
2934 } /* End if (ident_length > 0) */
2935 } /* End switch */
2936 } /* End per-char loop */
2937
2938 /* Come here to return -- but first give an error message
2939 if there was an unterminated successful conditional. */
2940 ending:
2941 if (if_stack != ip->if_stack) {
2942 char *str;
2943 switch (if_stack->type) {
2944 case T_IF:
2945 str = "if";
2946 break;
2947 case T_IFDEF:
2948 str = "ifdef";
2949 break;
2950 case T_IFNDEF:
2951 str = "ifndef";
2952 break;
2953 case T_ELSE:
2954 str = "else";
2955 break;
2956 case T_ELIF:
2957 str = "elif";
2958 break;
2959 }
2960 error_with_line (line_for_error (if_stack->lineno),
2961 "unterminated `#%s' conditional", str);
2962 }
2963 if_stack = ip->if_stack;
2964}
2965\f
2966/*
2967 * Rescan a string into a temporary buffer and return the result
2968 * as a FILE_BUF. Note this function returns a struct, not a pointer.
2969 *
2970 * OUTPUT_MARKS nonzero means keep Newline markers found in the input
2971 * and insert such markers when appropriate. See `rescan' for details.
2972 * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
2973 * before substitution; it is 0 for other uses.
2974 */
2975static FILE_BUF
2976expand_to_temp_buffer (buf, limit, output_marks, assertions)
2977 U_CHAR *buf, *limit;
2978 int output_marks, assertions;
2979{
2980 register FILE_BUF *ip;
2981 FILE_BUF obuf;
2982 int length = limit - buf;
2983 U_CHAR *buf1;
2984 int odepth = indepth;
2985 int save_assertions_flag = assertions_flag;
2986
2987 assertions_flag = assertions;
2988
2989 if (length < 0)
2990 abort ();
2991
2992 /* Set up the input on the input stack. */
2993
2994 buf1 = (U_CHAR *) alloca (length + 1);
2995 {
2996 register U_CHAR *p1 = buf;
2997 register U_CHAR *p2 = buf1;
2998
2999 while (p1 != limit)
3000 *p2++ = *p1++;
3001 }
3002 buf1[length] = 0;
3003
3004 /* Set up to receive the output. */
3005
3006 obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */
3007 obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
3008 obuf.fname = 0;
3009 obuf.macro = 0;
3010 obuf.free_ptr = 0;
3011
3012 CHECK_DEPTH ({return obuf;});
3013
3014 ++indepth;
3015
3016 ip = &instack[indepth];
3017 ip->fname = 0;
3018 ip->nominal_fname = 0;
3019 ip->system_header_p = 0;
3020 ip->macro = 0;
3021 ip->free_ptr = 0;
3022 ip->length = length;
3023 ip->buf = ip->bufp = buf1;
3024 ip->if_stack = if_stack;
3025
3026 ip->lineno = obuf.lineno = 1;
3027
3028 /* Scan the input, create the output. */
3029 rescan (&obuf, output_marks);
3030
3031 /* Pop input stack to original state. */
3032 --indepth;
3033
3034 if (indepth != odepth)
3035 abort ();
3036
3037 /* Record the output. */
3038 obuf.length = obuf.bufp - obuf.buf;
3039
3040 assertions_flag = save_assertions_flag;
3041 return obuf;
3042}
3043\f
3044/*
3045 * Process a # directive. Expects IP->bufp to point after the '#', as in
3046 * `#define foo bar'. Passes to the command handler
3047 * (do_define, do_include, etc.): the addresses of the 1st and
3048 * last chars of the command (starting immediately after the #
3049 * keyword), plus op and the keyword table pointer. If the command
3050 * contains comments it is copied into a temporary buffer sans comments
3051 * and the temporary buffer is passed to the command handler instead.
3052 * Likewise for backslash-newlines.
3053 *
3054 * Returns nonzero if this was a known # directive.
3055 * Otherwise, returns zero, without advancing the input pointer.
3056 */
3057
3058static int
3059handle_directive (ip, op)
3060 FILE_BUF *ip, *op;
3061{
3062 register U_CHAR *bp, *cp;
3063 register struct directive *kt;
3064 register int ident_length;
3065 U_CHAR *resume_p;
3066
3067 /* Nonzero means we must copy the entire command
3068 to get rid of comments or backslash-newlines. */
3069 int copy_command = 0;
3070
3071 U_CHAR *ident, *after_ident;
3072
3073 bp = ip->bufp;
3074
3075 /* Record where the directive started. do_xifdef needs this. */
3076 directive_start = bp - 1;
3077
3078 /* Skip whitespace and \-newline. */
3079 while (1) {
3080 if (is_hor_space[*bp]) {
3081 if ((*bp == '\f' || *bp == '\v') && pedantic)
3082 pedwarn ("%s in preprocessing directive",
3083 *bp == '\f' ? "formfeed" : "vertical tab");
3084 bp++;
3085 } else if (*bp == '/' && bp[1] == '*') {
3086 ip->bufp = bp;
3087 skip_to_end_of_comment (ip, &ip->lineno, 0);
3088 bp = ip->bufp;
3089 } else if (*bp == '\\' && bp[1] == '\n') {
3090 bp += 2; ip->lineno++;
3091 } else break;
3092 }
3093
3094 /* Now find end of directive name.
3095 If we encounter a backslash-newline, exchange it with any following
3096 symbol-constituents so that we end up with a contiguous name. */
3097
3098 cp = bp;
3099 while (1) {
3100 if (is_idchar[*cp])
3101 cp++;
3102 else {
3103 if (*cp == '\\' && cp[1] == '\n')
3104 name_newline_fix (cp);
3105 if (is_idchar[*cp])
3106 cp++;
3107 else break;
3108 }
3109 }
3110 ident_length = cp - bp;
3111 ident = bp;
3112 after_ident = cp;
3113
3114 /* A line of just `#' becomes blank. */
3115
3116 if (ident_length == 0 && *after_ident == '\n') {
3117 ip->bufp = after_ident;
3118 return 1;
3119 }
3120
3121 if (ident_length == 0 || !is_idstart[*ident]) {
3122 U_CHAR *p = ident;
3123 while (is_idchar[*p]) {
3124 if (*p < '0' || *p > '9')
3125 break;
3126 p++;
3127 }
3128 /* Handle # followed by a line number. */
3129 if (p != ident && !is_idchar[*p]) {
3130 static struct directive line_directive_table[] = {
3131 { 4, do_line, "line", T_LINE},
3132 };
3133 if (pedantic)
3134 pedwarn ("`#' followed by integer");
3135 after_ident = ident;
3136 kt = line_directive_table;
3137 goto old_linenum;
3138 }
3139
3140 /* Avoid error for `###' and similar cases unless -pedantic. */
3141 if (p == ident) {
3142 while (*p == '#' || is_hor_space[*p]) p++;
3143 if (*p == '\n') {
3144 if (pedantic && !lang_asm)
3145 warning ("invalid preprocessor directive");
3146 return 0;
3147 }
3148 }
3149
3150 if (!lang_asm)
3151 error ("invalid preprocessor directive name");
3152
3153 return 0;
3154 }
3155
3156 /*
3157 * Decode the keyword and call the appropriate expansion
3158 * routine, after moving the input pointer up to the next line.
3159 */
3160 for (kt = directive_table; kt->length > 0; kt++) {
3161 if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) {
3162 register U_CHAR *buf;
3163 register U_CHAR *limit;
3164 int unterminated;
3165 int junk;
3166 int *already_output = 0;
3167
3168 /* Nonzero means do not delete comments within the directive.
3169 #define needs this when -traditional. */
3170 int keep_comments;
3171
3172 old_linenum:
3173
3174 limit = ip->buf + ip->length;
3175 unterminated = 0;
3176 keep_comments = traditional && kt->traditional_comments;
3177 /* #import is defined only in Objective C, or when on the NeXT. */
3178 if (kt->type == T_IMPORT && !(objc || lookup ("__NeXT__", -1, -1)))
3179 break;
3180
3181 /* Find the end of this command (first newline not backslashed
3182 and not in a string or comment).
3183 Set COPY_COMMAND if the command must be copied
3184 (it contains a backslash-newline or a comment). */
3185
3186 buf = bp = after_ident;
3187 while (bp < limit) {
3188 register U_CHAR c = *bp++;
3189 switch (c) {
3190 case '\\':
3191 if (bp < limit) {
3192 if (*bp == '\n') {
3193 ip->lineno++;
3194 copy_command = 1;
3195 }
3196 bp++;
3197 }
3198 break;
3199
3200 case '\'':
3201 case '\"':
3202 bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_command, &unterminated);
3203 /* Don't bother calling the directive if we already got an error
3204 message due to unterminated string. Skip everything and pretend
3205 we called the directive. */
3206 if (unterminated) {
3207 if (traditional) {
3208 /* Traditional preprocessing permits unterminated strings. */
3209 ip->bufp = bp;
3210 goto endloop1;
3211 }
3212 ip->bufp = bp;
3213 return 1;
3214 }
3215 break;
3216
3217 /* <...> is special for #include. */
3218 case '<':
3219 if (!kt->angle_brackets)
3220 break;
3221 while (*bp && *bp != '>') bp++;
3222 break;
3223
3224 case '/':
3225 if (*bp == '\\' && bp[1] == '\n')
3226 newline_fix (bp);
3227 if (*bp == '*'
3228 || (cplusplus_comments && *bp == '/')) {
3229 U_CHAR *obp = bp - 1;
3230 ip->bufp = bp + 1;
3231 skip_to_end_of_comment (ip, &ip->lineno, 0);
3232 bp = ip->bufp;
3233 /* No need to copy the command because of a comment at the end;
3234 just don't include the comment in the directive. */
3235 if (bp == limit || *bp == '\n') {
3236 bp = obp;
3237 goto endloop1;
3238 }
3239 /* Don't remove the comments if -traditional. */
3240 if (! keep_comments)
3241 copy_command++;
3242 }
3243 break;
3244
3245 case '\f':
3246 case '\v':
3247 if (pedantic)
3248 pedwarn ("%s in preprocessing directive",
3249 c == '\f' ? "formfeed" : "vertical tab");
3250 break;
3251
3252 case '\n':
3253 --bp; /* Point to the newline */
3254 ip->bufp = bp;
3255 goto endloop1;
3256 }
3257 }
3258 ip->bufp = bp;
3259
3260 endloop1:
3261 resume_p = ip->bufp;
3262 /* BP is the end of the directive.
3263 RESUME_P is the next interesting data after the directive.
3264 A comment may come between. */
3265
3266 /* If a directive should be copied through, and -E was given,
3267 pass it through before removing comments. */
3268 if (!no_output && kt->pass_thru && put_out_comments) {
3269 int len;
3270
3271 /* Output directive name. */
3272 check_expand (op, kt->length + 2);
3273 /* Make sure # is at the start of a line */
3274 if (op->bufp > op->buf && op->bufp[-1] != '\n') {
3275 op->lineno++;
3276 *op->bufp++ = '\n';
3277 }
3278 *op->bufp++ = '#';
3279 bcopy (kt->name, op->bufp, kt->length);
3280 op->bufp += kt->length;
3281
3282 /* Output arguments. */
3283 len = (bp - buf);
3284 check_expand (op, len);
3285 bcopy (buf, op->bufp, len);
3286 op->bufp += len;
3287 /* Take account of any (escaped) newlines just output. */
3288 while (--len >= 0)
3289 if (buf[len] == '\n')
3290 op->lineno++;
3291
3292 already_output = &junk;
3293 } /* Don't we need a newline or #line? */
3294
3295 if (copy_command) {
3296 register U_CHAR *xp = buf;
3297 /* Need to copy entire command into temp buffer before dispatching */
3298
3299 cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus
3300 some slop */
3301 buf = cp;
3302
3303 /* Copy to the new buffer, deleting comments
3304 and backslash-newlines (and whitespace surrounding the latter). */
3305
3306 while (xp < bp) {
3307 register U_CHAR c = *xp++;
3308 *cp++ = c;
3309
3310 switch (c) {
3311 case '\n':
3312 abort (); /* A bare newline should never part of the line. */
3313 break;
3314
3315 /* <...> is special for #include. */
3316 case '<':
3317 if (!kt->angle_brackets)
3318 break;
3319 while (xp < bp && c != '>') {
3320 c = *xp++;
3321 if (c == '\\' && xp < bp && *xp == '\n')
3322 xp++;
3323 else
3324 *cp++ = c;
3325 }
3326 break;
3327
3328 case '\\':
3329 if (*xp == '\n') {
3330 xp++;
3331 cp--;
3332 if (cp != buf && is_space[cp[-1]]) {
3333 while (cp != buf && is_space[cp[-1]]) cp--;
3334 cp++;
3335 SKIP_WHITE_SPACE (xp);
3336 } else if (is_space[*xp]) {
3337 *cp++ = *xp++;
3338 SKIP_WHITE_SPACE (xp);
3339 }
3340 } else {
3341 *cp++ = *xp++;
3342 }
3343 break;
3344
3345 case '\'':
3346 case '\"':
3347 {
3348 register U_CHAR *bp1
3349 = skip_quoted_string (xp - 1, bp, ip->lineno,
3350 NULL_PTR, NULL_PTR, NULL_PTR);
3351 while (xp != bp1)
3352 if (*xp == '\\') {
3353 if (*++xp != '\n')
3354 *cp++ = '\\';
3355 else
3356 xp++;
3357 } else
3358 *cp++ = *xp++;
3359 }
3360 break;
3361
3362 case '/':
3363 if (*xp == '*'
3364 || (cplusplus_comments && *xp == '/')) {
3365 ip->bufp = xp + 1;
3366 /* If we already copied the command through,
3367 already_output != 0 prevents outputting comment now. */
3368 skip_to_end_of_comment (ip, already_output, 0);
3369 if (keep_comments)
3370 while (xp != ip->bufp)
3371 *cp++ = *xp++;
3372 /* Delete or replace the slash. */
3373 else if (traditional)
3374 cp--;
3375 else
3376 cp[-1] = ' ';
3377 xp = ip->bufp;
3378 }
3379 }
3380 }
3381
3382 /* Null-terminate the copy. */
3383
3384 *cp = 0;
3385 } else
3386 cp = bp;
3387
3388 ip->bufp = resume_p;
3389
3390 /* Some directives should be written out for cc1 to process,
3391 just as if they were not defined. And sometimes we're copying
3392 definitions through. */
3393
3394 if (!no_output && already_output == 0
3395 && (kt->pass_thru
3396 || (kt->type == T_DEFINE
3397 && (dump_macros == dump_names
3398 || dump_macros == dump_definitions)))) {
3399 int len;
3400
3401 /* Output directive name. */
3402 check_expand (op, kt->length + 1);
3403 *op->bufp++ = '#';
3404 bcopy (kt->name, op->bufp, kt->length);
3405 op->bufp += kt->length;
3406
3407 if (kt->pass_thru || dump_macros == dump_definitions) {
3408 /* Output arguments. */
3409 len = (cp - buf);
3410 check_expand (op, len);
3411 bcopy (buf, op->bufp, len);
3412 op->bufp += len;
3413 } else if (kt->type == T_DEFINE && dump_macros == dump_names) {
3414 U_CHAR *xp = buf;
3415 U_CHAR *yp;
3416 SKIP_WHITE_SPACE (xp);
3417 yp = xp;
3418 while (is_idchar[*xp]) xp++;
3419 len = (xp - yp);
3420 check_expand (op, len + 1);
3421 *op->bufp++ = ' ';
3422 bcopy (yp, op->bufp, len);
3423 op->bufp += len;
3424 }
3425 } /* Don't we need a newline or #line? */
3426
3427 /* Call the appropriate command handler. buf now points to
3428 either the appropriate place in the input buffer, or to
3429 the temp buffer if it was necessary to make one. cp
3430 points to the first char after the contents of the (possibly
3431 copied) command, in either case. */
3432 (*kt->func) (buf, cp, op, kt);
3433 check_expand (op, ip->length - (ip->bufp - ip->buf));
3434
3435 return 1;
3436 }
3437 }
3438
3439 /* It is deliberate that we don't warn about undefined directives.
3440 That is the responsibility of cc1. */
3441 return 0;
3442}
3443\f
3444static struct tm *
3445timestamp ()
3446{
3447 static struct tm *timebuf;
3448 if (!timebuf) {
3449 time_t t = time (0);
3450 timebuf = localtime (&t);
3451 }
3452 return timebuf;
3453}
3454
3455static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
3456 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
3457 };
3458
3459/*
3460 * expand things like __FILE__. Place the expansion into the output
3461 * buffer *without* rescanning.
3462 */
3463
3464static void
3465special_symbol (hp, op)
3466 HASHNODE *hp;
3467 FILE_BUF *op;
3468{
3469 char *buf;
3470 int i, len;
3471 int true_indepth;
3472 FILE_BUF *ip = NULL;
3473 struct tm *timebuf;
3474
3475 int paren = 0; /* For special `defined' keyword */
3476
3477 if (pcp_outfile && pcp_inside_if
3478 && hp->type != T_SPEC_DEFINED && hp->type != T_CONST)
3479 error ("Predefined macro `%s' used inside `#if' during precompilation",
3480 hp->name);
3481
3482 for (i = indepth; i >= 0; i--)
3483 if (instack[i].fname != NULL) {
3484 ip = &instack[i];
3485 break;
3486 }
3487 if (ip == NULL) {
3488 error ("cccp error: not in any file?!");
3489 return; /* the show must go on */
3490 }
3491
3492 switch (hp->type) {
3493 case T_FILE:
3494 case T_BASE_FILE:
3495 {
3496 char *string;
3497 if (hp->type == T_FILE)
3498 string = ip->nominal_fname;
3499 else
3500 string = instack[0].nominal_fname;
3501
3502 if (string)
3503 {
3504 buf = (char *) alloca (3 + strlen (string));
3505 sprintf (buf, "\"%s\"", string);
3506 }
3507 else
3508 buf = "\"\"";
3509
3510 break;
3511 }
3512
3513 case T_INCLUDE_LEVEL:
3514 true_indepth = 0;
3515 for (i = indepth; i >= 0; i--)
3516 if (instack[i].fname != NULL)
3517 true_indepth++;
3518
3519 buf = (char *) alloca (8); /* Eight bytes ought to be more than enough */
3520 sprintf (buf, "%d", true_indepth - 1);
3521 break;
3522
3523 case T_VERSION:
3524 buf = (char *) alloca (3 + strlen (version_string));
3525 sprintf (buf, "\"%s\"", version_string);
3526 break;
3527
3528 case T_SIZE_TYPE:
3529 buf = (char *) alloca (3 + strlen (SIZE_TYPE));
3530 sprintf (buf, "%s", SIZE_TYPE);
3531 break;
3532
3533 case T_PTRDIFF_TYPE:
3534 buf = (char *) alloca (3 + strlen (PTRDIFF_TYPE));
3535 sprintf (buf, "%s", PTRDIFF_TYPE);
3536 break;
3537
3538 case T_WCHAR_TYPE:
3539 buf = (char *) alloca (3 + strlen (WCHAR_TYPE));
3540 sprintf (buf, "%s", WCHAR_TYPE);
3541 break;
3542
3543 case T_CONST:
3544 buf = (char *) alloca (4 * sizeof (int));
3545 sprintf (buf, "%d", hp->value.ival);
3546 if (pcp_inside_if && pcp_outfile)
3547 /* Output a precondition for this macro use */
3548 fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival);
3549 break;
3550
3551 case T_SPECLINE:
3552 buf = (char *) alloca (10);
3553 sprintf (buf, "%d", ip->lineno);
3554 break;
3555
3556 case T_DATE:
3557 case T_TIME:
3558 buf = (char *) alloca (20);
3559 timebuf = timestamp ();
3560 if (hp->type == T_DATE)
3561 sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
3562 timebuf->tm_mday, timebuf->tm_year + 1900);
3563 else
3564 sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
3565 timebuf->tm_sec);
3566 break;
3567
3568 case T_SPEC_DEFINED:
3569 buf = " 0 "; /* Assume symbol is not defined */
3570 ip = &instack[indepth];
3571 SKIP_WHITE_SPACE (ip->bufp);
3572 if (*ip->bufp == '(') {
3573 paren++;
3574 ip->bufp++; /* Skip over the paren */
3575 SKIP_WHITE_SPACE (ip->bufp);
3576 }
3577
3578 if (!is_idstart[*ip->bufp])
3579 goto oops;
3580 if (hp = lookup (ip->bufp, -1, -1)) {
3581 if (pcp_outfile && pcp_inside_if
3582 && hp->value.defn->predefined)
3583 /* Output a precondition for this macro use. */
3584 fprintf (pcp_outfile, "#define %s\n", hp->name);
3585 buf = " 1 ";
3586 }
3587 else
3588 if (pcp_outfile && pcp_inside_if) {
3589 /* Output a precondition for this macro use */
3590 U_CHAR *cp = ip->bufp;
3591 fprintf (pcp_outfile, "#undef ");
3592 while (is_idchar[*cp]) /* Ick! */
3593 fputc (*cp++, pcp_outfile);
3594 putc ('\n', pcp_outfile);
3595 }
3596 while (is_idchar[*ip->bufp])
3597 ++ip->bufp;
3598 SKIP_WHITE_SPACE (ip->bufp);
3599 if (paren) {
3600 if (*ip->bufp != ')')
3601 goto oops;
3602 ++ip->bufp;
3603 }
3604 break;
3605
3606oops:
3607
3608 error ("`defined' without an identifier");
3609 break;
3610
3611 default:
3612 error ("cccp error: invalid special hash type"); /* time for gdb */
3613 abort ();
3614 }
3615 len = strlen (buf);
3616 check_expand (op, len);
3617 bcopy (buf, op->bufp, len);
3618 op->bufp += len;
3619
3620 return;
3621}
3622
3623\f
3624/* Routines to handle #directives */
3625
3626/* Handle #include and #import.
3627 This function expects to see "fname" or <fname> on the input. */
3628
3629static int
3630do_include (buf, limit, op, keyword)
3631 U_CHAR *buf, *limit;
3632 FILE_BUF *op;
3633 struct directive *keyword;
3634{
3635 int importing = (keyword->type == T_IMPORT);
3636 int skip_dirs = (keyword->type == T_INCLUDE_NEXT);
3637 static int import_warning = 0;
3638 char *fname; /* Dynamically allocated fname buffer */
3639 char *pcftry;
3640 char *pcfname;
3641 U_CHAR *fbeg, *fend; /* Beginning and end of fname */
3642
3643 struct file_name_list *search_start = include; /* Chain of dirs to search */
3644 struct file_name_list dsp[1]; /* First in chain, if #include "..." */
3645 struct file_name_list *searchptr = 0;
3646 int flen;
3647
3648 int f; /* file number */
3649
3650 int retried = 0; /* Have already tried macro
3651 expanding the include line*/
3652 FILE_BUF trybuf; /* It got expanded into here */
3653 int angle_brackets = 0; /* 0 for "...", 1 for <...> */
3654 int pcf = -1;
3655 char *pcfbuf;
3656 int pcfbuflimit;
3657 int pcfnum;
3658 f= -1; /* JF we iz paranoid! */
3659
3660 if (importing && warn_import && !inhibit_warnings
3661 && !instack[indepth].system_header_p && !import_warning) {
3662 import_warning = 1;
3663 warning ("using `#import' is not recommended");
3664 fprintf (stderr, "The fact that a certain header file need not be processed more than once\n");
3665 fprintf (stderr, "should be indicated in the header file, not where it is used.\n");
3666 fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n");
3667 fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n");
3668 fprintf (stderr, " #define _FOO_H_INCLUDED\n");
3669 fprintf (stderr, " ... <real contents of file> ...\n");
3670 fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n");
3671 fprintf (stderr, "Then users can use `#include' any number of times.\n");
3672 fprintf (stderr, "GNU C automatically avoids processing the file more than once\n");
3673 fprintf (stderr, "when it is equipped with such a conditional.\n");
3674 }
3675
3676get_filename:
3677
3678 fbeg = buf;
3679 SKIP_WHITE_SPACE (fbeg);
3680 /* Discard trailing whitespace so we can easily see
3681 if we have parsed all the significant chars we were given. */
3682 while (limit != fbeg && is_hor_space[limit[-1]]) limit--;
3683
3684 switch (*fbeg++) {
3685 case '\"':
3686 {
3687 FILE_BUF *fp;
3688 /* Copy the operand text, concatenating the strings. */
3689 {
3690 U_CHAR *fin = fbeg;
3691 fbeg = (U_CHAR *) alloca (limit - fbeg + 1);
3692 fend = fbeg;
3693 while (fin != limit) {
3694 while (fin != limit && *fin != '\"')
3695 *fend++ = *fin++;
3696 fin++;
3697 if (fin == limit)
3698 break;
3699 /* If not at the end, there had better be another string. */
3700 /* Skip just horiz space, and don't go past limit. */
3701 while (fin != limit && is_hor_space[*fin]) fin++;
3702 if (fin != limit && *fin == '\"')
3703 fin++;
3704 else
3705 goto fail;
3706 }
3707 }
3708 *fend++ = 0;
3709
3710 /* We have "filename". Figure out directory this source
3711 file is coming from and put it on the front of the list. */
3712
3713 /* If -I- was specified, don't search current dir, only spec'd ones. */
3714 if (ignore_srcdir) break;
3715
3716 for (fp = &instack[indepth]; fp >= instack; fp--)
3717 {
3718 int n;
3719 char *ep,*nam;
3720
3721 if ((nam = fp->nominal_fname) != NULL) {
3722 /* Found a named file. Figure out dir of the file,
3723 and put it in front of the search list. */
3724 dsp[0].next = search_start;
3725 search_start = dsp;
3726#ifndef VMS
3727 ep = rindex (nam, '/');
3728#else /* VMS */
3729 ep = rindex (nam, ']');
3730 if (ep == NULL) ep = rindex (nam, '>');
3731 if (ep == NULL) ep = rindex (nam, ':');
3732 if (ep != NULL) ep++;
3733#endif /* VMS */
3734 if (ep != NULL) {
3735 n = ep - nam;
3736 dsp[0].fname = (char *) alloca (n + 1);
3737 strncpy (dsp[0].fname, nam, n);
3738 dsp[0].fname[n] = '\0';
3739 if (n + INCLUDE_LEN_FUDGE > max_include_len)
3740 max_include_len = n + INCLUDE_LEN_FUDGE;
3741 } else {
3742 dsp[0].fname = 0; /* Current directory */
3743 }
3744 break;
3745 }
3746 }
3747 break;
3748 }
3749
3750 case '<':
3751 fend = fbeg;
3752 while (fend != limit && *fend != '>') fend++;
3753 if (*fend == '>' && fend + 1 == limit) {
3754 angle_brackets = 1;
3755 /* If -I-, start with the first -I dir after the -I-. */
3756 if (first_bracket_include)
3757 search_start = first_bracket_include;
3758 break;
3759 }
3760 goto fail;
3761
3762 default:
3763 fail:
3764 if (retried) {
3765 if (importing)
3766 error ("`#import' expects \"fname\" or <fname>");
3767 else
3768 error ("`#include' expects \"fname\" or <fname>");
3769 return 0;
3770 } else {
3771 trybuf = expand_to_temp_buffer (buf, limit, 0, 0);
3772 buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
3773 bcopy (trybuf.buf, buf, trybuf.bufp - trybuf.buf);
3774 limit = buf + (trybuf.bufp - trybuf.buf);
3775 free (trybuf.buf);
3776 retried++;
3777 goto get_filename;
3778 }
3779 }
3780
3781 /* For #include_next, skip in the search path
3782 past the dir in which the containing file was found. */
3783 if (skip_dirs) {
3784 FILE_BUF *fp;
3785 for (fp = &instack[indepth]; fp >= instack; fp--)
3786 if (fp->fname != NULL) {
3787 /* fp->dir is null if the containing file was specified
3788 with an absolute file name. In that case, don't skip anything. */
3789 if (fp->dir)
3790 search_start = fp->dir->next;
3791 break;
3792 }
3793 }
3794
3795 flen = fend - fbeg;
3796 /* Allocate this permanently, because it gets stored in the definitions
3797 of macros. */
3798 fname = (char *) xmalloc (max_include_len + flen + 2);
3799 /* + 2 above for slash and terminating null. */
3800
3801 /* If specified file name is absolute, just open it. */
3802
3803 if (*fbeg == '/') {
3804 strncpy (fname, fbeg, flen);
3805 fname[flen] = 0;
3806 if (redundant_include_p (fname))
3807 return 0;
3808 if (importing)
3809 f = lookup_import (fname);
3810 else
3811 f = open (fname, O_RDONLY, 0666);
3812 if (f == -2)
3813 return 0; /* Already included this file */
3814 } else {
3815 /* Search directory path, trying to open the file.
3816 Copy each filename tried into FNAME. */
3817
3818 for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
3819 if (searchptr->fname) {
3820 /* The empty string in a search path is ignored.
3821 This makes it possible to turn off entirely
3822 a standard piece of the list. */
3823 if (searchptr->fname[0] == 0)
3824 continue;
3825 strcpy (fname, searchptr->fname);
3826 strcat (fname, "/");
3827 fname[strlen (fname) + flen] = 0;
3828 } else {
3829 fname[0] = 0;
3830 }
3831 strncat (fname, fbeg, flen);
3832#ifdef VMS
3833 /* Change this 1/2 Unix 1/2 VMS file specification into a
3834 full VMS file specification */
3835 if (searchptr->fname && (searchptr->fname[0] != 0)) {
3836 /* Fix up the filename */
3837 hack_vms_include_specification (fname);
3838 } else {
3839 /* This is a normal VMS filespec, so use it unchanged. */
3840 strncpy (fname, fbeg, flen);
3841 fname[flen] = 0;
3842 }
3843#endif /* VMS */
3844 if (importing)
3845 f = lookup_import (fname);
3846 else
3847 f = open (fname, O_RDONLY, 0666);
3848 if (f == -2)
3849 return 0; /* Already included this file */
3850 if (redundant_include_p (fname)) {
3851 close (f);
3852 return 0;
3853 }
3854 if (f >= 0)
3855 break;
3856 }
3857 }
3858
3859 if (f < 0) {
3860 /* A file that was not found. */
3861
3862 strncpy (fname, fbeg, flen);
3863 fname[flen] = 0;
3864 if (search_start)
3865 error_from_errno (fname);
3866 else
3867 error ("No include path in which to find %s", fname);
3868
3869 /* For -M, add this file to the dependencies. */
3870 if (print_deps > (angle_brackets || (system_include_depth > 0))) {
3871 /* Break the line before this. */
3872 deps_output ("", 0);
3873
3874 /* If it was requested as a system header file,
3875 then assume it belongs in the first place to look for such. */
3876 if (angle_brackets) {
3877 for (searchptr = search_start; searchptr; searchptr = searchptr->next) {
3878 if (searchptr->fname) {
3879 if (searchptr->fname[0] == 0)
3880 continue;
3881 deps_output (searchptr->fname, 0);
3882 deps_output ("/", 0);
3883 break;
3884 }
3885 }
3886 }
3887 /* Otherwise, omit the directory, as if the file existed
3888 in the directory with the source. */
3889 deps_output (fbeg, flen);
3890 deps_output (" ", 0);
3891 }
3892 } else {
3893 struct stat stat_f;
3894
3895 /* Check to see if this include file is a once-only include file.
3896 If so, give up. */
3897
3898 struct file_name_list* ptr;
3899
3900 for (ptr = dont_repeat_files; ptr; ptr = ptr->next) {
3901 if (!strcmp (ptr->fname, fname)) {
3902 close (f);
3903 return 0; /* This file was once'd. */
3904 }
3905 }
3906
3907 for (ptr = all_include_files; ptr; ptr = ptr->next) {
3908 if (!strcmp (ptr->fname, fname))
3909 break; /* This file was included before. */
3910 }
3911
3912 if (ptr == 0) {
3913 /* This is the first time for this file. */
3914 /* Add it to list of files included. */
3915
3916 ptr = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
3917 ptr->control_macro = 0;
3918 ptr->next = all_include_files;
3919 all_include_files = ptr;
3920 ptr->fname = savestring (fname);
3921
3922 /* For -M, add this file to the dependencies. */
3923 if (print_deps > (angle_brackets || (system_include_depth > 0))) {
3924 deps_output ("", 0);
3925 deps_output (fname, 0);
3926 deps_output (" ", 0);
3927 }
3928 }
3929
3930 /* Handle -H option. */
3931 if (print_include_names)
3932 fprintf (stderr, "%s\n", fname);
3933
3934 if (angle_brackets)
3935 system_include_depth++;
3936
3937 /* Actually process the file. */
3938 add_import (f, fname); /* Record file on "seen" list for #import. */
3939
3940 pcftry = (char *) alloca (strlen (fname) + 30);
3941 pcfbuf = 0;
3942 pcfnum = 0;
3943
3944 fstat (f, &stat_f);
3945
3946 if (!no_precomp)
3947 do {
3948 sprintf (pcftry, "%s%d", fname, pcfnum++);
3949
3950 pcf = open (pcftry, O_RDONLY, 0666);
3951 if (pcf != -1)
3952 {
3953 struct stat s;
3954
3955 fstat (pcf, &s);
3956 if (bcmp (&stat_f.st_ino, &s.st_ino, sizeof (s.st_ino))
3957 || stat_f.st_dev != s.st_dev)
3958 {
3959 pcfbuf = check_precompiled (pcf, fname, &pcfbuflimit);
3960 /* Don't need it any more. */
3961 close (pcf);
3962 }
3963 else
3964 {
3965 /* Don't need it at all. */
3966 close (pcf);
3967 break;
3968 }
3969 }
3970 } while (pcf != -1 && !pcfbuf);
3971
3972 /* Actually process the file */
3973 if (pcfbuf) {
3974 pcfname = xmalloc (strlen (pcftry) + 1);
3975 strcpy (pcfname, pcftry);
3976 pcfinclude (pcfbuf, pcfbuflimit, fname, op);
3977 }
3978 else
3979 finclude (f, fname, op, is_system_include (fname), searchptr);
3980
3981 if (angle_brackets)
3982 system_include_depth--;
3983 }
3984 return 0;
3985}
3986
3987/* Return nonzero if there is no need to include file NAME
3988 because it has already been included and it contains a conditional
3989 to make a repeated include do nothing. */
3990
3991static int
3992redundant_include_p (name)
3993 char *name;
3994{
3995 struct file_name_list *l = all_include_files;
3996 for (; l; l = l->next)
3997 if (! strcmp (name, l->fname)
3998 && l->control_macro
3999 && lookup (l->control_macro, -1, -1))
4000 return 1;
4001 return 0;
4002}
4003
4004/* Return nonzero if the given FILENAME is an absolute pathname which
4005 designates a file within one of the known "system" include file
4006 directories. We assume here that if the given FILENAME looks like
4007 it is the name of a file which resides either directly in a "system"
4008 include file directory, or within any subdirectory thereof, then the
4009 given file must be a "system" include file. This function tells us
4010 if we should suppress pedantic errors/warnings for the given FILENAME. */
4011
4012static int
4013is_system_include (filename)
4014 register char *filename;
4015{
4016 struct file_name_list *searchptr;
4017
4018 for (searchptr = first_system_include; searchptr;
4019 searchptr = searchptr->next)
4020 if (searchptr->fname) {
4021 register char *sys_dir = searchptr->fname;
4022 register unsigned length = strlen (sys_dir);
4023
4024 if (! strncmp (sys_dir, filename, length) && filename[length] == '/')
4025 return 1;
4026 }
4027 return 0;
4028}
4029\f
4030/* Process the contents of include file FNAME, already open on descriptor F,
4031 with output to OP.
4032 SYSTEM_HEADER_P is 1 if this file was specified using <...>.
4033 DIRPTR is the link in the dir path through which this file was found,
4034 or 0 if the file name was absolute. */
4035
4036static void
4037finclude (f, fname, op, system_header_p, dirptr)
4038 int f;
4039 char *fname;
4040 FILE_BUF *op;
4041 int system_header_p;
4042 struct file_name_list *dirptr;
4043{
4044 int st_mode;
4045 long st_size;
4046 long i;
4047 FILE_BUF *fp; /* For input stack frame */
4048 int missing_newline = 0;
4049
4050 CHECK_DEPTH (return;);
4051
4052 if (file_size_and_mode (f, &st_mode, &st_size) < 0)
4053 {
4054 perror_with_name (fname);
4055 close (f);
4056 return;
4057 }
4058
4059 fp = &instack[indepth + 1];
4060 bzero (fp, sizeof (FILE_BUF));
4061 fp->nominal_fname = fp->fname = fname;
4062 fp->length = 0;
4063 fp->lineno = 1;
4064 fp->if_stack = if_stack;
4065 fp->system_header_p = system_header_p;
4066 fp->dir = dirptr;
4067
4068 if (S_ISREG (st_mode)) {
4069 fp->buf = (U_CHAR *) xmalloc (st_size + 2);
4070 fp->bufp = fp->buf;
4071
4072 /* Read the file contents, knowing that st_size is an upper bound
4073 on the number of bytes we can read. */
4074 while (st_size > 0) {
4075 i = read (f, fp->buf + fp->length, st_size);
4076 if (i <= 0) {
4077 if (i == 0) break;
4078 goto nope;
4079 }
4080 fp->length += i;
4081 st_size -= i;
4082 }
4083 }
4084 else {
4085 /* Cannot count its file size before reading.
4086 First read the entire file into heap and
4087 copy them into buffer on stack. */
4088
4089 U_CHAR *bufp;
4090 U_CHAR *basep;
4091 int bsize = 2000;
4092
4093 st_size = 0;
4094 basep = (U_CHAR *) xmalloc (bsize + 2);
4095 fp->buf = basep; /* So it will get freed, on error. */
4096 bufp = basep;
4097
4098 for (;;) {
4099 i = read (f, bufp, bsize - st_size);
4100 if (i < 0)
4101 goto nope; /* error! */
4102 if (i == 0)
4103 break; /* End of file */
4104 st_size += i;
4105 bufp += i;
4106 if (bsize == st_size) { /* Buffer is full! */
4107 bsize *= 2;
4108 basep = (U_CHAR *) xrealloc (basep, bsize + 2);
4109 fp->buf = basep;
4110 bufp = basep + st_size; /* May have moved */
4111 }
4112 }
4113 fp->bufp = fp->buf;
4114 fp->length = st_size;
4115 }
4116
4117 /* Close descriptor now, so nesting does not use lots of descriptors. */
4118 close (f);
4119
4120 /* Must do this before calling trigraph_pcp, so that the correct file name
4121 will be printed in warning messages. */
4122
4123 indepth++;
4124 input_file_stack_tick++;
4125
4126 if (!no_trigraphs)
4127 trigraph_pcp (fp);
4128
4129 if ((fp->length > 0 && fp->buf[fp->length - 1] != '\n')
4130 /* Backslash-newline at end is not good enough. */
4131 || (fp->length > 1 && fp->buf[fp->length - 2] == '\\')) {
4132 fp->buf[fp->length++] = '\n';
4133 missing_newline = 1;
4134 }
4135 fp->buf[fp->length] = '\0';
4136
4137 output_line_command (fp, op, 0, enter_file);
4138 rescan (op, 0);
4139
4140 if (pedantic && missing_newline)
4141 pedwarn ("file does not end in newline");
4142
4143 indepth--;
4144 input_file_stack_tick++;
4145 output_line_command (&instack[indepth], op, 0, leave_file);
4146 free (fp->buf);
4147 return;
4148
4149 nope:
4150
4151 perror_with_name (fname);
4152 close (f);
4153 free (fp->buf);
4154}
4155
4156/* Record that inclusion of the file named FILE
4157 should be controlled by the macro named MACRO_NAME.
4158 This means that trying to include the file again
4159 will do something if that macro is defined. */
4160
4161static void
4162record_control_macro (file, macro_name)
4163 char *file;
4164 U_CHAR *macro_name;
4165{
4166 struct file_name_list *new;
4167
4168 for (new = all_include_files; new; new = new->next) {
4169 if (!strcmp (new->fname, file)) {
4170 new->control_macro = macro_name;
4171 return;
4172 }
4173 }
4174
4175 /* If the file is not in all_include_files, something's wrong. */
4176 abort ();
4177}
4178\f
4179/* Maintain and search list of included files, for #import. */
4180
4181#define IMPORT_HASH_SIZE 31
4182
4183struct import_file {
4184 char *name;
4185 ino_t inode;
4186 dev_t dev;
4187 struct import_file *next;
4188};
4189
4190/* Hash table of files already included with #include or #import. */
4191
4192static struct import_file *import_hash_table[IMPORT_HASH_SIZE];
4193
4194/* Hash a file name for import_hash_table. */
4195
4196static int
4197import_hash (f)
4198 char *f;
4199{
4200 int val = 0;
4201
4202 while (*f) val += *f++;
4203 return (val%IMPORT_HASH_SIZE);
4204}
4205
4206/* Search for file FILENAME in import_hash_table.
4207 Return -2 if found, either a matching name or a matching inode.
4208 Otherwise, open the file and return a file descriptor if successful
4209 or -1 if unsuccessful. */
4210
4211static int
4212lookup_import (filename)
4213 char *filename;
4214{
4215 struct import_file *i;
4216 int h;
4217 int hashval;
4218 struct stat sb;
4219 int fd;
4220
4221 hashval = import_hash (filename);
4222
4223 /* Attempt to find file in list of already included files */
4224 i = import_hash_table[hashval];
4225
4226 while (i) {
4227 if (!strcmp (filename, i->name))
4228 return -2; /* return found */
4229 i = i->next;
4230 }
4231 /* Open it and try a match on inode/dev */
4232 fd = open (filename, O_RDONLY, 0666);
4233 if (fd < 0)
4234 return fd;
4235 fstat (fd, &sb);
4236 for (h = 0; h < IMPORT_HASH_SIZE; h++) {
4237 i = import_hash_table[h];
4238 while (i) {
4239 /* Compare the inode and the device.
4240 Supposedly on some systems the inode is not a scalar. */
4241 if (!bcmp (&i->inode, &sb.st_ino, sizeof (sb.st_ino))
4242 && i->dev == sb.st_dev) {
4243 close (fd);
4244 return -2; /* return found */
4245 }
4246 i = i->next;
4247 }
4248 }
4249 return fd; /* Not found, return open file */
4250}
4251
4252/* Add the file FNAME, open on descriptor FD, to import_hash_table. */
4253
4254static void
4255add_import (fd, fname)
4256 int fd;
4257 char *fname;
4258{
4259 struct import_file *i;
4260 int hashval;
4261 struct stat sb;
4262
4263 hashval = import_hash (fname);
4264 fstat (fd, &sb);
4265 i = (struct import_file *)xmalloc (sizeof (struct import_file));
4266 i->name = (char *)xmalloc (strlen (fname)+1);
4267 strcpy (i->name, fname);
4268 bcopy (&sb.st_ino, &i->inode, sizeof (sb.st_ino));
4269 i->dev = sb.st_dev;
4270 i->next = import_hash_table[hashval];
4271 import_hash_table[hashval] = i;
4272}
4273\f
4274/* Load the specified precompiled header into core, and verify its
4275 preconditions. PCF indicates the file descriptor to read, which must
4276 be a regular file. FNAME indicates the file name of the original
4277 header. *LIMIT will be set to an address one past the end of the file.
4278 If the preconditions of the file are not satisfied, the buffer is
4279 freed and we return 0. If the preconditions are satisfied, return
4280 the address of the buffer following the preconditions. The buffer, in
4281 this case, should never be freed because various pieces of it will
4282 be referred to until all precompiled strings are output at the end of
4283 the run.
4284*/
4285static char *
4286check_precompiled (pcf, fname, limit)
4287 int pcf;
4288 char *fname;
4289 char **limit;
4290{
4291 int st_mode;
4292 long st_size;
4293 int length = 0;
4294 char *buf;
4295 char *dollar_loc;
4296 int i;
4297 char *cp;
4298
4299 if (pcp_outfile)
4300 return 0;
4301
4302 if (file_size_and_mode (pcf, &st_mode, &st_size) < 0)
4303 return 0;
4304
4305 if (S_ISREG (st_mode))
4306 {
4307 buf = xmalloc (st_size + 2);
4308 while (st_size > 0)
4309 {
4310 i = read (pcf, buf + length, st_size);
4311 if (i < 0)
4312 goto nope;
4313 if (i == 0)
4314 break;
4315 length += i;
4316 st_size -= i;
4317 }
4318 }
4319 else
4320 abort ();
4321
4322 if (length > 0 && buf[length-1] != '\n')
4323 buf[length++] = '\n';
4324 buf[length] = '\0';
4325
4326 *limit = buf + length;
4327
4328 /* File is in core. Check the preconditions. */
4329 if (!check_preconditions (buf))
4330 goto nope;
4331 for (cp = buf; *cp; cp++)
4332 ;
4333#ifdef DEBUG_PCP
4334 fprintf (stderr, "Using preinclude %s\n", fname);
4335#endif
4336 return cp + 1;
4337
4338 nope:
4339#ifdef DEBUG_PCP
4340 fprintf (stderr, "Cannot use preinclude %s\n", fname);
4341#endif
4342 free (buf);
4343 return 0;
4344}
4345
4346/* PREC (null terminated) points to the preconditions of a
4347 precompiled header. These are a series of #define and #undef
4348 lines which must match the current contents of the hash
4349 table. */
4350static int
4351check_preconditions (prec)
4352 char *prec;
4353{
4354 MACRODEF mdef;
4355 char *lineend;
4356
4357 while (*prec) {
4358 lineend = (char *) index (prec, '\n');
4359
4360 if (*prec++ != '#') {
4361 error ("Bad format encountered while reading precompiled file");
4362 return 0;
4363 }
4364 if (!strncmp (prec, "define", 6)) {
4365 HASHNODE *hp;
4366
4367 prec += 6;
4368 mdef = create_definition (prec, lineend, NULL_PTR);
4369
4370 if (mdef.defn == 0)
4371 abort();
4372
4373 if ((hp = lookup (mdef.symnam, mdef.symlen, -1)) == NULL
4374 || (hp->type != T_MACRO && hp->type != T_CONST)
4375 || (hp->type == T_MACRO
4376 && !compare_defs (mdef.defn, hp->value.defn)
4377 && (mdef.defn->length != 2
4378 || mdef.defn->expansion[0] != '\n'
4379 || mdef.defn->expansion[1] != ' ')))
4380 return 0;
4381 } else if (!strncmp (prec, "undef", 5)) {
4382 char *name;
4383 int len;
4384
4385 prec += 5;
4386 while (is_hor_space[*prec])
4387 prec++;
4388 name = prec;
4389 while (is_idchar[*prec])
4390 prec++;
4391 len = prec - name;
4392
4393 if (lookup (name, len, -1))
4394 return 0;
4395 } else {
4396 error ("Bad format encountered while reading precompiled file");
4397 return 0;
4398 }
4399 prec = lineend + 1;
4400 }
4401 /* They all passed successfully */
4402 return 1;
4403}
4404
4405/* Process the main body of a precompiled file. BUF points to the
4406 string section of the file, following the preconditions. LIMIT is one
4407 character past the end. NAME is the name of the file being read
4408 in. OP is the main output buffer */
4409static void
4410pcfinclude (buf, limit, name, op)
4411 U_CHAR *buf, *limit, *name;
4412 FILE_BUF *op;
4413{
4414 FILE_BUF tmpbuf;
4415 int nstrings;
4416 U_CHAR *cp = buf;
4417
4418 /* First in the file comes 4 bytes indicating the number of strings, */
4419 /* in network byte order. (MSB first). */
4420 nstrings = *cp++;
4421 nstrings = (nstrings << 8) | *cp++;
4422 nstrings = (nstrings << 8) | *cp++;
4423 nstrings = (nstrings << 8) | *cp++;
4424
4425 /* Looping over each string... */
4426 while (nstrings--) {
4427 U_CHAR *string_start;
4428 U_CHAR *endofthiskey;
4429 STRINGDEF *str;
4430 int nkeys;
4431
4432 /* Each string starts with a STRINGDEF structure (str), followed */
4433 /* by the text of the string (string_start) */
4434
4435 /* First skip to a longword boundary */
4436 /* ??? Why a 4-byte boundary? On all machines? */
4437 /* NOTE: This works correctly even if HOST_WIDE_INT
4438 is narrower than a pointer.
4439 Do not try risky measures here to get another type to use!
4440 Do not include gstddef.h or stddef.h--either one will fail! */
4441 if ((HOST_WIDE_INT) cp & 3)
4442 cp += 4 - ((HOST_WIDE_INT) cp & 3);
4443
4444 /* Now get the string. */
4445 str = (STRINGDEF *) cp;
4446 string_start = cp += sizeof (STRINGDEF);
4447
4448 for (; *cp; cp++) /* skip the string */
4449 ;
4450
4451 /* We need to macro expand the string here to ensure that the
4452 proper definition environment is in place. If it were only
4453 expanded when we find out it is needed, macros necessary for
4454 its proper expansion might have had their definitions changed. */
4455 tmpbuf = expand_to_temp_buffer (string_start, cp++, 0, 0);
4456 /* Lineno is already set in the precompiled file */
4457 str->contents = tmpbuf.buf;
4458 str->len = tmpbuf.length;
4459 str->writeflag = 0;
4460 str->filename = name;
4461 str->output_mark = outbuf.bufp - outbuf.buf;
4462
4463 str->chain = 0;
4464 *stringlist_tailp = str;
4465 stringlist_tailp = &str->chain;
4466
4467 /* Next comes a fourbyte number indicating the number of keys */
4468 /* for this string. */
4469 nkeys = *cp++;
4470 nkeys = (nkeys << 8) | *cp++;
4471 nkeys = (nkeys << 8) | *cp++;
4472 nkeys = (nkeys << 8) | *cp++;
4473
4474 /* If this number is -1, then the string is mandatory. */
4475 if (nkeys == -1)
4476 str->writeflag = 1;
4477 else
4478 /* Otherwise, for each key, */
4479 for (; nkeys--; free (tmpbuf.buf), cp = endofthiskey + 1) {
4480 KEYDEF *kp = (KEYDEF *) cp;
4481 HASHNODE *hp;
4482
4483 /* It starts with a KEYDEF structure */
4484 cp += sizeof (KEYDEF);
4485
4486 /* Find the end of the key. At the end of this for loop we
4487 advance CP to the start of the next key using this variable. */
4488 endofthiskey = cp + strlen (cp);
4489 kp->str = str;
4490
4491 /* Expand the key, and enter it into the hash table. */
4492 tmpbuf = expand_to_temp_buffer (cp, endofthiskey, 0, 0);
4493 tmpbuf.bufp = tmpbuf.buf;
4494
4495 while (is_hor_space[*tmpbuf.bufp])
4496 tmpbuf.bufp++;
4497 if (!is_idstart[*tmpbuf.bufp]
4498 || tmpbuf.bufp == tmpbuf.buf + tmpbuf.length) {
4499 str->writeflag = 1;
4500 continue;
4501 }
4502
4503 hp = lookup (tmpbuf.bufp, -1, -1);
4504 if (hp == NULL) {
4505 kp->chain = 0;
4506 install (tmpbuf.bufp, -1, T_PCSTRING, 0, (char *) kp, -1);
4507 }
4508 else if (hp->type == T_PCSTRING) {
4509 kp->chain = hp->value.keydef;
4510 hp->value.keydef = kp;
4511 }
4512 else
4513 str->writeflag = 1;
4514 }
4515 }
4516 /* This output_line_command serves to switch us back to the current
4517 input file in case some of these strings get output (which will
4518 result in line commands for the header file being output). */
4519 output_line_command (&instack[indepth], op, 0, enter_file);
4520}
4521
4522/* Called from rescan when it hits a key for strings. Mark them all */
4523 /* used and clean up. */
4524static void
4525pcstring_used (hp)
4526 HASHNODE *hp;
4527{
4528 KEYDEF *kp, *tmp;
4529
4530 for (kp = hp->value.keydef; kp; kp = kp->chain)
4531 kp->str->writeflag = 1;
4532 delete_macro (hp);
4533}
4534
4535/* Write the output, interspersing precompiled strings in their */
4536 /* appropriate places. */
4537static void
4538write_output ()
4539{
4540 STRINGDEF *next_string;
4541 U_CHAR *cur_buf_loc;
4542 int line_command_len = 80;
4543 char *line_command = xmalloc (line_command_len);
4544 int len;
4545
4546 /* In each run through the loop, either cur_buf_loc == */
4547 /* next_string_loc, in which case we print a series of strings, or */
4548 /* it is less than next_string_loc, in which case we write some of */
4549 /* the buffer. */
4550 cur_buf_loc = outbuf.buf;
4551 next_string = stringlist;
4552
4553 while (cur_buf_loc < outbuf.bufp || next_string) {
4554 if (next_string
4555 && cur_buf_loc - outbuf.buf == next_string->output_mark) {
4556 if (next_string->writeflag) {
4557 len = strlen (next_string->filename);
4558 if (len > line_command_len)
4559 line_command = xrealloc (line_command,
4560 line_command_len *= 2);
4561 sprintf (line_command, "\n# %d \"%s\"\n",
4562 next_string->lineno, next_string->filename);
4563 write (fileno (stdout), line_command,
4564 strlen (line_command));
4565 write (fileno (stdout),
4566 next_string->contents, next_string->len);
4567 }
4568 next_string = next_string->chain;
4569 }
4570 else {
4571 len = (next_string
4572 ? (next_string->output_mark
4573 - (cur_buf_loc - outbuf.buf))
4574 : outbuf.bufp - cur_buf_loc);
4575
4576 write (fileno (stdout), cur_buf_loc, len);
4577 cur_buf_loc += len;
4578 }
4579 }
4580}
4581
4582/* Pass a directive through to the output file.
4583 BUF points to the contents of the directive, as a contiguous string.
4584 LIMIT points to the first character past the end of the directive.
4585 KEYWORD is the keyword-table entry for the directive. */
4586
4587static void
4588pass_thru_directive (buf, limit, op, keyword)
4589 U_CHAR *buf, *limit;
4590 FILE_BUF *op;
4591 struct directive *keyword;
4592{
4593 register unsigned keyword_length = keyword->length;
4594
4595 check_expand (op, 1 + keyword_length + (limit - buf));
4596 *op->bufp++ = '#';
4597 bcopy (keyword->name, op->bufp, keyword_length);
4598 op->bufp += keyword_length;
4599 if (limit != buf && buf[0] != ' ')
4600 *op->bufp++ = ' ';
4601 bcopy (buf, op->bufp, limit - buf);
4602 op->bufp += (limit - buf);
4603#if 0
4604 *op->bufp++ = '\n';
4605 /* Count the line we have just made in the output,
4606 to get in sync properly. */
4607 op->lineno++;
4608#endif
4609}
4610\f
4611/* The arglist structure is built by do_define to tell
4612 collect_definition where the argument names begin. That
4613 is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
4614 would contain pointers to the strings x, y, and z.
4615 Collect_definition would then build a DEFINITION node,
4616 with reflist nodes pointing to the places x, y, and z had
4617 appeared. So the arglist is just convenience data passed
4618 between these two routines. It is not kept around after
4619 the current #define has been processed and entered into the
4620 hash table. */
4621
4622struct arglist {
4623 struct arglist *next;
4624 U_CHAR *name;
4625 int length;
4626 int argno;
4627 char rest_args;
4628};
4629
4630/* Create a DEFINITION node from a #define directive. Arguments are
4631 as for do_define. */
4632static MACRODEF
4633create_definition (buf, limit, op)
4634 U_CHAR *buf, *limit;
4635 FILE_BUF *op;
4636{
4637 U_CHAR *bp; /* temp ptr into input buffer */
4638 U_CHAR *symname; /* remember where symbol name starts */
4639 int sym_length; /* and how long it is */
4640 int line = instack[indepth].lineno;
4641 char *file = instack[indepth].nominal_fname;
4642 int rest_args = 0;
4643
4644 DEFINITION *defn;
4645 int arglengths = 0; /* Accumulate lengths of arg names
4646 plus number of args. */
4647 MACRODEF mdef;
4648
4649 bp = buf;
4650
4651 while (is_hor_space[*bp])
4652 bp++;
4653
4654 symname = bp; /* remember where it starts */
4655 sym_length = check_macro_name (bp, "macro");
4656 bp += sym_length;
4657
4658 /* Lossage will occur if identifiers or control keywords are broken
4659 across lines using backslash. This is not the right place to take
4660 care of that. */
4661
4662 if (*bp == '(') {
4663 struct arglist *arg_ptrs = NULL;
4664 int argno = 0;
4665
4666 bp++; /* skip '(' */
4667 SKIP_WHITE_SPACE (bp);
4668
4669 /* Loop over macro argument names. */
4670 while (*bp != ')') {
4671 struct arglist *temp;
4672
4673 temp = (struct arglist *) alloca (sizeof (struct arglist));
4674 temp->name = bp;
4675 temp->next = arg_ptrs;
4676 temp->argno = argno++;
4677 temp->rest_args = 0;
4678 arg_ptrs = temp;
4679
4680 if (rest_args)
4681 pedwarn ("another parameter follows `%s'",
4682 rest_extension);
4683
4684 if (!is_idstart[*bp])
4685 pedwarn ("invalid character in macro parameter name");
4686
4687 /* Find the end of the arg name. */
4688 while (is_idchar[*bp]) {
4689 bp++;
4690 /* do we have a "special" rest-args extension here? */
4691 if (limit - bp > REST_EXTENSION_LENGTH &&
4692 strncmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) {
4693 rest_args = 1;
4694 temp->rest_args = 1;
4695 break;
4696 }
4697 }
4698 temp->length = bp - temp->name;
4699 if (rest_args == 1)
4700 bp += REST_EXTENSION_LENGTH;
4701 arglengths += temp->length + 2;
4702 SKIP_WHITE_SPACE (bp);
4703 if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
4704 error ("badly punctuated parameter list in `#define'");
4705 goto nope;
4706 }
4707 if (*bp == ',') {
4708 bp++;
4709 SKIP_WHITE_SPACE (bp);
4710 }
4711 if (bp >= limit) {
4712 error ("unterminated parameter list in `#define'");
4713 goto nope;
4714 }
4715 {
4716 struct arglist *otemp;
4717
4718 for (otemp = temp->next; otemp != NULL; otemp = otemp->next)
4719 if (temp->length == otemp->length &&
4720 strncmp(temp->name, otemp->name, temp->length) == 0) {
4721 U_CHAR *name;
4722
4723 name = (U_CHAR *) alloca(temp->length + 1);
4724 (void) strncpy(name, temp->name, temp->length);
4725 name[temp->length] = '\0';
4726 error ("duplicate argument name `%s' in `#define'", name);
4727 goto nope;
4728 }
4729 }
4730 }
4731
4732 ++bp; /* skip paren */
4733 /* Skip exactly one space or tab if any. */
4734 if (bp < limit && (*bp == ' ' || *bp == '\t')) ++bp;
4735 /* now everything from bp before limit is the definition. */
4736 defn = collect_expansion (bp, limit, argno, arg_ptrs);
4737 defn->rest_args = rest_args;
4738
4739 /* Now set defn->args.argnames to the result of concatenating
4740 the argument names in reverse order
4741 with comma-space between them. */
4742 defn->args.argnames = (U_CHAR *) xmalloc (arglengths + 1);
4743 {
4744 struct arglist *temp;
4745 int i = 0;
4746 for (temp = arg_ptrs; temp; temp = temp->next) {
4747 bcopy (temp->name, &defn->args.argnames[i], temp->length);
4748 i += temp->length;
4749 if (temp->next != 0) {
4750 defn->args.argnames[i++] = ',';
4751 defn->args.argnames[i++] = ' ';
4752 }
4753 }
4754 defn->args.argnames[i] = 0;
4755 }
4756 } else {
4757 /* simple expansion or empty definition; gobble it */
4758 if (is_hor_space[*bp])
4759 ++bp; /* skip exactly one blank/tab char */
4760 /* now everything from bp before limit is the definition. */
4761 defn = collect_expansion (bp, limit, -1, NULL_PTR);
4762 defn->args.argnames = (U_CHAR *) "";
4763 }
4764
4765 defn->line = line;
4766 defn->file = file;
4767
4768 /* OP is null if this is a predefinition */
4769 defn->predefined = !op;
4770 mdef.defn = defn;
4771 mdef.symnam = symname;
4772 mdef.symlen = sym_length;
4773
4774 return mdef;
4775
4776 nope:
4777 mdef.defn = 0;
4778 return mdef;
4779}
4780
4781/* Process a #define command.
4782BUF points to the contents of the #define command, as a contiguous string.
4783LIMIT points to the first character past the end of the definition.
4784KEYWORD is the keyword-table entry for #define. */
4785
4786static int
4787do_define (buf, limit, op, keyword)
4788 U_CHAR *buf, *limit;
4789 FILE_BUF *op;
4790 struct directive *keyword;
4791{
4792 int hashcode;
4793 MACRODEF mdef;
4794
4795 /* If this is a precompiler run (with -pcp) pass thru #define commands. */
4796 if (pcp_outfile && op)
4797 pass_thru_directive (buf, limit, op, keyword);
4798
4799 mdef = create_definition (buf, limit, op);
4800 if (mdef.defn == 0)
4801 goto nope;
4802
4803 hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
4804
4805 {
4806 HASHNODE *hp;
4807 if ((hp = lookup (mdef.symnam, mdef.symlen, hashcode)) != NULL) {
4808 int ok = 0;
4809 /* Redefining a precompiled key is ok. */
4810 if (hp->type == T_PCSTRING)
4811 ok = 1;
4812 /* Redefining a macro is ok if the definitions are the same. */
4813 else if (hp->type == T_MACRO)
4814 ok = ! compare_defs (mdef.defn, hp->value.defn);
4815 /* Redefining a constant is ok with -D. */
4816 else if (hp->type == T_CONST)
4817 ok = ! done_initializing;
4818 /* Print the warning if it's not ok. */
4819 if (!ok) {
4820 U_CHAR *msg; /* what pain... */
4821
4822 /* If we are passing through #define and #undef directives, do
4823 that for this re-definition now. */
4824 if (debug_output && op)
4825 pass_thru_directive (buf, limit, op, keyword);
4826
4827 msg = (U_CHAR *) alloca (mdef.symlen + 22);
4828 *msg = '`';
4829 bcopy (mdef.symnam, msg + 1, mdef.symlen);
4830 strcpy ((char *) (msg + mdef.symlen + 1), "' redefined");
4831 pedwarn (msg);
4832 if (hp->type == T_MACRO)
4833 pedwarn_with_file_and_line (hp->value.defn->file, hp->value.defn->line,
4834 "this is the location of the previous definition");
4835 }
4836 /* Replace the old definition. */
4837 hp->type = T_MACRO;
4838 hp->value.defn = mdef.defn;
4839 } else {
4840 /* If we are passing through #define and #undef directives, do
4841 that for this new definition now. */
4842 if (debug_output && op)
4843 pass_thru_directive (buf, limit, op, keyword);
4844 install (mdef.symnam, mdef.symlen, T_MACRO, 0,
4845 (char *) mdef.defn, hashcode);
4846 }
4847 }
4848
4849 return 0;
4850
4851nope:
4852
4853 return 1;
4854}
4855\f
4856/* Check a purported macro name SYMNAME, and yield its length.
4857 USAGE is the kind of name this is intended for. */
4858
4859static int
4860check_macro_name (symname, usage)
4861 U_CHAR *symname;
4862 char *usage;
4863{
4864 U_CHAR *p;
4865 int sym_length;
4866
4867 for (p = symname; is_idchar[*p]; p++)
4868 ;
4869 sym_length = p - symname;
4870 if (sym_length == 0)
4871 error ("invalid %s name", usage);
4872 else if (!is_idstart[*symname]) {
4873 U_CHAR *msg; /* what pain... */
4874 msg = (U_CHAR *) alloca (sym_length + 1);
4875 bcopy (symname, msg, sym_length);
4876 msg[sym_length] = 0;
4877 error ("invalid %s name `%s'", usage, msg);
4878 } else {
4879 if (! strncmp (symname, "defined", 7) && sym_length == 7)
4880 error ("invalid %s name `defined'", usage);
4881 }
4882 return sym_length;
4883}
4884
4885/*
4886 * return zero if two DEFINITIONs are isomorphic
4887 */
4888static int
4889compare_defs (d1, d2)
4890 DEFINITION *d1, *d2;
4891{
4892 register struct reflist *a1, *a2;
4893 register U_CHAR *p1 = d1->expansion;
4894 register U_CHAR *p2 = d2->expansion;
4895 int first = 1;
4896
4897 if (d1->nargs != d2->nargs)
4898 return 1;
4899 if (strcmp ((char *)d1->args.argnames, (char *)d2->args.argnames))
4900 return 1;
4901 for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
4902 a1 = a1->next, a2 = a2->next) {
4903 if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars))
4904 || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
4905 || a1->argno != a2->argno
4906 || a1->stringify != a2->stringify
4907 || a1->raw_before != a2->raw_before
4908 || a1->raw_after != a2->raw_after)
4909 return 1;
4910 first = 0;
4911 p1 += a1->nchars;
4912 p2 += a2->nchars;
4913 }
4914 if (a1 != a2)
4915 return 1;
4916 if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
4917 p2, d2->length - (p2 - d2->expansion), 1))
4918 return 1;
4919 return 0;
4920}
4921
4922/* Return 1 if two parts of two macro definitions are effectively different.
4923 One of the parts starts at BEG1 and has LEN1 chars;
4924 the other has LEN2 chars at BEG2.
4925 Any sequence of whitespace matches any other sequence of whitespace.
4926 FIRST means these parts are the first of a macro definition;
4927 so ignore leading whitespace entirely.
4928 LAST means these parts are the last of a macro definition;
4929 so ignore trailing whitespace entirely. */
4930
4931static int
4932comp_def_part (first, beg1, len1, beg2, len2, last)
4933 int first;
4934 U_CHAR *beg1, *beg2;
4935 int len1, len2;
4936 int last;
4937{
4938 register U_CHAR *end1 = beg1 + len1;
4939 register U_CHAR *end2 = beg2 + len2;
4940 if (first) {
4941 while (beg1 != end1 && is_space[*beg1]) beg1++;
4942 while (beg2 != end2 && is_space[*beg2]) beg2++;
4943 }
4944 if (last) {
4945 while (beg1 != end1 && is_space[end1[-1]]) end1--;
4946 while (beg2 != end2 && is_space[end2[-1]]) end2--;
4947 }
4948 while (beg1 != end1 && beg2 != end2) {
4949 if (is_space[*beg1] && is_space[*beg2]) {
4950 while (beg1 != end1 && is_space[*beg1]) beg1++;
4951 while (beg2 != end2 && is_space[*beg2]) beg2++;
4952 } else if (*beg1 == *beg2) {
4953 beg1++; beg2++;
4954 } else break;
4955 }
4956 return (beg1 != end1) || (beg2 != end2);
4957}
4958\f
4959/* Read a replacement list for a macro with parameters.
4960 Build the DEFINITION structure.
4961 Reads characters of text starting at BUF until END.
4962 ARGLIST specifies the formal parameters to look for
4963 in the text of the definition; NARGS is the number of args
4964 in that list, or -1 for a macro name that wants no argument list.
4965 MACRONAME is the macro name itself (so we can avoid recursive expansion)
4966 and NAMELEN is its length in characters.
4967
4968Note that comments and backslash-newlines have already been deleted
4969from the argument. */
4970
4971/* Leading and trailing Space, Tab, etc. are converted to markers
4972 Newline Space, Newline Tab, etc.
4973 Newline Space makes a space in the final output
4974 but is discarded if stringified. (Newline Tab is similar but
4975 makes a Tab instead.)
4976
4977 If there is no trailing whitespace, a Newline Space is added at the end
4978 to prevent concatenation that would be contrary to the standard. */
4979
4980static DEFINITION *
4981collect_expansion (buf, end, nargs, arglist)
4982 U_CHAR *buf, *end;
4983 int nargs;
4984 struct arglist *arglist;
4985{
4986 DEFINITION *defn;
4987 register U_CHAR *p, *limit, *lastp, *exp_p;
4988 struct reflist *endpat = NULL;
4989 /* Pointer to first nonspace after last ## seen. */
4990 U_CHAR *concat = 0;
4991 /* Pointer to first nonspace after last single-# seen. */
4992 U_CHAR *stringify = 0;
4993 int maxsize;
4994 int expected_delimiter = '\0';
4995
4996 /* Scan thru the replacement list, ignoring comments and quoted
4997 strings, picking up on the macro calls. It does a linear search
4998 thru the arg list on every potential symbol. Profiling might say
4999 that something smarter should happen. */
5000
5001 if (end < buf)
5002 abort ();
5003
5004 /* Find the beginning of the trailing whitespace. */
5005 /* Find end of leading whitespace. */
5006 limit = end;
5007 p = buf;
5008 while (p < limit && is_space[limit[-1]]) limit--;
5009 while (p < limit && is_space[*p]) p++;
5010
5011 /* Allocate space for the text in the macro definition.
5012 Leading and trailing whitespace chars need 2 bytes each.
5013 Each other input char may or may not need 1 byte,
5014 so this is an upper bound.
5015 The extra 2 are for invented trailing newline-marker and final null. */
5016 maxsize = (sizeof (DEFINITION)
5017 + 2 * (end - limit) + 2 * (p - buf)
5018 + (limit - p) + 3);
5019 defn = (DEFINITION *) xcalloc (1, maxsize);
5020
5021 defn->nargs = nargs;
5022 exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
5023 lastp = exp_p;
5024
5025 p = buf;
5026
5027 /* Convert leading whitespace to Newline-markers. */
5028 while (p < limit && is_space[*p]) {
5029 *exp_p++ = '\n';
5030 *exp_p++ = *p++;
5031 }
5032
5033 if (limit - p >= 2 && p[0] == '#' && p[1] == '#') {
5034 error ("`##' at start of macro definition");
5035 p += 2;
5036 }
5037
5038 /* Process the main body of the definition. */
5039 while (p < limit) {
5040 int skipped_arg = 0;
5041 register U_CHAR c = *p++;
5042
5043 *exp_p++ = c;
5044
5045 if (!traditional) {
5046 switch (c) {
5047 case '\'':
5048 case '\"':
5049 if (expected_delimiter != '\0') {
5050 if (c == expected_delimiter)
5051 expected_delimiter = '\0';
5052 } else
5053 expected_delimiter = c;
5054 break;
5055
5056 /* Special hack: if a \# is written in the #define
5057 include a # in the definition. This is useless for C code
5058 but useful for preprocessing other things. */
5059
5060 case '\\':
5061 /* \# quotes a # even outside of strings. */
5062 if (p < limit && *p == '#' && !expected_delimiter) {
5063 exp_p--;
5064 *exp_p++ = *p++;
5065 } else if (p < limit && expected_delimiter) {
5066 /* In a string, backslash goes through
5067 and makes next char ordinary. */
5068 *exp_p++ = *p++;
5069 }
5070 break;
5071
5072 case '#':
5073 /* # is ordinary inside a string. */
5074 if (expected_delimiter)
5075 break;
5076 if (p < limit && *p == '#') {
5077 /* ##: concatenate preceding and following tokens. */
5078 /* Take out the first #, discard preceding whitespace. */
5079 exp_p--;
5080 while (exp_p > lastp && is_hor_space[exp_p[-1]])
5081 --exp_p;
5082 /* Skip the second #. */
5083 p++;
5084 /* Discard following whitespace. */
5085 SKIP_WHITE_SPACE (p);
5086 concat = p;
5087 if (p == limit)
5088 error ("`##' at end of macro definition");
5089 } else {
5090 /* Single #: stringify following argument ref.
5091 Don't leave the # in the expansion. */
5092 exp_p--;
5093 SKIP_WHITE_SPACE (p);
5094 if (p == limit || ! is_idstart[*p] || nargs <= 0)
5095 error ("`#' operator is not followed by a macro argument name");
5096 else
5097 stringify = p;
5098 }
5099 break;
5100 }
5101 } else {
5102 /* In -traditional mode, recognize arguments inside strings and
5103 and character constants, and ignore special properties of #.
5104 Arguments inside strings are considered "stringified", but no
5105 extra quote marks are supplied. */
5106 switch (c) {
5107 case '\'':
5108 case '\"':
5109 if (expected_delimiter != '\0') {
5110 if (c == expected_delimiter)
5111 expected_delimiter = '\0';
5112 } else
5113 expected_delimiter = c;
5114 break;
5115
5116 case '\\':
5117 /* Backslash quotes delimiters and itself, but not macro args. */
5118 if (expected_delimiter != 0 && p < limit
5119 && (*p == expected_delimiter || *p == '\\')) {
5120 *exp_p++ = *p++;
5121 continue;
5122 }
5123 break;
5124
5125 case '/':
5126 if (expected_delimiter != '\0') /* No comments inside strings. */
5127 break;
5128 if (*p == '*') {
5129 /* If we find a comment that wasn't removed by handle_directive,
5130 this must be -traditional. So replace the comment with
5131 nothing at all. */
5132 exp_p--;
5133 p += 1;
5134 while (p < limit && !(p[-2] == '*' && p[-1] == '/'))
5135 p++;
5136#if 0
5137 /* Mark this as a concatenation-point, as if it had been ##. */
5138 concat = p;
5139#endif
5140 }
5141 break;
5142 }
5143 }
5144
5145 /* Handle the start of a symbol. */
5146 if (is_idchar[c] && nargs > 0) {
5147 U_CHAR *id_beg = p - 1;
5148 int id_len;
5149
5150 --exp_p;
5151 while (p != limit && is_idchar[*p]) p++;
5152 id_len = p - id_beg;
5153
5154 if (is_idstart[c]) {
5155 register struct arglist *arg;
5156
5157 for (arg = arglist; arg != NULL; arg = arg->next) {
5158 struct reflist *tpat;
5159
5160 if (arg->name[0] == c
5161 && arg->length == id_len
5162 && strncmp (arg->name, id_beg, id_len) == 0) {
5163 if (expected_delimiter && warn_stringify) {
5164 if (traditional) {
5165 warning ("macro argument `%.*s' is stringified.",
5166 id_len, arg->name);
5167 } else {
5168 warning ("macro arg `%.*s' would be stringified with -traditional.",
5169 id_len, arg->name);
5170 }
5171 }
5172 /* If ANSI, don't actually substitute inside a string. */
5173 if (!traditional && expected_delimiter)
5174 break;
5175 /* make a pat node for this arg and append it to the end of
5176 the pat list */
5177 tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
5178 tpat->next = NULL;
5179 tpat->raw_before = concat == id_beg;
5180 tpat->raw_after = 0;
5181 tpat->rest_args = arg->rest_args;
5182 tpat->stringify = (traditional ? expected_delimiter != '\0'
5183 : stringify == id_beg);
5184
5185 if (endpat == NULL)
5186 defn->pattern = tpat;
5187 else
5188 endpat->next = tpat;
5189 endpat = tpat;
5190
5191 tpat->argno = arg->argno;
5192 tpat->nchars = exp_p - lastp;
5193 {
5194 register U_CHAR *p1 = p;
5195 SKIP_WHITE_SPACE (p1);
5196 if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
5197 tpat->raw_after = 1;
5198 }
5199 lastp = exp_p; /* place to start copying from next time */
5200 skipped_arg = 1;
5201 break;
5202 }
5203 }
5204 }
5205
5206 /* If this was not a macro arg, copy it into the expansion. */
5207 if (! skipped_arg) {
5208 register U_CHAR *lim1 = p;
5209 p = id_beg;
5210 while (p != lim1)
5211 *exp_p++ = *p++;
5212 if (stringify == id_beg)
5213 error ("`#' operator should be followed by a macro argument name");
5214 }
5215 }
5216 }
5217
5218 if (limit < end) {
5219 /* Convert trailing whitespace to Newline-markers. */
5220 while (limit < end && is_space[*limit]) {
5221 *exp_p++ = '\n';
5222 *exp_p++ = *limit++;
5223 }
5224 } else if (!traditional && expected_delimiter == 0) {
5225 /* There is no trailing whitespace, so invent some in ANSI mode.
5226 But not if "inside a string" (which in ANSI mode
5227 happens only for -D option). */
5228 *exp_p++ = '\n';
5229 *exp_p++ = ' ';
5230 }
5231
5232 *exp_p = '\0';
5233
5234 defn->length = exp_p - defn->expansion;
5235
5236 /* Crash now if we overrun the allocated size. */
5237 if (defn->length + 1 > maxsize)
5238 abort ();
5239
5240#if 0
5241/* This isn't worth the time it takes. */
5242 /* give back excess storage */
5243 defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
5244#endif
5245
5246 return defn;
5247}
5248\f
5249static int
5250do_assert (buf, limit, op, keyword)
5251 U_CHAR *buf, *limit;
5252 FILE_BUF *op;
5253 struct directive *keyword;
5254{
5255 U_CHAR *bp; /* temp ptr into input buffer */
5256 U_CHAR *symname; /* remember where symbol name starts */
5257 int sym_length; /* and how long it is */
5258 struct arglist *tokens = NULL;
5259
5260 if (pedantic && done_initializing && !instack[indepth].system_header_p)
5261 pedwarn ("ANSI C does not allow `#assert'");
5262
5263 bp = buf;
5264
5265 while (is_hor_space[*bp])
5266 bp++;
5267
5268 symname = bp; /* remember where it starts */
5269 sym_length = check_macro_name (bp, "assertion");
5270 bp += sym_length;
5271 /* #define doesn't do this, but we should. */
5272 SKIP_WHITE_SPACE (bp);
5273
5274 /* Lossage will occur if identifiers or control tokens are broken
5275 across lines using backslash. This is not the right place to take
5276 care of that. */
5277
5278 if (*bp != '(') {
5279 error ("missing token-sequence in `#assert'");
5280 return 1;
5281 }
5282
5283 {
5284 int error_flag = 0;
5285
5286 bp++; /* skip '(' */
5287 SKIP_WHITE_SPACE (bp);
5288
5289 tokens = read_token_list (&bp, limit, &error_flag);
5290 if (error_flag)
5291 return 1;
5292 if (tokens == 0) {
5293 error ("empty token-sequence in `#assert'");
5294 return 1;
5295 }
5296
5297 ++bp; /* skip paren */
5298 SKIP_WHITE_SPACE (bp);
5299 }
5300
5301 /* If this name isn't already an assertion name, make it one.
5302 Error if it was already in use in some other way. */
5303
5304 {
5305 ASSERTION_HASHNODE *hp;
5306 int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
5307 struct tokenlist_list *value
5308 = (struct tokenlist_list *) xmalloc (sizeof (struct tokenlist_list));
5309
5310 hp = assertion_lookup (symname, sym_length, hashcode);
5311 if (hp == NULL) {
5312 if (sym_length == 7 && ! strncmp (symname, "defined", sym_length))
5313 error ("`defined' redefined as assertion");
5314 hp = assertion_install (symname, sym_length, hashcode);
5315 }
5316
5317 /* Add the spec'd token-sequence to the list of such. */
5318 value->tokens = tokens;
5319 value->next = hp->value;
5320 hp->value = value;
5321 }
5322
5323 return 0;
5324}
5325\f
5326static int
5327do_unassert (buf, limit, op, keyword)
5328 U_CHAR *buf, *limit;
5329 FILE_BUF *op;
5330 struct directive *keyword;
5331{
5332 U_CHAR *bp; /* temp ptr into input buffer */
5333 U_CHAR *symname; /* remember where symbol name starts */
5334 int sym_length; /* and how long it is */
5335
5336 struct arglist *tokens = NULL;
5337 int tokens_specified = 0;
5338
5339 if (pedantic && done_initializing && !instack[indepth].system_header_p)
5340 pedwarn ("ANSI C does not allow `#unassert'");
5341
5342 bp = buf;
5343
5344 while (is_hor_space[*bp])
5345 bp++;
5346
5347 symname = bp; /* remember where it starts */
5348 sym_length = check_macro_name (bp, "assertion");
5349 bp += sym_length;
5350 /* #define doesn't do this, but we should. */
5351 SKIP_WHITE_SPACE (bp);
5352
5353 /* Lossage will occur if identifiers or control tokens are broken
5354 across lines using backslash. This is not the right place to take
5355 care of that. */
5356
5357 if (*bp == '(') {
5358 int error_flag = 0;
5359
5360 bp++; /* skip '(' */
5361 SKIP_WHITE_SPACE (bp);
5362
5363 tokens = read_token_list (&bp, limit, &error_flag);
5364 if (error_flag)
5365 return 1;
5366 if (tokens == 0) {
5367 error ("empty token list in `#unassert'");
5368 return 1;
5369 }
5370
5371 tokens_specified = 1;
5372
5373 ++bp; /* skip paren */
5374 SKIP_WHITE_SPACE (bp);
5375 }
5376
5377 {
5378 ASSERTION_HASHNODE *hp;
5379 int hashcode = hashf (symname, sym_length, ASSERTION_HASHSIZE);
5380 struct tokenlist_list *tail, *prev;
5381
5382 hp = assertion_lookup (symname, sym_length, hashcode);
5383 if (hp == NULL)
5384 return 1;
5385
5386 /* If no token list was specified, then eliminate this assertion
5387 entirely. */
5388 if (! tokens_specified) {
5389 struct tokenlist_list *next;
5390 for (tail = hp->value; tail; tail = next) {
5391 next = tail->next;
5392 free_token_list (tail->tokens);
5393 free (tail);
5394 }
5395 delete_assertion (hp);
5396 } else {
5397 /* If a list of tokens was given, then delete any matching list. */
5398
5399 tail = hp->value;
5400 prev = 0;
5401 while (tail) {
5402 struct tokenlist_list *next = tail->next;
5403 if (compare_token_lists (tail->tokens, tokens)) {
5404 if (prev)
5405 prev->next = next;
5406 else
5407 hp->value = tail->next;
5408 free_token_list (tail->tokens);
5409 free (tail);
5410 } else {
5411 prev = tail;
5412 }
5413 tail = next;
5414 }
5415 }
5416 }
5417
5418 return 0;
5419}
5420\f
5421/* Test whether there is an assertion named NAME
5422 and optionally whether it has an asserted token list TOKENS.
5423 NAME is not null terminated; its length is SYM_LENGTH.
5424 If TOKENS_SPECIFIED is 0, then don't check for any token list. */
5425
5426int
5427check_assertion (name, sym_length, tokens_specified, tokens)
5428 U_CHAR *name;
5429 int sym_length;
5430 int tokens_specified;
5431 struct arglist *tokens;
5432{
5433 ASSERTION_HASHNODE *hp;
5434 int hashcode = hashf (name, sym_length, ASSERTION_HASHSIZE);
5435
5436 if (pedantic && !instack[indepth].system_header_p)
5437 pedwarn ("ANSI C does not allow testing assertions");
5438
5439 hp = assertion_lookup (name, sym_length, hashcode);
5440 if (hp == NULL)
5441 /* It is not an assertion; just return false. */
5442 return 0;
5443
5444 /* If no token list was specified, then value is 1. */
5445 if (! tokens_specified)
5446 return 1;
5447
5448 {
5449 struct tokenlist_list *tail;
5450
5451 tail = hp->value;
5452
5453 /* If a list of tokens was given,
5454 then succeed if the assertion records a matching list. */
5455
5456 while (tail) {
5457 if (compare_token_lists (tail->tokens, tokens))
5458 return 1;
5459 tail = tail->next;
5460 }
5461
5462 /* Fail if the assertion has no matching list. */
5463 return 0;
5464 }
5465}
5466
5467/* Compare two lists of tokens for equality including order of tokens. */
5468
5469static int
5470compare_token_lists (l1, l2)
5471 struct arglist *l1, *l2;
5472{
5473 while (l1 && l2) {
5474 if (l1->length != l2->length)
5475 return 0;
5476 if (strncmp (l1->name, l2->name, l1->length))
5477 return 0;
5478 l1 = l1->next;
5479 l2 = l2->next;
5480 }
5481
5482 /* Succeed if both lists end at the same time. */
5483 return l1 == l2;
5484}
5485\f
5486/* Read a space-separated list of tokens ending in a close parenthesis.
5487 Return a list of strings, in the order they were written.
5488 (In case of error, return 0 and store -1 in *ERROR_FLAG.)
5489 Parse the text starting at *BPP, and update *BPP.
5490 Don't parse beyond LIMIT. */
5491
5492static struct arglist *
5493read_token_list (bpp, limit, error_flag)
5494 U_CHAR **bpp;
5495 U_CHAR *limit;
5496 int *error_flag;
5497{
5498 struct arglist *token_ptrs = 0;
5499 U_CHAR *bp = *bpp;
5500 int depth = 1;
5501
5502 *error_flag = 0;
5503
5504 /* Loop over the assertion value tokens. */
5505 while (depth > 0) {
5506 struct arglist *temp;
5507 int eofp = 0;
5508 U_CHAR *beg = bp;
5509
5510 /* Find the end of the token. */
5511 if (*bp == '(') {
5512 bp++;
5513 depth++;
5514 } else if (*bp == ')') {
5515 depth--;
5516 if (depth == 0)
5517 break;
5518 bp++;
5519 } else if (*bp == '"' || *bp == '\'')
5520 bp = skip_quoted_string (bp, limit, 0, NULL_PTR, NULL_PTR, &eofp);
5521 else
5522 while (! is_hor_space[*bp] && *bp != '(' && *bp != ')'
5523 && *bp != '"' && *bp != '\'' && bp != limit)
5524 bp++;
5525
5526 temp = (struct arglist *) xmalloc (sizeof (struct arglist));
5527 temp->name = (U_CHAR *) xmalloc (bp - beg + 1);
5528 bcopy (beg, temp->name, bp - beg);
5529 temp->name[bp - beg] = 0;
5530 temp->next = token_ptrs;
5531 token_ptrs = temp;
5532 temp->length = bp - beg;
5533
5534 SKIP_WHITE_SPACE (bp);
5535
5536 if (bp >= limit) {
5537 error ("unterminated token sequence in `#assert' or `#unassert'");
5538 *error_flag = -1;
5539 return 0;
5540 }
5541 }
5542 *bpp = bp;
5543
5544 /* We accumulated the names in reverse order.
5545 Now reverse them to get the proper order. */
5546 {
5547 register struct arglist *prev = 0, *this, *next;
5548 for (this = token_ptrs; this; this = next) {
5549 next = this->next;
5550 this->next = prev;
5551 prev = this;
5552 }
5553 return prev;
5554 }
5555}
5556
5557static void
5558free_token_list (tokens)
5559 struct arglist *tokens;
5560{
5561 while (tokens) {
5562 struct arglist *next = tokens->next;
5563 free (tokens->name);
5564 free (tokens);
5565 tokens = next;
5566 }
5567}
5568\f
5569/*
5570 * Install a name in the assertion hash table.
5571 *
5572 * If LEN is >= 0, it is the length of the name.
5573 * Otherwise, compute the length by scanning the entire name.
5574 *
5575 * If HASH is >= 0, it is the precomputed hash code.
5576 * Otherwise, compute the hash code.
5577 */
5578static ASSERTION_HASHNODE *
5579assertion_install (name, len, hash)
5580 U_CHAR *name;
5581 int len;
5582 int hash;
5583{
5584 register ASSERTION_HASHNODE *hp;
5585 register int i, bucket;
5586 register U_CHAR *p, *q;
5587
5588 i = sizeof (ASSERTION_HASHNODE) + len + 1;
5589 hp = (ASSERTION_HASHNODE *) xmalloc (i);
5590 bucket = hash;
5591 hp->bucket_hdr = &assertion_hashtab[bucket];
5592 hp->next = assertion_hashtab[bucket];
5593 assertion_hashtab[bucket] = hp;
5594 hp->prev = NULL;
5595 if (hp->next != NULL)
5596 hp->next->prev = hp;
5597 hp->length = len;
5598 hp->value = 0;
5599 hp->name = ((U_CHAR *) hp) + sizeof (ASSERTION_HASHNODE);
5600 p = hp->name;
5601 q = name;
5602 for (i = 0; i < len; i++)
5603 *p++ = *q++;
5604 hp->name[len] = 0;
5605 return hp;
5606}
5607
5608/*
5609 * find the most recent hash node for name name (ending with first
5610 * non-identifier char) installed by install
5611 *
5612 * If LEN is >= 0, it is the length of the name.
5613 * Otherwise, compute the length by scanning the entire name.
5614 *
5615 * If HASH is >= 0, it is the precomputed hash code.
5616 * Otherwise, compute the hash code.
5617 */
5618static ASSERTION_HASHNODE *
5619assertion_lookup (name, len, hash)
5620 U_CHAR *name;
5621 int len;
5622 int hash;
5623{
5624 register U_CHAR *bp;
5625 register ASSERTION_HASHNODE *bucket;
5626
5627 bucket = assertion_hashtab[hash];
5628 while (bucket) {
5629 if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
5630 return bucket;
5631 bucket = bucket->next;
5632 }
5633 return NULL;
5634}
5635
5636static void
5637delete_assertion (hp)
5638 ASSERTION_HASHNODE *hp;
5639{
5640
5641 if (hp->prev != NULL)
5642 hp->prev->next = hp->next;
5643 if (hp->next != NULL)
5644 hp->next->prev = hp->prev;
5645
5646 /* make sure that the bucket chain header that
5647 the deleted guy was on points to the right thing afterwards. */
5648 if (hp == *hp->bucket_hdr)
5649 *hp->bucket_hdr = hp->next;
5650
5651 free (hp);
5652}
5653\f
5654/*
5655 * interpret #line command. Remembers previously seen fnames
5656 * in its very own hash table.
5657 */
5658#define FNAME_HASHSIZE 37
5659
5660static int
5661do_line (buf, limit, op, keyword)
5662 U_CHAR *buf, *limit;
5663 FILE_BUF *op;
5664 struct directive *keyword;
5665{
5666 register U_CHAR *bp;
5667 FILE_BUF *ip = &instack[indepth];
5668 FILE_BUF tem;
5669 int new_lineno;
5670 enum file_change_code file_change = same_file;
5671
5672 /* Expand any macros. */
5673 tem = expand_to_temp_buffer (buf, limit, 0, 0);
5674
5675 /* Point to macroexpanded line, which is null-terminated now. */
5676 bp = tem.buf;
5677 SKIP_WHITE_SPACE (bp);
5678
5679 if (!isdigit (*bp)) {
5680 error ("invalid format `#line' command");
5681 return 0;
5682 }
5683
5684 /* The Newline at the end of this line remains to be processed.
5685 To put the next line at the specified line number,
5686 we must store a line number now that is one less. */
5687 new_lineno = atoi (bp) - 1;
5688
5689 /* skip over the line number. */
5690 while (isdigit (*bp))
5691 bp++;
5692
5693#if 0 /* #line 10"foo.c" is supposed to be allowed. */
5694 if (*bp && !is_space[*bp]) {
5695 error ("invalid format `#line' command");
5696 return;
5697 }
5698#endif
5699
5700 SKIP_WHITE_SPACE (bp);
5701
5702 if (*bp == '\"') {
5703 static HASHNODE *fname_table[FNAME_HASHSIZE];
5704 HASHNODE *hp, **hash_bucket;
5705 U_CHAR *fname;
5706 int fname_length;
5707
5708 fname = ++bp;
5709
5710 while (*bp && *bp != '\"')
5711 bp++;
5712 if (*bp != '\"') {
5713 error ("invalid format `#line' command");
5714 return 0;
5715 }
5716
5717 fname_length = bp - fname;
5718
5719 bp++;
5720 SKIP_WHITE_SPACE (bp);
5721 if (*bp) {
5722 if (*bp == '1')
5723 file_change = enter_file;
5724 else if (*bp == '2')
5725 file_change = leave_file;
5726 else if (*bp == '3')
5727 ip->system_header_p = 1;
5728 else {
5729 error ("invalid format `#line' command");
5730 return 0;
5731 }
5732
5733 bp++;
5734 SKIP_WHITE_SPACE (bp);
5735 if (*bp == '3') {
5736 ip->system_header_p = 1;
5737 bp++;
5738 SKIP_WHITE_SPACE (bp);
5739 }
5740 if (*bp) {
5741 error ("invalid format `#line' command");
5742 return 0;
5743 }
5744 }
5745
5746 hash_bucket =
5747 &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
5748 for (hp = *hash_bucket; hp != NULL; hp = hp->next)
5749 if (hp->length == fname_length &&
5750 strncmp (hp->value.cpval, fname, fname_length) == 0) {
5751 ip->nominal_fname = hp->value.cpval;
5752 break;
5753 }
5754 if (hp == 0) {
5755 /* Didn't find it; cons up a new one. */
5756 hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
5757 hp->next = *hash_bucket;
5758 *hash_bucket = hp;
5759
5760 hp->length = fname_length;
5761 ip->nominal_fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
5762 bcopy (fname, hp->value.cpval, fname_length);
5763 }
5764 } else if (*bp) {
5765 error ("invalid format `#line' command");
5766 return 0;
5767 }
5768
5769 ip->lineno = new_lineno;
5770 output_line_command (ip, op, 0, file_change);
5771 check_expand (op, ip->length - (ip->bufp - ip->buf));
5772 return 0;
5773}
5774
5775/*
5776 * remove the definition of a symbol from the symbol table.
5777 * according to un*x /lib/cpp, it is not an error to undef
5778 * something that has no definitions, so it isn't one here either.
5779 */
5780
5781static int
5782do_undef (buf, limit, op, keyword)
5783 U_CHAR *buf, *limit;
5784 FILE_BUF *op;
5785 struct directive *keyword;
5786{
5787 int sym_length;
5788 HASHNODE *hp;
5789 U_CHAR *orig_buf = buf;
5790
5791 /* If this is a precompiler run (with -pcp) pass thru #undef commands. */
5792 if (pcp_outfile && op)
5793 pass_thru_directive (buf, limit, op, keyword);
5794
5795 SKIP_WHITE_SPACE (buf);
5796 sym_length = check_macro_name (buf, "macro");
5797
5798 while ((hp = lookup (buf, sym_length, -1)) != NULL) {
5799 /* If we are generating additional info for debugging (with -g) we
5800 need to pass through all effective #undef commands. */
5801 if (debug_output && op)
5802 pass_thru_directive (orig_buf, limit, op, keyword);
5803 if (hp->type != T_MACRO)
5804 warning ("undefining `%s'", hp->name);
5805 delete_macro (hp);
5806 }
5807
5808 if (pedantic) {
5809 buf += sym_length;
5810 SKIP_WHITE_SPACE (buf);
5811 if (buf != limit)
5812 pedwarn ("garbage after `#undef' directive");
5813 }
5814 return 0;
5815}
5816\f
5817/*
5818 * Report a fatal error detected by the program we are processing.
5819 * Use the text of the line in the error message, then terminate.
5820 * (We use error() because it prints the filename & line#.)
5821 */
5822
5823static int
5824do_error (buf, limit, op, keyword)
5825 U_CHAR *buf, *limit;
5826 FILE_BUF *op;
5827 struct directive *keyword;
5828{
5829 int length = limit - buf;
5830 char *copy = (char *) xmalloc (length + 1);
5831 bcopy (buf, copy, length);
5832 copy[length] = 0;
5833 SKIP_WHITE_SPACE (copy);
5834 error ("#error %s", copy);
5835 exit (FAILURE_EXIT_CODE);
5836 /* NOTREACHED */
5837 return 0;
5838}
5839
5840/*
5841 * Report a warning detected by the program we are processing.
5842 * Use the text of the line in the warning message, then continue.
5843 * (We use error() because it prints the filename & line#.)
5844 */
5845
5846static int
5847do_warning (buf, limit, op, keyword)
5848 U_CHAR *buf, *limit;
5849 FILE_BUF *op;
5850 struct directive *keyword;
5851{
5852 int length = limit - buf;
5853 char *copy = (char *) xmalloc (length + 1);
5854 bcopy (buf, copy, length);
5855 copy[length] = 0;
5856 SKIP_WHITE_SPACE (copy);
5857 warning ("#warning %s", copy);
5858 return 0;
5859}
5860
5861/* Remember the name of the current file being read from so that we can
5862 avoid ever including it again. */
5863
5864static int
5865do_once ()
5866{
5867 int i;
5868 FILE_BUF *ip = NULL;
5869
5870 for (i = indepth; i >= 0; i--)
5871 if (instack[i].fname != NULL) {
5872 ip = &instack[i];
5873 break;
5874 }
5875
5876 if (ip != NULL) {
5877 struct file_name_list *new;
5878
5879 new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
5880 new->next = dont_repeat_files;
5881 dont_repeat_files = new;
5882 new->fname = savestring (ip->fname);
5883 new->control_macro = 0;
5884 }
5885 return 0;
5886}
5887
5888/* #ident has already been copied to the output file, so just ignore it. */
5889
5890static int
5891do_ident (buf, limit)
5892 U_CHAR *buf, *limit;
5893{
5894 /* Allow #ident in system headers, since that's not user's fault. */
5895 if (pedantic && !instack[indepth].system_header_p)
5896 pedwarn ("ANSI C does not allow `#ident'");
5897 return 0;
5898}
5899
5900/* #pragma and its argument line have already been copied to the output file.
5901 Just check for some recognized pragmas that need validation here. */
5902
5903static int
5904do_pragma (buf, limit)
5905 U_CHAR *buf, *limit;
5906{
5907 while (*buf == ' ' || *buf == '\t')
5908 buf++;
5909 if (!strncmp (buf, "once", 4)) {
5910 /* Allow #pragma once in system headers, since that's not the user's
5911 fault. */
5912 if (!instack[indepth].system_header_p)
5913 warning ("`#pragma once' is obsolete");
5914 do_once ();
5915 }
5916
5917 if (!strncmp (buf, "implementation", 14)) {
5918 /* Be quiet about `#pragma implementation' for a file only if it hasn't
5919 been included yet. */
5920 struct file_name_list *ptr;
5921 U_CHAR *p = buf + 14, *fname, *inc_fname;
5922 SKIP_WHITE_SPACE (p);
5923 if (*p == '\n' || *p != '\"')
5924 return 0;
5925
5926 fname = p + 1;
5927 if (p = (U_CHAR *) index (fname, '\"'))
5928 *p = '\0';
5929
5930 for (ptr = all_include_files; ptr; ptr = ptr->next) {
5931 inc_fname = (U_CHAR *) rindex (ptr->fname, '/');
5932 inc_fname = inc_fname ? inc_fname + 1 : (U_CHAR *) ptr->fname;
5933 if (inc_fname && !strcmp (inc_fname, fname))
5934 warning ("`#pragma implementation' for `%s' appears after file is included",
5935 fname);
5936 }
5937 }
5938
5939 return 0;
5940}
5941
5942#if 0
5943/* This was a fun hack, but #pragma seems to start to be useful.
5944 By failing to recognize it, we pass it through unchanged to cc1. */
5945
5946/*
5947 * the behavior of the #pragma directive is implementation defined.
5948 * this implementation defines it as follows.
5949 */
5950
5951static int
5952do_pragma ()
5953{
5954 close (0);
5955 if (open ("/dev/tty", O_RDONLY, 0666) != 0)
5956 goto nope;
5957 close (1);
5958 if (open ("/dev/tty", O_WRONLY, 0666) != 1)
5959 goto nope;
5960 execl ("/usr/games/hack", "#pragma", 0);
5961 execl ("/usr/games/rogue", "#pragma", 0);
5962 execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
5963 execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
5964nope:
5965 fatal ("You are in a maze of twisty compiler features, all different");
5966}
5967#endif
5968
5969/* Just ignore #sccs, on systems where we define it at all. */
5970
5971static int
5972do_sccs ()
5973{
5974 if (pedantic)
5975 pedwarn ("ANSI C does not allow `#sccs'");
5976 return 0;
5977}
5978\f
5979/*
5980 * handle #if command by
5981 * 1) inserting special `defined' keyword into the hash table
5982 * that gets turned into 0 or 1 by special_symbol (thus,
5983 * if the luser has a symbol called `defined' already, it won't
5984 * work inside the #if command)
5985 * 2) rescan the input into a temporary output buffer
5986 * 3) pass the output buffer to the yacc parser and collect a value
5987 * 4) clean up the mess left from steps 1 and 2.
5988 * 5) call conditional_skip to skip til the next #endif (etc.),
5989 * or not, depending on the value from step 3.
5990 */
5991
5992static int
5993do_if (buf, limit, op, keyword)
5994 U_CHAR *buf, *limit;
5995 FILE_BUF *op;
5996 struct directive *keyword;
5997{
5998 int value;
5999 FILE_BUF *ip = &instack[indepth];
6000
6001 value = eval_if_expression (buf, limit - buf);
6002 conditional_skip (ip, value == 0, T_IF, NULL_PTR);
6003 return 0;
6004}
6005
6006/*
6007 * handle a #elif directive by not changing if_stack either.
6008 * see the comment above do_else.
6009 */
6010
6011static int
6012do_elif (buf, limit, op, keyword)
6013 U_CHAR *buf, *limit;
6014 FILE_BUF *op;
6015 struct directive *keyword;
6016{
6017 int value;
6018 FILE_BUF *ip = &instack[indepth];
6019
6020 if (if_stack == instack[indepth].if_stack) {
6021 error ("`#elif' not within a conditional");
6022 return 0;
6023 } else {
6024 if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
6025 error ("`#elif' after `#else'");
6026 fprintf (stderr, " (matches line %d", if_stack->lineno);
6027 if (if_stack->fname != NULL && ip->fname != NULL &&
6028 strcmp (if_stack->fname, ip->nominal_fname) != 0)
6029 fprintf (stderr, ", file %s", if_stack->fname);
6030 fprintf (stderr, ")\n");
6031 }
6032 if_stack->type = T_ELIF;
6033 }
6034
6035 if (if_stack->if_succeeded)
6036 skip_if_group (ip, 0);
6037 else {
6038 value = eval_if_expression (buf, limit - buf);
6039 if (value == 0)
6040 skip_if_group (ip, 0);
6041 else {
6042 ++if_stack->if_succeeded; /* continue processing input */
6043 output_line_command (ip, op, 1, same_file);
6044 }
6045 }
6046 return 0;
6047}
6048
6049/*
6050 * evaluate a #if expression in BUF, of length LENGTH,
6051 * then parse the result as a C expression and return the value as an int.
6052 */
6053static int
6054eval_if_expression (buf, length)
6055 U_CHAR *buf;
6056 int length;
6057{
6058 FILE_BUF temp_obuf;
6059 HASHNODE *save_defined;
6060 int value;
6061
6062 save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, 0, -1);
6063 pcp_inside_if = 1;
6064 temp_obuf = expand_to_temp_buffer (buf, buf + length, 0, 1);
6065 pcp_inside_if = 0;
6066 delete_macro (save_defined); /* clean up special symbol */
6067
6068 value = parse_c_expression (temp_obuf.buf);
6069
6070 free (temp_obuf.buf);
6071
6072 return value;
6073}
6074
6075/*
6076 * routine to handle ifdef/ifndef. Try to look up the symbol,
6077 * then do or don't skip to the #endif/#else/#elif depending
6078 * on what directive is actually being processed.
6079 */
6080
6081static int
6082do_xifdef (buf, limit, op, keyword)
6083 U_CHAR *buf, *limit;
6084 FILE_BUF *op;
6085 struct directive *keyword;
6086{
6087 int skip;
6088 FILE_BUF *ip = &instack[indepth];
6089 U_CHAR *end;
6090 int start_of_file = 0;
6091 U_CHAR *control_macro = 0;
6092
6093 /* Detect a #ifndef at start of file (not counting comments). */
6094 if (ip->fname != 0 && keyword->type == T_IFNDEF) {
6095 U_CHAR *p = ip->buf;
6096 while (p != directive_start) {
6097 char c = *p++;
6098 if (is_space[c])
6099 ;
6100 else if (c == '/' && p != ip->bufp && *p == '*') {
6101 /* Skip this comment. */
6102 int junk;
6103 U_CHAR *save_bufp = ip->bufp;
6104 ip->bufp = p + 1;
6105 p = skip_to_end_of_comment (ip, &junk, 1);
6106 ip->bufp = save_bufp;
6107 } else {
6108 goto fail;
6109 }
6110 }
6111 /* If we get here, this conditional is the beginning of the file. */
6112 start_of_file = 1;
6113 fail: ;
6114 }
6115
6116 /* Discard leading and trailing whitespace. */
6117 SKIP_WHITE_SPACE (buf);
6118 while (limit != buf && is_hor_space[limit[-1]]) limit--;
6119
6120 /* Find the end of the identifier at the beginning. */
6121 for (end = buf; is_idchar[*end]; end++);
6122
6123 if (end == buf) {
6124 skip = (keyword->type == T_IFDEF);
6125 if (! traditional)
6126 pedwarn (end == limit ? "`#%s' with no argument"
6127 : "`#%s' argument starts with punctuation",
6128 keyword->name);
6129 } else {
6130 HASHNODE *hp;
6131
6132 if (pedantic && buf[0] >= '0' && buf[0] <= '9')
6133 pedwarn ("`#%s' argument starts with a digit", keyword->name);
6134 else if (end != limit && !traditional)
6135 pedwarn ("garbage at end of `#%s' argument", keyword->name);
6136
6137 hp = lookup (buf, end-buf, -1);
6138
6139 if (pcp_outfile) {
6140 /* Output a precondition for this macro. */
6141 if (hp && hp->value.defn->predefined)
6142 fprintf(pcp_outfile, "#define %s\n", hp->name);
6143 else {
6144 U_CHAR *cp = buf;
6145 fprintf(pcp_outfile, "#undef ");
6146 while (is_idchar[*cp]) /* Ick! */
6147 fputc (*cp++, pcp_outfile);
6148 putc ('\n', pcp_outfile);
6149 }
6150 }
6151
6152 skip = (hp == NULL) ^ (keyword->type == T_IFNDEF);
6153 if (start_of_file && !skip) {
6154 control_macro = (U_CHAR *) xmalloc (end - buf + 1);
6155 bcopy (buf, control_macro, end - buf);
6156 control_macro[end - buf] = 0;
6157 }
6158 }
6159
6160 conditional_skip (ip, skip, T_IF, control_macro);
6161 return 0;
6162}
6163
6164/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
6165 If this is a #ifndef starting at the beginning of a file,
6166 CONTROL_MACRO is the macro name tested by the #ifndef.
6167 Otherwise, CONTROL_MACRO is 0. */
6168
6169static void
6170conditional_skip (ip, skip, type, control_macro)
6171 FILE_BUF *ip;
6172 int skip;
6173 enum node_type type;
6174 U_CHAR *control_macro;
6175{
6176 IF_STACK_FRAME *temp;
6177
6178 temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
6179 temp->fname = ip->nominal_fname;
6180 temp->lineno = ip->lineno;
6181 temp->next = if_stack;
6182 temp->control_macro = control_macro;
6183 if_stack = temp;
6184
6185 if_stack->type = type;
6186
6187 if (skip != 0) {
6188 skip_if_group (ip, 0);
6189 return;
6190 } else {
6191 ++if_stack->if_succeeded;
6192 output_line_command (ip, &outbuf, 1, same_file);
6193 }
6194}
6195
6196/*
6197 * skip to #endif, #else, or #elif. adjust line numbers, etc.
6198 * leaves input ptr at the sharp sign found.
6199 * If ANY is nonzero, return at next directive of any sort.
6200 */
6201static void
6202skip_if_group (ip, any)
6203 FILE_BUF *ip;
6204 int any;
6205{
6206 register U_CHAR *bp = ip->bufp, *cp;
6207 register U_CHAR *endb = ip->buf + ip->length;
6208 struct directive *kt;
6209 IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
6210 U_CHAR *beg_of_line = bp;
6211 register int ident_length;
6212 U_CHAR *ident, *after_ident;
6213
6214 while (bp < endb) {
6215 switch (*bp++) {
6216 case '/': /* possible comment */
6217 if (*bp == '\\' && bp[1] == '\n')
6218 newline_fix (bp);
6219 if (*bp == '*'
6220 || (cplusplus_comments && *bp == '/')) {
6221 ip->bufp = ++bp;
6222 bp = skip_to_end_of_comment (ip, &ip->lineno, 0);
6223 }
6224 break;
6225 case '\"':
6226 case '\'':
6227 bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno,
6228 NULL_PTR, NULL_PTR);
6229 break;
6230 case '\\':
6231 /* Char after backslash loses its special meaning. */
6232 if (bp < endb) {
6233 if (*bp == '\n')
6234 ++ip->lineno; /* But do update the line-count. */
6235 bp++;
6236 }
6237 break;
6238 case '\n':
6239 ++ip->lineno;
6240 beg_of_line = bp;
6241 break;
6242 case '#':
6243 ip->bufp = bp - 1;
6244
6245 /* # keyword: a # must be first nonblank char on the line */
6246 if (beg_of_line == 0)
6247 break;
6248 /* Scan from start of line, skipping whitespace, comments
6249 and backslash-newlines, and see if we reach this #.
6250 If not, this # is not special. */
6251 bp = beg_of_line;
6252 while (1) {
6253 if (is_hor_space[*bp])
6254 bp++;
6255 else if (*bp == '\\' && bp[1] == '\n')
6256 bp += 2;
6257 else if (*bp == '/' && bp[1] == '*') {
6258 bp += 2;
6259 while (!(*bp == '*' && bp[1] == '/'))
6260 bp++;
6261 bp += 2;
6262 } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') {
6263 bp += 2;
6264 while (*bp++ != '\n') ;
6265 }
6266 else break;
6267 }
6268 if (bp != ip->bufp) {
6269 bp = ip->bufp + 1; /* Reset bp to after the #. */
6270 break;
6271 }
6272
6273 bp = ip->bufp + 1; /* Point after the '#' */
6274
6275 /* Skip whitespace and \-newline. */
6276 while (1) {
6277 if (is_hor_space[*bp])
6278 bp++;
6279 else if (*bp == '\\' && bp[1] == '\n')
6280 bp += 2;
6281 else if (*bp == '/' && bp[1] == '*') {
6282 bp += 2;
6283 while (!(*bp == '*' && bp[1] == '/')) {
6284 if (*bp == '\n')
6285 ip->lineno++;
6286 bp++;
6287 }
6288 bp += 2;
6289 } else if (cplusplus_comments && *bp == '/' && bp[1] == '/') {
6290 bp += 2;
6291 while (*bp++ != '\n') ;
6292 }
6293 else break;
6294 }
6295
6296 cp = bp;
6297
6298 /* Now find end of directive name.
6299 If we encounter a backslash-newline, exchange it with any following
6300 symbol-constituents so that we end up with a contiguous name. */
6301
6302 while (1) {
6303 if (is_idchar[*bp])
6304 bp++;
6305 else {
6306 if (*bp == '\\' && bp[1] == '\n')
6307 name_newline_fix (bp);
6308 if (is_idchar[*bp])
6309 bp++;
6310 else break;
6311 }
6312 }
6313 ident_length = bp - cp;
6314 ident = cp;
6315 after_ident = bp;
6316
6317 /* A line of just `#' becomes blank. */
6318
6319 if (ident_length == 0 && *after_ident == '\n') {
6320 continue;
6321 }
6322
6323 if (ident_length == 0 || !is_idstart[*ident]) {
6324 U_CHAR *p = ident;
6325 while (is_idchar[*p]) {
6326 if (*p < '0' || *p > '9')
6327 break;
6328 p++;
6329 }
6330 /* Handle # followed by a line number. */
6331 if (p != ident && !is_idchar[*p]) {
6332 if (pedantic)
6333 pedwarn ("`#' followed by integer");
6334 continue;
6335 }
6336
6337 /* Avoid error for `###' and similar cases unless -pedantic. */
6338 if (p == ident) {
6339 while (*p == '#' || is_hor_space[*p]) p++;
6340 if (*p == '\n') {
6341 if (pedantic && !lang_asm)
6342 pedwarn ("invalid preprocessor directive");
6343 continue;
6344 }
6345 }
6346
6347 if (!lang_asm && pedantic)
6348 pedwarn ("invalid preprocessor directive name");
6349 continue;
6350 }
6351
6352 for (kt = directive_table; kt->length >= 0; kt++) {
6353 IF_STACK_FRAME *temp;
6354 if (ident_length == kt->length
6355 && strncmp (cp, kt->name, kt->length) == 0) {
6356 /* If we are asked to return on next directive, do so now. */
6357 if (any)
6358 return;
6359
6360 switch (kt->type) {
6361 case T_IF:
6362 case T_IFDEF:
6363 case T_IFNDEF:
6364 temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
6365 temp->next = if_stack;
6366 if_stack = temp;
6367 temp->lineno = ip->lineno;
6368 temp->fname = ip->nominal_fname;
6369 temp->type = kt->type;
6370 break;
6371 case T_ELSE:
6372 case T_ENDIF:
6373 if (pedantic && if_stack != save_if_stack)
6374 validate_else (bp);
6375 case T_ELIF:
6376 if (if_stack == instack[indepth].if_stack) {
6377 error ("`#%s' not within a conditional", kt->name);
6378 break;
6379 }
6380 else if (if_stack == save_if_stack)
6381 return; /* found what we came for */
6382
6383 if (kt->type != T_ENDIF) {
6384 if (if_stack->type == T_ELSE)
6385 error ("`#else' or `#elif' after `#else'");
6386 if_stack->type = kt->type;
6387 break;
6388 }
6389
6390 temp = if_stack;
6391 if_stack = if_stack->next;
6392 free (temp);
6393 break;
6394 }
6395 break;
6396 }
6397 }
6398 /* Don't let erroneous code go by. */
6399 if (kt->length < 0 && !lang_asm && pedantic)
6400 pedwarn ("invalid preprocessor directive name");
6401 }
6402 }
6403 ip->bufp = bp;
6404 /* after this returns, rescan will exit because ip->bufp
6405 now points to the end of the buffer.
6406 rescan is responsible for the error message also. */
6407}
6408
6409/*
6410 * handle a #else directive. Do this by just continuing processing
6411 * without changing if_stack ; this is so that the error message
6412 * for missing #endif's etc. will point to the original #if. It
6413 * is possible that something different would be better.
6414 */
6415
6416static int
6417do_else (buf, limit, op, keyword)
6418 U_CHAR *buf, *limit;
6419 FILE_BUF *op;
6420 struct directive *keyword;
6421{
6422 FILE_BUF *ip = &instack[indepth];
6423
6424 if (pedantic) {
6425 SKIP_WHITE_SPACE (buf);
6426 if (buf != limit)
6427 pedwarn ("text following `#else' violates ANSI standard");
6428 }
6429
6430 if (if_stack == instack[indepth].if_stack) {
6431 error ("`#else' not within a conditional");
6432 return 0;
6433 } else {
6434 /* #ifndef can't have its special treatment for containing the whole file
6435 if it has a #else clause. */
6436 if_stack->control_macro = 0;
6437
6438 if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
6439 error ("`#else' after `#else'");
6440 fprintf (stderr, " (matches line %d", if_stack->lineno);
6441 if (strcmp (if_stack->fname, ip->nominal_fname) != 0)
6442 fprintf (stderr, ", file %s", if_stack->fname);
6443 fprintf (stderr, ")\n");
6444 }
6445 if_stack->type = T_ELSE;
6446 }
6447
6448 if (if_stack->if_succeeded)
6449 skip_if_group (ip, 0);
6450 else {
6451 ++if_stack->if_succeeded; /* continue processing input */
6452 output_line_command (ip, op, 1, same_file);
6453 }
6454 return 0;
6455}
6456
6457/*
6458 * unstack after #endif command
6459 */
6460
6461static int
6462do_endif (buf, limit, op, keyword)
6463 U_CHAR *buf, *limit;
6464 FILE_BUF *op;
6465 struct directive *keyword;
6466{
6467 if (pedantic) {
6468 SKIP_WHITE_SPACE (buf);
6469 if (buf != limit)
6470 pedwarn ("text following `#endif' violates ANSI standard");
6471 }
6472
6473 if (if_stack == instack[indepth].if_stack)
6474 error ("unbalanced `#endif'");
6475 else {
6476 IF_STACK_FRAME *temp = if_stack;
6477 if_stack = if_stack->next;
6478 if (temp->control_macro != 0) {
6479 /* This #endif matched a #ifndef at the start of the file.
6480 See if it is at the end of the file. */
6481 FILE_BUF *ip = &instack[indepth];
6482 U_CHAR *p = ip->bufp;
6483 U_CHAR *ep = ip->buf + ip->length;
6484
6485 while (p != ep) {
6486 U_CHAR c = *p++;
6487 switch (c) {
6488 case ' ':
6489 case '\t':
6490 case '\n':
6491 break;
6492 case '/':
6493 if (p != ep && *p == '*') {
6494 /* Skip this comment. */
6495 int junk;
6496 U_CHAR *save_bufp = ip->bufp;
6497 ip->bufp = p + 1;
6498 p = skip_to_end_of_comment (ip, &junk, 1);
6499 ip->bufp = save_bufp;
6500 }
6501 break;
6502 default:
6503 goto fail;
6504 }
6505 }
6506 /* If we get here, this #endif ends a #ifndef
6507 that contains all of the file (aside from whitespace).
6508 Arrange not to include the file again
6509 if the macro that was tested is defined. */
6510 if (indepth != 0)
6511 record_control_macro (ip->fname, temp->control_macro);
6512 fail: ;
6513 }
6514 free (temp);
6515 output_line_command (&instack[indepth], op, 1, same_file);
6516 }
6517 return 0;
6518}
6519
6520/* When an #else or #endif is found while skipping failed conditional,
6521 if -pedantic was specified, this is called to warn about text after
6522 the command name. P points to the first char after the command name. */
6523
6524static void
6525validate_else (p)
6526 register U_CHAR *p;
6527{
6528 /* Advance P over whitespace and comments. */
6529 while (1) {
6530 if (*p == '\\' && p[1] == '\n')
6531 p += 2;
6532 if (is_hor_space[*p])
6533 p++;
6534 else if (*p == '/') {
6535 if (p[1] == '\\' && p[2] == '\n')
6536 newline_fix (p + 1);
6537 if (p[1] == '*') {
6538 p += 2;
6539 /* Don't bother warning about unterminated comments
6540 since that will happen later. Just be sure to exit. */
6541 while (*p) {
6542 if (p[1] == '\\' && p[2] == '\n')
6543 newline_fix (p + 1);
6544 if (*p == '*' && p[1] == '/') {
6545 p += 2;
6546 break;
6547 }
6548 p++;
6549 }
6550 }
6551 else if (cplusplus_comments && p[1] == '/') {
6552 p += 2;
6553 while (*p && *p++ != '\n') ;
6554 }
6555 } else break;
6556 }
6557 if (*p && *p != '\n')
6558 pedwarn ("text following `#else' or `#endif' violates ANSI standard");
6559}
6560\f
6561/* Skip a comment, assuming the input ptr immediately follows the
6562 initial slash-star. Bump *LINE_COUNTER for each newline.
6563 (The canonical line counter is &ip->lineno.)
6564 Don't use this routine (or the next one) if bumping the line
6565 counter is not sufficient to deal with newlines in the string.
6566
6567 If NOWARN is nonzero, don't warn about slash-star inside a comment.
6568 This feature is useful when processing a comment that is going to be
6569 processed or was processed at another point in the preprocessor,
6570 to avoid a duplicate warning. */
6571static U_CHAR *
6572skip_to_end_of_comment (ip, line_counter, nowarn)
6573 register FILE_BUF *ip;
6574 int *line_counter; /* place to remember newlines, or NULL */
6575 int nowarn;
6576{
6577 register U_CHAR *limit = ip->buf + ip->length;
6578 register U_CHAR *bp = ip->bufp;
6579 FILE_BUF *op = &outbuf; /* JF */
6580 int output = put_out_comments && !line_counter;
6581
6582 /* JF this line_counter stuff is a crock to make sure the
6583 comment is only put out once, no matter how many times
6584 the comment is skipped. It almost works */
6585 if (output) {
6586 *op->bufp++ = '/';
6587 *op->bufp++ = '*';
6588 }
6589 if (cplusplus_comments && bp[-1] == '/') {
6590 if (output) {
6591 while (bp < limit)
6592 if ((*op->bufp++ = *bp++) == '\n') {
6593 bp--;
6594 break;
6595 }
6596 op->bufp[-1] = '*';
6597 *op->bufp++ = '/';
6598 *op->bufp++ = '\n';
6599 } else {
6600 while (bp < limit) {
6601 if (*bp++ == '\n') {
6602 bp--;
6603 break;
6604 }
6605 }
6606 }
6607 ip->bufp = bp;
6608 return bp;
6609 }
6610 while (bp < limit) {
6611 if (output)
6612 *op->bufp++ = *bp;
6613 switch (*bp++) {
6614 case '/':
6615 if (warn_comments && !nowarn && bp < limit && *bp == '*')
6616 warning ("`/*' within comment");
6617 break;
6618 case '\n':
6619 if (line_counter != NULL)
6620 ++*line_counter;
6621 if (output)
6622 ++op->lineno;
6623 break;
6624 case '*':
6625 if (*bp == '\\' && bp[1] == '\n')
6626 newline_fix (bp);
6627 if (*bp == '/') {
6628 if (output)
6629 *op->bufp++ = '/';
6630 ip->bufp = ++bp;
6631 return bp;
6632 }
6633 break;
6634 }
6635 }
6636 ip->bufp = bp;
6637 return bp;
6638}
6639
6640/*
6641 * Skip over a quoted string. BP points to the opening quote.
6642 * Returns a pointer after the closing quote. Don't go past LIMIT.
6643 * START_LINE is the line number of the starting point (but it need
6644 * not be valid if the starting point is inside a macro expansion).
6645 *
6646 * The input stack state is not changed.
6647 *
6648 * If COUNT_NEWLINES is nonzero, it points to an int to increment
6649 * for each newline passed.
6650 *
6651 * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
6652 * if we pass a backslash-newline.
6653 *
6654 * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.
6655 */
6656static U_CHAR *
6657skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
6658 register U_CHAR *bp;
6659 register U_CHAR *limit;
6660 int start_line;
6661 int *count_newlines;
6662 int *backslash_newlines_p;
6663 int *eofp;
6664{
6665 register U_CHAR c, match;
6666
6667 match = *bp++;
6668 while (1) {
6669 if (bp >= limit) {
6670 error_with_line (line_for_error (start_line),
6671 "unterminated string or character constant");
6672 if (eofp)
6673 *eofp = 1;
6674 break;
6675 }
6676 c = *bp++;
6677 if (c == '\\') {
6678 while (*bp == '\\' && bp[1] == '\n') {
6679 if (backslash_newlines_p)
6680 *backslash_newlines_p = 1;
6681 if (count_newlines)
6682 ++*count_newlines;
6683 bp += 2;
6684 }
6685 if (*bp == '\n' && count_newlines) {
6686 if (backslash_newlines_p)
6687 *backslash_newlines_p = 1;
6688 ++*count_newlines;
6689 }
6690 bp++;
6691 } else if (c == '\n') {
6692 if (traditional) {
6693 /* Unterminated strings and character constants are 'legal'. */
6694 bp--; /* Don't consume the newline. */
6695 if (eofp)
6696 *eofp = 1;
6697 break;
6698 }
6699 if (match == '\'') {
6700 error_with_line (line_for_error (start_line),
6701 "unterminated character constant");
6702 bp--;
6703 if (eofp)
6704 *eofp = 1;
6705 break;
6706 }
6707 if (traditional) { /* Unterminated strings are 'legal'. */
6708 if (eofp)
6709 *eofp = 1;
6710 break;
6711 }
6712 /* If not traditional, then allow newlines inside strings. */
6713 if (count_newlines)
6714 ++*count_newlines;
6715 } else if (c == match)
6716 break;
6717 }
6718 return bp;
6719}
6720
6721/* Skip across a group of balanced parens, starting from IP->bufp.
6722 IP->bufp is updated. Use this with IP->bufp pointing at an open-paren.
6723
6724 This does not handle newlines, because it's used for the arg of #if,
6725 where there aren't any newlines. Also, backslash-newline can't appear. */
6726
6727static U_CHAR *
6728skip_paren_group (ip)
6729 register FILE_BUF *ip;
6730{
6731 U_CHAR *limit = ip->buf + ip->length;
6732 U_CHAR *p = ip->bufp;
6733 int depth = 0;
6734 int lines_dummy = 0;
6735
6736 while (p != limit) {
6737 int c = *p++;
6738 switch (c) {
6739 case '(':
6740 depth++;
6741 break;
6742
6743 case ')':
6744 depth--;
6745 if (depth == 0)
6746 return ip->bufp = p;
6747 break;
6748
6749 case '/':
6750 if (*p == '*') {
6751 ip->bufp = p;
6752 p = skip_to_end_of_comment (ip, &lines_dummy, 0);
6753 p = ip->bufp;
6754 }
6755
6756 case '"':
6757 case '\'':
6758 {
6759 int eofp = 0;
6760 p = skip_quoted_string (p - 1, limit, 0, NULL_PTR, NULL_PTR, &eofp);
6761 if (eofp)
6762 return ip->bufp = p;
6763 }
6764 break;
6765 }
6766 }
6767
6768 ip->bufp = p;
6769 return p;
6770}
6771\f
6772/*
6773 * write out a #line command, for instance, after an #include file.
6774 * If CONDITIONAL is nonzero, we can omit the #line if it would
6775 * appear to be a no-op, and we can output a few newlines instead
6776 * if we want to increase the line number by a small amount.
6777 * FILE_CHANGE says whether we are entering a file, leaving, or neither.
6778 */
6779
6780static void
6781output_line_command (ip, op, conditional, file_change)
6782 FILE_BUF *ip, *op;
6783 int conditional;
6784 enum file_change_code file_change;
6785{
6786 int len;
6787 char *line_cmd_buf;
6788
6789 if (no_line_commands
6790 || ip->fname == NULL
6791 || no_output) {
6792 op->lineno = ip->lineno;
6793 return;
6794 }
6795
6796 if (conditional) {
6797 if (ip->lineno == op->lineno)
6798 return;
6799
6800 /* If the inherited line number is a little too small,
6801 output some newlines instead of a #line command. */
6802 if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
6803 check_expand (op, 10);
6804 while (ip->lineno > op->lineno) {
6805 *op->bufp++ = '\n';
6806 op->lineno++;
6807 }
6808 return;
6809 }
6810 }
6811
6812 /* Don't output a line number of 0 if we can help it. */
6813 if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length
6814 && *ip->bufp == '\n') {
6815 ip->lineno++;
6816 ip->bufp++;
6817 }
6818
6819 line_cmd_buf = (char *) alloca (strlen (ip->nominal_fname) + 100);
6820#ifdef OUTPUT_LINE_COMMANDS
6821 sprintf (line_cmd_buf, "#line %d \"%s\"", ip->lineno, ip->nominal_fname);
6822#else
6823 sprintf (line_cmd_buf, "# %d \"%s\"", ip->lineno, ip->nominal_fname);
6824#endif
6825 if (file_change != same_file)
6826 strcat (line_cmd_buf, file_change == enter_file ? " 1" : " 2");
6827 /* Tell cc1 if following text comes from a system header file. */
6828 if (ip->system_header_p)
6829 strcat (line_cmd_buf, " 3");
6830 len = strlen (line_cmd_buf);
6831 line_cmd_buf[len++] = '\n';
6832 check_expand (op, len + 1);
6833 if (op->bufp > op->buf && op->bufp[-1] != '\n')
6834 *op->bufp++ = '\n';
6835 bcopy (line_cmd_buf, op->bufp, len);
6836 op->bufp += len;
6837 op->lineno = ip->lineno;
6838}
6839\f
6840/* This structure represents one parsed argument in a macro call.
6841 `raw' points to the argument text as written (`raw_length' is its length).
6842 `expanded' points to the argument's macro-expansion
6843 (its length is `expand_length').
6844 `stringified_length' is the length the argument would have
6845 if stringified.
6846 `use_count' is the number of times this macro arg is substituted
6847 into the macro. If the actual use count exceeds 10,
6848 the value stored is 10.
6849 `free1' and `free2', if nonzero, point to blocks to be freed
6850 when the macro argument data is no longer needed. */
6851
6852struct argdata {
6853 U_CHAR *raw, *expanded;
6854 int raw_length, expand_length;
6855 int stringified_length;
6856 U_CHAR *free1, *free2;
6857 char newlines;
6858 char comments;
6859 char use_count;
6860};
6861
6862/* Expand a macro call.
6863 HP points to the symbol that is the macro being called.
6864 Put the result of expansion onto the input stack
6865 so that subsequent input by our caller will use it.
6866
6867 If macro wants arguments, caller has already verified that
6868 an argument list follows; arguments come from the input stack. */
6869
6870static void
6871macroexpand (hp, op)
6872 HASHNODE *hp;
6873 FILE_BUF *op;
6874{
6875 int nargs;
6876 DEFINITION *defn = hp->value.defn;
6877 register U_CHAR *xbuf;
6878 int xbuf_len;
6879 int start_line = instack[indepth].lineno;
6880 int rest_args, rest_zero;
6881
6882 CHECK_DEPTH (return;);
6883
6884 /* it might not actually be a macro. */
6885 if (hp->type != T_MACRO) {
6886 special_symbol (hp, op);
6887 return;
6888 }
6889
6890 /* This macro is being used inside a #if, which means it must be */
6891 /* recorded as a precondition. */
6892 if (pcp_inside_if && pcp_outfile && defn->predefined)
6893 dump_single_macro (hp, pcp_outfile);
6894
6895 nargs = defn->nargs;
6896
6897 if (nargs >= 0) {
6898 register int i;
6899 struct argdata *args;
6900 char *parse_error = 0;
6901
6902 args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
6903
6904 for (i = 0; i < nargs; i++) {
6905 args[i].raw = args[i].expanded = (U_CHAR *) "";
6906 args[i].raw_length = args[i].expand_length
6907 = args[i].stringified_length = 0;
6908 args[i].free1 = args[i].free2 = 0;
6909 args[i].use_count = 0;
6910 }
6911
6912 /* Parse all the macro args that are supplied. I counts them.
6913 The first NARGS args are stored in ARGS.
6914 The rest are discarded.
6915 If rest_args is set then we assume macarg absorbed the rest of the args.
6916 */
6917 i = 0;
6918 rest_args = 0;
6919 do {
6920 /* Discard the open-parenthesis or comma before the next arg. */
6921 ++instack[indepth].bufp;
6922 if (rest_args)
6923 continue;
6924 if (i < nargs || (nargs == 0 && i == 0)) {
6925 /* if we are working on last arg which absorbs rest of args... */
6926 if (i == nargs - 1 && defn->rest_args)
6927 rest_args = 1;
6928 parse_error = macarg (&args[i], rest_args);
6929 }
6930 else
6931 parse_error = macarg (NULL_PTR, 0);
6932 if (parse_error) {
6933 error_with_line (line_for_error (start_line), parse_error);
6934 break;
6935 }
6936 i++;
6937 } while (*instack[indepth].bufp != ')');
6938
6939 /* If we got one arg but it was just whitespace, call that 0 args. */
6940 if (i == 1) {
6941 register U_CHAR *bp = args[0].raw;
6942 register U_CHAR *lim = bp + args[0].raw_length;
6943 while (bp != lim && is_space[*bp]) bp++;
6944 if (bp == lim)
6945 i = 0;
6946 }
6947
6948 /* Don't output an error message if we have already output one for
6949 a parse error above. */
6950 rest_zero = 0;
6951 if (nargs == 0 && i > 0) {
6952 if (! parse_error)
6953 error ("arguments given to macro `%s'", hp->name);
6954 } else if (i < nargs) {
6955 /* traditional C allows foo() if foo wants one argument. */
6956 if (nargs == 1 && i == 0 && traditional)
6957 ;
6958 /* the rest args token is allowed to absorb 0 tokens */
6959 else if (i == nargs - 1 && defn->rest_args)
6960 rest_zero = 1;
6961 else if (parse_error)
6962 ;
6963 else if (i == 0)
6964 error ("macro `%s' used without args", hp->name);
6965 else if (i == 1)
6966 error ("macro `%s' used with just one arg", hp->name);
6967 else
6968 error ("macro `%s' used with only %d args", hp->name, i);
6969 } else if (i > nargs) {
6970 if (! parse_error)
6971 error ("macro `%s' used with too many (%d) args", hp->name, i);
6972 }
6973
6974 /* Swallow the closeparen. */
6975 ++instack[indepth].bufp;
6976
6977 /* If macro wants zero args, we parsed the arglist for checking only.
6978 Read directly from the macro definition. */
6979 if (nargs == 0) {
6980 xbuf = defn->expansion;
6981 xbuf_len = defn->length;
6982 } else {
6983 register U_CHAR *exp = defn->expansion;
6984 register int offset; /* offset in expansion,
6985 copied a piece at a time */
6986 register int totlen; /* total amount of exp buffer filled so far */
6987
6988 register struct reflist *ap, *last_ap;
6989
6990 /* Macro really takes args. Compute the expansion of this call. */
6991
6992 /* Compute length in characters of the macro's expansion.
6993 Also count number of times each arg is used. */
6994 xbuf_len = defn->length;
6995 for (ap = defn->pattern; ap != NULL; ap = ap->next) {
6996 if (ap->stringify)
6997 xbuf_len += args[ap->argno].stringified_length;
6998 else if (ap->raw_before || ap->raw_after || traditional)
6999 xbuf_len += args[ap->argno].raw_length;
7000 else
7001 xbuf_len += args[ap->argno].expand_length;
7002
7003 if (args[ap->argno].use_count < 10)
7004 args[ap->argno].use_count++;
7005 }
7006
7007 xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
7008
7009 /* Generate in XBUF the complete expansion
7010 with arguments substituted in.
7011 TOTLEN is the total size generated so far.
7012 OFFSET is the index in the definition
7013 of where we are copying from. */
7014 offset = totlen = 0;
7015 for (last_ap = NULL, ap = defn->pattern; ap != NULL;
7016 last_ap = ap, ap = ap->next) {
7017 register struct argdata *arg = &args[ap->argno];
7018
7019 /* add chars to XBUF unless rest_args was zero with concatenation */
7020 for (i = 0; i < ap->nchars; i++, offset++)
7021 if (! (rest_zero && ((ap->rest_args && ap->raw_before)
7022 || (last_ap != NULL && last_ap->rest_args
7023 && last_ap->raw_after))))
7024 xbuf[totlen++] = exp[offset];
7025
7026 if (ap->stringify != 0) {
7027 int arglen = arg->raw_length;
7028 int escaped = 0;
7029 int in_string = 0;
7030 int c;
7031 i = 0;
7032 while (i < arglen
7033 && (c = arg->raw[i], is_space[c]))
7034 i++;
7035 while (i < arglen
7036 && (c = arg->raw[arglen - 1], is_space[c]))
7037 arglen--;
7038 if (!traditional)
7039 xbuf[totlen++] = '\"'; /* insert beginning quote */
7040 for (; i < arglen; i++) {
7041 c = arg->raw[i];
7042
7043 /* Special markers Newline Space
7044 generate nothing for a stringified argument. */
7045 if (c == '\n' && arg->raw[i+1] != '\n') {
7046 i++;
7047 continue;
7048 }
7049
7050 /* Internal sequences of whitespace are replaced by one space
7051 except within an string or char token. */
7052 if (! in_string
7053 && (c == '\n' ? arg->raw[i+1] == '\n' : is_space[c])) {
7054 while (1) {
7055 /* Note that Newline Space does occur within whitespace
7056 sequences; consider it part of the sequence. */
7057 if (c == '\n' && is_space[arg->raw[i+1]])
7058 i += 2;
7059 else if (c != '\n' && is_space[c])
7060 i++;
7061 else break;
7062 c = arg->raw[i];
7063 }
7064 i--;
7065 c = ' ';
7066 }
7067
7068 if (escaped)
7069 escaped = 0;
7070 else {
7071 if (c == '\\')
7072 escaped = 1;
7073 if (in_string) {
7074 if (c == in_string)
7075 in_string = 0;
7076 } else if (c == '\"' || c == '\'')
7077 in_string = c;
7078 }
7079
7080 /* Escape these chars */
7081 if (c == '\"' || (in_string && c == '\\'))
7082 xbuf[totlen++] = '\\';
7083 if (isprint (c))
7084 xbuf[totlen++] = c;
7085 else {
7086 sprintf ((char *) &xbuf[totlen], "\\%03o", (unsigned int) c);
7087 totlen += 4;
7088 }
7089 }
7090 if (!traditional)
7091 xbuf[totlen++] = '\"'; /* insert ending quote */
7092 } else if (ap->raw_before || ap->raw_after || traditional) {
7093 U_CHAR *p1 = arg->raw;
7094 U_CHAR *l1 = p1 + arg->raw_length;
7095 if (ap->raw_before) {
7096 while (p1 != l1 && is_space[*p1]) p1++;
7097 while (p1 != l1 && is_idchar[*p1])
7098 xbuf[totlen++] = *p1++;
7099 /* Delete any no-reexpansion marker that follows
7100 an identifier at the beginning of the argument
7101 if the argument is concatenated with what precedes it. */
7102 if (p1[0] == '\n' && p1[1] == '-')
7103 p1 += 2;
7104 }
7105 if (ap->raw_after) {
7106 /* Arg is concatenated after: delete trailing whitespace,
7107 whitespace markers, and no-reexpansion markers. */
7108 while (p1 != l1) {
7109 if (is_space[l1[-1]]) l1--;
7110 else if (l1[-1] == '-') {
7111 U_CHAR *p2 = l1 - 1;
7112 /* If a `-' is preceded by an odd number of newlines then it
7113 and the last newline are a no-reexpansion marker. */
7114 while (p2 != p1 && p2[-1] == '\n') p2--;
7115 if ((l1 - 1 - p2) & 1) {
7116 l1 -= 2;
7117 }
7118 else break;
7119 }
7120 else break;
7121 }
7122 }
7123 bcopy (p1, xbuf + totlen, l1 - p1);
7124 totlen += l1 - p1;
7125 } else {
7126 bcopy (arg->expanded, xbuf + totlen, arg->expand_length);
7127 totlen += arg->expand_length;
7128 /* If a macro argument with newlines is used multiple times,
7129 then only expand the newlines once. This avoids creating output
7130 lines which don't correspond to any input line, which confuses
7131 gdb and gcov. */
7132 if (arg->use_count > 1 && arg->newlines > 0) {
7133 /* Don't bother doing delete_newlines for subsequent
7134 uses of arg. */
7135 arg->use_count = 1;
7136 arg->expand_length
7137 = delete_newlines (arg->expanded, arg->expand_length);
7138 }
7139 }
7140
7141 if (totlen > xbuf_len)
7142 abort ();
7143 }
7144
7145 /* if there is anything left of the definition
7146 after handling the arg list, copy that in too. */
7147
7148 for (i = offset; i < defn->length; i++) {
7149 /* if we've reached the end of the macro */
7150 if (exp[i] == ')')
7151 rest_zero = 0;
7152 if (! (rest_zero && last_ap != NULL && last_ap->rest_args
7153 && last_ap->raw_after))
7154 xbuf[totlen++] = exp[i];
7155 }
7156
7157 xbuf[totlen] = 0;
7158 xbuf_len = totlen;
7159
7160 for (i = 0; i < nargs; i++) {
7161 if (args[i].free1 != 0)
7162 free (args[i].free1);
7163 if (args[i].free2 != 0)
7164 free (args[i].free2);
7165 }
7166 }
7167 } else {
7168 xbuf = defn->expansion;
7169 xbuf_len = defn->length;
7170 }
7171
7172 /* Now put the expansion on the input stack
7173 so our caller will commence reading from it. */
7174 {
7175 register FILE_BUF *ip2;
7176
7177 ip2 = &instack[++indepth];
7178
7179 ip2->fname = 0;
7180 ip2->nominal_fname = 0;
7181 ip2->lineno = 0;
7182 ip2->buf = xbuf;
7183 ip2->length = xbuf_len;
7184 ip2->bufp = xbuf;
7185 ip2->free_ptr = (nargs > 0) ? xbuf : 0;
7186 ip2->macro = hp;
7187 ip2->if_stack = if_stack;
7188 ip2->system_header_p = 0;
7189
7190 /* Recursive macro use sometimes works traditionally.
7191 #define foo(x,y) bar(x(y,0), y)
7192 foo(foo, baz) */
7193
7194 if (!traditional)
7195 hp->type = T_DISABLED;
7196 }
7197}
7198\f
7199/*
7200 * Parse a macro argument and store the info on it into *ARGPTR.
7201 * REST_ARGS is passed to macarg1 to make it absorb the rest of the args.
7202 * Return nonzero to indicate a syntax error.
7203 */
7204
7205static char *
7206macarg (argptr, rest_args)
7207 register struct argdata *argptr;
7208 int rest_args;
7209{
7210 FILE_BUF *ip = &instack[indepth];
7211 int paren = 0;
7212 int newlines = 0;
7213 int comments = 0;
7214
7215 /* Try to parse as much of the argument as exists at this
7216 input stack level. */
7217 U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length,
7218 &paren, &newlines, &comments, rest_args);
7219
7220 /* If we find the end of the argument at this level,
7221 set up *ARGPTR to point at it in the input stack. */
7222 if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
7223 && bp != ip->buf + ip->length) {
7224 if (argptr != 0) {
7225 argptr->raw = ip->bufp;
7226 argptr->raw_length = bp - ip->bufp;
7227 argptr->newlines = newlines;
7228 }
7229 ip->bufp = bp;
7230 } else {
7231 /* This input stack level ends before the macro argument does.
7232 We must pop levels and keep parsing.
7233 Therefore, we must allocate a temporary buffer and copy
7234 the macro argument into it. */
7235 int bufsize = bp - ip->bufp;
7236 int extra = newlines;
7237 U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
7238 int final_start = 0;
7239
7240 bcopy (ip->bufp, buffer, bufsize);
7241 ip->bufp = bp;
7242 ip->lineno += newlines;
7243
7244 while (bp == ip->buf + ip->length) {
7245 if (instack[indepth].macro == 0) {
7246 free (buffer);
7247 return "unterminated macro call";
7248 }
7249 ip->macro->type = T_MACRO;
7250 if (ip->free_ptr)
7251 free (ip->free_ptr);
7252 ip = &instack[--indepth];
7253 newlines = 0;
7254 comments = 0;
7255 bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren,
7256 &newlines, &comments, rest_args);
7257 final_start = bufsize;
7258 bufsize += bp - ip->bufp;
7259 extra += newlines;
7260 buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
7261 bcopy (ip->bufp, buffer + bufsize - (bp - ip->bufp), bp - ip->bufp);
7262 ip->bufp = bp;
7263 ip->lineno += newlines;
7264 }
7265
7266 /* Now, if arg is actually wanted, record its raw form,
7267 discarding comments and duplicating newlines in whatever
7268 part of it did not come from a macro expansion.
7269 EXTRA space has been preallocated for duplicating the newlines.
7270 FINAL_START is the index of the start of that part. */
7271 if (argptr != 0) {
7272 argptr->raw = buffer;
7273 argptr->raw_length = bufsize;
7274 argptr->free1 = buffer;
7275 argptr->newlines = newlines;
7276 argptr->comments = comments;
7277 if ((newlines || comments) && ip->fname != 0)
7278 argptr->raw_length
7279 = final_start +
7280 discard_comments (argptr->raw + final_start,
7281 argptr->raw_length - final_start,
7282 newlines);
7283 argptr->raw[argptr->raw_length] = 0;
7284 if (argptr->raw_length > bufsize + extra)
7285 abort ();
7286 }
7287 }
7288
7289 /* If we are not discarding this argument,
7290 macroexpand it and compute its length as stringified.
7291 All this info goes into *ARGPTR. */
7292
7293 if (argptr != 0) {
7294 FILE_BUF obuf;
7295 register U_CHAR *buf, *lim;
7296 register int totlen;
7297
7298 obuf = expand_to_temp_buffer (argptr->raw,
7299 argptr->raw + argptr->raw_length,
7300 1, 0);
7301
7302 argptr->expanded = obuf.buf;
7303 argptr->expand_length = obuf.length;
7304 argptr->free2 = obuf.buf;
7305
7306 buf = argptr->raw;
7307 lim = buf + argptr->raw_length;
7308
7309 while (buf != lim && is_space[*buf])
7310 buf++;
7311 while (buf != lim && is_space[lim[-1]])
7312 lim--;
7313 totlen = traditional ? 0 : 2; /* Count opening and closing quote. */
7314 while (buf != lim) {
7315 register U_CHAR c = *buf++;
7316 totlen++;
7317 /* Internal sequences of whitespace are replaced by one space
7318 in most cases, but not always. So count all the whitespace
7319 in case we need to keep it all. */
7320#if 0
7321 if (is_space[c])
7322 SKIP_ALL_WHITE_SPACE (buf);
7323 else
7324#endif
7325 if (c == '\"' || c == '\\') /* escape these chars */
7326 totlen++;
7327 else if (!isprint (c))
7328 totlen += 3;
7329 }
7330 argptr->stringified_length = totlen;
7331 }
7332 return 0;
7333}
7334\f
7335/* Scan text from START (inclusive) up to LIMIT (exclusive),
7336 counting parens in *DEPTHPTR,
7337 and return if reach LIMIT
7338 or before a `)' that would make *DEPTHPTR negative
7339 or before a comma when *DEPTHPTR is zero.
7340 Single and double quotes are matched and termination
7341 is inhibited within them. Comments also inhibit it.
7342 Value returned is pointer to stopping place.
7343
7344 Increment *NEWLINES each time a newline is passed.
7345 REST_ARGS notifies macarg1 that it should absorb the rest of the args.
7346 Set *COMMENTS to 1 if a comment is seen. */
7347
7348static U_CHAR *
7349macarg1 (start, limit, depthptr, newlines, comments, rest_args)
7350 U_CHAR *start;
7351 register U_CHAR *limit;
7352 int *depthptr, *newlines, *comments;
7353 int rest_args;
7354{
7355 register U_CHAR *bp = start;
7356
7357 while (bp < limit) {
7358 switch (*bp) {
7359 case '(':
7360 (*depthptr)++;
7361 break;
7362 case ')':
7363 if (--(*depthptr) < 0)
7364 return bp;
7365 break;
7366 case '\\':
7367 /* Traditionally, backslash makes following char not special. */
7368 if (bp + 1 < limit && traditional)
7369 {
7370 bp++;
7371 /* But count source lines anyway. */
7372 if (*bp == '\n')
7373 ++*newlines;
7374 }
7375 break;
7376 case '\n':
7377 ++*newlines;
7378 break;
7379 case '/':
7380 if (bp[1] == '\\' && bp[2] == '\n')
7381 newline_fix (bp + 1);
7382 if (cplusplus_comments && bp[1] == '/') {
7383 *comments = 1;
7384 bp += 2;
7385 while (bp < limit && *bp++ != '\n') ;
7386 ++*newlines;
7387 break;
7388 }
7389 if (bp[1] != '*' || bp + 1 >= limit)
7390 break;
7391 *comments = 1;
7392 bp += 2;
7393 while (bp + 1 < limit) {
7394 if (bp[0] == '*'
7395 && bp[1] == '\\' && bp[2] == '\n')
7396 newline_fix (bp + 1);
7397 if (bp[0] == '*' && bp[1] == '/')
7398 break;
7399 if (*bp == '\n') ++*newlines;
7400 bp++;
7401 }
7402 break;
7403 case '\'':
7404 case '\"':
7405 {
7406 int quotec;
7407 for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
7408 if (*bp == '\\') {
7409 bp++;
7410 if (*bp == '\n')
7411 ++*newlines;
7412 while (*bp == '\\' && bp[1] == '\n') {
7413 bp += 2;
7414 }
7415 } else if (*bp == '\n') {
7416 ++*newlines;
7417 if (quotec == '\'')
7418 break;
7419 }
7420 }
7421 }
7422 break;
7423 case ',':
7424 /* if we've returned to lowest level and we aren't absorbing all args */
7425 if ((*depthptr) == 0 && rest_args == 0)
7426 return bp;
7427 break;
7428 }
7429 bp++;
7430 }
7431
7432 return bp;
7433}
7434\f
7435/* Discard comments and duplicate newlines
7436 in the string of length LENGTH at START,
7437 except inside of string constants.
7438 The string is copied into itself with its beginning staying fixed.
7439
7440 NEWLINES is the number of newlines that must be duplicated.
7441 We assume that that much extra space is available past the end
7442 of the string. */
7443
7444static int
7445discard_comments (start, length, newlines)
7446 U_CHAR *start;
7447 int length;
7448 int newlines;
7449{
7450 register U_CHAR *ibp;
7451 register U_CHAR *obp;
7452 register U_CHAR *limit;
7453 register int c;
7454
7455 /* If we have newlines to duplicate, copy everything
7456 that many characters up. Then, in the second part,
7457 we will have room to insert the newlines
7458 while copying down.
7459 NEWLINES may actually be too large, because it counts
7460 newlines in string constants, and we don't duplicate those.
7461 But that does no harm. */
7462 if (newlines > 0) {
7463 ibp = start + length;
7464 obp = ibp + newlines;
7465 limit = start;
7466 while (limit != ibp)
7467 *--obp = *--ibp;
7468 }
7469
7470 ibp = start + newlines;
7471 limit = start + length + newlines;
7472 obp = start;
7473
7474 while (ibp < limit) {
7475 *obp++ = c = *ibp++;
7476 switch (c) {
7477 case '\n':
7478 /* Duplicate the newline. */
7479 *obp++ = '\n';
7480 break;
7481
7482 case '\\':
7483 if (*ibp == '\n') {
7484 obp--;
7485 ibp++;
7486 }
7487 break;
7488
7489 case '/':
7490 if (*ibp == '\\' && ibp[1] == '\n')
7491 newline_fix (ibp);
7492 /* Delete any comment. */
7493 if (cplusplus_comments && ibp[0] == '/') {
7494 obp--;
7495 ibp++;
7496 while (ibp < limit && *ibp++ != '\n') ;
7497 break;
7498 }
7499 if (ibp[0] != '*' || ibp + 1 >= limit)
7500 break;
7501 obp--;
7502 ibp++;
7503 while (ibp + 1 < limit) {
7504 if (ibp[0] == '*'
7505 && ibp[1] == '\\' && ibp[2] == '\n')
7506 newline_fix (ibp + 1);
7507 if (ibp[0] == '*' && ibp[1] == '/')
7508 break;
7509 ibp++;
7510 }
7511 ibp += 2;
7512 break;
7513
7514 case '\'':
7515 case '\"':
7516 /* Notice and skip strings, so that we don't
7517 think that comments start inside them,
7518 and so we don't duplicate newlines in them. */
7519 {
7520 int quotec = c;
7521 while (ibp < limit) {
7522 *obp++ = c = *ibp++;
7523 if (c == quotec)
7524 break;
7525 if (c == '\n' && quotec == '\'')
7526 break;
7527 if (c == '\\' && ibp < limit) {
7528 while (*ibp == '\\' && ibp[1] == '\n')
7529 ibp += 2;
7530 *obp++ = *ibp++;
7531 }
7532 }
7533 }
7534 break;
7535 }
7536 }
7537
7538 return obp - start;
7539}
7540\f
7541/* Delete newlines in the string of length LENGTH at START, except inside
7542 of string constants. The string is copied into itself with its beginning
7543 staying fixed. */
7544
7545static int
7546delete_newlines (start, length)
7547 U_CHAR *start;
7548 int length;
7549{
7550 register U_CHAR *ibp;
7551 register U_CHAR *obp;
7552 register U_CHAR *limit;
7553 register int c;
7554
7555 ibp = start;
7556 limit = start + length;
7557 obp = start;
7558
7559 while (ibp < limit) {
7560 *obp++ = c = *ibp++;
7561 switch (c) {
7562 case '\n':
7563 /* If this is a NEWLINE NEWLINE, then this is a real newline in the
7564 output. Skip past the newline and its duplicate. */
7565 if (*ibp == '\n')
7566 {
7567 ibp++;
7568 obp--;
7569 }
7570 break;
7571
7572 case '\'':
7573 case '\"':
7574 /* Notice and skip strings, so that we don't delete newlines in them. */
7575 {
7576 int quotec = c;
7577 while (ibp < limit) {
7578 *obp++ = c = *ibp++;
7579 if (c == quotec)
7580 break;
7581 if (c == '\n' && quotec == '\'')
7582 break;
7583 }
7584 }
7585 break;
7586 }
7587 }
7588
7589 return obp - start;
7590}
7591\f
7592/*
7593 * error - print error message and increment count of errors.
7594 */
7595
7596void
7597error (msg, arg1, arg2, arg3)
7598 char *msg;
7599 char *arg1, *arg2, *arg3;
7600{
7601 int i;
7602 FILE_BUF *ip = NULL;
7603
7604 print_containing_files ();
7605
7606 for (i = indepth; i >= 0; i--)
7607 if (instack[i].fname != NULL) {
7608 ip = &instack[i];
7609 break;
7610 }
7611
7612 if (ip != NULL)
7613 fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
7614 fprintf (stderr, msg, arg1, arg2, arg3);
7615 fprintf (stderr, "\n");
7616 errors++;
7617}
7618
7619/* Error including a message from `errno'. */
7620
7621static void
7622error_from_errno (name)
7623 char *name;
7624{
7625 int i;
7626 FILE_BUF *ip = NULL;
7627
7628 print_containing_files ();
7629
7630 for (i = indepth; i >= 0; i--)
7631 if (instack[i].fname != NULL) {
7632 ip = &instack[i];
7633 break;
7634 }
7635
7636 if (ip != NULL)
7637 fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
7638
7639 if (errno < sys_nerr)
7640 fprintf (stderr, "%s: %s\n", name, sys_errlist[errno]);
7641 else
7642 fprintf (stderr, "%s: undocumented I/O error\n", name);
7643
7644 errors++;
7645}
7646
7647/* Print error message but don't count it. */
7648
7649void
7650warning (msg, arg1, arg2, arg3)
7651 char *msg;
7652 char *arg1, *arg2, *arg3;
7653{
7654 int i;
7655 FILE_BUF *ip = NULL;
7656
7657 if (inhibit_warnings)
7658 return;
7659
7660 if (warnings_are_errors)
7661 errors++;
7662
7663 print_containing_files ();
7664
7665 for (i = indepth; i >= 0; i--)
7666 if (instack[i].fname != NULL) {
7667 ip = &instack[i];
7668 break;
7669 }
7670
7671 if (ip != NULL)
7672 fprintf (stderr, "%s:%d: ", ip->nominal_fname, ip->lineno);
7673 fprintf (stderr, "warning: ");
7674 fprintf (stderr, msg, arg1, arg2, arg3);
7675 fprintf (stderr, "\n");
7676}
7677
7678static void
7679error_with_line (line, msg, arg1, arg2, arg3)
7680 int line;
7681 char *msg;
7682 char *arg1, *arg2, *arg3;
7683{
7684 int i;
7685 FILE_BUF *ip = NULL;
7686
7687 print_containing_files ();
7688
7689 for (i = indepth; i >= 0; i--)
7690 if (instack[i].fname != NULL) {
7691 ip = &instack[i];
7692 break;
7693 }
7694
7695 if (ip != NULL)
7696 fprintf (stderr, "%s:%d: ", ip->nominal_fname, line);
7697 fprintf (stderr, msg, arg1, arg2, arg3);
7698 fprintf (stderr, "\n");
7699 errors++;
7700}
7701
7702/* print an error message and maybe count it. */
7703
7704void
7705pedwarn (msg, arg1, arg2, arg3)
7706 char *msg;
7707 char *arg1, *arg2, *arg3;
7708{
7709 if (pedantic_errors)
7710 error (msg, arg1, arg2, arg3);
7711 else
7712 warning (msg, arg1, arg2, arg3);
7713}
7714
7715/* Report a warning (or an error if pedantic_errors)
7716 giving specified file name and line number, not current. */
7717
7718static void
7719pedwarn_with_file_and_line (file, line, msg, arg1, arg2, arg3)
7720 char *file;
7721 int line;
7722 char *msg;
7723 char *arg1, *arg2, *arg3;
7724{
7725 int i;
7726 if (!pedantic_errors && inhibit_warnings)
7727 return;
7728 if (file != NULL)
7729 fprintf (stderr, "%s:%d: ", file, line);
7730 if (pedantic_errors || warnings_are_errors)
7731 errors++;
7732 if (!pedantic_errors)
7733 fprintf (stderr, "warning: ");
7734 fprintf (stderr, msg, arg1, arg2, arg3);
7735 fprintf (stderr, "\n");
7736}
7737\f
7738/* Print the file names and line numbers of the #include
7739 commands which led to the current file. */
7740
7741static void
7742print_containing_files ()
7743{
7744 FILE_BUF *ip = NULL;
7745 int i;
7746 int first = 1;
7747
7748 /* If stack of files hasn't changed since we last printed
7749 this info, don't repeat it. */
7750 if (last_error_tick == input_file_stack_tick)
7751 return;
7752
7753 for (i = indepth; i >= 0; i--)
7754 if (instack[i].fname != NULL) {
7755 ip = &instack[i];
7756 break;
7757 }
7758
7759 /* Give up if we don't find a source file. */
7760 if (ip == NULL)
7761 return;
7762
7763 /* Find the other, outer source files. */
7764 for (i--; i >= 0; i--)
7765 if (instack[i].fname != NULL) {
7766 ip = &instack[i];
7767 if (first) {
7768 first = 0;
7769 fprintf (stderr, "In file included");
7770 } else {
7771 fprintf (stderr, ",");
7772 }
7773
7774 fprintf (stderr, " from %s:%d", ip->nominal_fname, ip->lineno);
7775 }
7776 if (! first)
7777 fprintf (stderr, ":\n");
7778
7779 /* Record we have printed the status as of this time. */
7780 last_error_tick = input_file_stack_tick;
7781}
7782\f
7783/* Return the line at which an error occurred.
7784 The error is not necessarily associated with the current spot
7785 in the input stack, so LINE says where. LINE will have been
7786 copied from ip->lineno for the current input level.
7787 If the current level is for a file, we return LINE.
7788 But if the current level is not for a file, LINE is meaningless.
7789 In that case, we return the lineno of the innermost file. */
7790
7791static int
7792line_for_error (line)
7793 int line;
7794{
7795 int i;
7796 int line1 = line;
7797
7798 for (i = indepth; i >= 0; ) {
7799 if (instack[i].fname != 0)
7800 return line1;
7801 i--;
7802 if (i < 0)
7803 return 0;
7804 line1 = instack[i].lineno;
7805 }
7806 abort ();
7807 /*NOTREACHED*/
7808 return 0;
7809}
7810
7811/*
7812 * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
7813 *
7814 * As things stand, nothing is ever placed in the output buffer to be
7815 * removed again except when it's KNOWN to be part of an identifier,
7816 * so flushing and moving down everything left, instead of expanding,
7817 * should work ok.
7818 */
7819
7820/* You might think void was cleaner for the return type,
7821 but that would get type mismatch in check_expand in strict ANSI. */
7822static int
7823grow_outbuf (obuf, needed)
7824 register FILE_BUF *obuf;
7825 register int needed;
7826{
7827 register U_CHAR *p;
7828 int minsize;
7829
7830 if (obuf->length - (obuf->bufp - obuf->buf) > needed)
7831 return 0;
7832
7833 /* Make it at least twice as big as it is now. */
7834 obuf->length *= 2;
7835 /* Make it have at least 150% of the free space we will need. */
7836 minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
7837 if (minsize > obuf->length)
7838 obuf->length = minsize;
7839
7840 if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL)
7841 memory_full ();
7842
7843 obuf->bufp = p + (obuf->bufp - obuf->buf);
7844 obuf->buf = p;
7845
7846 return 0;
7847}
7848\f
7849/* Symbol table for macro names and special symbols */
7850
7851/*
7852 * install a name in the main hash table, even if it is already there.
7853 * name stops with first non alphanumeric, except leading '#'.
7854 * caller must check against redefinition if that is desired.
7855 * delete_macro () removes things installed by install () in fifo order.
7856 * this is important because of the `defined' special symbol used
7857 * in #if, and also if pushdef/popdef directives are ever implemented.
7858 *
7859 * If LEN is >= 0, it is the length of the name.
7860 * Otherwise, compute the length by scanning the entire name.
7861 *
7862 * If HASH is >= 0, it is the precomputed hash code.
7863 * Otherwise, compute the hash code.
7864 */
7865static HASHNODE *
7866install (name, len, type, ivalue, value, hash)
7867 U_CHAR *name;
7868 int len;
7869 enum node_type type;
7870 int ivalue;
7871 char *value;
7872 int hash;
7873{
7874 register HASHNODE *hp;
7875 register int i, bucket;
7876 register U_CHAR *p, *q;
7877
7878 if (len < 0) {
7879 p = name;
7880 while (is_idchar[*p])
7881 p++;
7882 len = p - name;
7883 }
7884
7885 if (hash < 0)
7886 hash = hashf (name, len, HASHSIZE);
7887
7888 i = sizeof (HASHNODE) + len + 1;
7889 hp = (HASHNODE *) xmalloc (i);
7890 bucket = hash;
7891 hp->bucket_hdr = &hashtab[bucket];
7892 hp->next = hashtab[bucket];
7893 hashtab[bucket] = hp;
7894 hp->prev = NULL;
7895 if (hp->next != NULL)
7896 hp->next->prev = hp;
7897 hp->type = type;
7898 hp->length = len;
7899 if (hp->type == T_CONST)
7900 hp->value.ival = ivalue;
7901 else
7902 hp->value.cpval = value;
7903 hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
7904 p = hp->name;
7905 q = name;
7906 for (i = 0; i < len; i++)
7907 *p++ = *q++;
7908 hp->name[len] = 0;
7909 return hp;
7910}
7911
7912/*
7913 * find the most recent hash node for name name (ending with first
7914 * non-identifier char) installed by install
7915 *
7916 * If LEN is >= 0, it is the length of the name.
7917 * Otherwise, compute the length by scanning the entire name.
7918 *
7919 * If HASH is >= 0, it is the precomputed hash code.
7920 * Otherwise, compute the hash code.
7921 */
7922HASHNODE *
7923lookup (name, len, hash)
7924 U_CHAR *name;
7925 int len;
7926 int hash;
7927{
7928 register U_CHAR *bp;
7929 register HASHNODE *bucket;
7930
7931 if (len < 0) {
7932 for (bp = name; is_idchar[*bp]; bp++) ;
7933 len = bp - name;
7934 }
7935
7936 if (hash < 0)
7937 hash = hashf (name, len, HASHSIZE);
7938
7939 bucket = hashtab[hash];
7940 while (bucket) {
7941 if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
7942 return bucket;
7943 bucket = bucket->next;
7944 }
7945 return NULL;
7946}
7947
7948/*
7949 * Delete a hash node. Some weirdness to free junk from macros.
7950 * More such weirdness will have to be added if you define more hash
7951 * types that need it.
7952 */
7953
7954/* Note that the DEFINITION of a macro is removed from the hash table
7955 but its storage is not freed. This would be a storage leak
7956 except that it is not reasonable to keep undefining and redefining
7957 large numbers of macros many times.
7958 In any case, this is necessary, because a macro can be #undef'd
7959 in the middle of reading the arguments to a call to it.
7960 If #undef freed the DEFINITION, that would crash. */
7961
7962static void
7963delete_macro (hp)
7964 HASHNODE *hp;
7965{
7966
7967 if (hp->prev != NULL)
7968 hp->prev->next = hp->next;
7969 if (hp->next != NULL)
7970 hp->next->prev = hp->prev;
7971
7972 /* make sure that the bucket chain header that
7973 the deleted guy was on points to the right thing afterwards. */
7974 if (hp == *hp->bucket_hdr)
7975 *hp->bucket_hdr = hp->next;
7976
7977#if 0
7978 if (hp->type == T_MACRO) {
7979 DEFINITION *d = hp->value.defn;
7980 struct reflist *ap, *nextap;
7981
7982 for (ap = d->pattern; ap != NULL; ap = nextap) {
7983 nextap = ap->next;
7984 free (ap);
7985 }
7986 free (d);
7987 }
7988#endif
7989 free (hp);
7990}
7991
7992/*
7993 * return hash function on name. must be compatible with the one
7994 * computed a step at a time, elsewhere
7995 */
7996static int
7997hashf (name, len, hashsize)
7998 register U_CHAR *name;
7999 register int len;
8000 int hashsize;
8001{
8002 register int r = 0;
8003
8004 while (len--)
8005 r = HASHSTEP (r, *name++);
8006
8007 return MAKE_POS (r) % hashsize;
8008}
8009\f
8010
8011/* Dump the definition of a single macro HP to OF. */
8012static void
8013dump_single_macro (hp, of)
8014 register HASHNODE *hp;
8015 FILE *of;
8016{
8017 register DEFINITION *defn = hp->value.defn;
8018 struct reflist *ap;
8019 int offset;
8020 int concat;
8021
8022
8023 /* Print the definition of the macro HP. */
8024
8025 fprintf (of, "#define %s", hp->name);
8026
8027 if (defn->nargs >= 0) {
8028 int i;
8029
8030 fprintf (of, "(");
8031 for (i = 0; i < defn->nargs; i++) {
8032 dump_arg_n (defn, i, of);
8033 if (i + 1 < defn->nargs)
8034 fprintf (of, ", ");
8035 }
8036 fprintf (of, ")");
8037 }
8038
8039 fprintf (of, " ");
8040
8041 offset = 0;
8042 concat = 0;
8043 for (ap = defn->pattern; ap != NULL; ap = ap->next) {
8044 dump_defn_1 (defn->expansion, offset, ap->nchars, of);
8045 if (ap->nchars != 0)
8046 concat = 0;
8047 offset += ap->nchars;
8048 if (ap->stringify)
8049 fprintf (of, " #");
8050 if (ap->raw_before && !concat)
8051 fprintf (of, " ## ");
8052 concat = 0;
8053 dump_arg_n (defn, ap->argno, of);
8054 if (ap->raw_after) {
8055 fprintf (of, " ## ");
8056 concat = 1;
8057 }
8058 }
8059 dump_defn_1 (defn->expansion, offset, defn->length - offset, of);
8060 fprintf (of, "\n");
8061}
8062
8063/* Dump all macro definitions as #defines to stdout. */
8064
8065static void
8066dump_all_macros ()
8067{
8068 int bucket;
8069
8070 for (bucket = 0; bucket < HASHSIZE; bucket++) {
8071 register HASHNODE *hp;
8072
8073 for (hp = hashtab[bucket]; hp; hp= hp->next) {
8074 if (hp->type == T_MACRO)
8075 dump_single_macro (hp, stdout);
8076 }
8077 }
8078}
8079
8080/* Output to OF a substring of a macro definition.
8081 BASE is the beginning of the definition.
8082 Output characters START thru LENGTH.
8083 Discard newlines outside of strings, thus
8084 converting funny-space markers to ordinary spaces. */
8085
8086static void
8087dump_defn_1 (base, start, length, of)
8088 U_CHAR *base;
8089 int start;
8090 int length;
8091 FILE *of;
8092{
8093 U_CHAR *p = base + start;
8094 U_CHAR *limit = base + start + length;
8095
8096 while (p < limit) {
8097 if (*p != '\n')
8098 putc (*p, of);
8099 else if (*p == '\"' || *p =='\'') {
8100 U_CHAR *p1 = skip_quoted_string (p, limit, 0, NULL_PTR,
8101 NULL_PTR, NULL_PTR);
8102 fwrite (p, p1 - p, 1, of);
8103 p = p1 - 1;
8104 }
8105 p++;
8106 }
8107}
8108
8109/* Print the name of argument number ARGNUM of macro definition DEFN
8110 to OF.
8111 Recall that DEFN->args.argnames contains all the arg names
8112 concatenated in reverse order with comma-space in between. */
8113
8114static void
8115dump_arg_n (defn, argnum, of)
8116 DEFINITION *defn;
8117 int argnum;
8118 FILE *of;
8119{
8120 register U_CHAR *p = defn->args.argnames;
8121 while (argnum + 1 < defn->nargs) {
8122 p = (U_CHAR *) index (p, ' ') + 1;
8123 argnum++;
8124 }
8125
8126 while (*p && *p != ',') {
8127 putc (*p, of);
8128 p++;
8129 }
8130}
8131\f
8132/* Initialize syntactic classifications of characters. */
8133
8134static void
8135initialize_char_syntax ()
8136{
8137 register int i;
8138
8139 /*
8140 * Set up is_idchar and is_idstart tables. These should be
8141 * faster than saying (is_alpha (c) || c == '_'), etc.
8142 * Set up these things before calling any routines tthat
8143 * refer to them.
8144 */
8145 for (i = 'a'; i <= 'z'; i++) {
8146 is_idchar[i - 'a' + 'A'] = 1;
8147 is_idchar[i] = 1;
8148 is_idstart[i - 'a' + 'A'] = 1;
8149 is_idstart[i] = 1;
8150 }
8151 for (i = '0'; i <= '9'; i++)
8152 is_idchar[i] = 1;
8153 is_idchar['_'] = 1;
8154 is_idstart['_'] = 1;
8155 is_idchar['$'] = dollars_in_ident;
8156 is_idstart['$'] = dollars_in_ident;
8157
8158 /* horizontal space table */
8159 is_hor_space[' '] = 1;
8160 is_hor_space['\t'] = 1;
8161 is_hor_space['\v'] = 1;
8162 is_hor_space['\f'] = 1;
8163 is_hor_space['\r'] = 1;
8164
8165 is_space[' '] = 1;
8166 is_space['\t'] = 1;
8167 is_space['\v'] = 1;
8168 is_space['\f'] = 1;
8169 is_space['\n'] = 1;
8170 is_space['\r'] = 1;
8171}
8172
8173/* Initialize the built-in macros. */
8174
8175static void
8176initialize_builtins (inp, outp)
8177 FILE_BUF *inp;
8178 FILE_BUF *outp;
8179{
8180 install ("__LINE__", -1, T_SPECLINE, 0, 0, -1);
8181 install ("__DATE__", -1, T_DATE, 0, 0, -1);
8182 install ("__FILE__", -1, T_FILE, 0, 0, -1);
8183 install ("__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1);
8184 install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1);
8185 install ("__VERSION__", -1, T_VERSION, 0, 0, -1);
8186 install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1);
8187 install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0, 0, -1);
8188 install ("__WCHAR_TYPE__", -1, T_WCHAR_TYPE, 0, 0, -1);
8189 install ("__TIME__", -1, T_TIME, 0, 0, -1);
8190 if (!traditional)
8191 install ("__STDC__", -1, T_CONST, STDC_VALUE, 0, -1);
8192 if (objc)
8193 install ("__OBJC__", -1, T_CONST, 1, 0, -1);
8194/* This is supplied using a -D by the compiler driver
8195 so that it is present only when truly compiling with GNU C. */
8196/* install ("__GNUC__", -1, T_CONST, 2, 0, -1); */
8197
8198 if (debug_output)
8199 {
8200 char directive[2048];
8201 register struct directive *dp = &directive_table[0];
8202 struct tm *timebuf = timestamp ();
8203
8204 sprintf (directive, " __BASE_FILE__ \"%s\"\n",
8205 instack[0].nominal_fname);
8206 output_line_command (inp, outp, 0, same_file);
8207 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8208
8209 sprintf (directive, " __VERSION__ \"%s\"\n", version_string);
8210 output_line_command (inp, outp, 0, same_file);
8211 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8212
8213 sprintf (directive, " __SIZE_TYPE__ %s\n", SIZE_TYPE);
8214 output_line_command (inp, outp, 0, same_file);
8215 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8216
8217 sprintf (directive, " __PTRDIFF_TYPE__ %s\n", PTRDIFF_TYPE);
8218 output_line_command (inp, outp, 0, same_file);
8219 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8220
8221 sprintf (directive, " __WCHAR_TYPE__ %s\n", WCHAR_TYPE);
8222 output_line_command (inp, outp, 0, same_file);
8223 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8224
8225 sprintf (directive, " __DATE__ \"%s %2d %4d\"\n",
8226 monthnames[timebuf->tm_mon],
8227 timebuf->tm_mday, timebuf->tm_year + 1900);
8228 output_line_command (inp, outp, 0, same_file);
8229 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8230
8231 sprintf (directive, " __TIME__ \"%02d:%02d:%02d\"\n",
8232 timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec);
8233 output_line_command (inp, outp, 0, same_file);
8234 pass_thru_directive (directive, &directive[strlen (directive)], outp, dp);
8235
8236 if (!traditional)
8237 {
8238 sprintf (directive, " __STDC__ 1");
8239 output_line_command (inp, outp, 0, same_file);
8240 pass_thru_directive (directive, &directive[strlen (directive)],
8241 outp, dp);
8242 }
8243 if (objc)
8244 {
8245 sprintf (directive, " __OBJC__ 1");
8246 output_line_command (inp, outp, 0, same_file);
8247 pass_thru_directive (directive, &directive[strlen (directive)],
8248 outp, dp);
8249 }
8250 }
8251}
8252\f
8253/*
8254 * process a given definition string, for initialization
8255 * If STR is just an identifier, define it with value 1.
8256 * If STR has anything after the identifier, then it should
8257 * be identifier=definition.
8258 */
8259
8260static void
8261make_definition (str, op)
8262 U_CHAR *str;
8263 FILE_BUF *op;
8264{
8265 FILE_BUF *ip;
8266 struct directive *kt;
8267 U_CHAR *buf, *p;
8268
8269 buf = str;
8270 p = str;
8271 if (!is_idstart[*p]) {
8272 error ("malformed option `-D %s'", str);
8273 return;
8274 }
8275 while (is_idchar[*++p])
8276 ;
8277 if (*p == 0) {
8278 buf = (U_CHAR *) alloca (p - buf + 4);
8279 strcpy ((char *)buf, str);
8280 strcat ((char *)buf, " 1");
8281 } else if (*p != '=') {
8282 error ("malformed option `-D %s'", str);
8283 return;
8284 } else {
8285 U_CHAR *q;
8286 /* Copy the entire option so we can modify it. */
8287 buf = (U_CHAR *) alloca (2 * strlen (str) + 1);
8288 strncpy (buf, str, p - str);
8289 /* Change the = to a space. */
8290 buf[p - str] = ' ';
8291 /* Scan for any backslash-newline and remove it. */
8292 p++;
8293 q = &buf[p - str];
8294 while (*p) {
8295 if (*p == '\\' && p[1] == '\n')
8296 p += 2;
8297 /* Change newline chars into newline-markers. */
8298 else if (*p == '\n')
8299 {
8300 *q++ = '\n';
8301 *q++ = '\n';
8302 p++;
8303 }
8304 else
8305 *q++ = *p++;
8306 }
8307 *q = 0;
8308 }
8309
8310 ip = &instack[++indepth];
8311 ip->nominal_fname = ip->fname = "*Initialization*";
8312
8313 ip->buf = ip->bufp = buf;
8314 ip->length = strlen (buf);
8315 ip->lineno = 1;
8316 ip->macro = 0;
8317 ip->free_ptr = 0;
8318 ip->if_stack = if_stack;
8319 ip->system_header_p = 0;
8320
8321 for (kt = directive_table; kt->type != T_DEFINE; kt++)
8322 ;
8323
8324 do_define (buf, buf + strlen (buf) , op, kt);
8325 --indepth;
8326}
8327
8328/* JF, this does the work for the -U option */
8329
8330static void
8331make_undef (str, op)
8332 U_CHAR *str;
8333 FILE_BUF *op;
8334{
8335 FILE_BUF *ip;
8336 struct directive *kt;
8337
8338 ip = &instack[++indepth];
8339 ip->nominal_fname = ip->fname = "*undef*";
8340
8341 ip->buf = ip->bufp = str;
8342 ip->length = strlen (str);
8343 ip->lineno = 1;
8344 ip->macro = 0;
8345 ip->free_ptr = 0;
8346 ip->if_stack = if_stack;
8347 ip->system_header_p = 0;
8348
8349 for (kt = directive_table; kt->type != T_UNDEF; kt++)
8350 ;
8351
8352 do_undef (str, str + strlen (str), op, kt);
8353 --indepth;
8354}
8355\f
8356/* Process the string STR as if it appeared as the body of a #assert.
8357 OPTION is the option name for which STR was the argument. */
8358
8359static void
8360make_assertion (option, str)
8361 char *option;
8362 U_CHAR *str;
8363{
8364 FILE_BUF *ip;
8365 struct directive *kt;
8366 U_CHAR *buf, *p, *q;
8367
8368 /* Copy the entire option so we can modify it. */
8369 buf = (U_CHAR *) alloca (strlen (str) + 1);
8370 strcpy ((char *) buf, str);
8371 /* Scan for any backslash-newline and remove it. */
8372 p = q = buf;
8373 while (*p) {
8374 if (*p == '\\' && p[1] == '\n')
8375 p += 2;
8376 else
8377 *q++ = *p++;
8378 }
8379 *q = 0;
8380
8381 p = buf;
8382 if (!is_idstart[*p]) {
8383 error ("malformed option `%s %s'", option, str);
8384 return;
8385 }
8386 while (is_idchar[*++p])
8387 ;
8388 while (*p == ' ' || *p == '\t') p++;
8389 if (! (*p == 0 || *p == '(')) {
8390 error ("malformed option `%s %s'", option, str);
8391 return;
8392 }
8393
8394 ip = &instack[++indepth];
8395 ip->nominal_fname = ip->fname = "*Initialization*";
8396
8397 ip->buf = ip->bufp = buf;
8398 ip->length = strlen (buf);
8399 ip->lineno = 1;
8400 ip->macro = 0;
8401 ip->free_ptr = 0;
8402 ip->if_stack = if_stack;
8403 ip->system_header_p = 0;
8404
8405 for (kt = directive_table; kt->type != T_ASSERT; kt++)
8406 ;
8407
8408 /* pass NULL as output ptr to do_define since we KNOW it never
8409 does any output.... */
8410 do_assert (buf, buf + strlen (buf) , NULL_PTR, kt);
8411 --indepth;
8412}
8413\f
8414/* Append a chain of `struct file_name_list's
8415 to the end of the main include chain.
8416 FIRST is the beginning of the chain to append, and LAST is the end. */
8417
8418static void
8419append_include_chain (first, last)
8420 struct file_name_list *first, *last;
8421{
8422 struct file_name_list *dir;
8423
8424 if (!first || !last)
8425 return;
8426
8427 if (include == 0)
8428 include = first;
8429 else
8430 last_include->next = first;
8431
8432 if (first_bracket_include == 0)
8433 first_bracket_include = first;
8434
8435 for (dir = first; ; dir = dir->next) {
8436 int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE;
8437 if (len > max_include_len)
8438 max_include_len = len;
8439 if (dir == last)
8440 break;
8441 }
8442
8443 last->next = NULL;
8444 last_include = last;
8445}
8446\f
8447/* Add output to `deps_buffer' for the -M switch.
8448 STRING points to the text to be output.
8449 SIZE is the number of bytes, or 0 meaning output until a null.
8450 Outputting the empty string breaks the line if it is long enough. */
8451
8452static void
8453deps_output (string, size)
8454 char *string;
8455 unsigned size;
8456{
8457 if (size == 0)
8458 size = strlen (string);
8459
8460#ifndef MAX_OUTPUT_COLUMNS
8461#define MAX_OUTPUT_COLUMNS 75
8462#endif
8463 if (size == 0 && deps_column != 0
8464 && size + deps_column > MAX_OUTPUT_COLUMNS) {
8465 deps_output ("\\\n ", 0);
8466 deps_column = 0;
8467 }
8468
8469 if (deps_size + size + 1 > deps_allocated_size) {
8470 deps_allocated_size = deps_size + size + 50;
8471 deps_allocated_size *= 2;
8472 deps_buffer = (char *) xrealloc (deps_buffer, deps_allocated_size);
8473 }
8474 bcopy (string, &deps_buffer[deps_size], size);
8475 deps_size += size;
8476 deps_column += size;
8477 deps_buffer[deps_size] = 0;
8478}
8479\f
8480#if defined(USG) || defined(VMS)
8481#ifndef BSTRING
8482
8483void
8484bzero (b, length)
8485 register char *b;
8486 register unsigned length;
8487{
8488 while (length-- > 0)
8489 *b++ = 0;
8490}
8491
8492void
8493bcopy (b1, b2, length)
8494 register char *b1;
8495 register char *b2;
8496 register unsigned length;
8497{
8498 while (length-- > 0)
8499 *b2++ = *b1++;
8500}
8501
8502int
8503bcmp (b1, b2, length) /* This could be a macro! */
8504 register char *b1;
8505 register char *b2;
8506 register unsigned length;
8507{
8508 while (length-- > 0)
8509 if (*b1++ != *b2++)
8510 return 1;
8511
8512 return 0;
8513}
8514#endif /* not BSTRING */
8515#endif /* USG or VMS */
8516
8517\f
8518static void
8519fatal (str, arg)
8520 char *str, *arg;
8521{
8522 fprintf (stderr, "%s: ", progname);
8523 fprintf (stderr, str, arg);
8524 fprintf (stderr, "\n");
8525 exit (FAILURE_EXIT_CODE);
8526}
8527
8528/* More 'friendly' abort that prints the line and file.
8529 config.h can #define abort fancy_abort if you like that sort of thing. */
8530
8531void
8532fancy_abort ()
8533{
8534 fatal ("Internal gcc abort.");
8535}
8536
8537static void
8538perror_with_name (name)
8539 char *name;
8540{
8541 fprintf (stderr, "%s: ", progname);
8542 if (errno < sys_nerr)
8543 fprintf (stderr, "%s: %s\n", name, sys_errlist[errno]);
8544 else
8545 fprintf (stderr, "%s: undocumented I/O error\n", name);
8546 errors++;
8547}
8548
8549static void
8550pfatal_with_name (name)
8551 char *name;
8552{
8553 perror_with_name (name);
8554#ifdef VMS
8555 exit (vaxc$errno);
8556#else
8557 exit (FAILURE_EXIT_CODE);
8558#endif
8559}
8560
8561\f
8562static void
8563memory_full ()
8564{
8565 fatal ("Memory exhausted.");
8566}
8567
8568
8569char *
8570xmalloc (size)
8571 unsigned size;
8572{
8573 register char *ptr = (char *) malloc (size);
8574 if (ptr != 0) return (ptr);
8575 memory_full ();
8576 /*NOTREACHED*/
8577 return 0;
8578}
8579
8580static char *
8581xrealloc (old, size)
8582 char *old;
8583 unsigned size;
8584{
8585 register char *ptr = (char *) realloc (old, size);
8586 if (ptr != 0) return (ptr);
8587 memory_full ();
8588 /*NOTREACHED*/
8589 return 0;
8590}
8591
8592static char *
8593xcalloc (number, size)
8594 unsigned number, size;
8595{
8596 register unsigned total = number * size;
8597 register char *ptr = (char *) malloc (total);
8598 if (ptr != 0) {
8599 if (total > 100)
8600 bzero (ptr, total);
8601 else {
8602 /* It's not too long, so loop, zeroing by longs.
8603 It must be safe because malloc values are always well aligned. */
8604 register long *zp = (long *) ptr;
8605 register long *zl = (long *) (ptr + total - 4);
8606 register int i = total - 4;
8607 while (zp < zl)
8608 *zp++ = 0;
8609 if (i < 0)
8610 i = 0;
8611 while (i < total)
8612 ptr[i++] = 0;
8613 }
8614 return ptr;
8615 }
8616 memory_full ();
8617 /*NOTREACHED*/
8618 return 0;
8619}
8620
8621static char *
8622savestring (input)
8623 char *input;
8624{
8625 unsigned size = strlen (input);
8626 char *output = xmalloc (size + 1);
8627 strcpy (output, input);
8628 return output;
8629}
8630\f
8631/* Get the file-mode and data size of the file open on FD
8632 and store them in *MODE_POINTER and *SIZE_POINTER. */
8633
8634static int
8635file_size_and_mode (fd, mode_pointer, size_pointer)
8636 int fd;
8637 int *mode_pointer;
8638 long int *size_pointer;
8639{
8640 struct stat sbuf;
8641
8642 if (fstat (fd, &sbuf) < 0) return (-1);
8643 if (mode_pointer) *mode_pointer = sbuf.st_mode;
8644 if (size_pointer) *size_pointer = sbuf.st_size;
8645 return 0;
8646}
8647\f
8648#ifdef VMS
8649
8650/* Under VMS we need to fix up the "include" specification
8651 filename so that everything following the 1st slash is
8652 changed into its correct VMS file specification. */
8653
8654static void
8655hack_vms_include_specification (fname)
8656 char *fname;
8657{
8658 register char *cp, *cp1, *cp2;
8659 int f, check_filename_before_returning, no_prefix_seen;
8660 char Local[512];
8661
8662 check_filename_before_returning = 0;
8663 no_prefix_seen = 0;
8664
8665 /* Ignore leading "./"s */
8666 while (fname[0] == '.' && fname[1] == '/') {
8667 strcpy (fname, fname+2);
8668 no_prefix_seen = 1; /* mark this for later */
8669 }
8670 /* Look for the boundary between the VMS and UNIX filespecs */
8671 cp = rindex (fname, ']'); /* Look for end of dirspec. */
8672 if (cp == 0) cp = rindex (fname, '>'); /* ... Ditto */
8673 if (cp == 0) cp = rindex (fname, ':'); /* Look for end of devspec. */
8674 if (cp) {
8675 cp++;
8676 } else {
8677 cp = index (fname, '/'); /* Look for the "/" */
8678 }
8679
8680 cp2 = Local; /* initialize */
8681
8682 /* We are trying to do a number of things here. First of all, we are
8683 trying to hammer the filenames into a standard format, such that later
8684 processing can handle them.
8685
8686 If the file name contains something like [dir.], then it recognizes this
8687 as a root, and strips the ".]". Later processing will add whatever is
8688 needed to get things working properly.
8689
8690 If no device is specified, then the first directory name is taken to be
8691 a device name (or a rooted logical). */
8692
8693 /* See if we found that 1st slash */
8694 if (cp == 0) return; /* Nothing to do!!! */
8695 if (*cp != '/') return; /* Nothing to do!!! */
8696 /* Point to the UNIX filename part (which needs to be fixed!) */
8697 cp1 = cp+1;
8698 /* If the directory spec is not rooted, we can just copy
8699 the UNIX filename part and we are done */
8700 if (((cp - fname) > 1) && ((cp[-1] == ']') || (cp[-1] == '>'))) {
8701 if (cp[-2] != '.') {
8702 /*
8703 * The VMS part ends in a `]', and the preceding character is not a `.'.
8704 * We strip the `]', and then splice the two parts of the name in the
8705 * usual way. Given the default locations for include files in cccp.c,
8706 * we will only use this code if the user specifies alternate locations
8707 * with the /include (-I) switch on the command line. */
8708 cp -= 1; /* Strip "]" */
8709 cp1--; /* backspace */
8710 } else {
8711 /*
8712 * The VMS part has a ".]" at the end, and this will not do. Later
8713 * processing will add a second directory spec, and this would be a syntax
8714 * error. Thus we strip the ".]", and thus merge the directory specs.
8715 * We also backspace cp1, so that it points to a '/'. This inhibits the
8716 * generation of the 000000 root directory spec (which does not belong here
8717 * in this case).
8718 */
8719 cp -= 2; /* Strip ".]" */
8720 cp1--; }; /* backspace */
8721 } else {
8722
8723 /* We drop in here if there is no VMS style directory specification yet.
8724 * If there is no device specification either, we make the first dir a
8725 * device and try that. If we do not do this, then we will be essentially
8726 * searching the users default directory (as if they did a #include "asdf.h").
8727 *
8728 * Then all we need to do is to push a '[' into the output string. Later
8729 * processing will fill this in, and close the bracket.
8730 */
8731 if(cp[-1] != ':') *cp2++ = ':'; /* dev not in spec. take first dir */
8732 *cp2++ = '['; /* Open the directory specification */
8733 }
8734
8735 /* at this point we assume that we have the device spec, and (at least
8736 the opening "[" for a directory specification. We may have directories
8737 specified already */
8738
8739 /* If there are no other slashes then the filename will be
8740 in the "root" directory. Otherwise, we need to add
8741 directory specifications. */
8742 if (index (cp1, '/') == 0) {
8743 /* Just add "000000]" as the directory string */
8744 strcpy (cp2, "000000]");
8745 cp2 += strlen (cp2);
8746 check_filename_before_returning = 1; /* we might need to fool with this later */
8747 } else {
8748 /* As long as there are still subdirectories to add, do them. */
8749 while (index (cp1, '/') != 0) {
8750 /* If this token is "." we can ignore it */
8751 if ((cp1[0] == '.') && (cp1[1] == '/')) {
8752 cp1 += 2;
8753 continue;
8754 }
8755 /* Add a subdirectory spec. Do not duplicate "." */
8756 if (cp2[-1] != '.' && cp2[-1] != '[' && cp2[-1] != '<')
8757 *cp2++ = '.';
8758 /* If this is ".." then the spec becomes "-" */
8759 if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) {
8760 /* Add "-" and skip the ".." */
8761 *cp2++ = '-';
8762 cp1 += 3;
8763 continue;
8764 }
8765 /* Copy the subdirectory */
8766 while (*cp1 != '/') *cp2++= *cp1++;
8767 cp1++; /* Skip the "/" */
8768 }
8769 /* Close the directory specification */
8770 if(cp2[-1] == '.') /* no trailing periods */
8771 cp2--;
8772 *cp2++ = ']';
8773 }
8774 /* Now add the filename */
8775 while (*cp1) *cp2++ = *cp1++;
8776 *cp2 = 0;
8777 /* Now append it to the original VMS spec. */
8778 strcpy (cp, Local);
8779
8780 /* If we put a [000000] in the filename, try to open it first. If this fails,
8781 remove the [000000], and return that name. This provides flexibility
8782 to the user in that they can use both rooted and non-rooted logical names
8783 to point to the location of the file. */
8784
8785 if (check_filename_before_returning && no_prefix_seen) {
8786 f = open (fname, O_RDONLY, 0666);
8787 if (f >= 0) {
8788 /* The file name is OK as it is, so return it as is. */
8789 close (f);
8790 return;
8791 }
8792 /* The filename did not work. Try to remove the [000000] from the name,
8793 and return it. */
8794 cp = index (fname, '[');
8795 cp2 = index (fname, ']') + 1;
8796 strcpy (cp, cp2); /* this gets rid of it */
8797 }
8798 return;
8799}
8800#endif /* VMS */
8801\f
8802#ifdef VMS
8803
8804/* These are the read/write replacement routines for
8805 VAX-11 "C". They make read/write behave enough
8806 like their UNIX counterparts that CCCP will work */
8807
8808static int
8809read (fd, buf, size)
8810 int fd;
8811 char *buf;
8812 int size;
8813{
8814#undef read /* Get back the REAL read routine */
8815 register int i;
8816 register int total = 0;
8817
8818 /* Read until the buffer is exhausted */
8819 while (size > 0) {
8820 /* Limit each read to 32KB */
8821 i = (size > (32*1024)) ? (32*1024) : size;
8822 i = read (fd, buf, i);
8823 if (i <= 0) {
8824 if (i == 0) return (total);
8825 return(i);
8826 }
8827 /* Account for this read */
8828 total += i;
8829 buf += i;
8830 size -= i;
8831 }
8832 return (total);
8833}
8834
8835static int
8836write (fd, buf, size)
8837 int fd;
8838 char *buf;
8839 int size;
8840{
8841#undef write /* Get back the REAL write routine */
8842 int i;
8843 int j;
8844
8845 /* Limit individual writes to 32Kb */
8846 i = size;
8847 while (i > 0) {
8848 j = (i > (32*1024)) ? (32*1024) : i;
8849 if (write (fd, buf, j) < 0) return (-1);
8850 /* Account for the data written */
8851 buf += j;
8852 i -= j;
8853 }
8854 return (size);
8855}
8856
8857/* The following wrapper functions supply additional arguments to the VMS
8858 I/O routines to optimize performance with file handling. The arguments
8859 are:
8860 "mbc=16" - Set multi-block count to 16 (use a 8192 byte buffer).
8861 "deq=64" - When extending the file, extend it in chunks of 32Kbytes.
8862 "fop=tef"- Truncate unused portions of file when closing file.
8863 "shr=nil"- Disallow file sharing while file is open.
8864 */
8865
8866static FILE *
8867freopen (fname, type, oldfile)
8868 char *fname;
8869 char *type;
8870 FILE *oldfile;
8871{
8872#undef freopen /* Get back the REAL fopen routine */
8873 if (strcmp (type, "w") == 0)
8874 return freopen (fname, type, oldfile, "mbc=16", "deq=64", "fop=tef", "shr=nil");
8875 return freopen (fname, type, oldfile, "mbc=16");
8876}
8877
8878static FILE *
8879fopen (fname, type)
8880 char *fname;
8881 char *type;
8882{
8883#undef fopen /* Get back the REAL fopen routine */
8884 if (strcmp (type, "w") == 0)
8885 return fopen (fname, type, "mbc=16", "deq=64", "fop=tef", "shr=nil");
8886 return fopen (fname, type, "mbc=16");
8887}
8888
8889static int
8890open (fname, flags, prot)
8891 char *fname;
8892 int flags;
8893 int prot;
8894{
8895#undef open /* Get back the REAL open routine */
8896 return open (fname, flags, prot, "mbc=16", "deq=64", "fop=tef");
8897}
8898
8899/* Avoid run-time library bug, where copying M out of N+M characters with
8900 N >= 65535 results in VAXCRTL's strncat falling into an infinite loop.
8901 gcc-cpp exercises this particular bug. */
8902
8903static char *
8904strncat (dst, src, cnt)
8905 char *dst;
8906 const char *src;
8907 unsigned cnt;
8908{
8909 register char *d = dst, *s = (char *) src;
8910 register int n = cnt; /* convert to _signed_ type */
8911
8912 while (*d) d++; /* advance to end */
8913 while (--n >= 0)
8914 if (!(*d++ = *s++)) break;
8915 if (n < 0) *d = '\0';
8916 return dst;
8917}
8918#endif /* VMS */