Annotation of coherent/b/bin/c/coh/cc.c.sav, revision 1.1.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.