diff options
Diffstat (limited to '')
-rw-r--r-- | command_line/CmdLine/Src/CLToolExec.c | 243 |
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; +} |