MWCC/command_line/CmdLine/Src/CLToolExec.c

242 lines
7.9 KiB
C

#include "cmdline.h"
extern char STSbuf[256];
extern PCmdLine pCmdLine;
void AppendArgumentList(int *argc, char ***argv, const char *str) {
*argv = xrealloc("command-line arguments", *argv, sizeof(char *) * (*argc + 2));
(*argv)[(*argc)++] = xstrdup(str);
}
static int CopyArgumentList(int argc, char **argv, int *Argc, char ***Argv) {
int x;
int y;
y = Argc ? *Argc : 0;
*Argv = xrealloc("command-line arguments", *Argv, sizeof(char *) * (y + argc + 1));
if (argv) {
for (x = 0; x < argc; x++) {
(*Argv)[y++] = xstrdup(argv[x]);
}
}
(*Argv)[y] = NULL;
if (Argc)
*Argc = y;
return 1;
}
static int FreeArgumentList(char **argv) {
char **scan;
for (scan = argv; *scan; scan++)
xfree(*scan);
xfree(argv);
return 1;
}
static int SetupLinkerCommandLine(SInt32 dropinflags, File *file, CWCommandLineArgs *args) {
CWCommandLineArgs *baseargs;
int x;
SInt32 idx;
OSSpec spec;
for (x = 0; x < numPlugins; x++) {
if (pluginInfo[x].plugintype == CWDROPINLINKERTYPE && ((dropinflags & (isPostLinker | isPreLinker)) == (pluginInfo[x].dropinflags & (isPostLinker | isPreLinker))))
break;
}
OS_ASSERT(89, x < numPlugins);
args->argc = 1;
args->argv = xmalloc("command-line arguments", 2 * sizeof(char *));
Main_PassSpecialArgs(&args->argc, &args->argv);
baseargs = &plugin_args[x];
CopyArgumentList(baseargs->argc - 1, baseargs->argv + 1, &args->argc, &args->argv);
x = 0;
if (baseargs->envp) {
while (baseargs->envp[x])
x++;
}
args->envp = NULL;
CopyArgumentList(x, baseargs->envp, NULL, &args->envp);
if (!file && !(dropinflags & isPostLinker)) {
for (idx = 0; idx < Files_Count(&gTarg->files); idx++) {
file = Files_GetFile(&gTarg->files, idx);
if (file->sourceUsage & CmdLineStageMask_Cg) {
AppendArgumentList(&args->argc, &args->argv, file->srcfilename);
}
if (file->objectUsage & CmdLineStageMask_Cg) {
if (GetOutputFile(file, CmdLineStageMask_Cg) != 0 && StoreObjectFile(file))
AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf)));
else
return 0;
}
}
} else if (file) {
args->argv = xrealloc("command-line arguments", args->argv, sizeof(char *) * (args->argc + 1));
if (file->sourceUsage & CmdLineStageMask_Cg) {
AppendArgumentList(&args->argc, &args->argv, file->srcfilename);
}
if (file->objectUsage & CmdLineStageMask_Cg) {
if (GetOutputFile(file, CmdLineStageMask_Cg) != 0 && StoreObjectFile(file)) {
AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf)));
}
}
if ((pCmdLine.toDisk & CmdLineStageMask_Ds) && (file->objectUsage & CmdLineStageMask_Pp) && file->outfilename[0] && GetOutputFile(file, CmdLineStageMask_Ds)) {
AppendArgumentList(&args->argc, &args->argv, "-o");
AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf)));
}
} else if (dropinflags & isPostLinker) {
OS_FSSpec_To_OSSpec(&gTarg->targetinfo->outfile, &spec);
AppendArgumentList(&args->argc, &args->argv, OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)));
}
args->argv[args->argc] = NULL;
return 1;
}
int SetupTemporaries(void) {
SInt32 idx;
File *file;
for (idx = 0; idx < Files_Count(&gTarg->files); idx++) {
file = Files_GetFile(&gTarg->files, idx);
if ((file->objectUsage & CmdLineStageMask_Cg) && !(optsCmdLine.toDisk & CmdLineStageMask_Cg) && !(file->writeToDisk & CmdLineStageMask_Cg)) {
if (!optsCompiler.keepObjects)
file->tempOnDisk |= CmdLineStageMask_Cg;
else
file->writeToDisk |= CmdLineStageMask_Cg;
}
}
return 1;
}
int DeleteTemporaries(void) {
SInt32 idx;
File *file;
for (idx = 0; idx < Files_Count(&gTarg->files); idx++) {
file = Files_GetFile(&gTarg->files, idx);
if ((file->objectUsage & CmdLineStageMask_Cg) && (file->tempOnDisk & CmdLineStageMask_Cg) && (file->wroteToDisk & CmdLineStageMask_Cg)) {
GetOutputFile(file, CmdLineStageMask_Cg);
if (optsCmdLine.verbose > 1)
CLReport(19, OS_SpecToString(&file->outfss, STSbuf, sizeof(STSbuf)));
OS_Delete(&file->outfss);
file->tempOnDisk &= ~CmdLineStageMask_Cg;
file->wroteToDisk &= ~CmdLineStageMask_Cg;
}
}
return 1;
}
int ExecuteLinker(Plugin *plugin, SInt32 dropinflags, File *file, char *stdoutfile, char *stderrfile) {
char cname[64];
const char *linkername;
OSSpec linkerspec;
CWCommandLineArgs args;
int exitcode;
int execerr;
const char *linkertype;
int ret;
char *ptr;
char *ptr2;
int x;
// TODO rename this flag to isExecutableTool
OS_ASSERT(269, dropinflags & dropInExecutableTool);
args.argc = 0;
args.argv = args.envp = NULL;
if (dropinflags & isPreLinker)
linkertype = "pre-linker";
else if (dropinflags & isPostLinker)
linkertype = "post-linker";
else
linkertype = "linker";
linkername = Plugin_GetDropInName(plugin);
if (!(dropinflags & (isPreLinker | isPostLinker)) && optsCompiler.linkerName[0])
linkername = optsCompiler.linkerName;
if (OS_FindProgram(linkername, &linkerspec)) {
strcpy(cname, clState.programName);
for (ptr = cname; *ptr; ptr++)
*ptr = tolower(*ptr);
if ((ptr = strstr(cname, "cc")) || (ptr = strstr(cname, "pas")) || (ptr = strstr(cname, "asm"))) {
if (ptr[0] != 'c') {
memmove(ptr + 2, ptr + 3, strlen(ptr) - 3);
ptr[strlen(ptr) - 1] = 0;
}
ptr[0] = 'l';
ptr[1] = 'd';
} else {
if ((ptr = strstr(cname, "mwc"))) {
// this ptr2 seems redundant, but it's needed to generate the same code
ptr2 = ptr + 2;
memmove(ptr2 + 3, ptr2, strlen(ptr2));
memcpy(ptr + 2, "Link", 4);
}
}
if (!OS_FindProgram(cname, &linkerspec)) {
ptr = cname;
if (optsCompiler.linkerName[0]) {
CLReportWarning(66, linkertype, optsCompiler.linkerName);
CLReport(65, ptr, clState.programName);
} else if (optsCmdLine.verbose) {
CLReport(65, ptr, clState.programName);
}
} else {
CLReportError(66, linkertype, linkername);
return 0;
}
}
ret = 1;
SetupLinkerCommandLine(dropinflags, file, &args);
args.argv[0] = xstrdup(OS_SpecToString(&linkerspec, STSbuf, sizeof(STSbuf)));
args.argv[args.argc] = 0;
if (optsCmdLine.verbose || optsCmdLine.dryRun) {
CLPrint("\nCommand line:\n");
for (x = 0; x < args.argc && args.argv[x]; x++) {
if (strchr(args.argv[x], ' '))
CLPrint("\"%s\" ", args.argv[x]);
else
CLPrint("%s ", args.argv[x]);
}
CLPrint("\n\n");
}
fflush(stdout);
fflush(stderr);
if (optsCmdLine.verbose)
CLReport(67, linkertype, OS_SpecToString(&linkerspec, STSbuf, sizeof(STSbuf)));
if (!optsCmdLine.dryRun) {
execerr = OS_Execute(&linkerspec, args.argv, args.envp, stdoutfile, stderrfile, &exitcode);
if (execerr) {
CLReportError(68, linkertype, args.argv[0], OS_GetErrText(execerr));
ret = 0;
} else if (exitcode) {
CLReportError(69 /*nice*/, linkertype, args.argv[0], exitcode);
ret = 0;
}
}
FreeArgumentList(args.argv);
FreeArgumentList(args.envp);
return ret;
}