Annotation of coherent/b/bin/c/coh/cc.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * coh/cc.c
        !             3:  * CC command.
        !             4:  * Compile, assemble and link edit C programs.
        !             5:  * A lot of grunge.
        !             6:  * Revised by rec 5/87 to incorporate all
        !             7:  * COHERENT and GEMDOS revisions to date.
        !             8:  * Revised by steve 3/92 to produce monolithic COHERENT compiler.
        !             9:  *
        !            10:  * Compliing with -DVeryVflag produces very verbose output under -V option.
        !            11:  *
        !            12:  * C compiler/loader switch map.
        !            13:  *     *7      marks a version seven documented option.
        !            14:  *     *7d     marks a defunct version seven option.
        !            15:  *     *7c     marks a changed version seven option.
        !            16:  *     *u      marks an option unrecognized by cc, i.e. passed to loader
        !            17:  *             with no interpretation or processing.
        !            18:  *
        !            19:  * Options still up for grabs:
        !            20:  * [  C  FGH J     P R    W Y ]
        !            21:  * [ b     h j  m           yz]
        !            22:  * Change the verbose usage() message below when options change!
        !            23:  *
        !            24:  *     ?               list available options, cf. usage(1) below
        !            25:  *     A               auto edit mode
        !            26:  *7c   Bstring         use string to find compiler passes
        !            27:  *7    Dname[=value]   preprocessor: #define
        !            28:  *7    E               run preprocessor to stdout
        !            29:  *7    Ipathname       preprocessor: #include search directory
        !            30:  *     K               keep intermediate files
        !            31:  *     Lpathname       loader: library directory specification
        !            32:  *     Mstring         use string as cross-compiler prefix
        !            33:  *     N[01ab2sdlrt]string     rename pass with string
        !            34:  *7    O               run object code optimiser
        !            35:  *7d   P               put preprocessor output into name.i; use -Kqp
        !            36:  *     Q               be quiet, make no messages
        !            37:  *7    S               make assembly language output
        !            38:  *     T[value]        use in-memory tempfiles of size value (default: 64K)
        !            39:  *7    Uname           preprocessor: #undef
        !            40:  *     V               be verbose, report everything
        !            41:  *     Vvariant        enable variant
        !            42:  *     X               loader: remove C-generated local symbols
        !            43:  *     Z               (GEMDOS) floppy change prompts for phases
        !            44:  *     a               do not implicit output file name to loader
        !            45:  *7    c               compile but do not load
        !            46:  *     d               loader: define common space
        !            47:  *7    e name          loader: entry point specification
        !            48:  *7c   f               load floating point output conversion routines
        !            49:  *     g               generate debug info, same as -VDB
        !            50:  *7u   i               loader: separate i and d spaces
        !            51:  *     k system        loader: bind as kernel process [but ld doesn't grok it]
        !            52:  *7c   lname           loader: library specification
        !            53:  *7u   n               loader: shared instruction space
        !            54:  *7    o name          loader: output file name
        !            55:  *7    p               generate code to profile function calls
        !            56:  *     q[p012s]        quit after specified pass
        !            57:  *     r               loader: retain relocation in output
        !            58:  *     s               loader: strip symbol table
        !            59:  *7c   t[p012adlrt]    take specified passes from -Bdirectory
        !            60:  *7    u name          loader: undefine name
        !            61:  *     v               verbose, same as V
        !            62:  *     w               loader: watch
        !            63:  *     x               loader: remove local symbols from symbol table
        !            64:  */
        !            65: 
        !            66: #if    GEMDOS
        !            67: #ifndef VERS
        !            68: #define VERS   "2.1"
        !            69: #endif
        !            70: #endif
        !            71: 
        !            72: #include <stdio.h>
        !            73: #include <setjmp.h>
        !            74: #include <string.h>
        !            75: #include <ctype.h>
        !            76: #include <signal.h>
        !            77: #include <path.h>
        !            78: #include <errno.h>
        !            79: #include "mch.h"
        !            80: #include "host.h"
        !            81: #include "ops.h"
        !            82: #include "stream.h"
        !            83: #undef NONE
        !            84: #include "var.h"
        !            85: #include "varmch.h"
        !            86: 
        !            87: #ifndef VeryVflag
        !            88: #define VeryVflag 0
        !            89: #endif
        !            90: 
        !            91: #ifndef PREFIX
        !            92: #define PREFIX ""
        !            93: #endif
        !            94: 
        !            95: #if    _I386
        !            96: #define        DTEFG   "_dtefg"
        !            97: #else
        !            98: #define        DTEFG   "_dtefg_"
        !            99: #endif
        !           100: 
        !           101: /*
        !           102: ** Pass information.
        !           103: */
        !           104: #define NONE   -1
        !           105: #define CPP    0       /* Pass index numbers */
        !           106: #define CC0    1
        !           107: #define CC1    2
        !           108: #define CC2    3
        !           109: #define CC3    4
        !           110: #define CC4    5       /* Output writer postprocessor */
        !           111: #define AS     6
        !           112: #define LD     7
        !           113: #define LD2    8       /* Loader postprocessor */
        !           114: #define ED     9
        !           115: #define LIB    10
        !           116: #define CRT    11
        !           117: #define TMP    12
        !           118: #define ALL    13
        !           119: #define        CC2B    14      /* for monolithic compiler */
        !           120: 
        !           121: #define P_TAKE 1       /* Take pass from backup directory */
        !           122: #define P_BACK 2       /* Backup directory specified */
        !           123: #define P_LIB  4       /* Take pass from LIBPATH */
        !           124: #define P_BIN  8       /* Take pass from BIN */
        !           125: 
        !           126: #define PTMP   32      /* Pass name buffer size */
        !           127: 
        !           128: char   dnul[] = "";            /* Global null string */
        !           129: char   dmch[PTMP] = PREFIX;    /* Cross compiler prefix */
        !           130: 
        !           131: struct pass {
        !           132:        char p_flag;            /* Flags */
        !           133:        char p_psn;             /* Pass short name */
        !           134:        char p_pln[PTMP];       /* Pass long name */
        !           135:        char p_pfs[4];          /* Pass output file suffix */
        !           136:        char *p_ifn;            /* Input file name */
        !           137:        char *p_ofn;            /* Output file name */
        !           138:        char *p_sfn;            /* Scratch file name */
        !           139:        char *p_dir;            /* Path lookup or backup string */
        !           140:        char *p_mch;            /* Machine prefix name */
        !           141: } pass[] = {
        !           142:        { P_LIB, 'p', "cpp",  "i",      NULL, NULL, NULL, NULL, dmch },
        !           143:        { P_LIB, '0', "cc0",  "0",      NULL, NULL, NULL, NULL, dmch },
        !           144:        { P_LIB, '1', "cc1",  "1",      NULL, NULL, NULL, NULL, dmch },
        !           145:        { P_LIB, '2', "cc2",  "o",      NULL, NULL, NULL, NULL, dmch },
        !           146:        { P_LIB, '3', "cc3",  "s",      NULL, NULL, NULL, NULL, dmch },
        !           147:        { P_LIB, '4', "cc4",  "o",      NULL, NULL, NULL, NULL, dmch },
        !           148:        { P_BIN, 's', "as",   "o",      NULL, NULL, NULL, NULL, dmch },
        !           149:        { P_BIN, 'd', "ld",   "",       NULL, NULL, NULL, NULL, dnul },
        !           150:        { P_BIN, 'x', "ld2",  "",       NULL, NULL, NULL, NULL, dnul },
        !           151:        { P_BIN, 'e', "me",   "",       NULL, NULL, NULL, NULL, dnul },
        !           152:        { P_LIB, 'l', "lib",  "a",      NULL, NULL, NULL, NULL, dmch },
        !           153:        { P_LIB, 'r', "crts0.o", "",    NULL, NULL, NULL, NULL, dmch },
        !           154:        {     0, 't', "cc",    "",      NULL, NULL, NULL, NULL, dnul }
        !           155: };
        !           156: 
        !           157: /*
        !           158: ** Option and argument information.
        !           159: */
        !           160: #define CCOPT  0x001           /* Argument flags in argf[] */
        !           161: #define PPOPT  0x002           /* Also in option table, at least */
        !           162: #define LDOPT  0x004           /* those that fit in a byte */
        !           163: #define LD2OPT 0x008
        !           164: #define CCLIB  0x010
        !           165: #define LDLIB  0x020
        !           166: #define CCARG  0x040
        !           167: #define ASARG  0x080
        !           168: #define MARG   0x100
        !           169: #define LDARG  0x200
        !           170: 
        !           171: /* Flag bits for ccvariant. */
        !           172: #define FLAG_c 0x001           /* -c flag */
        !           173: #define FLAG_O 0x002           /* -O flag */
        !           174: #define FLAG_f 0x004           /* -f flag */
        !           175: #define FLAG_K 0x008           /* -K or -VKEEP flag */
        !           176: #define VS     0x010           /* Turn on strict messages */
        !           177: #define VDB    0x020           /* Turn on debugging */
        !           178: #define FLAG_A 0x040           /* Auto edit mode */
        !           179: #define FLAG_Z 0x080           /* Floppy change prompts */
        !           180: #define FLAG_V 0x100           /* Verbose flag */
        !           181: #if    GEMDOS
        !           182: #define FLAG_GEMAPP    0x200   /* Gem application compile */
        !           183: #define FLAG_GEMACC    0x400   /* Gem accessory compile */
        !           184: #endif
        !           185: #define        FLAG_a  0x800           /* Suppress output file name to ld */
        !           186: 
        !           187: struct option {                        /* option table */
        !           188:        char o_kind;
        !           189:        char o_flag;
        !           190:        char *o_name;
        !           191:        int o_bits;
        !           192: } option[] = {
        !           193: /* Strict */
        !           194:        { 0,    CCOPT,  "VSUREG",       VSUREG  },
        !           195:        { 0,    CCOPT,  "VSUVAR",       VSUVAR  },
        !           196:        { 0,    CCOPT,  "VSNREG",       VSNREG  },
        !           197:        { 0,    CCOPT,  "VSRTVC",       VSRTVC  },
        !           198:        { 0,    CCOPT,  "VSMEMB",       VSMEMB  },
        !           199:        { 0,    CCOPT,  "VSBOOK",       VSBOOK  },
        !           200:        { 0,    CCOPT,  "VSLCON",       VSLCON  },
        !           201:        { 0,    CCOPT,  "VSPVAL",       VSPVAL  },
        !           202:        { 0,    CCOPT,  "VSCCON",       VSCCON  },
        !           203: /*
        !           204:  * Debug.
        !           205:  * The -VDB option turns on all of these;
        !           206:  * no earlier option may start with "VD",
        !           207:  * and the next non-debug option must not start with "VD".
        !           208:  */
        !           209:        { 0,    CCOPT,  "VDEBUG",       VDEBUG  },      
        !           210:        { 0,    CCOPT,  "VDLINE",       VLINES  },
        !           211:        { 0,    CCOPT,  "VDTYPE",       VTYPES  },
        !           212:        { 0,    CCOPT,  "VDSYMB",       VDSYMB  },
        !           213: 
        !           214: /* Miscellaneous */
        !           215:        { 0,    CCOPT,  "VSTAT",        VSTAT   },
        !           216:        { 0,    CCOPT,  "VWIDEN",       VWIDEN  },
        !           217:        { 0,    CCOPT,  "VPEEP",        VPEEP   },
        !           218:        { 0,    CCOPT,  "VCOMM",        VCOMM   },
        !           219:        { 0,    CCOPT,  "VQUIET",       VQUIET  },
        !           220:        { 0,    CCOPT,  "VPSTR",        VPSTR   },
        !           221:        { 0,    CCOPT,  "VROM",         VROM    },
        !           222:        { 0,    CCOPT,  "VASM",         VASM    },
        !           223: 
        !           224:        { 0,    CCOPT,  "VLIB",         VLIB    },
        !           225:        { 0,    CCOPT,  "VNOWARN",      VNOWARN },
        !           226:        { 0,    CCOPT,  "VPROF",        VPROF   },
        !           227:        { 0,    CCOPT,  "VALIEN",       VALIEN  },
        !           228:        { 0,    CCOPT,  "VREADONLY",    VREADONLY },
        !           229:        { 0,    CCOPT,  "VSINU",        VSINU   },
        !           230:        { 0,    CCOPT,  "VNOOPT",       VNOOPT  },
        !           231:        { 0,    CCOPT,  "VCPLUS",       VCPLUS  },
        !           232:        { 0,    CCOPT,  "VCPPE",        VCPPE   },
        !           233:        { 0,    CCOPT,  "VCPPC",        VCPPC   },
        !           234:        { 0,    CCOPT,  "VCPP",         VCPP    },
        !           235:        { 0,    CCOPT,  "VTPROF",       VTPROF  },
        !           236:        { 0,    CCOPT,  "V3GRAPH",      V3GRAPH },
        !           237: #if 1
        !           238: /* Intel flags */
        !           239:        { 0,    CCOPT,  "VSMALL",       VSMALL  },
        !           240:        { 0,    CCOPT,  "VLARGE",       VLARGE  },
        !           241:        { 0,    CCOPT,  "V8087",        V8087   },
        !           242:        { 0,    CCOPT,  "VNDP",         VNDP    },
        !           243:        { 0,    CCOPT,  "VRAM",         VRAM    },
        !           244:        { 0,    CCOPT,  "VOMF",         VOMF    },
        !           245:        { 0,    CCOPT,  "V80186",       V80186  },
        !           246:        { 0,    CCOPT,  "V80287",       V80287  },
        !           247:        { 0,    CCOPT,  "VALIGN",       VALIGN  },
        !           248:        { 0,    CCOPT,  "VEMU87",       VEMU87  },
        !           249:        { 0,    CCOPT,  "VXSTAT",       VXSTAT  },
        !           250: #endif
        !           251: #if    GEMDOS
        !           252: /* Motorola and Gemdos flags */
        !           253:        { 12,   CCOPT,  "VGEMACC",      FLAG_GEMACC     },
        !           254:        { 12,   CCOPT,  "VGEMAPP",      FLAG_GEMAPP     },
        !           255:        { 12,   CCOPT,  "VGEM",         FLAG_GEMAPP     },
        !           256:        { 10,   CCOPT,  "VSPLIM",       VSPLIM  },
        !           257:        { 10,   CCOPT,  "VNOTRAPS",     VNOTRAPS        },
        !           258: #endif
        !           259: /* More miscellaneous flags */
        !           260:        { 2,    CCOPT,  "VDB",          VDB     },
        !           261:        { 2,    CCOPT,  "g",            VDB     },
        !           262:        { 2,    CCOPT,  "VS",           VS      },
        !           263:        { 12,   CCOPT,  "A",            FLAG_A  },
        !           264:        { 12,   CCOPT,  "a",            FLAG_a  },
        !           265:        { 12,   CCOPT,  "Z",            FLAG_Z  },
        !           266:        { 12,   CCOPT,  "c",            FLAG_c  },
        !           267:        { 10,   CCOPT,  "S",            VASM    },
        !           268:        { 2,    CCOPT,  "O",            FLAG_O  },
        !           269:        { 0,    CCOPT,  "E",            VCPPE   },
        !           270:        { 12,   CCOPT,  "f",            FLAG_f  },
        !           271:        { 12,   CCOPT,  "VFLOAT",       FLAG_f  },
        !           272:        { 0,    CCOPT,  "p",            VPROF   },
        !           273:        { 12,   CCOPT,  "VKEEP",        FLAG_K  },
        !           274:        { 12,   CCOPT,  "K",            FLAG_K  },
        !           275:        { 0,    CCOPT,  "Q",            VQUIET  },
        !           276:        { 11,   CCOPT,  "VVERSION"              },
        !           277:        { 12,   CCOPT,  "V",            FLAG_V  },      /* all -V* must precede this */
        !           278:        { 12,   CCOPT,  "v",            FLAG_V  },
        !           279: /* Preprocessor options */
        !           280:        { 3,    PPOPT,  "D"     },
        !           281:        { 3,    PPOPT,  "I"     },
        !           282:        { 3,    PPOPT,  "U"     },
        !           283: /* Loader options */
        !           284:        { 4,    LDOPT,  "d"     },
        !           285:        { 4,    LDOPT,  "i"     },
        !           286:        { 4,    LDOPT,  "n"     },
        !           287:        { 5,    LDOPT,  "o"     },
        !           288:        { 4,    LDOPT,  "r"     },
        !           289:        { 4,    LDOPT,  "s"     },
        !           290:        { 4,    LDOPT,  "w"     },
        !           291:        { 4,    LDOPT,  "x"     },
        !           292:        { 4,    LDOPT,  "X"     },
        !           293: #if    1
        !           294:        { 8,    LDOPT,  "L"     },
        !           295: #endif
        !           296:        { 5,    LDOPT,  "e"     },
        !           297:        { 5,    LDOPT,  "k"     },
        !           298:        { 5,    LDOPT,  "u"     },
        !           299: /* C dispatcher options */
        !           300:        { 6,    CCOPT,  "q"     },
        !           301:        { 7,    CCOPT,  "t"     },
        !           302:        { 7,    CCOPT,  "B"     },
        !           303:        { 7,    CCOPT,  "M"     },
        !           304:        { 7,    CCOPT,  "N"     },
        !           305: #if    TEMPBUF
        !           306:        { 9,    CCOPT,  "T"     },
        !           307: #endif
        !           308:        { 8,    CCLIB,  "l"     },
        !           309:        { 13,   CCOPT,  "?"     },
        !           310:        { -1,   -1,     ""      }
        !           311: };
        !           312: 
        !           313: int    ccvariant = 0;                  /* Variant template */
        !           314: VARIANT        variant;                        /* Binary variant template */
        !           315: char   vstr[2*VMAXIM/VGRANU + 1];      /* Ascii variant string */
        !           316: char   vstr2[2*VMAXIM/VGRANU + 1];     /* Ascii variant string for .m */
        !           317: 
        !           318: /*
        !           319: ** Compiler parameters and flags
        !           320: */
        !           321: #define        NCMDA   128             /* Size of argument pointer buffer */
        !           322: #define        NCMDB   1024            /* Size of argument buffer */
        !           323: #define        NTMP    L_tmpnam        /* Temp file buffer size, from stdio.h */
        !           324: #define        MAGIC   127             /* Exit status mask */
        !           325: #define        NSLEEP  10              /* # of sleeps */
        !           326: #define        DELAY   5               /* Sleep delay, seconds */
        !           327: 
        !           328: int    nldob;                  /* Number of objects created */
        !           329: int    nfile;                  /* Number of files to compile or assemble */
        !           330: int    nname;                  /* Number of file name arguments */
        !           331: int    ndota;
        !           332: int    ndotc;
        !           333: int    ndotm;
        !           334: int    ndoto;
        !           335: int    ndots;
        !           336: int    partial;                        /* Partial link specified */
        !           337: 
        !           338: #define        aflag   ((ccvariant&FLAG_a)!=0)
        !           339: #define        cflag   ((ccvariant&FLAG_c)!=0)
        !           340: #define pflag  isvariant(VPROF)
        !           341: #define        fflag   ((ccvariant&FLAG_f)!=0)
        !           342: #define        Kflag   ((ccvariant&FLAG_K)!=0)
        !           343: #define        Oflag   ((ccvariant&FLAG_O)!=0)
        !           344: #define Sflag  isvariant(VASM)
        !           345: #define        Eflag   isvariant(VCPPE)
        !           346: #define Vflag  ((ccvariant&FLAG_V)!=0)
        !           347: #define        Qflag   isvariant(VQUIET)
        !           348: #define        Aflag   ((ccvariant&FLAG_A)!=0)
        !           349: #define        Zflag   ((ccvariant&FLAG_Z)!=0)
        !           350: #if    GEMDOS
        !           351: #define GEMAPPflag     ((ccvariant&FLAG_GEMAPP)!=0)
        !           352: #define GEMACCflag     ((ccvariant&FLAG_GEMACC)!=0)
        !           353: #endif
        !           354: 
        !           355: int    qpass = NONE;           /* Quit after this pass */
        !           356: int    nload;                  /* No load phase */
        !           357: char   *outf;                  /* Output file */
        !           358: char   *doutf;                 /* Default output file stem */
        !           359: char   *dpath = DEFPATH;
        !           360: char   *dlibpath = DEFLIBPATH;
        !           361: int    xstat;                  /* Exit status */
        !           362: 
        !           363: char   *cmda[NCMDA];           /* Argument pointer buffer */
        !           364: char   cmdb[NCMDB];            /* Argument buffer */
        !           365: char   newo[NTMP];             /* New object to be removed */
        !           366: char   tmp[7][NTMP];           /* Intermediate filenames */
        !           367: char   istmp[7];               /* Truth about their temporariness */
        !           368: int    argf[NCMDA];            /* Argument flags */
        !           369: char   optb[NCMDB];            /* Option rewrite buffer */
        !           370: char   *optp = &optb[0];       /* Option rewrite position */
        !           371: 
        !           372: #if    TEMPBUF
        !           373: unsigned char  *inbuf;                 /* memory input buffer  */
        !           374: unsigned char  *inbufp;                /* input buffer pointer */
        !           375: unsigned char  *inbufmax;              /* input buffer end     */
        !           376: unsigned char  *outbuf;                /* memory output buffer */
        !           377: unsigned char  *outbufp;               /* output buffer pointer */
        !           378: unsigned char  *outbufmax;             /* output buffer end    */
        !           379: unsigned int   tempsize = 65536;       /* memory buffer size   */
        !           380: #endif
        !           381: 
        !           382: #if    MONOLITHIC
        !           383: int            monolithic = 1;         /* set to 0 if phases needed    */
        !           384: 
        !           385: /* Information passed to phases through globals in monolithic compiler */
        !           386: jmp_buf                death;                  /* for fatal error handling     */
        !           387: int            dotseg;                 /* current segment              */
        !           388: char           file[NFNAME];           /* current input file name      */
        !           389: char           basefile[NFNAME];       /* original input file name     */
        !           390: char           id[NCSYMB];             /* global identifier buffer     */
        !           391: FILE           *ifp;                   /* input FILE                   */
        !           392: int            line;                   /* line number                  */
        !           393: int            mflag;                  /* debug flag                   */
        !           394: char           module[NMNAME];         /* module name buffer           */
        !           395: int            oflag;                  /* debug flag                   */
        !           396: FILE           *ofp;                   /* output FILE                  */
        !           397: int            sflag;                  /* debug flag                   */
        !           398: #endif
        !           399: 
        !           400: /* Forward. */
        !           401: FILE   *ccopen();
        !           402: char   *makepass();
        !           403: char   *makelib();
        !           404: int    cleanup();
        !           405: 
        !           406: /* External. */
        !           407: char   *getenv();
        !           408: char   *malloc();
        !           409: char   *tempnam();
        !           410: char   *path();
        !           411: 
        !           412: main(argc, argv) int argc; char *argv[];
        !           413: {
        !           414:        register char *p;
        !           415:        register struct option *op;
        !           416:        int i, narg, c, n;
        !           417: 
        !           418: #if COHERENT
        !           419:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !           420:                signal(SIGINT, cleanup);
        !           421: #endif
        !           422: #if    _I386
        !           423:        /* Conditionalized only because _addargs() not in COH286 libc.a yet. */
        !           424:        _addargs("CC", &argc, &argv);
        !           425: #endif
        !           426:        setbuf(stdout, NULL);
        !           427:        setbuf(stderr, NULL);
        !           428:        setvariant(VSUVAR);
        !           429:        setvariant(VSMEMB);
        !           430:        setvariant(VSLCON);
        !           431:        setvariant(VSPVAL);
        !           432:        setvariant(VPEEP);
        !           433:        setvariant(VCOMM);
        !           434:        setvariant(VPSTR);
        !           435:        setvariant(V80186);
        !           436: 
        !           437: #if    0
        !           438:        printmem("initially");
        !           439: #endif
        !           440:        if (p = getenv("PATH")) dpath = p;
        !           441:        if (p = getenv("LIBPATH")) dlibpath = p;
        !           442:        if (p = getenv("EDITOR")) strcpy(pass[ED].p_pln, p);
        !           443: 
        !           444:        for (i=1; i<argc; i+=narg) {
        !           445:                narg = 1;
        !           446:                p = argv[i];
        !           447:                if (*p++ == '-') {
        !           448:                        /*
        !           449:                         * Process an option argument.
        !           450:                         * This is particularly squirrly because it allows
        !           451:                         * several options to be combined in a single arg.
        !           452:                         */
        !           453:                        char *ppopt = "";
        !           454:                        static char tldopt[64] = "-";
        !           455:                        char *tlp = &tldopt[1];
        !           456: 
        !           457:                        if (*p == '\0') {
        !           458:                badopt:
        !           459:                                whatopt(argv[i]);
        !           460:                                continue;
        !           461:                        }
        !           462:                        while (*p != '\0') {
        !           463:                                for (op = &option[0]; ; op += 1)
        !           464:                                        if (op->o_name[0] == '\0')
        !           465:                                                goto badopt;
        !           466:                                        else if (opeq(op->o_name, p))
        !           467:                                                break;
        !           468:                                if (VeryVflag && Vflag)
        !           469:                                        printf("Option: -%s\n", op->o_name);
        !           470:                                argf[i] |= op->o_flag;
        !           471:                                switch (op->o_kind) {
        !           472:                                case 0:
        !           473:                                        /* Toggle variant. */
        !           474:                                        chgvariant(op->o_bits);
        !           475:                                        p += strlen(op->o_name);
        !           476:                                        continue;
        !           477:                                case 10:
        !           478:                                        /* Set variant. */
        !           479:                                        setvariant(op->o_bits);
        !           480:                                        p += strlen(op->o_name);
        !           481:                                        continue;
        !           482:                                case 2:
        !           483:                                        /* Toggle ccvariant. */
        !           484:                                        ccvariant ^= op->o_bits;
        !           485:                                        p += strlen(op->o_name);
        !           486:                                        /* Set strict */
        !           487:                                        if ((ccvariant&VS) != 0) {
        !           488:                                                for (op = &option[0];; op += 1)
        !           489:                                                        if (op->o_name[1]=='S')
        !           490:                                                                break;
        !           491:                                                while (op->o_name[1]=='S') {
        !           492:                                                        setvariant(op->o_bits);
        !           493:                                                        op += 1;
        !           494:                                                }
        !           495:                                        }
        !           496:                                        /* Set debug */
        !           497:                                        if ((ccvariant&VDB) != 0) {
        !           498:                                                for (op = &option[0];; op += 1)
        !           499:                                                        if (op->o_name[1]=='D')
        !           500:                                                                break;
        !           501:                                                while (op->o_name[1]=='D') {
        !           502:                                                        setvariant(op->o_bits);
        !           503:                                                        op += 1;
        !           504:                                                }
        !           505:                                        }
        !           506:                                        continue;
        !           507:                                case 12:
        !           508:                                        /* Set ccvariant. */
        !           509:                                        ccvariant |= op->o_bits;
        !           510:                                        p += strlen(op->o_name);
        !           511:                                        continue;
        !           512:                                case 3:
        !           513:                                        /* Preprocessor options. */
        !           514:                                        ppopt = p;
        !           515:                                        p += strlen(p);
        !           516:                                        continue;
        !           517:                                case 5:
        !           518:                                        /* ld options with file args */
        !           519:                                        if (*p == 'o') {
        !           520:                                                outf = argv[i+narg];
        !           521:                                        }
        !           522:                                        if (*p == 'u')
        !           523:                                                ndoto += 1;
        !           524:                                        if (i+narg >= argc)
        !           525:                                                missingname();
        !           526:                                        argf[i+narg++] = LDOPT;
        !           527:                                        /* Fall through */
        !           528:                                case 4:
        !           529:                                        /* ld options without args */
        !           530:                                        if (*p == 'r')
        !           531:                                                ++partial;
        !           532:                                        n = strlen(op->o_name);
        !           533:                                        if (tlp + n >= &tldopt[64])
        !           534:                                                cquit("ld args too long");
        !           535:                                        strcpy(tlp, op->o_name);
        !           536:                                        tlp += n;
        !           537:                                        p += n;
        !           538:                                        continue;
        !           539:                                case 6:
        !           540:                                        /* -q */
        !           541:                                        if ((c = p[1]) == '\0'
        !           542:                                         || (c = getpsn(c)) < CPP)
        !           543:                                                goto badopt;
        !           544:                                        qpass = c;
        !           545:                                        p += 2;
        !           546:                                        continue;
        !           547:                                case 7:
        !           548:                                        /* Pass renaming options -tBMN */
        !           549: #if    MONOLITHIC
        !           550:                                        monolithic = 0;         /* need phases */
        !           551: #if    TEMPBUF
        !           552:                                        tempsize = 0;           /* use disk temps */
        !           553: #endif
        !           554: #endif
        !           555:                                        c = p[0];
        !           556:                                        getpass(c, p+1);
        !           557:                                        p = dnul;
        !           558:                                        continue;
        !           559:                                case 8:
        !           560:                                        /* -l */
        !           561:                                        p = dnul;
        !           562:                                        continue;
        !           563: #if    TEMPBUF
        !           564:                                case 9:
        !           565:                                        /* -T */
        !           566:                                        tempsize = atoi(++p);
        !           567:                                        tempsize = (tempsize + 3) & ~3;
        !           568:                                        p = dnul;
        !           569:                                        continue;
        !           570: #endif
        !           571:                                case 11:
        !           572:                                        /* -VVERSION */
        !           573:                                        p += strlen(op->o_name);
        !           574:                                        fprintf(stderr, "cc: "
        !           575: #if    COHERENT
        !           576:                                                "COHERENT "
        !           577: #endif
        !           578: #if    _I386
        !           579:                                                "i386 "
        !           580: #endif
        !           581:                                                "cc " VERSMWC "\n");
        !           582:                                        break;
        !           583: 
        !           584:                                case 13:
        !           585:                                        /* -? */
        !           586:                                        usage(1);
        !           587:                                        break;
        !           588:                                default:
        !           589:                                        cquit("options");
        !           590:                                }
        !           591:                        }
        !           592:                        if (((unsigned)argf[i]-1)&((unsigned)argf[i])) {
        !           593:                                /*
        !           594:                                 * Handle multiple arg types in a single arg
        !           595:                                 * by writing the arg,
        !           596:                                 * then the cpp form of the arg,
        !           597:                                 * then the ld form of the arg.
        !           598:                                 * runpp and runld understand how to grovel
        !           599:                                 * for their args when this gets used,
        !           600:                                 * undoing this braindamage.
        !           601:                                 */
        !           602:                                if (optp + strlen(argv[i]) + 1
        !           603:                                         + 1 + strlen(ppopt) + 1
        !           604:                                         + strlen(tldopt) + 1 >= &optb[NCMDB])
        !           605:                                        cquit("option buffer overflow");
        !           606:                                strcpy(optp, argv[i]);
        !           607:                                argv[i] = optp;
        !           608:                                optp += strlen(optp)+1;
        !           609:                                *optp++ = '-';
        !           610:                                strcpy(optp, ppopt);
        !           611:                                optp += strlen(optp)+1;
        !           612:                                strcpy(optp, tldopt);
        !           613:                                optp += strlen(optp)+1;
        !           614:                        }
        !           615:                } else {
        !           616:                        while (*p) p+=1;
        !           617:                        c = *--p;
        !           618:                        if (*--p != '.') c = 0;
        !           619:                        if (c >= 'A' && c <= 'Z')
        !           620:                                c |= 'a'-'A';
        !           621:                        switch (c) {
        !           622:                        case 'h':
        !           623:                        case 'c':
        !           624:                                if (doutf == NULL) doutf = argv[i];
        !           625:                                ndotc += 1;
        !           626:                                argf[i] = CCARG;
        !           627:                                if (VeryVflag && Vflag)
        !           628:                                        printf("cc file: %s\n", argv[i]);
        !           629:                                break;
        !           630:                        case 's':
        !           631:                                if (doutf == NULL) doutf = argv[i];
        !           632:                                ndots += 1;
        !           633:                                argf[i] = ASARG;
        !           634:                                if (VeryVflag && Vflag)
        !           635:                                        printf("as file: %s\n", argv[i]);
        !           636:                                break;
        !           637:                        case 'm':
        !           638:                                if (doutf == NULL) doutf = argv[i];
        !           639:                                ndotm += 1;
        !           640:                                argf[i] = MARG;
        !           641:                                if (VeryVflag && Vflag)
        !           642:                                        printf("m file: %s\n", argv[i]);
        !           643:                                break;
        !           644:                        case 'o':
        !           645:                                if (doutf == NULL) doutf = argv[i];
        !           646:                                ndoto += 1;
        !           647:                                argf[i] = LDARG;
        !           648:                                if (VeryVflag && Vflag)
        !           649:                                        printf("ld file: %s\n", argv[i]);
        !           650:                                break;
        !           651:                        case 'a':
        !           652:                        default:
        !           653:                                ndota += 1;
        !           654:                                argf[i] = LDLIB;
        !           655:                                if (VeryVflag && Vflag)
        !           656:                                        printf("library: %s\n", argv[i]);
        !           657:                                break;
        !           658:                        }
        !           659:                }
        !           660:        }
        !           661: #if    GEMDOS
        !           662:        if (Vflag) {
        !           663:         fprintf(stderr, "Mark Williams C for the Atari ST, %s\n", VERS);
        !           664:         fprintf(stderr, "Copyright 1984-1987, Mark Williams Co., Chicago\n");
        !           665:        }
        !           666: #endif
        !           667:        resolve();
        !           668:        compile(argc, argv);
        !           669:        if (nload==0 && runld(argc, argv)==0) {
        !           670:                if (Kflag==0 && nldob==1 && newo[0]!=0)
        !           671:                        rm(newo);
        !           672:        }
        !           673: #if    TEMPBUF
        !           674:        if (inbuf != NULL)
        !           675:                free(inbuf);
        !           676:        if (outbuf != NULL)
        !           677:                free(outbuf);
        !           678: #if    0
        !           679:        printmem("before exit");
        !           680: #endif
        !           681: #endif
        !           682:        exit(xstat);
        !           683: }
        !           684: 
        !           685: /*
        !           686:  * Resolve remaining ambiguities.
        !           687:  * Initialize variant arguments and files.
        !           688:  */
        !           689: resolve()
        !           690: {
        !           691:        register int i;
        !           692: 
        !           693: #if    TEMPBUF
        !           694:        register char *p;
        !           695: 
        !           696:        /*
        !           697:         * The following malloc is a temporary hack for COH386 efficiency.
        !           698:         * The rationale is:
        !           699:         * (1) reduce the number of required sbrk() calls, and
        !           700:         * (2) reduce the risk of running out of memory,
        !           701:         * because COH386 without paging requires old+new bytes free
        !           702:         * to grow from old to new.
        !           703:         * This will doubtless be changed in the future.
        !           704:         */
        !           705: #define        NARENA  131072
        !           706:        if ((p = malloc(tempsize + tempsize + NARENA)) != NULL)
        !           707:                free(p);
        !           708:        if (tempsize != 0 && Eflag == 0 && Kflag == 0) {
        !           709:                inbuf = malloc(tempsize);
        !           710:                outbuf = malloc(tempsize);
        !           711:                outbufp = outbuf;
        !           712:                outbufmax = outbuf + tempsize;
        !           713:                if (inbuf == NULL || outbuf == NULL) {
        !           714:                        fprintf(stderr, "cc: in-memory tempfile buffer allocation failed\n");
        !           715:                        if (inbuf != NULL)
        !           716:                                free(inbuf);
        !           717:                        inbuf = outbuf = NULL;
        !           718:                }
        !           719:        }
        !           720: #if    0
        !           721:        printmem("after buffer allocation");
        !           722: #endif
        !           723: #endif
        !           724:        for (i = CPP; i < ALL; i += 1) {
        !           725:                if (pass[i].p_flag & P_BACK)
        !           726:                        ;
        !           727:                else if (pass[i].p_flag & P_LIB)
        !           728:                        pass[i].p_dir = dlibpath;
        !           729:                else if (pass[i].p_flag & P_BIN)
        !           730:                        pass[i].p_dir = dpath;
        !           731:                strcpy(cmdb, pass[i].p_mch);
        !           732:                strcat(cmdb, pass[i].p_pln);
        !           733: #if    GEMDOS
        !           734:                if (i <= ED && strchr(pass[i].p_pln, '.') == NULL)
        !           735:                        strcat(cmdb, i==ED ? ".tos" : ".prg");
        !           736: #endif
        !           737:                if (strlen(cmdb) > PTMP-1)
        !           738:                        cquit("pass name \"%s\" is too long", cmdb);
        !           739:                strcpy(pass[i].p_pln, cmdb);
        !           740:        }
        !           741: #if 1
        !           742:        if (isvariant(VOMF)) {
        !           743:                clrvariant(VCOMM);
        !           744:                if (isvariant(VLARGE) && isvariant(VSMALL))
        !           745:                        cquit("invalid model specification");
        !           746:                if (notvariant(VLARGE) && notvariant(VSMALL))
        !           747:                        setvariant(VSMALL);
        !           748:        } else {
        !           749:                clrvariant(VLARGE);
        !           750:                setvariant(VSMALL);
        !           751:        }
        !           752: #endif
        !           753: #if    GEMDOS
        !           754:        if (GEMAPPflag && GEMACCflag)
        !           755:                cquit("specify VGEMAPP or VGEMACC, not both");
        !           756:        if (GEMAPPflag) getpass('N', "rcrtsg.o");
        !           757:        if (GEMACCflag) getpass('N', "rcrtsd.o");
        !           758: #endif
        !           759:        if (pflag) getpass('N', "rmcrts0.o");
        !           760:        if (Eflag) setvariant(VCPP);
        !           761:        if (qpass == NONE) {
        !           762:                if (isvariant(VCPP))
        !           763:                        qpass = CPP;
        !           764:                else if (Sflag)
        !           765:                        qpass = CC3;
        !           766:                else if (cflag)
        !           767:                        qpass = AS;
        !           768:                else
        !           769:                        qpass = LD;
        !           770:        } else if (qpass == CPP)
        !           771:                setvariant(VCPP);
        !           772:        if (VeryVflag && Vflag)
        !           773:                printf("quit pass is %s\n", pass[qpass].p_pln);
        !           774:        makvariant(vstr);
        !           775:        if (ndotm != 0 && notvariant(VCPP) && notvariant(VCPPE)) {
        !           776:                setvariant(VCPP);
        !           777:                setvariant(VCPPE);
        !           778:                makvariant(vstr2);
        !           779:                clrvariant(VCPP);
        !           780:                clrvariant(VCPPE);
        !           781:        }
        !           782:        nfile = ndotc + ndots + ndotm;
        !           783:        nname = nfile + ndoto + ndota;
        !           784:        if (nname == 0)
        !           785:                usage(0);
        !           786:        if (qpass < LD)
        !           787:                ++nload;
        !           788:        if (Aflag)
        !           789:                maketempfile(6);
        !           790:        if ( ! Eflag) {
        !           791:                chkofile();
        !           792:                if (Kflag) {
        !           793:                        pass[CPP].p_ofn = pass[CC0].p_ifn = tmp[0];
        !           794:                        pass[CC0].p_ofn = pass[CC1].p_ifn = tmp[1];
        !           795:                        pass[CC1].p_ofn = pass[CC2].p_ifn = tmp[2];
        !           796:                        if ( ! Sflag) {
        !           797:                                pass[CC2].p_sfn = tmp[3];
        !           798:                                pass[CC2].p_ofn = tmp[5];
        !           799:                        } else {
        !           800:                                pass[CC3].p_ifn = pass[CC2].p_ofn = tmp[3];
        !           801:                                pass[CC3].p_ofn = tmp[5];
        !           802:                        }
        !           803:                } else {
        !           804:                        pass[CPP].p_ofn = pass[CC0].p_ifn = tmp[0];
        !           805:                        pass[CC0].p_ofn = pass[CC1].p_ifn = tmp[1];
        !           806:                        pass[CC1].p_ofn = pass[CC2].p_ifn = tmp[0];
        !           807:                        if ( ! Sflag) {
        !           808:                                pass[CC2].p_sfn = tmp[1];
        !           809:                                pass[CC2].p_ofn = tmp[5];
        !           810:                        } else {
        !           811:                                pass[CC3].p_ifn = pass[CC2].p_ofn = tmp[1];
        !           812:                                pass[CC3].p_ofn = tmp[5];
        !           813:                        }
        !           814: #if    TEMPBUF
        !           815:                        if (inbuf != NULL && outbuf != NULL)
        !           816:                                tmp[0][0] = tmp[1][0] = '\0';
        !           817:                        else
        !           818: #endif
        !           819:                        {
        !           820:                                maketempfile(0);
        !           821:                                maketempfile(1);
        !           822:                        }
        !           823:                }
        !           824:                pass[AS].p_ofn = tmp[5];
        !           825:        }
        !           826: }
        !           827: 
        !           828: maketempfile(i) register int i;
        !           829: {
        !           830:        register char *p;
        !           831: 
        !           832:        strcpy(tmp[i], p = tempnam(pass[TMP].p_dir, pass[TMP].p_pln));
        !           833:        free(p);
        !           834:        ++istmp[i];
        !           835: }
        !           836: 
        !           837: /*
        !           838: ** Compilation.
        !           839: */
        !           840: compile(argc, argv) int argc; char *argv[];
        !           841: {
        !           842:        register char *p1;
        !           843:        register c, i, err;
        !           844: 
        !           845:        err = 0;
        !           846:        for (i=1; i<argc; ++i) {
        !           847:                if ((c = (argf[i] & (CCARG | ASARG | MARG))) == 0)
        !           848:                        continue;
        !           849:                p1 = argv[i];
        !           850:                if (err) {
        !           851:                        err = 0;
        !           852:                        if (runme(p1)) {
        !           853:                                ++nload;
        !           854:                        } else {
        !           855:                                --i;
        !           856:                                xstat = 0;
        !           857:                        }
        !           858:                        continue;
        !           859:                }
        !           860:                if (nfile > 1 && Qflag == 0)
        !           861:                        printf("%s:\n", p1);
        !           862:                setfiles(c, p1);
        !           863:                if (c == CCARG) {
        !           864:                        if (runpp(argc, argv, vstr)) {
        !           865:                                if (Aflag) {
        !           866:                                        ++err; --i;
        !           867:                                } else
        !           868:                                        ++nload;
        !           869:                                continue;
        !           870:                        }
        !           871:                        if (qpass <= CC0)
        !           872:                                continue;
        !           873:                        if (runcc(CC1)) {
        !           874:                                ++nload;
        !           875:                                continue;
        !           876:                        }
        !           877:                        if (qpass <= CC1)
        !           878:                                continue;
        !           879:                        if (runcc(CC2)) {
        !           880:                                ++nload;
        !           881:                                continue;
        !           882:                        }
        !           883:                        if (qpass <= CC2)
        !           884:                                continue;
        !           885:                        if (Sflag) {
        !           886:                                if (runcc(CC3)) {
        !           887:                                        ++nload;
        !           888:                                        continue;
        !           889:                                }
        !           890:                                if (qpass <= CC3)
        !           891:                                        continue;
        !           892:                        }
        !           893:                } else if (c == ASARG && qpass>=AS) {
        !           894:                        if (runas()) {
        !           895:                                if (Aflag) {
        !           896:                                        ++err; --i;
        !           897:                                } else
        !           898:                                        ++nload;
        !           899:                                continue;
        !           900:                        }
        !           901:                        if (qpass <= AS)
        !           902:                                continue;
        !           903:                } else if (c == MARG) {
        !           904:                        if (runpp(argc, argv, vstr2)) {
        !           905:                                if (Aflag) {
        !           906:                                        ++err; --i;
        !           907:                                } else
        !           908:                                        ++nload;
        !           909:                                continue;
        !           910:                        }
        !           911:                        if (qpass < AS)
        !           912:                                continue;
        !           913:                        if (runas()) {
        !           914:                                if (Aflag) {
        !           915:                                        ++err; --i;
        !           916:                                } else
        !           917:                                        ++nload;
        !           918:                                continue;
        !           919:                        }
        !           920:                        if (qpass == AS)
        !           921:                                continue;
        !           922:                }
        !           923:                makeft(p1, p1, "o");
        !           924:        }
        !           925:        cleanup(0);
        !           926: }
        !           927: 
        !           928: runpp(argc, argv, var) int argc; register char *argv[]; char var[];
        !           929: {
        !           930:        register char **cp;
        !           931:        register int i;
        !           932:        char *p1;
        !           933: #if    MONOLITHIC
        !           934:        int status;
        !           935:        extern int nerr;                        /* in common/diag.c */
        !           936: #endif
        !           937: 
        !           938:        cp = cmda;
        !           939: #if    MONOLITHIC
        !           940:        if (monolithic) {
        !           941:                nerr = 0;
        !           942:                *cp++ = "cc0";
        !           943:        } else {
        !           944: #endif
        !           945:                p1 = cmdb;
        !           946:                p1 = makepass(CC0, *cp++ = p1, AEXEC);
        !           947: #if    MONOLITHIC
        !           948:        }
        !           949: #endif
        !           950:        *cp++ = var;
        !           951:        *cp++ = pass[CPP].p_ifn;
        !           952:        if (qpass < CC0)
        !           953:                p1 = *cp++ = Kflag ? pass[CPP].p_ofn : "-";
        !           954:        else
        !           955:                p1 = *cp++ = pass[CC0].p_ofn;
        !           956:        for (i=1; i<argc; ++i) {
        !           957:                if ((argf[i]&PPOPT) != 0) {
        !           958:                        *cp++ = argv[i];
        !           959:                        if ((argf[i]&~PPOPT) != 0)      /* see comment in main */
        !           960:                                cp[-1] += strlen(cp[-1])+1;
        !           961:                }
        !           962:        }
        !           963:        *cp = 0;
        !           964: #if    MONOLITHIC
        !           965:        if (monolithic) {
        !           966:                if ((ifp = fopen(pass[CPP].p_ifn, "r")) == NULL) {
        !           967:                        fprintf(stderr, "cc: cannot open %s\n", pass[CPP].p_ifn);
        !           968:                        return 1;
        !           969:                }
        !           970:                if (Eflag)
        !           971:                        ofp = (strcmp(p1, "-") == 0) ? stdout : ccopen(p1, "w");
        !           972:                else
        !           973:                        ofp = (*p1 == '\0') ? NULL : ccopen(p1, SWMODE);
        !           974:                argc = cp - cmda;
        !           975:                if (Vflag) {
        !           976:                        for (i = 0; i < argc; i++)
        !           977:                                printf("%s ", cmda[i]);
        !           978:                        if (ofp == NULL)
        !           979:                                printf("0x%x", outbuf);
        !           980:                        printf("\n");
        !           981:                }
        !           982:                if (Aflag)
        !           983:                        err_open();
        !           984:                status = cc0(argc, cmda);
        !           985:                if (Aflag)
        !           986:                        err_close(status);
        !           987:                closeinout();
        !           988: #if    0
        !           989:                printmem("after cc0");
        !           990: #endif
        !           991:                if (status)
        !           992:                        xstat = 1;
        !           993:                return status;
        !           994:        }
        !           995: #endif
        !           996:        return run(Aflag, 0);
        !           997: }
        !           998: 
        !           999: #if    MONOLITHIC
        !          1000: 
        !          1001: #if    0
        !          1002: /* This is temporary stuff, here for malloc arena debugging. */
        !          1003: /* Knows format of malloc arena. */
        !          1004: #include <sys/malloc.h>
        !          1005: printmem(s) char *s;
        !          1006: {
        !          1007:        register int i, j;
        !          1008:        unsigned int u;
        !          1009:        register MBLOCK *p;
        !          1010:        register unsigned char *cp;
        !          1011:        int nfree, nused, bfree, bused, freef;
        !          1012: 
        !          1013:        printf("%s:\n", s);
        !          1014:        printf("__a_count=%d\n", __a_count);
        !          1015:        printf("__a_scanp=%x\n", __a_scanp);
        !          1016:        printf("__a_first=%x\n", __a_first);
        !          1017:        nfree = nused = bfree = bused = 0;
        !          1018:        for (p = __a_first, i = 0; i < __a_count; i++) {
        !          1019:                u = p->blksize;
        !          1020:                freef = isfree(u);
        !          1021:                u = realsize(u);
        !          1022:                printf("%x: size %d ", p, u-4);
        !          1023:                if (freef) {
        !          1024:                        printf("free\n");
        !          1025:                        ++nfree;
        !          1026:                        bfree += u - sizeof(unsigned);
        !          1027:                } else {
        !          1028:                        ++nused;
        !          1029:                        if (u != 0) {
        !          1030:                                printf("%x: size %d ", p, u-4);
        !          1031:                                printf("used\n");
        !          1032:                                bused += u - sizeof(unsigned);
        !          1033:                        }
        !          1034:                        if (u != tempsize + 4) {
        !          1035:                                for (j = 4, cp = (char *)p + 4; j < u; j++)
        !          1036:                                        printf("%02x ", *cp++);
        !          1037:                                printf("\n");
        !          1038:                        }
        !          1039:                }
        !          1040:                p = bumpp(p, u);
        !          1041:        }
        !          1042:        printf("nfree=%d nused=%d\n", nfree, nused-1);
        !          1043:        printf("bfree=%d bused=%d overhead=%d total=%d\n",
        !          1044:                bfree, bused, 4*(nfree+nused+1), bfree+bused+4*(nfree+nused+1));
        !          1045: }
        !          1046: #endif
        !          1047: 
        !          1048: /*
        !          1049:  * Close input and output files as appropriate.
        !          1050:  */
        !          1051: closeinout()
        !          1052: {
        !          1053:        if (ifp != NULL) {
        !          1054:                fclose(ifp);
        !          1055:                ifp = NULL;
        !          1056:        }
        !          1057:        if (ofp != NULL) {
        !          1058:                fclose(ofp);
        !          1059:                ofp = NULL;
        !          1060:        }
        !          1061: }
        !          1062: 
        !          1063: /*
        !          1064:  * Set input and output file pointers for monolithic compiler.
        !          1065:  * Print verbose phase message if Vflag.
        !          1066:  */
        !          1067: setinout(pn) register int pn;
        !          1068: {
        !          1069:        register char *p, *in, *out, *ln;
        !          1070: 
        !          1071:        if (pn == CC2B) {
        !          1072:                ln = "cc2b";
        !          1073:                in = pass[CC2].p_sfn;
        !          1074:                out = pass[CC2].p_ofn;
        !          1075:        } else {
        !          1076:                in = pass[pn].p_ifn;
        !          1077:                if (pn == CC2) {
        !          1078:                        ln = "cc2a";
        !          1079:                        out = (Sflag) ? pass[pn].p_ofn : pass[pn].p_sfn;
        !          1080:                } else {
        !          1081:                        ln = pass[pn].p_pln;
        !          1082:                        out = pass[pn].p_ofn;
        !          1083:                }
        !          1084:        }
        !          1085:        if (Vflag)
        !          1086:                printf("%s %s ", ln, vstr);
        !          1087:        if (*in == '\0') {
        !          1088:                ifp = NULL;
        !          1089:                p = inbuf;
        !          1090:                inbuf = inbufp = outbuf;
        !          1091:                inbufmax = outbufp;
        !          1092:                outbuf = outbufp = p;
        !          1093:                outbufmax = outbuf + tempsize;
        !          1094:                if (Vflag)
        !          1095:                        printf("0x%x ", inbuf);
        !          1096:        } else {
        !          1097:                ifp = ccopen(in, SRMODE);
        !          1098:                if (Vflag)
        !          1099:                        printf("%s ", in);
        !          1100:        }
        !          1101:        if (*out == '\0') {
        !          1102:                ofp = NULL;
        !          1103:                if (Vflag)
        !          1104:                        printf("0x%x\n", outbuf);
        !          1105:        } else {
        !          1106:                ofp = ccopen(out, SWMODE);
        !          1107:                if (Vflag)
        !          1108:                        printf("%s\n", out);
        !          1109:        }
        !          1110: }
        !          1111: #endif
        !          1112: 
        !          1113: runcc(pn) register int pn;
        !          1114: {
        !          1115:        register char **cp;
        !          1116: #if    MONOLITHIC
        !          1117:        register int status;
        !          1118: 
        !          1119:        if (monolithic) {
        !          1120:                setinout(pn);
        !          1121:                switch(pn) {
        !          1122:                case CC1:
        !          1123:                                status = cc1();
        !          1124:                                break;
        !          1125:                case CC2:
        !          1126:                                if (status = cc2a())
        !          1127:                                         break;
        !          1128:                                if (!Sflag) {
        !          1129:                                        closeinout();
        !          1130:                                        setinout(CC2B);
        !          1131:                                        status = cc2b();
        !          1132:                                }
        !          1133:                                break;
        !          1134:                case CC3:
        !          1135:                                status = cc3();
        !          1136:                                break;
        !          1137:                default:
        !          1138:                                cquit("bad pass number %d", pn);
        !          1139:                                break;
        !          1140:                }
        !          1141:                closeinout();
        !          1142: #if    0
        !          1143:                printmem((pn == CC1) ? "after cc1": (pn == CC2) ? "after cc2" : "after cc3");
        !          1144: #endif
        !          1145:                return status;
        !          1146:        }
        !          1147: #endif
        !          1148:        cp = cmda;
        !          1149:        makepass(pn, *cp++ = cmdb, AEXEC);
        !          1150:        *cp++ = vstr;
        !          1151:        *cp++ = pass[pn].p_ifn;
        !          1152:        *cp++ = pass[pn].p_ofn;
        !          1153:        if (pn == CC2)
        !          1154:                *cp++ = pass[CC2].p_sfn;
        !          1155:        *cp = 0;
        !          1156:        return run(0, 0);
        !          1157: }
        !          1158: 
        !          1159: runas()
        !          1160: {
        !          1161:        register char **cp;
        !          1162: 
        !          1163:        cp = cmda;
        !          1164:        makepass(AS, *cp++ = cmdb, AEXEC);
        !          1165: #if    _I386
        !          1166:        *cp++ = "-fgx";
        !          1167:        if (Qflag)
        !          1168:                *cp++ = "-w";
        !          1169: #else
        !          1170:        *cp++ = "-gx";
        !          1171: #endif
        !          1172:        *cp++ = "-o";
        !          1173:        *cp++ = pass[AS].p_ofn;
        !          1174:        *cp++ = pass[AS].p_ifn;
        !          1175:        *cp = 0;
        !          1176:        return run(Aflag, 0);
        !          1177: }
        !          1178: 
        !          1179: runme(fn)
        !          1180: char *fn;
        !          1181: {
        !          1182:        register char **cp;
        !          1183: 
        !          1184:        cp = cmda;
        !          1185:        makepass(ED, *cp++ = cmdb, AEXEC);
        !          1186:        *cp++ = fn;
        !          1187:        *cp++ = "-e";
        !          1188:        *cp++ = tmp[6];
        !          1189:        *cp = 0;
        !          1190:        return run(0, 0);
        !          1191: }
        !          1192: runld(argc, argv)
        !          1193: char *argv[];
        !          1194: {
        !          1195:        char *p1;
        !          1196:        register char *p2;
        !          1197:        register char **cp;
        !          1198:        char **cp1;
        !          1199:        register char **cp2;
        !          1200:        int i;
        !          1201:        static char buff[32];
        !          1202: 
        !          1203:        cp = cmda;
        !          1204:        p1 = makepass(LD, *cp++ = cmdb, AEXEC);
        !          1205:        *cp++ = ((ccvariant&VDB) != 0) ? "-g" : "-X";
        !          1206: #if    _I386
        !          1207:        if (Qflag)
        !          1208:                *cp++ = "-Q";
        !          1209: #endif
        !          1210:        if (isvariant(VNDP)) {
        !          1211:                /*
        !          1212:                 * This gets libraries and rts from /lib/ndp on system
        !          1213:                 * with both software fp and NDP libraries, hack hack...
        !          1214:                 * It also puts /usr/lib/ndp in the ld library search path.
        !          1215:                 */
        !          1216:                pass[CRT].p_flag |= P_BACK;
        !          1217:                pass[CRT].p_dir = "/lib/ndp";
        !          1218:                *cp++ = "-L/lib/ndp";
        !          1219:                *cp++ = "-L/usr/lib/ndp";
        !          1220:        }
        !          1221:        if (outf == NULL && !aflag) {
        !          1222:                *cp++ = "-o";
        !          1223:                if (partial || doutf == NULL) {
        !          1224: #if    COHERENT
        !          1225: #if    _I386
        !          1226:                        *cp++ = "a.out";
        !          1227: #else
        !          1228:                        *cp++ = "l.out";
        !          1229: #endif
        !          1230: #endif
        !          1231: #if    GEMDOS
        !          1232:                        *cp++ = "l.prg";
        !          1233: #endif
        !          1234:                } else {
        !          1235:                        basename(doutf, buff);
        !          1236: #if    GEMDOS
        !          1237:                        strcat(buff, ".prg");
        !          1238: #endif
        !          1239:                        *cp++ = buff;
        !          1240:                }
        !          1241:        }
        !          1242:        for (i=1; i<argc; ++i) {
        !          1243:                if ((argf[i]&LDOPT)!=0) {
        !          1244:                        *cp++ = argv[i];
        !          1245:                        if ((argf[i]&~LDOPT)!=0) {      /* see comment in main */
        !          1246:                                cp[-1] += strlen(cp[-1])+1;
        !          1247:                                cp[-1] += strlen(cp[-1])+1;
        !          1248:                        }
        !          1249:                }
        !          1250:        }
        !          1251:        cp1 = cp;
        !          1252:        p1 = makepass(CRT, *cp++ = p1, AREAD);
        !          1253:        if (fflag) {
        !          1254:                *cp++ = "-u";
        !          1255:                *cp++ = DTEFG;
        !          1256:        }
        !          1257:        for (i=1; i<argc; ++i) {
        !          1258:                p2 = argv[i];
        !          1259:                if ((argf[i]&CCLIB)!=0) {
        !          1260:                        while (*p2++ != 'l');
        !          1261:                        p1 = makelib(LIB, *cp++ = p1, p2);
        !          1262:                } else if ((argf[i]&(CCARG|ASARG|MARG|LDARG))!=0) {
        !          1263:                        for (cp2=cp1; cp2<cp; ++cp2)
        !          1264:                                if (strcmp(*cp2, p2) == 0)
        !          1265:                                        break;
        !          1266:                        if (cp2 == cp) {
        !          1267:                                *cp++ = p2;
        !          1268:                                ++nldob;
        !          1269:                        }
        !          1270:                } else if ((argf[i]&LDLIB)!=0) {
        !          1271:                        *cp++ = p2;
        !          1272:                }
        !          1273:        }
        !          1274: #if    GEMDOS
        !          1275:        if ( ! partial && (GEMAPPflag || GEMACCflag)) {
        !          1276:                p1 = makelib(LIB, *cp++ = p1, "aes");
        !          1277:                p1 = makelib(LIB, *cp++ = p1, "vdi");
        !          1278:        }
        !          1279: #endif
        !          1280:        p1 = makelib(LIB, *cp++ = p1, "c");
        !          1281: #if    _I386
        !          1282:        if (Kflag == 0 && nldob == 1 && newo[0] != 0) {
        !          1283:                *cp++ = "-Z";
        !          1284:                *cp++ = newo;
        !          1285:        }
        !          1286: #endif
        !          1287:        *cp = 0;
        !          1288:        return run(0, 1);
        !          1289: }
        !          1290: 
        !          1291: basename(in, out)
        !          1292: char *in, *out;
        !          1293: {
        !          1294:        register char *s;
        !          1295:        register int n;
        !          1296: 
        !          1297:        if ((s = strrchr(in, PATHSEP)) != NULL)
        !          1298:                in = ++s;               /* skip past last PATHSEP */
        !          1299:        if ((s = strrchr(in, '.')) != NULL)
        !          1300:                n = s - in;             /* copy to last '.' */
        !          1301:        else
        !          1302:                n = strlen(in);         /* copy all */
        !          1303:        strncpy(out, in, n);            /* copy as appropriate */
        !          1304:        out[n] = '\0';                  /* and NUL-terminate */
        !          1305: }
        !          1306: 
        !          1307: run(catch_errors, nofork) int catch_errors; int nofork;
        !          1308: {
        !          1309:        int s;
        !          1310:        extern char **environ;
        !          1311: 
        !          1312:        if (Vflag) {
        !          1313:                char *cp, **cpp;
        !          1314:                cpp = cmda;
        !          1315:                while ((cp = *cpp) != NULL) {
        !          1316:                        if (cpp != cmda)
        !          1317:                                putchar(' ');
        !          1318:                        printf("%s", cp);
        !          1319:                        ++cpp;
        !          1320:                }
        !          1321:                putchar('\n');
        !          1322:                fflush(stdout);
        !          1323:        }
        !          1324:        if (catch_errors)
        !          1325:                err_open();
        !          1326: #if    COHERENT
        !          1327: #if    _I386
        !          1328:        if (nofork) {
        !          1329:                execve(cmda[0], cmda, environ);
        !          1330:                cquit("cannot execute %s", cmda[0]);
        !          1331:        }
        !          1332: #endif
        !          1333:        {
        !          1334:                int nsleep;
        !          1335:                int status;
        !          1336:                int pid;
        !          1337:                nsleep = NSLEEP;
        !          1338:                while ((pid=fork())<0 && nsleep--)
        !          1339:                        sleep(DELAY);
        !          1340:                if (pid < 0)
        !          1341:                        cquit("can't fork");
        !          1342:                if (pid == 0) {
        !          1343:                        execve(cmda[0], cmda, environ);
        !          1344:                        exit(MAGIC);
        !          1345:                }
        !          1346:                while (wait(&status) != pid)
        !          1347:                        ;
        !          1348:                if ((s = status&0177)!=0 && s!=SIGINT) {
        !          1349:                        extern char *signame[];
        !          1350: 
        !          1351:                        fprintf(stderr, "cc: %s ", cmda[0]);
        !          1352:                        if (s==SIGSYS && (status&0200)==0)
        !          1353:                                fprintf(stderr, "exec failed");
        !          1354:                        else
        !          1355:                                fprintf(stderr, signame[s]);
        !          1356:                        if ((status&0200) != 0)
        !          1357:                                fprintf(stderr, " -- core dumped");
        !          1358:                        fprintf(stderr, "\n");
        !          1359:                } else if ((s = (status>>8)&0377) == MAGIC)
        !          1360:                        cquit("cannot execute %s", cmda[0]);
        !          1361:        }
        !          1362: #else
        !          1363:        if (s = execve(cmda[0], cmda, environ))
        !          1364:                if (s < 0)
        !          1365:                        perror(cmda[0]);
        !          1366: #endif
        !          1367:        if (catch_errors)
        !          1368:                err_close(s);
        !          1369:        if (s != 0)
        !          1370:                xstat = 1;
        !          1371:        return s;
        !          1372: }
        !          1373: 
        !          1374: /*
        !          1375:  * Routines to catch and release stderr for -A.
        !          1376:  */
        !          1377: int new_fd;
        !          1378: int saved_fd;
        !          1379: 
        !          1380: err_open()
        !          1381: {
        !          1382:        fflush(stderr);
        !          1383:        saved_fd = dup(2);
        !          1384:        if ((new_fd = creat(tmp[6], 0644)) < 0)
        !          1385:                cquit("%s: %s", tmp[6], sys_errlist[errno]);
        !          1386:        if (dup2(new_fd, 2) < 0)
        !          1387:                cquit("dup2 failed");
        !          1388: }
        !          1389: 
        !          1390: err_close(status) int status;
        !          1391: {
        !          1392:        register int c;
        !          1393:        register FILE *fp;
        !          1394: 
        !          1395:        fflush(stderr);
        !          1396:        if (dup2(saved_fd, 2) < 0)
        !          1397:                cquit("dup2 failed");
        !          1398:        if (close(new_fd) < 0)
        !          1399:                /* cquit("error on close") */ ;
        !          1400:        if (status == 0 && (fp = fopen(tmp[6], "r")) != NULL) {
        !          1401:                /* Copy warnings, otherwise they go down the rathole. */
        !          1402:                while ((c = getc(fp)) != EOF)
        !          1403:                        fputc(c, stderr);
        !          1404:                fclose(fp);
        !          1405:        }
        !          1406: }
        !          1407: 
        !          1408: /*
        !          1409: ** Option processing.
        !          1410: */
        !          1411: 
        !          1412: /*
        !          1413:  * Compare option name to argument.
        !          1414:  */
        !          1415: opeq(op, ap)
        !          1416: register char *op, *ap;
        !          1417: {
        !          1418:        while (*op!=0)
        !          1419:                if (*op++ != *ap++)
        !          1420:                        return 0;
        !          1421:        return 1;
        !          1422: }
        !          1423: 
        !          1424: 
        !          1425: /*
        !          1426:  * Get short pass name.
        !          1427:  *     translate single character code into pass index number.
        !          1428:  */
        !          1429: getpsn(c)
        !          1430: register int c;
        !          1431: {
        !          1432:        register int pn;
        !          1433: 
        !          1434:        for (pn = CPP; pn < ALL; pn += 1)
        !          1435:                if (pass[pn].p_psn == c)
        !          1436:                        return pn;
        !          1437:        return NONE;
        !          1438: }
        !          1439: 
        !          1440: /*
        !          1441:  * Process -t*, -B*, -M* options.
        !          1442:  *     -t*     sets take flag for specified passes.
        !          1443:  *     -B*     copies prefix string for flagged passes
        !          1444:  *             or for all machine dependent passes if none flagged.
        !          1445:  *     -M*     copies machine string for machine dependent passes.
        !          1446:  *     -N*     renames a pass, such as crts0.o.
        !          1447:  */
        !          1448: getpass(c, cp)
        !          1449: register int c;
        !          1450: register char *cp;
        !          1451: {
        !          1452:        if (c == 't') {         /* Take passes from backup */
        !          1453:                if (*cp != 0)
        !          1454:                        while ((c = *cp++) != 0)
        !          1455:                                if ((c = getpsn(c)) >= CPP) {
        !          1456:                                        pass[c].p_flag |= P_TAKE;
        !          1457:                                        pass[c].p_dir = dnul;
        !          1458:                                        if (Vflag)
        !          1459:                                                passrpt(c);
        !          1460:                                } else {
        !          1461:                                        badpsn(cp[-1]);
        !          1462:                                }
        !          1463:                else
        !          1464:                        getpass('t', "01234");
        !          1465:        } else if (c == 'B') {  /* Get backup string */
        !          1466:                for (c = CPP; c < ALL; c += 1) {
        !          1467:                        if ((pass[c].p_flag&P_TAKE) != 0) {
        !          1468:                                pass[c].p_flag ^= P_TAKE;
        !          1469:                                pass[c].p_flag |= P_BACK;
        !          1470:                                pass[c].p_dir = cp;
        !          1471:                                if (Vflag)
        !          1472:                                        passrpt(c);
        !          1473:                        }
        !          1474:                }
        !          1475:        } else if (c == 'M') {  /* Machine prefix string */
        !          1476:                if (strlen(cp) > PTMP-1)
        !          1477:                        toolong(cp);
        !          1478:                strcpy(dmch, cp);
        !          1479:                if (Vflag)
        !          1480:                        printf("Prefix: %s\n", dmch);
        !          1481:        } else if (c == 'N') {  /* New pass name */
        !          1482:                if ((c = getpsn(*cp++)) >= CPP) {
        !          1483:                        if (strlen(cp) > PTMP-1)
        !          1484:                                toolong(cp);
        !          1485:                        if (Vflag)
        !          1486:                                printf("Rename: %s to %s\n", pass[c].p_pln, cp);
        !          1487:                        strcpy(pass[c].p_pln, cp);
        !          1488:                } else
        !          1489:                        badpsn(cp[-1]);
        !          1490:        }
        !          1491: }
        !          1492: 
        !          1493: passrpt(c)
        !          1494: register int c;
        !          1495: {
        !          1496:        printf("Use: {%s}%s%s\n", pass[c].p_dir, pass[c].p_mch, pass[c].p_pln);
        !          1497: }
        !          1498: 
        !          1499: missingname()
        !          1500: {
        !          1501:        fprintf(stderr, "cc: missing name in -o, -e or -u\n");
        !          1502:        exit(1);
        !          1503: }
        !          1504: 
        !          1505: badoutput()
        !          1506: {
        !          1507:        fprintf(stderr, "cc: improbable name in -o: %s\n", outf);
        !          1508:        exit(1);
        !          1509: }
        !          1510: 
        !          1511: toomany()
        !          1512: {
        !          1513:        fprintf(stderr, "cc: too many files for -o option\n");
        !          1514:        exit(1);
        !          1515: }
        !          1516: 
        !          1517: badpsn(c)
        !          1518: {
        !          1519:        fprintf(stderr, "cc: unknown short path name: %c\n", c);
        !          1520:        exit(1);
        !          1521: }
        !          1522: 
        !          1523: toolong(cp)
        !          1524: char *cp;
        !          1525: {
        !          1526:        fprintf(stderr, "cc: name, prefix, or directory too long: %s\n", cp);
        !          1527:        exit(1);
        !          1528: }
        !          1529: 
        !          1530: /*
        !          1531:  * Check specified output file name,
        !          1532:  * or construct name from first file
        !          1533:  * name seen.
        !          1534:  */
        !          1535: chkofile()
        !          1536: {
        !          1537:        register char *fn;
        !          1538:        register char c;
        !          1539: 
        !          1540:        if ((fn = outf) == NULL)
        !          1541:                return;
        !          1542:        if (fn[0] == '-')
        !          1543:                badoutput();
        !          1544:        if (nname > 1 && qpass < LD)
        !          1545:                toomany();
        !          1546:        while (*fn != 0)
        !          1547:                ++fn;
        !          1548:        while (*fn != '.' && fn > outf)
        !          1549:                --fn;
        !          1550:        if (*fn++ == '.' && (c = *fn++) &&  *fn == '\0') {
        !          1551:                if (c == 'c'
        !          1552:                || c == 'h'
        !          1553:                || c == 'm'
        !          1554:                || (c != 'o' && cflag)
        !          1555:                || (c == 'o' && !cflag)
        !          1556:                || (c != 's' && Sflag)
        !          1557:                || (c == 's' && !Sflag))
        !          1558:                        badoutput();
        !          1559:        } else {
        !          1560:                if (Sflag || cflag)
        !          1561:                        badoutput();
        !          1562:        }
        !          1563: }
        !          1564: 
        !          1565: whatopt(s)
        !          1566: char *s;
        !          1567: {
        !          1568:        fprintf(stderr, "cc: unrecognized option: %s\n", s);
        !          1569:        usage(0);
        !          1570: }
        !          1571: 
        !          1572: cquit(s)
        !          1573: char *s;
        !          1574: {
        !          1575:        fprintf(stderr, "cc: fatal error: %r\n", &s);
        !          1576:        cleanup(0);
        !          1577:        exit(1);
        !          1578: }
        !          1579: 
        !          1580: /*
        !          1581: ** Intermediate file processing.
        !          1582: */
        !          1583: /*
        !          1584:  * Given cp -> `name.[chms]' rewrite ultimate destination and intermediates
        !          1585:  * if necessary.
        !          1586:  */
        !          1587: setfiles(c, cp)
        !          1588: int c;
        !          1589: register char *cp;
        !          1590: {
        !          1591:        register char *ip;
        !          1592: 
        !          1593:        ip = cp;
        !          1594:        if (qpass < LD && outf != NULL)
        !          1595:                cp = outf;
        !          1596:        if (c == CCARG) {
        !          1597:                pass[CPP].p_ifn = ip;
        !          1598:                if (Eflag)
        !          1599:                        return;
        !          1600:                if (Kflag) {
        !          1601:                        makeft(pass[CPP].p_ofn, cp, "i");
        !          1602:                        makeft(pass[CC0].p_ofn, cp, "0");
        !          1603:                        makeft(pass[CC1].p_ofn, cp, "1");
        !          1604:                        if ( ! Sflag)
        !          1605:                                makeft(pass[CC2].p_sfn, cp, "2");
        !          1606:                        else
        !          1607:                                makeft(pass[CC2].p_ofn, cp, "2");
        !          1608:                }
        !          1609:        } else if (c == MARG) {
        !          1610:                pass[CPP].p_ifn = ip;
        !          1611:                if (Kflag)
        !          1612:                        makeft(pass[CC0].p_ofn, cp, "s");
        !          1613:                pass[AS].p_ifn = pass[CC0].p_ofn;
        !          1614:        } else if (c == ASARG)
        !          1615:                pass[AS].p_ifn = ip;
        !          1616:        makeft(tmp[5], cp, Sflag ? "s" : "o");
        !          1617:        if (!Sflag && newo[0] == 0 && access(tmp[5], 0) < 0)
        !          1618:                strcpy(newo, tmp[5]);
        !          1619: }
        !          1620: 
        !          1621: #if    MONOLITHIC
        !          1622: /*
        !          1623:  * Open a file, die on failure.
        !          1624:  */
        !          1625: FILE *
        !          1626: ccopen(name, mode) char *name; char *mode;
        !          1627: {
        !          1628:        register FILE *fp;
        !          1629: 
        !          1630:        if ((fp = fopen(name, mode)) != NULL)
        !          1631:                return fp;
        !          1632:        cquit("cannot open file \"%s\"", name);
        !          1633: }
        !          1634: #endif
        !          1635: 
        !          1636: /*
        !          1637:  * Unlink a file.
        !          1638:  * If `-V' echo the rm.
        !          1639:  */
        !          1640: rm(s)
        !          1641: register char *s;
        !          1642: {
        !          1643:        if (Vflag)
        !          1644:                printf("rm %s\n", s);
        !          1645:        unlink(s);
        !          1646: }
        !          1647: 
        !          1648: /*
        !          1649:  * Cleanup after yourself if
        !          1650:  * the user hits interrupt during a compile (sig == SIGINT),
        !          1651:  * or when all compiles have completed (sig == 0).
        !          1652:  */
        !          1653: cleanup(sig)
        !          1654: {
        !          1655:        register int i;
        !          1656: 
        !          1657: #if COHERENT
        !          1658:        if (sig == SIGINT)
        !          1659:                signal(SIGINT, SIG_IGN);
        !          1660: #endif
        !          1661:        for (i = 0; i < 7; i += 1)
        !          1662:                if (istmp[i])
        !          1663:                        rm(tmp[i]);
        !          1664: #if COHERENT
        !          1665:        if (sig == SIGINT && nldob==1 && newo[0]!=0)
        !          1666:                rm(newo);
        !          1667:        if (sig == SIGINT)
        !          1668:                exit(1);
        !          1669: #endif
        !          1670: }
        !          1671: 
        !          1672: /*
        !          1673: ** Name construction.
        !          1674: */
        !          1675: char *
        !          1676: ccpath(cp, p, n, mode) register char *cp; char *p, *n; int mode;
        !          1677: {
        !          1678:        register char *pn;
        !          1679:        if (VeryVflag && Vflag)
        !          1680:                printf("search %s for %s\n", p, n);
        !          1681:        while ((pn = path(p, n, mode)) == NULL) {
        !          1682:                if (Zflag) {    /* Disk swap dialog flag */
        !          1683: fprintf(stderr, "Insert %s's disk in a free drive and press <Return>\n", n);
        !          1684:                        gets(cp);
        !          1685:                        continue;
        !          1686:                }
        !          1687:                pn = n;
        !          1688:                break;
        !          1689:        }
        !          1690:        while (*cp++ = *pn++) ;
        !          1691:        return cp;
        !          1692: }
        !          1693: 
        !          1694: char *
        !          1695: makepass(pn, cp, mode)
        !          1696: int pn;
        !          1697: register char *cp;
        !          1698: int mode;
        !          1699: {
        !          1700:        return ccpath(cp, pass[pn].p_dir, pass[pn].p_pln, mode);
        !          1701: }
        !          1702: 
        !          1703: char *
        !          1704: makelib(pn, cp, lp)
        !          1705: int pn;
        !          1706: char *cp;
        !          1707: char *lp;
        !          1708: {
        !          1709: #if    _I386
        !          1710:        /* Let ld do the work, just pass -lwhatever. */
        !          1711:        strcpy(cp, "-l");
        !          1712:        strcat(cp, lp);
        !          1713:        return cp + strlen(cp) + 1;
        !          1714: #else
        !          1715:        strcpy(cp, pass[pn].p_pln);
        !          1716:        strcat(cp, lp);
        !          1717:        strcat(cp, ".a");
        !          1718:        return ccpath(cp, pass[pn].p_dir, cp, AREAD);
        !          1719: #endif
        !          1720: }
        !          1721: 
        !          1722: makeft(op, ip, ft)
        !          1723: char *op, *ip, *ft;
        !          1724: {
        !          1725:        register char *ep, *tp;
        !          1726:        register c;
        !          1727:        char *dp;
        !          1728: 
        !          1729:        ep = ip;
        !          1730:        tp = op;
        !          1731:        dp = NULL;
        !          1732:        while ((c = *ep++) != '\0') {
        !          1733:                if (c == PATHSEP && ip != outf) {
        !          1734:                        tp = op;
        !          1735:                        dp = NULL;
        !          1736:                } else {
        !          1737:                        if (c == '.')
        !          1738:                                dp = tp;
        !          1739:                        *tp++ = c;
        !          1740:                }
        !          1741:        }
        !          1742:        if (ip == outf)
        !          1743:                return;
        !          1744:        if (dp != NULL)
        !          1745:                tp = dp;
        !          1746:        *tp++ = '.';
        !          1747:        ep = ft;
        !          1748:        while (*tp++ = *ep++)
        !          1749:                ;
        !          1750: }
        !          1751: 
        !          1752: /*
        !          1753:  * Print a terse or verbose usage message.
        !          1754:  */
        !          1755: usage(flag) register int flag;
        !          1756: {
        !          1757:        register FILE *ofp;
        !          1758: 
        !          1759:        ofp = (flag) ? stdout : stderr;
        !          1760:        fprintf(ofp, "Usage: cc [ option ... ] file ...\n");
        !          1761:        if (flag == 0)
        !          1762:                fprintf(ofp, "Type \"cc -?\" to list the available options.\n");
        !          1763:        else
        !          1764:                fprintf(ofp,    
        !          1765:                "Options:\n"
        !          1766:                "\t-A\t\tAuto edit mode\n"
        !          1767:                "\t-Bpathname\tUse pathname to find substitute compiler passes\n"
        !          1768:                "\t-Dname[=value]\tcpp: #define\n"
        !          1769:                "\t-E\t\tExpand: run preprocessor to stdout\n"
        !          1770:                "\t-Ipathname\tcpp: #include search directory\n"
        !          1771:                "\t-K\t\tKeep intermediate files\n"
        !          1772:                "\t-Lpathname\tld: library directory specification\n"
        !          1773:                "\t-Mstring\t\tUse string as cross-compiler prefix\n"
        !          1774:                "\t-N[01ab2sdlrt]string\tRename pass with string\n"
        !          1775:                "\t-O\t\tOptimize: run object code optimizer\n"
        !          1776:                "\t-Q\t\tQuiet: no error or warning messages\n"
        !          1777:                "\t-S\t\tOutput assembly language\n"
        !          1778:                "\t-T[value]\tTemp size for in-memory tempfiles (default: 64K)\n"
        !          1779:                "\t-Uname\t\tcpp: #undef\n"
        !          1780:                "\t-V\t\tVerbose: report everything\n"
        !          1781:                "\t-Vvariant\tVariant enable/disable, see list below\n"
        !          1782:                "\t-X\t\tld: remove C-generated local symbols\n"
        !          1783: #if    GEMDOS
        !          1784:                "\t-Z\t\t(GEMDOS) floppy change prompts for phases\n"
        !          1785: #endif
        !          1786:                "\t-a\t\tDo not use implicit output file name for loader\n"
        !          1787:                "\t-c\t\tCompile only, do not load\n"
        !          1788:                "\t-d\t\tld: define common space\n"
        !          1789:                "\t-e name\t\tld: entry point specification\n"
        !          1790:                "\t-f\t\tld: use floating point output conversion routines\n"
        !          1791:                "\t-g\t\tGenerate debug information, same as -VDB\n"
        !          1792:                "\t-i\t\tld: separate i and d spaces\n"
        !          1793:                "\t-lname\t\tld: library specification\n"
        !          1794:                "\t-n\t\tld: shared instruction space\n"
        !          1795:                "\t-o name\t\tld: output file name\n"
        !          1796:                "\t-p\t\tProfile: generate code to profile function calls\n"
        !          1797:                "\t-q[p012s]\tQuit after specified pass\n"
        !          1798:                "\t-r\t\tld: retain relocation information in output\n"
        !          1799:                "\t-s\t\tld: strip symbol table\n"
        !          1800:                "\t-t[p012adlrt]\ttake specified passes from -Bdirectory\n"
        !          1801:                "\t-u name\t\tld: undefine name\n"
        !          1802:                "\t-v\t\tVerbose: report everything, same as -V\n"
        !          1803:                "\t-w\t\tld: watch\n"
        !          1804:                "\t-x\t\tld: remove all local symbols from symbol table\n"
        !          1805:                "Variant options:\n"
        !          1806:                "\t-VASM\t\tAssembly language output, same as -S\n"
        !          1807:                "\t-VCOMM\t\tCommon data items (default)\n"
        !          1808:                "\t-VCPLUS\t\tIgnore C++ style online //-delimited comments\n"
        !          1809:                "\t-VCPPE\t\tRun cpp in -E mode, same as -E\n"
        !          1810:                "\t-VDB\t\tDebug: generate debug output, same as -g\n"
        !          1811:                "\t-VFLOAT\t\tFloating point output conversion, same as -f\n"
        !          1812:                "\t-VKEEP\t\tKeep intermediate files, same as -K\n"
        !          1813:                "\t-VNDP\t\tUse hardware (80x87) floating point\n"
        !          1814:                "\t-VNOOPT\t\tNo optimization\n"
        !          1815:                "\t-VNOWARN\tNo warning messages\n"
        !          1816:                "\t-VPEEP\t\tPeephole optimization (default)\n"
        !          1817:                "\t-VPROF\t\tProfile: generate code to profile function calls\n"
        !          1818:                "\t-VPSTR\t\tPure strings (default)\n"
        !          1819:                "\t-VQUIET\t\tNo messages, same as -Q\n"
        !          1820:                "\t-VREADONLY\tRecognize \"readonly\" keyword\n"
        !          1821:                "\t-VS\t\tStrict: turn on all strict messages\n"
        !          1822:                "\t-VSBOOK\t\tStrict: only constructs in K&R\n"
        !          1823:                "\t-VSCCON\t\tStrict: constant conditional\n"
        !          1824:                "\t-VSINU\t\tAllow struct-in-union constructs\n"
        !          1825:                "\t-VSLCON\t\tStrict: long constant promotion (default)\n"
        !          1826:                "\t-VSMEMB\t\tStrict: strict member checking (default)\n"
        !          1827:                "\t-VSNREG\t\tStrict: declared register but allocated auto\n"
        !          1828:                "\t-VSPVAL\t\tStrict: pointer value truncation (default)\n"
        !          1829:                "\t-VSRTVC\t\tStrict: risky constructs in truth contexts\n"
        !          1830:                "\t-VSTAT\t\tStatistics on optimization\n"
        !          1831:                "\t-VSUREG\t\tStrict: unused registers\n"
        !          1832:                "\t-VSUVAR\t\tStrict: unused variables (default)\n"
        !          1833:                "\t-VVERSION\tPrint compiler version number\n"
        !          1834:                "\t-VWIDEN\t\tWidening of parameter or function value warning\n"
        !          1835:                "\t-VXSTAT\t\tWrite static external symbols\n"
        !          1836:                "\t-V3GRAPH\tRecognize ANSI trigraphs\n"
        !          1837:                );
        !          1838:                exit(1);
        !          1839: #if    0
        !          1840: /*
        !          1841:  * The following variants are not included in the usage(1) output above
        !          1842:  * because they are useful primarily for MWC internal purposes
        !          1843:  * or they are for machine models which are currently irrelevant
        !          1844:  * or because I'm not sure what they do.
        !          1845:  */
        !          1846: /* Miscellaneous */
        !          1847: /* ld does not grok -k, dunno why -k exists. */
        !          1848: "\tk system\tld: bind as kernel process\n"
        !          1849: VALIEN\t\tAlien (PL/M) calling conventions
        !          1850: VALIGN\t\tAlign the stack (i8086)
        !          1851: VTPROF\t\tCode table profiling
        !          1852: VROM\t\tProduce ROMable code
        !          1853: VLIB
        !          1854: VCPPC\t
        !          1855: VCPP\t
        !          1856: /* Debug */
        !          1857: VDEBUG\tDebug: 
        !          1858: VDLINE\tDebug: 
        !          1859: VDTYPE\tDebug: 
        !          1860: VDSYMB\tDebug: 
        !          1861: /* Intel */
        !          1862: VSMALL
        !          1863: VLARGE
        !          1864: V8087
        !          1865: VRAM
        !          1866: VOMF
        !          1867: V80186 (default)
        !          1868: V80287
        !          1869: VEMU87
        !          1870: #if    GEMDOS
        !          1871: /* Motorola and Gemdos */
        !          1872: VGEMACC
        !          1873: VGEMAPP
        !          1874: VGEM
        !          1875: VSPLIM
        !          1876: VNOTRAPS
        !          1877: #endif
        !          1878: #endif
        !          1879: }
        !          1880: 
        !          1881: /* end of coh/cc.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.