home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / sys / unix / cpp2.shr < prev    next >
Encoding:
Text File  |  1993-08-01  |  52.3 KB  |  1,764 lines  |  [TEXT/R*ch]

  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  1764.