|
|
1.1 ! root 1: /* ! 2: * cc.c ! 3: * 11/3/90 ! 4: * CC command. ! 5: * Compile, assemble and link edit C programs. ! 6: * A lot of grunge. ! 7: * Revised by rec may1987 to incorporate all ! 8: * coherent and gemdos revisions to date. ! 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: *7c Bstring use string to find compiler passes ! 21: * A run in auto edit mode ! 22: *7 Dname[=value] preprocessor: #define ! 23: *7 E run preprocessor to stdout ! 24: *7 Ipathname preprocessor: #include search directory ! 25: * K keep intermediate files in name.[P012so] ! 26: * L loader: directive for >64K file sizes ! 27: * Mstring use string as cross-compiler prefix ! 28: * N[01ab2sdlrt]string rename pass with string ! 29: *7 O run object code optimiser ! 30: *7d P put preprocessor output into name.i; use -Kqp ! 31: * Q be quiet, make no messages ! 32: *7 S make assembly language output in name.s ! 33: *7 Uname preprocessor: #undef ! 34: * V be verbose, report everything ! 35: * Vvariant enable variant ! 36: * X loader: remove c generated local symbols ! 37: * Z (GEMDOS) floppy change prompts for phases ! 38: *7 c compile but do not load ! 39: * d loader: define common space ! 40: *7 e name loader: entry point specification ! 41: *7c f fake floating point operations ! 42: *7u i loader: separate i and d spaces ! 43: * k[system] loader: bind as kernel process ! 44: *7c lname loader: library specification ! 45: *7u n loader: shared instruction space ! 46: *7 o name loader: output file name ! 47: *7 p generate code to profile function calls ! 48: * q[p012s] quit after specified pass ! 49: * r loader: retain relocation in output ! 50: * s loader: strip symbol table ! 51: *7c t[p012adlrt] take specified passes from -Bdirectory ! 52: *7 u name loader: enter name into symbol table ! 53: * w loader: watch ! 54: * x loader: remove local symbols from symbol table ! 55: */ ! 56: #if GEMDOS ! 57: #ifndef VERS ! 58: #define VERS "2.1" ! 59: #endif ! 60: #endif ! 61: ! 62: #include <stdio.h> ! 63: #include <ctype.h> ! 64: #include <signal.h> ! 65: #include <path.h> ! 66: #include <errno.h> ! 67: #include "mch.h" ! 68: #undef NONE ! 69: #include "var.h" ! 70: #include "varmch.h" ! 71: ! 72: #ifndef VeryVflag ! 73: #define VeryVflag 0 ! 74: #endif ! 75: ! 76: #ifndef PREFIX ! 77: #define PREFIX "" ! 78: #endif ! 79: ! 80: /* ! 81: ** Pass information. ! 82: */ ! 83: #define NONE -1 ! 84: #define CPP 0 /* Pass index numbers */ ! 85: #define CC0 1 ! 86: #define CC1 2 ! 87: #define CC2 3 ! 88: #define CC3 4 ! 89: #define CC4 5 /* Output writer postprocessor */ ! 90: #define AS 6 ! 91: #define LD 7 ! 92: #define LD2 8 /* Loader postprocessor */ ! 93: #define ED 9 ! 94: #define LIB 10 ! 95: #define CRT 11 ! 96: #define TMP 12 ! 97: #define ALL 13 ! 98: ! 99: #define P_TAKE 1 /* Take pass from backup directory */ ! 100: #define P_BACK 2 /* Backup directory specified */ ! 101: #define P_LIB 4 /* Take pass from LIBPATH */ ! 102: #define P_BIN 8 /* Take pass from BIN */ ! 103: ! 104: #define PTMP 16 /* Pass name buffer size */ ! 105: ! 106: char dnul[] = ""; /* Global null string */ ! 107: char dmch[PTMP] = PREFIX; /* Cross compiler prefix */ ! 108: ! 109: struct pass { ! 110: char p_flag; /* Flags */ ! 111: char p_psn; /* Pass short name */ ! 112: char p_pln[PTMP]; /* Pass long name */ ! 113: char p_pfs[4]; /* Pass output file suffix */ ! 114: char *p_ifn; /* Input file name */ ! 115: char *p_ofn; /* Output file name */ ! 116: char *p_sfn; /* Scratch file name */ ! 117: char *p_dir; /* Path lookup or backup string */ ! 118: char *p_mch; /* Machine prefix name */ ! 119: } pass[] = { ! 120: { P_LIB, 'p', "cpp", "i", NULL, NULL, NULL, NULL, dmch }, ! 121: { P_LIB, '0', "cc0", "0", NULL, NULL, NULL, NULL, dmch }, ! 122: { P_LIB, '1', "cc1", "1", NULL, NULL, NULL, NULL, dmch }, ! 123: { P_LIB, '2', "cc2", "o", NULL, NULL, NULL, NULL, dmch }, ! 124: { P_LIB, '3', "cc3", "s", NULL, NULL, NULL, NULL, dmch }, ! 125: { P_LIB, '4', "cc4", "o", NULL, NULL, NULL, NULL, dmch }, ! 126: { P_BIN, 's', "as", "o", NULL, NULL, NULL, NULL, dmch }, ! 127: { P_BIN, 'd', "ld", "", NULL, NULL, NULL, NULL, dnul }, ! 128: { P_BIN, 'x', "ld2", "", NULL, NULL, NULL, NULL, dnul }, ! 129: { P_BIN, 'e', "me", "", NULL, NULL, NULL, NULL, dnul }, ! 130: { P_LIB, 'l', "lib", "a", NULL, NULL, NULL, NULL, dmch }, ! 131: { P_LIB, 'r', "crts0.o", "", NULL, NULL, NULL, NULL, dmch }, ! 132: { 0, 't', "cc", "", NULL, NULL, NULL, NULL, dnul } ! 133: }; ! 134: ! 135: /* ! 136: ** Option and argument information. ! 137: */ ! 138: #define CCOPT 0x001 /* Argument flags in argf[] */ ! 139: #define PPOPT 0x002 /* Also in option table, at least */ ! 140: #define LDOPT 0x004 /* those that fit in a byte */ ! 141: #define LD2OPT 0x008 ! 142: #define CCLIB 0x010 ! 143: #define LDLIB 0x020 ! 144: #define CCARG 0x040 ! 145: #define ASARG 0x080 ! 146: #define MARG 0x100 ! 147: #define LDARG 0x200 ! 148: ! 149: #define FLAG_c 1 /* -c flag */ ! 150: #define FLAG_O 2 /* -O flag */ ! 151: #define FLAG_f 4 /* -f flag */ ! 152: #define FLAG_K 010 /* -K or -VKEEP flag */ ! 153: #define VS 020 /* Turn on strict messages */ ! 154: #define VDB 040 /* Turn on debugging */ ! 155: #define FLAG_A 0100 /* Auto edit mode */ ! 156: #define FLAG_Z 0200 /* Floppy change prompts */ ! 157: #define FLAG_V 0400 /* Verbose flag */ ! 158: ! 159: #define FLAG_GEMAPP 01000 /* Gem application compile */ ! 160: #define FLAG_GEMACC 02000 /* Gem accessory compile */ ! 161: ! 162: struct option { /* option table */ ! 163: char o_kind; ! 164: char o_flag; ! 165: char *o_name; ! 166: int o_bits; ! 167: } option[] = { ! 168: /* Strict */ ! 169: { 0, CCOPT, "VSUREG", VSUREG }, ! 170: { 0, CCOPT, "VSUVAR", VSUVAR }, ! 171: { 0, CCOPT, "VSNREG", VSNREG }, ! 172: { 0, CCOPT, "VSRTVC", VSRTVC }, ! 173: { 0, CCOPT, "VSMEMB", VSMEMB }, ! 174: { 0, CCOPT, "VSBOOK", VSBOOK }, ! 175: { 0, CCOPT, "VSLCON", VSLCON }, ! 176: { 0, CCOPT, "VSPVAL", VSPVAL }, ! 177: { 0, CCOPT, "VSCCON", VSCCON }, ! 178: /* Debug */ ! 179: { 0, CCOPT, "VDEBUG", VDEBUG }, ! 180: { 0, CCOPT, "VDLINE", VLINES }, ! 181: { 0, CCOPT, "VDTYPE", VTYPES }, ! 182: { 0, CCOPT, "VDSYMB", VDSYMB }, ! 183: { 0, CCOPT, "VDCALL", VCALLS }, ! 184: /* Miscellaneous */ ! 185: { 0, CCOPT, "VSTAT", VSTAT }, ! 186: { 0, CCOPT, "VSINU", VSINU }, ! 187: { 0, CCOPT, "VPEEP", VPEEP }, ! 188: { 0, CCOPT, "VCOMM", VCOMM }, ! 189: { 0, CCOPT, "VQUIET", VQUIET }, ! 190: { 0, CCOPT, "VPSTR", VPSTR }, ! 191: { 0, CCOPT, "VROM", VROM }, ! 192: { 0, CCOPT, "VASM", VASM }, ! 193: { 0, CCOPT, "VPROF", VPROF }, ! 194: { 0, CCOPT, "VALIEN", VALIEN }, ! 195: { 0, CCOPT, "VNOOPT", VNOOPT }, ! 196: { 0, CCOPT, "VCHASM", VCHASM }, ! 197: { 0, CCOPT, "VCPP", VCPP }, ! 198: { 0, CCOPT, "VCPPE", VCPPE }, ! 199: { 0, CCOPT, "VTPROF", VTPROF }, ! 200: { 0, CCOPT, "V3GRAPH", V3GRAPH }, ! 201: #if 1 ! 202: /* Intel flags */ ! 203: { 0, CCOPT, "VSMALL", VSMALL }, ! 204: { 0, CCOPT, "VLARGE", VLARGE }, ! 205: { 0, CCOPT, "V8087", V8087 }, ! 206: { 0, CCOPT, "VRAM", VRAM }, ! 207: { 0, CCOPT, "VOMF", VOMF }, ! 208: { 0, CCOPT, "V80186", V80186 }, ! 209: { 0, CCOPT, "V80287", V80287 }, ! 210: { 0, CCOPT, "VALIGN", VALIGN }, ! 211: { 0, CCOPT, "VEMU87", VEMU87 }, ! 212: #endif ! 213: /* Motorola and Gemdos flags */ ! 214: { 12, CCOPT, "VGEMACC", FLAG_GEMACC }, ! 215: { 12, CCOPT, "VGEMAPP", FLAG_GEMAPP }, ! 216: { 12, CCOPT, "VGEM", FLAG_GEMAPP }, ! 217: { 10, CCOPT, "VSPLIM", VSPLIM }, ! 218: { 10, CCOPT, "VNOTRAPS", VNOTRAPS }, ! 219: /* More miscellaneous flags */ ! 220: { 2, CCOPT, "VDB", VDB }, ! 221: { 2, CCOPT, "VS", VS }, ! 222: { 12, CCOPT, "A", FLAG_A }, ! 223: { 12, CCOPT, "Z", FLAG_Z }, ! 224: { 12, CCOPT, "c", FLAG_c }, ! 225: { 10, CCOPT, "S", VASM }, ! 226: { 2, CCOPT, "O", FLAG_O }, ! 227: { 0, CCOPT, "E", VCPPE }, ! 228: { 12, CCOPT, "f", FLAG_f }, ! 229: { 12, CCOPT, "VFLOAT", FLAG_f }, ! 230: { 0, CCOPT, "p", VPROF }, ! 231: { 12, CCOPT, "VKEEP", FLAG_K }, ! 232: { 12, CCOPT, "K", FLAG_K }, ! 233: { 0, CCOPT, "Q", VQUIET }, ! 234: { 12, CCOPT, "V", FLAG_V }, ! 235: { 12, CCOPT, "v", FLAG_V }, ! 236: /* Preprocessor options */ ! 237: { 3, PPOPT, "D" }, ! 238: { 3, PPOPT, "I" }, ! 239: { 3, PPOPT, "U" }, ! 240: /* Loader options */ ! 241: { 4, LDOPT, "d" }, ! 242: { 4, LDOPT, "i" }, ! 243: { 4, LDOPT, "n" }, ! 244: { 5, LDOPT, "o" }, ! 245: { 4, LDOPT, "r" }, ! 246: { 4, LDOPT, "s" }, ! 247: { 4, LDOPT, "w" }, ! 248: { 4, LDOPT, "x" }, ! 249: { 4, LDOPT, "X" }, ! 250: #if 0 ! 251: { 4, LDOPT, "L" }, ! 252: #endif ! 253: { 5, LDOPT, "e" }, ! 254: { 5, LDOPT, "k" }, ! 255: { 5, LDOPT, "u" }, ! 256: /* C dispatcher options */ ! 257: { 6, CCOPT, "q" }, ! 258: { 7, CCOPT, "t" }, ! 259: { 7, CCOPT, "B" }, ! 260: { 7, CCOPT, "M" }, ! 261: { 7, CCOPT, "N" }, ! 262: { 8, CCLIB, "l" }, ! 263: ! 264: { -1, -1, "" } ! 265: }; ! 266: ! 267: int ccvariant = 0; /* Variant template */ ! 268: VARIANT variant; /* Binary variant template */ ! 269: char vstr[2*VMAXIM/VGRANU + 1]; /* Ascii variant string */ ! 270: char vstr2[2*VMAXIM/VGRANU + 1]; /* Ascii variant string for .m */ ! 271: ! 272: /* ! 273: ** Compiler parameters and flags ! 274: */ ! 275: #define NCMDA 128 /* Size of argument pointer buffer */ ! 276: #define NCMDB 1024 /* Size of argument buffer */ ! 277: #define NTMP L_tmpnam /* Temp file buffer size, from stdio.h */ ! 278: #define MAGIC 127 /* Exit status mask */ ! 279: #define NSLEEP 10 /* # of sleeps */ ! 280: #define DELAY 5 /* Sleep delay, seconds */ ! 281: ! 282: int nldob; /* Number of objects created */ ! 283: int nfile; /* Number of files to compile or assemble */ ! 284: int nname; /* Number of file name arguments */ ! 285: int ndota; ! 286: int ndotc; ! 287: int ndotm; ! 288: int ndoto; ! 289: int ndots; ! 290: int partial; /* Partial link specified */ ! 291: ! 292: #define cflag ((ccvariant&FLAG_c)!=0) ! 293: #define pflag isvariant(VPROF) ! 294: #define fflag ((ccvariant&FLAG_f)!=0) ! 295: #define Kflag ((ccvariant&FLAG_K)!=0) ! 296: #define Oflag ((ccvariant&FLAG_O)!=0) ! 297: #define Sflag isvariant(VASM) ! 298: #define Eflag isvariant(VCPPE) ! 299: #define Vflag ((ccvariant&FLAG_V)!=0) ! 300: #define Qflag isvariant(VQUIET) ! 301: #define Aflag ((ccvariant&FLAG_A)!=0) ! 302: #define Zflag ((ccvariant&FLAG_Z)!=0) ! 303: #define GEMAPPflag ((ccvariant&FLAG_GEMAPP)!=0) ! 304: #define GEMACCflag ((ccvariant&FLAG_GEMACC)!=0) ! 305: ! 306: int qpass = NONE; /* Quit after this pass */ ! 307: int nload; /* No load phase */ ! 308: char *outf; /* Output file */ ! 309: char *doutf; /* Default output file stem */ ! 310: char *dpath = DEFPATH; ! 311: char *dlibpath = DEFLIBPATH; ! 312: int xstat; /* Exit status */ ! 313: ! 314: char *cmda[NCMDA]; /* Argument pointer buffer */ ! 315: char cmdb[NCMDB]; /* Argument buffer */ ! 316: char newo[NTMP]; /* New object to be removed */ ! 317: char tmp[7][NTMP]; /* Intermediate filenames */ ! 318: char istmp[7]; /* Truth about their temporariness */ ! 319: int argf[NCMDA]; /* Argument flags */ ! 320: char optb[NCMDB]; /* Option rewrite buffer */ ! 321: char *optp = &optb[0]; /* Option rewrite position */ ! 322: ! 323: char *makepass(); ! 324: char *makelib(); ! 325: int cleanup(); ! 326: char *getenv(); ! 327: char *tempnam(); ! 328: char *path(); ! 329: ! 330: main(argc, argv) ! 331: char *argv[]; ! 332: { ! 333: register char *p; ! 334: register struct option *op; ! 335: int i, narg, c; ! 336: ! 337: #if COHERENT ! 338: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 339: signal(SIGINT, cleanup); ! 340: #endif ! 341: setbuf(stdout, NULL); ! 342: setbuf(stderr, NULL); ! 343: setvariant(VSUVAR); ! 344: setvariant(VSMEMB); ! 345: setvariant(VSLCON); ! 346: setvariant(VSPVAL); ! 347: setvariant(VPEEP); ! 348: setvariant(VCOMM); ! 349: setvariant(V80186); ! 350: ! 351: if (p = getenv("PATH")) dpath = p; ! 352: if (p = getenv("LIBPATH")) dlibpath = p; ! 353: if (p = getenv("EDITOR")) strcpy(pass[ED].p_pln, p); ! 354: ! 355: for (i=1; i<argc; i+=narg) { ! 356: narg = 1; ! 357: p = argv[i]; ! 358: if (*p++ == '-') { ! 359: static char tppopt[64] = "-"; ! 360: static char tldopt[64] = "-"; ! 361: char *tpp = &tppopt[1]; ! 362: char *tlp = &tldopt[1]; ! 363: ! 364: if (*p == '\0') { ! 365: badopt: ! 366: whatopt(argv[i]); ! 367: continue; ! 368: } ! 369: while (*p != '\0') { ! 370: for (op = &option[0]; ; op += 1) ! 371: if (op->o_name[0] == '\0') ! 372: goto badopt; ! 373: else if (opeq(op->o_name, p)) ! 374: break; ! 375: if (VeryVflag && Vflag) ! 376: printf("Option: -%s\n", op->o_name); ! 377: argf[i] |= op->o_flag; ! 378: switch (op->o_kind) { ! 379: case 0: ! 380: chgvariant(op->o_bits); ! 381: p += strlen(op->o_name); ! 382: continue; ! 383: case 10: ! 384: setvariant(op->o_bits); ! 385: p += strlen(op->o_name); ! 386: continue; ! 387: case 2: ! 388: ccvariant ^= op->o_bits; ! 389: p += strlen(op->o_name); ! 390: /* Set strict */ ! 391: if ((ccvariant&VS) != 0) { ! 392: for (op = &option[0];; op += 1) ! 393: if (op->o_name[1]=='S') ! 394: break; ! 395: while (op->o_name[1]=='S') { ! 396: setvariant(op->o_bits); ! 397: op += 1; ! 398: } ! 399: } ! 400: /* Set debug */ ! 401: if ((ccvariant&VDB) != 0) { ! 402: for (op = &option[0];; op += 1) ! 403: if (op->o_name[1]=='D') ! 404: break; ! 405: while (op->o_name[1]=='D') { ! 406: setvariant(op->o_bits); ! 407: op += 1; ! 408: } ! 409: } ! 410: continue; ! 411: case 12: ! 412: ccvariant |= op->o_bits; ! 413: p += strlen(op->o_name); ! 414: continue; ! 415: case 3: ! 416: while (*tpp++ = *p) ! 417: p++; ! 418: continue; ! 419: case 5: ! 420: if (*p == 'o') { ! 421: outf = argv[i+narg]; ! 422: } ! 423: if (*p == 'u') ! 424: ndoto += 1; ! 425: if (i+narg >= argc) ! 426: missingname(); ! 427: argf[i+narg++] = LDOPT; ! 428: /* Fall through */ ! 429: case 4: ! 430: if (*p == 'r') ! 431: ++partial; ! 432: strcpy(tlp, op->o_name); ! 433: tlp += strlen(op->o_name); ! 434: p += strlen(op->o_name); ! 435: continue; ! 436: case 6: ! 437: if ((c = p[1]) == '\0' ! 438: || (c = getpsn(c)) < CPP) ! 439: goto badopt; ! 440: qpass = c; ! 441: p += 2; ! 442: continue; ! 443: case 7: ! 444: c = p[0]; ! 445: getpass(c, p+1); ! 446: p = dnul; ! 447: continue; ! 448: case 8: ! 449: p = dnul; ! 450: continue; ! 451: default: ! 452: cfatal("options"); ! 453: } ! 454: } ! 455: if (((unsigned)argf[i]-1)&((unsigned)argf[i])) { ! 456: strcpy(optp, argv[i]); ! 457: argv[i] = optp; ! 458: optp += strlen(optp)+1; ! 459: strcpy(optp, tppopt); ! 460: optp += strlen(optp)+1; ! 461: strcpy(optp, tldopt); ! 462: optp += strlen(optp)+1; ! 463: } ! 464: } else { ! 465: while (*p) p+=1; ! 466: c = *--p; ! 467: if (*--p != '.') c = 0; ! 468: if (c >= 'A' && c <= 'Z') ! 469: c |= 'a'-'A'; ! 470: switch (c) { ! 471: case 'h': ! 472: case 'c': ! 473: if (doutf == NULL) doutf = argv[i]; ! 474: ndotc += 1; ! 475: argf[i] = CCARG; ! 476: if (VeryVflag && Vflag) ! 477: printf("cc file: %s\n", argv[i]); ! 478: break; ! 479: case 's': ! 480: if (doutf == NULL) doutf = argv[i]; ! 481: ndots += 1; ! 482: argf[i] = ASARG; ! 483: if (VeryVflag && Vflag) ! 484: printf("as file: %s\n", argv[i]); ! 485: break; ! 486: case 'm': ! 487: if (doutf == NULL) doutf = argv[i]; ! 488: ndotm += 1; ! 489: argf[i] = MARG; ! 490: if (VeryVflag && Vflag) ! 491: printf("m file: %s\n", argv[i]); ! 492: break; ! 493: case 'o': ! 494: if (doutf == NULL) doutf = argv[i]; ! 495: ndoto += 1; ! 496: argf[i] = LDARG; ! 497: if (VeryVflag && Vflag) ! 498: printf("ld file: %s\n", argv[i]); ! 499: break; ! 500: case 'a': ! 501: default: ! 502: ndota += 1; ! 503: argf[i] = LDLIB; ! 504: if (VeryVflag && Vflag) ! 505: printf("library: %s\n", argv[i]); ! 506: break; ! 507: } ! 508: } ! 509: } ! 510: #if GEMDOS ! 511: if (Vflag) { ! 512: fprintf(stderr, "Mark Williams C for the Atart ST, %s\n", VERS); ! 513: fprintf(stderr, "Copyright 1984-1987, Mark Williams Co., Chicago\n"); ! 514: } ! 515: #endif ! 516: resolve(); ! 517: compile(argc, argv); ! 518: if (nload==0 && runld(argc, argv)==0) { ! 519: if (Kflag==0 && nldob==1 && newo[0]!=0) ! 520: rm(newo); ! 521: } ! 522: exit(xstat); ! 523: } ! 524: ! 525: /* ! 526: * Resolve remaining ambiguities. ! 527: * Initialize variant arguments and files. ! 528: */ ! 529: resolve() ! 530: { ! 531: register int i; ! 532: extern char *index(); ! 533: ! 534: for (i = CPP; i < ALL; i += 1) { ! 535: if (pass[i].p_flag & P_BACK) ! 536: ; ! 537: else if (pass[i].p_flag & P_LIB) ! 538: pass[i].p_dir = dlibpath; ! 539: else if (pass[i].p_flag & P_BIN) ! 540: pass[i].p_dir = dpath; ! 541: strcpy(cmdb, pass[i].p_mch); ! 542: strcat(cmdb, pass[i].p_pln); ! 543: #if GEMDOS ! 544: if (i <= ED && index(pass[i].p_pln, '.') == NULL) ! 545: strcat(cmdb, i==ED ? ".tos" : ".prg"); ! 546: #endif ! 547: if (strlen(cmdb) > PTMP-1) ! 548: cfatal("pass name \"%s\" is too long", cmdb); ! 549: strcpy(pass[i].p_pln, cmdb); ! 550: } ! 551: #if 1 ! 552: if (isvariant(VOMF)) { ! 553: clrvariant(VCOMM); ! 554: if (isvariant(VLARGE) && isvariant(VSMALL)) ! 555: cfatal("invalid model specification"); ! 556: if (notvariant(VLARGE) && notvariant(VSMALL)) ! 557: setvariant(VSMALL); ! 558: } else { ! 559: clrvariant(VLARGE); ! 560: setvariant(VSMALL); ! 561: } ! 562: #endif ! 563: if (GEMAPPflag && GEMACCflag) ! 564: cfatal("specify VGEMAPP or VGEMACC, not both"); ! 565: if (GEMAPPflag) getpass('N', "rcrtsg.o"); ! 566: if (GEMACCflag) getpass('N', "rcrtsd.o"); ! 567: if (pflag) getpass('N', "rmcrts0.o"); ! 568: if (Eflag) setvariant(VCPP); ! 569: if (qpass == NONE) { ! 570: if (isvariant(VCPP)) ! 571: qpass = CPP; ! 572: else if (Sflag) ! 573: qpass = CC3; ! 574: else if (cflag) ! 575: qpass = AS; ! 576: else ! 577: qpass = LD; ! 578: } else if (qpass == CPP) ! 579: setvariant(VCPP); ! 580: if (VeryVflag && Vflag) ! 581: printf("quit pass is %s\n", pass[qpass].p_pln); ! 582: makvariant(vstr); ! 583: if (ndotm != 0 && notvariant(VCPP) && notvariant(VCPPE)) { ! 584: setvariant(VCPP); ! 585: setvariant(VCPPE); ! 586: makvariant(vstr2); ! 587: clrvariant(VCPP); ! 588: clrvariant(VCPPE); ! 589: } ! 590: nfile = ndotc + ndots + ndotm; ! 591: nname = nfile + ndoto + ndota; ! 592: if (nname == 0) { ! 593: fprintf(stderr, ! 594: "Usage: cc [ -o output ] [ options ] file [ ... ]\n"); ! 595: exit(1); ! 596: } ! 597: if (qpass < LD) ! 598: ++nload; ! 599: if (Aflag) ! 600: maketempfile(6); ! 601: if ( ! Eflag) { ! 602: chkofile(); ! 603: if (Kflag) { ! 604: pass[CPP].p_ofn = pass[CC0].p_ifn = tmp[0]; ! 605: pass[CC0].p_ofn = pass[CC1].p_ifn = tmp[1]; ! 606: pass[CC1].p_ofn = pass[CC2].p_ifn = tmp[2]; ! 607: if ( ! Sflag) { ! 608: pass[CC2].p_sfn = tmp[3]; ! 609: pass[CC2].p_ofn = tmp[5]; ! 610: } else { ! 611: pass[CC3].p_ifn = pass[CC2].p_ofn = tmp[3]; ! 612: pass[CC3].p_ofn = tmp[5]; ! 613: } ! 614: } else { ! 615: pass[CPP].p_ofn = pass[CC0].p_ifn = tmp[0]; ! 616: pass[CC0].p_ofn = pass[CC1].p_ifn = tmp[1]; ! 617: pass[CC1].p_ofn = pass[CC2].p_ifn = tmp[0]; ! 618: if ( ! Sflag) { ! 619: pass[CC2].p_sfn = tmp[1]; ! 620: pass[CC2].p_ofn = tmp[5]; ! 621: } else { ! 622: pass[CC3].p_ifn = pass[CC2].p_ofn = tmp[1]; ! 623: pass[CC3].p_ofn = tmp[5]; ! 624: } ! 625: maketempfile(0); ! 626: maketempfile(1); ! 627: } ! 628: pass[AS].p_ofn = tmp[5]; ! 629: } ! 630: } ! 631: ! 632: maketempfile(i) int i; ! 633: { ! 634: char *p; ! 635: strcpy(tmp[i], p = tempnam(pass[TMP].p_dir, pass[TMP].p_pln)); ! 636: free(p); ! 637: ++istmp[i]; ! 638: } ! 639: ! 640: /* ! 641: ** Compilation. ! 642: */ ! 643: compile(argc, argv) ! 644: char *argv[]; ! 645: { ! 646: register char *p1; ! 647: register c, i, err; ! 648: ! 649: err = 0; ! 650: for (i=1; i<argc; ++i) { ! 651: if ((c = (argf[i] & (CCARG | ASARG | MARG))) == 0) ! 652: continue; ! 653: p1 = argv[i]; ! 654: if (err) { ! 655: err = 0; ! 656: if (runme(p1)) { ! 657: ++nload; ! 658: } else { ! 659: --i; ! 660: xstat = 0; ! 661: } ! 662: continue; ! 663: } ! 664: if (nfile > 1 && Qflag == 0) ! 665: printf("%s:\n", p1); ! 666: setfiles(c, p1); ! 667: if (c == CCARG) { ! 668: if (runpp(argc, argv, vstr)) { ! 669: if (Aflag) { ! 670: ++err; --i; ! 671: } else ! 672: ++nload; ! 673: continue; ! 674: } ! 675: if (qpass <= CC0) ! 676: continue; ! 677: if (runcc(CC1)) { ! 678: ++nload; ! 679: continue; ! 680: } ! 681: if (qpass <= CC1) ! 682: continue; ! 683: if (runcc(CC2)) { ! 684: ++nload; ! 685: continue; ! 686: } ! 687: if (qpass <= CC2) ! 688: continue; ! 689: if (Sflag) { ! 690: if (runcc(CC3)) { ! 691: ++nload; ! 692: continue; ! 693: } ! 694: if (qpass <= CC3) ! 695: continue; ! 696: } ! 697: } else if (c == ASARG && qpass>=AS) { ! 698: if (runas()) { ! 699: if (Aflag) { ! 700: ++err; --i; ! 701: } else ! 702: ++nload; ! 703: continue; ! 704: } ! 705: if (qpass <= AS) ! 706: continue; ! 707: } else if (c == MARG) { ! 708: if (runpp(argc, argv, vstr2)) { ! 709: if (Aflag) { ! 710: ++err; --i; ! 711: } else ! 712: ++nload; ! 713: continue; ! 714: } ! 715: if (qpass < AS) ! 716: continue; ! 717: if (runas()) { ! 718: if (Aflag) { ! 719: ++err; --i; ! 720: } else ! 721: ++nload; ! 722: continue; ! 723: } ! 724: if (qpass == AS) ! 725: continue; ! 726: } ! 727: makeft(p1, p1, "o"); ! 728: } ! 729: cleanup(0); ! 730: } ! 731: ! 732: runpp(argc, argv, var) ! 733: register char *argv[]; ! 734: char var[]; ! 735: { ! 736: register char **cp; ! 737: register int i; ! 738: char *p1; ! 739: ! 740: cp = cmda; ! 741: p1 = cmdb; ! 742: p1 = makepass(CC0, *cp++ = p1, AEXEC); ! 743: *cp++ = var; ! 744: *cp++ = pass[CPP].p_ifn; ! 745: if (qpass < CC0) ! 746: *cp++ = Kflag ? pass[CPP].p_ofn : "-"; ! 747: else ! 748: *cp++ = pass[CC0].p_ofn; ! 749: for (i=1; i<argc; ++i) { ! 750: if ((argf[i]&PPOPT) != 0) { ! 751: *cp++ = argv[i]; ! 752: if ((argf[i]&~PPOPT) != 0) ! 753: cp[-1] += strlen(cp[-1])+1; ! 754: } ! 755: } ! 756: *cp = 0; ! 757: return (run(Aflag)); ! 758: } ! 759: ! 760: runcc(pn) ! 761: { ! 762: register char **cp; ! 763: ! 764: cp = cmda; ! 765: makepass(pn, *cp++ = cmdb, AEXEC); ! 766: *cp++ = vstr; ! 767: *cp++ = pass[pn].p_ifn; ! 768: *cp++ = pass[pn].p_ofn; ! 769: if (pn == CC2) ! 770: *cp++ = pass[CC2].p_sfn; ! 771: *cp = 0; ! 772: return (run(0)); ! 773: } ! 774: ! 775: runas() ! 776: { ! 777: register char **cp; ! 778: ! 779: cp = cmda; ! 780: makepass(AS, *cp++ = cmdb, AEXEC); ! 781: *cp++ = "-gx"; ! 782: *cp++ = "-o"; ! 783: *cp++ = pass[AS].p_ofn; ! 784: *cp++ = pass[AS].p_ifn; ! 785: *cp = 0; ! 786: return (run(Aflag)); ! 787: } ! 788: ! 789: runme(fn) ! 790: char *fn; ! 791: { ! 792: register char **cp; ! 793: ! 794: cp = cmda; ! 795: makepass(ED, *cp++ = cmdb, AEXEC); ! 796: *cp++ = fn; ! 797: *cp++ = "-e"; ! 798: *cp++ = tmp[6]; ! 799: *cp = 0; ! 800: return (run(0)); ! 801: } ! 802: runld(argc, argv) ! 803: char *argv[]; ! 804: { ! 805: char *p1; ! 806: register char *p2; ! 807: register char **cp; ! 808: char **cp1; ! 809: register char **cp2; ! 810: int i; ! 811: static char buff[32]; ! 812: ! 813: cp = cmda; ! 814: p1 = makepass(LD, *cp++ = cmdb, AEXEC); ! 815: *cp++ = "-X"; ! 816: if (outf == NULL) { ! 817: *cp++ = "-o"; ! 818: if (partial || doutf == NULL) { ! 819: #if COHERENT ! 820: *cp++ = "l.out"; ! 821: #endif ! 822: #if GEMDOS ! 823: *cp++ = "l.prg"; ! 824: #endif ! 825: } else { ! 826: basename(doutf, buff); ! 827: #if GEMDOS ! 828: strcat(buff, ".prg"); ! 829: #endif ! 830: *cp++ = buff; ! 831: } ! 832: } ! 833: for (i=1; i<argc; ++i) { ! 834: if ((argf[i]&LDOPT)!=0) { ! 835: *cp++ = argv[i]; ! 836: if ((argf[i]&~LDOPT)!=0) { ! 837: cp[-1] += strlen(cp[-1])+1; ! 838: cp[-1] += strlen(cp[-1])+1; ! 839: } ! 840: } ! 841: } ! 842: cp1 = cp; ! 843: p1 = makepass(CRT, *cp++ = p1, AREAD); ! 844: if (fflag) { ! 845: *cp++ = "-u"; ! 846: *cp++ = "_dtefg_"; ! 847: } ! 848: for (i=1; i<argc; ++i) { ! 849: p2 = argv[i]; ! 850: if ((argf[i]&CCLIB)!=0) { ! 851: while (*p2++ != 'l'); ! 852: p1 = makelib(LIB, *cp++ = p1, p2); ! 853: } else if ((argf[i]&(CCARG|ASARG|MARG|LDARG))!=0) { ! 854: for (cp2=cp1; cp2<cp; ++cp2) ! 855: if (strcmp(*cp2, p2) == 0) ! 856: break; ! 857: if (cp2 == cp) { ! 858: *cp++ = p2; ! 859: ++nldob; ! 860: } ! 861: } else if ((argf[i]&LDLIB)!=0) { ! 862: *cp++ = p2; ! 863: } ! 864: } ! 865: if ( ! partial && (GEMAPPflag || GEMACCflag)) { ! 866: p1 = makelib(LIB, *cp++ = p1, "aes"); ! 867: p1 = makelib(LIB, *cp++ = p1, "vdi"); ! 868: } ! 869: p1 = makelib(LIB, *cp++ = p1, "c"); ! 870: *cp = 0; ! 871: return (run(0)); ! 872: } ! 873: ! 874: basename(in, out) ! 875: char *in, *out; ! 876: { ! 877: register char *ip = in, *op = out; ! 878: register int c; ! 879: ! 880: while (*ip++) ! 881: ; ! 882: ip -= 2; ! 883: while (ip >= in && *ip != PATHSEP) ! 884: --ip; ! 885: while ((c = *++ip) && c != '.') ! 886: *op++ = c; ! 887: *op = '\0'; ! 888: } ! 889: ! 890: run(catch_errors) int catch_errors; ! 891: { ! 892: int new_fd; ! 893: int saved_fd; ! 894: int s; ! 895: extern char **environ; ! 896: ! 897: if (Vflag) { ! 898: char *cp, **cpp; ! 899: cpp = cmda; ! 900: while ((cp = *cpp) != NULL) { ! 901: if (cpp != cmda) ! 902: putchar(' '); ! 903: printf("%s", cp); ! 904: ++cpp; ! 905: } ! 906: putchar('\n'); ! 907: fflush(stdout); ! 908: } ! 909: if (catch_errors) { ! 910: fflush(stdout); ! 911: saved_fd = dup(1); ! 912: if ((new_fd = creat(tmp[6], 0644)) < 0) ! 913: cfatal("%s: %s", tmp[6], sys_errlist[errno]); ! 914: if (dup2(new_fd, 1) < 0) ! 915: cfatal("dup2 failed"); ! 916: } ! 917: #if COHERENT ! 918: { ! 919: int nsleep; ! 920: int status; ! 921: int pid; ! 922: nsleep = NSLEEP; ! 923: while ((pid=fork())<0 && nsleep--) ! 924: sleep(DELAY); ! 925: if (pid < 0) ! 926: cfatal("can't fork"); ! 927: if (pid == 0) { ! 928: execve(cmda[0], cmda, environ); ! 929: exit(MAGIC); ! 930: } ! 931: while (wait(&status) != pid) ! 932: ; ! 933: if ((s = status&0177)!=0 && s!=SIGINT) { ! 934: extern char *signame[]; ! 935: ! 936: fprintf(stderr, "cc: %s ", cmda[0]); ! 937: if (s==SIGSYS && (status&0200)==0) ! 938: fprintf(stderr, "exec failed"); ! 939: else ! 940: fprintf(stderr, signame[s]); ! 941: if ((status&0200) != 0) ! 942: fprintf(stderr, " -- core dumped"); ! 943: fprintf(stderr, "\n"); ! 944: } else if ((s = (status>>8)&0377) == MAGIC) ! 945: cfatal("cannot execute %s", cmda[0]); ! 946: } ! 947: #else ! 948: if (s = execve(cmda[0], cmda, environ)) ! 949: if (s < 0) ! 950: perror(cmda[0]); ! 951: #endif ! 952: if (catch_errors) { ! 953: fflush(stdout); ! 954: if (dup2(saved_fd, 1) < 0) ! 955: cfatal("dup2 failed"); ! 956: if (close(new_fd) < 0) ! 957: /* cfatal("error on close") */ ; ! 958: } ! 959: if (s != 0) ! 960: xstat = 1; ! 961: return (s); ! 962: } ! 963: ! 964: /* ! 965: ** Option processing. ! 966: */ ! 967: ! 968: /* ! 969: * Compare option name to argument. ! 970: */ ! 971: opeq(op, ap) ! 972: register char *op, *ap; ! 973: { ! 974: while (*op!=0) ! 975: if (*op++ != *ap++) ! 976: return (0); ! 977: return (1); ! 978: } ! 979: ! 980: ! 981: /* ! 982: * Get short pass name. ! 983: * translate single character code into pass index number. ! 984: */ ! 985: getpsn(c) ! 986: register int c; ! 987: { ! 988: register int pn; ! 989: ! 990: for (pn = CPP; pn < ALL; pn += 1) ! 991: if (pass[pn].p_psn == c) ! 992: return (pn); ! 993: return (NONE); ! 994: } ! 995: ! 996: /* ! 997: * Process -t*, -B*, -M* options. ! 998: * -t* sets take flag for specified passes. ! 999: * -B* copies prefix string for flagged passes ! 1000: * or for all machine dependent passes if none flagged. ! 1001: * -M* copies machine string for machine dependent passes. ! 1002: * -N* renames a pass, such as crts0.o. ! 1003: */ ! 1004: getpass(c, cp) ! 1005: register int c; ! 1006: register char *cp; ! 1007: { ! 1008: if (c == 't') { /* Take passes from backup */ ! 1009: if (*cp != 0) ! 1010: while ((c = *cp++) != 0) ! 1011: if ((c = getpsn(c)) >= CPP) { ! 1012: pass[c].p_flag |= P_TAKE; ! 1013: pass[c].p_dir = dnul; ! 1014: if (Vflag) ! 1015: passrpt(c); ! 1016: } else { ! 1017: badpsn(cp[-1]); ! 1018: } ! 1019: else ! 1020: getpass('t', "01234"); ! 1021: } else if (c == 'B') { /* Get backup string */ ! 1022: for (c = CPP; c < ALL; c += 1) { ! 1023: if ((pass[c].p_flag&P_TAKE) != 0) { ! 1024: pass[c].p_flag ^= P_TAKE; ! 1025: pass[c].p_flag |= P_BACK; ! 1026: pass[c].p_dir = cp; ! 1027: if (Vflag) ! 1028: passrpt(c); ! 1029: } ! 1030: } ! 1031: } else if (c == 'M') { /* Machine prefix string */ ! 1032: if (strlen(cp) > PTMP-1) ! 1033: toolong(cp); ! 1034: strcpy(dmch, cp); ! 1035: if (Vflag) ! 1036: printf("Prefix: %s\n", dmch); ! 1037: } else if (c == 'N') { /* New pass name */ ! 1038: if ((c = getpsn(*cp++)) >= CPP) { ! 1039: if (strlen(cp) > PTMP-1) ! 1040: toolong(cp); ! 1041: if (Vflag) ! 1042: printf("Rename: %s to %s\n", pass[c].p_pln, cp); ! 1043: strcpy(pass[c].p_pln, cp); ! 1044: } else ! 1045: badpsn(cp[-1]); ! 1046: } ! 1047: } ! 1048: ! 1049: passrpt(c) ! 1050: register int c; ! 1051: { ! 1052: printf("Use: {%s}%s%s\n", pass[c].p_dir, pass[c].p_mch, pass[c].p_pln); ! 1053: } ! 1054: ! 1055: missingname() ! 1056: { ! 1057: fprintf(stderr, "cc: missing name in -o, -e or -u\n"); ! 1058: exit(1); ! 1059: } ! 1060: ! 1061: badoutput() ! 1062: { ! 1063: fprintf(stderr, "cc: improbable name in -o: %s\n", outf); ! 1064: exit(1); ! 1065: } ! 1066: ! 1067: toomany() ! 1068: { ! 1069: fprintf(stderr, "cc: too many files for -o option\n"); ! 1070: exit(1); ! 1071: } ! 1072: ! 1073: badpsn(c) ! 1074: { ! 1075: fprintf(stderr, "cc: unknown short path name: %c\n", c); ! 1076: exit(1); ! 1077: } ! 1078: ! 1079: toolong(cp) ! 1080: char *cp; ! 1081: { ! 1082: fprintf(stderr, "cc: name, prefix, or directory too long: %s\n", cp); ! 1083: exit(1); ! 1084: } ! 1085: ! 1086: /* ! 1087: * Check specified output file name, ! 1088: * or construct name from first file ! 1089: * name seen. ! 1090: */ ! 1091: chkofile() ! 1092: { ! 1093: register char *fn; ! 1094: register char c; ! 1095: ! 1096: if ((fn = outf) == NULL) ! 1097: return; ! 1098: if (fn[0] == '-') ! 1099: badoutput(); ! 1100: if (nname > 1 && qpass < LD) ! 1101: toomany(); ! 1102: while (*fn != 0) ! 1103: ++fn; ! 1104: while (*fn != '.' && fn > outf) ! 1105: --fn; ! 1106: if (*fn++ == '.' && (c = *fn++) && *fn == '\0') { ! 1107: if (c == 'c' ! 1108: || c == 'h' ! 1109: || c == 'm' ! 1110: || (c != 'o' && cflag) ! 1111: || (c == 'o' && !cflag) ! 1112: || (c != 's' && Sflag) ! 1113: || (c == 's' && !Sflag)) ! 1114: badoutput(); ! 1115: } else { ! 1116: if (Sflag || cflag) ! 1117: badoutput(); ! 1118: } ! 1119: } ! 1120: ! 1121: whatopt(s) ! 1122: char *s; ! 1123: { ! 1124: fprintf(stderr, "cc: unrecognized option: %s\n", s); ! 1125: exit(1); ! 1126: } ! 1127: ! 1128: cfatal(s) ! 1129: char *s; ! 1130: { ! 1131: fprintf(stderr, "cc: fatal error: %r\n", &s); ! 1132: cleanup(0); ! 1133: exit(1); ! 1134: } ! 1135: ! 1136: /* ! 1137: ** Intermediate file processing. ! 1138: */ ! 1139: /* ! 1140: * Given cp -> `name.[chms]' rewrite ultimate destination and intermediates ! 1141: * if necessary. ! 1142: */ ! 1143: setfiles(c, cp) ! 1144: int c; ! 1145: register char *cp; ! 1146: { ! 1147: register char *ip; ! 1148: ! 1149: ip = cp; ! 1150: if (qpass < LD && outf != NULL) ! 1151: cp = outf; ! 1152: if (c == CCARG) { ! 1153: pass[CPP].p_ifn = ip; ! 1154: if (Eflag) ! 1155: return; ! 1156: if (Kflag) { ! 1157: makeft(pass[CPP].p_ofn, cp, "i"); ! 1158: makeft(pass[CC0].p_ofn, cp, "0"); ! 1159: makeft(pass[CC1].p_ofn, cp, "1"); ! 1160: if ( ! Sflag) ! 1161: makeft(pass[CC2].p_sfn, cp, "2"); ! 1162: else ! 1163: makeft(pass[CC2].p_ofn, cp, "2"); ! 1164: } ! 1165: } else if (c == MARG) { ! 1166: pass[CPP].p_ifn = ip; ! 1167: if (Kflag) ! 1168: makeft(pass[CC0].p_ofn, cp, "s"); ! 1169: pass[AS].p_ifn = pass[CC0].p_ofn; ! 1170: } else if (c == ASARG) ! 1171: pass[AS].p_ifn = ip; ! 1172: makeft(tmp[5], cp, Sflag ? "s" : "o"); ! 1173: if (!Sflag && newo[0] == 0 && access(tmp[5], 0) < 0) ! 1174: strcpy(newo, tmp[5]); ! 1175: } ! 1176: ! 1177: /* ! 1178: * Unlink a file. ! 1179: * If `-V' echo the rm. ! 1180: */ ! 1181: rm(s) ! 1182: register char *s; ! 1183: { ! 1184: if (Vflag) ! 1185: printf("rm %s\n", s); ! 1186: unlink(s); ! 1187: } ! 1188: ! 1189: /* ! 1190: * Cleanup after yourself if ! 1191: * the user hits interrupt during a compile (sig == SIGINT), ! 1192: * or when all compiles have completed (sig == 0). ! 1193: */ ! 1194: cleanup(sig) ! 1195: { ! 1196: register int i; ! 1197: ! 1198: #if COHERENT ! 1199: if (sig == SIGINT) ! 1200: signal(SIGINT, SIG_IGN); ! 1201: #endif ! 1202: for (i = 0; i < 7; i += 1) ! 1203: if (istmp[i]) ! 1204: rm(tmp[i]); ! 1205: #if COHERENT ! 1206: if (sig == SIGINT && nldob==1 && newo[0]!=0) ! 1207: rm(newo); ! 1208: if (sig == SIGINT) ! 1209: exit(1); ! 1210: #endif ! 1211: } ! 1212: ! 1213: /* ! 1214: ** Name construction. ! 1215: */ ! 1216: char * ! 1217: ccpath(cp, p, n, mode) register char *cp; char *p, *n; int mode; ! 1218: { ! 1219: register char *pn; ! 1220: if (VeryVflag && Vflag) ! 1221: printf("search %s for %s\n", p, n); ! 1222: while ((pn = path(p, n, mode)) == NULL) { ! 1223: if (Zflag) { /* Disk swap dialog flag */ ! 1224: fprintf(stderr, "Insert %s's disk in a free drive and press <Return>\n", n); ! 1225: gets(cp); ! 1226: continue; ! 1227: } ! 1228: pn = n; ! 1229: break; ! 1230: } ! 1231: while (*cp++ = *pn++) ; ! 1232: return cp; ! 1233: } ! 1234: ! 1235: char * ! 1236: makepass(pn, cp, mode) ! 1237: int pn; ! 1238: register char *cp; ! 1239: int mode; ! 1240: { ! 1241: return ccpath(cp, pass[pn].p_dir, pass[pn].p_pln, mode); ! 1242: } ! 1243: ! 1244: char * ! 1245: makelib(pn, cp, lp) ! 1246: int pn; ! 1247: char *cp; ! 1248: char *lp; ! 1249: { ! 1250: strcpy(cp, pass[pn].p_pln); ! 1251: strcat(cp, lp); ! 1252: strcat(cp, ".a"); ! 1253: return ccpath(cp, pass[pn].p_dir, cp, AREAD); ! 1254: } ! 1255: ! 1256: makeft(op, ip, ft) ! 1257: char *op, *ip, *ft; ! 1258: { ! 1259: register char *ep, *tp; ! 1260: register c; ! 1261: char *dp; ! 1262: ! 1263: ep = ip; ! 1264: tp = op; ! 1265: dp = NULL; ! 1266: while ((c = *ep++) != '\0') { ! 1267: if (c == PATHSEP && ip != outf) { ! 1268: tp = op; ! 1269: dp = NULL; ! 1270: } else { ! 1271: if (c == '.') ! 1272: dp = tp; ! 1273: *tp++ = c; ! 1274: } ! 1275: } ! 1276: if (ip == outf) ! 1277: return; ! 1278: if (dp != NULL) ! 1279: tp = dp; ! 1280: *tp++ = '.'; ! 1281: ep = ft; ! 1282: while (*tp++ = *ep++) ! 1283: ; ! 1284: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.