|
|
1.1 root 1: /* C Compatible Compiler Preprocessor (CCCP)
2: Copyright (C) 1986, 1987, Free Software Foundation, Inc.
3: Written by Paul Rubin, June 1986
4: Adapted to ANSI C, Richard Stallman, Jan 1987
5:
6: NO WARRANTY
7:
8: BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
9: NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
10: WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
11: RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
12: WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
13: BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
14: FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
15: AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
16: DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
17: CORRECTION.
18:
19: IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
20: STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
21: WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
22: LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
23: OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
24: USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
25: DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
26: A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
27: PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
28: DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
29:
30: GENERAL PUBLIC LICENSE TO COPY
31:
32: 1. You may copy and distribute verbatim copies of this source file
33: as you receive it, in any medium, provided that you conspicuously
34: and appropriately publish on each copy a valid copyright notice
35: "Copyright (C) 1987, Free Software Foundation"; and include
36: following the copyright notice a verbatim copy of the above disclaimer
37: of warranty and of this License. You may charge a distribution fee for the
38: physical act of transferring a copy.
39:
40: 2. You may modify your copy or copies of this source file or
41: any portion of it, and copy and distribute such modifications under
42: the terms of Paragraph 1 above, provided that you also do the following:
43:
44: a) cause the modified files to carry prominent notices stating
45: that you changed the files and the date of any change; and
46:
47: b) cause the whole of any work that you distribute or publish,
48: that in whole or in part contains or is a derivative of this
49: program or any part thereof, to be licensed at no charge to all
50: third parties on terms identical to those contained in this
51: License Agreement (except that you may choose to grant more extensive
52: warranty protection to some or all third parties, at your option).
53:
54: c) You may charge a distribution fee for the physical act of
55: transferring a copy, and you may at your option offer warranty
56: protection in exchange for a fee.
57:
58: Mere aggregation of another unrelated program with this program (or its
59: derivative) on a volume of a storage or distribution medium does not bring
60: the other program under the scope of these terms.
61:
62: 3. You may copy and distribute this program (or a portion or derivative
63: of it, under Paragraph 2) in object code or executable form under the terms
64: of Paragraphs 1 and 2 above provided that you also do one of the following:
65:
66: a) accompany it with the complete corresponding machine-readable
67: source code, which must be distributed under the terms of
68: Paragraphs 1 and 2 above; or,
69:
70: b) accompany it with a written offer, valid for at least three
71: years, to give any third party free (except for a nominal
72: shipping charge) a complete machine-readable copy of the
73: corresponding source code, to be distributed under the terms of
74: Paragraphs 1 and 2 above; or,
75:
76: c) accompany it with the information you received as to where the
77: corresponding source code may be obtained. (This alternative is
78: allowed only for noncommercial distribution and only if you
79: received the program in object code or executable form alone.)
80:
81: For an executable file, complete source code means all the source code for
82: all modules it contains; but, as a special exception, it need not include
83: source code for modules which are standard libraries that accompany the
84: operating system on which the executable file runs.
85:
86: 4. You may not copy, sublicense, distribute or transfer this program
87: except as expressly provided under this License Agreement. Any attempt
88: otherwise to copy, sublicense, distribute or transfer this program is void and
89: your rights to use the program under this License agreement shall be
90: automatically terminated. However, parties who have received computer
91: software programs from you with this License Agreement will not have
92: their licenses terminated so long as such parties remain in full compliance.
93:
94: 5. If you wish to incorporate parts of this program into other free
95: programs whose distribution conditions are different, write to the Free
96: Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
97: worked out a simple rule that can be stated here, but we will often permit
98: this. We will be guided by the two goals of preserving the free status of
99: all derivatives of our free software and of promoting the sharing and reuse of
100: software.
101:
102:
103: In other words, you are welcome to use, share and improve this program.
104: You are forbidden to forbid anyone else to use, share and improve
105: what you give them. Help stamp out software-hoarding! */
106:
107: typedef unsigned char U_CHAR;
108:
109: #ifdef EMACS
110: #define NO_SHORTNAMES
111: #include "../src/config.h"
112: #ifdef open
113: #undef open
114: #undef read
115: #undef write
116: #endif /* open */
117: #endif /* EMACS */
118:
119: #ifndef EMACS
120: #include "config.h"
121: #endif /* not EMACS */
122:
123: /* In case config.h defines these. */
124: #undef bcopy
125: #undef bzero
126: #undef bcmp
127:
128: #include <sys/types.h>
129: #include <sys/stat.h>
130: #include <ctype.h>
131: #include <stdio.h>
132:
133: #ifndef VMS
134: #include <sys/file.h>
135: #ifndef USG
136: #include <sys/time.h> /* for __DATE__ and __TIME__ */
137: #include <sys/resource.h>
138: #else
139: #define index strchr
140: #define rindex strrchr
141: #include <time.h>
142: #include <fcntl.h>
143: #endif /* USG */
144: #endif /* not VMS */
145:
146: /* VMS-specific definitions */
147: #ifdef VMS
148: #include <time.h>
149: #include <errno.h> /* This defines "errno" properly */
150: #include <perror.h> /* This defines sys_errlist/sys_nerr properly */
151: #define O_RDONLY 0 /* Open arg for Read/Only */
152: #define O_WRONLY 1 /* Open arg for Write/Only */
153: #define read(fd,buf,size) VAX11_C_read(fd,buf,size)
154: #define write(fd,buf,size) VAX11_C_write(fd,buf,size)
155: #ifdef __GNUC__
156: #define BSTRING /* VMS/GCC supplies the bstring routines */
157: #endif __GNUC__
158: #endif /* VMS */
159:
160: /* External declarations. */
161:
162: void bcopy (), bzero ();
163: int bcmp ();
164: extern char version_string[];
165:
166: /* Forward declarations. */
167:
168: int do_define (), do_line (), do_include (), do_undef (), do_error (),
169: do_pragma (), do_if (), do_xifdef (), do_else (),
170: do_elif (), do_endif (), do_sccs ();
171:
172: struct hashnode *install ();
173: struct hashnode *lookup ();
174:
175: char *xmalloc (), *xrealloc (), *xcalloc ();
176: void fatal (), pfatal_with_name (), perror_with_name ();
177:
178: int grow_outbuf ();
179: int handle_directive ();
180: void memory_full ();
181:
182: U_CHAR *macarg1 ();
183: char *macarg ();
184:
185: U_CHAR *skip_to_end_of_comment ();
186: U_CHAR *skip_quoted_string ();
187:
188: #ifndef FATAL_EXIT_CODE
189: #define FATAL_EXIT_CODE 33 /* gnu cc command understands this */
190: #endif
191:
192: #ifndef SUCCESS_EXIT_CODE
193: #define SUCCESS_EXIT_CODE 0 /* 0 means success on Unix. */
194: #endif
195:
196: /* Name under which this program was invoked. */
197:
198: char *progname;
199:
200: /* Current maximum length of directory names in the search path
201: for include files. (Altered as we get more of them.) */
202:
203: int max_include_len = sizeof("/usr/local/lib/gcc-include");
204:
205: /* Nonzero means copy comments into the output file. */
206:
207: int put_out_comments = 0;
208:
209: /* Nonzero means don't process the ANSI trigraph sequences. */
210:
211: int no_trigraphs = 0;
212:
213: /* Nonzero means print the names of included files rather than
214: the preprocessed output. 1 means just the #include "...",
215: 2 means #include <...> as well. */
216:
217: int print_deps = 0;
218:
219: /* Nonzero means don't output line number information. */
220:
221: int no_line_commands;
222:
223: /* Nonzero means inhibit output of the preprocessed text
224: and instead output the definitions of all user-defined macros
225: in a form suitable for use as input to cccp. */
226:
227: int dump_macros;
228:
229: /* Nonzero means give all the error messages the ANSI standard requires. */
230:
231: int pedantic;
232:
233: /* Nonzero means warn if slash-star appears in a comment. */
234:
235: int warn_comments;
236:
237: /* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
238:
239: int traditional;
240:
241: /* Nonzero causes output not to be done,
242: but directives such as #define that have side effects
243: are still obeyed. */
244:
245: int no_output;
246:
247: /* I/O buffer structure.
248: The `fname' field is nonzero for source files and #include files
249: and for the dummy text used for -D and -U.
250: It is zero for rescanning results of macro expansion
251: and for expanding macro arguments. */
252: #define INPUT_STACK_MAX 200
253: struct file_buf {
254: char *fname;
255: int lineno;
256: int length;
257: U_CHAR *buf;
258: U_CHAR *bufp;
259: /* Macro that this level is the expansion of.
260: Included so that we can reenable the macro
261: at the end of this level. */
262: struct hashnode *macro;
263: /* Value of if_stack at start of this file.
264: Used to prohibit unmatched #endif (etc) in an include file. */
265: struct if_stack *if_stack;
266: /* Object to be freed at end of input at this level. */
267: U_CHAR *free;
268: } instack[INPUT_STACK_MAX];
269:
270: /* Current nesting level of input sources.
271: `instack[indepth]' is the level currently being read. */
272: int indepth = -1;
273:
274: typedef struct file_buf FILE_BUF;
275:
276: /* The output buffer. Its LENGTH field is the amount of room allocated
277: for the buffer, not the number of chars actually present. To get
278: that, subtract outbuf.buf from outbuf.bufp. */
279:
280: #define OUTBUF_SIZE 10 /* initial size of output buffer */
281: FILE_BUF outbuf;
282:
283: /* Grow output buffer OBUF points at
284: so it can hold at least NEEDED more chars. */
285:
286: #define check_expand(OBUF, NEEDED) \
287: (((OBUF)->length - ((OBUF)->bufp - (OBUF)->buf) <= (NEEDED)) \
288: ? grow_outbuf ((OBUF), (NEEDED)) : 0)
289:
290: struct directory_stack
291: {
292: struct directory_stack *next;
293: char *fname;
294: };
295:
296: /* #include "file" looks in source file dir, then stack. */
297: /* #include <file> just looks in the stack. */
298: /* -I directories are added to the end, then the defaults are added. */
299: struct directory_stack include_defaults[] =
300: {
301: #ifndef VMS
302: #ifdef CPLUSPLUS
303: /* Pick up GNU C++ specific include files. */
304: { &include_defaults[1], "/usr/local/lib/g++-include" },
305: /* Borrow AT&T C++ head files, if available. */
306: { &include_defaults[2], "/usr/include/CC" },
307: /* Use GNU CC specific header files. */
308: { &include_defaults[3], "/usr/local/lib/gcc-include" },
309: #else
310: { &include_defaults[1], "/usr/local/lib/gcc-include" },
311: #endif
312: { 0, "/usr/include" }
313: #else
314: { &include_defaults[1], "GNU_CC_INCLUDE:" }, /* GNU includes */
315: { &include_defaults[2], "SYS$SYSROOT:[SYSLIB.]" }, /* VAX-11 "C" includes */
316: { 0, "" }, /* This makes normal VMS filespecs work OK */
317: #endif /* VMS */
318: };
319:
320: struct directory_stack *include = 0; /* First dir to search */
321: /* First dir to search for <file> */
322: struct directory_stack *first_bracket_include = 0;
323: struct directory_stack *last_include = 0; /* Last in chain */
324:
325: /* Structure allocated for every #define. For a simple replacement
326: such as
327: #define foo bar ,
328: nargs = -1, the `pattern' list is null, and the expansion is just
329: the replacement text. Nargs = 0 means a functionlike macro with no args,
330: e.g.,
331: #define getchar() getc (stdin) .
332: When there are args, the expansion is the replacement text with the
333: args squashed out, and the reflist is a list describing how to
334: build the output from the input: e.g., "3 chars, then the 1st arg,
335: then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg".
336: The chars here come from the expansion. Whatever is left of the
337: expansion after the last arg-occurrence is copied after that arg.
338: Note that the reflist can be arbitrarily long---
339: its length depends on the number of times the arguments appear in
340: the replacement text, not how many args there are. Example:
341: #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and
342: pattern list
343: { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL }
344: where (x, y) means (nchars, argno). */
345:
346: typedef struct definition DEFINITION;
347: struct definition {
348: int nargs;
349: int length; /* length of expansion string */
350: U_CHAR *expansion;
351: struct reflist {
352: struct reflist *next;
353: char stringify; /* nonzero if this arg was preceded by a
354: # operator. */
355: char raw_before; /* Nonzero if a ## operator before arg. */
356: char raw_after; /* Nonzero if a ## operator after arg. */
357: int nchars; /* Number of literal chars to copy before
358: this arg occurrence. */
359: int argno; /* Number of arg to substitute (origin-0) */
360: } *pattern;
361: /* Names of macro args, concatenated in reverse order
362: with comma-space between them.
363: The only use of this is that we warn on redefinition
364: if this differs between the old and new definitions. */
365: U_CHAR *argnames;
366: };
367:
368: /* different kinds of things that can appear in the value field
369: of a hash node. Actually, this may be useless now. */
370: union hashval {
371: int ival;
372: char *cpval;
373: DEFINITION *defn;
374: };
375:
376:
377: /* The structure of a node in the hash table. The hash table
378: has entries for all tokens defined by #define commands (type T_MACRO),
379: plus some special tokens like __LINE__ (these each have their own
380: type, and the appropriate code is run when that type of node is seen.
381: It does not contain control words like "#define", which are recognized
382: by a separate piece of code. */
383:
384: /* different flavors of hash nodes --- also used in keyword table */
385: enum node_type {
386: T_DEFINE = 1, /* the `#define' keyword */
387: T_INCLUDE, /* the `#include' keyword */
388: T_IFDEF, /* the `#ifdef' keyword */
389: T_IFNDEF, /* the `#ifndef' keyword */
390: T_IF, /* the `#if' keyword */
391: T_ELSE, /* `#else' */
392: #if 0
393: /* cpp can pass #pragma through unchanged. */
394: T_PRAGMA, /* `#pragma' */
395: #endif
396: T_ELIF, /* `#else' */
397: T_UNDEF, /* `#undef' */
398: T_LINE, /* `#line' */
399: T_ERROR, /* `#error' */
400: T_ENDIF, /* `#endif' */
401: T_SCCS, /* `#sccs', used on system V. */
402: T_SPECLINE, /* special symbol `__LINE__' */
403: T_DATE, /* `__DATE__' */
404: T_FILE, /* `__FILE__' */
405: T_VERSION, /* `__VERSION__' */
406: T_TIME, /* `__TIME__' */
407: T_CONST, /* Constant value, used by `__STDC__' */
408: T_MACRO, /* macro defined by `#define' */
409: T_DISABLED, /* macro temporarily turned off for rescan */
410: T_SPEC_DEFINED, /* special `defined' macro for use in #if statements */
411: T_UNUSED /* Used for something not defined. */
412: };
413:
414: struct hashnode {
415: struct hashnode *next; /* double links for easy deletion */
416: struct hashnode *prev;
417: struct hashnode **bucket_hdr; /* also, a back pointer to this node's hash
418: chain is kept, in case the node is the head
419: of the chain and gets deleted. */
420: enum node_type type; /* type of special token */
421: int length; /* length of token, for quick comparison */
422: U_CHAR *name; /* the actual name */
423: union hashval value; /* pointer to expansion, or whatever */
424: };
425:
426: typedef struct hashnode HASHNODE;
427:
428: /* Some definitions for the hash table. The hash function MUST be
429: computed as shown in hashf () below. That is because the rescan
430: loop computes the hash value `on the fly' for most tokens,
431: in order to avoid the overhead of a lot of procedure calls to
432: the hashf () function. Hashf () only exists for the sake of
433: politeness, for use when speed isn't so important. */
434:
435: #define HASHSIZE 1403
436: HASHNODE *hashtab[HASHSIZE];
437: #define HASHSTEP(old, c) ((old << 2) + c)
438: #define MAKE_POS(v) (v & ~0x80000000) /* make number positive */
439:
440: /* Symbols to predefine. */
441:
442: #ifdef CPP_PREDEFINES
443: char *predefs = CPP_PREDEFINES;
444: #else
445: char *predefs = "";
446: #endif
447:
448: /* `struct directive' defines one #-directive, including how to handle it. */
449:
450: struct directive {
451: int length; /* Length of name */
452: int (*func)(); /* Function to handle directive */
453: char *name; /* Name of directive */
454: enum node_type type; /* Code which describes which directive. */
455: char angle_brackets; /* Nonzero => don't delete comments. */
456: };
457:
458: /* Here is the actual list of #-directives, most-often-used first. */
459:
460: struct directive directive_table[] = {
461: { 6, do_define, "define", T_DEFINE},
462: { 2, do_if, "if", T_IF},
463: { 5, do_xifdef, "ifdef", T_IFDEF},
464: { 6, do_xifdef, "ifndef", T_IFNDEF},
465: { 5, do_endif, "endif", T_ENDIF},
466: { 4, do_else, "else", T_ELSE},
467: { 4, do_elif, "elif", T_ELIF},
468: { 4, do_line, "line", T_LINE},
469: { 7, do_include, "include", T_INCLUDE, 1},
470: { 5, do_undef, "undef", T_UNDEF},
471: { 5, do_error, "error", T_ERROR},
472: #ifdef SCCS_DIRECTIVE
473: { 4, do_sccs, "sccs", T_SCCS},
474: #endif
475: #if 0
476: { 6, do_pragma, "pragma", T_PRAGMA},
477: #endif
478: { -1, 0, "", T_UNUSED},
479: };
480:
481: /* table to tell if char can be part of a C identifier. */
482: U_CHAR is_idchar[256];
483: /* table to tell if char can be first char of a c identifier. */
484: U_CHAR is_idstart[256];
485: /* table to tell if c is horizontal space. */
486: U_CHAR is_hor_space[256];
487: /* table to tell if c is horizontal or vertical space. */
488: U_CHAR is_space[256];
489:
490: #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0)
491: #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0)
492:
493: int errors = 0; /* Error counter for exit code */
494:
495: /* Nonzero if have already warned about use of `$'. */
496: int dollar_seen = 0;
497:
498: FILE_BUF expand_to_temp_buffer ();
499:
500: DEFINITION *collect_expansion ();
501:
502: /* Stack of conditionals currently in progress
503: (including both successful and failing conditionals). */
504:
505: struct if_stack {
506: struct if_stack *next; /* for chaining to the next stack frame */
507: char *fname; /* copied from input when frame is made */
508: int lineno; /* similarly */
509: int if_succeeded; /* true if a leg of this if-group
510: has been passed through rescan */
511: enum node_type type; /* type of last directive seen in this group */
512: };
513: typedef struct if_stack IF_STACK_FRAME;
514: IF_STACK_FRAME *if_stack = NULL;
515:
516: /* Buffer of -M output. */
517:
518: char *deps_buffer;
519:
520: /* Number of bytes allocated in above. */
521: int deps_allocated_size;
522:
523: /* Number of bytes used. */
524: int deps_size;
525:
526: /* Number of bytes since the last newline. */
527: int deps_column;
528:
529: /* Nonzero means -I- has been seen,
530: so don't look for #include "foo" the source-file directory. */
531: int ignore_srcdir;
532:
533: int
534: main (argc, argv)
535: int argc;
536: char **argv;
537: {
538: int st_mode;
539: long st_size;
540: char *in_fname, *out_fname;
541: int f, i;
542: FILE_BUF *fp;
543: char **pend_files = (char **) xmalloc (argc * sizeof (char *));
544: char **pend_defs = (char **) xmalloc (argc * sizeof (char *));
545: char **pend_undefs = (char **) xmalloc (argc * sizeof (char *));
546: int inhibit_predefs = 0;
547: int no_standard_includes = 0;
548:
549: #ifdef RLIMIT_STACK
550: /* Get rid of any avoidable limit on stack size. */
551: {
552: struct rlimit rlim;
553:
554: /* Set the stack limit huge so that alloca (particularly stringtab
555: * in dbxread.c) does not fail. */
556: getrlimit (RLIMIT_STACK, &rlim);
557: rlim.rlim_cur = rlim.rlim_max;
558: setrlimit (RLIMIT_STACK, &rlim);
559: }
560: #endif /* RLIMIT_STACK defined */
561:
562: progname = argv[0];
563: in_fname = NULL;
564: out_fname = NULL;
565: initialize_random_junk ();
566:
567: no_line_commands = 0;
568: no_trigraphs = 1;
569: dump_macros = 0;
570: no_output = 0;
571:
572: bzero (pend_files, argc * sizeof (char *));
573: bzero (pend_defs, argc * sizeof (char *));
574: bzero (pend_undefs, argc * sizeof (char *));
575:
576: /* Process switches and find input file name. */
577:
578: for (i = 1; i < argc; i++) {
579: if (argv[i][0] != '-') {
580: if (out_fname != NULL)
581: fatal ("Usage: %s [switches] input output\n", argv[0]);
582: else if (in_fname != NULL) {
583: out_fname = argv[i];
584: if (! freopen (out_fname, "w", stdout))
585: pfatal_with_name (out_fname);
586: } else
587: in_fname = argv[i];
588: } else {
589: switch (argv[i][1]) {
590:
591: case 'i':
592: if (argv[i][2] != 0)
593: pend_files[i] = argv[i] + 2;
594: else
595: pend_files[i] = argv[i+1], i++;
596: break;
597:
598: case 'o':
599: if (out_fname != NULL)
600: fatal ("Output filename specified twice\n");
601: out_fname = argv[++i];
602: if (! freopen (out_fname, "w", stdout))
603: pfatal_with_name (out_fname);
604: break;
605:
606: case 'p':
607: pedantic = 1;
608: break;
609:
610: case 't':
611: traditional = 1;
612: break;
613:
614: case 'W':
615: warn_comments = 1;
616: break;
617:
618: case 'M':
619: if (!strcmp (argv[i], "-M"))
620: print_deps = 2;
621: else if (!strcmp (argv[i], "-MM"))
622: print_deps = 1;
623: deps_allocated_size = 200;
624: deps_buffer = (char *) xmalloc (deps_allocated_size);
625: deps_buffer[0] = 0;
626: deps_size = 0;
627: deps_column = 0;
628:
629: break;
630:
631: case 'd':
632: dump_macros = 1;
633: no_output = 1;
634: break;
635:
636: case 'v':
637: {
638: fprintf (stderr, "GNU CPP version %s\n", version_string);
639: }
640: break;
641:
642: case 'D':
643: {
644: char *p, *p1;
645:
646: if (argv[i][2] != 0)
647: p = argv[i] + 2;
648: else
649: p = argv[++i];
650:
651: if ((p1 = (char *) index (p, '=')) != NULL)
652: *p1 = ' ';
653: pend_defs[i] = p;
654: }
655: break;
656:
657: case 'U': /* JF #undef something */
658: if (argv[i][2] != 0)
659: pend_undefs[i] = argv[i] + 2;
660: else
661: pend_undefs[i] = argv[i+1], i++;
662: break;
663:
664: case 'C':
665: put_out_comments = 1;
666: break;
667:
668: case 'E': /* -E comes from cc -E; ignore it. */
669: break;
670:
671: case 'P':
672: no_line_commands = 1;
673: break;
674:
675: case 'T': /* Enable ANSI trigraphs */
676: no_trigraphs = 0;
677: break;
678:
679: case 'I': /* Add directory to path for includes. */
680: {
681: struct directory_stack *dirtmp;
682:
683: if (! ignore_srcdir && !strcmp (argv[i] + 2, "-"))
684: ignore_srcdir;
685: else {
686: dirtmp = (struct directory_stack *)
687: xmalloc (sizeof (struct directory_stack));
688: dirtmp->next = 0; /* New one goes on the end */
689: if (include == 0)
690: include = dirtmp;
691: else
692: last_include->next = dirtmp;
693: last_include = dirtmp; /* Tail follows the last one */
694: if (argv[i][2] != 0)
695: dirtmp->fname = argv[i] + 2;
696: else
697: dirtmp->fname = argv[++i];
698: if (strlen (dirtmp->fname) > max_include_len)
699: max_include_len = strlen (dirtmp->fname);
700: if (ignore_srcdir && first_bracket_include == 0)
701: first_bracket_include = dirtmp;
702: }
703: }
704: break;
705:
706: case 'n':
707: /* -nostdinc causes no default include directories.
708: You must specify all include-file directories with -I. */
709: no_standard_includes = 1;
710: break;
711:
712: case 'u':
713: /* Sun compiler passes undocumented switch "-undef".
714: Let's assume it means to inhibit the predefined symbols. */
715: inhibit_predefs = 1;
716: break;
717:
718: case '\0': /* JF handle '-' as file name meaning stdin or stdout */
719: if (in_fname == NULL) {
720: in_fname = "";
721: break;
722: } else if (out_fname == NULL) {
723: out_fname = "stdout";
724: break;
725: } /* else fall through into error */
726:
727: default:
728: fatal ("Invalid option `%s'\n", argv[i]);
729: }
730: }
731: }
732:
733: /* Do standard #defines that identify processor type. */
734:
735: if (!inhibit_predefs) {
736: char *p = (char *) alloca (strlen (predefs) + 1);
737: strcpy (p, predefs);
738: while (*p) {
739: char *q;
740: if (p[0] != '-' || p[1] != 'D')
741: abort ();
742: q = &p[2];
743: while (*p && *p != ' ') p++;
744: if (*p != 0)
745: *p++= 0;
746: make_definition (q);
747: }
748: }
749:
750: /* Do defines specified with -D. */
751: for (i = 1; i < argc; i++)
752: if (pend_defs[i])
753: make_definition (pend_defs[i]);
754:
755: /* Do undefines specified with -U. */
756: for (i = 1; i < argc; i++)
757: if (pend_undefs[i])
758: make_undef (pend_undefs[i]);
759:
760: /* Unless -fnostdinc,
761: tack on the standard include file dirs to the specified list */
762: if (!no_standard_includes) {
763: if (include == 0)
764: include = include_defaults;
765: else
766: last_include->next = include_defaults;
767: }
768:
769: /* Initialize output buffer */
770:
771: outbuf.buf = (U_CHAR *) xmalloc (OUTBUF_SIZE);
772: outbuf.bufp = outbuf.buf;
773: outbuf.length = OUTBUF_SIZE;
774:
775: /* Scan the -i files before the main input.
776: Much like #including them, but with no_output set
777: so that only their macro definitions matter. */
778:
779: no_output++;
780: for (i = 1; i < argc; i++)
781: if (pend_files[i]) {
782: int fd = open (pend_files[i], O_RDONLY, 0666);
783: if (fd < 0) {
784: perror_with_name (pend_files[i]);
785: return FATAL_EXIT_CODE;
786: }
787: finclude (fd, pend_files[i], &outbuf);
788: }
789: no_output--;
790:
791: /* Create an input stack level for the main input file
792: and copy the entire contents of the file into it. */
793:
794: fp = &instack[++indepth];
795:
796: /* JF check for stdin */
797: if (in_fname == NULL || *in_fname == 0) {
798: in_fname = "";
799: f = 0;
800: } else if ((f = open (in_fname, O_RDONLY)) < 0)
801: goto perror;
802:
803: /* For -M, print the expected object file name
804: as the target of this Make-rule. */
805: if (print_deps) {
806: if (*in_fname == 0)
807: deps_output ("-: ", 0);
808: else {
809: int len;
810: char *p = in_fname;
811: char *p1 = p;
812: /* Discard all directory prefixes from P. */
813: while (*p1)
814: {
815: if (*p1 == '/')
816: p = p1;
817: p1++;
818: }
819: /* Output P, but remove known suffixes. */
820: len = strlen (p);
821: if (p[len - 2] == '.' && p[len - 1] == 'c')
822: deps_output (p, len - 2);
823: else if (p[len - 3] == '.'
824: && p[len - 2] == 'c'
825: && p[len - 1] == 'c')
826: deps_output (p, len - 3);
827: else
828: deps_output (p, 0);
829: /* Supply our own suffix. */
830: deps_output (".o : ", 0);
831: deps_output (in_fname, 0);
832: deps_output (" ", 0);
833: }
834: }
835:
836: file_size_and_mode (f, &st_mode, &st_size);
837: fp->fname = in_fname;
838: fp->lineno = 1;
839: /* JF all this is mine about reading pipes and ttys */
840: if ((st_mode & S_IFMT) != S_IFREG) {
841: /* Read input from a file that is not a normal disk file.
842: We cannot preallocate a buffer with the correct size,
843: so we must read in the file a piece at the time and make it bigger. */
844: int size;
845: int bsize;
846: int cnt;
847: U_CHAR *bufp;
848:
849: bsize = 2000;
850: size = 0;
851: fp->buf = (U_CHAR *) xmalloc (bsize + 2);
852: bufp = fp->buf;
853: for (;;) {
854: cnt = read (f, bufp, bsize - size);
855: if (cnt < 0) goto perror; /* error! */
856: if (cnt == 0) break; /* End of file */
857: size += cnt;
858: bufp += cnt;
859: if (bsize == size) { /* Buffer is full! */
860: bsize *= 2;
861: fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);
862: bufp = fp->buf + size; /* May have moved */
863: }
864: }
865: fp->length = size;
866: } else {
867: /* Read a file whose size we can determine in advance.
868: For the sake of VMS, st_size is just an upper bound. */
869: long i;
870: fp->length = 0;
871: fp->buf = (U_CHAR *) xmalloc (st_size + 2);
872:
873: while (st_size > 0) {
874: i = read (f, fp->buf + fp->length, st_size);
875: if (i <= 0) {
876: if (i == 0) break;
877: goto perror;
878: }
879: fp->length += i;
880: st_size -= i;
881: }
882: }
883: fp->bufp = fp->buf;
884: fp->if_stack = if_stack;
885:
886: /* Unless inhibited, convert trigraphs in the input. */
887:
888: if (!no_trigraphs)
889: trigraph_pcp (fp);
890:
891: /* Make sure data ends with a newline. And put a null after it. */
892:
893: if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
894: fp->buf[fp->length++] = '\n';
895: fp->buf[fp->length] = '\0';
896:
897: output_line_command (fp, &outbuf, 0);
898:
899: /* Scan the input, processing macros and directives. */
900:
901: rescan (&outbuf, 0);
902:
903: /* Now we have processed the entire input
904: Write whichever kind of output has been requested. */
905:
906:
907: if (dump_macros)
908: dump_all_macros ();
909: else if (print_deps)
910: puts (deps_buffer);
911: else if (write (fileno (stdout), outbuf.buf, outbuf.bufp - outbuf.buf) < 0)
912: fatal ("I/O error on output");
913:
914: if (ferror (stdout))
915: fatal ("I/O error on output");
916:
917: if (errors)
918: exit (FATAL_EXIT_CODE);
919: exit (SUCCESS_EXIT_CODE);
920:
921: perror:
922: pfatal_with_name (in_fname);
923: }
924:
925: /* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF
926: before main CCCP processing. Name `pcp' is also in honor of the
927: drugs the trigraph designers must have been on.
928:
929: Using an extra pass through the buffer takes a little extra time,
930: but is infinitely less hairy than trying to handle ??/" inside
931: strings, etc. everywhere, and also makes sure that trigraphs are
932: only translated in the top level of processing. */
933:
934: trigraph_pcp (buf)
935: FILE_BUF *buf;
936: {
937: register U_CHAR c, *fptr, *bptr, *sptr;
938: int len;
939:
940: fptr = bptr = sptr = buf->buf;
941: while ((sptr = (U_CHAR *) index (sptr, '?')) != NULL) {
942: if (*++sptr != '?')
943: continue;
944: switch (*++sptr) {
945: case '=':
946: c = '#';
947: break;
948: case '(':
949: c = '[';
950: break;
951: case '/':
952: c = '\\';
953: break;
954: case ')':
955: c = ']';
956: break;
957: case '\'':
958: c = '^';
959: break;
960: case '<':
961: c = '{';
962: break;
963: case '!':
964: c = '|';
965: break;
966: case '>':
967: c = '}';
968: break;
969: case '-':
970: c = '~';
971: break;
972: case '?':
973: sptr--;
974: continue;
975: default:
976: continue;
977: }
978: len = sptr - fptr - 2;
979: if (bptr != fptr && len > 0)
980: bcopy (fptr, bptr, len); /* BSD doc says bcopy () works right
981: for overlapping strings. In ANSI
982: C, this will be memmove (). */
983: bptr += len;
984: *bptr++ = c;
985: fptr = ++sptr;
986: }
987: len = buf->length - (fptr - buf->buf);
988: if (bptr != fptr && len > 0)
989: bcopy (fptr, bptr, len);
990: buf->length -= fptr - bptr;
991: buf->buf[buf->length] = '\0';
992: }
993:
994: /* Move all backslash-newline pairs out of embarrassing places.
995: Exchange all such pairs following BP
996: with any potentially-embarrasing characters that follow them.
997: Potentially-embarrassing characters are / and *
998: (because a backslash-newline inside a comment delimiter
999: would cause it not to be recognized). */
1000:
1001: newline_fix (bp)
1002: U_CHAR *bp;
1003: {
1004: register U_CHAR *p = bp;
1005: register int count = 0;
1006:
1007: /* First count the backslash-newline pairs here. */
1008:
1009: while (*p++ == '\\' && *p++ == '\n')
1010: count++;
1011:
1012: p = bp + count * 2;
1013:
1014: /* What follows the backslash-newlines is not embarrassing. */
1015:
1016: if (count == 0 || (*p != '/' && *p != '*'))
1017: return;
1018:
1019: /* Copy all potentially embarrassing characters
1020: that follow the backslash-newline pairs
1021: down to where the pairs originally started. */
1022:
1023: while (*p == '*' || *p == '/')
1024: *bp++ = *p++;
1025:
1026: /* Now write the same number of pairs after the embarrassing chars. */
1027: while (count-- > 0) {
1028: *bp++ = '\\';
1029: *bp++ = '\n';
1030: }
1031: }
1032:
1033: /* Like newline_fix but for use within a directive-name.
1034: Move any backslash-newlines up past any following symbol constituents. */
1035:
1036: name_newline_fix (bp)
1037: U_CHAR *bp;
1038: {
1039: register U_CHAR *p = bp;
1040: register int count = 0;
1041:
1042: /* First count the backslash-newline pairs here. */
1043:
1044: while (*p++ == '\\' && *p++ == '\n')
1045: count++;
1046:
1047: p = bp + count * 2;
1048:
1049: /* What follows the backslash-newlines is not embarrassing. */
1050:
1051: if (count == 0 || !is_idchar[*p])
1052: return;
1053:
1054: /* Copy all potentially embarrassing characters
1055: that follow the backslash-newline pairs
1056: down to where the pairs originally started. */
1057:
1058: while (is_idchar[*p])
1059: *bp++ = *p++;
1060:
1061: /* Now write the same number of pairs after the embarrassing chars. */
1062: while (count-- > 0) {
1063: *bp++ = '\\';
1064: *bp++ = '\n';
1065: }
1066: }
1067:
1068: /*
1069: * The main loop of the program.
1070: *
1071: * Read characters from the input stack, transferring them to the
1072: * output buffer OP.
1073: *
1074: * Macros are expanded and push levels on the input stack.
1075: * At the end of such a level it is popped off and we keep reading.
1076: * At the end of any other kind of level, we return.
1077: * #-directives are handled, except within macros.
1078: *
1079: * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input
1080: * and insert them when appropriate. This is set while scanning macro
1081: * arguments before substitution. It is zero when scanning for final output.
1082: * There are three types of Newline markers:
1083: * * Newline - follows a macro name that was not expanded
1084: * because it appeared inside an expansion of the same macro.
1085: * This marker prevents future expansion of that identifier.
1086: * When the input is rescanned into the final output, these are deleted.
1087: * These are also deleted by ## concatenation.
1088: * * Newline Space (or Newline and any other whitespace character)
1089: * stands for a place that tokens must be separated or whitespace
1090: * is otherwise desirable, but where the ANSI standard specifies there
1091: * is no whitespace. This marker turns into a Space (or whichever other
1092: * whitespace char appears in the marker) in the final output,
1093: * but it turns into nothing in an argument that is stringified with #.
1094: * Such stringified arguments are the only place where the ANSI standard
1095: * specifies with precision that whitespace may not appear.
1096: *
1097: * During this function, IP->bufp is kept cached in IBP for speed of access.
1098: * Likewise, OP->bufp is kept in OBP. Before calling a subroutine
1099: * IBP, IP and OBP must be copied back to memory. IP and IBP are
1100: * copied back with the RECACHE macro. OBP must be copied back from OP->bufp
1101: * explicitly, and before RECACHE, since RECACHE uses OBP.
1102: */
1103:
1104: rescan (op, output_marks)
1105: FILE_BUF *op;
1106: int output_marks;
1107: {
1108: /* Character being scanned in main loop. */
1109: register U_CHAR c;
1110:
1111: /* Length of pending accumulated identifier. */
1112: register int ident_length = 0;
1113:
1114: /* Hash code of pending accumulated identifier. */
1115: register int hash = 0;
1116:
1117: /* Current input level (&instack[indepth]). */
1118: FILE_BUF *ip;
1119:
1120: /* Pointer for scanning input. */
1121: register U_CHAR *ibp;
1122:
1123: /* Pointer to end of input. End of scan is controlled by LIMIT. */
1124: register U_CHAR *limit;
1125:
1126: /* Pointer for storing output. */
1127: register U_CHAR *obp;
1128:
1129: /* REDO_CHAR is nonzero if we are processing an identifier
1130: after backing up over the terminating character.
1131: Sometimes we process an identifier without backing up over
1132: the terminating character, if the terminating character
1133: is not special. Backing up is done so that the terminating character
1134: will be dispatched on again once the identifier is dealt with. */
1135: int redo_char = 0;
1136:
1137: /* 1 if within an identifier inside of which a concatenation
1138: marker (Newline -) has been seen. */
1139: int concatenated = 0;
1140:
1141: /* While scanning a comment or a string constant,
1142: this records the line it started on, for error messages. */
1143: int start_line;
1144:
1145: /* Record position of last `real' newline. */
1146: U_CHAR *beg_of_line;
1147:
1148: /* Pop the innermost input stack level, assuming it is a macro expansion. */
1149:
1150: #define POPMACRO \
1151: do { ip->macro->type = T_MACRO; \
1152: if (ip->free) free (ip->free); \
1153: --indepth; } while (0)
1154:
1155: /* Reload `rescan's local variables that describe the current
1156: level of the input stack. */
1157:
1158: #define RECACHE \
1159: do { ip = &instack[indepth]; \
1160: ibp = ip->bufp; \
1161: limit = ip->buf + ip->length; \
1162: op->bufp = obp; \
1163: check_expand (op, limit - ibp); \
1164: beg_of_line = 0; \
1165: obp = op->bufp; } while (0)
1166:
1167: if (no_output && instack[indepth].fname != 0)
1168: skip_if_group (&instack[indepth], 1);
1169:
1170: obp = op->bufp;
1171: RECACHE;
1172: beg_of_line = ibp;
1173:
1174: /* Our caller must always put a null after the end of
1175: the input at each input stack level. */
1176: if (*limit != 0)
1177: abort ();
1178:
1179: while (1) {
1180: c = *ibp++;
1181: *obp++ = c;
1182:
1183: switch (c) {
1184: case '\\':
1185: if (ibp >= limit)
1186: break;
1187: if (*ibp == '\n') {
1188: /* Always merge lines ending with backslash-newline,
1189: even in middle of identifier. */
1190: ++ibp;
1191: ++ip->lineno;
1192: --obp; /* remove backslash from obuf */
1193: break;
1194: }
1195: /* Otherwise, backslash suppresses specialness of following char,
1196: so copy it here to prevent the switch from seeing it.
1197: But first get any pending identifier processed. */
1198: if (ident_length > 0)
1199: goto specialchar;
1200: *obp++ = *ibp++;
1201: break;
1202:
1203: case '#':
1204: /* If this is expanding a macro definition, don't recognize
1205: preprocessor directives. */
1206: if (ip->macro != 0)
1207: goto randomchar;
1208: if (ident_length)
1209: goto specialchar;
1210:
1211: /* # keyword: a # must be first nonblank char on the line */
1212: if (beg_of_line == 0)
1213: goto randomchar;
1214: {
1215: U_CHAR *bp;
1216:
1217: /* Scan from start of line, skipping whitespace, comments
1218: and backslash-newlines, and see if we reach this #.
1219: If not, this # is not special. */
1220: bp = beg_of_line;
1221: while (1) {
1222: if (is_hor_space[*bp])
1223: bp++;
1224: else if (*bp == '\\' && bp[1] == '\n')
1225: bp += 2;
1226: else if (*bp == '/' && bp[1] == '*') {
1227: bp += 2;
1228: while (!(*bp == '*' && bp[1] == '/'))
1229: bp++;
1230: bp += 2;
1231: }
1232: #ifdef CPLUSPLUS
1233: else if (*bp == '/' && bp[1] == '/') {
1234: bp += 2;
1235: while (*bp++ != '\n') ;
1236: }
1237: #endif
1238: else break;
1239: }
1240: if (bp + 1 != ibp)
1241: goto randomchar;
1242: }
1243:
1244: /* This # can start a directive. */
1245:
1246: --obp; /* Don't copy the '#' */
1247:
1248: ip->bufp = ibp;
1249: op->bufp = obp;
1250: if (! handle_directive (ip, op)) {
1251: /* Not a known directive: treat it as ordinary text.
1252: IP, OP, IBP, etc. have not been changed. */
1253: if (no_output && instack[indepth].fname) {
1254: /* If not generating expanded output,
1255: what we do with ordinary text is skip it.
1256: Discard everything until next # directive. */
1257: skip_if_group (&instack[indepth], 1);
1258: RECACHE;
1259: beg_of_line = ibp;
1260: break;
1261: }
1262: ++obp; /* Copy the '#' after all */
1263: goto randomchar;
1264: }
1265: /* A # directive has been successfully processed. */
1266: /* If not generating expanded output, ignore everything until
1267: next # directive. */
1268: if (no_output && instack[indepth].fname)
1269: skip_if_group (&instack[indepth], 1);
1270: obp = op->bufp;
1271: RECACHE;
1272: beg_of_line = ibp;
1273: break;
1274:
1275: case '\"': /* skip quoted string */
1276: case '\'':
1277: /* A single quoted string is treated like a double -- some
1278: programs (e.g., troff) are perverse this way */
1279:
1280: if (ident_length)
1281: goto specialchar;
1282:
1283: start_line = ip->lineno;
1284:
1285: /* Skip ahead to a matching quote. */
1286:
1287: while (1) {
1288: if (ibp >= limit)
1289: {
1290: error_with_line (line_for_error (start_line),
1291: "unterminated string constant");
1292: break;
1293: }
1294: *obp++ = *ibp;
1295: switch (*ibp++) {
1296: case '\n':
1297: ++ip->lineno;
1298: ++op->lineno;
1299: break;
1300:
1301: case '\\':
1302: if (ibp >= limit)
1303: break;
1304: if (*ibp == '\n')
1305: {
1306: /* Backslash newline is replaced by nothing at all,
1307: but keep the line counts correct. */
1308: --obp;
1309: ++ibp;
1310: ++ip->lineno;
1311: }
1312: else {
1313: /* ANSI stupidly requires that in \\ the second \
1314: is *not* prevented from combining with a newline. */
1315: while (*ibp == '\\' && ibp[1] == '\n') {
1316: ibp += 2;
1317: ++ip->lineno;
1318: }
1319: *obp++ = *ibp++;
1320: }
1321: break;
1322:
1323: case '\"':
1324: case '\'':
1325: if (ibp[-1] == c)
1326: goto while2end;
1327: break;
1328: }
1329: }
1330: while2end:
1331: break;
1332:
1333: case '/':
1334: if (*ibp == '\\' && ibp[1] == '\n')
1335: newline_fix (ibp);
1336: #ifdef CPLUSPLUS
1337: if (*ibp == '/')
1338: {
1339: /* C++ style comment... */
1340: start_line = ip->lineno;
1341:
1342: --ibp; /* Back over the slash */
1343: --obp;
1344:
1345: /* Comments are equivalent to spaces. */
1346: if (! put_out_comments)
1347: *obp++ = ' ';
1348: else {
1349: /* must fake up a comment here */
1350: *obp++ = '/';
1351: *obp++ = '/';
1352: }
1353: {
1354: U_CHAR *before_bp = ibp+2;
1355:
1356: while (ibp < limit) {
1357: if (*ibp++ == '\n') {
1358: ibp--;
1359: if (put_out_comments) {
1360: bcopy (before_bp, obp, ibp - before_bp);
1361: obp += ibp - before_bp;
1362: }
1363: break;
1364: }
1365: }
1366: break;
1367: }
1368: }
1369: #endif
1370: if (*ibp != '*')
1371: goto randomchar;
1372: if (ip->macro != 0)
1373: goto randomchar;
1374: if (ident_length)
1375: goto specialchar;
1376:
1377: /* We have a comment. Skip it, optionally copying it to output. */
1378:
1379: start_line = ip->lineno;
1380:
1381: ++ibp; /* Skip the star. */
1382:
1383: /* Comments are equivalent to spaces.
1384: Note that we already output the slash; we might not want it.
1385: For -traditional, a comment is equivalent to nothing. */
1386: if (! put_out_comments)
1387: {
1388: if (traditional)
1389: obp--;
1390: else
1391: obp[-1] = ' ';
1392: }
1393: else
1394: *obp++ = '*';
1395:
1396: {
1397: U_CHAR *before_bp = ibp;
1398:
1399: while (ibp < limit) {
1400: switch (*ibp++) {
1401: case '/':
1402: if (warn_comments && ibp < limit && *ibp == '*')
1403: warning("`/*' within comment");
1404: break;
1405: case '*':
1406: if (*ibp == '\\' && ibp[1] == '\n')
1407: newline_fix (ibp);
1408: if (ibp >= limit || *ibp == '/')
1409: goto comment_end;
1410: break;
1411: case '\n':
1412: ++ip->lineno;
1413: /* Copy the newline into the output buffer, in order to
1414: avoid the pain of a #line every time a multiline comment
1415: is seen. */
1416: if (!put_out_comments)
1417: *obp++ = '\n';
1418: ++op->lineno;
1419: }
1420: }
1421: comment_end:
1422:
1423: if (ibp >= limit)
1424: error_with_line (line_for_error (start_line),
1425: "unterminated comment");
1426: else {
1427: ibp++;
1428: if (put_out_comments) {
1429: bcopy (before_bp, obp, ibp - before_bp);
1430: obp += ibp - before_bp;
1431: }
1432: }
1433: }
1434: break;
1435:
1436: case '$':
1437: if (pedantic)
1438: {
1439: if (! dollar_seen)
1440: warning ("ANSI C forbids `$' in identifier (first use here)");
1441: dollar_seen = 1;
1442: }
1443: goto letter;
1444:
1445: case '0': case '1': case '2': case '3': case '4':
1446: case '5': case '6': case '7': case '8': case '9':
1447: /* If digit is not part of identifier, it starts a number,
1448: which means that following letters are not an identifier.
1449: "0x5" does not refer to an identifier "x5".
1450: So copy all alphanumerics that follow without accumulating
1451: as an identifier. Periods also, for sake of "3.e7". */
1452:
1453: if (ident_length == 0) {
1454: while (ibp < limit) {
1455: c = *ibp++;
1456: if (!isalnum (c) && c != '.') {
1457: --ibp;
1458: break;
1459: }
1460: *obp++ = c;
1461: }
1462: break;
1463: }
1464: /* fall through */
1465:
1466: case '_':
1467: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1468: case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1469: case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
1470: case 's': case 't': case 'u': case 'v': case 'w': case 'x':
1471: case 'y': case 'z':
1472: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1473: case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
1474: case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
1475: case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
1476: case 'Y': case 'Z':
1477: letter:
1478: ident_length++;
1479: /* Compute step of hash function, to avoid a proc call on every token */
1480: hash = HASHSTEP (hash, c);
1481: break;
1482:
1483: case '\n':
1484: /* If reprocessing a macro expansion, newline is a special marker. */
1485: if (ip->macro != 0) {
1486: /* Newline White is a "funny space" to separate tokens that are
1487: supposed to be separate but without space between.
1488: Here While means any horizontal whitespace character.
1489: Newline - marks a recursive macro use that is not
1490: supposed to be expandable. */
1491:
1492: if (*ibp == '-') {
1493: /* Newline - inhibits expansion of preceding token.
1494: If expanding a macro arg, we keep the newline -.
1495: In final output, it is deleted. */
1496: if (! concatenated) {
1497: ident_length = 0;
1498: hash = 0;
1499: }
1500: ibp++;
1501: if (!output_marks) {
1502: obp--;
1503: } else {
1504: /* If expanding a macro arg, keep the newline -. */
1505: *obp++ = '-';
1506: }
1507: } else if (is_space[*ibp]) {
1508: /* Newline Space does not prevent expansion of preceding token
1509: so expand the preceding token and then come back. */
1510: if (ident_length > 0)
1511: goto specialchar;
1512:
1513: /* If generating final output, newline space makes a space. */
1514: if (!output_marks) {
1515: obp[-1] = *ibp++;
1516: /* And Newline Newline makes a newline, so count it. */
1517: if (obp[-1] == '\n')
1518: op->lineno++;
1519: } else {
1520: /* If expanding a macro arg, keep the newline space.
1521: If the arg gets stringified, newline space makes nothing. */
1522: *obp++ = *ibp++;
1523: }
1524: } else abort (); /* Newline followed by something random? */
1525: break;
1526: }
1527:
1528: /* If there is a pending identifier, handle it and come back here. */
1529: if (ident_length > 0)
1530: goto specialchar;
1531:
1532: beg_of_line = ibp;
1533:
1534: /* Update the line counts and output a #line if necessary. */
1535: ++ip->lineno;
1536: ++op->lineno;
1537: if (ip->lineno != op->lineno) {
1538: op->bufp = obp;
1539: output_line_command (ip, op, 1);
1540: check_expand (op, ip->length - (ip->bufp - ip->buf));
1541: obp = op->bufp;
1542: }
1543: break;
1544:
1545: /* Come here either after (1) a null character that is part of the input
1546: or (2) at the end of the input, because there is a null there. */
1547: case 0:
1548: if (ibp <= limit)
1549: /* Our input really contains a null character. */
1550: goto randomchar;
1551:
1552: /* At end of a macro-expansion level, pop it and read next level. */
1553: if (ip->macro != 0) {
1554: obp--;
1555: ibp--;
1556: POPMACRO;
1557: RECACHE;
1558: break;
1559: }
1560:
1561: /* If we don't have a pending identifier,
1562: return at end of input. */
1563: if (ident_length == 0)
1564: {
1565: obp--;
1566: ibp--;
1567: op->bufp = obp;
1568: ip->bufp = ibp;
1569: goto ending;
1570: }
1571:
1572: /* If we do have a pending identifier, just consider this null
1573: a special character and arrange to dispatch on it again.
1574: The second time, IDENT_LENGTH will be zero so we will return. */
1575:
1576: /* Fall through */
1577:
1578: specialchar:
1579:
1580: /* Handle the case of a character such as /, ', " or null
1581: seen following an identifier. Back over it so that
1582: after the identifier is processed the special char
1583: will be dispatched on again. */
1584:
1585: ibp--;
1586: obp--;
1587: redo_char = 1;
1588:
1589: default:
1590:
1591: randomchar:
1592:
1593: if (ident_length > 0) {
1594: register HASHNODE *hp;
1595:
1596: /* We have just seen an identifier end. If it's a macro, expand it.
1597:
1598: IDENT_LENGTH is the length of the identifier
1599: and HASH is its hash code.
1600:
1601: The identifier has already been copied to the output,
1602: so if it is a macro we must remove it.
1603:
1604: If REDO_CHAR is 0, the char that terminated the identifier
1605: has been skipped in the output and the input.
1606: OBP-IDENT_LENGTH-1 points to the identifier.
1607: If the identifier is a macro, we must back over the terminator.
1608:
1609: If REDO_CHAR is 1, the terminating char has already been
1610: backed over. OBP-IDENT_LENGTH points to the identifier. */
1611:
1612: for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;
1613: hp = hp->next) {
1614:
1615: if (hp->length == ident_length) {
1616: U_CHAR *obufp_before_macroname;
1617: int op_lineno_before_macroname;
1618: register int i = ident_length;
1619: register U_CHAR *p = hp->name;
1620: register U_CHAR *q = obp - i;
1621: int disabled;
1622:
1623: if (! redo_char)
1624: q--;
1625:
1626: do { /* All this to avoid a strncmp () */
1627: if (*p++ != *q++)
1628: goto hashcollision;
1629: } while (--i);
1630:
1631: /* We found a use of a macro name.
1632: see if the context shows it is a macro call. */
1633:
1634: /* Back up over terminating character if not already done. */
1635: if (! redo_char)
1636: {
1637: ibp--;
1638: obp--;
1639: }
1640:
1641: obufp_before_macroname = obp - ident_length;
1642: op_lineno_before_macroname = op->lineno;
1643:
1644: /* Record whether the macro is disabled. */
1645: disabled = hp->type == T_DISABLED;
1646:
1647: /* This looks like a macro ref, but if the macro was disabled,
1648: just copy its name and put in a marker if requested. */
1649:
1650: if (disabled)
1651: {
1652: if (output_marks) {
1653: check_expand (op, limit - ibp + 2);
1654: *obp++ = '\n';
1655: *obp++ = '-';
1656: }
1657: break;
1658: }
1659:
1660: /* If macro wants an arglist, verify that a '(' follows.
1661: first skip all whitespace, copying it to the output
1662: after the macro name. Then, if there is no '(',
1663: decide this is not a macro call and leave things that way. */
1664: if ((hp->type == T_MACRO || hp->type == T_DISABLED)
1665: && hp->value.defn->nargs >= 0)
1666: {
1667: while (1) {
1668: /* Scan forward over whitespace, copying it to the output. */
1669: if (ibp == limit && ip->macro != 0) {
1670: POPMACRO;
1671: RECACHE;
1672: }
1673: else if (is_space[*ibp]) {
1674: *obp++ = *ibp++;
1675: if (ibp[-1] == '\n')
1676: {
1677: if (ip->macro == 0) {
1678: /* Newline in a file. Count it. */
1679: ++ip->lineno;
1680: ++op->lineno;
1681: } else if (!output_marks) {
1682: /* A newline mark, and we don't want marks
1683: in the output. If it is newline-hyphen,
1684: discard it entirely. Otherwise, it is
1685: newline-whitechar, so keep the whitechar. */
1686: obp--;
1687: if (*ibp == '-')
1688: ibp++;
1689: else {
1690: if (*ibp == '\n')
1691: ++op->lineno;
1692: *obp++ = *ibp++;
1693: }
1694: } else {
1695: /* A newline mark; copy both chars to the output. */
1696: *obp++ = *ibp++;
1697: }
1698: }
1699: }
1700: else break;
1701: }
1702: if (*ibp != '(')
1703: break;
1704: }
1705:
1706: /* This is now known to be a macro call.
1707: Discard the macro name from the output,
1708: along with any following whitespace just copied. */
1709: obp = obufp_before_macroname;
1710: op->lineno = op_lineno_before_macroname;
1711:
1712: /* Expand the macro, reading arguments as needed,
1713: and push the expansion on the input stack. */
1714: ip->bufp = ibp;
1715: op->bufp = obp;
1716: macroexpand (hp, op);
1717:
1718: /* Reexamine input stack, since macroexpand has pushed
1719: a new level on it. */
1720: obp = op->bufp;
1721: RECACHE;
1722: break;
1723: }
1724: hashcollision:
1725: ;
1726: } /* End hash-table-search loop */
1727: ident_length = hash = 0; /* Stop collecting identifier */
1728: redo_char = 0;
1729: concatenated = 0;
1730: } /* End if (ident_length > 0) */
1731: } /* End switch */
1732: } /* End per-char loop */
1733:
1734: /* Come here to return -- but first give an error message
1735: if there was an unterminated successful conditional. */
1736: ending:
1737: if (if_stack != ip->if_stack) {
1738: char *str;
1739: switch (if_stack->type) {
1740: case T_IF:
1741: str = "if";
1742: break;
1743: case T_IFDEF:
1744: str = "ifdef";
1745: break;
1746: case T_IFNDEF:
1747: str = "ifndef";
1748: break;
1749: case T_ELSE:
1750: str = "else";
1751: break;
1752: case T_ELIF:
1753: str = "elif";
1754: break;
1755: }
1756: error_with_line (line_for_error (if_stack->lineno),
1757: "unterminated #%s conditional", str);
1758: }
1759: if_stack = ip->if_stack;
1760: }
1761:
1762: /*
1763: * Rescan a string into a temporary buffer and return the result
1764: * as a FILE_BUF. Note this function returns a struct, not a pointer.
1765: *
1766: * OUTPUT_MARKS nonzero means keep Newline markers found in the input
1767: * and insert such markers when appropriate. See `rescan' for details.
1768: * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately
1769: * before substitution; it is 0 for other uses.
1770: */
1771: static FILE_BUF
1772: expand_to_temp_buffer (buf, limit, output_marks)
1773: U_CHAR *buf, *limit;
1774: int output_marks;
1775: {
1776: register FILE_BUF *ip;
1777: FILE_BUF obuf;
1778: int length = limit - buf;
1779: U_CHAR *buf1;
1780: int odepth = indepth;
1781:
1782: if (length < 0)
1783: abort ();
1784:
1785: /* Set up the input on the input stack. */
1786:
1787: buf1 = (U_CHAR *) alloca (length + 1);
1788: {
1789: register U_CHAR *p1 = buf;
1790: register U_CHAR *p2 = buf1;
1791:
1792: while (p1 != limit)
1793: *p2++ = *p1++;
1794: }
1795: buf1[length] = 0;
1796:
1797: ++indepth;
1798:
1799: ip = &instack[indepth];
1800: ip->fname = 0;
1801: ip->macro = 0;
1802: ip->free = 0;
1803: ip->length = length;
1804: ip->buf = ip->bufp = buf1;
1805: ip->if_stack = if_stack;
1806:
1807: /* Set up to receive the output. */
1808:
1809: obuf.length = length * 2 + 100; /* Usually enough. Why be stingy? */
1810: obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);
1811: obuf.fname = 0;
1812: obuf.macro = 0;
1813: obuf.free = 0;
1814:
1815: ip->lineno = obuf.lineno = 1;
1816:
1817: /* Scan the input, create the output. */
1818:
1819: rescan (&obuf, output_marks);
1820:
1821: /* Pop input stack to original state. */
1822: --indepth;
1823:
1824: if (indepth != odepth)
1825: abort ();
1826:
1827: /* Record the output. */
1828: obuf.length = obuf.bufp - obuf.buf;
1829:
1830: return obuf;
1831: }
1832:
1833: /*
1834: * Process a # directive. Expects IP->bufp to point to the '#', as in
1835: * `#define foo bar'. Passes to the command handler
1836: * (do_define, do_include, etc.): the addresses of the 1st and
1837: * last chars of the command (starting immediately after the #
1838: * keyword), plus op and the keyword table pointer. If the command
1839: * contains comments it is copied into a temporary buffer sans comments
1840: * and the temporary buffer is passed to the command handler instead.
1841: * Likewise for backslash-newlines.
1842: *
1843: * Returns nonzero if this was a known # directive.
1844: * Otherwise, returns zero, without advancing the input pointer.
1845: */
1846:
1847: int
1848: handle_directive (ip, op)
1849: FILE_BUF *ip, *op;
1850: {
1851: register U_CHAR *bp, *cp;
1852: register struct directive *kt;
1853: register int ident_length;
1854: U_CHAR *resume_p;
1855:
1856: /* Nonzero means we must copy the entire command
1857: to get rid of comments or backslash-newlines. */
1858: int copy_command = 0;
1859:
1860: U_CHAR *ident, *after_ident;
1861:
1862: bp = ip->bufp;
1863: /* Skip whitespace and \-newline. */
1864: while (1) {
1865: if (is_hor_space[*bp])
1866: bp++;
1867: else if (*bp == '\\' && bp[1] == '\n') {
1868: bp += 2; ip->lineno++;
1869: } else break;
1870: }
1871:
1872: /* Now find end of directive name.
1873: If we encounter a backslash-newline, exchange it with any following
1874: symbol-constituents so that we end up with a contiguous name. */
1875:
1876: cp = bp;
1877: while (1) {
1878: if (is_idchar[*cp])
1879: cp++;
1880: else {
1881: if (*cp == '\\' && cp[1] == '\n')
1882: name_newline_fix (cp);
1883: if (is_idchar[*cp])
1884: cp++;
1885: else break;
1886: }
1887: }
1888: ident_length = cp - bp;
1889: ident = bp;
1890: after_ident = cp;
1891:
1892: /*
1893: * Decode the keyword and call the appropriate expansion
1894: * routine, after moving the input pointer up to the next line.
1895: */
1896: for (kt = directive_table; kt->length > 0; kt++) {
1897: if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) {
1898: register U_CHAR *buf;
1899: register U_CHAR *limit = ip->buf + ip->length;
1900: int unterminated = 0;
1901:
1902: /* Find the end of this command (first newline not backslashed
1903: and not in a string or comment).
1904: Set COPY_COMMAND if the command must be copied
1905: (it contains a backslash-newline or a comment). */
1906:
1907: buf = bp = after_ident;
1908: while (bp < limit) {
1909: register U_CHAR c = *bp++;
1910: switch (c) {
1911: case '\\':
1912: if (bp < limit) {
1913: if (*bp == '\n')
1914: {
1915: ip->lineno++;
1916: copy_command = 1;
1917: }
1918: bp++;
1919: }
1920: break;
1921:
1922: case '\'':
1923: case '\"':
1924: bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, ©_command, &unterminated);
1925: /* Don't bother calling the directive if we already got an error
1926: message due to unterminated string. Skip everything and pretend
1927: we called the directive. */
1928: if (unterminated) {
1929: ip->bufp = bp;
1930: return 1;
1931: }
1932: break;
1933:
1934: /* <...> is special for #include. */
1935: case '<':
1936: if (!kt->angle_brackets)
1937: break;
1938: while (*bp && *bp != '>') bp++;
1939: break;
1940:
1941: case '/':
1942: if (*bp == '\\' && bp[1] == '\n')
1943: newline_fix (bp);
1944: if (*bp == '*'
1945: #ifdef CPLUSPLUS
1946: || *bp == '/'
1947: #endif
1948: ) {
1949: U_CHAR *obp = bp - 1;
1950: ip->bufp = bp + 1;
1951: skip_to_end_of_comment (ip, &ip->lineno);
1952: bp = ip->bufp;
1953: /* No need to copy the command because of a comment at the end;
1954: just don't include the comment in the directive. */
1955: if (bp == limit || *bp == '\n') {
1956: bp = obp;
1957: goto endloop1;
1958: }
1959: copy_command++;
1960: }
1961: break;
1962:
1963: case '\n':
1964: --bp; /* Point to the newline */
1965: ip->bufp = bp;
1966: goto endloop1;
1967: }
1968: }
1969: ip->bufp = bp;
1970:
1971: endloop1:
1972: resume_p = ip->bufp;
1973: /* BP is the end of the directive.
1974: RESUME_P is the next interesting data after the directive.
1975: A comment may come between. */
1976:
1977: if (copy_command) {
1978: register U_CHAR *xp = buf;
1979: /* Need to copy entire command into temp buffer before dispatching */
1980:
1981: cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus
1982: some slop */
1983: buf = cp;
1984:
1985: /* Copy to the new buffer, deleting comments
1986: and backslash-newlines (and whitespace surrounding the latter). */
1987:
1988: while (xp < bp) {
1989: register U_CHAR c = *xp++;
1990: *cp++ = c;
1991:
1992: switch (c) {
1993: case '\n':
1994: break;
1995:
1996: /* <...> is special for #include. */
1997: case '<':
1998: if (!kt->angle_brackets)
1999: break;
2000: while (*bp && *bp != '>') bp++;
2001: break;
2002:
2003: case '\\':
2004: if (*xp == '\n') {
2005: xp++;
2006: cp--;
2007: if (cp != buf && is_space[cp[-1]]) {
2008: while (cp != buf && is_space[cp[-1]]) cp--;
2009: cp++;
2010: SKIP_WHITE_SPACE (xp);
2011: } else if (is_space[*xp]) {
2012: *cp++ = *xp++;
2013: SKIP_WHITE_SPACE (xp);
2014: }
2015: }
2016: break;
2017:
2018: case '\'':
2019: case '\"':
2020: {
2021: register U_CHAR *bp1
2022: = skip_quoted_string (xp - 1, limit, ip->lineno, 0, 0, 0);
2023: while (xp != bp1)
2024: *cp++ = *xp++;
2025: }
2026: break;
2027:
2028: case '/':
2029: if (*xp == '*'
2030: #ifdef CPLUSPLUS
2031: || *xp == '/'
2032: #endif
2033: ) {
2034: if (traditional)
2035: cp--;
2036: else
2037: cp[-1] = ' ';
2038: ip->bufp = xp + 1;
2039: skip_to_end_of_comment (ip, 0);
2040: xp = ip->bufp;
2041: }
2042: }
2043: }
2044:
2045: /* Null-terminate the copy. */
2046:
2047: *cp = 0;
2048: }
2049: else
2050: cp = bp;
2051:
2052: ip->bufp = resume_p;
2053:
2054: /* Call the appropriate command handler. buf now points to
2055: either the appropriate place in the input buffer, or to
2056: the temp buffer if it was necessary to make one. cp
2057: points to the first char after the contents of the (possibly
2058: copied) command, in either case. */
2059: (*kt->func) (buf, cp, op, kt);
2060: check_expand (op, ip->length - (ip->bufp - ip->buf));
2061:
2062: return 1;
2063: }
2064: }
2065:
2066: return 0;
2067: }
2068:
2069: static char *monthnames[] = {"jan", "feb", "mar", "apr", "may", "jun",
2070: "jul", "aug", "sep", "oct", "nov", "dec",
2071: };
2072:
2073: /*
2074: * expand things like __FILE__. Place the expansion into the output
2075: * buffer *without* rescanning.
2076: */
2077: special_symbol (hp, op)
2078: HASHNODE *hp;
2079: FILE_BUF *op;
2080: {
2081: char *buf;
2082: int i, len;
2083: FILE_BUF *ip = NULL;
2084: static struct tm *timebuf = NULL;
2085: struct tm *localtime ();
2086:
2087: int paren = 0; /* For special `defined' keyword */
2088:
2089: for (i = indepth; i >= 0; i--)
2090: if (instack[i].fname != NULL) {
2091: ip = &instack[i];
2092: break;
2093: }
2094: if (ip == NULL) {
2095: error ("cccp error: not in any file?!");
2096: return; /* the show must go on */
2097: }
2098:
2099: switch (hp->type) {
2100: case T_FILE:
2101: buf = (char *) alloca (3 + strlen (ip->fname));
2102: sprintf (buf, "\"%s\"", ip->fname);
2103: break;
2104:
2105: case T_VERSION:
2106: buf = (char *) alloca (3 + strlen (version_string));
2107: sprintf (buf, "\"%s\"", version_string);
2108: break;
2109:
2110: case T_CONST:
2111: buf = (char *) alloca (4 * sizeof (int));
2112: sprintf (buf, "%d", hp->value.ival);
2113: break;
2114:
2115: case T_SPECLINE:
2116: buf = (char *) alloca (10);
2117: sprintf (buf, "%d", ip->lineno);
2118: break;
2119:
2120: case T_DATE:
2121: case T_TIME:
2122: if (timebuf == NULL) {
2123: i = time (0);
2124: timebuf = localtime (&i);
2125: }
2126: buf = (char *) alloca (20);
2127: if (hp->type == T_DATE)
2128: sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon],
2129: timebuf->tm_mday, timebuf->tm_year + 1900);
2130: else
2131: sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min,
2132: timebuf->tm_sec);
2133: break;
2134:
2135: case T_SPEC_DEFINED:
2136: buf = " 0 "; /* Assume symbol is not defined */
2137: ip = &instack[indepth];
2138: SKIP_WHITE_SPACE (ip->bufp);
2139: if (*ip->bufp == '(') {
2140: paren++;
2141: ip->bufp++; /* Skip over the paren */
2142: SKIP_WHITE_SPACE (ip->bufp);
2143: }
2144:
2145: if (!is_idstart[*ip->bufp])
2146: goto oops;
2147: if (lookup (ip->bufp, -1, -1))
2148: buf = " 1 ";
2149: while (is_idchar[*ip->bufp])
2150: ++ip->bufp;
2151: SKIP_WHITE_SPACE (ip->bufp);
2152: if (paren) {
2153: if (*ip->bufp != ')')
2154: goto oops;
2155: ++ip->bufp;
2156: }
2157: break;
2158:
2159: oops:
2160:
2161: error ("`defined' must be followed by ident or (ident)");
2162: break;
2163:
2164: default:
2165: error ("cccp error: invalid special hash type"); /* time for gdb */
2166: abort ();
2167: }
2168: len = strlen (buf);
2169: check_expand (op, len);
2170: bcopy (buf, op->bufp, len);
2171: op->bufp += len;
2172:
2173: return;
2174: }
2175:
2176:
2177: /* Routines to handle #directives */
2178:
2179: /*
2180: * Process include file by reading it in and calling rescan.
2181: * Expects to see "fname" or <fname> on the input.
2182: */
2183:
2184: do_include (buf, limit, op, keyword)
2185: U_CHAR *buf, *limit;
2186: FILE_BUF *op;
2187: struct directive *keyword;
2188: {
2189: char *fname; /* Dynamically allocated fname buffer */
2190: U_CHAR *fbeg, *fend; /* Beginning and end of fname */
2191:
2192: struct directory_stack *stackp = include; /* Chain of dirs to search */
2193: struct directory_stack dsp[1]; /* First in chain, if #include "..." */
2194: int flen;
2195:
2196: int f; /* file number */
2197:
2198: int retried = 0; /* Have already tried macro
2199: expanding the include line*/
2200: FILE_BUF trybuf; /* It got expanded into here */
2201: int system_header_p = 0; /* 0 for "...", 1 for <...> */
2202:
2203: f= -1; /* JF we iz paranoid! */
2204:
2205: get_filename:
2206:
2207: fbeg = buf;
2208: SKIP_WHITE_SPACE (fbeg);
2209: /* Discard trailing whitespace so we can easily see
2210: if we have parsed all the significant chars we were given. */
2211: while (limit != fbeg && is_hor_space[limit[-1]]) limit--;
2212:
2213: switch (*fbeg++) {
2214: case '\"':
2215: fend = fbeg;
2216: while (fend != limit && *fend != '\"')
2217: fend++;
2218: if (*fend == '\"' && fend + 1 == limit) {
2219: FILE_BUF *fp;
2220:
2221: /* We have "filename". Figure out directory this source
2222: file is coming from and put it on the front of the list. */
2223:
2224: /* If -I- was specified, don't search current dir, only spec'd ones. */
2225: if (ignore_srcdir) break;
2226:
2227: for (fp = &instack[indepth]; fp >= instack; fp--)
2228: {
2229: int n;
2230: char *ep,*nam;
2231: extern char *rindex ();
2232:
2233: if ((nam = fp->fname) != NULL)
2234: {
2235: /* Found a named file. Figure out dir of the file,
2236: and put it in front of the search list. */
2237: dsp[0].next = stackp;
2238: stackp = dsp;
2239: #ifndef VMS
2240: ep = rindex (nam, '/');
2241: #else /* VMS */
2242: ep = rindex (nam, ']');
2243: if (ep == NULL) ep = rindex (nam, '>');
2244: if (ep == NULL) ep = rindex (nam, ':');
2245: if (ep != NULL) ep++;
2246: #endif /* VMS */
2247: if (ep != NULL) {
2248: n = ep - nam;
2249: dsp[0].fname = (char *) alloca (n + 1);
2250: strncpy (dsp[0].fname, nam, n);
2251: dsp[0].fname[n] = '\0';
2252: if (n > max_include_len) max_include_len = n;
2253: } else {
2254: dsp[0].fname = 0; /* Current directory */
2255: }
2256: break;
2257: }
2258: }
2259: break;
2260: }
2261: goto fail;
2262:
2263: case '<':
2264: fend = fbeg;
2265: while (fend != limit && *fend != '>') fend++;
2266: if (*fend == '>' && fend + 1 == limit) {
2267: system_header_p = 1;
2268: /* If -I-, start with the first -I dir after the -I-. */
2269: if (first_bracket_include)
2270: stackp = first_bracket_include;
2271: break;
2272: }
2273: goto fail;
2274:
2275: default:
2276: fail:
2277: if (retried) {
2278: error ("#include expects \"fname\" or <fname>");
2279: return;
2280: } else {
2281: trybuf = expand_to_temp_buffer (buf, limit, 0);
2282: buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
2283: bcopy (trybuf.buf, buf, trybuf.bufp - trybuf.buf);
2284: limit = buf + (trybuf.bufp - trybuf.buf);
2285: free (trybuf.buf);
2286: retried++;
2287: goto get_filename;
2288: }
2289: }
2290:
2291: flen = fend - fbeg;
2292: fname = (char *) alloca (max_include_len + flen + 2);
2293: /* + 2 above for slash and terminating null. */
2294:
2295: /* If specified file name is absolute, just open it. */
2296:
2297: if (*fbeg == '/') {
2298: strncpy (fname, fbeg, flen);
2299: fname[flen] = 0;
2300: f = open (fname, O_RDONLY);
2301: } else {
2302: /* Search directory path, trying to open the file.
2303: Copy each filename tried into FNAME. */
2304:
2305: for (; stackp; stackp = stackp->next) {
2306: if (stackp->fname) {
2307: strcpy (fname, stackp->fname);
2308: strcat (fname, "/");
2309: fname[strlen (fname) + flen] = 0;
2310: } else {
2311: fname[0] = 0;
2312: }
2313: strncat (fname, fbeg, flen);
2314: #ifdef VMS
2315: /* Change this 1/2 Unix 1/2 VMS file specification into a
2316: full VMS file specification */
2317: if (stackp->fname && (stackp->fname[0] != 0)) {
2318: /* Fix up the filename */
2319: hack_vms_include_specification (fname);
2320: } else {
2321: /* This is a normal VMS filespec, so use it unchanged. */
2322: strncpy (fname, fbeg, flen);
2323: fname[flen] = 0;
2324: }
2325: #endif /* VMS */
2326: if ((f = open (fname, O_RDONLY)) >= 0)
2327: break;
2328: }
2329: }
2330:
2331: /* For -M, print the name of the included file. */
2332: if (print_deps > system_header_p)
2333: {
2334: deps_output (fname, strlen (fname));
2335: deps_output (" ", 0);
2336: }
2337:
2338: if (f < 0) {
2339: strncpy (fname, fbeg, flen);
2340: fname[flen] = 0;
2341: error ("can't find include file `%s'", fname);
2342: } else {
2343: finclude (f, fname, op);
2344: close (f);
2345: }
2346: }
2347:
2348: /* Process the contents of include file FNAME, already open on descriptor F,
2349: with output to OP. */
2350:
2351: finclude (f, fname, op)
2352: int f;
2353: char *fname;
2354: FILE_BUF *op;
2355: {
2356: long st_size;
2357: long i;
2358: FILE_BUF *fp; /* For input stack frame */
2359: int success = 0;
2360:
2361: if (file_size_and_mode (f, (int *)0, &st_size) < 0)
2362: goto nope; /* Impossible? */
2363:
2364: fp = &instack[indepth + 1];
2365: bzero (fp, sizeof (FILE_BUF));
2366: fp->buf = (U_CHAR *) alloca (st_size + 2);
2367: fp->fname = fname;
2368: fp->length = 0;
2369: fp->lineno = 1;
2370: fp->bufp = fp->buf;
2371: fp->if_stack = if_stack;
2372:
2373: /* Read the file contents, knowing that st_size is an upper bound
2374: on the number of bytes we can read. */
2375: while (st_size > 0) {
2376: i = read (f, fp->buf + fp->length, st_size);
2377: if (i <= 0) {
2378: if (i == 0) break;
2379: goto nope;
2380: }
2381: fp->length += i;
2382: st_size -= i;
2383: }
2384:
2385: if (!no_trigraphs)
2386: trigraph_pcp (fp);
2387:
2388: if (fp->length > 0 && fp->buf[fp->length-1] != '\n')
2389: fp->buf[fp->length++] = '\n';
2390: fp->buf[fp->length] = '\0';
2391:
2392: success = 1;
2393: indepth++;
2394:
2395: output_line_command (fp, op, 0);
2396: rescan (op, 0);
2397: indepth--;
2398: output_line_command (&instack[indepth], op, 0);
2399:
2400: nope:
2401:
2402: close (f);
2403: if (!success) {
2404: perror_with_name (fname);
2405: }
2406: }
2407:
2408: /* The arglist structure is built by do_define to tell
2409: collect_definition where the argument names begin. That
2410: is, for a define like "#define f(x,y,z) foo+x-bar*y", the arglist
2411: would contain pointers to the strings x, y, and z.
2412: Collect_definition would then build a DEFINITION node,
2413: with reflist nodes pointing to the places x, y, and z had
2414: appeared. So the arglist is just convenience data passed
2415: between these two routines. It is not kept around after
2416: the current #define has been processed and entered into the
2417: hash table. */
2418:
2419: struct arglist {
2420: struct arglist *next;
2421: U_CHAR *name;
2422: int length;
2423: int argno;
2424: };
2425:
2426: /* Process a #define command.
2427: BUF points to the contents of the #define command, as a continguous string.
2428: LIMIT points to the first character past the end of the definition.
2429: KEYWORD is the keyword-table entry for #define. */
2430:
2431: do_define (buf, limit, op, keyword)
2432: U_CHAR *buf, *limit;
2433: FILE_BUF *op;
2434: struct directive *keyword;
2435: {
2436: U_CHAR *bp; /* temp ptr into input buffer */
2437: U_CHAR *symname; /* remember where symbol name starts */
2438: int sym_length; /* and how long it is */
2439:
2440: DEFINITION *defn;
2441: int arglengths = 0; /* Accumulate lengths of arg names
2442: plus number of args. */
2443: int hashcode;
2444:
2445: bp = buf;
2446:
2447: while (is_hor_space[*bp])
2448: bp++;
2449: if (!is_idstart[*bp])
2450: warning ("macro name starts with a digit");
2451:
2452: symname = bp; /* remember where it starts */
2453: while (is_idchar[*bp] && bp < limit) {
2454: if (*bp == '$' && pedantic) {
2455: if (! dollar_seen)
2456: warning ("ANSI C forbids `$' in identifier (first use here)");
2457: dollar_seen = 1;
2458: }
2459: bp++;
2460: }
2461: sym_length = bp - symname;
2462:
2463: /* lossage will occur if identifiers or control keywords are broken
2464: across lines using backslash. This is not the right place to take
2465: care of that. */
2466:
2467: if (*bp == '(') {
2468: struct arglist *arg_ptrs = NULL;
2469: int argno = 0;
2470:
2471: bp++; /* skip '(' */
2472: SKIP_WHITE_SPACE (bp);
2473:
2474: /* Loop over macro argument names. */
2475: while (*bp != ')') {
2476: struct arglist *temp;
2477:
2478: temp = (struct arglist *) alloca (sizeof (struct arglist));
2479: temp->name = bp;
2480: temp->next = arg_ptrs;
2481: temp->argno = argno++;
2482: arg_ptrs = temp;
2483:
2484: if (!is_idstart[*bp])
2485: warning ("parameter name starts with a digit in #define");
2486:
2487: /* Find the end of the arg name. */
2488: while (is_idchar[*bp]) {
2489: if (*bp == '$' && pedantic) {
2490: if (! dollar_seen)
2491: warning ("ANSI C forbids `$' in identifier (first use here)");
2492: dollar_seen = 1;
2493: }
2494: bp++;
2495: }
2496: temp->length = bp - temp->name;
2497: arglengths += temp->length + 2;
2498: SKIP_WHITE_SPACE (bp);
2499: if (temp->length == 0 || (*bp != ',' && *bp != ')')) {
2500: error ("badly punctuated parameter list in #define");
2501: goto nope;
2502: }
2503: if (*bp == ',') {
2504: bp++;
2505: SKIP_WHITE_SPACE (bp);
2506: }
2507: if (bp >= limit) {
2508: error ("unterminated parameter list in #define");
2509: goto nope;
2510: }
2511: }
2512:
2513: ++bp; /* skip paren */
2514: /* Skip exactly one space or tab if any. */
2515: if (bp < limit && (*bp == ' ' || *bp == '\t')) ++bp;
2516: /* now everything from bp before limit is the definition. */
2517: defn = collect_expansion (bp, limit, argno, arg_ptrs);
2518:
2519: /* Now set defn->argnames to the result of concatenating
2520: the argument names in reverse order
2521: with comma-space between them. */
2522: defn->argnames = (U_CHAR *) xmalloc (arglengths + 1);
2523: {
2524: struct arglist *temp;
2525: int i = 0;
2526: for (temp = arg_ptrs; temp; temp = temp->next)
2527: {
2528: bcopy (temp->name, &defn->argnames[i], temp->length);
2529: i += temp->length;
2530: if (temp->next != 0) {
2531: defn->argnames[i++] = ',';
2532: defn->argnames[i++] = ' ';
2533: }
2534: }
2535: defn->argnames[i] = 0;
2536: }
2537: } else {
2538: /* simple expansion or empty definition; gobble it */
2539: if (is_hor_space[*bp])
2540: ++bp; /* skip exactly one blank/tab char */
2541: /* now everything from bp before limit is the definition. */
2542: defn = collect_expansion (bp, limit, -1, 0);
2543: defn->argnames = (U_CHAR *) "";
2544: }
2545:
2546: hashcode = hashf (symname, sym_length, HASHSIZE);
2547:
2548: {
2549: HASHNODE *hp;
2550: if ((hp = lookup (symname, sym_length, hashcode)) != NULL) {
2551: if (hp->type != T_MACRO
2552: || compare_defs (defn, hp->value.defn)) {
2553: U_CHAR *msg; /* what pain... */
2554: msg = (U_CHAR *) alloca (sym_length + 20);
2555: bcopy (symname, msg, sym_length);
2556: strcpy (msg + sym_length, " redefined");
2557: warning (msg);
2558: }
2559: /* Replace the old definition. */
2560: hp->type = T_MACRO;
2561: hp->value.defn = defn;
2562: } else
2563: install (symname, sym_length, T_MACRO, defn, hashcode);
2564: }
2565:
2566: return 0;
2567:
2568: nope:
2569:
2570: return 1;
2571: }
2572:
2573: /*
2574: * return zero if two DEFINITIONs are isomorphic
2575: */
2576: static
2577: compare_defs (d1, d2)
2578: DEFINITION *d1, *d2;
2579: {
2580: register struct reflist *a1, *a2;
2581: register U_CHAR *p1 = d1->expansion;
2582: register U_CHAR *p2 = d2->expansion;
2583: int first = 1;
2584:
2585: if (d1->nargs != d2->nargs)
2586: return 1;
2587: if (strcmp (d1->argnames, d2->argnames))
2588: return 1;
2589: for (a1 = d1->pattern, a2 = d2->pattern; a1 && a2;
2590: a1 = a1->next, a2 = a2->next) {
2591: if (!((a1->nchars == a2->nchars && ! strncmp (p1, p2, a1->nchars))
2592: || ! comp_def_part (first, p1, a1->nchars, p2, a2->nchars, 0))
2593: || a1->argno != a2->argno
2594: || a1->stringify != a2->stringify
2595: || a1->raw_before != a2->raw_before
2596: || a1->raw_after != a2->raw_after)
2597: return 1;
2598: first = 0;
2599: p1 += a1->nchars;
2600: p2 += a2->nchars;
2601: }
2602: if (a1 != a2)
2603: return 1;
2604: if (comp_def_part (first, p1, d1->length - (p1 - d1->expansion),
2605: p2, d2->length - (p2 - d2->expansion), 1))
2606: return 1;
2607: return 0;
2608: }
2609:
2610: /* Return 1 if two parts of two macro definitions are effectively different.
2611: One of the parts starts at BEG1 and has LEN1 chars;
2612: the other has LEN2 chars at BEG2.
2613: Any sequence of whitespace matches any other sequence of whitespace.
2614: FIRST means these parts are the first of a macro definition;
2615: so ignore leading whitespace entirely.
2616: LAST means these parts are the last of a macro definition;
2617: so ignore trailing whitespace entirely. */
2618:
2619: comp_def_part (first, beg1, len1, beg2, len2, last)
2620: int first;
2621: U_CHAR *beg1, *beg2;
2622: int len1, len2;
2623: int last;
2624: {
2625: register U_CHAR *end1 = beg1 + len1;
2626: register U_CHAR *end2 = beg2 + len2;
2627: if (first) {
2628: while (beg1 != end1 && is_space[*beg1]) beg1++;
2629: while (beg2 != end2 && is_space[*beg2]) beg2++;
2630: }
2631: if (last) {
2632: while (beg1 != end1 && is_space[end1[-1]]) end1--;
2633: while (beg2 != end2 && is_space[end2[-1]]) end2--;
2634: }
2635: while (beg1 != end1 && beg2 != end2) {
2636: if (is_space[*beg1] && is_space[*beg2]) {
2637: while (beg1 != end1 && is_space[*beg1]) beg1++;
2638: while (beg2 != end2 && is_space[*beg2]) beg2++;
2639: } else if (*beg1 == *beg2) {
2640: beg1++; beg2++;
2641: } else break;
2642: }
2643: return (beg1 != end1) || (beg2 != end2);
2644: }
2645:
2646: /* Read a replacement list for a macro with parameters.
2647: Build the DEFINITION structure.
2648: Reads characters of text starting at BUF until LIMIT.
2649: ARGLIST specifies the formal parameters to look for
2650: in the text of the definition; NARGS is the number of args
2651: in that list, or -1 for a macro name that wants no argument list.
2652: MACRONAME is the macro name itself (so we can avoid recursive expansion)
2653: and NAMELEN is its length in characters.
2654:
2655: Note that comments and backslash-newlines have already been deleted
2656: from the argument. */
2657:
2658: /* Leading and trailing Space, Tab, etc. are converted to markers
2659: Newline Space, Newline Tab, etc.
2660: Newline Space makes a space in the final output
2661: but is discarded if stringified. (Newline Tab is similar but
2662: makes a Tab instead.)
2663:
2664: If there is no trailing whitespace, a Newline Space is added at the end
2665: to prevent concatenation that would be contrary to the standard. */
2666:
2667: static DEFINITION *
2668: collect_expansion (buf, end, nargs, arglist)
2669: U_CHAR *buf, *end;
2670: int nargs;
2671: struct arglist *arglist;
2672: {
2673: DEFINITION *defn;
2674: register U_CHAR *p, *limit, *lastp, *exp_p;
2675: struct reflist *endpat = NULL;
2676: /* Pointer to first nonspace after last ## seen. */
2677: U_CHAR *concat = 0;
2678: /* Pointer to first nonspace after last single-# seen. */
2679: U_CHAR *stringify = 0;
2680:
2681: /* Scan thru the replacement list, ignoring comments and quoted
2682: strings, picking up on the macro calls. It does a linear search
2683: thru the arg list on every potential symbol. Profiling might say
2684: that something smarter should happen. */
2685:
2686: if (end < buf)
2687: abort ();
2688:
2689: defn = (DEFINITION *) xcalloc (1, sizeof (DEFINITION) + 2 * (end - buf + 2));
2690:
2691: defn->nargs = nargs;
2692: exp_p = defn->expansion = (U_CHAR *) defn + sizeof (DEFINITION);
2693: lastp = exp_p;
2694:
2695: /* Speed this loop up later? */
2696:
2697: p = buf;
2698: limit = end;
2699:
2700: /* Find the beginning of the trailing whitespace. */
2701: while (p < limit && is_space[limit[-1]]) limit--;
2702:
2703: /* Convert leading whitespace to Newline-markers. */
2704: while (p < limit && is_space[*p]) {
2705: *exp_p++ = '\n';
2706: *exp_p++ = *p++;
2707: }
2708:
2709: /* Process the main body of the definition. */
2710: while (p < limit) {
2711: int skipped_arg = 0;
2712: register U_CHAR c = *p++;
2713:
2714: *exp_p++ = c;
2715:
2716: switch (c) {
2717: case '\'':
2718: case '\"':
2719: if (!traditional) {
2720: for (; p < limit && *p != c; p++) {
2721: *exp_p++ = *p;
2722: if (*p == '\\') {
2723: *exp_p++ = *++p;
2724: }
2725: }
2726: *exp_p++ = *p++;
2727: }
2728: break;
2729:
2730: /* Special hack: if a \# is written in the #define
2731: include a # in the definition. This is useless for C code
2732: but useful for preprocessing other things. */
2733:
2734: case '\\':
2735: if (p < limit && *p == '#') {
2736: /* Pass through this # */
2737: exp_p--;
2738: *exp_p++ = *p++;
2739: }
2740: break;
2741:
2742: case '#':
2743: if (p < limit && *p == '#') {
2744: /* ##: concatenate preceding and following tokens. */
2745: /* Take out the first #, discard preceding whitespace. */
2746: exp_p--;
2747: while (exp_p > lastp && is_hor_space[exp_p[-1]])
2748: --exp_p;
2749: /* Skip the second #. */
2750: p++;
2751: /* Discard following whitespace. */
2752: SKIP_WHITE_SPACE (p);
2753: concat = p;
2754: } else {
2755: /* Single #: stringify following argument ref.
2756: Don't leave the # in the expansion. */
2757: exp_p--;
2758: SKIP_WHITE_SPACE (p);
2759: if (p == limit || ! is_idstart[*p] || nargs <= 0)
2760: error ("# operator should be followed by a macro argument name\n");
2761: else
2762: stringify = p;
2763: }
2764: break;
2765: }
2766:
2767: if (is_idchar[c] && nargs > 0) {
2768: U_CHAR *id_beg = p - 1;
2769: int id_len;
2770:
2771: --exp_p;
2772: while (p != limit && is_idchar[*p]) p++;
2773: id_len = p - id_beg;
2774:
2775: if (is_idstart[c]) {
2776: register struct arglist *arg;
2777:
2778: for (arg = arglist; arg != NULL; arg = arg->next) {
2779: struct reflist *tpat;
2780:
2781: if (arg->name[0] == c
2782: && arg->length == id_len
2783: && strncmp (arg->name, id_beg, id_len) == 0) {
2784: /* make a pat node for this arg and append it to the end of
2785: the pat list */
2786: tpat = (struct reflist *) xmalloc (sizeof (struct reflist));
2787: tpat->next = NULL;
2788: tpat->stringify = stringify == id_beg;
2789: tpat->raw_before = concat == id_beg;
2790: tpat->raw_after = 0;
2791:
2792: if (endpat == NULL)
2793: defn->pattern = tpat;
2794: else
2795: endpat->next = tpat;
2796: endpat = tpat;
2797:
2798: tpat->argno = arg->argno;
2799: tpat->nchars = exp_p - lastp;
2800: {
2801: register U_CHAR *p1 = p;
2802: SKIP_WHITE_SPACE (p1);
2803: if (p1 + 2 <= limit && p1[0] == '#' && p1[1] == '#')
2804: tpat->raw_after = 1;
2805: }
2806: lastp = exp_p; /* place to start copying from next time */
2807: skipped_arg = 1;
2808: break;
2809: }
2810: }
2811: }
2812:
2813: /* If this was not a macro arg, copy it into the expansion. */
2814: if (! skipped_arg) {
2815: register U_CHAR *lim1 = p;
2816: p = id_beg;
2817: while (p != lim1)
2818: *exp_p++ = *p++;
2819: if (stringify == id_beg)
2820: error ("# operator should be followed by a macro argument name\n");
2821: }
2822: }
2823: }
2824:
2825: if (limit < end) {
2826: /* Convert trailing whitespace to Newline-markers. */
2827: while (limit < end && is_space[*limit]) {
2828: *exp_p++ = '\n';
2829: *exp_p++ = *limit++;
2830: }
2831: } else if (!traditional) {
2832: /* There is no trailing whitespace, so invent some. */
2833: *exp_p++ = '\n';
2834: *exp_p++ = ' ';
2835: }
2836:
2837: *exp_p = '\0';
2838:
2839: defn->length = exp_p - defn->expansion;
2840:
2841: #if 0
2842: /* This isn't worth the time it takes. */
2843: /* give back excess storage */
2844: defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1);
2845: #endif
2846:
2847: return defn;
2848: }
2849:
2850: #ifdef DEBUG
2851: /*
2852: * debugging routine ---- return a ptr to a string containing
2853: * first n chars of s. Returns a ptr to a static object
2854: * since I happen to know it will fit.
2855: */
2856: static U_CHAR *
2857: prefix (s, n)
2858: U_CHAR *s;
2859: int n;
2860: {
2861: static U_CHAR buf[1000];
2862: bcopy (s, buf, n);
2863: buf[n] = '\0'; /* this should not be necessary! */
2864: return buf;
2865: }
2866: #endif
2867:
2868: /*
2869: * interpret #line command. Remembers previously seen fnames
2870: * in its very own hash table.
2871: */
2872: #define FNAME_HASHSIZE 37
2873:
2874: do_line (buf, limit, op, keyword)
2875: U_CHAR *buf, *limit;
2876: FILE_BUF *op;
2877: struct directive *keyword;
2878: {
2879: register U_CHAR *bp;
2880: FILE_BUF *ip = &instack[indepth];
2881: FILE_BUF tem;
2882: int new_lineno;
2883:
2884: /* Expand any macros. */
2885: tem = expand_to_temp_buffer (buf, limit, 0);
2886:
2887: /* Point to macroexpanded line, which is null-terminated now. */
2888: bp = tem.buf;
2889: SKIP_WHITE_SPACE (bp);
2890:
2891: if (!isdigit (*bp)) {
2892: error ("invalid format #line command");
2893: return;
2894: }
2895:
2896: /* The Newline at the end of this line remains to be processed.
2897: To put the next line at the specified line number,
2898: we must store a line number now that is one less. */
2899: new_lineno = atoi (bp) - 1;
2900:
2901: /* skip over the line number. */
2902: while (isdigit (*bp))
2903: bp++;
2904: if (*bp && !is_space[*bp]) {
2905: error ("invalid format #line command");
2906: return;
2907: }
2908:
2909: SKIP_WHITE_SPACE (bp);
2910:
2911: if (*bp == '\"') {
2912: static HASHNODE *fname_table[FNAME_HASHSIZE];
2913: HASHNODE *hp, **hash_bucket;
2914: U_CHAR *fname;
2915: int fname_length;
2916:
2917: fname = ++bp;
2918:
2919: while (*bp && *bp != '\"')
2920: bp++;
2921: if (*bp != '\"') {
2922: error ("invalid format #line command");
2923: return;
2924: }
2925:
2926: fname_length = bp - fname;
2927:
2928: bp++;
2929: SKIP_WHITE_SPACE (bp);
2930: if (*bp) {
2931: error ("invalid format #line command");
2932: return;
2933: }
2934:
2935: hash_bucket =
2936: &fname_table[hashf (fname, fname_length, FNAME_HASHSIZE)];
2937: for (hp = *hash_bucket; hp != NULL; hp = hp->next)
2938: if (hp->length == fname_length &&
2939: strncmp (hp->value.cpval, fname, fname_length) == 0) {
2940: ip->fname = hp->value.cpval;
2941: break;
2942: }
2943: if (hp == 0) {
2944: /* Didn't find it; cons up a new one. */
2945: hp = (HASHNODE *) xcalloc (1, sizeof (HASHNODE) + fname_length + 1);
2946: hp->next = *hash_bucket;
2947: *hash_bucket = hp;
2948:
2949: hp->length = fname_length;
2950: ip->fname = hp->value.cpval = ((char *) hp) + sizeof (HASHNODE);
2951: bcopy (fname, hp->value.cpval, fname_length);
2952: }
2953: } else if (*bp) {
2954: error ("invalid format #line command");
2955: return;
2956: }
2957:
2958: ip->lineno = new_lineno;
2959: output_line_command (ip, op, 0);
2960: check_expand (op, ip->length - (ip->bufp - ip->buf));
2961: }
2962:
2963: /*
2964: * remove all definitions of symbol from symbol table.
2965: * according to un*x /lib/cpp, it is not an error to undef
2966: * something that has no definitions, so it isn't one here either.
2967: */
2968: do_undef (buf, limit, op, keyword)
2969: U_CHAR *buf, *limit;
2970: FILE_BUF *op;
2971: struct directive *keyword;
2972: {
2973: HASHNODE *hp;
2974:
2975: SKIP_WHITE_SPACE (buf);
2976:
2977: while ((hp = lookup (buf, -1, -1)) != NULL) {
2978: if (hp->type != T_MACRO)
2979: error ("undefining `%s'", hp->name);
2980: delete_macro (hp);
2981: }
2982: }
2983:
2984: /*
2985: * Report a fatal error detected by the program we are processing.
2986: * Use the text of the line in the error message, then terminate.
2987: * (We use error() because it prints the filename & line#.)
2988: */
2989: do_error (buf, limit, op, keyword)
2990: U_CHAR *buf, *limit;
2991: FILE_BUF *op;
2992: struct directive *keyword;
2993: {
2994: int length = limit - buf;
2995: char *copy = (char *) xmalloc (length + 1);
2996: bcopy (buf, copy, length);
2997: copy[length] = 0;
2998: SKIP_WHITE_SPACE (copy);
2999: error ("#error %s", copy);
3000: exit (FATAL_EXIT_CODE);
3001: }
3002:
3003: #if 0
3004: /* This was a fun hack, but #pragma seems to start to be useful.
3005: By failing to recognize it, we pass it through unchanged to cc1. */
3006:
3007: /*
3008: * the behavior of the #pragma directive is implementation defined.
3009: * this implementation defines it as follows.
3010: */
3011: do_pragma ()
3012: {
3013: close (0);
3014: if (open ("/dev/tty", O_RDONLY) != 0)
3015: goto nope;
3016: close (1);
3017: if (open ("/dev/tty", O_WRONLY) != 1)
3018: goto nope;
3019: execl ("/usr/games/hack", "#pragma", 0);
3020: execl ("/usr/games/rogue", "#pragma", 0);
3021: execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
3022: execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
3023: nope:
3024: fatal ("You are in a maze of twisty compiler features, all different");
3025: }
3026: #endif
3027:
3028: /* Just ignore #sccs, on systems where we define it at all. */
3029: do_sccs ()
3030: {}
3031:
3032: /*
3033: * handle #if command by
3034: * 1) inserting special `defined' keyword into the hash table
3035: * that gets turned into 0 or 1 by special_symbol (thus,
3036: * if the luser has a symbol called `defined' already, it won't
3037: * work inside the #if command)
3038: * 2) rescan the input into a temporary output buffer
3039: * 3) pass the output buffer to the yacc parser and collect a value
3040: * 4) clean up the mess left from steps 1 and 2.
3041: * 5) call conditional_skip to skip til the next #endif (etc.),
3042: * or not, depending on the value from step 3.
3043: */
3044:
3045: do_if (buf, limit, op, keyword)
3046: U_CHAR *buf, *limit;
3047: FILE_BUF *op;
3048: struct directive *keyword;
3049: {
3050: int value;
3051: FILE_BUF *ip = &instack[indepth];
3052:
3053: value = eval_if_expression (buf, limit - buf);
3054: conditional_skip (ip, value == 0, T_IF);
3055: }
3056:
3057: /*
3058: * handle a #elif directive by not changing if_stack either.
3059: * see the comment above do_else.
3060: */
3061:
3062: do_elif (buf, limit, op, keyword)
3063: U_CHAR *buf, *limit;
3064: FILE_BUF *op;
3065: struct directive *keyword;
3066: {
3067: int value;
3068: FILE_BUF *ip = &instack[indepth];
3069:
3070: if (if_stack == instack[indepth].if_stack) {
3071: error ("#elif not within a conditional");
3072: return;
3073: } else {
3074: if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
3075: error ("#elif after #else");
3076: fprintf (stderr, " (matches line %d", if_stack->lineno);
3077: if (if_stack->fname != NULL && ip->fname != NULL &&
3078: strcmp (if_stack->fname, ip->fname) != 0)
3079: fprintf (stderr, ", file %s", if_stack->fname);
3080: fprintf (stderr, ")\n");
3081: }
3082: if_stack->type = T_ELIF;
3083: }
3084:
3085: if (if_stack->if_succeeded)
3086: skip_if_group (ip, 0);
3087: else {
3088: value = eval_if_expression (buf, limit - buf);
3089: if (value == 0)
3090: skip_if_group (ip, 0);
3091: else {
3092: ++if_stack->if_succeeded; /* continue processing input */
3093: output_line_command (ip, op, 1);
3094: }
3095: }
3096: }
3097:
3098: /*
3099: * evaluate a #if expression in BUF, of length LENGTH,
3100: * then parse the result as a C expression and return the value as an int.
3101: */
3102: static int
3103: eval_if_expression (buf, length)
3104: U_CHAR *buf;
3105: int length;
3106: {
3107: FILE_BUF temp_obuf;
3108: HASHNODE *save_defined;
3109: int value;
3110:
3111: save_defined = install ("defined", -1, T_SPEC_DEFINED, 0, -1);
3112: temp_obuf = expand_to_temp_buffer (buf, buf + length, 0);
3113: delete_macro (save_defined); /* clean up special symbol */
3114:
3115: value = parse_c_expression (temp_obuf.buf);
3116:
3117: free (temp_obuf.buf);
3118:
3119: return value;
3120: }
3121:
3122: /*
3123: * routine to handle ifdef/ifndef. Try to look up the symbol,
3124: * then do or don't skip to the #endif/#else/#elif depending
3125: * on what directive is actually being processed.
3126: */
3127: do_xifdef (buf, limit, op, keyword)
3128: U_CHAR *buf, *limit;
3129: FILE_BUF *op;
3130: struct directive *keyword;
3131: {
3132: int skip;
3133: FILE_BUF *ip = &instack[indepth];
3134: U_CHAR *end;
3135:
3136: /* Discard leading and trailing whitespace. */
3137: SKIP_WHITE_SPACE (buf);
3138: while (limit != buf && is_hor_space[limit[-1]]) limit--;
3139:
3140: /* Find the end of the identifier at the beginning. */
3141: for (end = buf; is_idchar[*end]; end++);
3142:
3143: if (end == buf)
3144: {
3145: skip = (keyword->type == T_IFDEF);
3146: if (! traditional)
3147: warning (end == limit ? "#%s with no argument"
3148: : "#%s argument starts with punctuation",
3149: keyword->name);
3150: }
3151: else
3152: {
3153: if (pedantic && buf[0] >= '0' && buf[0] <= '9')
3154: warning ("#%s argument starts with a digit", keyword->name);
3155: else if (end != limit && !traditional)
3156: warning ("garbage at end of #%s argument", keyword->name);
3157:
3158: skip = (lookup (buf, end-buf, -1) == NULL) ^ (keyword->type == T_IFNDEF);
3159: }
3160:
3161: conditional_skip (ip, skip, T_IF);
3162: }
3163:
3164: /*
3165: * push TYPE on stack; then, if SKIP is nonzero, skip ahead.
3166: */
3167: static
3168: conditional_skip (ip, skip, type)
3169: FILE_BUF *ip;
3170: int skip;
3171: enum node_type type;
3172: {
3173: IF_STACK_FRAME *temp;
3174:
3175: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
3176: temp->fname = ip->fname;
3177: temp->lineno = ip->lineno;
3178: temp->next = if_stack;
3179: if_stack = temp;
3180:
3181: if_stack->type = type;
3182:
3183: if (skip != 0) {
3184: skip_if_group (ip, 0);
3185: return;
3186: } else {
3187: ++if_stack->if_succeeded;
3188: output_line_command (ip, &outbuf, 1);
3189: }
3190: }
3191:
3192: /*
3193: * skip to #endif, #else, or #elif. adjust line numbers, etc.
3194: * leaves input ptr at the sharp sign found.
3195: * If ANY is nonzero, return at next directive of any sort.
3196: */
3197: static
3198: skip_if_group (ip, any)
3199: FILE_BUF *ip;
3200: int any;
3201: {
3202: register U_CHAR *bp = ip->bufp, *cp;
3203: register U_CHAR *endb = ip->buf + ip->length;
3204: struct directive *kt;
3205: IF_STACK_FRAME *save_if_stack = if_stack; /* don't pop past here */
3206: U_CHAR *beg_of_line = bp;
3207:
3208: while (bp < endb) {
3209: switch (*bp++) {
3210: case '/': /* possible comment */
3211: if (*bp == '\\' && bp[1] == '\n')
3212: newline_fix (bp);
3213: if (*bp == '*'
3214: #ifdef CPLUSPLUS
3215: || *bp == '/'
3216: #endif
3217: ) {
3218: ip->bufp = ++bp;
3219: bp = skip_to_end_of_comment (ip, &ip->lineno);
3220: }
3221: break;
3222: case '\"':
3223: case '\'':
3224: if (!traditional)
3225: bp = skip_quoted_string (bp - 1, endb, ip->lineno, &ip->lineno, 0, 0);
3226: break;
3227: case '\n':
3228: ++ip->lineno;
3229: beg_of_line = bp;
3230: break;
3231: case '#':
3232: ip->bufp = bp - 1;
3233:
3234: /* # keyword: a # must be first nonblank char on the line */
3235: if (beg_of_line == 0)
3236: break;
3237: /* Scan from start of line, skipping whitespace, comments
3238: and backslash-newlines, and see if we reach this #.
3239: If not, this # is not special. */
3240: bp = beg_of_line;
3241: while (1) {
3242: if (is_hor_space[*bp])
3243: bp++;
3244: else if (*bp == '\\' && bp[1] == '\n')
3245: bp += 2;
3246: else if (*bp == '/' && bp[1] == '*') {
3247: bp += 2;
3248: while (!(*bp == '*' && bp[1] == '/'))
3249: bp++;
3250: bp += 2;
3251: }
3252: #ifdef CPLUSPLUS
3253: else if (*bp == '/' && bp[1] == '/') {
3254: bp += 2;
3255: while (*bp++ != '\n') ;
3256: }
3257: #endif
3258: else break;
3259: }
3260: if (bp != ip->bufp) {
3261: bp = ip->bufp + 1; /* Reset bp to after the #. */
3262: break;
3263: }
3264:
3265: bp = ip->bufp + 1; /* point at '#' */
3266:
3267: /* Skip whitespace and \-newline. */
3268: while (1) {
3269: if (is_hor_space[*bp])
3270: bp++;
3271: else if (*bp == '\\' && bp[1] == '\n')
3272: bp += 2;
3273: else break;
3274: }
3275:
3276: cp = bp;
3277:
3278: /* Now find end of directive name.
3279: If we encounter a backslash-newline, exchange it with any following
3280: symbol-constituents so that we end up with a contiguous name. */
3281:
3282: while (1) {
3283: if (is_idchar[*bp])
3284: bp++;
3285: else {
3286: if (*bp == '\\' && bp[1] == '\n')
3287: name_newline_fix (bp);
3288: if (is_idchar[*bp])
3289: bp++;
3290: else break;
3291: }
3292: }
3293:
3294: for (kt = directive_table; kt->length >= 0; kt++) {
3295: IF_STACK_FRAME *temp;
3296: if (strncmp (cp, kt->name, kt->length) == 0
3297: && !is_idchar[cp[kt->length]]) {
3298:
3299: /* If we are asked to return on next directive,
3300: do so now. */
3301: if (any)
3302: return;
3303:
3304: switch (kt->type) {
3305: case T_IF:
3306: case T_IFDEF:
3307: case T_IFNDEF:
3308: temp = (IF_STACK_FRAME *) xcalloc (1, sizeof (IF_STACK_FRAME));
3309: temp->next = if_stack;
3310: if_stack = temp;
3311: temp->lineno = ip->lineno;
3312: temp->fname = ip->fname;
3313: temp->type = kt->type;
3314: break;
3315: case T_ELSE:
3316: case T_ENDIF:
3317: if (pedantic && if_stack != save_if_stack)
3318: validate_else (bp);
3319: case T_ELIF:
3320: if (if_stack == instack[indepth].if_stack) {
3321: error ("#%s not within a conditional", kt->name);
3322: break;
3323: }
3324: else if (if_stack == save_if_stack)
3325: return; /* found what we came for */
3326:
3327: if (kt->type != T_ENDIF) {
3328: if (if_stack->type == T_ELSE)
3329: error ("#else or #elif after #else");
3330: if_stack->type = kt->type;
3331: break;
3332: }
3333:
3334: temp = if_stack;
3335: if_stack = if_stack->next;
3336: free (temp);
3337: break;
3338: }
3339: break;
3340: }
3341: }
3342: }
3343: }
3344: ip->bufp = bp;
3345: /* after this returns, rescan will exit because ip->bufp
3346: now points to the end of the buffer.
3347: rescan is responsible for the error message also. */
3348: }
3349:
3350: /*
3351: * handle a #else directive. Do this by just continuing processing
3352: * without changing if_stack ; this is so that the error message
3353: * for missing #endif's etc. will point to the original #if. It
3354: * is possible that something different would be better.
3355: */
3356: do_else (buf, limit, op, keyword)
3357: U_CHAR *buf, *limit;
3358: FILE_BUF *op;
3359: struct directive *keyword;
3360: {
3361: FILE_BUF *ip = &instack[indepth];
3362:
3363: if (pedantic) {
3364: SKIP_WHITE_SPACE (buf);
3365: if (buf != limit)
3366: warning ("text following #else violates ANSI standard");
3367: }
3368:
3369: if (if_stack == instack[indepth].if_stack) {
3370: error ("#else not within a conditional");
3371: return;
3372: } else {
3373: if (if_stack->type != T_IF && if_stack->type != T_ELIF) {
3374: error ("#else after #else");
3375: fprintf (stderr, " (matches line %d", if_stack->lineno);
3376: if (strcmp (if_stack->fname, ip->fname) != 0)
3377: fprintf (stderr, ", file %s", if_stack->fname);
3378: fprintf (stderr, ")\n");
3379: }
3380: if_stack->type = T_ELSE;
3381: }
3382:
3383: if (if_stack->if_succeeded)
3384: skip_if_group (ip, 0);
3385: else {
3386: ++if_stack->if_succeeded; /* continue processing input */
3387: output_line_command (ip, op, 1);
3388: }
3389: }
3390:
3391: /*
3392: * unstack after #endif command
3393: */
3394: do_endif (buf, limit, op, keyword)
3395: U_CHAR *buf, *limit;
3396: FILE_BUF *op;
3397: struct directive *keyword;
3398: {
3399: if (pedantic) {
3400: SKIP_WHITE_SPACE (buf);
3401: if (buf != limit)
3402: warning ("text following #endif violates ANSI standard");
3403: }
3404:
3405: if (if_stack == instack[indepth].if_stack)
3406: error ("unbalanced #endif");
3407: else {
3408: IF_STACK_FRAME *temp = if_stack;
3409: if_stack = if_stack->next;
3410: free (temp);
3411: output_line_command (&instack[indepth], op, 1);
3412: }
3413: }
3414:
3415: /* When an #else or #endif is found while skipping failed conditional,
3416: if -pedantic was specified, this is called to warn about text after
3417: the command name. P points to the first char after the command name. */
3418:
3419: validate_else (p)
3420: register U_CHAR *p;
3421: {
3422: /* Advance P over whitespace and comments. */
3423: while (1) {
3424: if (*p == '\\' && p[1] == '\n')
3425: p += 2;
3426: if (is_hor_space[*p])
3427: p++;
3428: else if (*p == '/') {
3429: if (p[1] == '\\' && p[2] == '\n')
3430: newline_fix (p + 1);
3431: if (p[1] == '*') {
3432: p += 2;
3433: /* Don't bother warning about unterminated comments
3434: since that will happen later. Just be sure to exit. */
3435: while (*p) {
3436: if (p[1] == '\\' && p[2] == '\n')
3437: newline_fix (p + 1);
3438: if (*p == '*' && p[1] == '/') {
3439: p += 2;
3440: break;
3441: }
3442: p++;
3443: }
3444: }
3445: #ifdef CPLUSPLUS
3446: else if (p[1] == '/') {
3447: p += 2;
3448: while (*p && *p++ != '\n') ;
3449: }
3450: #endif
3451: } else break;
3452: }
3453: if (*p && *p != '\n')
3454: warning ("text following #else or #endif violates ANSI standard");
3455: }
3456:
3457: /*
3458: * Skip a comment, assuming the input ptr immediately follows the
3459: * initial slash-star. Bump line counter as necessary.
3460: * (The canonical line counter is &ip->lineno).
3461: * Don't use this routine (or the next one) if bumping the line
3462: * counter is not sufficient to deal with newlines in the string.
3463: */
3464: U_CHAR *
3465: skip_to_end_of_comment (ip, line_counter)
3466: register FILE_BUF *ip;
3467: int *line_counter; /* place to remember newlines, or NULL */
3468: {
3469: register U_CHAR *limit = ip->buf + ip->length;
3470: register U_CHAR *bp = ip->bufp;
3471: FILE_BUF *op = &outbuf; /* JF */
3472: int output = put_out_comments && !line_counter;
3473:
3474: /* JF this line_counter stuff is a crock to make sure the
3475: comment is only put out once, no matter how many times
3476: the comment is skipped. It almost works */
3477: if (output) {
3478: *op->bufp++ = '/';
3479: *op->bufp++ = '*';
3480: }
3481: #ifdef CPLUSPLUS
3482: if (bp[-1] == '/') {
3483: if (output)
3484: {
3485: while (bp < limit)
3486: if ((*op->bufp++ = *bp++) == '\n')
3487: {
3488: bp--;
3489: break;
3490: }
3491: op->bufp[-1] = '*';
3492: *op->bufp++ = '/';
3493: *op->bufp++ = '\n';
3494: }
3495: else
3496: {
3497: while (bp < limit) {
3498: if (*bp++ == '\n')
3499: {
3500: bp--;
3501: break;
3502: }
3503: }
3504: }
3505: ip->bufp = bp;
3506: return bp;
3507: }
3508: #endif
3509: while (bp < limit) {
3510: if (output)
3511: *op->bufp++ = *bp;
3512: switch (*bp++) {
3513: case '\n':
3514: if (line_counter != NULL)
3515: ++*line_counter;
3516: if (output)
3517: ++op->lineno;
3518: break;
3519: case '*':
3520: if (*bp == '\\' && bp[1] == '\n')
3521: newline_fix (bp);
3522: if (*bp == '/') {
3523: if (output)
3524: *op->bufp++ = '/';
3525: ip->bufp = ++bp;
3526: return bp;
3527: }
3528: break;
3529: }
3530: }
3531: ip->bufp = bp;
3532: return bp;
3533: }
3534:
3535: /*
3536: * Skip over a quoted string. BP points to the opening quote.
3537: * Returns a pointer after the closing quote. Don't go past LIMIT.
3538: * START_LINE is the line number of the starting point (but it need
3539: * not be valid if the starting point is inside a macro expansion).
3540: *
3541: * The input stack state is not changed.
3542: *
3543: * If COUNT_NEWLINES is nonzero, it points to an int to increment
3544: * for each newline passed.
3545: *
3546: * If BACKSLASH_NEWLINES_P is nonzero, store 1 thru it
3547: * if we pass a backslash-newline.
3548: *
3549: * If EOFP is nonzero, set *EOFP to 1 if the string is unterminated.
3550: */
3551: U_CHAR *
3552: skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, eofp)
3553: register U_CHAR *bp;
3554: register U_CHAR *limit;
3555: int start_line;
3556: int *count_newlines;
3557: int *backslash_newlines_p;
3558: int *eofp;
3559: {
3560: register U_CHAR c, match;
3561:
3562: match = *bp++;
3563: while (1) {
3564: if (bp >= limit) {
3565: error_with_line (line_for_error (start_line),
3566: "unterminated string constant");
3567: if (eofp)
3568: *eofp = 1;
3569: break;
3570: }
3571: c = *bp++;
3572: if (c == '\\') {
3573: while (*bp == '\\' && bp[1] == '\n') {
3574: if (backslash_newlines_p)
3575: *backslash_newlines_p = 1;
3576: if (count_newlines)
3577: ++*count_newlines;
3578: bp += 2;
3579: }
3580: if (*bp == '\n' && count_newlines) {
3581: if (backslash_newlines_p)
3582: *backslash_newlines_p = 1;
3583: ++*count_newlines;
3584: }
3585: bp++;
3586: } else if (c == '\n') {
3587: if (count_newlines)
3588: ++*count_newlines;
3589: } else if (c == match)
3590: break;
3591: }
3592: return bp;
3593: }
3594:
3595: /*
3596: * write out a #line command, for instance, after an #include file.
3597: * If CONDITIONAL is nonzero, we can omit the #line if it would
3598: * appear to be a no-op, and we can output a few newlines instead
3599: * if we want to increase the line number by a small amount.
3600: */
3601: static
3602: output_line_command (ip, op, conditional)
3603: FILE_BUF *ip, *op;
3604: int conditional;
3605: {
3606: int len;
3607: char line_cmd_buf[500];
3608:
3609: if (no_line_commands
3610: || ip->fname == NULL
3611: || no_output) {
3612: op->lineno = ip->lineno;
3613: return;
3614: }
3615:
3616: if (conditional) {
3617: if (ip->lineno == op->lineno)
3618: return;
3619:
3620: /* If the inherited line number is a little too small,
3621: output some newlines instead of a #line command. */
3622: if (ip->lineno > op->lineno && ip->lineno < op->lineno + 8) {
3623: check_expand (op, 10);
3624: while (ip->lineno > op->lineno) {
3625: *op->bufp++ = '\n';
3626: op->lineno++;
3627: }
3628: return;
3629: }
3630: }
3631:
3632: #ifdef OUTPUT_LINE_COMMANDS
3633: sprintf (line_cmd_buf, "#line %d \"%s\"\n", ip->lineno, ip->fname);
3634: #else
3635: sprintf (line_cmd_buf, "# %d \"%s\"\n", ip->lineno, ip->fname);
3636: #endif
3637: len = strlen (line_cmd_buf);
3638: check_expand (op, len + 1);
3639: if (op->bufp > op->buf && op->bufp[-1] != '\n')
3640: *op->bufp++ = '\n';
3641: bcopy (line_cmd_buf, op->bufp, len);
3642: op->bufp += len;
3643: op->lineno = ip->lineno;
3644: }
3645:
3646: /* This structure represents one parsed argument in a macro call.
3647: `raw' points to the argument text as written (`raw_length' is its length).
3648: `expanded' points to the argument's macro-expansion
3649: (its length is `expand_length').
3650: `stringified_length' is the length the argument would have
3651: if stringified.
3652: `free1' and `free2', if nonzero, point to blocks to be freed
3653: when the macro argument data is no longer needed. */
3654:
3655: struct argdata {
3656: U_CHAR *raw, *expanded;
3657: int raw_length, expand_length;
3658: int stringified_length;
3659: U_CHAR *free1, *free2;
3660: char newlines;
3661: char comments;
3662: };
3663:
3664: /* Expand a macro call.
3665: HP points to the symbol that is the macro being called.
3666: Put the result of expansion onto the input stack
3667: so that subsequent input by our caller will use it.
3668:
3669: If macro wants arguments, caller has already verified that
3670: an argument list follows; arguments come from the input stack. */
3671:
3672: macroexpand (hp, op)
3673: HASHNODE *hp;
3674: FILE_BUF *op;
3675: {
3676: int nargs;
3677: DEFINITION *defn = hp->value.defn;
3678: register U_CHAR *xbuf;
3679: int xbuf_len;
3680: int start_line = instack[indepth].lineno;
3681:
3682: /* it might not actually be a macro. */
3683: if (hp->type != T_MACRO)
3684: {
3685: special_symbol (hp, op);
3686: return;
3687: }
3688:
3689: nargs = defn->nargs;
3690:
3691: if (nargs >= 0)
3692: {
3693: register int i;
3694: struct argdata *args;
3695: char *parse_error = 0;
3696:
3697: args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata));
3698:
3699: for (i = 0; i < nargs; i++) {
3700: args[i].raw = args[i].expanded = (U_CHAR *) "";
3701: args[i].raw_length = args[i].expand_length
3702: = args[i].stringified_length = 0;
3703: args[i].free1 = args[i].free2 = 0;
3704: }
3705:
3706: /* Parse all the macro args that are supplied. I counts them.
3707: The first NARGS args are stored in ARGS.
3708: The rest are discarded. */
3709: i = 0;
3710: do {
3711: /* Discard the open-parenthesis or comma before the next arg. */
3712: ++instack[indepth].bufp;
3713: if (parse_error = macarg ((i < nargs || (nargs == 0 && i == 0)) ? &args[i] : 0))
3714: {
3715: error_with_line (line_for_error (start_line), parse_error);
3716: break;
3717: }
3718: i++;
3719: } while (*instack[indepth].bufp != ')');
3720:
3721: if (nargs == 0 && i == 1) {
3722: register U_CHAR *bp = args[0].raw;
3723: register U_CHAR *lim = bp + args[0].raw_length;
3724: while (bp != lim && is_space[*bp]) bp++;
3725: if (bp != lim)
3726: error ("arguments given to macro `%s'", hp->name);
3727: } else if (i < nargs)
3728: error ("only %d args to macro `%s'", i, hp->name);
3729: else if (i > nargs)
3730: error ("too many (%d) args to macro `%s'", i, hp->name);
3731:
3732: /* Swallow the closeparen. */
3733: ++instack[indepth].bufp;
3734:
3735: /* If macro wants zero args, we parsed the arglist for checking only.
3736: Read directly from the macro definition. */
3737: if (nargs == 0) {
3738: xbuf = defn->expansion;
3739: xbuf_len = defn->length;
3740: } else {
3741: register U_CHAR *exp = defn->expansion;
3742: register int offset; /* offset in expansion,
3743: copied a piece at a time */
3744: register int totlen; /* total amount of exp buffer filled so far */
3745:
3746: register struct reflist *ap;
3747:
3748: /* Macro really takes args. Compute the expansion of this call. */
3749:
3750: /* Compute length in characters of the macro's expansion. */
3751: xbuf_len = defn->length;
3752: for (ap = defn->pattern; ap != NULL; ap = ap->next) {
3753: if (ap->stringify)
3754: xbuf_len += args[ap->argno].stringified_length;
3755: else if (ap->raw_before || ap->raw_after)
3756: xbuf_len += args[ap->argno].raw_length;
3757: else
3758: xbuf_len += args[ap->argno].expand_length;
3759: }
3760:
3761: xbuf = (U_CHAR *) xmalloc (xbuf_len + 1);
3762:
3763: /* Generate in XBUF the complete expansion
3764: with arguments substituted in.
3765: TOTLEN is the total size generated so far.
3766: OFFSET is the index in the definition
3767: of where we are copying from. */
3768: offset = totlen = 0;
3769: for (ap = defn->pattern; ap != NULL; ap = ap->next) {
3770: register struct argdata *arg = &args[ap->argno];
3771:
3772: for (i = 0; i < ap->nchars; i++)
3773: xbuf[totlen++] = exp[offset++];
3774:
3775: if (ap->stringify != 0) {
3776: int arglen = arg->raw_length;
3777: int escaped = 0;
3778: int in_string = 0;
3779: int c;
3780: i = 0;
3781: while (i < arglen
3782: && (c = arg->raw[i], is_space[c]))
3783: i++;
3784: while (i < arglen
3785: && (c = arg->raw[arglen - 1], is_space[c]))
3786: arglen--;
3787: xbuf[totlen++] = '\"'; /* insert beginning quote */
3788: for (; i < arglen; i++) {
3789: c = arg->raw[i];
3790:
3791: /* Special markers Newline Space and Newline Newline
3792: generate nothing for a stringified argument. */
3793: if (c == '\n') {
3794: i++;
3795: continue;
3796: }
3797:
3798: /* Internal sequences of whitespace are replaced by one space. */
3799: if (is_space[c]) {
3800: while (c = arg->raw[i+1], is_space[c]) i++;
3801: c = ' ';
3802: }
3803:
3804: if (escaped)
3805: escaped = 0;
3806: else {
3807: if (c == '\\')
3808: escaped = 1;
3809: if (in_string && c == in_string)
3810: in_string = 0;
3811: else if (c == '\"' || c == '\'')
3812: in_string = c;
3813: }
3814:
3815: /* Escape these chars */
3816: if (c == '\"' || (in_string && c == '\\'))
3817: xbuf[totlen++] = '\\';
3818: if (isprint (c))
3819: xbuf[totlen++] = c;
3820: else {
3821: sprintf (&xbuf[totlen], "\\%03o", (unsigned int) c);
3822: totlen += 4;
3823: }
3824: }
3825: xbuf[totlen++] = '\"'; /* insert ending quote */
3826: } else if (ap->raw_before || ap->raw_after) {
3827: U_CHAR *p1 = arg->raw;
3828: U_CHAR *l1 = p1 + arg->raw_length;
3829: if (ap->raw_before) {
3830: while (p1 != l1 && is_space[*p1]) p1++;
3831: while (p1 != l1 && is_idchar[*p1])
3832: xbuf[totlen++] = *p1++;
3833: /* Delete any no-reexpansion marker that follows
3834: an identifier at the beginning of the argument
3835: if the argument is concatenated with what precedes it. */
3836: if (p1[0] == '\n' && p1[1] == '-')
3837: p1 += 2;
3838: }
3839: if (ap->raw_after) {
3840: /* Arg is concatenated after: delete trailing whitespace,
3841: whitespace markers, and no-reexpansion markers. */
3842: while (p1 != l1) {
3843: if (is_space[l1[-1]]) l1--;
3844: else if (l1[-1] == '-') {
3845: U_CHAR *p2 = l1 - 1;
3846: /* If a `-' is preceded by an odd number of newlines then it
3847: and the last newline are a no-reexpansion marker. */
3848: while (p2 != p1 && p2[-1] == '\n') p2--;
3849: if ((l1 - 1 - p2) & 1) {
3850: l1 -= 2;
3851: }
3852: else break;
3853: }
3854: else break;
3855: }
3856: }
3857: bcopy (p1, xbuf + totlen, l1 - p1);
3858: totlen += l1 - p1;
3859: } else {
3860: bcopy (arg->expanded, xbuf + totlen, arg->expand_length);
3861: totlen += arg->expand_length;
3862: }
3863:
3864: if (totlen > xbuf_len)
3865: abort ();
3866: }
3867:
3868: /* if there is anything left of the definition
3869: after handling the arg list, copy that in too. */
3870:
3871: for (i = offset; i < defn->length; i++)
3872: xbuf[totlen++] = exp[i];
3873:
3874: xbuf[totlen] = 0;
3875: xbuf_len = totlen;
3876:
3877: for (i = 0; i < nargs; i++) {
3878: if (args[i].free1 != 0)
3879: free (args[i].free1);
3880: if (args[i].free2 != 0)
3881: free (args[i].free2);
3882: }
3883: }
3884: }
3885: else
3886: {
3887: xbuf = defn->expansion;
3888: xbuf_len = defn->length;
3889: }
3890:
3891: /* Now put the expansion on the input stack
3892: so our caller will commence reading from it. */
3893: {
3894: register FILE_BUF *ip2;
3895:
3896: ip2 = &instack[++indepth];
3897:
3898: ip2->fname = 0;
3899: ip2->lineno = 0;
3900: ip2->buf = xbuf;
3901: ip2->length = xbuf_len;
3902: ip2->bufp = xbuf;
3903: ip2->free = (nargs > 0) ? xbuf : 0;
3904: ip2->macro = hp;
3905: ip2->if_stack = if_stack;
3906:
3907: if (!traditional)
3908: hp->type = T_DISABLED;
3909: }
3910: }
3911:
3912: /*
3913: * Parse a macro argument and store the info on it into *ARGPTR.
3914: * Return nonzero to indicate a syntax error.
3915: */
3916:
3917: char *
3918: macarg (argptr)
3919: register struct argdata *argptr;
3920: {
3921: FILE_BUF *ip = &instack[indepth];
3922: int paren = 0;
3923: int newlines = 0;
3924: int comments = 0;
3925:
3926: /* Try to parse as much of the argument as exists at this
3927: input stack level. */
3928: U_CHAR *bp = macarg1 (ip->bufp, ip->buf + ip->length,
3929: &paren, &newlines, &comments);
3930:
3931: /* If we find the end of the argument at this level,
3932: set up *ARGPTR to point at it in the input stack. */
3933: if (!(ip->fname != 0 && (newlines != 0 || comments != 0))
3934: && bp != ip->buf + ip->length) {
3935: if (argptr != 0) {
3936: argptr->raw = ip->bufp;
3937: argptr->raw_length = bp - ip->bufp;
3938: }
3939: ip->bufp = bp;
3940: } else {
3941: /* This input stack level ends before the macro argument does.
3942: We must pop levels and keep parsing.
3943: Therefore, we must allocate a temporary buffer and copy
3944: the macro argument into it. */
3945: int bufsize = bp - ip->bufp;
3946: int extra = newlines;
3947: U_CHAR *buffer = (U_CHAR *) xmalloc (bufsize + extra + 1);
3948: int final_start = 0;
3949:
3950: bcopy (ip->bufp, buffer, bufsize);
3951: ip->bufp = bp;
3952: ip->lineno += newlines;
3953:
3954: while (bp == ip->buf + ip->length) {
3955: if (instack[indepth].macro == 0) {
3956: free (buffer);
3957: return "Unterminated macro call";
3958: }
3959: ip->macro->type = T_MACRO;
3960: free (ip->buf);
3961: ip = &instack[--indepth];
3962: newlines = 0;
3963: comments = 0;
3964: bp = macarg1 (ip->bufp, ip->buf + ip->length, &paren,
3965: &newlines, &comments);
3966: final_start = bufsize;
3967: bufsize += bp - ip->bufp;
3968: extra += newlines;
3969: buffer = (U_CHAR *) xrealloc (buffer, bufsize + extra + 1);
3970: bcopy (ip->bufp, buffer + bufsize - (bp - ip->bufp), bp - ip->bufp);
3971: ip->bufp = bp;
3972: ip->lineno += newlines;
3973: }
3974:
3975: /* Now, if arg is actually wanted, record its raw form,
3976: discarding comments and duplicating newlines in whatever
3977: part of it did not come from a macro expansion.
3978: EXTRA space has been preallocated for duplicating the newlines.
3979: FINAL_START is the index of the start of that part. */
3980: if (argptr != 0) {
3981: argptr->raw = buffer;
3982: argptr->raw_length = bufsize;
3983: argptr->free1 = buffer;
3984: argptr->newlines = newlines;
3985: argptr->comments = comments;
3986: if ((newlines || comments) && ip->fname != 0)
3987: argptr->raw_length
3988: = final_start +
3989: discard_comments (argptr->raw + final_start,
3990: argptr->raw_length - final_start,
3991: newlines);
3992: argptr->raw[argptr->raw_length] = 0;
3993: if (argptr->raw_length > bufsize + extra)
3994: abort ();
3995: }
3996: }
3997:
3998: /* If we are not discarding this argument,
3999: macroexpand it and compute its length as stringified.
4000: All this info goes into *ARGPTR. */
4001:
4002: if (argptr != 0) {
4003: FILE_BUF obuf;
4004: register U_CHAR *buf, *lim;
4005: register int totlen;
4006:
4007: obuf = expand_to_temp_buffer (argptr->raw,
4008: argptr->raw + argptr->raw_length,
4009: 1);
4010:
4011: argptr->expanded = obuf.buf;
4012: argptr->expand_length = obuf.length;
4013: argptr->free2 = obuf.buf;
4014:
4015: buf = argptr->raw;
4016: lim = buf + argptr->raw_length;
4017:
4018: while (buf != lim && is_space[*buf])
4019: buf++;
4020: while (buf != lim && is_space[lim[-1]])
4021: lim--;
4022: totlen = 2; /* Count opening and closing quote. */
4023: while (buf != lim) {
4024: register U_CHAR c = *buf++;
4025: totlen++;
4026: /* Internal sequences of whitespace are replaced by one space. */
4027: if (is_space[c])
4028: SKIP_ALL_WHITE_SPACE (buf);
4029: else if (c == '\"' || c == '\\') /* escape these chars */
4030: totlen++;
4031: else if (!isprint (c))
4032: totlen += 3;
4033: }
4034: argptr->stringified_length = totlen;
4035: }
4036: return 0;
4037: }
4038:
4039: /* Scan text from START (inclusive) up to LIMIT (exclusive),
4040: counting parens in *DEPTHPTR,
4041: and return if reach LIMIT
4042: or before a `)' that would make *DEPTHPTR negative
4043: or before a comma when *DEPTHPTR is zero.
4044: Single and double quotes are matched and termination
4045: is inhibited within them. Comments also inhibit it.
4046: Value returned is pointer to stopping place.
4047:
4048: Increment *NEWLINES each time a newline is passed.
4049: Set *COMMENTS to 1 if a comment is seen. */
4050:
4051: U_CHAR *
4052: macarg1 (start, limit, depthptr, newlines, comments)
4053: U_CHAR *start;
4054: register U_CHAR *limit;
4055: int *depthptr, *newlines, *comments;
4056: {
4057: register U_CHAR *bp = start;
4058:
4059: while (bp < limit) {
4060: switch (*bp) {
4061: case '(':
4062: (*depthptr)++;
4063: break;
4064: case ')':
4065: if (--(*depthptr) < 0)
4066: return bp;
4067: break;
4068: case '\n':
4069: ++*newlines;
4070: break;
4071: case '/':
4072: if (bp[1] == '\\' && bp[2] == '\n')
4073: newline_fix (bp + 1);
4074: #ifdef CPLUSPLUS
4075: if (bp[1] == '/') {
4076: *comments = 1;
4077: bp += 2;
4078: while (bp < limit && *bp++ != '\n') ;
4079: ++*newlines;
4080: break;
4081: }
4082: #endif
4083: if (bp[1] != '*' || bp + 1 >= limit)
4084: break;
4085: *comments = 1;
4086: bp += 2;
4087: while (bp + 1 < limit) {
4088: if (bp[0] == '*'
4089: && bp[1] == '\\' && bp[2] == '\n')
4090: newline_fix (bp + 1);
4091: if (bp[0] == '*' && bp[1] == '/')
4092: break;
4093: if (*bp == '\n') ++*newlines;
4094: bp++;
4095: }
4096: break;
4097: case '\'':
4098: case '\"':
4099: {
4100: int quotec;
4101: for (quotec = *bp++; bp + 1 < limit && *bp != quotec; bp++) {
4102: if (*bp == '\\') {
4103: bp++;
4104: if (*bp == '\n')
4105: ++*newlines;
4106: while (*bp == '\\' && bp[1] == '\n') {
4107: bp += 2;
4108: }
4109: } else if (*bp == '\n')
4110: ++*newlines;
4111: }
4112: }
4113: break;
4114: case ',':
4115: if ((*depthptr) == 0)
4116: return bp;
4117: break;
4118: }
4119: bp++;
4120: }
4121:
4122: return bp;
4123: }
4124:
4125: /* Discard comments and duplicate newlines
4126: in the string of length LENGTH at START,
4127: except inside of string constants.
4128: The string is copied into itself with its beginning staying fixed.
4129:
4130: NEWLINES is the number of newlines that must be duplicated.
4131: We assume that that much extra space is available past the end
4132: of the string. */
4133:
4134: int
4135: discard_comments (start, length, newlines)
4136: U_CHAR *start;
4137: int length;
4138: int newlines;
4139: {
4140: register U_CHAR *ibp;
4141: register U_CHAR *obp;
4142: register U_CHAR *limit;
4143: register int c;
4144:
4145: /* If we have newlines to duplicate, copy everything
4146: that many characters up. Then, in the second part,
4147: we will have room to insert the newlines
4148: while copying down.
4149: NEWLINES may actually be too large, because it counts
4150: newlines in string constants, and we don't duplicate those.
4151: But that does no harm. */
4152: if (newlines > 0) {
4153: ibp = start + length;
4154: obp = ibp + newlines;
4155: limit = start;
4156: while (limit != ibp)
4157: *--obp = *--ibp;
4158: }
4159:
4160: ibp = start + newlines;
4161: limit = start + length + newlines;
4162: obp = start;
4163:
4164: while (ibp < limit) {
4165: *obp++ = c = *ibp++;
4166: switch (c) {
4167: case '\n':
4168: /* Duplicate the newline. */
4169: *obp++ = '\n';
4170: break;
4171:
4172: case '/':
4173: if (*ibp == '\\' && ibp[1] == '\n')
4174: newline_fix (ibp);
4175: /* Delete any comment. */
4176: #ifdef CPLUSPLUS
4177: if (ibp[0] == '/') {
4178: obp--;
4179: ibp++;
4180: while (ibp < limit && *ibp++ != '\n') ;
4181: break;
4182: }
4183: #endif
4184: if (ibp[0] != '*' || ibp + 1 >= limit)
4185: break;
4186: obp--;
4187: ibp++;
4188: while (ibp + 1 < limit) {
4189: if (ibp[0] == '*'
4190: && ibp[1] == '\\' && ibp[2] == '\n')
4191: newline_fix (ibp + 1);
4192: if (ibp[0] == '*' && ibp[1] == '/')
4193: break;
4194: ibp++;
4195: }
4196: ibp += 2;
4197: break;
4198:
4199: case '\'':
4200: case '\"':
4201: /* Notice and skip strings, so that we don't
4202: think that comments start inside them,
4203: and so we don't duplicate newlines in them. */
4204: {
4205: int quotec = c;
4206: while (ibp < limit)
4207: {
4208: *obp++ = c = *ibp++;
4209: if (c == quotec)
4210: break;
4211: if (c == '\\' && ibp < limit) {
4212: while (*ibp == '\\' && ibp[1] == '\n')
4213: ibp += 2;
4214: *obp++ = *ibp++;
4215: }
4216: }
4217: }
4218: break;
4219: }
4220: }
4221:
4222: return obp - start;
4223: }
4224:
4225: /*
4226: * error - print error message and increment count of errors.
4227: */
4228: error (msg, arg1, arg2, arg3)
4229: U_CHAR *msg;
4230: {
4231: int i;
4232: FILE_BUF *ip = NULL;
4233:
4234: for (i = indepth; i >= 0; i--)
4235: if (instack[i].fname != NULL) {
4236: ip = &instack[i];
4237: break;
4238: }
4239:
4240: if (ip != NULL)
4241: fprintf (stderr, "%s:%d: ", ip->fname, ip->lineno);
4242: fprintf (stderr, msg, arg1, arg2, arg3);
4243: fprintf (stderr, "\n", msg);
4244: errors++;
4245: return 0;
4246: }
4247:
4248: /* Print error message but don't count it. */
4249:
4250: warning (msg, arg1, arg2, arg3)
4251: U_CHAR *msg;
4252: {
4253: int i;
4254: FILE_BUF *ip = NULL;
4255:
4256: for (i = indepth; i >= 0; i--)
4257: if (instack[i].fname != NULL) {
4258: ip = &instack[i];
4259: break;
4260: }
4261:
4262: if (ip != NULL)
4263: fprintf (stderr, "%s:%d: ", ip->fname, ip->lineno);
4264: fprintf (stderr, "warning: ");
4265: fprintf (stderr, msg, arg1, arg2, arg3);
4266: fprintf (stderr, "\n", msg);
4267: return 0;
4268: }
4269:
4270: error_with_line (line, msg, arg1, arg2, arg3)
4271: int line;
4272: U_CHAR *msg;
4273: {
4274: int i;
4275: FILE_BUF *ip = NULL;
4276:
4277: for (i = indepth; i >= 0; i--)
4278: if (instack[i].fname != NULL) {
4279: ip = &instack[i];
4280: break;
4281: }
4282:
4283: if (ip != NULL)
4284: fprintf (stderr, "%s:%d: ", ip->fname, line);
4285: fprintf (stderr, msg, arg1, arg2, arg3);
4286: fprintf (stderr, "\n", msg);
4287: errors++;
4288: return 0;
4289: }
4290:
4291: /* Return the line at which an error occurred.
4292: The error is not necessarily associated with the current spot
4293: in the input stack, so LINE says where. LINE will have been
4294: copied from ip->lineno for the current input level.
4295: If the current level is for a file, we return LINE.
4296: But if the current level is not for a file, LINE is meaningless.
4297: In that case, we return the lineno of the innermost file. */
4298: int
4299: line_for_error (line)
4300: int line;
4301: {
4302: int i;
4303: int line1 = line;
4304:
4305: for (i = indepth; i >= 0; ) {
4306: if (instack[i].fname != 0)
4307: return line1;
4308: i--;
4309: if (i < 0)
4310: return 0;
4311: line1 = instack[i].lineno;
4312: }
4313: }
4314:
4315: /*
4316: * If OBUF doesn't have NEEDED bytes after OPTR, make it bigger.
4317: *
4318: * As things stand, nothing is ever placed in the output buffer to be
4319: * removed again except when it's KNOWN to be part of an identifier,
4320: * so flushing and moving down everything left, instead of expanding,
4321: * should work ok.
4322: */
4323:
4324: int
4325: grow_outbuf (obuf, needed)
4326: register FILE_BUF *obuf;
4327: register int needed;
4328: {
4329: register U_CHAR *p;
4330: int minsize;
4331:
4332: if (obuf->length - (obuf->bufp - obuf->buf) > needed)
4333: return;
4334:
4335: /* Make it at least twice as big as it is now. */
4336: obuf->length *= 2;
4337: /* Make it have at least 150% of the free space we will need. */
4338: minsize = (3 * needed) / 2 + (obuf->bufp - obuf->buf);
4339: if (minsize > obuf->length)
4340: obuf->length = minsize;
4341:
4342: if ((p = (U_CHAR *) xrealloc (obuf->buf, obuf->length)) == NULL)
4343: memory_full ();
4344:
4345: obuf->bufp = p + (obuf->bufp - obuf->buf);
4346: obuf->buf = p;
4347: }
4348:
4349: /* Symbol table for macro names and special symbols */
4350:
4351: /*
4352: * install a name in the main hash table, even if it is already there.
4353: * name stops with first non alphanumeric, except leading '#'.
4354: * caller must check against redefinition if that is desired.
4355: * delete_macro () removes things installed by install () in fifo order.
4356: * this is important because of the `defined' special symbol used
4357: * in #if, and also if pushdef/popdef directives are ever implemented.
4358: *
4359: * If LEN is >= 0, it is the length of the name.
4360: * Otherwise, compute the length by scanning the entire name.
4361: *
4362: * If HASH is >= 0, it is the precomputed hash code.
4363: * Otherwise, compute the hash code.
4364: */
4365: HASHNODE *
4366: install (name, len, type, value, hash)
4367: U_CHAR *name;
4368: int len;
4369: enum node_type type;
4370: int value;
4371: int hash;
4372: /* watch out here if sizeof (U_CHAR *) != sizeof (int) */
4373: {
4374: register HASHNODE *hp;
4375: register int i, bucket;
4376: register U_CHAR *p, *q;
4377:
4378: if (len < 0) {
4379: p = name;
4380: while (is_idchar[*p])
4381: p++;
4382: len = p - name;
4383: }
4384:
4385: if (hash < 0)
4386: hash = hashf (name, len, HASHSIZE);
4387:
4388: i = sizeof (HASHNODE) + len + 1;
4389: hp = (HASHNODE *) xmalloc (i);
4390: bucket = hash;
4391: hp->bucket_hdr = &hashtab[bucket];
4392: hp->next = hashtab[bucket];
4393: hashtab[bucket] = hp;
4394: hp->prev = NULL;
4395: if (hp->next != NULL)
4396: hp->next->prev = hp;
4397: hp->type = type;
4398: hp->length = len;
4399: hp->value.ival = value;
4400: hp->name = ((U_CHAR *) hp) + sizeof (HASHNODE);
4401: p = hp->name;
4402: q = name;
4403: for (i = 0; i < len; i++)
4404: *p++ = *q++;
4405: hp->name[len] = 0;
4406: return hp;
4407: }
4408:
4409: /*
4410: * find the most recent hash node for name name (ending with first
4411: * non-identifier char) installed by install
4412: *
4413: * If LEN is >= 0, it is the length of the name.
4414: * Otherwise, compute the length by scanning the entire name.
4415: *
4416: * If HASH is >= 0, it is the precomputed hash code.
4417: * Otherwise, compute the hash code.
4418: */
4419: HASHNODE *
4420: lookup (name, len, hash)
4421: U_CHAR *name;
4422: int len;
4423: int hash;
4424: {
4425: register U_CHAR *bp;
4426: register HASHNODE *bucket;
4427:
4428: if (len < 0) {
4429: for (bp = name; is_idchar[*bp]; bp++) ;
4430: len = bp - name;
4431: }
4432:
4433: if (hash < 0)
4434: hash = hashf (name, len, HASHSIZE);
4435:
4436: bucket = hashtab[hash];
4437: while (bucket) {
4438: if (bucket->length == len && strncmp (bucket->name, name, len) == 0)
4439: return bucket;
4440: bucket = bucket->next;
4441: }
4442: return NULL;
4443: }
4444:
4445: /*
4446: * Delete a hash node. Some weirdness to free junk from macros.
4447: * More such weirdness will have to be added if you define more hash
4448: * types that need it.
4449: */
4450:
4451: /* Note that the DEFINITION of a macro is removed from the hash table
4452: but its storage is not freed. This would be a storage leak
4453: except that it is not reasonable to keep undefining and redefining
4454: large numbers of macros many times.
4455: In any case, this is necessary, because a macro can be #undef'd
4456: in the middle of reading the arguments to a call to it.
4457: If #undef freed the DEFINITION, that would crash. */
4458:
4459: delete_macro (hp)
4460: HASHNODE *hp;
4461: {
4462:
4463: if (hp->prev != NULL)
4464: hp->prev->next = hp->next;
4465: if (hp->next != NULL)
4466: hp->next->prev = hp->prev;
4467:
4468: /* make sure that the bucket chain header that
4469: the deleted guy was on points to the right thing afterwards. */
4470: if (hp == *hp->bucket_hdr)
4471: *hp->bucket_hdr = hp->next;
4472:
4473: #if 0
4474: if (hp->type == T_MACRO) {
4475: DEFINITION *d = hp->value.defn;
4476: struct reflist *ap, *nextap;
4477:
4478: for (ap = d->pattern; ap != NULL; ap = nextap) {
4479: nextap = ap->next;
4480: free (ap);
4481: }
4482: free (d);
4483: }
4484: #endif
4485: free (hp);
4486: }
4487:
4488: /*
4489: * return hash function on name. must be compatible with the one
4490: * computed a step at a time, elsewhere
4491: */
4492: int
4493: hashf (name, len, hashsize)
4494: register U_CHAR *name;
4495: register int len;
4496: int hashsize;
4497: {
4498: register int r = 0;
4499:
4500: while (len--)
4501: r = HASHSTEP (r, *name++);
4502:
4503: return MAKE_POS (r) % hashsize;
4504: }
4505:
4506: /* Dump all macro definitions as #defines to stdout. */
4507:
4508: dump_all_macros ()
4509: {
4510: int bucket;
4511:
4512: for (bucket = 0; bucket < HASHSIZE; bucket++) {
4513: register HASHNODE *hp;
4514:
4515: for (hp = hashtab[bucket]; hp; hp= hp->next) {
4516: if (hp->type == T_MACRO) {
4517: register DEFINITION *defn = hp->value.defn;
4518: struct reflist *ap;
4519: int offset;
4520: int concat;
4521:
4522:
4523: /* Print the definition of the macro HP. */
4524:
4525: printf ("#define %s", hp->name);
4526: if (defn->nargs >= 0) {
4527: int i;
4528:
4529: printf ("(");
4530: for (i = 0; i < defn->nargs; i++) {
4531: dump_arg_n (defn, i);
4532: if (i + 1 < defn->nargs)
4533: printf (", ");
4534: }
4535: printf (")");
4536: }
4537:
4538: printf (" ");
4539:
4540: offset = 0;
4541: concat = 0;
4542: for (ap = defn->pattern; ap != NULL; ap = ap->next) {
4543: dump_defn_1 (defn->expansion, offset, ap->nchars);
4544: if (ap->nchars != 0)
4545: concat = 0;
4546: offset += ap->nchars;
4547: if (ap->stringify)
4548: printf (" #");
4549: if (ap->raw_before && !concat)
4550: printf (" ## ");
4551: concat = 0;
4552: dump_arg_n (defn, ap->argno);
4553: if (ap->raw_after) {
4554: printf (" ## ");
4555: concat = 1;
4556: }
4557: }
4558: dump_defn_1 (defn->expansion, offset, defn->length - offset);
4559: printf ("\n");
4560: }
4561: }
4562: }
4563: return NULL;
4564: }
4565:
4566: /* Output to stdout a substring of a macro definition.
4567: BASE is the beginning of the definition.
4568: Output characters START thru LENGTH.
4569: Discard newlines outside of strings, thus
4570: converting funny-space markers to ordinary spaces. */
4571:
4572: dump_defn_1 (base, start, length)
4573: U_CHAR *base;
4574: int start;
4575: int length;
4576: {
4577: U_CHAR *p = base + start;
4578: U_CHAR *limit = base + start + length;
4579:
4580: while (p < limit) {
4581: if (*p != '\n')
4582: putchar (*p);
4583: else if (*p == '\"' || *p =='\'') {
4584: U_CHAR *p1 = skip_quoted_string (p, limit, 0, 0, 0);
4585: fwrite (p, p1 - p, 1, stdout);
4586: p = p1 - 1;
4587: }
4588: p++;
4589: }
4590: }
4591:
4592: /* Print the name of argument number ARGNUM of macro definition DEFN.
4593: Recall that DEFN->argnames contains all the arg names
4594: concatenated in reverse order with comma-space in between. */
4595:
4596: dump_arg_n (defn, argnum)
4597: DEFINITION *defn;
4598: int argnum;
4599: {
4600: register U_CHAR *p = defn->argnames;
4601: while (argnum + 1 < defn->nargs) {
4602: p = (U_CHAR *) index (p, ' ') + 1;
4603: argnum++;
4604: }
4605:
4606: while (*p && *p != ',') {
4607: putchar (*p);
4608: p++;
4609: }
4610: }
4611:
4612: /*
4613: * initialize random junk in the hash table and maybe other places
4614: */
4615: initialize_random_junk ()
4616: {
4617: register int i;
4618:
4619: /*
4620: * Set up is_idchar and is_idstart tables. These should be
4621: * faster than saying (is_alpha (c) || c == '_'), etc.
4622: * Must do set up these things before calling any routines tthat
4623: * refer to them.
4624: */
4625: for (i = 'a'; i <= 'z'; i++) {
4626: ++is_idchar[i - 'a' + 'A'];
4627: ++is_idchar[i];
4628: ++is_idstart[i - 'a' + 'A'];
4629: ++is_idstart[i];
4630: }
4631: for (i = '0'; i <= '9'; i++)
4632: ++is_idchar[i];
4633: ++is_idchar['_'];
4634: ++is_idstart['_'];
4635: ++is_idchar['$'];
4636: ++is_idstart['$'];
4637:
4638: /* horizontal space table */
4639: ++is_hor_space[' '];
4640: ++is_hor_space['\t'];
4641: ++is_hor_space['\v'];
4642: ++is_hor_space['\f'];
4643:
4644: ++is_space[' '];
4645: ++is_space['\t'];
4646: ++is_space['\v'];
4647: ++is_space['\f'];
4648: ++is_space['\n'];
4649:
4650: install ("__LINE__", -1, T_SPECLINE, 0, -1);
4651: install ("__DATE__", -1, T_DATE, 0, -1);
4652: install ("__FILE__", -1, T_FILE, 0, -1);
4653: install ("__VERSION__", -1, T_VERSION, 0, -1);
4654: install ("__TIME__", -1, T_TIME, 0, -1);
4655: install ("__STDC__", -1, T_CONST, 1, -1);
4656: /* install ("__GNU__", -1, T_CONST, 1, -1); */
4657: /* This is supplied using a -D by the compiler driver
4658: so that it is present only when truly compiling with GNU C. */
4659: }
4660:
4661: /*
4662: * process a given definition string, for initialization
4663: * If STR is just an identifier, define it with value 1.
4664: * If STR has anything after the identifier, then it should
4665: * be identifier-space-definition.
4666: */
4667: make_definition (str)
4668: U_CHAR *str;
4669: {
4670: FILE_BUF *ip;
4671: struct directive *kt;
4672: U_CHAR *buf, *p;
4673:
4674: buf = str;
4675: p = str;
4676: while (is_idchar[*p]) p++;
4677: if (*p == 0) {
4678: buf = (U_CHAR *) alloca (p - buf + 4);
4679: strcpy (buf, str);
4680: strcat (buf, " 1");
4681: }
4682:
4683: ip = &instack[++indepth];
4684: ip->fname = "*Initialization*";
4685:
4686: ip->buf = ip->bufp = buf;
4687: ip->length = strlen (buf);
4688: ip->lineno = 1;
4689: ip->macro = 0;
4690: ip->free = 0;
4691: ip->if_stack = if_stack;
4692:
4693: for (kt = directive_table; kt->type != T_DEFINE; kt++)
4694: ;
4695:
4696: /* pass NULL as output ptr to do_define since we KNOW it never
4697: does any output.... */
4698: do_define (buf, buf + strlen (buf) , NULL, kt);
4699: --indepth;
4700: }
4701:
4702: /* JF, this does the work for the -U option */
4703: make_undef (str)
4704: U_CHAR *str;
4705: {
4706: FILE_BUF *ip;
4707: struct directive *kt;
4708:
4709: ip = &instack[++indepth];
4710: ip->fname = "*undef*";
4711:
4712: ip->buf = ip->bufp = str;
4713: ip->length = strlen (str);
4714: ip->lineno = 1;
4715: ip->macro = 0;
4716: ip->free = 0;
4717: ip->if_stack = if_stack;
4718:
4719: for (kt = directive_table; kt->type != T_UNDEF; kt++)
4720: ;
4721:
4722: do_undef (str,str + strlen (str) - 1, NULL, kt);
4723: --indepth;
4724: }
4725:
4726: /* Add output to `deps_buffer' for the -M switch.
4727: STRING points to the text to be output.
4728: SIZE is the number of bytes, or 0 meaning output until a null.
4729: If SIZE is nonzero, we break the line first, if it is long enough. */
4730:
4731: deps_output (string, size)
4732: char *string;
4733: int size;
4734: {
4735: if (size != 0 && deps_column > 50)
4736: {
4737: deps_output ("\\\n ", 0);
4738: deps_column = 0;
4739: }
4740:
4741: if (size == 0)
4742: size = strlen (string);
4743:
4744: if (deps_size + size + 1 > deps_allocated_size)
4745: {
4746: deps_allocated_size = deps_size + size + 50;
4747: deps_allocated_size *= 2;
4748: deps_buffer = (char *) xrealloc (deps_buffer, deps_allocated_size);
4749: }
4750: bcopy (string, &deps_buffer[deps_size], size);
4751: deps_size += size;
4752: deps_column += size;
4753: deps_buffer[deps_size] = 0;
4754: }
4755:
4756: #ifndef BSD
4757: #ifndef BSTRING
4758:
4759: void
4760: bzero (b, length)
4761: register char *b;
4762: register int length;
4763: {
4764: #ifdef VMS
4765: short zero = 0;
4766: long max_str = 65535;
4767:
4768: while (length > max_str)
4769: {
4770: (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
4771: length -= max_str;
4772: b += max_str;
4773: }
4774: (void) LIB$MOVC5 (&zero, &zero, &zero, &length, b);
4775: #else
4776: while (length-- > 0)
4777: *b++ = 0;
4778: #endif /* not VMS */
4779: }
4780:
4781: void
4782: bcopy (b1, b2, length)
4783: register char *b1;
4784: register char *b2;
4785: register int length;
4786: {
4787: #ifdef VMS
4788: long max_str = 65535;
4789:
4790: while (length > max_str)
4791: {
4792: (void) LIB$MOVC3 (&max_str, b1, b2);
4793: length -= max_str;
4794: b1 += max_str;
4795: b2 += max_str;
4796: }
4797: (void) LIB$MOVC3 (&length, b1, b2);
4798: #else
4799: while (length-- > 0)
4800: *b2++ = *b1++;
4801: #endif /* not VMS */
4802: }
4803:
4804: int
4805: bcmp (b1, b2, length) /* This could be a macro! */
4806: register char *b1;
4807: register char *b2;
4808: register int length;
4809: {
4810: #ifdef VMS
4811: struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
4812: struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
4813:
4814: return STR$COMPARE (&src1, &src2);
4815: #else
4816: while (length-- > 0)
4817: if (*b1++ != *b2++)
4818: return 1;
4819:
4820: return 0;
4821: #endif /* not VMS */
4822: }
4823: #endif /* not BSTRING */
4824: #endif /* not BSD */
4825:
4826:
4827: void
4828: fatal (str, arg)
4829: char *str, *arg;
4830: {
4831: fprintf (stderr, "%s: ", progname);
4832: fprintf (stderr, str, arg);
4833: fprintf (stderr, "\n");
4834: exit (FATAL_EXIT_CODE);
4835: }
4836:
4837: void
4838: perror_with_name (name)
4839: char *name;
4840: {
4841: extern int errno, sys_nerr;
4842: extern char *sys_errlist[];
4843:
4844: fprintf (stderr, "%s: ", progname);
4845: if (errno < sys_nerr)
4846: fprintf (stderr, "%s for `%s'\n", sys_errlist[errno], name);
4847: else
4848: fprintf (stderr, "cannot open `%s'\n", sys_errlist[errno], name);
4849: }
4850:
4851: void
4852: pfatal_with_name (name)
4853: char *name;
4854: {
4855: perror_with_name (name);
4856: exit (FATAL_EXIT_CODE);
4857: }
4858:
4859:
4860: void
4861: memory_full ()
4862: {
4863: fatal ("Memory exhausted.");
4864: }
4865:
4866:
4867: char *
4868: xmalloc (size)
4869: int size;
4870: {
4871: extern char *malloc ();
4872: register char *ptr = malloc (size);
4873: if (ptr != 0) return (ptr);
4874: memory_full ();
4875: /*NOTREACHED*/
4876: }
4877:
4878: char *
4879: xrealloc (old, size)
4880: char *old;
4881: int size;
4882: {
4883: extern char *realloc ();
4884: register char *ptr = realloc (old, size);
4885: if (ptr != 0) return (ptr);
4886: memory_full ();
4887: /*NOTREACHED*/
4888: }
4889:
4890: char *
4891: xcalloc (number, size)
4892: int number, size;
4893: {
4894: extern char *malloc ();
4895: register int total = number * size;
4896: register char *ptr = malloc (total);
4897: if (ptr != 0)
4898: {
4899: if (total > 100)
4900: bzero (ptr, total);
4901: else {
4902: /* It's not too long, so loop, zeroing by longs.
4903: It must be safe because malloc values are always well aligned. */
4904: register long *zp = (long *) ptr;
4905: register long *zl = (long *) (ptr + total - 4);
4906: register int i = total - 4;
4907: while (zp < zl)
4908: *zp++ = 0;
4909: if (i < 0)
4910: i = 0;
4911: while (i < total)
4912: ptr[i++] = 0;
4913: }
4914: return ptr;
4915: }
4916: memory_full ();
4917: /*NOTREACHED*/
4918: }
4919:
4920:
4921: /* Get the file-mode and data size of the file open on FD
4922: and store them in *MODE_POINTER and *SIZE_POINTER. */
4923:
4924: int
4925: file_size_and_mode (fd, mode_pointer, size_pointer)
4926: int fd;
4927: int *mode_pointer;
4928: long int *size_pointer;
4929: {
4930: struct stat sbuf;
4931:
4932: if (fstat (fd, &sbuf) < 0) return (-1);
4933: #ifdef VMS
4934: #ifdef __GNUC__
4935: #ifdef stat_alignment_fix
4936: /* Fix the size data in the stat buffer (this is temporary!) */
4937: sbuf.st_size = (stat_alignment_fix(&(sbuf))->st_size);
4938: #endif stat_alignment_fix
4939: #endif __GNUC__
4940: #endif VMS
4941: if (mode_pointer) *mode_pointer = sbuf.st_mode;
4942: if (size_pointer) *size_pointer = sbuf.st_size;
4943: return 0;
4944: }
4945:
4946: #ifdef VMS
4947:
4948: /* Under VMS we need to fix up the "include" specification
4949: filename so that everything following the 1st slash is
4950: changed into its correct VMS file specification. */
4951:
4952: hack_vms_include_specification (fname)
4953: char *fname;
4954: {
4955: register char *cp, *cp1, *cp2;
4956: char Local[512];
4957: extern char *index (), *rindex ();
4958:
4959: /* Ignore leading "./"s */
4960: while (fname[0] == '.' && fname[1] == '/')
4961: strcpy (fname, fname+2);
4962: /* Look for the boundary between the VMS and UNIX filespecs */
4963: cp = rindex (fname, ']'); /* Look for end of dirspec. */
4964: if (cp == 0) cp == rindex (fname, '>'); /* ... Ditto */
4965: if (cp == 0) cp == rindex (fname, ':'); /* Look for end of devspec. */
4966: if (cp) {
4967: cp++;
4968: } else {
4969: cp = index (fname, '/'); /* Look for the "/" */
4970: }
4971: /* See if we found that 1st slash */
4972: if (cp == 0) return; /* Nothing to do!!! */
4973: if (*cp != '/') return; /* Nothing to do!!! */
4974: /* Point to the UNIX filename part (which needs to be fixed!) */
4975: cp1 = cp+1;
4976: /* If the directory spec is not rooted, we can just copy
4977: the UNIX filename part and we are done */
4978: if (((cp - fname) > 2)
4979: && ((cp[-1] == ']') || (cp[-1] == '>'))
4980: && (cp[-2] != '.')) {
4981: strcpy (cp, cp1);
4982: return;
4983: }
4984: /* If there are no other slashes then the filename will be
4985: in the "root" directory. Otherwise, we need to add
4986: directory specifications. */
4987: if (index (cp1, '/') == 0) {
4988: /* Just add "[000000]" as the directory string */
4989: strcpy (Local, "[000000]");
4990: cp2 = Local + strlen (Local);
4991: } else {
4992: /* Open the directory specification */
4993: cp2 = Local;
4994: *cp2++ = '[';
4995: /* As long as there are still subdirectories to add, do them. */
4996: while (index (cp1, '/') != 0) {
4997: /* If this token is "." we can ignore it */
4998: if ((cp1[0] == '.') && (cp1[1] == '/')) {
4999: cp1 += 2;
5000: continue;
5001: }
5002: /* Add a subdirectory spec. */
5003: if (cp2 != Local+1) *cp2++ = '.';
5004: /* If this is ".." then the spec becomes "-" */
5005: if ((cp1[0] == '.') && (cp1[1] == '.') && (cp[2] == '/')) {
5006: /* Add "-" and skip the ".." */
5007: *cp2++ = '-';
5008: cp1 += 3;
5009: continue;
5010: }
5011: /* Copy the subdirectory */
5012: while (*cp1 != '/') *cp2++= *cp1++;
5013: cp1++; /* Skip the "/" */
5014: }
5015: /* Close the directory specification */
5016: *cp2++ = ']';
5017: }
5018: /* Now add the filename */
5019: while (*cp1) *cp2++ = *cp1++;
5020: *cp2 = 0;
5021: /* Now append it to the original VMS spec. */
5022: strcpy (cp, Local);
5023: return;
5024: }
5025: #endif /* VMS */
5026:
5027: #ifdef VMS
5028:
5029: /* These are the read/write replacement routines for
5030: VAX-11 "C". They make read/write behave enough
5031: like their UNIX counterparts that CCCP will work */
5032:
5033: int
5034: read (fd, buf, size)
5035: int fd;
5036: char *buf;
5037: int size;
5038: {
5039: #undef read /* Get back the REAL read routine */
5040: register int i;
5041: register int total = 0;
5042:
5043: /* Read until the buffer is exhausted */
5044: while (size > 0) {
5045: /* Limit each read to 32KB */
5046: i = (size > (32*1024)) ? (32*1024) : size;
5047: i = read (fd, buf, i);
5048: if (i <= 0) {
5049: if (i == 0) return (total);
5050: return(i);
5051: }
5052: /* Account for this read */
5053: total += i;
5054: buf += i;
5055: size -= i;
5056: }
5057: return (total);
5058: }
5059:
5060: int
5061: write (fd, buf, size)
5062: int fd;
5063: char *buf;
5064: int size;
5065: {
5066: #undef write /* Get back the REAL write routine */
5067: int i;
5068: int j;
5069:
5070: /* Limit individual writes to 32Kb */
5071: i = size;
5072: while (i > 0) {
5073: j = (i > (32*1024)) ? (32*1024) : i;
5074: if (write (fd, buf, j) < 0) return (-1);
5075: /* Account for the data written */
5076: buf += j;
5077: i -= j;
5078: }
5079: return (size);
5080: }
5081:
5082: #endif /* VMS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.