/*
* mimosa.c - front end for Mesa/Cedar compiler
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/dir.h>
#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
*/