mirror of https://git.wuffs.org/MWCC
290 lines
8.2 KiB
C
290 lines
8.2 KiB
C
|
#include "mwcc_decomp.h"
|
||
|
#include <errno.h>
|
||
|
|
||
|
// TODO: figure out who defines this
|
||
|
extern char STSbuf[256];
|
||
|
|
||
|
static Boolean setStage;
|
||
|
SInt16 outputOrdering;
|
||
|
Boolean setOutputDirectory;
|
||
|
Boolean setLinkerOutputFilename;
|
||
|
char linkerOutputFilename[256];
|
||
|
|
||
|
int Opt_HandleOutputName(const char *opt, void *, const char *filename) {
|
||
|
OSSpec spec;
|
||
|
int err;
|
||
|
SInt32 result;
|
||
|
Boolean isfile;
|
||
|
|
||
|
if (!filename)
|
||
|
filename = opt;
|
||
|
|
||
|
if ((pCmdLine.state == OptsCmdLineState_3 || (pCmdLine.state == OptsCmdLineState_0 && pTool->TYPE == CWDROPINLINKERTYPE)) && pCmdLine.toDisk != 4) {
|
||
|
if (setLinkerOutputFilename) {
|
||
|
CLPReportError(41, filename);
|
||
|
return 0;
|
||
|
}
|
||
|
setLinkerOutputFilename = 1;
|
||
|
if (pTool->TYPE == CWDROPINCOMPILERTYPE) {
|
||
|
strncpy(linkerOutputFilename, filename, 256);
|
||
|
} else {
|
||
|
OSSpec spec;
|
||
|
int err;
|
||
|
Boolean isfile;
|
||
|
err = OS_MakeSpec(filename, &spec, &isfile);
|
||
|
if (err) {
|
||
|
CLPOSAlert(64, err, filename);
|
||
|
return 0;
|
||
|
}
|
||
|
if (isfile)
|
||
|
OS_NameSpecToString(&spec.name, linkerOutputFilename, 256);
|
||
|
SetOutputFileDirectory(&spec.path);
|
||
|
}
|
||
|
return 1;
|
||
|
} else {
|
||
|
err = OS_MakeSpec(filename, &spec, &isfile);
|
||
|
if (err) {
|
||
|
CLPOSAlert(64, err, filename);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (!err && !isfile) {
|
||
|
FSSpec ofd;
|
||
|
if (setOutputDirectory) {
|
||
|
CLPReportError(59, filename);
|
||
|
return 0;
|
||
|
}
|
||
|
setOutputDirectory = 1;
|
||
|
|
||
|
OS_OSSpec_To_FSSpec(&spec, &ofd);
|
||
|
result = CWParserSetOutputFileDirectory(parseopts.context, &ofd);
|
||
|
if (result) {
|
||
|
failedCallback = "CWParserSetOutputFileDirectory";
|
||
|
longjmp(exit_plugin, result);
|
||
|
}
|
||
|
return 1;
|
||
|
} else {
|
||
|
SInt32 index;
|
||
|
CWProjectFileInfo pfi;
|
||
|
if (parseopts.lastoutputname[0]) {
|
||
|
CLPReportError(41, filename);
|
||
|
return 0;
|
||
|
}
|
||
|
strncpy(parseopts.lastoutputname, filename, 256);
|
||
|
if (pCmdLine.stages == CmdLineStageMask_Dp)
|
||
|
return 1;
|
||
|
|
||
|
if (outputOrdering == OutputOrdering0 || outputOrdering == OutputOrdering1) {
|
||
|
CWGetProjectFileCount(parseopts.context, &index);
|
||
|
while (index-- > 0) {
|
||
|
if (!CWGetFileInfo(parseopts.context, index, 0, &pfi) && pfi.filetype == CWFOURCHAR('T','E','X','T')) {
|
||
|
outputOrdering = OutputOrdering1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (index <= 0) {
|
||
|
CWGetProjectFileCount(parseopts.context, &index);
|
||
|
if (index > 0)
|
||
|
outputOrdering = OutputOrdering1;
|
||
|
--index;
|
||
|
}
|
||
|
|
||
|
if (outputOrdering == OutputOrdering0) {
|
||
|
outputOrdering = OutputOrdering2;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
SetFileOutputName(index, lastStage, parseopts.lastoutputname);
|
||
|
parseopts.lastoutputname[0] = 0;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int ValidateToolState(Boolean mustHaveFiles) {
|
||
|
if (parseopts.noOptions) {
|
||
|
pCmdLine.state = OptsCmdLineState_1;
|
||
|
ShowVersion(1);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (parseopts.success) {
|
||
|
if (!parseopts.userSpecifiedFiles) {
|
||
|
if (!parseopts.hadAnyOutput) {
|
||
|
if (mustHaveFiles) {
|
||
|
CLPReportError(70);
|
||
|
return 0;
|
||
|
}
|
||
|
} else {
|
||
|
if (mustHaveFiles)
|
||
|
pCmdLine.state = OptsCmdLineState_1;
|
||
|
return 1;
|
||
|
}
|
||
|
} else if (parseopts.unusedFiles > 0) {
|
||
|
CLPReportError(69);
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (pCmdLine.state == OptsCmdLineState_0 || (parseopts.userSpecifiedFiles > 0 && pCmdLine.state == OptsCmdLineState_1))
|
||
|
pCmdLine.state = OptsCmdLineState_3;
|
||
|
|
||
|
if (!setStage) {
|
||
|
pCmdLine.stages = CmdLineStageMask_Cg;
|
||
|
if (pCmdLine.state == OptsCmdLineState_2)
|
||
|
pCmdLine.toDisk |= 2;
|
||
|
}
|
||
|
|
||
|
if (pCmdLine.state == OptsCmdLineState_3 && !(pCmdLine.stages & CmdLineStageMask_Cg))
|
||
|
pCmdLine.state = OptsCmdLineState_2;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
void ToolReportMessage(SInt16 errid, SInt16 type, va_list va) {
|
||
|
char str[256];
|
||
|
char buf[1024];
|
||
|
|
||
|
GetIndString((StringPtr) str, 13000, errid);
|
||
|
p2cstr((StringPtr) str);
|
||
|
vsprintf(buf, str, va);
|
||
|
CWReportMessage(parseopts.context, 0, buf, 0, type, 0);
|
||
|
}
|
||
|
|
||
|
void ToolReportWarning(SInt16 id, ...) {
|
||
|
va_list va;
|
||
|
va_start(va, id);
|
||
|
ToolReportMessage(id, messagetypeWarning, va);
|
||
|
va_end(va);
|
||
|
}
|
||
|
|
||
|
void ToolReportError(SInt16 id, ...) {
|
||
|
va_list va;
|
||
|
va_start(va, id);
|
||
|
ToolReportMessage(id, messagetypeError, va);
|
||
|
va_end(va);
|
||
|
parseopts.hadErrors = 1;
|
||
|
}
|
||
|
|
||
|
void ToolReportOSError(SInt16 id, int err, ...) {
|
||
|
char str[256];
|
||
|
char buf[1024];
|
||
|
va_list va;
|
||
|
|
||
|
GetIndString((StringPtr) str, 13000, id);
|
||
|
p2cstr((StringPtr) str);
|
||
|
va_start(va, err);
|
||
|
vsprintf(buf, str, va);
|
||
|
va_end(va);
|
||
|
CWAlert(parseopts.context, buf, OS_GetErrText(err), 0, 0);
|
||
|
}
|
||
|
|
||
|
void ToolReportInfo(SInt16 id, ...) {
|
||
|
va_list va;
|
||
|
va_start(va, id);
|
||
|
ToolReportMessage(id, messagetypeInfo, va);
|
||
|
va_end(va);
|
||
|
}
|
||
|
|
||
|
int Opt_DoNotLink(const char *opt, void *var, const char *arg) {
|
||
|
if (pCmdLine.state == OptsCmdLineState_3 || pCmdLine.state == OptsCmdLineState_0 || pCmdLine.state == OptsCmdLineState_1)
|
||
|
pCmdLine.state = OptsCmdLineState_2;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int Opt_IncreaseVerbosity(const char *opt, void *var, const char *arg) {
|
||
|
if (pCmdLine.verbose)
|
||
|
pCmdLine.verbose++;
|
||
|
else
|
||
|
pCmdLine.verbose = 2;
|
||
|
|
||
|
Parser_StorePanels(parseopts.context);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int Opt_SetStage(const char *opt, void *str, const char *arg, int flags) {
|
||
|
unsigned char *ptr;
|
||
|
Boolean set;
|
||
|
Boolean no;
|
||
|
UInt16 flag;
|
||
|
|
||
|
ptr = (unsigned char *) str;
|
||
|
// doesn't match - type issue with 'no'
|
||
|
no = (Boolean) ((flags & PARAMPARSEFLAGS_8) >> 3);
|
||
|
set = (Boolean) (no ^ 1);
|
||
|
|
||
|
while (*ptr) {
|
||
|
if (*ptr == '+') {
|
||
|
set = !no;
|
||
|
} else if (*ptr == '-') {
|
||
|
set = no;
|
||
|
} else if (*ptr == '|') {
|
||
|
set = (Boolean) (no ^ 1);
|
||
|
} else {
|
||
|
flag = (ptr[0] << 8) | ptr[1];
|
||
|
setStage = 1;
|
||
|
|
||
|
switch (flag) {
|
||
|
case 'Cg':
|
||
|
if (set)
|
||
|
pCmdLine.stages |= CmdLineStageMask_Cg;
|
||
|
else
|
||
|
pCmdLine.stages &= ~CmdLineStageMask_Cg;
|
||
|
lastStage = CmdLineStage_Cg;
|
||
|
break;
|
||
|
case 'Ds':
|
||
|
if (set)
|
||
|
pCmdLine.stages |= CmdLineStageMask_Ds;
|
||
|
else
|
||
|
pCmdLine.stages &= ~CmdLineStageMask_Ds;
|
||
|
lastStage = CmdLineStage_Ds;
|
||
|
break;
|
||
|
case 'Pp':
|
||
|
if (set)
|
||
|
pCmdLine.stages |= CmdLineStageMask_Pp;
|
||
|
else
|
||
|
pCmdLine.stages &= ~CmdLineStageMask_Pp;
|
||
|
lastStage = CmdLineStage_Pp;
|
||
|
break;
|
||
|
case 'Dp':
|
||
|
if (set)
|
||
|
pCmdLine.stages |= CmdLineStageMask_Dp;
|
||
|
else
|
||
|
pCmdLine.stages &= ~CmdLineStageMask_Dp;
|
||
|
break;
|
||
|
default:
|
||
|
CLPFatalError("Bad stage settings in %s (%c%c)\n", str, ptr[0], ptr[1]);
|
||
|
}
|
||
|
|
||
|
++ptr;
|
||
|
}
|
||
|
|
||
|
++ptr;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int Opt_RedirectStream(const char *opt, void *file, const char *filename) {
|
||
|
OSSpec spec;
|
||
|
int err;
|
||
|
FILE *nw;
|
||
|
|
||
|
err = OS_MakeFileSpec(filename, &spec);
|
||
|
if (err) {
|
||
|
CLPReportError(78, filename, OS_GetErrText(err));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
nw = freopen(OS_SpecToString(&spec, STSbuf, 256), "wt", (FILE *) file);
|
||
|
if (!nw) {
|
||
|
CLPReportError(78, filename, strerror(errno));
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|