diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-10-19 21:16:13 +0100 |
commit | d1f153d34b023d81768f6087f67dbfff714bafc9 (patch) | |
tree | a694d470a60655d0cda15a70791fbdb90a2398cf /command_line/CmdLine/Src/Plugins | |
parent | 775b6861666af36d317fb577cf489e2c6377f878 (diff) | |
download | MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.tar.gz MWCC-d1f153d34b023d81768f6087f67dbfff714bafc9.zip |
let's commit all this before my VM blows up and nukes my work
Diffstat (limited to 'command_line/CmdLine/Src/Plugins')
-rw-r--r-- | command_line/CmdLine/Src/Plugins/CLPlugins.c | 981 |
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; +} + |