#include "plugin_internal.h" // Forward declarations CWResult OSErrtoCWResult(OSErr err); static Boolean ValidateContext(CWPluginContext context) { return context && (context->shellSignature == CWFOURCHAR('C','W','I','E')) && (context->request != reqInitialize) && (context->request != reqTerminate) && (context->request != reqIdle); } static Boolean ValidateInitTermContext(CWPluginContext context) { return context && (context->shellSignature == CWFOURCHAR('C','W','I','E')) && ((context->request == reqInitialize) || (context->request == reqTerminate) || (context->request == reqIdle)); } static Boolean IsVCSContext(CWPluginContext context) { return context && (context->pluginType == CWDROPINVCSTYPE); } CW_CALLBACK CWGetPluginRequest(CWPluginContext context, SInt32 *request) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (request == NULL) return cwErrInvalidParameter; *request = context->request; return cwNoErr; } CW_CALLBACK CWGetAPIVersion(CWPluginContext context, SInt32 *version) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (version == NULL) return cwErrInvalidParameter; *version = context->apiVersion; return cwNoErr; } CW_CALLBACK CWGetIDEInfo(CWPluginContext context, CWIDEInfo *info) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (info == NULL) return cwErrInvalidParameter; *info = *context->shellInfo; return cwNoErr; } CW_CALLBACK CWGetCallbackOSError(CWPluginContext context, CWOSResult *error) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (error == NULL) return cwErrInvalidParameter; *error = context->callbackOSError; return cwNoErr; } CW_CALLBACK CWSetPluginOSError(CWPluginContext context, CWOSResult error) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; context->pluginOSError = error; return cwNoErr; } CW_CALLBACK CWGetProjectFile(CWPluginContext context, CWFileSpec *projectSpec) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (projectSpec == NULL) return cwErrInvalidParameter; *projectSpec = context->projectFile; return cwNoErr; } CW_CALLBACK CWGetTargetDataDirectory(CWPluginContext context, CWFileSpec *targetDataDirectorySpec) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (targetDataDirectorySpec == NULL) return cwErrInvalidParameter; if (context->targetDataDirectorySpec == NULL) return cwErrInvalidCallback; *targetDataDirectorySpec = *context->targetDataDirectorySpec; return cwNoErr; } CW_CALLBACK CWGetTargetName(CWPluginContext context, char *name, short maxLength) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (context->apiVersion >= 8) return context->callbacks->cbGetTargetName(context, name, maxLength); else return cwErrRequestFailed; } CW_CALLBACK CWGetProjectFileCount(CWPluginContext context, SInt32 *count) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (count == NULL) return cwErrInvalidParameter; *count = context->numFiles; return cwNoErr; } CW_CALLBACK CWGetOutputFileDirectory(CWPluginContext context, CWFileSpec *outputFileDirectory) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (outputFileDirectory == NULL) return cwErrInvalidParameter; *outputFileDirectory = context->outputFileDirectory; return cwNoErr; } CW_CALLBACK CWGetOverlay1GroupsCount(CWPluginContext context, SInt32 *count) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (count == NULL) return cwErrInvalidParameter; *count = context->numOverlayGroups; return cwNoErr; } CW_CALLBACK CWGetFileInfo(CWPluginContext context, SInt32 whichfile, Boolean checkFileLocation, CWProjectFileInfo *fileinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (fileinfo == NULL) return cwErrInvalidParameter; return context->callbacks->cbGetFileInfo(context, whichfile, checkFileLocation, fileinfo); } CW_CALLBACK CWFindAndLoadFile(CWPluginContext context, const char *filename, CWFileInfo *fileinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (filename == NULL) return cwErrInvalidParameter; if (fileinfo == NULL) return cwErrInvalidParameter; return context->callbacks->cbFindAndLoadFile(context, filename, fileinfo); } static CWResult EnsureCachedAccessPaths(CWPluginContext context) { if (!context->accessPathList) { CWResult res = context->callbacks->cbCacheAccessPathList(context); if (res) return res; if (!context->accessPathList) return cwErrRequestFailed; } return cwNoErr; } CW_CALLBACK CWGetAccessPathListInfo(CWPluginContext context, CWAccessPathListInfo *pathListInfo) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (pathListInfo == NULL) return cwErrInvalidParameter; if (context->apiVersion < 10) return cwErrInvalidCallback; CWResult res = EnsureCachedAccessPaths(context); if (res) return res; pathListInfo->systemPathCount = context->accessPathList->systemPathCount; pathListInfo->userPathCount = context->accessPathList->userPathCount; pathListInfo->alwaysSearchUserPaths = context->accessPathList->alwaysSearchUserPaths; pathListInfo->convertPaths = context->accessPathList->convertPaths; return cwNoErr; } CW_CALLBACK CWGetAccessPathInfo(CWPluginContext context, CWAccessPathType pathType, SInt32 whichPath, CWAccessPathInfo *pathInfo) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (pathInfo == NULL) return cwErrInvalidParameter; if (context->apiVersion < 10) return cwErrInvalidCallback; CWResult res = EnsureCachedAccessPaths(context); if (res) return res; IDEAccessPath *paths; SInt32 count; switch (pathType) { case cwSystemPath: paths = context->accessPathList->systemPaths; count = context->accessPathList->systemPathCount; break; case cwUserPath: paths = context->accessPathList->userPaths; count = context->accessPathList->userPathCount; break; default: return cwErrInvalidParameter; } if (whichPath < 0 || whichPath >= count) return cwErrInvalidParameter; IDEAccessPath *path = &paths[whichPath]; pathInfo->pathSpec = path->pathSpec; pathInfo->recursive = path->recursive; pathInfo->subdirectoryCount = path->subdirectoryCount; return cwNoErr; } CW_CALLBACK CWGetAccessPathSubdirectory(CWPluginContext context, CWAccessPathType pathType, SInt32 whichPath, SInt32 whichSubdirectory, CWFileSpec *subdirectory) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (subdirectory == NULL) return cwErrInvalidParameter; if (context->apiVersion < 10) return cwErrInvalidCallback; CWResult res = EnsureCachedAccessPaths(context); if (res) return res; IDEAccessPath *paths; SInt32 count; switch (pathType) { case cwSystemPath: paths = context->accessPathList->systemPaths; count = context->accessPathList->systemPathCount; break; case cwUserPath: paths = context->accessPathList->userPaths; count = context->accessPathList->userPathCount; break; default: return cwErrInvalidParameter; } if (whichPath < 0 || whichPath >= count) return cwErrInvalidParameter; IDEAccessPath *path = &paths[whichPath]; if (whichSubdirectory < 0 || whichSubdirectory >= path->subdirectoryCount) return cwErrInvalidParameter; *subdirectory = path->subdirectories[whichSubdirectory]; return cwNoErr; } CW_CALLBACK CWGetFileText(CWPluginContext context, const CWFileSpec *filespec, const char **text, SInt32 *textLength, short *filedatatype) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (!filespec) return cwErrInvalidParameter; if (!text) return cwErrInvalidParameter; if (!textLength) return cwErrInvalidParameter; if (!filedatatype) return cwErrInvalidParameter; return context->callbacks->cbGetFileText(context, filespec, text, textLength, filedatatype); } CW_CALLBACK CWReleaseFileText(CWPluginContext context, const char *text) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (text) return context->callbacks->cbReleaseFileText(context, text); else return cwNoErr; } CW_CALLBACK CWGetSegmentInfo(CWPluginContext context, SInt32 whichsegment, CWProjectSegmentInfo *segmentinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!segmentinfo) return cwErrInvalidParameter; return context->callbacks->cbGetSegmentInfo(context, whichsegment, segmentinfo); } CW_CALLBACK CWGetOverlay1GroupInfo(CWPluginContext context, SInt32 whichgroup, CWOverlay1GroupInfo *groupinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!groupinfo) return cwErrInvalidParameter; return context->callbacks->cbGetOverlay1GroupInfo(context, whichgroup, groupinfo); } CW_CALLBACK CWGetOverlay1Info(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, CWOverlay1Info *overlayinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!overlayinfo) return cwErrInvalidParameter; return context->callbacks->cbGetOverlay1Info(context, whichgroup, whichoverlay, overlayinfo); } CW_CALLBACK CWGetOverlay1FileInfo(CWPluginContext context, SInt32 whichgroup, SInt32 whichoverlay, SInt32 whichoverlayfile, CWOverlay1FileInfo *fileinfo) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!fileinfo) return cwErrInvalidParameter; return context->callbacks->cbGetOverlay1FileInfo(context, whichgroup, whichoverlay, whichoverlayfile, fileinfo); } CW_CALLBACK CWReportMessage(CWPluginContext context, const CWMessageRef *msgRef, const char *line1, const char *line2, short errorlevel, SInt32 errorNumber) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbReportMessage(context, msgRef, line1, line2, errorlevel, errorNumber); } CW_CALLBACK CWAlert(CWPluginContext context, const char *msg1, const char *msg2, const char *msg3, const char *msg4) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbAlert(context, msg1, msg2, msg3, msg4); } CW_CALLBACK CWShowStatus(CWPluginContext context, const char *line1, const char *line2) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbShowStatus(context, line1, line2); } CW_CALLBACK CWUserBreak(CWPluginContext context) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbUserBreak(context); } CW_CALLBACK CWGetNamedPreferences(CWPluginContext context, const char *prefsname, CWMemHandle *prefsdata) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (!prefsname) return cwErrInvalidParameter; if (!prefsdata) return cwErrInvalidParameter; return context->callbacks->cbGetNamedPreferences(context, prefsname, prefsdata); } CW_CALLBACK CWStorePluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle prefsdata) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbStorePluginData(context, whichfile, type, prefsdata); } CW_CALLBACK CWGetPluginData(CWPluginContext context, SInt32 whichfile, CWDataType type, CWMemHandle *prefsdata) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbGetPluginData(context, whichfile, type, prefsdata); } CW_CALLBACK CWSetModDate(CWPluginContext context, const CWFileSpec *filespec, CWFileTime *moddate, Boolean isGenerated) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!filespec) return cwErrInvalidParameter; return context->callbacks->cbSetModDate(context, filespec, moddate, isGenerated); } CW_CALLBACK CWAddProjectEntry(CWPluginContext context, const CWFileSpec *fileSpec, Boolean isGenerated, const CWNewProjectEntryInfo *projectEntryInfo, SInt32 *whichfile) { if (IsVCSContext(context) || !ValidateContext(context)) return cwErrInvalidParameter; if (!fileSpec) return cwErrInvalidParameter; if (context->apiVersion < 8) return cwErrRequestFailed; return context->callbacks->cbAddProjectEntry(context, fileSpec, isGenerated, projectEntryInfo, whichfile); } CW_CALLBACK CWCreateNewTextDocument(CWPluginContext context, const CWNewTextDocumentInfo *docinfo) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (!docinfo) return cwErrInvalidParameter; return context->callbacks->cbCreateNewTextDocument(context, docinfo); } CW_CALLBACK CWAllocateMemory(CWPluginContext context, SInt32 size, Boolean isPermanent, void **ptr) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (!ptr) return cwErrInvalidParameter; return context->callbacks->cbAllocateMemory(context, size, isPermanent, ptr); } CW_CALLBACK CWFreeMemory(CWPluginContext context, void *ptr, Boolean isPermanent) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (!ptr) return cwNoErr; return context->callbacks->cbFreeMemory(context, ptr, isPermanent); } CW_CALLBACK CWAllocMemHandle(CWPluginContext context, SInt32 size, Boolean useTempMemory, CWMemHandle *handle) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (!handle) return cwErrInvalidParameter; return context->callbacks->cbAllocMemHandle(context, size, useTempMemory, handle); } CW_CALLBACK CWFreeMemHandle(CWPluginContext context, CWMemHandle handle) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbFreeMemHandle(context, handle); } CW_CALLBACK CWGetMemHandleSize(CWPluginContext context, CWMemHandle handle, SInt32 *size) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (!size) return cwErrInvalidParameter; return context->callbacks->cbGetMemHandleSize(context, handle, size); } CW_CALLBACK CWResizeMemHandle(CWPluginContext context, CWMemHandle handle, SInt32 newSize) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbResizeMemHandle(context, handle, newSize); } CW_CALLBACK CWLockMemHandle(CWPluginContext context, CWMemHandle handle, Boolean moveHi, void **ptr) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; if (!ptr) return cwErrInvalidParameter; return context->callbacks->cbLockMemHandle(context, handle, moveHi, ptr); } CW_CALLBACK CWUnlockMemHandle(CWPluginContext context, CWMemHandle handle) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbUnlockMemHandle(context, handle); } CW_CALLBACK CWDonePluginRequest(CWPluginContext, CWResult resultCode) { return resultCode; } CW_CALLBACK CWPreDialog(CWPluginContext context) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbPreDialog(context); } CW_CALLBACK CWPostDialog(CWPluginContext context) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbPostDialog(context); } CW_CALLBACK CWPreFileAction(CWPluginContext context, const CWFileSpec *theFile) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbPreFileAction(context, theFile); } CW_CALLBACK CWPostFileAction(CWPluginContext context, const CWFileSpec *theFile) { if (!ValidateContext(context)) return cwErrInvalidParameter; return context->callbacks->cbPostFileAction(context, theFile); } CW_CALLBACK CWCheckoutLicense(CWPluginContext context, const char *featureName, const char *licenseVersion, SInt32 flags, void *reserved, SInt32 *cookie) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbCheckoutLicense(context, featureName, licenseVersion, flags, reserved, cookie); } CW_CALLBACK CWCheckinLicense(CWPluginContext context, SInt32 cookie) { if (!ValidateContext(context) && !ValidateInitTermContext(context)) return cwErrInvalidParameter; return context->callbacks->cbCheckinLicense(context, cookie); } CW_CALLBACK CWResolveRelativePath(CWPluginContext context, const CWRelativePath *relativePath, CWFileSpec *fileSpec, Boolean create) { if (!ValidateContext(context)) return cwErrInvalidParameter; if (relativePath == NULL) return cwErrInvalidParameter; if (fileSpec == NULL) return cwErrInvalidParameter; return context->callbacks->cbResolveRelativePath(context, relativePath, fileSpec, create); } CW_CALLBACK CWMacOSErrToCWResult(CWPluginContext context, OSErr err) { return OSErrtoCWResult(err); } CWResult OSErrtoCWResult(OSErr err) { switch (err) { case noErr: return cwNoErr; case userCanceledErr: return cwErrUserCanceled; case paramErr: return cwErrInvalidParameter; case memFullErr: return cwErrOutOfMemory; case fnfErr: return cwErrFileNotFound; default: return cwErrRequestFailed; } }