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