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