|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.