#include "cmdline.h" static Plugin *pluginlist; static ToolVersionInfo toolVersionInfo; static VersionInfo toolVersion; static Boolean useToolVersion; static void GetToolVersionInfo(void) { useToolVersion = 0; } const ToolVersionInfo *Plugin_GetToolVersionInfo(void) { return useToolVersion ? &toolVersionInfo : 0; } static const char *Plugin_GetDisplayName(Plugin *pl) { const char *name; OS_ASSERT(251, 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; OS_ASSERT(263, 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; OS_ASSERT(276, 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; OS_ASSERT(329, 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; OS_ASSERT(345, 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; OS_ASSERT(358, pl); OS_ASSERT(359, 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; OS_ASSERT(381, 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; OS_ASSERT(401, pl); OS_ASSERT(402, 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; OS_ASSERT(422, pl); if (pl->cb->GetFileTypeMappings && pl->cb->GetFileTypeMappings(&ftml) == 0) return ftml; else return NULL; } const CWObjectFlags *Plugin_CL_GetObjectFlags(Plugin *pl) { static const CWObjectFlags fake = { 2, 0, "", "", "", "", "", "", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const CWObjectFlags *cof; OS_ASSERT(434, pl); OS_ASSERT(435, 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; OS_ASSERT(566, 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; OS_ASSERT(578, 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; OS_ASSERT(590, pl->cl_cb != NULL); OS_ASSERT(591, 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, sizeof(DropInFlagsV1), sizeof(DropInFlags)}; 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(CLStr91, 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(CLStr92, Plugin_GetDropInName(pl)); return 0; } else { return 1; } } void Plugins_Init(void) { pluginlist = NULL; GetToolVersionInfo(); } void Plugins_Term(void) { 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(CLStr88, dropinname, pl->cached_ascii_version, failreason); return 0; } scan = &pluginlist; while (*scan) { if (Plugin_MatchesName(*scan, dropinname)) { CLReportError(CLStr89, dropinname); return 0; } scan = &(*scan)->next; } *scan = pl; df = Plugin_GetDropInFlags(pl); if (!(df->dropinflags & dropInExecutableTool) && !SendInitOrTermRequest(pl, 1)) { CLReportError(CLStr3, dropinname); return 0; } if (df->dropintype == CWDROPINCOMPILERTYPE && df->dropinflags & 0x17C000) CLReportError(CLStr4, "compiler", dropinname); if (df->dropintype == CWDROPINLINKERTYPE && df->dropinflags & 0x5FE4000) CLReportError(CLStr4, "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: 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(CLStr5); for (idx = 0; idx < numPanels; idx++) { if (!supports[idx]) CLReport(CLStr6, 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); OS_ASSERT(1270, df != NULL); OS_ASSERT(1271, 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; }