mirror of https://git.wuffs.org/MWCC
968 lines
29 KiB
C
968 lines
29 KiB
C
#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: <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(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;
|
|
}
|
|
|