#include "cmdline.h" #include "plugin_internal.h" extern char STSbuf[256]; CWResult UCBCachePrecompiledHeader(CWPluginContext context, const CWFileSpec *filespec, CWMemHandle pchhandle) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBCachePrecompiledHeader"); OSSpec spec; Handle handle; OS_FSSpec_To_OSSpec(filespec, &spec); UCBSecretDetachHandle(context, pchhandle, &handle); CacheIncludeFile(&spec, handle, 1); return cwNoErr; } CWResult UCBLoadObjectData(CWPluginContext context, SInt32 whichfile, CWMemHandle *objectdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBLoadObjectData"); File *file = Files_GetFile(&gTarg->files, whichfile); if (!file) return cwErrUnknownFile; if (file->objectdata) { UCBSecretAttachHandle(context, file->objectdata, objectdata); return cwNoErr; } else { return cwErrRequestFailed; } } CWResult UCBStoreObjectData(CWPluginContext context, SInt32 whichfile, CWObjectData *object) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBStoreObjectData"); if (CheckForUserBreak()) return cwErrUserCanceled; File *filedata = Files_GetFile(&gTarg->files, whichfile); if (!filedata) return cwErrUnknownFile; if (!object->objectfile) { Handle objecthand; Handle browsehand; UCBSecretDetachHandle(context, object->objectdata, &objecthand); UCBSecretDetachHandle(context, object->browsedata, &browsehand); filedata->objectdata = objecthand; filedata->browsedata = browsehand; UCBSecretAttachHandle(context, objecthand, &object->objectdata); UCBSecretAttachHandle(context, browsehand, &object->browsedata); } else { if (filedata->outfileowner && filedata->outfileowner != CmdLineStageMask_Cg) { #line 240 DO_INTERNAL_ERROR("Cannot store object file spec for '%s'\n", filedata->srcfilename); } OS_FSSpec_To_OSSpec(object->objectfile, &filedata->outfss); filedata->wroteToDisk |= CmdLineStageMask_Cg; } filedata->codesize = object->codesize; filedata->udatasize = object->udatasize; filedata->idatasize = object->idatasize; filedata->compiledlines = object->compiledlines; if (filedata->dropinflags & kGeneratesrsrcs) filedata->hasresources = 1; else filedata->hasobjectcode = 1; filedata->recompileDependents = object->dependencyCount && object->interfaceChanged; OS_GetTime(&filedata->outmoddate); if (object->reserved1) filedata->filetype = object->reserved1; if (object->reserved2) { char *newname = reinterpret_cast(object->reserved2); CWFileInfo fi; if (OS_MakeSpec(newname, &filedata->srcfss, NULL) || OS_Status(&filedata->srcfss)) { fi.fullsearch = 1; fi.dependencyType = cwNoDependency; fi.isdependentoffile = -1; fi.suppressload = 1; if (UCBFindAndLoadFile(context, newname, &fi) == cwNoErr) { OS_FSSpec_To_OSSpec(&fi.filespec, &filedata->srcfss); } else { char *fnptr = OS_GetFileNamePtr(newname); if (fnptr != newname) { fi.fullsearch = 1; fi.dependencyType = cwNoDependency; fi.isdependentoffile = -1; fi.suppressload = 1; if (UCBFindAndLoadFile(context, fnptr, &fi) == cwNoErr) { OS_FSSpec_To_OSSpec(&fi.filespec, &filedata->srcfss); } } } } } return cwNoErr; } CWResult UCBFreeObjectData(CWPluginContext context, SInt32 whichfile, CWMemHandle objectdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBFreeObjectData"); File *file = Files_GetFile(&gTarg->files, whichfile); if (!file) return cwErrUnknownFile; if (file->objectdata) { DisposeHandle(file->objectdata); file->objectdata = NULL; return cwNoErr; } else { return cwErrInvalidParameter; } } CWResult UCBDisplayLines(CWPluginContext context, SInt32 nlines) { ShowWorking(12); if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBDisplayLines"); if (CheckForUserBreak()) return cwErrUserCanceled; else return cwNoErr; } CWResult UCBBeginSubCompile(CWPluginContext context, SInt32 whichfile, CWPluginContext *subContext) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBBeginSubCompile"); #line 372 DO_INTERNAL_ERROR("UCBBeginSubCompile not implemented"); return cwErrRequestFailed; } CWResult UCBEndSubCompile(CWPluginContext subContext) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBEndSubCompile"); #line 384 DO_INTERNAL_ERROR("UCBEndSubCompile not implemented"); return cwErrRequestFailed; } CWResult UCBGetPrecompiledHeaderSpec(CWPluginContext context, CWFileSpec *pchspec, const char *intarget) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetPrecompiledHeaderSpec"); CWCompilerLinkerContext *c; int err; OSSpec outfss; File *file; const CWObjectFlags *cof; char target[256]; if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) c = static_cast(context); else return cwErrInvalidCallback; file = Files_GetFile(&gTarg->files, c->whichfile); #line 420 OPTION_ASSERT(file != NULL); cof = Plugin_CL_GetObjectFlags(file->compiler); if (!file->outfilename[0]) { if (intarget) { if (optsCompiler.canonicalIncludes) strcpy(target, intarget); else if (OS_CanonPath(intarget, target) != noErr) return cwErrInvalidParameter; err = OS_MakeSpecWithPath(&file->srcfss.path, target, 0, &outfss); if (err) { CLReportOSError(CLStr97, err, target); return cwErrRequestFailed; } if (!file->outfileowner || file->outfileowner == CmdLineStageMask_Cg) { file->outfileowner = CmdLineStageMask_Cg; OS_SpecToStringRelative(&outfss, NULL, file->outfilename, sizeof(file->outfilename)); } if (optsCmdLine.verbose) CLReport(CLStr16, "precompiled ", OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf))); } else { OS_MakeSpecWithPath(&gTarg->outputDirectory, file->srcfilename, optsCompiler.relPathInOutputDir == 0, &outfss); OS_NameSpecSetExtension(&outfss.name, optsCompiler.pchFileExt[0] ? optsCompiler.pchFileExt : cof->pchFileExt); if (!file->outfileowner || file->outfileowner == CmdLineStageMask_Cg) { file->outfileowner = CmdLineStageMask_Cg; OS_NameSpecToString(&outfss.name, file->outfilename, sizeof(file->outfilename)); } CLReport(CLStr59, OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf))); } OS_OSSpec_To_FSSpec(&outfss, pchspec); } else { err = OS_MakeSpecWithPath(&gTarg->outputDirectory, file->outfilename, 0, &outfss); if (err) { CLReportOSError(CLStr97, err, file->outfilename); return cwErrRequestFailed; } OS_OSSpec_To_FSSpec(&outfss, pchspec); if (intarget) CLReport(CLStr60, OS_SpecToStringRelative(&outfss, NULL, STSbuf, sizeof(STSbuf)), intarget); } return cwNoErr; } CWResult UCBGetResourceFile(CWPluginContext context, CWFileSpec *filespec) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetResourceFile"); #line 514 DO_INTERNAL_ERROR("UCBGetResourceFile not implemented"); return cwErrRequestFailed; } CWResult UCBPutResourceFile(CWPluginContext context, const char *prompt, const char *name, CWFileSpec *filespec) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBPutResourceFile"); #line 529 DO_INTERNAL_ERROR("UCBPutResourceFile not implemented"); return cwErrRequestFailed; } static int UnitNameToSBMName(OSSpec *spec, File *srcfile) { const CWObjectFlags *cof; int err; cof = Plugin_CL_GetObjectFlags(srcfile->compiler); err = OS_NameSpecChangeExtension( &spec->name, cof->pchFileExt ? cof->pchFileExt : ".sbm", cof->pchFileExt ? (cof->pchFileExt[0] == '.') : 0 ); return err; } CWResult UCBLookUpUnit(CWPluginContext context, const char *name, Boolean isdependency, const void **unitdata, SInt32 *unitdatalength) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBLookUpUnit"); CWFileInfo includeinfo; OSSpec unitspec; OSSpec sbmspec; time_t unittime; UInt32 unitmactime; char sbmpath[256]; int err; CWCompilerLinkerContext *c; File *srcfile; File *sbmfile; if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) c = static_cast(context); else return cwErrInvalidCallback; srcfile = Files_GetFile(&gTarg->files, c->whichfile); #line 591 OPTION_ASSERT(srcfile != NULL); *unitdata = NULL; *unitdatalength = 0; if (optsCompiler.sbmState == OptsCompilerSbmState_1 || optsCompiler.sbmState == OptsCompilerSbmState_3) { if (clState.pluginDebug) CLPrint("UCBLookUpUnit: sbmState == sbmRebuild or sbmClean; failing\n"); return cwErrSBMNotFound; } includeinfo.fullsearch = 1; includeinfo.dependencyType = isdependency ? cwNormalDependency : cwNoDependency; includeinfo.isdependentoffile = -1; includeinfo.suppressload = 1; if (UCBFindAndLoadFile(context, name, &includeinfo) != cwNoErr) { if (clState.pluginDebug) CLPrint("UCBLookUpUnit: could not find source '%s'; failing\n", name); return cwErrFileNotFound; } OS_FSSpec_To_OSSpec(&includeinfo.filespec, &unitspec); sbmspec = unitspec; err = UnitNameToSBMName(&sbmspec, srcfile); if (err) { if (clState.pluginDebug) CLPrint("UCBLookUpUnit: could not make precompiled unit spec for '%s' (%s)\n", name, OS_GetErrText(err)); return cwErrRequestFailed; } if (optsCompiler.sbmPath[0]) { sbmspec.path = clState.sbmPathSpec; OS_SpecToString(&sbmspec, sbmpath, sizeof(sbmpath)); if (clState.pluginDebug) CLPrint("UCBLookUpUnit: Only looking at '%s'\n", sbmpath); } else { OS_NameSpecToString(&sbmspec.name, sbmpath, sizeof(sbmpath)); if (clState.pluginDebug) CLPrint("UCBLookUpUnit: searching paths for '%s'\n", sbmpath); } includeinfo.fullsearch = 1; includeinfo.dependencyType = isdependency ? cwNormalDependency : cwNoDependency; includeinfo.isdependentoffile = -1; includeinfo.suppressload = 0; if (UCBFindAndLoadFile(context, sbmpath, &includeinfo) != cwNoErr || !includeinfo.filedata) { if (clState.pluginDebug) CLPrint("UCBLookUpUnit: could not find or load precompiled unit file '%s'; failing\n", sbmpath); return cwErrFileNotFound; } OS_FSSpec_To_OSSpec(&includeinfo.filespec, &sbmspec); if (includeinfo.filedatatype != cwFileTypePrecompiledHeader) { CLPrint("UCBLookUpUnit: file '%s' does not appear to be precompiled\n", OS_SpecToString(&sbmspec, STSbuf, sizeof(STSbuf))); UCBReleaseFileText(context, includeinfo.filedata); return cwErrRequestFailed; } OS_GetFileTime(&unitspec, NULL, &unittime); OS_TimeToMac(unittime, &unitmactime); if (unitmactime != *reinterpret_cast(includeinfo.filedata)) { if (clState.pluginDebug) CLPrint( "UCBLookUpUnit: file '%s' does not have internal timestamp that matches source unit's timestamp (0x%8x != 0x%8x)\n", OS_SpecToString(&sbmspec, STSbuf, sizeof(STSbuf)), unitmactime, *reinterpret_cast(includeinfo.filedata)); UCBReleaseFileText(context, includeinfo.filedata); return cwErrRequestFailed; } sbmfile = Files_FindFile(&gTarg->pchs, &sbmspec); if (!sbmfile) { sbmfile = File_New(); sbmfile->srcfss = unitspec; OS_SpecToString(&sbmfile->srcfss, sbmfile->srcfilename, sizeof(sbmfile->srcfilename)); sbmfile->outfss = sbmspec; OS_SpecToString(&sbmfile->outfss, sbmfile->outfilename, sizeof(sbmfile->outfilename)); sbmfile->compiler = srcfile->compiler; sbmfile->outfileowner = CmdLineStageMask_Cg; sbmfile->writeToDisk = srcfile->writeToDisk; sbmfile->dropinflags = srcfile->dropinflags; sbmfile->objectflags = srcfile->objectflags; sbmfile->mappingflags = srcfile->mappingflags; Deps_Initialize(&sbmfile->deps, &gTarg->incls); if (!Files_AddFile(&gTarg->pchs, sbmfile)) return cwErrRequestFailed; } if (clState.pluginDebug) CLPrint("UCBLookUpUnit: success for '%s'\n", name); if (optsCmdLine.verbose) CLReport(CLStr62, "unit symbol table", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf))); *unitdata = includeinfo.filedata; *unitdatalength = includeinfo.filedatalength; return cwNoErr; } CWResult UCBSBMfiles(CWPluginContext context, short libref) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBSBMfiles"); return cwNoErr; } CWResult UCBStoreUnit(CWPluginContext context, const char *inunitname, CWMemHandle unitdata, CWDependencyTag dependencytag) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBStoreUnit"); char unitname[256]; OSSpec sbmspec; int err; Handle h; OSHandle unithand; OSFileHandle fhand; CWCompilerLinkerContext *c; File *srcfile; if (optsCompiler.canonicalIncludes) { strcpy(unitname, inunitname); } else if (OS_CanonPath(inunitname, unitname)) { return cwErrInvalidParameter; } if (optsCompiler.sbmState == OptsCompilerSbmState_0 || optsCompiler.sbmState == OptsCompilerSbmState_1) { if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) c = static_cast(context); else return cwErrInvalidCallback; srcfile = Files_GetFile(&gTarg->files, c->whichfile); #line 791 OPTION_ASSERT(srcfile != NULL); if (optsCompiler.sbmPath[0]) { err = OS_MakeSpecWithPath(&clState.sbmPathSpec, unitname, 1, &sbmspec); if (err) { if (clState.pluginDebug) CLPrint("UCBStoreUnit: '%s' is a bad unit name (%s)\n", unitname, OS_GetErrText(err)); return cwErrInvalidParameter; } } else { err = OS_MakeFileSpec(unitname, &sbmspec); if (err) { if (clState.pluginDebug) CLPrint("UCBStoreUnit: '%s' is a bad filename (%s)\n", unitname, OS_GetErrText(err)); return cwErrInvalidParameter; } } err = UnitNameToSBMName(&sbmspec, srcfile); if (err) { if (clState.pluginDebug) CLPrint("UCBStoreUnit: could not make precompiled unit form of '%s' (%s)\n", unitname, OS_GetErrText(err)); return cwErrInvalidParameter; } if (optsCmdLine.verbose) CLReport(CLStr61, "unit symbol table", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf))); UCBSecretDetachHandle(context, unitdata, &h); OS_DestroyMacHandle(h, &unithand); err = OS_NewFileHandle(&sbmspec, &unithand, 1, &fhand); if (err || (err = OS_FreeFileHandle(&fhand))) { CLReportOSError(CLStr18, err, "precompiled unit", OS_SpecToStringRelative(&sbmspec, NULL, STSbuf, sizeof(STSbuf))); return cwErrRequestFailed; } } return cwNoErr; } CWResult UCBReleaseUnit(CWPluginContext context, void *unitdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBReleaseUnit"); if (!unitdata) return cwErrRequestFailed; return UCBReleaseFileText(context, static_cast(unitdata)); } CWResult UCBUnitNameToFileName(CWPluginContext context, const char *unitname, char *filename) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBUnitNameToFileName"); strcpy(filename, unitname); if (!OS_EqualPath(filename + strlen(filename) - 2, ".p")) strcat(filename, ".p"); return cwNoErr; } CWResult UCBOSAlert(CWPluginContext context, const char *message, OSErr errorcode) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBOSAlert"); if (CheckForUserBreak()) return cwErrUserCanceled; char errormessage[256]; GetSysErrText(errorcode, errormessage); CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, errorcode, CLStyledMessageDispatch_Type4, "%\n(%)\n", message ? message : "", errormessage ); return cwNoErr; } CWResult UCBOSErrorMessage(CWPluginContext context, const char *message, OSErr errorcode) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBOSErrorMessage"); if (!errorcode) return cwNoErr; if (CheckForUserBreak()) return cwErrUserCanceled; char errormessage[256]; GetSysErrText(errorcode, errormessage); CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, errorcode, CLStyledMessageDispatch_Type4, "%\n%\n", message ? message : "", errormessage ); return cwNoErr; } CWResult UCBGetModifiedFiles(CWPluginContext context, SInt32 *modifiedFileCount, const SInt32 **modifiedFiles) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetModifiedFiles"); *modifiedFileCount = 0; #line 949 DO_INTERNAL_ERROR("CWGetModifiedFiles not implemented!\n"); return cwNoErr; } CWResult UCBGetSuggestedObjectFileSpec(CWPluginContext context, SInt32 whichfile, CWFileSpec *fileSpec) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetSuggestedObjectFileSpec"); File *file; if (!(file = Files_GetFile(&gTarg->files, whichfile))) return cwErrUnknownFile; if (!GetOutputFile(file, CmdLineStageMask_Cg)) return cwErrRequestFailed; OS_OSSpec_To_FSSpec(&file->outfss, fileSpec); return cwNoErr; } CWResult UCBGetStoredObjectFileSpec(CWPluginContext context, SInt32 whichfile, CWFileSpec *fileSpec) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetStoredObjectFileSpec"); File *file; if (!(file = Files_GetFile(&gTarg->files, whichfile))) return cwErrUnknownFile; if (file->outfileowner != CmdLineStageMask_Cg) { #line 993 DO_INTERNAL_ERROR("Lost stored object file spec for '%s'\n", file->srcfilename); return cwErrRequestFailed; } else { OS_OSSpec_To_FSSpec(&file->outfss, fileSpec); return cwNoErr; } } CWResult UCBGetFrameworkCount(CWPluginContext context, SInt32 *frameworkCount) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetFrameworkCount"); *frameworkCount = Frameworks_GetCount(); return cwNoErr; } CWResult UCBGetFrameworkInfo(CWPluginContext context, SInt32 whichFramework, CWFrameworkInfo *frameworkInfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetFrameworkCount"); Paths_FWInfo *info; if ((info = Frameworks_GetInfo(whichFramework))) { OS_OSSpec_To_FSSpec(&info->fileSpec, &frameworkInfo->fileSpec); strncpy(frameworkInfo->version, info->version.s, sizeof(frameworkInfo->version)); return cwNoErr; } return cwErrFileNotFound; } CWCompilerLinkerCallbacks sCompilerLinkerCallbacks = { UCBCachePrecompiledHeader, UCBLoadObjectData, UCBStoreObjectData, UCBFreeObjectData, UCBDisplayLines, UCBBeginSubCompile, UCBEndSubCompile, UCBGetPrecompiledHeaderSpec, UCBGetResourceFile, UCBPutResourceFile, UCBLookUpUnit, UCBSBMfiles, UCBStoreUnit, UCBReleaseUnit, UCBUnitNameToFileName, UCBOSErrorMessage, UCBOSAlert, UCBGetModifiedFiles, UCBGetSuggestedObjectFileSpec, UCBGetStoredObjectFileSpec, NULL, UCBGetFrameworkCount, UCBGetFrameworkInfo }; CWCompilerLinkerContext::CWCompilerLinkerContext() : CWPluginPrivateContext(clState.plugintype, sizeof(CWCompilerLinkerContext)) { targetinfo = static_cast(xmalloc("context", sizeof(CWTargetInfo))); memset(targetinfo, 0, sizeof(CWTargetInfo)); if (gTarg) { targetinfo->targetCPU = gTarg->cpu; targetinfo->targetOS = gTarg->os; } else { targetinfo->targetOS = targetOSAny; targetinfo->targetCPU = targetCPUAny; } whichfile = 0; memset(&sourcefile, 0, sizeof(sourcefile)); sourcetext = NULL; sourcetextsize = 0; preprocess = 0; autoprecompile = 0; precompile = 0; cachingPCH = 0; debuginfo = 0; fileID = 0; memset(&browseoptions, 0, sizeof(browseoptions)); reserved = NULL; sequenceID = 0; parentPB = NULL; targetStorage = NULL; texthandle = NULL; memset(&targetinfo_V7, 0, sizeof(targetinfo_V7)); callbacks = &sCompilerLinkerCallbacks; } CWCompilerLinkerContext::~CWCompilerLinkerContext() { xfree(targetinfo); }