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