summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/CLToolExec.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2022-10-19 21:16:13 +0100
committerAsh Wolf <ninji@wuffs.org>2022-10-19 21:16:13 +0100
commitd1f153d34b023d81768f6087f67dbfff714bafc9 (patch)
treea694d470a60655d0cda15a70791fbdb90a2398cf /command_line/CmdLine/Src/CLToolExec.c
parent775b6861666af36d317fb577cf489e2c6377f878 (diff)
downloadMWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.tar.gz
MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.zip
let's commit all this before my VM blows up and nukes my work
Diffstat (limited to '')
-rw-r--r--command_line/CmdLine/Src/CLToolExec.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/CLToolExec.c b/command_line/CmdLine/Src/CLToolExec.c
index e69de29..80e3a7c 100644
--- a/command_line/CmdLine/Src/CLToolExec.c
+++ b/command_line/CmdLine/Src/CLToolExec.c
@@ -0,0 +1,243 @@
+#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;
+ }
+
+#line 89
+ OPTION_ASSERT(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() {
+ 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() {
+ 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
+#line 269
+ OPTION_ASSERT(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;
+}