/* * mimosa.c - front end for Mesa/Cedar compiler */ #include #include #include #include #include #include #include #include #include "compServer.h" #include "compServerDefs.h" extern long time(); /* why is this not in time.h? */ extern int putenv(); static void ParseCommandLine(); static void CompileFile(); typedef struct { char *on; /* this is the corresponding cedar value switch when ON */ char *off; /* this is the corresponding cedar value switch when OFF */ } cedarSwitch; /* * this array contains the equivalent cedar (mimosa) switches for the * SSU frontend switches. */ cedarSwitch mimosaArgArray[] = { { "a", "~a" }, /* a */ { "~b", "b" }, /* b */ { "", "" }, /* c */ { "", "" }, /* d */ { "e", "~e" }, /* e */ { "~h", "h" }, /* f */ { "", "" }, /* g */ { "", "" }, /* h */ { "", "" }, /* i */ { "", "" }, /* j */ { "", "" }, /* k */ { "c", "~c" }, /* l */ { "m", "~m" }, /* m */ { "~n", "n" }, /* n */ { "", "" }, /* o */ { "p", "~p" }, /* p */ { "Xk", "" }, /* q */ { "%%", "~%%" }, /* r */ { "", "" }, /* s */ { "", "" }, /* t */ { "~u", "u" }, /* u */ { "", "" }, /* v */ { "~w", "w" }, /* w */ { "", "" }, /* x */ { "", "" }, /* y */ { "a", "~a" }, /* z */ { "p", "~p" }, /* pw */ { "XK", "" }, /* Q */ { "", "" }, /* zcirio */ { "k", "~k" } /* si - smaller installation code */ /* if you add another additional switches, update compServerDefs.h Switches enumeration and up size of typedef SwitchesArray in compServer.h */ }; main(argc, argv) int argc; char **argv; { int temp = 0; Handle h = NewHandle(argc, argv); /* defaults all switches FALSE */ h->job.jobKind = compile; /* parse the command line: */ ParseCommandLine(h); /* start the global timer: */ h->startTime = time((long *) NULL); /* for each source file, do the compilation: */ for (temp = 0; temp < h->nJobs; temp++) { h->job.shortFileName = h->jobList[temp]; CompileFile(h); PutS("\n"); } /* get the finish time: */ h->finishTime = time((long *) NULL); /* report finish time: */ if (!isSwitchSet(h, (Switches)'t')) { PutS("mimosa: seconds: "); PutLong(h->finishTime - h->startTime); PutS("\n"); } /* free handle and contents */ FreeHandle(h); ExitSuccessfully(); /*NOTREACHED*/ } static void PrintHelp() { PutS("mimosa: (see also \"man mimosa\")\n"); PutS("usage: mimosa [options] fileList\n"); PutS("options: \n"); PutS("\t-a\taccumulate execution data\n"); PutS("\t-b\tturn off bounds checking\n"); PutS("\t-c\tjust produce .c file\n"); PutS("\t-d\tshow (but don't execute) commands\n"); PutS("\t-e\tuse external initialization code\n"); PutS("\t-f\tgenerate old style signal catch code\n"); PutS("\t-g\tdon't produce dbx symbol tables\n"); PutS("\t-h\tprint this help message\n"); PutS("\t-i\tsimulate dryrun of an interface (used with -d)\n"); PutS("\t-j\tfinish the mimosa compile from the .c file\n"); PutS("\t-k\tkeep intermediate files\n"); PutS("\t-l\tuse .c2c.c instead of .c for filename extension\n"); PutS("\t-m\tjust produce mimosa intermediate file\n"); PutS("\t-n\tturn off nil checking\n"); PutS("\t-oN\toptimize object code - N is a value in [0..4]\n"); PutS("\t-p\tgenerate prof tables\n"); PutS("\t-pw\tpause for warning\n"); PutS("\t-q\tgenerate position independent code with -pic\n"); PutS("\t-Q\tgenerate position independent code with -PIC\n"); PutS("\t-target arch \t compile this file for the arch architecture\n"); PutS("\t-r\tperform additional address (and other) checks\n"); PutS("\t-s\tjust generate assembly code file\n"); PutS("\t-t\tdon't report compilation times\n"); PutS("\t-u\tdon't report uninitialized variables\n"); PutS("\t-v\tverbose\n"); PutS("\t-w\tdon't print warnings\n"); PutS("\t-x file\tcall /usr/lib/inline with \"-i file\"\n"); PutS("\t-y\tyell about runtime calls\n"); PutS("\t-z\tproduce Mesa debugging information\n"); PutS("\n"); ExitSuccessfully(); /*NOTREACHED*/ } static void Usage(h) Handle h; { Fatal(h, "Usage: mimosa [options] fileList"); } static int ProcessSwitches(h, argNo) Handle h; int argNo; { int wasQ = FALSE; char *argv = h->argv[argNo]; int ch = argv[1]; if (ch == 'Q') wasQ = TRUE; switch (tolower(ch)) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'i': case 'j': case 'k': case 'l': case 'n': setSwitch(h, (Switches)tolower(ch)); break; case 'h': PrintHelp(); break; case 'm': if (argv[2] == '\0') { setSwitch(h, (Switches)'m'); } else if (!strcmp("-mpp", argv)) { break; /* do nothing; mpp already done in front-end script */ } else { Fatal2(h, argv, ": unexpected command line option\n"); } break; case 'o': { int level = 3; resetSwitch(h, (Switches)'z'); /* optimizing turns off debugging */ setSwitch(h, (Switches)'o'); if (isdigit(argv[2])) { level = argv[2] - '0'; if ((level < 0) || (level > 4)) Fatal(h, "mimosa: optimization level must be between 0 and 4 inclusive.\n"); } else { Warning(h, "mimosa: unknown optimization level, setting to default.\n"); } h->optLevel = level; break; } case 'p': if (argv[2] == 'g') { Fatal(h, "Old format symbols no longer supported; use -p"); } else if (argv[2] == 'w') { setSwitch(h, pw); } else { setSwitch(h, (Switches)'p'); } break; case 'q': if (wasQ == TRUE) { setSwitch(h, Q); } else { setSwitch(h, (Switches)'q'); } wasQ = FALSE; break; case 'r': case 'u': case 'v': case 'w': setSwitch(h, (Switches)tolower(ch)); break; case 's': if (argv[2] == '\0') { setSwitch(h, (Switches)'s'); } else if (!strcmp("-si", argv)) { setSwitch(h, si); } else { Fatal2(h, argv, ": unexpected command line option\n"); } break; case 't': if (argv[2] == '\0') { setSwitch(h, (Switches)'t'); } else if (!strcmp("-target", argv)) { if (++argNo >= h->argc || !validArch(h->argv[argNo])) Fatal(h, "mimosa: invalid target architecture\n"); if (strcmp("sun4", h->argv[argNo])) resetSwitch(h, (Switches)'z'); h->archtype = archFromString(h->argv[argNo]); } else { Fatal2(h, argv, ": unexpected command line option\n"); } break; case 'x': setSwitch(h, (Switches)tolower(ch)); if (++argNo < h->argc) { h->inlineFile = strdup(h->argv[argNo]); } else { Usage(h); } break; case 'y': setSwitch(h, (Switches)'y'); break; /* case 'z': h->job.switches[ORD(z)] = TRUE; continue; */ /* For Laurie: */ case 'z': resetSwitch(h, (Switches)'z'); break; default: Fatal2(h, h->argv[argNo], ": unexpected command line option\n"); break; } return argNo; } static void doSwitch(h, s, sw) Handle h; char *s; Switches sw; { if (isSwitchSet(h, sw)) strcat(s, mimosaArgArray[sw - a].on); else strcat(s, mimosaArgArray[sw - a].off); } static void ParseCommandLine(h) Handle h; { int temp; char *suffix; char **argv = h->argv; #ifdef sun setSwitch(h, (Switches)'z'); /* default z to be TRUE */ #else setSwitch(h, zcirio); #endif for (temp = 1; temp < h->argc; temp++) { if (argv[temp][0] == '-') { /* process switches */ temp = ProcessSwitches(h, temp); continue; } /* * at this point all switches are handled, * look for conflicting and/or non-sensical switches */ if (h->archtype == UNKNOWN) { /* if no -target option */ char *archname = getenv("TARGET_ARCH"); if (archname == NULL) { /* if no TARGET_ARCH set to local arch */ h->archtype = getArch(); } else { h->archtype = archFromString(archname); } } if ((isSwitchSet(h, Q) || isSwitchSet(h, (Switches)'q')) && !isSun4Target(h)) { Warning(h, "mimosa: -Q and -q only supported on Sun\n"); resetSwitch(h, Q); resetSwitch(h, (Switches)'q'); } if (isSwitchSet(h, (Switches)'q') && isSwitchSet(h, Q)) { Warning(h, "mimosa: warning: -q and -Q specified, using -Q\n"); setSwitch(h, Q); resetSwitch(h, (Switches)'q'); } if (!isSwitchSet(h, (Switches)'g') && isSwitchSet(h, (Switches)'o')) { Warning(h, "mimosa: warning: -O disables dbx symbols\n"); setSwitch(h, (Switches)'g'); } if (isSwitchSet(h, (Switches)'z') && !isSun4Target(h)) { Warning(h, "mimosa: dbx debugging not supported on non-Sun platforms\n"); resetSwitch(h, (Switches)'z'); } if (isSwitchSet(h, (Switches)'x') && !isSun4Target(h)) { Warning(h, "mimosa: inlining not supported on non-Sun platforms\n"); resetSwitch(h, (Switches)'x'); h->inlineFile = 0; } if (isSwitchSet(h, (Switches)'a') && !isSun4Target(h)) { Warning(h, "mimosa: tcov not supported on non-Sun platforms\n"); resetSwitch(h, (Switches)'a'); } /* handle filenames */ suffix = rindex(argv[temp], '.'); if (suffix == NULL) { /* copy the string */ suffix = strdup(argv[temp]); h->jobList[h->nJobs++] = suffix; } else if (strcmp(suffix + 1, "mesa") == 0) { /* copy the string */ suffix = strdup(argv[temp]); h->jobList[h->nJobs++] = suffix; suffix = rindex(suffix, '.'); /* strip suffix */ suffix[0] = '\0'; } else { Fatal2(h, "Expected to see a mesa source file extension instead of ", argv[temp]); } } } static void AppendJStatusString(js, localJobStatus) char *js; JobStatus localJobStatus; { switch (localJobStatus) { case onReadyQueue: (void)strcpy(js, "onReadyQueue"); break; case mimosaInProgress: (void)strcpy(js, "mimosaInProgress"); break; case mimosaCompileFailed: (void)strcpy(js, "mimosaCompileFailed"); break; case successfulDef: (void)strcpy(js, "successfulDef"); break; case successfulImpl: (void)strcpy(js, "successfulImpl"); break; case successfulDefWithWarnings: (void)strcpy(js, "successfulDefWithWarnings"); break; case successfulImplWithWarnings: (void)strcpy(js, "successfulImplWithWarnings"); break; case successfulCind: (void)strcpy(js, "successfulCind"); break; case successfulCindWithWarnings: (void)strcpy(js, "successfulCindWithWarnings"); break; case cindFailed: (void)strcpy(js, "cindFailed"); break; case successfulMS: (void)strcpy(js, "successfulMS"); break; case successfulMSWithWarnings: (void)strcpy(js, "successfulMSWithWarnings"); break; case msFailed: (void)strcpy(js, "msFailed"); break; case jobNotFound: (void)strcpy(js, "jobNotFound"); break; case serverTimeout: (void)strcpy(js, "serverTimeout"); break; default: (void)strcpy(js, "(Unknown status code)"); break; } } static int DoMS(h) Handle h; { char statusString[MAXSTATUSSTRINGSIZE]; char mobsFile[MAXNAMLEN + 10]; char errorLogFile[MAXNAMLEN+10]; char *fileNameBase = h->job.shortFileName; JobQueryResult jobResult; int sstatus; int retval = FALSE; AppendFileName(mobsFile, fileNameBase, ".mob.s"); AppendFileName(errorLogFile, fileNameBase, ".msErrlog"); Verbose(h, "M"); if (isSun4Target(h)) sstatus = systeme(h,"msPackaged","msPackaged ",fileNameBase, SUN4, (int)successfulMS); else Fatal(h, "internal error: ms called for non-sun4 arch\n"); jobResult.js = JobStatusFromStatus(sstatus); switch (jobResult.js) { case msFailed: PutS(" MS failed! See "); PutS(errorLogFile); PutC('\n'); Fatal(h, jobResult.err); break; case successfulMSWithWarnings: Warning(h, "Warnings - see "); Warning(h, errorLogFile); if (isSwitchSet(h, pw)) Fatal(h, "-pw switch used: pausing for warnings"); retval = TRUE; break; case successfulMS: retval = TRUE; break; default: AppendJStatusString(statusString, jobResult.js); (void)strcat(statusString, ": "); Fatal2(h, statusString, jobResult.err); break; } return(retval); } static int DoMimosaAndC2CCompile(h) Handle h; { char *compilerLogFile = "Mimosa.log"; char statusString[MAXSTATUSSTRINGSIZE]; char cFileName[MAXNAMLEN + 10]; char errorLogFile[MAXNAMLEN + 10]; char intCodeFile[MAXNAMLEN + 10]; char namesFile[MAXNAMLEN + 10]; char cTypesFile[MAXNAMLEN + 10]; char cCodeFile[MAXNAMLEN + 10]; char objectFileName[MAXNAMLEN + 10]; char *fileNameBase = h->job.shortFileName; char *cExtension; char *outFileExtension; char cmdStr[MAXCOMMANDSTRINGSIZE]; int retval; int sstatus; JobQueryResult jobResult; cExtension = isSwitchSet(h, (Switches)'l') ? ".c2c.c" : ".c"; outFileExtension = isSwitchSet(h, (Switches)'l') ? ".c2c.o" : ".o"; AppendFileName(errorLogFile, fileNameBase, ".errlog"); AppendFileName(intCodeFile, fileNameBase, ".icd"); AppendFileName(namesFile, fileNameBase, ".names"); AppendFileName(cTypesFile, fileNameBase, ".cTypes"); AppendFileName(cCodeFile, h->job.shortFileName, cExtension); AppendFileName(objectFileName, fileNameBase, outFileExtension); (void) strcpy(cFileName, fileNameBase); (void) strcat(cFileName, cExtension); /* set the correct switches */ strcpy(cmdStr, "mimosaPackaged -l"); /* if (isSwitchSet(h, (Switches)'a') || isSwitchSet(h, (Switches)'z')) */ if (isSwitchSet(h, (Switches)'z')) strcat(cmdStr, "a"); else strcat(cmdStr, "~a"); doSwitch(h, cmdStr, (Switches)'b'); doSwitch(h, cmdStr, (Switches)'e'); doSwitch(h, cmdStr, (Switches)'f'); doSwitch(h, cmdStr, (Switches)'l'); doSwitch(h, cmdStr, (Switches)'m'); doSwitch(h, cmdStr, (Switches)'n'); doSwitch(h, cmdStr, pw); doSwitch(h, cmdStr, (Switches)'r'); doSwitch(h, cmdStr, si); doSwitch(h, cmdStr, (Switches)'u'); doSwitch(h, cmdStr, (Switches)'w'); PutC('M'); if (isSun4Target(h)) sstatus = systeme(h,"mimosaPackaged",cmdStr, fileNameBase, SUN4, (int)successfulImpl); else if (isDecTarget(h)) sstatus = systeme(h,"decMimPackaged",cmdStr, fileNameBase, SUN4, (int)successfulImpl); else if (isRS6000Target(h)) sstatus = systeme(h,"mimosaPackaged",cmdStr, fileNameBase, RS6000, (int)successfulImpl); else Fatal(h, "Internal error: unknown target type\n"); jobResult.js = JobStatusFromStatus(sstatus); switch (jobResult.js) { case mimosaCompileFailed: PutS(" Mimosa compile failed! See "); PutS(errorLogFile); PutC('\n'); if (!isSwitchSet(h, (Switches)'m') && !isSwitchSet(h, (Switches)'k')) { /* delete intermediate files */ DeleteFile(h, compilerLogFile); DeleteFile(h, intCodeFile); DeleteFile(h, namesFile); DeleteFile(h, cTypesFile); DeleteFile(h, cCodeFile); } Fatal(h, jobResult.err); retval = FALSE; break; case successfulDefWithWarnings: if (isSwitchSet(h, (Switches)'w')) jobResult.js = successfulDef; Warning(h, "Warnings - see "); Warning(h, errorLogFile); Warning(h, "\n"); DeleteFile(h, compilerLogFile); if (isSwitchSet(h, pw)) Fatal(h, "-pw switch used: pausing for warnings"); retval = FALSE; break; case successfulDef: if (!isSwitchSet(h, (Switches)'m') && !isSwitchSet(h, (Switches)'k')) DeleteFile(h, compilerLogFile); DeleteFile(h, objectFileName); retval = FALSE; break; case successfulImplWithWarnings: Warning(h, "Warnings - see "); Warning(h, errorLogFile); Warning(h, "\n"); if (!isSwitchSet(h, (Switches)'m') && !isSwitchSet(h, (Switches)'k')) DeleteFile(h, compilerLogFile); if (isSwitchSet(h, pw)) Fatal(h, "-pw switch used: pausing for warnings"); retval = !isSwitchSet(h, (Switches)'m'); break; case successfulImpl: if (!isSwitchSet(h, (Switches)'m') && !isSwitchSet(h, (Switches)'k')) DeleteFile(h, compilerLogFile); retval = !isSwitchSet(h, (Switches)'m'); break; default: AppendJStatusString(statusString, jobResult.js); (void) strcat(statusString, ": "); Fatal2(h, statusString, jobResult.err); retval = FALSE; break; } return retval; } static void DoMSCCompile(h) Handle h; { char *cpp1 = "/lib/cpp "; char *cpp2; /* * /lib/cpp FILENAME.c > FILENAME.E *OR* * /lib/cpp FILENAME.c2c.c > FILENAME.E */ /* This awk script does the following: * * - Look for the first line where lineno is greater than or equal * to 123000 and the file name is filename.mesa. * - After the first line is found, don't print lines (continue) * where the filename is filename.c (or filename.c2c.c). * - Unconditionally print all other lines. * * awk 'BEGIN {mesaSource = 0} \ * /^#/ {if (mesaSource == 0) \ * {if ($2 >= 123000 && $3 == "\"FILENAME.mesa\"") \ * mesaSource = 1} \ * else if ($3 == "\"FILENAME.c\"") continue} \ * {print}' FILENAME.E > FILENAME.E.c */ char *awk1 = "/bin/awk 'BEGIN {mesaSource = 0} "; char *awk2 = "/^#/ {if (mesaSource == 0) {if ($2 >= 123000 && $3 == \"\\\""; char *awk3 = ".mesa\\\"\") mesaSource = 1} else if ($3 == \"\\\""; char *awk4; char *redirect = " > "; char *ccom1 = "/lib/ccom "; char *ccom2 = "-Xg "; char *ccom3 = ".s"; /* * /lib/ccom [-p] [-w] -Xg FILENAME.E.c > FILENAME.s *OR* * /lib/ccom [-p] [-w] -Xg FILENAME.E.c2c.c > FILENAME.s */ char *fileNameBase = h->job.shortFileName; char cmdStr[500]; char eFile[MAXNAMLEN + 10]; char ecFile[MAXNAMLEN + 10]; int sstatus; int awkFailed = 0; AppendFileName(eFile, fileNameBase, ".E"); if (isSwitchSet(h, (Switches)'l')) { AppendFileName(ecFile, fileNameBase, ".E.c2c.c"); cpp2 = ".c2c.c > "; awk4 = ".c2c.c\\\"\") continue} {print}' "; } else { AppendFileName(ecFile, fileNameBase, ".E.c"); cpp2 = ".c > "; awk4 = ".c\\\"\") continue} {print}' "; } Verbose(h, "C"); (void) strcpy (cmdStr, cpp1); (void) strcat (cmdStr, fileNameBase); (void) strcat (cmdStr, cpp2); (void) strcat (cmdStr, eFile); Verbose(h, cmdStr); Verbose(h, "\n"); if (!isSwitchSet(h, (Switches)'d')) { sstatus = rsh_system(h, cmdStr); if ((sstatus & 0377) != 0) Fatal2(h, "cpp failed for: ", fileNameBase); } (void) strcpy (cmdStr, awk1); (void) strcat (cmdStr, awk2); (void) strcat (cmdStr, fileNameBase); (void) strcat (cmdStr, awk3); (void) strcat (cmdStr, fileNameBase); (void) strcat (cmdStr, awk4); (void) strcat (cmdStr, eFile); (void) strcat (cmdStr, redirect); (void) strcat (cmdStr, ecFile); Verbose(h, cmdStr); Verbose(h, "\n"); if (!isSwitchSet(h, (Switches)'d')) { sstatus = rsh_system(h, cmdStr); if ((sstatus & 0377) != 0) { /* awk step failed - just put on a warning and skip * the awk step. */ Warning(h, "Warning: awk failed for "); Warning(h, fileNameBase); awkFailed = 1; } } (void) strcpy(cmdStr, ccom1); if (isSwitchSet(h, (Switches)'p')) (void)strcat(cmdStr, mimosaArgArray['p' - a].on); if (isSwitchSet(h, (Switches)'q')) (void)strcat(cmdStr, mimosaArgArray['q' - a].on); if (isSwitchSet(h, Q)) (void)strcat(cmdStr, mimosaArgArray['Q' - a].on); if (isSwitchSet(h, (Switches)'w')) (void)strcat(cmdStr, mimosaArgArray['w' - a].on); (void)strcat(cmdStr, ccom2); (void)strcat(cmdStr, awkFailed ? eFile : ecFile); (void)strcat(cmdStr, redirect); (void)strcat(cmdStr, fileNameBase); (void)strcat(cmdStr, ccom3); Verbose(h, cmdStr); Verbose(h, "\n"); if (!isSwitchSet(h, (Switches)'d')) { sstatus = rsh_system(h, cmdStr); if ((sstatus & 0377) != 0) Fatal2(h, "ccom failed for: ", fileNameBase); if (!isSwitchSet(h, (Switches)'k')) { DeleteFile(h, eFile); DeleteFile(h, ecFile); } } } static void DoInline(h, inputFileName) Handle h; char *inputFileName; { char *av[MAXAVSIZE]; char outFileName[MAXNAMLEN+3]; int avc = 0; (void) strcpy(outFileName, h->job.shortFileName); (void) strcat(outFileName, ".i.s"); if (!isSun4Target(h)) { /* in theory we never get here because inlining has been * turned off for non-sun platforms after processing switches */ Fatal2(h, "inlining not supported on ", stringFromArch(h->archtype)); } else { av[avc++] = "/usr/lib/inline"; av[avc++] = "-i"; av[avc++] = h->inlineFile; av[avc++] = "-o"; av[avc++] = outFileName; av[avc++] = inputFileName; av[avc++] = NULL; } Verbose(h, "C"); if (CallSys(h, av[0], av)) Fatal2(h, "cc failed for: ", h->job.shortFileName); } static void CompileFile(h) Handle h; { char cCodeFile[MAXNAMLEN + 10]; char sFile[MAXNAMLEN + 10]; char mobsFile[MAXNAMLEN + 10]; char inlineFile[MAXNAMLEN + 10]; char ccInputFileSuffix[10]; char *cExtension; cExtension = isSwitchSet(h, (Switches)'l') ? ".c2c.c" : ".c"; AppendFileName(cCodeFile, h->job.shortFileName, cExtension); AppendFileName(sFile, h->job.shortFileName, ".s"); AppendFileName(mobsFile, h->job.shortFileName, ".mob.s"); AppendFileName(inlineFile, h->job.shortFileName, ".i.s"); if (!isSwitchSet(h, (Switches)'j')) { /* Then do the mimosa compile */ if (!DoMimosaAndC2CCompile(h) || isSwitchSet(h, (Switches)'c')) return; } /* otherwise, assume that a previous mimosa -c was done */ /* assert: was a successful impl to be C compiled */ (void) strcpy(ccInputFileSuffix, cExtension); if (isSwitchSet(h, (Switches)'z') && isSun4Target(h)) { /* -z option was specified - go through MS */ JobKind jobKind = h->job.jobKind; DoMSCCompile(h); h->job.jobKind = ms; if (!DoMS(h)) return; h->job.jobKind = jobKind; /* restore jobKind */ (void) strcpy(ccInputFileSuffix, ".mob.s"); } if (h->inlineFile != NULL) { /* -x option - run through inline */ if (isSwitchSet(h, (Switches)'z')) { DoInline(h, mobsFile); } else { setSwitch(h, (Switches)'s'); DoCCompile(h, cExtension, FALSE); resetSwitch(h, (Switches)'s'); DoInline(h, sFile); } (void) strcpy(ccInputFileSuffix, ".i.s"); } DoCCompile(h, ccInputFileSuffix, TRUE); /* Do the final C compile. */ if (!isSwitchSet(h, (Switches)'k')) { /* Delete the files. */ if (!isSwitchSet(h, (Switches)'j')) DeleteFile(h, cCodeFile); if (isSwitchSet(h, (Switches)'z')) { DeleteFile(h, mobsFile); DeleteFile(h, sFile); } if (h->inlineFile != NULL) { DeleteFile(h, inlineFile); DeleteFile(h, sFile); } } } /* * Revision History * [lah 03-Nov-88] Add -x option. * [JKF 8/24/89] Added -j option for tc. * [JKF March 5, 1990 12:45:50 pm PST] Rewrote to use system return codes. * [mna 24-Mar-91] * Massive changes made. Re-wrote large portions and added multiple * platform support */