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