OSDN Git Service

Initial Import
[nethackexpress/trunk.git] / sys / unix / cpp2.shr
1 # This is a shell archive.  Save it in a file, remove anything before
2 # this line, and then unpack it by entering "sh file".  Note, it may
3 # create directories; files and directories will be owned by you and
4 # have default permissions.
5 #
6 # This archive contains:
7 #
8 #       cpp1.c
9 #       cpp3.c
10 #       cpp4.c
11 #
12 echo x - cpp1.c
13 sed 's/^X//' >cpp1.c << 'END-of-cpp1.c'
14 X/*
15 X * CPP main program.
16 X *
17 X * Edit history
18 X * 21-May-84   MM      "Field test" release
19 X * 23-May-84   MM      Some minor hacks.
20 X * 30-May-84   ARF     Didn't get enough memory for __DATE__
21 X *                     Added code to read stdin if no input
22 X *                     files are provided.
23 X * 29-Jun-84   MM      Added ARF's suggestions, Unixifying cpp.
24 X * 11-Jul-84   MM      "Official" first release (that's what I thought!)
25 X * 22-Jul-84   MM/ARF/SCK Fixed line number bugs, added cpp recognition
26 X *                     of #line, fixed problems with #include.
27 X * 23-Jul-84   MM      More (minor) include hacking, some documentation.
28 X *                     Also, redid cpp's #include files
29 X * 25-Jul-84   MM      #line filename isn't used for #include searchlist
30 X *                     #line format is <number> <optional name>
31 X * 25-Jul-84   ARF/MM  Various bugs, mostly serious.  Removed homemade doprint
32 X * 01-Aug-84   MM      Fixed recursion bug, remove extra newlines and
33 X *                     leading whitespace from cpp output.
34 X * 02-Aug-84   MM      Hacked (i.e. optimized) out blank lines and unneeded
35 X *                     whitespace in general.  Cleaned up unget()'s.
36 X * 03-Aug-84   Keie    Several bug fixes from Ed Keizer, Vrije Universitet.
37 X *                     -- corrected arg. count in -D and pre-defined
38 X *                     macros.  Also, allow \n inside macro actual parameter
39 X *                     lists.
40 X * 06-Aug-84   MM      If debugging, dump the preset vector at startup.
41 X * 12-Aug-84   MM/SCK  Some small changes from Sam Kendall
42 X * 15-Aug-84   Keie/MM cerror, cwarn, etc. take a single string arg.
43 X *                     cierror, etc. take a single int. arg.
44 X *                     changed LINE_PREFIX slightly so it can be
45 X *                     changed in the makefile.
46 X * 31-Aug-84   MM      USENET net.sources release.
47 X *  7-Sep-84   SCH/ado Lint complaints
48 X * 10-Sep-84   Keie    Char's can't be signed in some implementations
49 X * 11-Sep-84   ado     Added -C flag, pathological line number fix
50 X * 13-Sep-84   ado     Added -E flag (does nothing) and "-" file for stdin.
51 X * 14-Sep-84   MM      Allow # 123 as a synonym for #line 123
52 X * 19-Sep-84   MM      scanid always reads to token, make sure #line is
53 X *                     written to a new line, even if -C switch given.
54 X *                     Also, cpp - - reads stdin, writes stdout.
55 X * 03-Oct-84   ado/MM  Several changes to line counting and keepcomments
56 X *                     stuff.  Also a rewritten control() hasher -- much
57 X *                     simpler and no less "perfect". Note also changes
58 X *                     in cpp3.c to fix numeric scanning.
59 X * 04-Oct-84   MM      Added recognition of macro formal parameters if
60 X *                     they are the only thing in a string, per the
61 X *                     draft standard.
62 X * 08-Oct-84   MM      One more attack on scannumber
63 X * 15-Oct-84   MM/ado  Added -N to disable predefined symbols.  Fixed
64 X *                     linecount if COMMENT_INVISIBLE enabled.
65 X * 22-Oct-84   MM      Don't evaluate the #if/#ifdef argument if
66 X *                     compilation is supressed.  This prevents
67 X *                     unnecessary error messages in sequences such as
68 X *                         #ifdef FOO          -- undefined
69 X *                         #if FOO == 10       -- shouldn't print warning
70 X * 25-Oct-84   MM      Fixed bug in false ifdef supression.  On vms,
71 X *                     #include <foo> should open foo.h -- this duplicates
72 X *                     the behavior of Vax-C
73 X * 31-Oct-84   ado/MM  Parametized $ in indentifiers.  Added a better
74 X *                     token concatenator and took out the trial
75 X *                     concatenation code.  Also improved #ifdef code
76 X *                     and cleaned up the macro recursion tester.
77 X *  2-Nov-84   MM/ado  Some bug fixes in token concatenation, also
78 X *                     a variety of minor (uninteresting) hacks.
79 X *  6-Nov-84   MM      Happy Birthday.  Broke into 4 files and added
80 X *                     #if sizeof (basic_types)
81 X *  9-Nov-84   MM      Added -S* for pointer type sizes
82 X * 13-Nov-84   MM      Split cpp1.c, added vms defaulting
83 X * 23-Nov-84   MM/ado  -E supresses error exit, added CPP_INCLUDE,
84 X *                     fixed strncpy bug.
85 X *  3-Dec-84   ado/MM  Added OLD_PREPROCESSOR
86 X *  7-Dec-84   MM      Stuff in Nov 12 Draft Standard
87 X * 17-Dec-84   george  Fixed problems with recursive macros
88 X * 17-Dec-84   MM      Yet another attack on #if's (f/t)level removed.
89 X * 07-Jan-85   ado     Init defines before doing command line options
90 X *                     so -Uunix works.
91 X */
92 X
93 X/*)BUILD
94 X       $(PROGRAM)      = cpp
95 X       $(FILES)        = { cpp1 cpp2 cpp3 cpp4 cpp5 cpp6 }
96 X       $(INCLUDE)      = { cppdef.h cpp.h }
97 X       $(STACK)        = 2000
98 X       $(TKBOPTIONS)   = {
99 X               STACK   = 2000
100 X       }
101 X*/
102 X
103 X#ifdef DOCUMENTATION
104 X
105 Xtitle  cpp             C Pre-Processor
106 Xindex                  C pre-processor
107 X
108 Xsynopsis
109 X       .s.nf
110 X       cpp [-options] [infile [outfile]]
111 X       .s.f
112 Xdescription
113 X
114 X       CPP reads a C source file, expands macros and include
115 X       files, and writes an input file for the C compiler.
116 X       If no file arguments are given, CPP reads from stdin
117 X       and writes to stdout.  If one file argument is given,
118 X       it will define the input file, while two file arguments
119 X       define both input and output files.  The file name "-"
120 X       is a synonym for stdin or stdout as appropriate.
121 X
122 X       The following options are supported.  Options may
123 X       be given in either case.
124 X       .lm +16
125 X       .p -16
126 X       -C              If set, source-file comments are written
127 X       to the output file.  This allows the output of CPP to be
128 X       used as the input to a program, such as lint, that expects
129 X       commands embedded in specially-formatted comments.
130 X       .p -16
131 X       -Dname=value    Define the name as if the programmer wrote
132 X
133 X           #define name value
134 X
135 X       at the start of the first file.  If "=value" is not
136 X       given, a value of "1" will be used.
137 X
138 X       On non-unix systems, all alphabetic text will be forced
139 X       to upper-case.
140 X       .p -16
141 X       -E              Always return "success" to the operating
142 X       system, even if errors were detected.  Note that some fatal
143 X       errors, such as a missing #include file, will terminate
144 X       CPP, returning "failure" even if the -E option is given.
145 X       .p -16
146 X       -Idirectory     Add this directory to the list of
147 X       directories searched for #include "..." and #include <...>
148 X       commands.  Note that there is no space between the
149 X       "-I" and the directory string.  More than one -I command
150 X       is permitted.  On non-Unix systems "directory" is forced
151 X       to upper-case.
152 X       .p -16
153 X       -N              CPP normally predefines some symbols defining
154 X       the target computer and operating system.  If -N is specified,
155 X       no symbols will be predefined.  If -N -N is specified, the
156 X       "always present" symbols, __LINE__, __FILE__, and __DATE__
157 X       are not defined.
158 X       .p -16
159 X       -Stext          CPP normally assumes that the size of
160 X       the target computer's basic variable types is the same as the size
161 X       of these types of the host computer.  (This can be overridden
162 X       when CPP is compiled, however.)  The -S option allows dynamic
163 X       respecification of these values.  "text" is a string of
164 X       numbers, separated by commas, that specifies correct sizes.
165 X       The sizes must be specified in the exact order:
166 X
167 X           char short int long float double
168 X
169 X       If you specify the option as "-S*text", pointers to these
170 X       types will be specified.  -S* takes one additional argument
171 X       for pointer to function (e.g. int (*)())
172 X
173 X       For example, to specify sizes appropriate for a PDP-11,
174 X       you would write:
175 X
176 X              c s i l f d func
177 X            -S1,2,2,2,4,8,
178 X           -S*2,2,2,2,2,2,2
179 X
180 X       Note that all values must be specified.
181 X       .p -16
182 X       -Uname          Undefine the name as if
183 X
184 X           #undef name
185 X
186 X       were given.  On non-Unix systems, "name" will be forced to
187 X       upper-case.
188 X       .p -16
189 X       -Xnumber        Enable debugging code.  If no value is
190 X       given, a value of 1 will be used.  (For maintenence of
191 X       CPP only.)
192 X       .s.lm -16
193 X
194 XPre-Defined Variables
195 X
196 X       When CPP begins processing, the following variables will
197 X       have been defined (unless the -N option is specified):
198 X       .s
199 X       Target computer (as appropriate):
200 X       .s
201 X           pdp11, vax, M68000 m68000 m68k
202 X       .s
203 X       Target operating system (as appropriate):
204 X       .s
205 X           rsx, rt11, vms, unix
206 X       .s
207 X       Target compiler (as appropriate):
208 X       .s
209 X           decus, vax11c
210 X       .s
211 X       The implementor may add definitions to this list.
212 X       The default definitions match the definition of the
213 X       host computer, operating system, and C compiler.
214 X       .s
215 X       The following are always available unless undefined (or
216 X       -N was specified twice):
217 X       .lm +16
218 X       .p -12
219 X       __FILE__        The input (or #include) file being compiled
220 X       (as a quoted string).
221 X       .p -12
222 X       __LINE__        The line number being compiled.
223 X       .p -12
224 X       __DATE__        The date and time of compilation as
225 X       a Unix ctime quoted string (the trailing newline is removed).
226 X       Thus,
227 X       .s
228 X           printf("Bug at line %s,", __LINE__);
229 X           printf(" source file %s", __FILE__);
230 X           printf(" compiled on %s", __DATE__);
231 X       .s.lm -16
232 X
233 XDraft Proposed Ansi Standard Considerations
234 X
235 X       The current version of the Draft Proposed Standard
236 X       explicitly states that "readers are requested not to specify
237 X       or claim conformance to this draft."  Readers and users
238 X       of Decus CPP should not assume that Decus CPP conforms
239 X       to the standard, or that it will conform to the actual
240 X       C Language Standard.
241 X
242 X       When CPP is itself compiled, many features of the Draft
243 X       Proposed Standard that are incompatible with existing
244 X       preprocessors may be disabled.  See the comments in CPP's
245 X       source for details.
246 X
247 X       The latest version of the Draft Proposed Standard (as reflected
248 X       in Decus CPP) is dated November 12, 1984.
249 X
250 X       Comments are removed from the input text.  The comment
251 X       is replaced by a single space character.  The -C option
252 X       preserves comments, writing them to the output file.
253 X
254 X       The '$' character is considered to be a letter.  This is
255 X       a permitted extension.
256 X
257 X       The following new features of C are processed by CPP:
258 X       .s.comment Note: significant spaces, not tabs, .br quotes #if, #elif
259 X       .br;####_#elif expression    (_#else _#if)
260 X       .br;####'_\xNNN'             (Hexadecimal constant)
261 X       .br;####'_\a'                (Ascii BELL)
262 X       .br;####'_\v'                (Ascii Vertical Tab)
263 X       .br;####_#if defined NAME    1 if defined, 0 if not
264 X       .br;####_#if defined (NAME)  1 if defined, 0 if not  
265 X       .br;####_#if sizeof (basic type)
266 X       .br;####unary +
267 X       .br;####123U, 123LU          Unsigned ints and longs.
268 X       .br;####12.3L                Long double numbers
269 X       .br;####token_#token         Token concatenation
270 X       .br;####_#include token      Expands to filename
271 X
272 X       The Draft Proposed Standard has extended C, adding a constant
273 X       string concatenation operator, where
274 X
275 X           "foo" "bar"
276 X
277 X       is regarded as the single string "foobar".  (This does not
278 X       affect CPP's processing but does permit a limited form of
279 X       macro argument substitution into strings as will be discussed.)
280 X
281 X       The Standard Committee plans to add token concatenation
282 X       to #define command lines.  One suggested implementation
283 X       is as follows:  the sequence "Token1#Token2" is treated
284 X       as if the programmer wrote "Token1Token2".  This could
285 X       be used as follows:
286 X
287 X           #line 123
288 X           #define ATLINE foo#__LINE__
289 X
290 X       ATLINE would be defined as foo123.
291 X
292 X       Note that "Token2" must either have the format of an
293 X       identifier or be a string of digits.  Thus, the string
294 X
295 X           #define ATLINE foo#1x3
296 X
297 X       generates two tokens: "foo1" and "x3".
298 X
299 X       If the tokens T1 and T2 are concatenated into T3,
300 X       this implementation operates as follows:
301 X
302 X         1. Expand T1 if it is a macro.
303 X         2. Expand T2 if it is a macro.
304 X         3. Join the tokens, forming T3.
305 X         4. Expand T3 if it is a macro.
306 X
307 X       A macro formal parameter will be substituted into a string
308 X       or character constant if it is the only component of that
309 X       constant:
310 X
311 X           #define VECSIZE 123
312 X           #define vprint(name, size) \
313 X             printf("name" "[" "size" "] = {\n")
314 X             ... vprint(vector, VECSIZE);
315 X
316 X       expands (effectively) to
317 X
318 X             vprint("vector[123] = {\n");
319 X
320 X       Note that this will be useful if your C compiler supports
321 X       the new string concatenation operation noted above.
322 X       As implemented here, if you write
323 X
324 X           #define string(arg) "arg"
325 X             ... string("foo") ...
326 X
327 X       This implementation generates "foo", rather than the strictly
328 X       correct ""foo"" (which will probably generate an error message).
329 X       This is, strictly speaking, an error in CPP and may be removed
330 X       from future releases.
331 X
332 Xerror messages
333 X
334 X       Many.  CPP prints warning or error messages if you try to
335 X       use multiple-byte character constants (non-transportable)
336 X       if you #undef a symbol that was not defined, or if your
337 X       program has potentially nested comments.
338 X
339 Xauthor
340 X
341 X       Martin Minow
342 X
343 Xbugs
344 X
345 X       The #if expression processor uses signed integers only.
346 X       I.e, #if 0xFFFFu < 0 may be TRUE.
347 X
348 X#endif
349 X\f
350 X#include       <stdio.h>
351 X#include       <ctype.h>
352 X#include       "cppdef.h"
353 X#include       "cpp.h"
354 X
355 X/*
356 X * Commonly used global variables:
357 X * line                is the current input line number.
358 X * wrongline   is set in many places when the actual output
359 X *             line is out of sync with the numbering, e.g,
360 X *             when expanding a macro with an embedded newline.
361 X *
362 X * token       holds the last identifier scanned (which might
363 X *             be a candidate for macro expansion).
364 X * errors      is the running cpp error counter.
365 X * infile      is the head of a linked list of input files (extended by
366 X *             #include and macros being expanded).  infile always points
367 X *             to the current file/macro.  infile->parent to the includer,
368 X *             etc.  infile->fd is NULL if this input stream is a macro.
369 X */
370 Xint            line;                   /* Current line number          */
371 Xint            wrongline;              /* Force #line to compiler      */
372 Xchar           token[IDMAX + 1];       /* Current input token          */
373 Xint            errors;                 /* cpp error counter            */
374 XFILEINFO       *infile = NULL;         /* Current input file           */
375 X#if DEBUG
376 Xint            debug;                  /* TRUE if debugging now        */
377 X#endif
378 X/*
379 X * This counter is incremented when a macro expansion is initiated.
380 X * If it exceeds a built-in value, the expansion stops -- this tests
381 X * for a runaway condition:
382 X *     #define X Y
383 X *     #define Y X
384 X *     X
385 X * This can be disabled by falsifying rec_recover.  (Nothing does this
386 X * currently: it is a hook for an eventual invocation flag.)
387 X */
388 Xint            recursion;              /* Infinite recursion counter   */
389 Xint            rec_recover = TRUE;     /* Unwind recursive macros      */
390 X
391 X/*
392 X * instring is set TRUE when a string is scanned.  It modifies the
393 X * behavior of the "get next character" routine, causing all characters
394 X * to be passed to the caller (except <DEF_MAGIC>).  Note especially that
395 X * comments and \<newline> are not removed from the source.  (This
396 X * prevents cpp output lines from being arbitrarily long).
397 X *
398 X * inmacro is set by #define -- it absorbs comments and converts
399 X * form-feed and vertical-tab to space, but returns \<newline>
400 X * to the caller.  Strictly speaking, this is a bug as \<newline>
401 X * shouldn't delimit tokens, but we'll worry about that some other
402 X * time -- it is more important to prevent infinitly long output lines.
403 X *
404 X * instring and inmarcor are parameters to the get() routine which
405 X * were made global for speed.
406 X */
407 Xint            instring = FALSE;       /* TRUE if scanning string      */
408 Xint            inmacro = FALSE;        /* TRUE if #defining a macro    */
409 X
410 X/*
411 X * work[] and workp are used to store one piece of text in a temporay
412 X * buffer.  To initialize storage, set workp = work.  To store one
413 X * character, call save(c);  (This will fatally exit if there isn't
414 X * room.)  To terminate the string, call save(EOS).  Note that
415 X * the work buffer is used by several subroutines -- be sure your
416 X * data won't be overwritten.  The extra byte in the allocation is
417 X * needed for string formal replacement.
418 X */
419 Xchar           work[NWORK + 1];        /* Work buffer                  */
420 Xchar           *workp;                 /* Work buffer pointer          */
421 X
422 X/*
423 X * keepcomments is set TRUE by the -C option.  If TRUE, comments
424 X * are written directly to the output stream.  This is needed if
425 X * the output from cpp is to be passed to lint (which uses commands
426 X * embedded in comments).  cflag contains the permanent state of the
427 X * -C flag.  keepcomments is always falsified when processing #control
428 X * commands and when compilation is supressed by a false #if
429 X *
430 X * If eflag is set, CPP returns "success" even if non-fatal errors
431 X * were detected.
432 X *
433 X * If nflag is non-zero, no symbols are predefined except __LINE__.
434 X * __FILE__, and __DATE__.  If nflag > 1, absolutely no symbols
435 X * are predefined.
436 X */
437 Xint            keepcomments = FALSE;   /* Write out comments flag      */
438 Xint            cflag = FALSE;          /* -C option (keep comments)    */
439 Xint            eflag = FALSE;          /* -E option (never fail)       */
440 Xint            nflag = 0;              /* -N option (no predefines)    */
441 X
442 X/*
443 X * ifstack[] holds information about nested #if's.  It is always
444 X * accessed via *ifptr.  The information is as follows:
445 X *     WAS_COMPILING   state of compiling flag at outer level.
446 X *     ELSE_SEEN       set TRUE when #else seen to prevent 2nd #else.
447 X *     TRUE_SEEN       set TRUE when #if or #elif succeeds
448 X * ifstack[0] holds the compiling flag.  It is TRUE if compilation
449 X * is currently enabled.  Note that this must be initialized TRUE.
450 X */
451 Xchar           ifstack[BLK_NEST] = { TRUE };   /* #if information      */
452 Xchar           *ifptr = ifstack;               /* -> current ifstack[] */
453 X
454 X/*
455 X * incdir[] stores the -i directories (and the system-specific
456 X * #include <...> directories.
457 X */
458 Xchar   *incdir[NINCLUDE];              /* -i directories               */
459 Xchar   **incend = incdir;              /* -> free space in incdir[]    */
460 X
461 X/*
462 X * This is the table used to predefine target machine and operating
463 X * system designators.  It may need hacking for specific circumstances.
464 X * Note: it is not clear that this is part of the Ansi Standard.
465 X * The -N option supresses preset definitions.
466 X */
467 Xchar   *preset[] = {                   /* names defined at cpp start   */
468 X#ifdef MACHINE
469 X       MACHINE,
470 X#endif
471 X#ifdef SYSTEM
472 X       SYSTEM,
473 X#endif
474 X#ifdef COMPILER
475 X       COMPILER,
476 X#endif
477 X#if    DEBUG
478 X       "decus_cpp",                    /* Ourselves!                   */
479 X#endif
480 X       NULL                            /* Must be last                 */
481 X};
482 X
483 X/*
484 X * The value of these predefined symbols must be recomputed whenever
485 X * they are evaluated.  The order must not be changed.
486 X */
487 Xchar   *magic[] = {                    /* Note: order is important     */
488 X       "__LINE__",
489 X       "__FILE__",
490 X       NULL                            /* Must be last                 */
491 X};
492 X\f
493 Xmain(argc, argv)
494 Xint            argc;
495 Xchar           *argv[];
496 X{
497 X       register int    i;
498 X
499 X#if HOST == SYS_VMS
500 X       argc = getredirection(argc, argv);      /* vms >file and <file  */
501 X#endif
502 X       initdefines();                          /* O.S. specific def's  */
503 X       i = dooptions(argc, argv);              /* Command line -flags  */
504 X       switch (i) {
505 X       case 3:
506 X           /*
507 X            * Get output file, "-" means use stdout.
508 X            */
509 X           if (!streq(argv[2], "-")) {
510 X#if HOST == SYS_VMS
511 X               /*
512 X                * On vms, reopen stdout with "vanilla rms" attributes.
513 X                */
514 X               if ((i = creat(argv[2], 0, "rat=cr", "rfm=var")) == -1
515 X                || dup2(i, fileno(stdout)) == -1) {
516 X#else
517 X               if (freopen(argv[2], "w", stdout) == NULL) {
518 X#endif
519 X                   perror(argv[2]);
520 X                   cerror("Can't open output file \"%s\"", argv[2]);
521 X                   exit(IO_ERROR);
522 X               }
523 X           }                           /* Continue by opening input    */
524 X       case 2:                         /* One file -> stdin            */
525 X           /*
526 X            * Open input file, "-" means use stdin.
527 X            */
528 X           if (!streq(argv[1], "-")) {
529 X               if (freopen(argv[1], "r", stdin) == NULL) {
530 X                   perror(argv[1]);
531 X                   cerror("Can't open input file \"%s\"", argv[1]);
532 X                   exit(IO_ERROR);
533 X               }
534 X               strcpy(work, argv[1]);  /* Remember input filename      */
535 X               break;
536 X           }                           /* Else, just get stdin         */
537 X       case 0:                         /* No args?                     */
538 X       case 1:                         /* No files, stdin -> stdout    */
539 X#if HOST == SYS_UNIX
540 X           work[0] = EOS;              /* Unix can't find stdin name   */
541 X#else
542 X           fgetname(stdin, work);      /* Vax-11C, Decus C know name   */
543 X#endif
544 X           break;
545 X
546 X       default:
547 X           exit(IO_ERROR);             /* Can't happen                 */
548 X       }
549 X       setincdirs();                   /* Setup -I include directories */
550 X       addfile(stdin, work);           /* "open" main input file       */
551 X#if DEBUG
552 X       if (debug > 0)
553 X           dumpdef("preset #define symbols");
554 X#endif
555 X       cppmain();                      /* Process main file            */
556 X       if ((i = (ifptr - &ifstack[0])) != 0) {
557 X#if OLD_PREPROCESSOR
558 X           ciwarn("Inside #ifdef block at end of input, depth = %d", i);
559 X#else
560 X           cierror("Inside #ifdef block at end of input, depth = %d", i);
561 X#endif
562 X       }
563 X       fclose(stdout);
564 X       if (errors > 0) {
565 X           fprintf(stderr, (errors == 1)
566 X               ? "%d error in preprocessor\n"
567 X               : "%d errors in preprocessor\n", errors);
568 X           if (!eflag)
569 X               exit(IO_ERROR);
570 X       }
571 X       exit(IO_NORMAL);                /* No errors or -E option set   */
572 X}
573 X\f
574 XFILE_LOCAL
575 Xcppmain()
576 X/*
577 X * Main process for cpp -- copies tokens from the current input
578 X * stream (main file, include file, or a macro) to the output
579 X * file.
580 X */
581 X{
582 X       register int            c;              /* Current character    */
583 X       register int            counter;        /* newlines and spaces  */
584 X       extern int              output();       /* Output one character */
585 X
586 X       /*
587 X        * Explicitly output a #line at the start of cpp output so
588 X        * that lint (etc.) knows the name of the original source
589 X        * file.  If we don't do this explicitly, we may get
590 X        * the name of the first #include file instead.
591 X        */
592 X       sharp();
593 X       /*
594 X        * This loop is started "from the top" at the beginning of each line
595 X        * wrongline is set TRUE in many places if it is necessary to write
596 X        * a #line record.  (But we don't write them when expanding macros.)
597 X        *
598 X        * The counter variable has two different uses:  at
599 X        * the start of a line, it counts the number of blank lines that
600 X        * have been skipped over.  These are then either output via
601 X        * #line records or by outputting explicit blank lines.
602 X        * When expanding tokens within a line, the counter remembers
603 X        * whether a blank/tab has been output.  These are dropped
604 X        * at the end of the line, and replaced by a single blank
605 X        * within lines.
606 X        */
607 X       for (;;) {
608 X           counter = 0;                        /* Count empty lines    */
609 X           for (;;) {                          /* For each line, ...   */
610 X               while (type[(c = get())] == SPA) /* Skip leading blanks */
611 X                   ;                           /* in this line.        */
612 X               if (c == '\n')                  /* If line's all blank, */
613 X                   ++counter;                  /* Do nothing now       */
614 X               else if (c == '#') {            /* Is 1st non-space '#' */
615 X                   keepcomments = FALSE;       /* Don't pass comments  */
616 X                   counter = control(counter); /* Yes, do a #command   */
617 X                   keepcomments = (cflag && compiling);
618 X               }
619 X               else if (c == EOF_CHAR)         /* At end of file?      */
620 X                   break;
621 X               else if (!compiling) {          /* #ifdef false?        */
622 X                   skipnl();                   /* Skip to newline      */
623 X                   counter++;                  /* Count it, too.       */
624 X               }
625 X               else {
626 X                   break;                      /* Actual token         */
627 X               }
628 X           }
629 X           if (c == EOF_CHAR)                  /* Exit process at      */
630 X               break;                          /* End of file          */
631 X           /*
632 X            * If the loop didn't terminate because of end of file, we
633 X            * know there is a token to compile.  First, clean up after
634 X            * absorbing newlines.  counter has the number we skipped.
635 X            */
636 X           if ((wrongline && infile->fp != NULL) || counter > 4)
637 X               sharp();                        /* Output # line number */
638 X           else {                              /* If just a few, stuff */
639 X               while (--counter >= 0)          /* them out ourselves   */
640 X                   putchar('\n');
641 X           }
642 X           /*
643 X            * Process each token on this line.
644 X            */
645 X           unget();                            /* Reread the char.     */
646 X           for (;;) {                          /* For the whole line,  */
647 X               do {                            /* Token concat. loop   */
648 X                   for (counter = 0; (type[(c = get())] == SPA);) {
649 X#if COMMENT_INVISIBLE
650 X                       if (c != COM_SEP)
651 X                           counter++;
652 X#else
653 X                       counter++;              /* Skip over blanks     */
654 X#endif
655 X                   }
656 X                   if (c == EOF_CHAR || c == '\n')
657 X                       goto end_line;          /* Exit line loop       */
658 X                   else if (counter > 0)       /* If we got any spaces */
659 X                       putchar(' ');           /* Output one space     */
660 X                   c = macroid(c);             /* Grab the token       */
661 X               } while (type[c] == LET && catenate());
662 X               if (c == EOF_CHAR || c == '\n') /* From macro exp error */
663 X                   goto end_line;              /* Exit line loop       */
664 X               switch (type[c]) {
665 X               case LET:
666 X                   fputs(token, stdout);       /* Quite ordinary token */
667 X                   break;
668 X
669 X
670 X               case DIG:                       /* Output a number      */
671 X               case DOT:                       /* Dot may begin floats */
672 X                   scannumber(c, output);
673 X                   break;
674 X
675 X               case QUO:                       /* char or string const */
676 X                   scanstring(c, output);      /* Copy it to output    */
677 X                   break;
678 X
679 X               default:                        /* Some other character */
680 X                   cput(c);                    /* Just output it       */
681 X                   break;
682 X               }                               /* Switch ends          */
683 X           }                                   /* Line for loop        */
684 Xend_line:   if (c == '\n') {                   /* Compiling at EOL?    */
685 X               putchar('\n');                  /* Output newline, if   */
686 X               if (infile->fp == NULL)         /* Expanding a macro,   */
687 X                   wrongline = TRUE;           /* Output # line later  */
688 X           }
689 X       }                                       /* Continue until EOF   */
690 X}
691 X\f
692 Xoutput(c)
693 Xint            c;
694 X/*
695 X * Output one character to stdout -- output() is passed as an
696 X * argument to scanstring()
697 X */
698 X{
699 X#if COMMENT_INVISIBLE
700 X       if (c != TOK_SEP && c != COM_SEP)
701 X#else
702 X       if (c != TOK_SEP)
703 X#endif
704 X           putchar(c);
705 X}
706 X
707 Xstatic char    *sharpfilename = NULL;
708 X
709 XFILE_LOCAL
710 Xsharp()
711 X/*
712 X * Output a line number line.
713 X */
714 X{
715 X       register char           *name;
716 X
717 X       if (keepcomments)                       /* Make sure # comes on */
718 X           putchar('\n');                      /* a fresh, new line.   */
719 X       printf("#%s %d", LINE_PREFIX, line);
720 X       if (infile->fp != NULL) {
721 X           name = (infile->progname != NULL)
722 X               ? infile->progname : infile->filename;
723 X           if (sharpfilename == NULL
724 X            || sharpfilename != NULL && !streq(name, sharpfilename)) {
725 X               if (sharpfilename != NULL)
726 X                   free(sharpfilename);
727 X               sharpfilename = savestring(name);
728 X               printf(" \"%s\"", name);
729 X            }
730 X       }
731 X       putchar('\n');
732 X       wrongline = FALSE;
733 X}
734 END-of-cpp1.c
735 echo x - cpp3.c
736 sed 's/^X//' >cpp3.c << 'END-of-cpp3.c'
737 X/*
738 X *                             C P P 3 . C
739 X *
740 X *                 File open and command line options
741 X *
742 X * Edit history
743 X * 13-Nov-84   MM      Split from cpp1.c
744 X */
745 X
746 X#include       <stdio.h>
747 X#include       <ctype.h>
748 X#include       "cppdef.h"
749 X#include       "cpp.h"
750 X#if DEBUG && (HOST == SYS_VMS || HOST == SYS_UNIX)
751 X#include       <signal.h>
752 Xextern int     abort();                /* For debugging                */
753 X#endif
754 X
755 Xint
756 Xopenfile(filename)
757 Xchar           *filename;
758 X/*
759 X * Open a file, add it to the linked list of open files.
760 X * This is called only from openfile() above.
761 X */
762 X{
763 X       register FILE           *fp;
764 X
765 X       if ((fp = fopen(filename, "r")) == NULL) {
766 X#if DEBUG
767 X           perror(filename);
768 X#endif
769 X           return (FALSE);
770 X       }
771 X#if DEBUG
772 X       if (debug)
773 X           fprintf(stderr, "Reading from \"%s\"\n", filename);
774 X#endif
775 X       addfile(fp, filename);
776 X       return (TRUE);
777 X}
778 X
779 Xaddfile(fp, filename)
780 XFILE           *fp;                    /* Open file pointer            */
781 Xchar           *filename;              /* Name of the file             */
782 X/*
783 X * Initialize tables for this open file.  This is called from openfile()
784 X * above (for #include files), and from the entry to cpp to open the main
785 X * input file.  It calls a common routine, getfile() to build the FILEINFO
786 X * structure which is used to read characters.  (getfile() is also called
787 X * to setup a macro replacement.)
788 X */
789 X{
790 X       register FILEINFO       *file;
791 X       extern FILEINFO         *getfile();
792 X
793 X       file = getfile(NBUFF, filename);
794 X       file->fp = fp;                  /* Better remember FILE *       */
795 X       file->buffer[0] = EOS;          /* Initialize for first read    */
796 X       line = 1;                       /* Working on line 1 now        */
797 X       wrongline = TRUE;               /* Force out initial #line      */
798 X}
799 X\f
800 Xsetincdirs()
801 X/*
802 X * Append system-specific directories to the include directory list.
803 X * Called only when cpp is started.
804 X */
805 X{
806 X
807 X#ifdef CPP_INCLUDE
808 X       *incend++ = CPP_INCLUDE;
809 X#define        IS_INCLUDE      1
810 X#else
811 X#define        IS_INCLUDE      0
812 X#endif
813 X
814 X#if HOST == SYS_UNIX
815 X       *incend++ = "/usr/include";
816 X#define        MAXINCLUDE      (NINCLUDE - 1 - IS_INCLUDE)
817 X#endif
818 X
819 X#if HOST == SYS_VMS
820 X       extern char     *getenv();
821 X
822 X       if (getenv("C$LIBRARY") != NULL)
823 X           *incend++ = "C$LIBRARY:";
824 X       *incend++ = "SYS$LIBRARY:";
825 X#define        MAXINCLUDE      (NINCLUDE - 2 - IS_INCLUDE)
826 X#endif
827 X
828 X#if HOST == SYS_RSX
829 X       extern int      $$rsts;                 /* TRUE on RSTS/E       */
830 X       extern int      $$pos;                  /* TRUE on PRO-350 P/OS */
831 X       extern int      $$vms;                  /* TRUE on VMS compat.  */
832 X
833 X       if ($$pos) {                            /* P/OS?                */
834 X           *incend++ = "SY:[ZZDECUSC]";        /* C #includes          */
835 X           *incend++ = "LB:[1,5]";             /* RSX library          */
836 X       }
837 X       else if ($$rsts) {                      /* RSTS/E?              */
838 X           *incend++ = "SY:@";                 /* User-defined account */
839 X           *incend++ = "C:";                   /* Decus-C library      */
840 X           *incend++ = "LB:[1,1]";             /* RSX library          */
841 X       }
842 X       else if ($$vms) {                       /* VMS compatibility?   */
843 X           *incend++ = "C:";
844 X       }
845 X       else {                                  /* Plain old RSX/IAS    */
846 X           *incend++ = "LB:[1,1]";
847 X       }
848 X#define        MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
849 X#endif
850 X
851 X#if HOST == SYS_RT11
852 X       extern int      $$rsts;                 /* RSTS/E emulation?    */
853 X
854 X       if ($$rsts)
855 X           *incend++ = "SY:@";                 /* User-defined account */
856 X       *incend++ = "C:";                       /* Decus-C library disk */
857 X       *incend++ = "SY:";                      /* System (boot) disk   */
858 X#define        MAXINCLUDE      (NINCLUDE - 3 - IS_INCLUDE)
859 X#endif
860 X}
861 X\f
862 Xint
863 Xdooptions(argc, argv)
864 Xint            argc;
865 Xchar           *argv[];
866 X/*
867 X * dooptions is called to process command line arguments (-Detc).
868 X * It is called only at cpp startup.
869 X */
870 X{
871 X       register char           *ap;
872 X       register DEFBUF         *dp;
873 X       register int            c;
874 X       int                     i, j;
875 X       char                    *arg;
876 X       SIZES                   *sizp;          /* For -S               */
877 X       int                     size;           /* For -S               */
878 X       int                     isdatum;        /* FALSE for -S*        */
879 X       int                     endtest;        /* For -S               */
880 X
881 X       for (i = j = 1; i < argc; i++) {
882 X           arg = ap = argv[i];
883 X           if (*ap++ != '-' || *ap == EOS)
884 X               argv[j++] = argv[i];
885 X           else {
886 X               c = *ap++;                      /* Option byte          */
887 X               if (islower(c))                 /* Normalize case       */
888 X                   c = toupper(c);
889 X               switch (c) {                    /* Command character    */
890 X               case 'C':                       /* Keep comments        */
891 X                   cflag = TRUE;
892 X                   keepcomments = TRUE;
893 X                   break;
894 X
895 X               case 'D':                       /* Define symbol        */
896 X#if HOST != SYS_UNIX
897 X                   zap_uc(ap);                 /* Force define to U.C. */
898 X#endif
899 X                   /*
900 X                    * If the option is just "-Dfoo", make it -Dfoo=1
901 X                    */
902 X                   while (*ap != EOS && *ap != '=')
903 X                       ap++;
904 X                   if (*ap == EOS)
905 X                       ap = "1";
906 X                   else
907 X                       *ap++ = EOS;
908 X                   /*
909 X                    * Now, save the word and its definition.
910 X                    */
911 X                   dp = defendel(argv[i] + 2, FALSE);
912 X                   dp->repl = savestring(ap);
913 X                   dp->nargs = DEF_NOARGS;
914 X                   break;
915 X
916 X               case 'E':                       /* Ignore non-fatal     */
917 X                   eflag = TRUE;               /* errors.              */
918 X                   break;
919 X
920 X               case 'I':                       /* Include directory    */
921 X                   if (incend >= &incdir[MAXINCLUDE])
922 X                       cfatal("Too many include directories", NULLST);
923 X                   *incend++ = ap;
924 X                   break;
925 X
926 X               case 'N':                       /* No predefineds       */
927 X                   nflag++;                    /* Repeat to undefine   */
928 X                   break;                      /* __LINE__, etc.       */
929 X
930 X               case 'S':
931 X                   sizp = size_table;
932 X                   if (isdatum = (*ap != '*')) /* If it's just -S,     */
933 X                       endtest = T_FPTR;       /* Stop here            */
934 X                   else {                      /* But if it's -S*      */
935 X                       ap++;                   /* Step over '*'        */
936 X                       endtest = 0;            /* Stop at end marker   */
937 X                   }
938 X                   while (sizp->bits != endtest && *ap != EOS) {
939 X                       if (!isdigit(*ap)) {    /* Skip to next digit   */
940 X                           ap++;
941 X                           continue;
942 X                       }
943 X                       size = 0;               /* Compile the value    */
944 X                       while (isdigit(*ap)) {
945 X                           size *= 10;
946 X                           size += (*ap++ - '0');
947 X                       }
948 X                       if (isdatum)
949 X                           sizp->size = size;  /* Datum size           */
950 X                       else
951 X                           sizp->psize = size; /* Pointer size         */
952 X                       sizp++;
953 X                   }
954 X                   if (sizp->bits != endtest)
955 X                       cwarn("-S, too few values specified in %s", argv[i]);
956 X                   else if (*ap != EOS)
957 X                       cwarn("-S, too many values, \"%s\" unused", ap);
958 X                   break;
959 X
960 X               case 'U':                       /* Undefine symbol      */
961 X#if HOST != SYS_UNIX
962 X                   zap_uc(ap);
963 X#endif
964 X                   if (defendel(ap, TRUE) == NULL)
965 X                       cwarn("\"%s\" wasn't defined", ap);
966 X                   break;
967 X
968 X#if DEBUG
969 X               case 'X':                       /* Debug                */
970 X                   debug = (isdigit(*ap)) ? atoi(ap) : 1;
971 X#if (HOST == SYS_VMS || HOST == SYS_UNIX)
972 X                   signal(SIGINT, abort);      /* Trap "interrupt"     */
973 X#endif
974 X                   fprintf(stderr, "Debug set to %d\n", debug);
975 X                   break;
976 X#endif
977 X
978 X               default:                        /* What is this one?    */
979 X                   cwarn("Unknown option \"%s\"", arg);
980 X                   fprintf(stderr, "The following options are valid:\n\
981 X  -C\t\t\tWrite source file comments to output\n\
982 X  -Dsymbol=value\tDefine a symbol with the given (optional) value\n\
983 X  -Idirectory\t\tAdd a directory to the #include search list\n\
984 X  -N\t\t\tDon't predefine target-specific names\n\
985 X  -Stext\t\tSpecify sizes for #if sizeof\n\
986 X  -Usymbol\t\tUndefine symbol\n");
987 X#if DEBUG
988 X                   fprintf(stderr, "  -Xvalue\t\tSet internal debug flag\n");
989 X#endif
990 X                   break;
991 X               }                       /* Switch on all options        */
992 X           }                           /* If it's a -option            */
993 X       }                               /* For all arguments            */
994 X       if (j > 3) {
995 X           cerror(
996 X               "Too many file arguments.  Usage: cpp [input [output]]",
997 X               NULLST);
998 X       }
999 X       return (j);                     /* Return new argc              */
1000 X}
1001 X\f
1002 X#if HOST != SYS_UNIX
1003 XFILE_LOCAL
1004 Xzap_uc(ap)
1005 Xregister char  *ap;
1006 X/*
1007 X * Dec operating systems mangle upper-lower case in command lines.
1008 X * This routine forces the -D and -U arguments to uppercase.
1009 X * It is called only on cpp startup by dooptions().
1010 X */
1011 X{
1012 X       while (*ap != EOS) {
1013 X           /*
1014 X            * Don't use islower() here so it works with Multinational
1015 X            */
1016 X           if (*ap >= 'a' && *ap <= 'z')
1017 X               *ap = toupper(*ap);
1018 X           ap++;
1019 X       }
1020 X}
1021 X#endif
1022 X
1023 Xinitdefines()
1024 X/*
1025 X * Initialize the built-in #define's.  There are two flavors:
1026 X *     #define decus   1               (static definitions)
1027 X *     #define __FILE__ ??             (dynamic, evaluated by magic)
1028 X * Called only on cpp startup.
1029 X *
1030 X * Note: the built-in static definitions are supressed by the -N option.
1031 X * __LINE__, __FILE__, and __DATE__ are always present.
1032 X */
1033 X{
1034 X       register char           **pp;
1035 X       register char           *tp;
1036 X       register DEFBUF         *dp;
1037 X       int                     i;
1038 X       long                    tvec;
1039 X       extern char             *ctime();
1040 X
1041 X       /*
1042 X        * Predefine the built-in symbols.  Allow the
1043 X        * implementor to pre-define a symbol as "" to
1044 X        * eliminate it.
1045 X        */
1046 X       if (nflag == 0) {
1047 X           for (pp = preset; *pp != NULL; pp++) {
1048 X               if (*pp[0] != EOS) {
1049 X                   dp = defendel(*pp, FALSE);
1050 X                   dp->repl = savestring("1");
1051 X                   dp->nargs = DEF_NOARGS;
1052 X               }
1053 X           }
1054 X       }
1055 X       /*
1056 X        * The magic pre-defines (__FILE__ and __LINE__ are
1057 X        * initialized with negative argument counts.  expand()
1058 X        * notices this and calls the appropriate routine.
1059 X        * DEF_NOARGS is one greater than the first "magic" definition.
1060 X        */
1061 X       if (nflag < 2) {
1062 X           for (pp = magic, i = DEF_NOARGS; *pp != NULL; pp++) {
1063 X               dp = defendel(*pp, FALSE);
1064 X               dp->nargs = --i;
1065 X           }
1066 X#if OK_DATE
1067 X           /*
1068 X            * Define __DATE__ as today's date.
1069 X            */
1070 X           dp = defendel("__DATE__", FALSE);
1071 X           dp->repl = tp = getmem(27);
1072 X           dp->nargs = DEF_NOARGS;
1073 X           time(&tvec);
1074 X           *tp++ = '"';
1075 X           strcpy(tp, ctime(&tvec));
1076 X           tp[24] = '"';                       /* Overwrite newline    */
1077 X#endif
1078 X       }
1079 X}
1080 X\f
1081 X#if HOST == SYS_VMS
1082 X/*
1083 X * getredirection() is intended to aid in porting C programs
1084 X * to VMS (Vax-11 C) which does not support '>' and '<'
1085 X * I/O redirection.  With suitable modification, it may
1086 X * useful for other portability problems as well.
1087 X */
1088 X
1089 Xint
1090 Xgetredirection(argc, argv)
1091 Xint            argc;
1092 Xchar           **argv;
1093 X/*
1094 X * Process vms redirection arg's.  Exit if any error is seen.
1095 X * If getredirection() processes an argument, it is erased
1096 X * from the vector.  getredirection() returns a new argc value.
1097 X *
1098 X * Warning: do not try to simplify the code for vms.  The code
1099 X * presupposes that getredirection() is called before any data is
1100 X * read from stdin or written to stdout.
1101 X *
1102 X * Normal usage is as follows:
1103 X *
1104 X *     main(argc, argv)
1105 X *     int             argc;
1106 X *     char            *argv[];
1107 X *     {
1108 X *             argc = getredirection(argc, argv);
1109 X *     }
1110 X */
1111 X{
1112 X       register char           *ap;    /* Argument pointer     */
1113 X       int                     i;      /* argv[] index         */
1114 X       int                     j;      /* Output index         */
1115 X       int                     file;   /* File_descriptor      */
1116 X       extern int              errno;  /* Last vms i/o error   */
1117 X
1118 X       for (j = i = 1; i < argc; i++) {   /* Do all arguments  */
1119 X           switch (*(ap = argv[i])) {
1120 X           case '<':                   /* <file                */
1121 X               if (freopen(++ap, "r", stdin) == NULL) {
1122 X                   perror(ap);         /* Can't find file      */
1123 X                   exit(errno);        /* Is a fatal error     */
1124 X               }
1125 X               break;
1126 X
1127 X           case '>':                   /* >file or >>file      */
1128 X               if (*++ap == '>') {     /* >>file               */
1129 X                   /*
1130 X                    * If the file exists, and is writable by us,
1131 X                    * call freopen to append to the file (using the
1132 X                    * file's current attributes).  Otherwise, create
1133 X                    * a new file with "vanilla" attributes as if the
1134 X                    * argument was given as ">filename".
1135 X                    * access(name, 2) returns zero if we can write on
1136 X                    * the specified file.
1137 X                    */
1138 X                   if (access(++ap, 2) == 0) {
1139 X                       if (freopen(ap, "a", stdout) != NULL)
1140 X                           break;      /* Exit case statement  */
1141 X                       perror(ap);     /* Error, can't append  */
1142 X                       exit(errno);    /* After access test    */
1143 X                   }                   /* If file accessable   */
1144 X               }
1145 X               /*
1146 X                * On vms, we want to create the file using "standard"
1147 X                * record attributes.  creat(...) creates the file
1148 X                * using the caller's default protection mask and
1149 X                * "variable length, implied carriage return"
1150 X                * attributes. dup2() associates the file with stdout.
1151 X                */
1152 X               if ((file = creat(ap, 0, "rat=cr", "rfm=var")) == -1
1153 X                || dup2(file, fileno(stdout)) == -1) {
1154 X                   perror(ap);         /* Can't create file    */
1155 X                   exit(errno);        /* is a fatal error     */
1156 X               }                       /* If '>' creation      */
1157 X               break;                  /* Exit case test       */
1158 X
1159 X           default:
1160 X               argv[j++] = ap;         /* Not a redirector     */
1161 X               break;                  /* Exit case test       */
1162 X           }
1163 X       }                               /* For all arguments    */
1164 X       argv[j] = NULL;                 /* Terminate argv[]     */
1165 X       return (j);                     /* Return new argc      */
1166 X}
1167 X#endif
1168 X
1169 X
1170 X
1171 END-of-cpp3.c
1172 echo x - cpp4.c
1173 sed 's/^X//' >cpp4.c << 'END-of-cpp4.c'
1174 X/*
1175 X *                         C P P 4 . C
1176 X *             M a c r o  D e f i n i t i o n s
1177 X *
1178 X * Edit History
1179 X * 31-Aug-84   MM      USENET net.sources release
1180 X * 04-Oct-84   MM      __LINE__ and __FILE__ must call ungetstring()
1181 X *                     so they work correctly with token concatenation.
1182 X *                     Added string formal recognition.
1183 X * 25-Oct-84   MM      "Short-circuit" evaluate #if's so that we
1184 X *                     don't print unnecessary error messages for
1185 X *                     #if !defined(FOO) && FOO != 0 && 10 / FOO ...
1186 X * 31-Oct-84   ado/MM  Added token concatenation
1187 X *  6-Nov-84   MM      Split off eval stuff
1188 X */
1189 X
1190 X#include       <stdio.h>
1191 X#include       <ctype.h>
1192 X#include       "cppdef.h"
1193 X#include       "cpp.h"
1194 X/*
1195 X * parm[], parmp, and parlist[] are used to store #define() argument
1196 X * lists.  nargs contains the actual number of parameters stored.
1197 X */
1198 Xstatic char    parm[NPARMWORK + 1];    /* define param work buffer     */
1199 Xstatic char    *parmp;                 /* Free space in parm           */
1200 Xstatic char    *parlist[LASTPARM];     /* -> start of each parameter   */
1201 Xstatic int     nargs;                  /* Parameters for this macro    */
1202 X
1203 Xdodefine()
1204 X/*
1205 X * Called from control when a #define is scanned.  This module
1206 X * parses formal parameters and the replacement string.  When
1207 X * the formal parameter name is encountered in the replacement
1208 X * string, it is replaced by a character in the range 128 to
1209 X * 128+NPARAM (this allows up to 32 parameters within the
1210 X * Dec Multinational range).  If cpp is ported to an EBCDIC
1211 X * machine, you will have to make other arrangements.
1212 X *
1213 X * There is some special case code to distinguish
1214 X *     #define foo     bar
1215 X * from        #define foo()   bar
1216 X *
1217 X * Also, we make sure that
1218 X *     #define foo     foo
1219 X * expands to "foo" but doesn't put cpp into an infinite loop.
1220 X *
1221 X * A warning message is printed if you redefine a symbol to a
1222 X * different text.  I.e,
1223 X *     #define foo     123
1224 X *     #define foo     123
1225 X * is ok, but
1226 X *     #define foo     123
1227 X *     #define foo     +123
1228 X * is not.
1229 X *
1230 X * The following subroutines are called from define():
1231 X * checkparm   called when a token is scanned.  It checks through the
1232 X *             array of formal parameters.  If a match is found, the
1233 X *             token is replaced by a control byte which will be used
1234 X *             to locate the parameter when the macro is expanded.
1235 X * textput     puts a string in the macro work area (parm[]), updating
1236 X *             parmp to point to the first free byte in parm[].
1237 X *             textput() tests for work buffer overflow.
1238 X * charput     puts a single character in the macro work area (parm[])
1239 X *             in a manner analogous to textput().
1240 X */
1241 X{
1242 X       register int            c;
1243 X       register DEFBUF         *dp;            /* -> new definition    */
1244 X       int                     isredefine;     /* TRUE if redefined    */
1245 X       char                    *old;           /* Remember redefined   */
1246 X       extern int              save();         /* Save char in work[]  */
1247 X
1248 X       if (type[(c = skipws())] != LET)
1249 X           goto bad_define;
1250 X       isredefine = FALSE;                     /* Set if redefining    */
1251 X       if ((dp = lookid(c)) == NULL)           /* If not known now     */
1252 X           dp = defendel(token, FALSE);        /* Save the name        */
1253 X       else {                                  /* It's known:          */
1254 X           isredefine = TRUE;                  /* Remember this fact   */
1255 X           old = dp->repl;                     /* Remember replacement */
1256 X           dp->repl = NULL;                    /* No replacement now   */
1257 X       }
1258 X       parlist[0] = parmp = parm;              /* Setup parm buffer    */
1259 X       if ((c = get()) == '(') {               /* With arguments?      */
1260 X           nargs = 0;                          /* Init formals counter */
1261 X           do {                                /* Collect formal parms */
1262 X               if (nargs >= LASTPARM)
1263 X                   cfatal("Too many arguments for macro", NULLST);
1264 X               else if ((c = skipws()) == ')')
1265 X                   break;                      /* Got them all         */
1266 X               else if (type[c] != LET)        /* Bad formal syntax    */
1267 X                   goto bad_define;
1268 X               scanid(c);                      /* Get the formal param */
1269 X               parlist[nargs++] = parmp;       /* Save its start       */
1270 X               textput(token);                 /* Save text in parm[]  */
1271 X           } while ((c = skipws()) == ',');    /* Get another argument */
1272 X           if (c != ')')                       /* Must end at )        */
1273 X               goto bad_define;
1274 X           c = ' ';                            /* Will skip to body    */
1275 X       }
1276 X       else {
1277 X           /*
1278 X            * DEF_NOARGS is needed to distinguish between
1279 X            * "#define foo" and "#define foo()".
1280 X            */
1281 X           nargs = DEF_NOARGS;                 /* No () parameters     */
1282 X       }
1283 X       if (type[c] == SPA)                     /* At whitespace?       */
1284 X           c = skipws();                       /* Not any more.        */
1285 X       workp = work;                           /* Replacement put here */
1286 X       inmacro = TRUE;                         /* Keep \<newline> now  */
1287 X       while (c != EOF_CHAR && c != '\n') {    /* Compile macro body   */
1288 X#if OK_CONCAT
1289 X           if (c == '#') {                     /* Token concatenation? */
1290 X               while (workp > work && type[workp[-1]] == SPA)
1291 X                   --workp;                    /* Erase leading spaces */
1292 X               save(TOK_SEP);                  /* Stuff a delimiter    */
1293 X               c = skipws();                   /* Eat whitespace       */
1294 X               if (type[c] == LET)             /* Another token here?  */
1295 X                   ;                           /* Stuff it normally    */
1296 X               else if (type[c] == DIG) {      /* Digit string after?  */
1297 X                   while (type[c] == DIG) {    /* Stuff the digits     */
1298 X                       save(c);
1299 X                       c = get();
1300 X                   }
1301 X                   save(TOK_SEP);              /* Delimit 2nd token    */
1302 X               }
1303 X               else {
1304 X                   ciwarn("Strange character after # (%d.)", c);
1305 X               }
1306 X               continue;
1307 X           }
1308 X#endif
1309 X           switch (type[c]) {
1310 X           case LET:
1311 X               checkparm(c, dp);               /* Might be a formal    */
1312 X               break;
1313 X
1314 X           case DIG:                           /* Number in mac. body  */
1315 X           case DOT:                           /* Maybe a float number */
1316 X               scannumber(c, save);            /* Scan it off          */
1317 X               break;
1318 X
1319 X           case QUO:                           /* String in mac. body  */
1320 X#if STRING_FORMAL
1321 X               stparmscan(c, dp);              /* Do string magic      */
1322 X#else
1323 X               stparmscan(c);
1324 X#endif
1325 X               break;
1326 X
1327 X           case BSH:                           /* Backslash            */
1328 X               save('\\');
1329 X               if ((c = get()) == '\n')
1330 X                   wrongline = TRUE;
1331 X               save(c);
1332 X               break;
1333 X
1334 X           case SPA:                           /* Absorb whitespace    */
1335 X               /*
1336 X                * Note: the "end of comment" marker is passed on
1337 X                * to allow comments to separate tokens.
1338 X                */
1339 X               if (workp[-1] == ' ')           /* Absorb multiple      */
1340 X                   break;                      /* spaces               */
1341 X               else if (c == '\t')
1342 X                   c = ' ';                    /* Normalize tabs       */
1343 X               /* Fall through to store character                      */
1344 X           default:                            /* Other character      */
1345 X               save(c);
1346 X               break;
1347 X           }
1348 X           c = get();
1349 X       }
1350 X       inmacro = FALSE;                        /* Stop newline hack    */
1351 X       unget();                                /* For control check    */
1352 X       if (workp > work && workp[-1] == ' ')   /* Drop trailing blank  */
1353 X           workp--;
1354 X       *workp = EOS;                           /* Terminate work       */
1355 X       dp->repl = savestring(work);            /* Save the string      */
1356 X       dp->nargs = nargs;                      /* Save arg count       */
1357 X#if DEBUG
1358 X       if (debug)
1359 X           dumpadef("macro definition", dp);
1360 X#endif
1361 X       if (isredefine) {                       /* Error if redefined   */
1362 X           if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl))
1363 X            || (old == NULL && dp->repl != NULL)
1364 X            || (old != NULL && dp->repl == NULL)) {
1365 X               cerror("Redefining defined variable \"%s\"", dp->name);
1366 X           }
1367 X           if (old != NULL)                    /* We don't need the    */
1368 X               free(old);                      /* old definition now.  */
1369 X       }        
1370 X       return;
1371 X
1372 Xbad_define:
1373 X       cerror("#define syntax error", NULLST);
1374 X       inmacro = FALSE;                        /* Stop <newline> hack  */
1375 X}
1376 X\f
1377 Xcheckparm(c, dp)
1378 Xregister int   c;
1379 XDEFBUF         *dp;
1380 X/*
1381 X * Replace this param if it's defined.  Note that the macro name is a
1382 X * possible replacement token.  We stuff DEF_MAGIC in front of the token
1383 X * which is treated as a LETTER by the token scanner and eaten by
1384 X * the output routine.  This prevents the macro expander from
1385 X * looping if someone writes "#define foo foo".
1386 X */
1387 X{
1388 X       register int            i;
1389 X       register char           *cp;
1390 X
1391 X       scanid(c);                              /* Get parm to token[]  */
1392 X       for (i = 0; i < nargs; i++) {           /* For each argument    */
1393 X           if (streq(parlist[i], token)) {     /* If it's known        */
1394 X               save(i + MAC_PARM);             /* Save a magic cookie  */
1395 X               return;                         /* And exit the search  */
1396 X           }
1397 X       }
1398 X       if (streq(dp->name, token))             /* Macro name in body?  */
1399 X           save(DEF_MAGIC);                    /* Save magic marker    */
1400 X       for (cp = token; *cp != EOS;)           /* And save             */
1401 X           save(*cp++);                        /* The token itself     */
1402 X}
1403 X\f
1404 X#if STRING_FORMAL
1405 Xstparmscan(delim, dp)
1406 Xint            delim;
1407 Xregister DEFBUF        *dp;
1408 X/*
1409 X * Scan the string (starting with the given delimiter).
1410 X * The token is replaced if it is the only text in this string or
1411 X * character constant.  The algorithm follows checkparm() above.
1412 X * Note that scanstring() has approved of the string.
1413 X */
1414 X{
1415 X       register int            c;
1416 X
1417 X       /*
1418 X        * Warning -- this code hasn't been tested for a while.
1419 X        * It exists only to preserve compatibility with earlier
1420 X        * implementations of cpp.  It is not part of the Draft
1421 X        * ANSI Standard C language.
1422 X        */
1423 X       save(delim);
1424 X       instring = TRUE;
1425 X       while ((c = get()) != delim
1426 X            && c != '\n'
1427 X            && c != EOF_CHAR) {
1428 X           if (type[c] == LET)                 /* Maybe formal parm    */
1429 X               checkparm(c, dp);
1430 X           else {
1431 X               save(c);
1432 X               if (c == '\\')
1433 X                   save(get());
1434 X           }
1435 X       }
1436 X       instring = FALSE;
1437 X       if (c != delim)
1438 X           cerror("Unterminated string in macro body", NULLST);
1439 X       save(c);
1440 X}
1441 X#else
1442 Xstparmscan(delim)
1443 Xint            delim;
1444 X/*
1445 X * Normal string parameter scan.
1446 X */
1447 X{
1448 X       register char           *wp;
1449 X       register int            i;
1450 X       extern int              save();
1451 X
1452 X       wp = workp;                     /* Here's where it starts       */
1453 X       if (!scanstring(delim, save))
1454 X           return;                     /* Exit on scanstring error     */
1455 X       workp[-1] = EOS;                /* Erase trailing quote         */
1456 X       wp++;                           /* -> first string content byte */ 
1457 X       for (i = 0; i < nargs; i++) {
1458 X           if (streq(parlist[i], wp)) {
1459 X               *wp++ = MAC_PARM + PAR_MAC;     /* Stuff a magic marker */
1460 X               *wp++ = (i + MAC_PARM);         /* Make a formal marker */
1461 X               *wp = wp[-3];                   /* Add on closing quote */
1462 X               workp = wp + 1;                 /* Reset string end     */
1463 X               return;
1464 X           }
1465 X       }
1466 X       workp[-1] = wp[-1];             /* Nope, reset end quote.       */
1467 X}
1468 X#endif
1469 X\f
1470 Xdoundef()
1471 X/*
1472 X * Remove the symbol from the defined list.
1473 X * Called from the #control processor.
1474 X */
1475 X{
1476 X       register int            c;
1477 X
1478 X       if (type[(c = skipws())] != LET)
1479 X           cerror("Illegal #undef argument", NULLST);
1480 X       else {
1481 X           scanid(c);                          /* Get name to token[]  */
1482 X           if (defendel(token, TRUE) == NULL) {
1483 X               cwarn("Symbol \"%s\" not defined in #undef", token);
1484 X           }
1485 X       }
1486 X}
1487 X
1488 Xtextput(text)
1489 Xchar           *text;
1490 X/*
1491 X * Put the string in the parm[] buffer.
1492 X */
1493 X{
1494 X       register int    size;
1495 X
1496 X       size = strlen(text) + 1;
1497 X       if ((parmp + size) >= &parm[NPARMWORK])
1498 X           cfatal("Macro work area overflow", NULLST);
1499 X       else {
1500 X           strcpy(parmp, text);
1501 X           parmp += size;
1502 X       }
1503 X}
1504 X
1505 Xcharput(c)
1506 Xregister int   c;
1507 X/*
1508 X * Put the byte in the parm[] buffer.
1509 X */
1510 X{
1511 X       if (parmp >= &parm[NPARMWORK])
1512 X           cfatal("Macro work area overflow", NULLST);
1513 X       else {
1514 X           *parmp++ = c;
1515 X       }
1516 X}
1517 X\f
1518 X/*
1519 X *             M a c r o   E x p a n s i o n
1520 X */
1521 X
1522 Xstatic DEFBUF  *macro;         /* Catches start of infinite macro      */
1523 X
1524 Xexpand(tokenp)
1525 Xregister DEFBUF        *tokenp;
1526 X/*
1527 X * Expand a macro.  Called from the cpp mainline routine (via subroutine
1528 X * macroid()) when a token is found in the symbol table.  It calls
1529 X * expcollect() to parse actual parameters, checking for the correct number.
1530 X * It then creates a "file" containing a single line containing the
1531 X * macro with actual parameters inserted appropriately.  This is
1532 X * "pushed back" onto the input stream.  (When the get() routine runs
1533 X * off the end of the macro line, it will dismiss the macro itself.)
1534 X */
1535 X{
1536 X       register int            c;
1537 X       register FILEINFO       *file;
1538 X       extern FILEINFO         *getfile();
1539 X
1540 X#if DEBUG
1541 X       if (debug)
1542 X           dumpadef("expand entry", tokenp);
1543 X#endif
1544 X       /*
1545 X        * If no macro is pending, save the name of this macro
1546 X        * for an eventual error message.
1547 X        */
1548 X       if (recursion++ == 0)
1549 X           macro = tokenp;
1550 X       else if (recursion == RECURSION_LIMIT) {
1551 X           cerror("Recursive macro definition of \"%s\"", tokenp->name);
1552 X           fprintf(stderr, "(Defined by \"%s\")\n", macro->name);
1553 X           if (rec_recover) {
1554 X               do {
1555 X                   c = get();
1556 X               } while (infile != NULL && infile->fp == NULL);
1557 X               unget();
1558 X               recursion = 0;
1559 X               return;
1560 X           }
1561 X       }
1562 X       /*
1563 X        * Here's a macro to expand.
1564 X        */
1565 X       nargs = 0;                              /* Formals counter      */
1566 X       parmp = parm;                           /* Setup parm buffer    */
1567 X       switch (tokenp->nargs) {
1568 X       case (-2):                              /* __LINE__             */
1569 X           sprintf(work, "%d", line);
1570 X           ungetstring(work);
1571 X           break;
1572 X
1573 X       case (-3):                              /* __FILE__             */
1574 X           for (file = infile; file != NULL; file = file->parent) {
1575 X               if (file->fp != NULL) {
1576 X                   sprintf(work, "\"%s\"", (file->progname != NULL)
1577 X                       ? file->progname : file->filename);
1578 X                   ungetstring(work);
1579 X                   break;
1580 X               }
1581 X           }
1582 X           break;
1583 X
1584 X       default:
1585 X           /*
1586 X            * Nothing funny about this macro.
1587 X            */
1588 X           if (tokenp->nargs < 0)
1589 X               cfatal("Bug: Illegal __ macro \"%s\"", tokenp->name);
1590 X           while ((c = skipws()) == '\n')      /* Look for (, skipping */
1591 X               wrongline = TRUE;               /* spaces and newlines  */
1592 X           if (c != '(') {
1593 X               /*
1594 X                * If the programmer writes
1595 X                *      #define foo() ...
1596 X                *      ...
1597 X                *      foo [no ()]
1598 X                * just write foo to the output stream.
1599 X                */
1600 X               unget();
1601 X               cwarn("Macro \"%s\" needs arguments", tokenp->name);
1602 X               fputs(tokenp->name, stdout);
1603 X               return;
1604 X           }
1605 X           else if (expcollect()) {            /* Collect arguments    */
1606 X               if (tokenp->nargs != nargs) {   /* Should be an error?  */
1607 X                   cwarn("Wrong number of macro arguments for \"%s\"",
1608 X                       tokenp->name);
1609 X               }
1610 X#if DEBUG
1611 X               if (debug)
1612 X                   dumpparm("expand");
1613 X#endif
1614 X           }                           /* Collect arguments            */
1615 X       case DEF_NOARGS:                /* No parameters just stuffs    */
1616 X           expstuff(tokenp);           /* Do actual parameters         */
1617 X       }                               /* nargs switch                 */
1618 X}
1619 X\f
1620 XFILE_LOCAL int
1621 Xexpcollect()
1622 X/*
1623 X * Collect the actual parameters for this macro.  TRUE if ok.
1624 X */
1625 X{
1626 X       register int    c;
1627 X       register int    paren;                  /* For embedded ()'s    */
1628 X       extern int      charput();
1629 X
1630 X       for (;;) {
1631 X           paren = 0;                          /* Collect next arg.    */
1632 X           while ((c = skipws()) == '\n')      /* Skip over whitespace */
1633 X               wrongline = TRUE;               /* and newlines.        */
1634 X           if (c == ')') {                     /* At end of all args?  */
1635 X               /*
1636 X                * Note that there is a guard byte in parm[]
1637 X                * so we don't have to check for overflow here.
1638 X                */
1639 X               *parmp = EOS;                   /* Make sure terminated */
1640 X               break;                          /* Exit collection loop */
1641 X           }
1642 X           else if (nargs >= LASTPARM)
1643 X               cfatal("Too many arguments in macro expansion", NULLST);
1644 X           parlist[nargs++] = parmp;           /* At start of new arg  */
1645 X           for (;; c = cget()) {               /* Collect arg's bytes  */
1646 X               if (c == EOF_CHAR) {
1647 X                   cerror("end of file within macro argument", NULLST);
1648 X                   return (FALSE);             /* Sorry.               */
1649 X               }
1650 X               else if (c == '\\') {           /* Quote next character */
1651 X                   charput(c);                 /* Save the \ for later */
1652 X                   charput(cget());            /* Save the next char.  */
1653 X                   continue;                   /* And go get another   */
1654 X               }
1655 X               else if (type[c] == QUO) {      /* Start of string?     */
1656 X                   scanstring(c, charput);     /* Scan it off          */
1657 X                   continue;                   /* Go get next char     */
1658 X               }
1659 X               else if (c == '(')              /* Worry about balance  */
1660 X                   paren++;                    /* To know about commas */
1661 X               else if (c == ')') {            /* Other side too       */
1662 X                   if (paren == 0) {           /* At the end?          */
1663 X                       unget();                /* Look at it later     */
1664 X                       break;                  /* Exit arg getter.     */
1665 X                   }
1666 X                   paren--;                    /* More to come.        */
1667 X               }
1668 X               else if (c == ',' && paren == 0) /* Comma delimits args */
1669 X                   break;
1670 X               else if (c == '\n')             /* Newline inside arg?  */
1671 X                   wrongline = TRUE;           /* We'll need a #line   */
1672 X               charput(c);                     /* Store this one       */
1673 X           }                                   /* Collect an argument  */
1674 X           charput(EOS);                       /* Terminate argument   */
1675 X#if DEBUG
1676 X           if (debug)
1677 X               printf("parm[%d] = \"%s\"\n", nargs, parlist[nargs - 1]);
1678 X#endif
1679 X       }                                       /* Collect all args.    */
1680 X       return (TRUE);                          /* Normal return        */
1681 X}
1682 X\f
1683 XFILE_LOCAL
1684 Xexpstuff(tokenp)
1685 XDEFBUF         *tokenp;                /* Current macro being expanded */
1686 X/*
1687 X * Stuff the macro body, replacing formal parameters by actual parameters.
1688 X */
1689 X{
1690 X       register int    c;                      /* Current character    */
1691 X       register char   *inp;                   /* -> repl string       */
1692 X       register char   *defp;                  /* -> macro output buff */
1693 X       int             size;                   /* Actual parm. size    */
1694 X       char            *defend;                /* -> output buff end   */
1695 X       int             string_magic;           /* String formal hack   */
1696 X       FILEINFO        *file;                  /* Funny #include       */
1697 X       extern FILEINFO *getfile();
1698 X
1699 X       file = getfile(NBUFF, tokenp->name);
1700 X       inp = tokenp->repl;                     /* -> macro replacement */
1701 X       defp = file->buffer;                    /* -> output buffer     */
1702 X       defend = defp + (NBUFF - 1);            /* Note its end         */
1703 X       if (inp != NULL) {
1704 X           while ((c = (*inp++ & 0xFF)) != EOS) {
1705 X               if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC)) {
1706 X                   string_magic = (c == (MAC_PARM + PAR_MAC));
1707 X                   if (string_magic)
1708 X                       c = (*inp++ & 0xFF);
1709 X                   /*
1710 X                    * Replace formal parameter by actual parameter string.
1711 X                    */
1712 X                   if ((c -= MAC_PARM) < nargs) {
1713 X                       size = strlen(parlist[c]);
1714 X                       if ((defp + size) >= defend)
1715 X                           goto nospace;
1716 X                       /*
1717 X                        * Erase the extra set of quotes.
1718 X                        */
1719 X                       if (string_magic && defp[-1] == parlist[c][0]) {
1720 X                           strcpy(defp-1, parlist[c]);
1721 X                           defp += (size - 2);
1722 X                       }
1723 X                       else {
1724 X                           strcpy(defp, parlist[c]);
1725 X                           defp += size;
1726 X                       }
1727 X                   }
1728 X               }
1729 X               else if (defp >= defend) {
1730 Xnospace:           cfatal("Out of space in macro \"%s\" arg expansion",
1731 X                       tokenp->name);
1732 X               }
1733 X               else {
1734 X                   *defp++ = c;
1735 X               }
1736 X           }
1737 X       }
1738 X       *defp = EOS;
1739 X#if DEBUG
1740 X       if (debug > 1)
1741 X           printf("macroline: \"%s\"\n", file->buffer);
1742 X#endif
1743 X}
1744 X\f
1745 X#if DEBUG
1746 Xdumpparm(why)
1747 Xchar           *why;
1748 X/*
1749 X * Dump parameter list.
1750 X */
1751 X{
1752 X       register int    i;
1753 X
1754 X       printf("dump of %d parameters (%d bytes total) %s\n",
1755 X           nargs, parmp - parm, why);
1756 X       for (i = 0; i < nargs; i++) {
1757 X           printf("parm[%d] (%d) = \"%s\"\n",
1758 X               i + 1, strlen(parlist[i]), parlist[i]);
1759 X       }
1760 X}
1761 X#endif
1762 END-of-cpp4.c
1763 exit