summaryrefslogtreecommitdiff
path: root/command_line/CmdLine/Src/Plugins/CLPlugins.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/Plugins/CLPlugins.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/Plugins/CLPlugins.c981
1 files changed, 981 insertions, 0 deletions
diff --git a/command_line/CmdLine/Src/Plugins/CLPlugins.c b/command_line/CmdLine/Src/Plugins/CLPlugins.c
index e69de29..5f31f45 100644
--- a/command_line/CmdLine/Src/Plugins/CLPlugins.c
+++ b/command_line/CmdLine/Src/Plugins/CLPlugins.c
@@ -0,0 +1,981 @@
+#include "cmdline.h"
+
+static Plugin *pluginlist;
+static ToolVersionInfo toolVersionInfo;
+static VersionInfo toolVersion;
+static Boolean useToolVersion;
+
+static void GetToolVersionInfo() {
+ useToolVersion = 0;
+}
+
+const ToolVersionInfo *Plugin_GetToolVersionInfo() {
+ return useToolVersion ? &toolVersionInfo : 0;
+}
+
+static const char *Plugin_GetDisplayName(Plugin *pl) {
+ const char *name;
+#line 251
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetDisplayName && pl->cb->GetDisplayName(&name) == 0)
+ return name;
+ else
+ return "(no name found)";
+}
+
+const char *Plugin_GetDropInName(Plugin *pl) {
+ const char *name;
+#line 263
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetDropInName && pl->cb->GetDropInName(&name) == 0)
+ return name;
+ else
+ return "(no name found)";
+}
+
+const VersionInfo *Plugin_GetVersionInfo(Plugin *pl) {
+ static const VersionInfo fakeversion = {0, 0, 0, 0};
+ const VersionInfo *vi;
+#line 276
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetVersionInfo && pl->cb->GetVersionInfo(&vi) == 0)
+ return vi;
+ else
+ return &fakeversion;
+}
+
+char *Plugin_GetVersionInfoASCII(Plugin *pl) {
+ const VersionInfo *vi;
+ char *buffer;
+ char vernum[16];
+ char *bptr;
+
+ if (!pl && useToolVersion) {
+ vi = &toolVersion;
+ } else if (!pl) {
+ return NULL;
+ } else {
+ vi = Plugin_GetVersionInfo(pl);
+ }
+
+ buffer = xmalloc("version info", 64);
+ if (vi->major | vi->minor | vi->patch | vi->build != 0) {
+ bptr = vernum;
+ bptr += sprintf(bptr, "%u", vi->major);
+ bptr += sprintf(bptr, ".%u", vi->minor);
+ if (vi->patch)
+ bptr += sprintf(bptr, ".%u", vi->patch);
+ if (vi->build)
+ bptr += sprintf(bptr, " build %u", vi->build);
+ sprintf(buffer, "Version %s", vernum);
+ return buffer;
+ } else {
+ return NULL;
+ }
+}
+
+DropInFlags *Plugin_GetDropInFlags(Plugin *pl) {
+ static DropInFlags retdf;
+ const DropInFlags *df;
+ SInt32 dfsize;
+
+#line 329
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetDropInFlags && pl->cb->GetDropInFlags(&df, &dfsize) == 0) {
+ memset(&retdf, 0, sizeof(retdf));
+ memcpy(&retdf, df, dfsize);
+ return &retdf;
+ } else {
+ return NULL;
+ }
+}
+
+OSType Plugin_GetPluginType(Plugin *pl) {
+ DropInFlags *df;
+
+#line 345
+ OPTION_ASSERT(pl);
+
+ df = Plugin_GetDropInFlags(pl);
+ if (df)
+ return df->dropintype;
+ else
+ return CWFOURCHAR('N','O','N','E');
+}
+
+const CWTargetList *Plugin_CL_GetTargetList(Plugin *pl) {
+ static const CWTargetList faketl = {
+ kCurrentCWTargetListVersion,
+ 0, NULL,
+ 0, NULL
+ };
+ const CWTargetList *tl;
+
+#line 358
+ OPTION_ASSERT(pl);
+ OPTION_ASSERT(pl->cl_cb != NULL);
+
+ if (pl->cl_cb->GetTargetList && pl->cl_cb->GetTargetList(&tl) == 0)
+ return tl;
+ else
+ return &faketl;
+}
+
+const CWPanelList *Plugin_GetPanelList(Plugin *pl) {
+ static CWPanelList fakepnl = {
+ kCurrentCWPanelListVersion, 0, NULL
+ };
+ const CWPanelList *pnl;
+
+#line 381
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetPanelList && pl->cb->GetPanelList(&pnl) == 0)
+ return pnl;
+ else
+ return &fakepnl;
+}
+
+const CWExtMapList *Plugin_CL_GetExtMapList(Plugin *pl) {
+ static CWExtMapList fakeel = {
+ kCurrentCWExtMapListVersion,
+ 0, NULL
+ };
+ const CWExtMapList *el;
+
+#line 401
+ OPTION_ASSERT(pl);
+ OPTION_ASSERT(pl->cl_cb != NULL);
+
+ if (pl->cl_cb->GetDefaultMappingList && pl->cl_cb->GetDefaultMappingList(&el) == 0)
+ return el;
+ else
+ return &fakeel;
+}
+
+const OSFileTypeMappingList *Plugin_GetFileTypeMappingList(Plugin *pl) {
+ const OSFileTypeMappingList *ftml;
+
+#line 422
+ OPTION_ASSERT(pl);
+
+ if (pl->cb->GetFileTypeMappings && pl->cb->GetFileTypeMappings(&ftml) == 0)
+ return ftml;
+ else
+ return NULL;
+}
+
+const CWObjectFlags *Plugin_CL_GetObjectFlags(Plugin *pl) {
+ static CWObjectFlags fake = {
+ 2, 0,
+ "", "", "", "", "", "",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ const CWObjectFlags *cof;
+
+#line 434
+ OPTION_ASSERT(pl);
+ OPTION_ASSERT(pl->cl_cb != NULL);
+
+ if (pl->cl_cb->GetObjectFlags && pl->cl_cb->GetObjectFlags(&cof) == 0)
+ return cof;
+ else if (Plugin_GetDropInFlags(pl)->dropintype == CWDROPINCOMPILERTYPE)
+ return NULL;
+ else
+ return &fake;
+}
+
+Boolean Plugin_MatchesName(Plugin *pl, const char *name) {
+ const char *pname = Plugin_GetDropInName(pl);
+ return !strcmp(pname, name);
+}
+
+Boolean Plugin_CL_MatchesTarget(Plugin *pl, OSType cpu, OSType os, Boolean exact) {
+ const CWTargetList *tl;
+ int idx;
+ int ix;
+
+ tl = Plugin_CL_GetTargetList(pl);
+
+ for (idx = 0; idx < tl->cpuCount; idx++) {
+ if (cpu == targetCPUAny || cpu == tl->cpus[idx] || (tl->cpus[idx] == targetCPUAny && !exact)) {
+ for (ix = 0; ix < tl->osCount; ix++) {
+ if (os == targetOSAny || os == tl->oss[ix] || (tl->oss[ix] == targetOSAny && !exact))
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+Boolean Plugins_CL_HaveMatchingTargets(Plugin *p1, Plugin *p2, Boolean exact) {
+ // does not match, annoyingly
+ const CWTargetList *t1;
+ const CWTargetList *t2;
+ int ic1;
+ int ic2;
+ int io1;
+ int io2;
+
+ t1 = Plugin_CL_GetTargetList(p1);
+ t2 = Plugin_CL_GetTargetList(p2);
+
+ for (ic1 = 0; ic1 < t1->cpuCount; ic1++) {
+ for (ic2 = 0; ic2 < t2->cpuCount; ic2++) {
+ if ((t2->cpus[ic2] == targetCPUAny && !exact) || (t1->cpus[ic1] == t2->cpus[ic2]) || (t1->cpus[ic1] == targetCPUAny && !exact)) {
+ for (io1 = 0; io1 < t1->osCount; io1++) {
+ for (io2 = 0; io2 < t2->osCount; io2++) {
+ if ((t2->oss[io2] == targetOSAny && !exact) || (t1->oss[io1] == t2->oss[io2]) || (t1->oss[io1] == targetOSAny && !exact)) {
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static Boolean CL_MatchesExtMapping(CWExtensionMapping *map, OSType type, const char *ext, Boolean exact) {
+ if (exact && type && map->type && type == map->type)
+ return 1;
+
+ if (
+ (((!map->extension[0] && !exact) || (!ext[0] && !exact)) && map->type == type)
+ ||
+ (((!map->type && !exact) || (!type && !exact)) && !ustrcmp(map->extension, ext))
+ ||
+ (!ustrcmp(map->extension, ext) && map->type == type)
+ ) {
+ return 1;
+ }
+
+ return 0;
+}
+
+Boolean Plugin_CL_MatchesFileType(Plugin *pl, OSType type, const char *extension, Boolean exact) {
+ const CWExtMapList *el;
+ int idx;
+
+ el = Plugin_CL_GetExtMapList(pl);
+
+ for (idx = 0; idx < el->nMappings; idx++) {
+ if (CL_MatchesExtMapping(&el->mappings[idx], type, extension, exact))
+ return 1;
+ }
+
+ return 0;
+}
+
+Boolean Plugin_MatchesType(Plugin *pl, OSType type, OSType lang, Boolean exact) {
+ const DropInFlags *df;
+
+ df = Plugin_GetDropInFlags(pl);
+ if (df->dropintype == type || type == CWDROPINANYTYPE) {
+ if (df->edit_language == lang || lang == Lang_Any || (df->edit_language == Lang_Any && !exact))
+ return 1;
+ }
+
+ return 0;
+}
+
+Boolean Plugin_Pr_MatchesPlugin(Plugin *pl, CLPluginInfo *pluginfo, OSType cpu, OSType os) {
+ Boolean isSupported;
+
+#line 566
+ OPTION_ASSERT(pl->pr_cb != NULL);
+
+ if (pl->pr_cb->SupportsPlugin && pl->pr_cb->SupportsPlugin(pluginfo, cpu, os, &isSupported) == 0)
+ return isSupported;
+ else
+ return 0;
+}
+
+Boolean Plugin_Pr_MatchesPanels(Plugin *pl, int numPanels, const char **panelNames) {
+ Boolean isSupported;
+
+#line 578
+ OPTION_ASSERT(pl->pr_cb != NULL);
+
+ if (pl->pr_cb->SupportsPanels && pl->pr_cb->SupportsPanels(numPanels, panelNames, &isSupported) == 0)
+ return isSupported;
+ else
+ return 0;
+}
+
+Boolean Plugin_CL_WriteObjectFile(Plugin *pl, FSSpec *srcfss, FSSpec *outfss, OSType creator, OSType type, Handle data) {
+ OSSpec outoss;
+
+#line 590
+ OPTION_ASSERT(pl->cl_cb != NULL);
+ OPTION_ASSERT(data != NULL && srcfss != NULL && outfss != NULL);
+
+ if (pl->cl_cb->WriteObjectFile) {
+ return pl->cl_cb->WriteObjectFile(srcfss, outfss, creator, type, data) == 0;
+ }
+
+ OS_FSSpec_To_OSSpec(outfss, &outoss);
+ return WriteBinaryHandleToFile(&outoss, creator, type, OS_PeekMacHandle(data));
+}
+
+Boolean Plugin_CL_GetCompilerMapping(Plugin *pl, OSType type, const char *ext, UInt32 *flags) {
+ const CWExtMapList *el;
+ int idx;
+ int pick;
+
+ el = Plugin_CL_GetExtMapList(pl);
+ pick = -1;
+ for (idx = 0; idx < el->nMappings; idx++) {
+ if (CL_MatchesExtMapping(&el->mappings[idx], type, ext, 0)) {
+ pick = idx;
+ if (CL_MatchesExtMapping(&el->mappings[idx], type, ext, 1))
+ break;
+ }
+ }
+
+ if (pick < 0) {
+ *flags = 0;
+ return 0;
+ } else {
+ *flags = el->mappings[pick].flags;
+ return 1;
+ }
+}
+
+static Boolean SupportedPlugin(Plugin *pl, const char **reason) {
+ static const SInt32 DropInFlagsSize[3] = {0, 0x10, 0x12};
+ const DropInFlags *df;
+ const CWObjectFlags *cof;
+ SInt32 dfsize;
+
+ *reason = "";
+ if (pl->cb->GetDropInFlags == NULL) {
+ *reason = "GetDropInFlags callback not found";
+ return 0;
+ }
+ if (pl->cb->GetDropInFlags(&df, &dfsize)) {
+ *reason = "GetDropInFlags callback failed";
+ return 0;
+ }
+ if (df->dropintype != CWDROPINCOMPILERTYPE && df->dropintype != CWDROPINLINKERTYPE && df->dropintype != CWDROPINPARSERTYPE && df->dropintype != CWDROPINDRIVERTYPE) {
+ *reason = "The plugin type is not supported by this driver";
+ return 0;
+ }
+ if (df->earliestCompatibleAPIVersion > 11) {
+ *reason = "The plugin's earliest compatible API version is too new for this driver";
+ return 0;
+ }
+ if (df->earliestCompatibleAPIVersion > 1 && df->newestAPIVersion < 11 && clState.pluginDebug) {
+ CLPrintErr("%s's newest compatible API version is probably too old for this driver\n", Plugin_GetDropInName(pl));
+ }
+ if (dfsize != DropInFlagsSize[df->rsrcversion]) {
+ *reason = "The plugin's DropInFlags has an unexpected size";
+ return 0;
+ }
+ if (!(df->dropinflags & dropInExecutableTool) && !pl->cb->main) {
+ *reason = "The plugin has no entry point";
+ return 0;
+ }
+ if ((df->dropinflags & dropInExecutableTool) && pl->cb->main) {
+ *reason = "The executable tool stub has an entry point";
+ return 0;
+ }
+
+ if (pl->cl_cb) {
+ if (pl->cl_cb->GetObjectFlags == NULL && df->dropintype == CWDROPINCOMPILERTYPE) {
+ *reason = "GetObjectFlags callback not found in compiler plugin";
+ return 0;
+ }
+
+ cof = Plugin_CL_GetObjectFlags(pl);
+ if (cof->version < 2 || cof->flags & 0x7FFFFFFF) {
+ *reason = "The object flags data is out-of-date or invalid";
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static Boolean VerifyPanels(Plugin *pl) {
+ const CWPanelList *pls;
+ Boolean failed;
+ int idx;
+
+ failed = 0;
+
+ if (pl->cb->GetPanelList && pl->cb->GetPanelList(&pls) == 0) {
+ for (idx = 0; idx < pls->count; idx++) {
+ if (Prefs_FindPanel(pls->names[idx]) == NULL) {
+ CLReportError(91, pls->names[idx]);
+ failed = 1;
+ }
+ }
+ }
+
+ return !failed;
+}
+
+Plugin *Plugin_New(const BasePluginCallbacks *cb, const CompilerLinkerPluginCallbacks *cl_cb, const ParserPluginCallbacks *pr_cb) {
+ Plugin *p;
+
+ p = xmalloc(NULL, sizeof(Plugin));
+ if (!p)
+ return NULL;
+ if (!cb)
+ return NULL;
+
+ p->cb = xmalloc(NULL, sizeof(BasePluginCallbacks));
+ if (!p->cb)
+ return NULL;
+ *p->cb = *cb;
+
+ if (cl_cb) {
+ p->cl_cb = xmalloc(NULL, sizeof(CompilerLinkerPluginCallbacks));
+ if (!p->cl_cb)
+ return NULL;
+ *p->cl_cb = *cl_cb;
+ } else {
+ p->cl_cb = NULL;
+ }
+
+ if (pr_cb) {
+ p->pr_cb = xmalloc(NULL, sizeof(ParserPluginCallbacks));
+ if (!p->pr_cb)
+ return NULL;
+ *p->pr_cb = *pr_cb;
+ } else {
+ p->pr_cb = NULL;
+ }
+
+ p->context = NULL;
+ p->next = NULL;
+ return p;
+}
+
+void Plugin_Free(Plugin *pl) {
+ if (pl) {
+ if (pl->cb)
+ xfree(pl->cb);
+ if (pl->cl_cb)
+ xfree(pl->cl_cb);
+ if (pl->pr_cb)
+ xfree(pl->pr_cb);
+ xfree(pl);
+ }
+}
+
+Boolean Plugin_VerifyPanels(Plugin *pl) {
+ if (!VerifyPanels(pl)) {
+ CLReportError(92, Plugin_GetDropInName(pl));
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+void Plugins_Init() {
+ pluginlist = NULL;
+ GetToolVersionInfo();
+}
+
+void Plugins_Term() {
+ Plugin *scan;
+ Plugin *next;
+
+ scan = pluginlist;
+ while (scan) {
+ next = scan->next;
+ SendInitOrTermRequest(scan, 0);
+ Plugin_Free(scan);
+ scan = next;
+ }
+
+ if (toolVersionInfo.company)
+ xfree(toolVersionInfo.company);
+ if (toolVersionInfo.product)
+ xfree(toolVersionInfo.product);
+ if (toolVersionInfo.tool)
+ xfree(toolVersionInfo.tool);
+ if (toolVersionInfo.copyright)
+ xfree(toolVersionInfo.copyright);
+ if (toolVersionInfo.version)
+ xfree(toolVersionInfo.version);
+}
+
+int Plugins_Add(Plugin *pl) {
+ Plugin **scan;
+ const char *dropinname;
+ const DropInFlags *df;
+ const CWTargetList *tl;
+ const CWExtMapList *el;
+ const CWPanelList *pnl;
+ const char *failreason;
+ CWDataType vislang;
+ SInt16 step;
+
+ dropinname = Plugin_GetDropInName(pl);
+ pl->cached_ascii_version = Plugin_GetVersionInfoASCII(pl);
+
+ if (!SupportedPlugin(pl, &failreason)) {
+ CLReportError(88, dropinname, pl->cached_ascii_version, failreason);
+ return 0;
+ }
+
+ scan = &pluginlist;
+ while (*scan) {
+ if (Plugin_MatchesName(*scan, dropinname)) {
+ CLReportError(89, dropinname);
+ return 0;
+ }
+ scan = &(*scan)->next;
+ }
+
+ *scan = pl;
+
+ df = Plugin_GetDropInFlags(pl);
+ if (!(df->dropinflags & dropInExecutableTool) && !SendInitOrTermRequest(pl, 1)) {
+ CLReportError(3, dropinname);
+ return 0;
+ }
+
+ if (df->dropintype == CWDROPINCOMPILERTYPE && df->dropinflags & 0x17C000)
+ CLReportError(4, "compiler", dropinname);
+ if (df->dropintype == CWDROPINLINKERTYPE && df->dropinflags & 0x5FE4000)
+ CLReportError(4, "linker", dropinname);
+
+ if (clState.pluginDebug) {
+ vislang = df->edit_language ? df->edit_language : CWFOURCHAR('-','-','-','-');
+ CLPrint("Added plugin '%s', version '%s'\n", dropinname, pl->cached_ascii_version);
+ CLPrint("Type: '%c%c%c%c'; Lang: '%c%c%c%c'; API range: %d-%d\n",
+ (df->dropintype & 0xFF000000) >> 24,
+ (df->dropintype & 0x00FF0000) >> 16,
+ (df->dropintype & 0x0000FF00) >> 8,
+ (df->dropintype & 0x000000FF),
+ (vislang & 0xFF000000) >> 24,
+ (vislang & 0x00FF0000) >> 16,
+ (vislang & 0x0000FF00) >> 8,
+ (vislang & 0x000000FF),
+ df->earliestCompatibleAPIVersion,
+ df->newestAPIVersion
+ );
+
+ if (pl->cl_cb) {
+ tl = Plugin_CL_GetTargetList(pl);
+ CLPrint("Target CPUs: ");
+ for (step = 0; step < tl->cpuCount; step++) {
+ CLPrint("'%c%c%c%c', ",
+ (tl->cpus[step] & 0xFF000000) >> 24,
+ (tl->cpus[step] & 0x00FF0000) >> 16,
+ (tl->cpus[step] & 0x0000FF00) >> 8,
+ (tl->cpus[step] & 0x000000FF)
+ );
+ }
+ CLPrint("\nTarget OSes: ");
+ for (step = 0; step < tl->osCount; step++) {
+ CLPrint("'%c%c%c%c', ",
+ (tl->oss[step] & 0xFF000000) >> 24,
+ (tl->oss[step] & 0x00FF0000) >> 16,
+ (tl->oss[step] & 0x0000FF00) >> 8,
+ (tl->oss[step] & 0x000000FF)
+ );
+ }
+ CLPrint("\n");
+
+ el = Plugin_CL_GetExtMapList(pl);
+ CLPrint("File mappings:\n");
+ for (step = 0; step < el->nMappings; step++) {
+ if (el->mappings[step].type) {
+ CLPrint("\tFile type: '%c%c%c%c' Extension: '%s'\n",
+ (el->mappings[step].type & 0xFF000000) >> 24,
+ (el->mappings[step].type & 0x00FF0000) >> 16,
+ (el->mappings[step].type & 0x0000FF00) >> 8,
+ (el->mappings[step].type & 0x000000FF),
+ el->mappings[step].extension
+ );
+ } else {
+ CLPrint("\tFile type: <none> Extension: '%s'\n",
+ el->mappings[step].extension
+ );
+ }
+ }
+ }
+
+ pnl = Plugin_GetPanelList(pl);
+ CLPrint("Pref panels needed:\n");
+ for (step = 0; step < pnl->count; step++) {
+ CLPrint("\t'%s'\n", pnl->names[step]);
+ }
+
+ CLPrint("Dropin flags:\n");
+ if (df->dropinflags & dropInExecutableTool) CLPrint("\texecutable tool,\n");
+ if (df->dropintype == CWDROPINCOMPILERTYPE) {
+ if (df->dropinflags & kGeneratescode) CLPrint("\tgenerates code,\n");
+ if (df->dropinflags & kGeneratesrsrcs) CLPrint("\tgenerates resources, \n");
+ if (df->dropinflags & kCanpreprocess) CLPrint("\tcan preprocess, \n");
+ if (df->dropinflags & kCanprecompile) CLPrint("\tcan precompile, \n");
+ if (df->dropinflags & kIspascal) CLPrint("\tis Pascal, \n");
+ if (df->dropinflags & kCanimport) CLPrint("\tcan import, \n");
+ if (df->dropinflags & kCandisassemble) CLPrint("\tcan disassemble, \n");
+ if (df->dropinflags & kCompAllowDupFileNames) CLPrint("\tallow duplicate filenames, \n");
+ if (df->dropinflags & kCompMultiTargAware) CLPrint("\tallow multiple targets, \n");
+ if (df->dropinflags & kCompUsesTargetStorage) CLPrint("\tuses target storage, \n");
+ if (df->dropinflags & kCompEmitsOwnBrSymbols) CLPrint("\temits own browser symbols, \n");
+ if (df->dropinflags & kCompAlwaysReload) CLPrint("\tshould be always reloaded, \n");
+ if (df->dropinflags & kCompRequiresProjectBuildStartedMsg) CLPrint("\trequires project build started msg, \n");
+ if (df->dropinflags & kCompRequiresTargetBuildStartedMsg) CLPrint("\trequires target build started msg, \n");
+ if (df->dropinflags & kCompRequiresSubProjectBuildStartedMsg) CLPrint("\trequires subproject build started msg, \n");
+ if (df->dropinflags & kCompRequiresFileListBuildStartedMsg) CLPrint("\trequires file list build started msg, \n");
+ }
+
+ if (df->dropintype == CWDROPINLINKERTYPE) {
+ if (df->dropinflags & cantDisassemble) CLPrint("\tcan't disassemble, \n");
+ if (df->dropinflags & isPostLinker) CLPrint("\tis a post-linker, \n");
+ if (df->dropinflags & linkAllowDupFileNames) CLPrint("\tallow duplicate filenames, \n");
+ if (df->dropinflags & linkMultiTargAware) CLPrint("\tallow multiple targets, \n");
+ if (df->dropinflags & isPreLinker) CLPrint("\tis a pre-linker, \n");
+ if (df->dropinflags & linkerUsesTargetStorage) CLPrint("\tuses target storage, \n");
+ if (df->dropinflags & linkerUnmangles) CLPrint("\tsupports unmangling, \n");
+ if (df->dropinflags & magicCapLinker) CLPrint("\tis Magic Cap linker, \n");
+ if (df->dropinflags & linkAlwaysReload) CLPrint("\tshould be always reloaded, \n");
+ if (df->dropinflags & linkRequiresProjectBuildStartedMsg) CLPrint("\trequires project build started msg, \n");
+ if (df->dropinflags & linkRequiresTargetBuildStartedMsg) CLPrint("\trequires target build started msg, \n");
+ if (df->dropinflags & linkRequiresSubProjectBuildStartedMsg) CLPrint("\trequires subproject build started msg, \n");
+ if (df->dropinflags & linkRequiresFileListBuildStartedMsg) CLPrint("\trequires file list build started msg, \n");
+ if (df->dropinflags & linkRequiresTargetLinkStartedMsg) CLPrint("\trequires target link started msg, \n");
+ if (df->dropinflags & linkerWantsPreRunRequest) CLPrint("\twants pre-run request, \n");
+ }
+
+ CLPrint("\n");
+ }
+
+ return 1;
+}
+
+Plugin *Plugins_MatchName(Plugin *list, const char *name) {
+ Plugin *scan;
+
+ scan = list ? list : pluginlist;
+ while (scan) {
+ if (Plugin_MatchesName(scan, name))
+ break;
+ scan = scan->next;
+ }
+
+ return scan;
+}
+
+Plugin *Plugins_CL_MatchTarget(Plugin *list, OSType cpu, OSType os, OSType type, OSType lang) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ while (scan) {
+ if (scan->cl_cb) {
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 0) && Plugin_MatchesType(scan, type, lang, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 1) && Plugin_MatchesType(scan, type, lang, 1))
+ break;
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_CL_MatchFileType(Plugin *list, OSType type, const char *ext, Boolean exact) {
+ Plugin *scan;
+
+ scan = list ? list : pluginlist;
+ while (scan) {
+ if (Plugin_CL_MatchesFileType(scan, type, ext, exact))
+ break;
+ scan = scan->next;
+ }
+
+ return scan;
+}
+
+Plugin *Plugins_GetPluginForFile(Plugin *list, OSType plugintype, OSType cpu, OSType os, OSType type, const char *ext, OSType lang) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ while (scan) {
+ if (Plugin_MatchesType(scan, plugintype, lang, 1) && scan->cl_cb) {
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 0) && Plugin_CL_MatchesFileType(scan, type, ext, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 1) && Plugin_CL_MatchesFileType(scan, type, ext, 1))
+ break;
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_GetLinker(Plugin *list, OSType cpu, OSType os) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ while (scan) {
+ if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) {
+ if (!(Plugin_GetDropInFlags(scan)->dropinflags & (isPreLinker | isPostLinker))) {
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 1))
+ break;
+ }
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_GetPreLinker(Plugin *list, OSType cpu, OSType os) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ while (scan) {
+ if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) {
+ if (Plugin_GetDropInFlags(scan)->dropinflags & isPreLinker) {
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 1))
+ break;
+ }
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_GetPostLinker(Plugin *list, OSType cpu, OSType os) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ while (scan) {
+ if (Plugin_MatchesType(scan, CWDROPINLINKERTYPE, Lang_Any, 1)) {
+ if (Plugin_GetDropInFlags(scan)->dropinflags & isPostLinker) {
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesTarget(scan, cpu, os, 1))
+ break;
+ }
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_GetParserForPlugin(Plugin *list, OSType style, int numPlugins, CLPluginInfo *plugins, OSType cpu, OSType os, int numPanels, const char **panelNames) {
+ Plugin *scan;
+ Plugin *pick;
+ Boolean allpanels;
+ Boolean hasplugintype;
+ Boolean *supports;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+ supports = alloca(numPanels);
+
+ while (scan) {
+ if (Plugin_MatchesType(scan, CWDROPINPARSERTYPE, style, 1)) {
+ int idx;
+ int pnl;
+ hasplugintype = 0;
+ for (idx = 0; idx < numPlugins; idx++) {
+ if (plugins[idx].plugintype != CWDROPINPARSERTYPE && plugins[idx].plugintype != CWDROPINDRIVERTYPE && !plugins[idx].storeCommandLine) {
+ if (Plugin_Pr_MatchesPlugin(scan, &plugins[idx], cpu, os))
+ hasplugintype = 1;
+ }
+ }
+
+ if (hasplugintype) {
+ pick = scan;
+ allpanels = 1;
+ for (pnl = 0; pnl < numPanels; pnl++) {
+ allpanels &= (supports[pnl] = Plugin_Pr_MatchesPanels(scan, 1, &panelNames[pnl]));
+ }
+
+ if (allpanels)
+ break;
+ }
+ }
+ scan = scan->next;
+ }
+
+ if (pick && !allpanels) {
+ int idx;
+ CLReport(5);
+
+ for (idx = 0; idx < numPanels; idx++) {
+ if (!supports[idx])
+ CLReport(6, panelNames[idx]);
+ }
+ }
+
+ return pick;
+}
+
+Plugin *Plugins_GetCompilerForLinker(Plugin *list, Plugin *linker, OSType type, const char *ext, OSType edit) {
+ Plugin *scan;
+ Plugin *pick;
+
+ scan = list ? list : pluginlist;
+ pick = NULL;
+
+ while (scan) {
+ if (Plugin_MatchesType(scan, CWDROPINCOMPILERTYPE, edit, 1)) {
+ if (Plugin_CL_MatchesFileType(scan, type, ext, 0) && Plugins_CL_HaveMatchingTargets(scan, linker, 0)) {
+ pick = scan;
+ if (Plugin_CL_MatchesFileType(scan, type, ext, 1) && Plugins_CL_HaveMatchingTargets(scan, linker, 1))
+ break;
+ }
+ }
+ scan = scan->next;
+ }
+
+ return pick;
+}
+
+int Plugins_GetPluginList(Plugin *list, int *numPlugins, CLPluginInfo **pluginInfo) {
+ Plugin *scan;
+ int idx;
+ const DropInFlags *df;
+ const VersionInfo *vi;
+
+ scan = list ? list : pluginlist;
+ idx = 0;
+ while (scan) {
+ scan = scan->next;
+ idx++;
+ }
+
+ *numPlugins = idx;
+ *pluginInfo = xmalloc(NULL, sizeof(CLPluginInfo) * idx);
+ if (!*pluginInfo)
+ return 0;
+
+ scan = list ? list : pluginlist;
+ idx = 0;
+ while (scan) {
+ df = Plugin_GetDropInFlags(scan);
+ vi = Plugin_GetVersionInfo(scan);
+#line 1270
+ OPTION_ASSERT(df != NULL);
+ OPTION_ASSERT(vi != NULL);
+ (*pluginInfo)[idx].plugintype = df->dropintype;
+ (*pluginInfo)[idx].language = df->edit_language;
+ (*pluginInfo)[idx].dropinflags = df->dropinflags;
+ (*pluginInfo)[idx].version = scan->cached_ascii_version;
+ (*pluginInfo)[idx].storeCommandLine = df->dropinflags & 1;
+ scan = scan->next;
+ idx++;
+ }
+
+ return 1;
+}
+
+int Plugins_GetPrefPanelUnion(Plugin *list, int *numPanels, const char ***panelNames) {
+ Plugin *scan;
+ int tempNum;
+ int idx;
+ const char **tempPanels;
+
+ scan = list ? list : pluginlist;
+
+ tempNum = 0;
+ while (scan) {
+ const CWPanelList *pl;
+ pl = Plugin_GetPanelList(scan);
+ tempNum += pl->count;
+ scan = scan->next;
+ }
+
+ tempPanels = xmalloc("plugin preference union", sizeof(const char *) * tempNum);
+
+ idx = 0;
+ scan = list ? list : pluginlist;
+ while (scan) {
+ const CWPanelList *pl;
+ int step;
+
+ pl = Plugin_GetPanelList(scan);
+ for (step = 0; step < pl->count; step++) {
+ int cmp;
+ for (cmp = 0; cmp < idx; cmp++) {
+ if (!ustrcmp(tempPanels[cmp], pl->names[step]))
+ break;
+ }
+
+ if (cmp >= idx)
+ tempPanels[idx++] = pl->names[step];
+ }
+
+ scan = scan->next;
+ }
+
+ *panelNames = xmalloc(NULL, idx * sizeof(const char *));
+ if (!*panelNames)
+ return 0;
+
+ *panelNames = xrealloc("plugin preference union", tempPanels, idx * sizeof(const char *));
+ *numPanels = idx;
+ return 1;
+}
+
+int Plugin_AddFileTypeMappings(Plugin *pl, OSFileTypeMappings **mlist) {
+ const OSFileTypeMappingList *ftml;
+
+ ftml = Plugin_GetFileTypeMappingList(pl);
+ if (!ftml) {
+ return 1;
+ } else {
+ AddFileTypeMappingList(NULL, ftml);
+ return 1;
+ }
+}
+
+int Plugins_AddFileTypeMappingsForTarget(Plugin *list, OSFileTypeMappings **mlist, OSType cpu, OSType os) {
+ if (!list)
+ list = pluginlist;
+
+ while (list) {
+ if (!list->cl_cb || Plugin_CL_MatchesTarget(list, cpu, os, 0))
+ Plugin_AddFileTypeMappings(list, mlist);
+ list = list->next;
+ }
+
+ return 1;
+}
+
+SInt16 Plugin_Call(Plugin *pl, void *context) {
+ if (pl->cb->main)
+ return pl->cb->main(context);
+ else
+ return cwErrRequestFailed;
+}
+