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