#include "cmdline.h" #include "plugin_internal.h" extern char STSbuf[256]; static void ANSI_To_Mac_GMT_Time(time_t sectm, UInt32 *secs) { struct tm *tmrec; int years; int ydays; tmrec = localtime(§m); years = tmrec->tm_year - 4; ydays = (years * 365) + ((years + 3) / 4) - ((years + 4) / 100) + ((years - 296) / 400); *secs = ((ydays + tmrec->tm_yday) * 86400) + (tmrec->tm_hour * 3600) + (tmrec->tm_min * 60) + (tmrec->tm_sec); } static void Mac_To_ANSI_Time(UInt32 secs, time_t *sectm) { static int monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; struct tm tmrec; int month; memset(&tmrec, 0, sizeof(tmrec)); tmrec.tm_sec = secs % 60; // line 1523 tmrec.tm_min = (secs / 60) % 60; // line 1524 tmrec.tm_hour = (secs / 3600) % 24; // line 1525 tmrec.tm_yday = (secs / 86400) % 365; tmrec.tm_year = (secs / 31536000) + 4; // line 1533 tmrec.tm_yday -= ((((secs / 31536000) + 3) / 4) - (((secs / 31536000) + 4) / 100) + ((SInt32)((secs / 31536000) - 296) / 400)) ; if ((tmrec.tm_year % 4) && ((tmrec.tm_year % 100) || !(tmrec.tm_year % 400))) { monthdays[1] = 28; } else { monthdays[1] = 29; } for (month = 0; tmrec.tm_yday >= monthdays[month]; month++) { tmrec.tm_yday -= monthdays[month]; } tmrec.tm_mon = month; tmrec.tm_mday = tmrec.tm_yday + 1; *sectm = mktime(&tmrec); if (month >= 4 && month < 10) *sectm += 3600; } CWResult UCBGetFileInfo(CWPluginContext context, SInt32 whichfile, Boolean checkFileLocation, CWProjectFileInfo *fileinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetFileInfo"); File *file; SInt16 id; int ret; char fullpath[256]; time_t tmptime; file = Files_GetFile(&gTarg->files, whichfile); if (!file) return cwErrUnknownFile; memset(fileinfo, 0, sizeof(CWProjectFileInfo)); OS_OSSpec_To_FSSpec(&file->srcfss, &fileinfo->filespec); OS_TimeToMac(file->srcmoddate, &fileinfo->moddate); Mac_To_ANSI_Time(fileinfo->moddate, &tmptime); ANSI_To_Mac_GMT_Time(tmptime, &fileinfo->moddate); fileinfo->segment = file->segnum; fileinfo->hasobjectcode = file->hasobjectcode; fileinfo->hasresources = file->hasresources; fileinfo->isresourcefile = file->isresourcefile; fileinfo->weakimport = file->weakimport; fileinfo->initbefore = file->initbefore; fileinfo->mergeintooutput = file->mergeintooutput; fileinfo->reserved = 0; fileinfo->gendebug = file->gendebug; OS_TimeToMac(file->outmoddate, &fileinfo->objmoddate); if (file->compiler) { strncpy(fileinfo->dropinname, Plugin_GetDropInName(file->compiler), 31); fileinfo->dropinname[31] = 0; } else { fileinfo->dropinname[0] = 0; } fileinfo->fileID = file->browseFileID; fileinfo->recordbrowseinfo = file->recordbrowseinfo; fileinfo->filetype = file->filetype; fileinfo->filecreator = file->filecreator; if (optsCompiler.browserEnabled) { ret = Browser_SearchFile(&clState.browseTableHandle, OS_SpecToString(&file->srcfss, fullpath, sizeof(fullpath)), &id); if (ret) { fileinfo->recordbrowseinfo = 1; fileinfo->fileID = id; } else { fileinfo->recordbrowseinfo = 0; fileinfo->fileID = id; } } else { fileinfo->recordbrowseinfo = 0; fileinfo->fileID = 0; } fileinfo->unitdatadependencytag = 0; fileinfo->hasunitdata = 0; return cwNoErr; } static Boolean FindAndLoad_VirtualFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) { VFile *vf; char *fnameptr; fnameptr = OS_GetFileNamePtr(const_cast(filename)); vf = VFiles_Find(gTarg->virtualFiles, fnameptr); if (vf) { if (!fileinfo->suppressload) { CopyFileText(vf->data, const_cast(&fileinfo->filedata), &fileinfo->filedatalength); *loaded = 1; } fileinfo->filedatatype = cwFileTypeText; fileinfo->fileID = 0; fileinfo->alreadyincluded = 0; fileinfo->recordbrowseinfo = 0; fileinfo->filespec.parID = 0; fileinfo->filespec.vRefNum = 0; c2pstrcpy(fileinfo->filespec.name, fnameptr); OS_MakeFileSpec(fnameptr, spec); if (optsCompiler.printHeaderNames) CLPrint("%s\n", fnameptr); return 1; } return 0; } static Boolean FindAndLoad_AccessPathFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) { SInt32 incl; shellContextType *sc; File *depfile; SInt16 id; int ret; char fullpath[256]; if (Incls_FindFileInPaths(&gTarg->incls, const_cast(filename), fileinfo->fullsearch || optsCompiler.noSysPath, spec, &incl)) { if (context->pluginType == CWDROPINCOMPILERTYPE) { depfile = Files_GetFile( &gTarg->files, (fileinfo->isdependentoffile < 0) ? static_cast(context)->whichfile : fileinfo->isdependentoffile); if (depfile) Deps_AddDependency(&depfile->deps, incl, NULL, 0, fileinfo->dependencyType, &fileinfo->alreadyincluded); if (optsCompiler.browserEnabled) { ret = Browser_SearchAndAddFile(&clState.browseTableHandle, OS_SpecToString(spec, fullpath, sizeof(fullpath)), &id); if (ret == 0) { return 2; } else if (ret < 0) { fileinfo->recordbrowseinfo = 1; fileinfo->fileID = id; } else { fileinfo->recordbrowseinfo = 0; fileinfo->fileID = id; } } else { fileinfo->recordbrowseinfo = 0; fileinfo->fileID = 0; } } OS_OSSpec_To_FSSpec(spec, &fileinfo->filespec); return 1; } return 0; } static Boolean FindAndLoad_MissingFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo, OSSpec *spec, Boolean *loaded) { File *file; CWCompilerLinkerContext *c; if (optsCompiler.ignoreMissingFiles) { if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) c = static_cast(context); else return 0; file = Files_GetFile(&gTarg->files, c->whichfile); OS_ASSERT(486, file != NULL); OS_MakeSpecWithPath(&file->srcfss.path, filename, 1, spec); Deps_AddDependency(&file->deps, -1, spec, !fileinfo->fullsearch && !optsCompiler.noSysPath, fileinfo->dependencyType, &fileinfo->alreadyincluded); fileinfo->fileID = 0; fileinfo->recordbrowseinfo = 0; if (!fileinfo->suppressload) { fileinfo->filedata = xstrdup(""); fileinfo->filedatalength = 0; fileinfo->filedatatype = cwFileTypeText; *loaded = 1; } else { fileinfo->filedata = NULL; fileinfo->filedatalength = 0; fileinfo->filedatatype = cwFileTypeUnknown; } OS_OSSpec_To_FSSpec(spec, &fileinfo->filespec); return 1; } return 0; } CWResult UCBFindAndLoadFile(CWPluginContext context, const char *infilename, CWFileInfo *fileinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBFindAndLoadFile"); OSSpec spec; Boolean loaded; char filename[256]; char browseinfo[64]; ShowWorking(8); if (CheckForUserBreak()) return cwErrUserCanceled; if (optsCompiler.canonicalIncludes) strcpy(filename, infilename); else if (OS_CanonPath(infilename, filename)) return cwErrInvalidParameter; loaded = 0; if (!FindAndLoad_VirtualFile(context, filename, fileinfo, &spec, &loaded) && !FindAndLoad_AccessPathFile(context, filename, fileinfo, &spec, &loaded) && !FindAndLoad_MissingFile(context, filename, fileinfo, &spec, &loaded)) { return cwErrFileNotFound; } if (optsCompiler.printHeaderNames) CLPrint("%s\n", OS_SpecToStringRelative(&spec, NULL, STSbuf, sizeof(STSbuf))); if (context->pluginType == CWDROPINCOMPILERTYPE) { if (optsCmdLine.verbose > 2) { sprintf(browseinfo, " (browse fileID %d)", fileinfo->fileID); CLReport( CLStr21, fileinfo->alreadyincluded ? "Included" : "Including", OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)), fileinfo->recordbrowseinfo ? browseinfo : ""); } else if (optsCmdLine.verbose > 1 && !fileinfo->alreadyincluded) { CLReport( CLStr21, "Including", OS_SpecToString(&spec, STSbuf, sizeof(STSbuf)), ""); } } else { fileinfo->fileID = 0; fileinfo->recordbrowseinfo = 0; fileinfo->alreadyincluded = 0; } if (!loaded) { if (!fileinfo->suppressload) { return UCBGetFileText(context, &fileinfo->filespec, &fileinfo->filedata, &fileinfo->filedatalength, &fileinfo->filedatatype); } else { fileinfo->filedata = NULL; fileinfo->filedatalength = 0; fileinfo->filedatatype = cwFileTypeUnknown; return cwNoErr; } } else { return cwNoErr; } } CWResult UCBGetFileText(CWPluginContext context, const CWFileSpec *filespec, const char **text, SInt32 *textLength, short *filedatatype) { int err; Handle texthandle = NULL; Boolean precomp; OSSpec spec; VFile *vf; char filename[64]; if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetFileText"); OS_FSSpec_To_OSSpec(filespec, &spec); err = LoadAndCacheFile(&spec, &texthandle, &precomp); if (err) { p2cstrcpy(filename, filespec->name); if (filespec->vRefNum || filespec->parID || !(vf = VFiles_Find(gTarg->virtualFiles, filename))) { CLReportOSError(CLStr93, err, OS_SpecToString(&spec, STSbuf, sizeof(STSbuf))); return cwErrFileNotFound; } CopyFileText(vf->data, const_cast(text), textLength); *filedatatype = cwFileTypeText; int err = OS_MakeFileSpec(filename, &spec); } else { if (texthandle) { if (!precomp) { CopyFileText(texthandle, const_cast(text), textLength); FreeIncludeFile(texthandle); } else { HLock(texthandle); *text = *texthandle; *textLength = GetHandleSize(texthandle); } } if (texthandle) { if (!precomp) *filedatatype = cwFileTypeText; else *filedatatype = cwFileTypePrecompiledHeader; } else { *filedatatype = cwFileTypeUnknown; } } return cwNoErr; } CWResult UCBReleaseFileText(CWPluginContext context, const char *text) { short callbackResult = 0; CWCompilerLinkerContext *cc = static_cast(context); if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBReleaseFileText"); if (text) { if (text != cc->sourcetext) xfree((void *) text); } else { callbackResult = cwErrInvalidParameter; } return callbackResult; } CWResult UCBGetSegmentInfo(CWPluginContext context, SInt32 whichsegment, CWProjectSegmentInfo *segmentinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetSegmentInfo"); if (gTarg->linkmodel != LinkModel1) return cwErrInvalidCallback; Segment *seg = Segments_GetSegment(&gTarg->linkage.segs, whichsegment); if (!seg) return cwErrUnknownSegment; strcpy(segmentinfo->name, seg->name); segmentinfo->attributes = seg->attrs; return cwNoErr; } CWResult UCBGetOverlay1GroupInfo(CWPluginContext context, SInt32 whichgroup, CWOverlay1GroupInfo *groupinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetOverlay1GroupInfo"); OvlGroup *grp = Overlays_GetOvlGroup(&gTarg->linkage.overlays, whichgroup); if (gTarg->linkmodel != LinkModel2) return cwErrInvalidCallback; if (grp) { strcpy(groupinfo->name, grp->name); groupinfo->address.lo = grp->addr.lo; groupinfo->address.hi = grp->addr.hi; groupinfo->numoverlays = OvlGroup_CountOverlays(grp); return cwNoErr; } else { return cwErrInvalidParameter; } } CWResult UCBGetOverlay1FileInfo(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, SInt32 whichoverlayfile, CWOverlay1FileInfo *fileinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetOverlay1FileInfo"); if (gTarg->linkmodel != LinkModel2) return cwErrInvalidCallback; SInt32 filenum = Overlays_GetFileInOverlay(&gTarg->linkage.overlays, whichgroup, whichoverlay, whichoverlayfile); if (filenum >= 0) { fileinfo->whichfile = filenum; return cwNoErr; } else { return cwErrInvalidParameter; } } CWResult UCBGetOverlay1Info(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, CWOverlay1Info *overlayinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetOverlay1Info"); if (gTarg->linkmodel != LinkModel2) return cwErrInvalidCallback; Overlay *oly = Overlays_GetOverlayInGroup(&gTarg->linkage.overlays, whichgroup, whichoverlay); if (oly) { strcpy(overlayinfo->name, oly->name); overlayinfo->numfiles = Overlay_CountFiles(oly); return cwNoErr; } else { return cwErrInvalidParameter; } } CWResult UCBReportMessage(CWPluginContext context, const CWMessageRef *msgRef, const char *line1, const char *line2, short errorlevel, SInt32 errorNumber) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBReportMessage"); short msgType; int eeol; const char *eeptr; char *tptr; MessageRef ref; CWCompilerLinkerContext *clx; static const char *fmts[2][2][2] = { "%\n", "%", "%\n", "%", "%\n%\n", "%%\n", "%\n%", "%%" }; if (line1 == NULL) { line1 = ""; eeol = 0; } else { eeptr = line1 + strlen(line1) - 1; eeol = *eeptr == '\r' || *eeptr == '\n'; } if (CheckForUserBreak()) return cwErrUserCanceled; if (errorlevel == messagetypeError) msgType = CLStyledMessageDispatch_Type3; else if (errorlevel == messagetypeWarning) msgType = CLStyledMessageDispatch_Type2; else msgType = CLStyledMessageDispatch_Type1; clx = static_cast(context); if (!msgRef) { if (line2 && line2[0]) { eeptr = line2 + strlen(line2) - 1; int eeol2 = *eeptr == '\r' || *eeptr == '\n'; CLStyledMessageDispatch( static_cast(clx->shellContext)->plugin, NULL, errorNumber, msgType, fmts[1][eeol2][eeol], line1, line2 ); } else { CLStyledMessageDispatch( static_cast(clx->shellContext)->plugin, NULL, errorNumber, msgType, fmts[0][0][eeol], line1 ); } } else { OS_FSSpec_To_OSSpec(&clx->sourcefile, &ref.sourcefile); OS_FSSpec_To_OSSpec(&msgRef->sourcefile, &ref.errorfile); ref.sourceline = const_cast(line2); ref.linenumber = msgRef->linenumber; ref.tokenoffset = msgRef->tokenoffset; ref.tokenlength = msgRef->tokenlength; ref.selectionoffset = msgRef->selectionoffset; ref.selectionlength = msgRef->selectionlength; if (ref.tokenoffset < 0) ref.tokenoffset = 0; if (ref.tokenlength < 0) ref.tokenlength = 0; if (ref.selectionoffset < 0) ref.selectionoffset = 0; if (ref.selectionlength < 0) ref.selectionlength = 0; CLStyledMessageDispatch( static_cast(clx->shellContext)->plugin, &ref, errorNumber, msgType, fmts[0][0][eeol], line1 ); } return cwNoErr; } CWResult UCBAlert(CWPluginContext context, const char *msg1, const char *msg2, const char *msg3, const char *msg4) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBAlert"); if (CheckForUserBreak()) return cwErrUserCanceled; if (msg4) { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type4, "%\n%\n%\n%\n", msg1 ? msg1 : "", msg2 ? msg2 : "", msg3 ? msg3 : "", msg4 ); } else if (msg3) { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type4, "%\n%\n%\n", msg1 ? msg1 : "", msg2 ? msg2 : "", msg3 ); } else if (msg2) { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type4, "%\n%\n", msg1 ? msg1 : "", msg2 ); } else { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type4, "%\n", msg1 ? msg1 : "" ); } return cwNoErr; } CWResult UCBShowStatus(CWPluginContext context, const char *line1, const char *line2) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBShowStatus"); if (CheckForUserBreak()) return cwErrUserCanceled; if (optsCmdLine.verbose > 1) { if ((!line1 || !*line1) && (!line2 || !*line2)) return cwNoErr; if (line2 && *line2) { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type5, "%\n%\n", line1 ? line1 : "", line2 ? line2 : "" ); } else { CLStyledMessageDispatch( static_cast(context->shellContext)->plugin, NULL, 0, CLStyledMessageDispatch_Type5, "%\n", line1 ? line1 : "" ); } } return cwNoErr; } CWResult UCBUserBreak(CWPluginContext context) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBUserBreak"); ShowWorking(8); if (CheckForUserBreak()) return cwErrUserCanceled; else return cwNoErr; } CWResult UCBGetNamedPreferences(CWPluginContext context, const char *prefsname, CWMemHandle *prefsdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetNamedPreferences"); PrefPanel *pnl = Prefs_FindPanel(prefsname); if (pnl) { if (optsCmdLine.verbose > 2) CLReport(CLStr83, prefsname); UCBSecretAttachHandle(context, PrefPanel_GetHandle(pnl), prefsdata); return cwNoErr; } else { CLReportError(CLStr91, prefsname); *prefsdata = NULL; return cwErrRequestFailed; } } CWResult UCBStorePluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle prefsdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBStorePluginData"); DO_INTERNAL_ERROR(1267, "UCBStorePluginData not implemented"); return cwErrRequestFailed; } CWResult UCBGetPluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle *prefsdata) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetPluginData"); DO_INTERNAL_ERROR(1286, "UCBGetPluginData not implemented"); return cwErrRequestFailed; } CWResult UCBSetModDate(CWPluginContext context, const CWFileSpec *filespec, CWFileTime *moddate, Boolean isGenerated) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBSetModDate"); OSSpec spec; time_t mdtm; int err; SInt32 idx; File *file; OS_FSSpec_To_OSSpec(filespec, &spec); if (!moddate || !*moddate) OS_GetTime(&mdtm); else OS_MacToTime(*moddate, &mdtm); for (idx = 0; idx < Files_Count(&gTarg->files); idx++) { file = Files_GetFile(&gTarg->files, idx); if (OS_EqualSpec(&file->srcfss, &spec)) file->srcmoddate = mdtm; else if (OS_EqualSpec(&file->outfss, &spec)) file->outmoddate = mdtm; } err = OS_SetFileTime(&spec, NULL, &mdtm); if (err == 0) return cwNoErr; else return cwErrRequestFailed; } CWResult UCBAddProjectEntry(CWPluginContext context, const CWFileSpec *fileSpec, Boolean isGenerated, const CWNewProjectEntryInfo *entry, SInt32 *whichfile) { // two registers are awkwardly swapped here... File *file; OSSpec fss; UInt32 filetype; Plugin *plugin; char *extptr; char ext[16]; UInt32 flags; char filename[256]; const DropInFlags *df; OvlGroup *ovg; Overlay *oly; SInt32 idx; if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBAddProjectEntry"); OS_FSSpec_To_OSSpec(fileSpec, &fss); if (OS_IsDir(&fss)) return cwErrInvalidParameter; OS_NameSpecToString(&fss.name, filename, sizeof(filename)); if (gTarg->linker && !(gTarg->linkerDropinFlags & (linkAllowDupFileNames | dropInExecutableTool))) { if (Files_FindFile(&gTarg->files, &fss)) { if (optsCmdLine.verbose > 1) CLReportWarning(CLStr106, filename); return cwNoErr; } } extptr = filename + strlen(filename) - 1; while (extptr > filename && *extptr != '.') --extptr; if (extptr <= filename) extptr = "."; strncpy(ext, extptr, sizeof(ext) - 1); ext[sizeof(ext) - 1] = 0; OS_SpecToStringRelative(&fss, NULL, filename, sizeof(filename)); if (optsCmdLine.verbose > 2) CLReport(CLStr77, " to project", filename); if (OS_GetMacFileType(&fss, &filetype)) filetype = CWFOURCHAR('T','E','X','T'); plugin = Plugins_GetPluginForFile(NULL, CWDROPINANYTYPE, targetCPUAny, targetOSAny, filetype, ext, Lang_Any); if (plugin && gTarg->linker && !Plugin_CL_MatchesTarget(plugin, gTarg->cpu, gTarg->os, 0)) CLReportError(CLStr76, filename); if (!plugin) plugin = Plugins_CL_MatchTarget(NULL, gTarg->cpu, gTarg->os, clState.plugintype, clState.language); if (plugin) { if (!Plugin_CL_GetCompilerMapping(plugin, filetype, ext, &flags)) { flags = 0; if (!isGenerated && !optsCompiler.compileIgnored && optsCompiler.forcePrecompile != 1) { CLReportWarning( CLStr73, "file", filename, (clState.plugintype == CWDROPINCOMPILERTYPE) ? "treating as source text" : "passing unknown file to linker" ); } if (isGenerated) flags = kIgnored; } else if (!isGenerated && (flags & kIgnored) && !optsCompiler.compileIgnored) { if ((!optsCmdLine.stages || (optsCmdLine.stages & (CmdLineStageMask_Cg | CmdLineStageMask_Ds))) && (optsCompiler.forcePrecompile != 1)) CLReportWarning(CLStr28, filename); else flags &= ~kIgnored; } if (optsCompiler.compileIgnored && !isGenerated) flags &= ~kIgnored; if (clState.pluginDebug) { CLPrint("Using plugin '%s' for '%s'\n", Plugin_GetDropInName(plugin), filename); CLPrint( "[flags: %s, %s, %s, %s]\n", (flags & kPrecompile) ? "precompile" : "don't precompile", (flags & kLaunchable) ? "launchable" : "not launchable", (flags & kRsrcfile) ? "resource file" : "not resource file", (flags & kIgnored) ? "ignored" : "used" ); } } else { CLReportError(CLStr74, filename); flags = kIgnored; } file = File_New(); if (!file) return cwErrOutOfMemory; Deps_Initialize(&file->deps, &gTarg->incls); file->segnum = (entry->segment == -1) ? (Segments_Count(&gTarg->linkage.segs) - 1) : entry->segment; strcpy(file->srcfilename, filename); file->srcfss = fss; OS_GetFileTime(&file->srcfss, NULL, &file->srcmoddate); OS_GetTime(&file->outmoddate); file->outfilename[0] = 0; memset(&file->outfss, 0, sizeof(file->outfss)); file->outfileowner = 0; file->tempOnDisk = 0; file->wroteToDisk = 0; file->writeToDisk = 0; if (plugin && Plugin_GetPluginType(plugin) != CWDROPINCOMPILERTYPE) file->compiler = NULL; else file->compiler = plugin; file->filetype = filetype; file->mappingflags = flags; if (file->compiler) { df = Plugin_GetDropInFlags(file->compiler); file->dropinflags = df->dropinflags; } else { file->dropinflags = 0; } file->weakimport = entry->weakimport; file->initbefore = entry->initbefore; file->mergeintooutput = entry->mergeintooutput; file->isresourcefile = (flags & kRsrcfile) != 0; if (file->compiler) file->objectflags = Plugin_CL_GetObjectFlags(file->compiler)->flags; else file->objectflags = 0; file->sourceUsage = 0; if (!(file->mappingflags & kIgnored)) { if (file->compiler) { file->sourceUsage |= CmdLineStageMask_Pp; if (!(file->objectflags & 0x80000000)) file->sourceUsage |= CmdLineStageMask_Cg; } else if (plugin) { file->sourceUsage |= CmdLineStageMask_Cg; } } if (file->isresourcefile) file->sourceUsage |= CmdLineStageMask_Cg; file->objectUsage = file->sourceUsage & CmdLineStageMask_Pp; if ((file->sourceUsage & CmdLineStageMask_Pp) && !(file->mappingflags & kPrecompile) && (optsCompiler.forcePrecompile != 1) && (file->objectflags & 0x80000000)) file->objectUsage |= CmdLineStageMask_Cg; *whichfile = 0; if ((entry->position != -1) ? (Files_AddFile(&gTarg->files, file) == 0) : (Files_InsertFile(&gTarg->files, file, entry->position) == 0)) return cwErrRequestFailed; *whichfile = file->filenum; context->numFiles++; if (gTarg->linkmodel == LinkModel2) { ovg = Overlays_GetOvlGroup( &gTarg->linkage.overlays, (entry->overlayGroup == -1) ? (Overlays_CountGroups(&gTarg->linkage.overlays) - 1) : entry->overlayGroup); if (ovg) { oly = OvlGroup_GetOverlay( ovg, (entry->overlay == -1) ? (OvlGroup_CountOverlays(ovg) - 1) : entry->overlay); if (oly) { if (!Overlay_AddFile(oly, file->filenum, &idx)) return cwErrRequestFailed; } else { return cwErrRequestFailed; } } else { return cwErrRequestFailed; } } return cwNoErr; } CWResult UCBCreateNewTextDocument(CWPluginContext context, const CWNewTextDocumentInfo *docinfo) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBCreateNewTextDocument"); if (context->pluginType == CWDROPINCOMPILERTYPE || context->pluginType == CWDROPINLINKERTYPE) { if (!docinfo->documentname) { CWCompilerLinkerContext *clcontext = static_cast(context); File *file = Files_GetFile(&gTarg->files, clcontext->whichfile); if (!file) return cwErrUnknownFile; if (file->textdata) { if (!ShowHandle(file->textdata, GetHandleSize(file->textdata), 1)) return cwErrRequestFailed; DisposeHandle(file->textdata); } UCBSecretDetachHandle(context, docinfo->text, &file->textdata); OS_GetTime(&file->outmoddate); return cwNoErr; } else { Handle texth; UCBSecretDetachHandle(context, docinfo->text, &texth); UInt32 size = GetHandleSize(texth); if (strcmp(docinfo->documentname, ">stdout") || clState.stdout_base) { FILE *stdfile; if (!strcmp(docinfo->documentname, ">stdout")) { stdfile = clState.stdout_written ? fopen(clState.stdout_base, "at") : fopen(clState.stdout_base, "wt"); clState.stdout_written = 1; } else { stdfile = fopen(docinfo->documentname, "wt"); } if (stdfile) { HLock(texth); fwrite(*texth, size, 1, stdfile); fclose(stdfile); HUnlock(texth); return cwNoErr; } } if (!ShowHandle(texth, size, 0)) return cwErrRequestFailed; else return cwNoErr; } } else if (context->pluginType == CWDROPINPARSERTYPE) { Str255 filename; VFile *vf; Handle texth; FSSpec fss; CWNewProjectEntryInfo entry; SInt32 pos; UCBSecretDetachHandle(context, docinfo->text, &texth); if (docinfo->markDirty) { if (!docinfo->documentname) return cwErrInvalidParameter; vf = VFile_New(docinfo->documentname, texth); if (!vf) return cwErrOutOfMemory; if (!VFiles_Add(&gTarg->virtualFiles, vf)) return cwErrRequestFailed; entry.overlay = -1; entry.overlayGroup = -1; entry.segment = -1; entry.position = -1; entry.groupPath = NULL; entry.initbefore = 0; entry.weakimport = 0; entry.mergeintooutput = 0; c2pstrcpy(filename, docinfo->documentname); FSMakeFSSpec(0, 0, filename, &fss); return UCBAddProjectEntry(context, &fss, 1, &entry, &pos); } else { if (ShowHandle(texth, GetHandleSize(texth), docinfo->documentname != NULL)) return cwNoErr; else return cwErrRequestFailed; } } else { DO_INTERNAL_ERROR(1755, "Cannot deal with unexpected document"); return cwErrInvalidCallback; } } CWResult UCBAllocateMemory(CWPluginContext context, SInt32 size, Boolean isPermanent, void **ptr) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBAllocateMemory"); *ptr = xmalloc(NULL, size); return (*ptr == NULL) ? cwErrRequestFailed : cwNoErr; } CWResult UCBFreeMemory(CWPluginContext context, void *ptr, Boolean isPermanent) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBFreeMemory"); if (ptr) { xfree(ptr); return cwNoErr; } else { return cwErrRequestFailed; } } CWResult UCBAllocMemHandle(CWPluginContext context, SInt32 size, Boolean useTempMemory, CWMemHandle *memhandle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBAllocMemHandle"); Handle handle = NewHandle(size); if (!handle) return cwErrOutOfMemory; UCBSecretAttachHandle(context, handle, memhandle); return cwNoErr; } CWResult UCBFreeMemHandle(CWPluginContext context, CWMemHandle memhandle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBFreeMemHandle"); Handle handle; UCBSecretDetachHandle(context, memhandle, &handle); DisposeHandle(handle); return cwNoErr; } CWResult UCBGetMemHandleSize(CWPluginContext context, CWMemHandle memhandle, SInt32 *size) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBGetMemHandleSize"); Handle handle; UCBSecretDetachHandle(context, memhandle, &handle); *size = GetHandleSize(handle); return cwNoErr; } CWResult UCBResizeMemHandle(CWPluginContext context, CWMemHandle memhandle, SInt32 newSize) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBResizeMemHandle"); Handle handle; UCBSecretDetachHandle(context, memhandle, &handle); SetHandleSize(handle, newSize); return (MemError() == noErr) ? cwNoErr : cwErrOutOfMemory; } CWResult UCBLockMemHandle(CWPluginContext context, CWMemHandle handle, Boolean moveHi, void **ptr) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBLockMemHandle"); HLock(reinterpret_cast(handle)); *ptr = *reinterpret_cast(handle); return cwNoErr; } CWResult UCBUnlockMemHandle(CWPluginContext context, CWMemHandle handle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBUnlockMemHandle"); HUnlock(reinterpret_cast(handle)); return cwNoErr; } CWResult UCBGetTargetName(CWPluginContext context, char *name, short maxLength) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBGetTargetName"); strncpy(name, "command-line target", maxLength); return cwNoErr; } CWResult UCBPreDialog(CWPluginContext context) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBPreDialog"); return cwNoErr; } CWResult UCBPostDialog(CWPluginContext context) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBPostDialog"); return cwNoErr; } CWResult UCBPreFileAction(CWPluginContext context, const CWFileSpec *theFile) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBPreFileAction"); DO_INTERNAL_ERROR(1963, "UCBPreFileAction not implemented"); return cwErrRequestFailed; } CWResult UCBPostFileAction(CWPluginContext context, const CWFileSpec *theFile) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBPostFileAction"); DO_INTERNAL_ERROR(1977, "UCBPostFileAction not implemented"); return cwErrRequestFailed; } CWResult UCBCacheAccessPathList(CWPluginContext context) { IDEAccessPathList *apl; shellContextType *sc; int x; sc = static_cast(context->shellContext); if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBCacheAccessPathList"); apl = context->accessPathList; if (!apl) apl = context->accessPathList = static_cast(calloc(sizeof(IDEAccessPathList), 1)); if (sc->userAccessPathsChanged || !apl->userPaths) { OSSpec spec; Path *path; IDEAccessPath *ap; apl->userPathCount = Paths_Count(&gTarg->userPaths); apl->userPaths = static_cast(xrealloc("access paths", apl->userPaths, sizeof(IDEAccessPath) * apl->userPathCount)); for (x = 0; x < apl->userPathCount; x++) { ap = &apl->userPaths[x]; path = Paths_GetPath(&gTarg->userPaths, x); OS_ASSERT(2010, path); OS_MakeSpecWithPath(path->spec, NULL, 0, &spec); OS_OSSpec_To_FSSpec(&spec, &ap->pathSpec); ap->recursive = path->recursive != 0; if (path->recursive) { ap->subdirectoryCount = Paths_CountRecurse(path->recursive); if (ap->subdirectories) xfree(ap->subdirectories); ap->subdirectories = static_cast(xmalloc(NULL, sizeof(FSSpec) * ap->subdirectoryCount)); Paths_CopyRecurseFSS(ap->subdirectories, path->recursive, ap->subdirectoryCount); } else { ap->subdirectoryCount = 0; ap->subdirectories = NULL; } } sc->userAccessPathsChanged = 0; } if (sc->systemAccessPathsChanged || !apl->systemPaths) { OSSpec spec; Path *path; IDEAccessPath *ap; apl->systemPathCount = Paths_Count(&gTarg->sysPaths); apl->systemPaths = static_cast(xrealloc("access paths", apl->systemPaths, sizeof(IDEAccessPath) * apl->systemPathCount)); for (x = 0; x < apl->systemPathCount; x++) { ap = &apl->systemPaths[x]; path = Paths_GetPath(&gTarg->sysPaths, x); OS_ASSERT(2044, path); OS_MakeSpecWithPath(path->spec, NULL, 0, &spec); OS_OSSpec_To_FSSpec(&spec, &ap->pathSpec); ap->recursive = path->recursive != 0; if (path->recursive) { ap->subdirectoryCount = Paths_CountRecurse(path->recursive); if (ap->subdirectories) xfree(ap->subdirectories); ap->subdirectories = static_cast(xmalloc(NULL, sizeof(FSSpec) * ap->subdirectoryCount)); Paths_CopyRecurseFSS(ap->subdirectories, path->recursive, ap->subdirectoryCount); } else { ap->subdirectoryCount = 0; ap->subdirectories = NULL; } } sc->systemAccessPathsChanged = 0; } return cwNoErr; } CWResult UCBSecretAttachHandle(CWPluginContext context, Handle handle, CWMemHandle *memHandle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBSecretAttachHandle"); *memHandle = reinterpret_cast(handle); return cwNoErr; } CWResult UCBSecretDetachHandle(CWPluginContext context, CWMemHandle memHandle, Handle *handle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBSecretDetachHandle"); if (!memHandle || !handle) { *handle = NULL; return cwErrInvalidParameter; } else { *handle = reinterpret_cast(memHandle); return cwNoErr; } } CWResult UCBSecretPeekHandle(CWPluginContext context, CWMemHandle memHandle, Handle *handle) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBSecretPeekHandle"); if (!memHandle || !handle) { *handle = NULL; return cwErrInvalidParameter; } else { *handle = reinterpret_cast(memHandle); return cwNoErr; } } CWResult UCBCheckoutLicense(CWPluginContext context, const char *a, const char *b, SInt32 c, void *d, SInt32 *cookiePtr) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBCheckoutLicense"); if (cookiePtr) *cookiePtr = 0xD0A; return cwErrInvalidCallback; } CWResult UCBCheckinLicense(CWPluginContext context, SInt32 cookie) { if (optsCmdLine.verbose > 3) CLPrint("Callback: %s\n", "UCBCheckinLicense"); return cwErrInvalidCallback; } CWResult UCBResolveRelativePath(CWPluginContext context, const CWRelativePath *relativePath, CWFileSpec *fileSpec, Boolean create) { DO_INTERNAL_ERROR(2255, "UCBResolveRelativePath not implemented"); return cwErrRequestFailed; } CWResult UCBMacOSErrToCWResult(CWPluginContext context, OSErr err) { if (optsCmdLine.verbose > 4) CLPrint("Callback: %s\n", "UCBMacOSErrToCWResult"); return OSErrtoCWResult(err); } CW_BasePluginCallbacks sBasePluginCallbacks = { UCBGetFileInfo, UCBFindAndLoadFile, UCBGetFileText, UCBReleaseFileText, UCBGetSegmentInfo, UCBGetOverlay1GroupInfo, UCBGetOverlay1Info, UCBGetOverlay1FileInfo, UCBReportMessage, UCBAlert, UCBShowStatus, UCBUserBreak, UCBGetNamedPreferences, UCBStorePluginData, UCBGetPluginData, UCBSetModDate, UCBAddProjectEntry, UCBCreateNewTextDocument, UCBAllocateMemory, UCBFreeMemory, UCBAllocMemHandle, UCBFreeMemHandle, UCBGetMemHandleSize, UCBResizeMemHandle, UCBLockMemHandle, UCBUnlockMemHandle, reinterpret_cast(UCBSecretAttachHandle), reinterpret_cast(UCBSecretDetachHandle), reinterpret_cast(UCBSecretPeekHandle), NULL, NULL, NULL, NULL, NULL, UCBGetTargetName, UCBCacheAccessPathList, UCBPreDialog, UCBPostDialog, UCBPreFileAction, UCBPostFileAction, UCBCheckoutLicense, UCBCheckinLicense, UCBResolveRelativePath }; static CWIDEInfo sIDEInfo = { 3, 3, 0, 0, 10 }; CWPluginPrivateContext::CWPluginPrivateContext(SInt32 thePluginType, SInt32 totalSize) { if (totalSize <= 0) totalSize = sizeof(CWPluginPrivateContext); memset(this, 0, totalSize); shellSignature = CWFOURCHAR('C','W','I','E'); pluginType = thePluginType; shellInfo = &sIDEInfo; callbacks = &sBasePluginCallbacks; } CWPluginPrivateContext::~CWPluginPrivateContext() { int x; if (accessPathList) { if (accessPathList->userPathCount) { for (x = 0; x < accessPathList->userPathCount; x++) { if (accessPathList->userPaths[x].subdirectories) xfree(accessPathList->userPaths[x].subdirectories); } } if (accessPathList->systemPathCount) { for (x = 0; x < accessPathList->systemPathCount; x++) { if (accessPathList->systemPaths[x].subdirectories) xfree(accessPathList->systemPaths[x].subdirectories); } } xfree(accessPathList->userPaths); xfree(accessPathList->systemPaths); xfree(accessPathList); accessPathList = NULL; } }