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