home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-01 | 18.0 KB | 885 lines | [TEXT/CWIE] |
- #define __NO_LOCATION_MACROS__
- #ifndef __EXCEPTIONS__
- #include "Exceptions.h"
- #endif
- #ifndef __DEBUGWRITE__
- #include "DebugWrite.h"
- #endif
- #ifndef __AEEXTRAS__
- #include "AEExtras.h"
- #endif
- #ifndef __STRINGUTILS__
- #include "StringUtils.h"
- #endif
-
- #ifndef __OSA__
- #include <OSA.h>
- #endif
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
- #ifndef __KEYUTILS__
- #include "KeyUtils.h"
- #endif
-
- #include <string.h>
-
- //------------------------------------------------------------------------------
-
- #if qDebug
- bool Exception::gBreakOnThrow = false;
- bool Exception::gLogExceptions = false;
- #endif
-
- Exception::ReportExceptionProcPtr Exception::gReportProc = nil;
-
- //------------------------------------------------------------------------------
-
- void LocationInCode::AppendToString(Str255& str) const
- {
- Str15 line;
-
- NumToString(fLineNum, line);
-
- cpstrcat(str, fFileName);
- pstrcat(str, "\p, line ");
- pstrcat(str, line);
-
- #if 0
- unsigned char tmpBuf[kErrorBufferSize];
- unsigned char length;
-
- // since this is debug only, hard coded strings are acceptable.
- memset(fErrorString,0,kErrorBufferSize);
-
- // make a nice error message from the info we get…
- strcpy((char *)fErrorString,"•Assertion Failed• Source File: ");
- if(fileName)
- strcat((char *)fErrorString,fileName);
- strcat((char *)fErrorString," | Line Number: ");
- NumToString(lineNum,tmpBuf);
- BlockMove(tmpBuf+1,fErrorString+strlen((char *)fErrorString),tmpBuf[0]);
- strcat((char *)fErrorString,"•");
-
- // REVIEW: This might be a nice place to add Macsbug data - AD
-
- // perform a dirty C to P string conversion…
- length = strlen((char *)fErrorString);
- if(length){
- BlockMove(fErrorString,fErrorString+1,length);
- }
- fErrorString[0] = length;
- #endif
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::IsFatal(void) const
- {
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::IsSilent(void) const
- {
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::AboutToThrow(void) const
- {
- if (qDebug)
- {
- if (BreakOnThrow() || KeyIsDown(kCapsLockKeyCode))
- {
- Str255 msg;
-
- SysBreakFunc("\pError thrown: ");
- GetErrorString(msg);
- SysBreakFunc(msg);
- Debugger();
- }
- else if (LogExceptions())
- {
- DebugWrite("\pthrowing ");
- Log();
- }
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSErr Exception::GetOSErr(void) const
- {
- OSStatus status = GetStatus();
-
- if (status <= SHRT_MAX && status >= SHRT_MIN)
- {
- return (OSErr) status;
- }
- else
- {
- return eGeneralErr;
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus Exception::GetStatus(void) const
- {
- return fStatus;
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus Exception::SetStatus(OSStatus status)
- {
- OSStatus oldStatus = fStatus;
-
- fStatus = status;
-
- return oldStatus;
- }
-
- //------------------------------------------------------------------------------
-
- /*
- long Exception::GetMessage(void) const
- {
- return 0;
- }
-
- //------------------------------------------------------------------------------
-
- long Exception::SetMessage(long message)
- {
- return 0;
- }
- */
-
- //------------------------------------------------------------------------------
-
- bool Exception::GetErrorMessage(AEDesc& msg) const
- {
- Str255 str;
-
- bool result = this->GetErrorString(str);
-
- if (result)
- {
- GetLocationInCode().LogIfErr(AECreateDesc(typeChar, &str[1], str[0], &msg));
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::GetErrorString(Str255& msg) const
- {
- NumToString(this->GetStatus(), msg);
-
- pstrcat(msg, "\p (");
- fThrowPoint.AppendToString(msg);
- pstrcat(msg, "\p)");
-
- return true;
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::Log() const
- {
- Str255 message; message[0] = '\0';
-
- fThrowPoint.AppendToString(message);
-
- DebugWrite("\perror ");
- DebugWriteNum(fStatus);
- DebugWrite("\p ");
- DebugWriteLn(message);
-
- fThrowPoint.LogIfErr(GetStatus());
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::Report() const
- {
- if (gReportProc != nil)
- {
- (*gReportProc)(*this);
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSErr Exception::GetAEParams(AERecord& result, bool create) const
- {
- OSErr err = noErr;
-
- // create a new record if we were passed null
-
- if (result.descriptorType == typeNull)
- {
- if (create)
- {
- err = AECreateList(nil, 0, true, &result);
- }
- else
- {
- return noErr;
- }
- }
-
- // fill in keyErrorNumber and keyErrorString if not already present
-
- if (err == noErr)
- {
- DescType typeCode;
- Size actualSize;
- long oldErr;
-
- if (AEGetParamPtr(&result, keyErrorNumber, typeLongInteger, &typeCode,
- &oldErr, sizeof(oldErr), &actualSize) != noErr
- || oldErr != noErr)
- {
- PutErrorNumber(result);
- }
-
- if (AESizeOfParam(&result, keyErrorString, &typeCode, &actualSize)
- != noErr)
- {
- PutErrorString(result);
- }
- }
-
- return err;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::PutErrorNumber(AERecord& event) const
- {
- OSStatus err = GetStatus();
-
- GetLocationInCode().LogIfErr(AEPutParamPtr(&event, keyErrorNumber, typeLongInteger, &err,
- sizeof(err)));
-
- return true;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::PutErrorString(AERecord& event) const
- {
- AEDesc desc;
-
- bool result = GetErrorMessage(desc);
-
- if (result)
- {
- GetLocationInCode().LogIfErr(::AEPutParamDesc(&event, keyErrorString, &desc));
- GetLocationInCode().LogIfErr(::AEDisposeDesc(&desc));
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::HasExpectedType() const
- {
- return HasErrorParam(kOSAErrorExpectedType);
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::PutExpectedType(
- DescType expectedType,
- DescType actualType,
- bool overwrite)
- {
- if (expectedType)
- {
- PutErrorParamPtr(kOSAErrorExpectedType,
- typeType,
- &expectedType,
- sizeof(expectedType),
- overwrite);
- }
-
- if (actualType)
- {
- PutErrorParamPtr(keyAEErrorActualType,
- typeType,
- &expectedType,
- sizeof(expectedType),
- overwrite);
- }
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::HasOffendingObject() const
- {
- return HasErrorParam(kOSAErrorOffendingObject);
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::PutOffendingObject(const AEDesc& objectSpec, bool overwrite)
- {
- PutErrorParamDesc(kOSAErrorOffendingObject, objectSpec, overwrite);
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::HasOffendingParameter() const
- {
- return HasErrorParam(kOSAErrorOffendingObject);
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::PutOffendingParameter(AEKeyword param, bool overwrite)
- {
- PutErrorParamPtr(kOSAErrorOffendingObject,
- typeKeyword,
- ¶m,
- sizeof(param),
- overwrite);
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::HasErrorParam(AEKeyword /*param*/) const
- {
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::PutErrorParamPtr(
- AEKeyword /*param*/,
- DescType /*type*/,
- const void* /*data*/,
- Size /*size*/,
- bool /*overwrite*/)
- {
- // Drop on the floor by default
- }
-
-
- //------------------------------------------------------------------------------
-
- void Exception::PutErrorParamDesc(
- AEKeyword /*param*/,
- const AEDesc& /*desc*/,
- bool /*overwrite*/)
- {
- // Drop on the floor by default
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus Exception::vStandardizeExceptions(VAProc proc, va_list arg)
- {
- StdException exc(GetLocationInCode()); // premptive exception
-
- try // Call the proc
- {
- return (*proc)(arg);
- }
- catch (Exception& err) // Exceptions are OK
- {
- throw /*err*/;
- }
- catch (char* msg)
- {
- exc.PutErrorParamPtr(keyErrorString, typeChar, msg, strlen(msg));
- }
- catch (long num)
- {
- exc.SetStatus(num);
- }
- catch (...)
- {
- }
-
- if (LogExceptions())
- {
- exc.Log();
- }
-
- exc.AboutToThrow();
-
- throw exc;
-
- return 0;
- }
-
- //------------------------------------------------------------------------------
-
- Exception::ReportExceptionProcPtr Exception::SetReportProc(ReportExceptionProcPtr newProc)
- {
- ReportExceptionProcPtr oldProc = gReportProc;
-
- gReportProc = newProc;
-
- return oldProc;
- }
-
- #if qDebug
- //------------------------------------------------------------------------------
-
- bool Exception::SetLogExceptions(bool newState)
- {
- bool oldState = gLogExceptions;
-
- gLogExceptions = newState;
-
- return oldState;
- }
-
- //------------------------------------------------------------------------------
-
- bool Exception::SetBreakOnThrow(bool newState)
- {
- bool oldState = gBreakOnThrow;
-
- gBreakOnThrow = newState;
-
- return oldState;
- }
- #endif
-
- //------------------------------------------------------------------------------
-
- OSStatus Exception::StandardizeExceptions(VAProc proc, ...)
- {
- va_list arg; va_start(arg, proc);
-
- return vStandardizeExceptions(proc, arg);
- }
-
- //------------------------------------------------------------------------------
-
- static OSStatus report_exception(va_list arg)
- {
- VA_ARG(Exception*, exc, arg);
-
- exc->Report();
-
- return 0;
- }
-
- void Exception::ReportExceptions(VAProc proc, ...)
- {
- va_list arg; va_start(arg, proc);
-
- try
- {
- GetLocationInCode().FailOSStatus(vStandardizeExceptions(proc, arg));
-
- va_end(arg);
- }
- catch (Exception& exc)
- {
- va_end(arg);
-
- StandardizeExceptions(report_exception, &exc);
-
- throw;
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSErr Exception::CatchAEErrors(AppleEvent* event, VAProc proc, ...)
- {
- va_list arg; va_start(arg, proc);
-
- OSStatus status;
-
- try
- {
- status = vStandardizeExceptions(proc, arg);
- }
- catch (Exception& exc)
- {
- status = exc.GetOSErr();
-
- if (event && event->dataHandle != nil)
- {
- if (status != errAEEventNotHandled)
- {
- // AppleScript has an undocumented "feature" where if we put
- // an error parameter in an unhandled event, it reports an
- // error rather than trying the system handlers.
-
- GetLocationInCode().LogIfErr(exc.GetAEParams(*event, false));
- }
- }
- }
-
- va_end(arg);
-
- if (status <= SHRT_MAX && status >= SHRT_MIN)
- {
- return (OSErr) status;
- }
- else
- {
- return eGeneralErr;
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus Exception::CatchOSStatus(VAProc proc, ...)
- {
- va_list arg; va_start(arg, proc);
-
- OSStatus status;
-
- try
- {
- status = vStandardizeExceptions(proc, arg);
- }
- catch (Exception& exc)
- {
- status = exc.GetStatus();
- }
-
- va_end(arg);
-
- return status;
- }
-
- //------------------------------------------------------------------------------
-
- OSErr Exception::CatchOSErrors(VAProc proc, ...)
- {
- va_list arg; va_start(arg, proc);
-
- OSStatus status;
-
- try
- {
- status = vStandardizeExceptions((VAProc) proc, arg);
- va_end(arg);
- return noErr;
- }
- catch (Exception& exc)
- {
- status = exc.GetOSErr();
- }
-
- va_end(arg);
-
- if (status <= SHRT_MAX && status >= SHRT_MIN)
- {
- return (OSErr) status;
- }
- else
- {
- return eGeneralErr;
- }
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::MakeTextDesc(AEDesc& desc, const char *cstr)
- {
- desc.descriptorType = typeNull;
- desc.dataHandle = nil;
-
- if (cstr)
- {
- GetLocationInCode().LogIfErr(AECreateDesc(typeChar, cstr, strlen(cstr), &desc));
- }
- }
-
- //------------------------------------------------------------------------------
-
- void Exception::MakeTextDesc(AEDesc& desc, ConstStr255Param pstr)
- {
- desc.descriptorType = typeNull;
- desc.dataHandle = nil;
-
- if (pstr)
- {
- GetLocationInCode().LogIfErr(AECreateDesc(typeChar, &pstr[1], pstr[0], &desc));
- }
- }
-
- //==============================================================================
-
- SilentException::~SilentException()
- {
- }
-
- //------------------------------------------------------------------------------
-
- void SilentException::Log() const
- {
- }
-
- //------------------------------------------------------------------------------
-
- void SilentException::Report() const
- {
- }
-
- //------------------------------------------------------------------------------
-
- bool SilentException::IsSilent(void) const
- {
- return true;
- }
-
- //------------------------------------------------------------------------------
-
- OSErr SilentException::GetAEParams(AERecord& /*evt*/, bool /*create*/) const
- {
- return noErr;
- }
-
- //==============================================================================
-
- StdException::StdException(const StdException& exc)
- : Exception(exc)
- {
- GetLocationInCode().LogIfErr(AEDuplicateDesc(&exc.fErrParams, &fErrParams));
- }
-
- //------------------------------------------------------------------------------
-
- /*
- StdException::StdException(
- const LocationInCode& where,
- OSStatus status,
- AEDesc* params)
- : Exception(where, status)
- {
- if (params)
- {
- fErrParams = *params;
- }
- else
- {
- params = &fErrParams;
- }
-
- params->descriptorType = typeNull;
- params->dataHandle = nil;
- }
- */
-
- //------------------------------------------------------------------------------
-
- StdException::~StdException()
- {
- GetLocationInCode().LogIfErr(AEDisposeDesc(&fErrParams));
- }
-
- //------------------------------------------------------------------------------
-
- void StdException::Log() const
- {
- Exception::Log();
-
- if (fErrParams.descriptorType != typeNull)
- {
- DebugWriteAE(&fErrParams);
- DebugWriteLn("\p", false);
- }
- }
-
- //------------------------------------------------------------------------------
-
- OSErr StdException::GetAEParams(AERecord& evt, bool create) const
- {
- OSErr err = noErr;
-
- if (create || evt.descriptorType != typeNull)
- {
- err = AECopyParams(&fErrParams, &evt, false);
-
- if (err == noErr)
- {
- err = Exception::GetAEParams(evt, create);
- }
- }
-
- return err;
- }
-
-
- //------------------------------------------------------------------------------
-
- bool StdException::GetErrorMessage(AEDesc& msg) const
- {
- OSErr err;
- bool result = (fErrParams.descriptorType != typeNull);
-
- if (result)
- {
- err = AEGetKeyDesc(&fErrParams, keyErrorString, typeWildCard, &msg);
-
- if (!(result = (err == noErr)) && err != errAEDescNotFound)
- {
- GetLocationInCode().LogIfErr(err);
- }
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- bool StdException::PutErrorString(AERecord& event) const
- {
- bool result = (fErrParams.descriptorType != typeNull);
-
- if (result)
- {
- AEDesc temp;
-
- OSErr err = AEGetKeyDesc(&fErrParams, keyErrorString, typeWildCard, &temp);
-
- if (err == noErr)
- {
- GetLocationInCode().LogIfErr(::AEPutParamDesc(&event, keyErrorString, &temp));
- }
- else
- {
- result = false;
- GetLocationInCode().LogIfNotErr(err, errAEDescNotFound);
- }
-
- AEDisposeDesc(&temp);
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- bool StdException::CanAddErrorParam(AEKeyword param, bool overwrite)
- {
- OSErr err = noErr;
-
- if (fErrParams.descriptorType == typeNull)
- {
- GetLocationInCode().LogIfErr(err = AECreateList(nil, 0, true, &fErrParams));
- }
- else if (!overwrite)
- {
- DescType actualType;
- Size actualSize;
-
- err = AESizeOfKeyDesc(&fErrParams, param, &actualType, &actualSize);
- }
-
- return (err == noErr || err == errAEDescNotFound);
- }
-
- //------------------------------------------------------------------------------
-
- bool StdException::HasErrorParam(AEKeyword param) const
- {
- OSErr err = errAENoSuchObject;
- DescType actualType;
- Size actualSize;
-
- if (fErrParams.descriptorType != typeNull)
- {
- err = AESizeOfKeyDesc(&fErrParams, param, &actualType, &actualSize);
- }
-
- return (err == noErr);
- }
-
- //------------------------------------------------------------------------------
-
- void StdException::PutErrorParamPtr(
- AEKeyword param,
- DescType type,
- const void* data,
- Size size,
- bool overwrite)
- {
- if (CanAddErrorParam(param, overwrite))
- {
- GetLocationInCode().LogIfErr(AEPutKeyPtr(&fErrParams, param, type, data, size));
- }
- }
-
- //------------------------------------------------------------------------------
-
- void StdException::PutErrorParamDesc(
- AEKeyword param,
- const AEDesc& desc,
- bool overwrite)
- {
- if (CanAddErrorParam(param, overwrite))
- {
- GetLocationInCode().LogIfErr(AEPutKeyDesc(&fErrParams, param, &desc));
- }
- }
-
-
- #if 0
- NotifyFailureProc gNotifyProc = nil;
-
- //--------------------------------------------------------------------------------
- // Install a single routine called at failure time before
- // exception processing begins. This function is used in
- // conjunction with ShowStackChain to record and later show
- // the stack at the time of failure (left over from old 68K
- // code that doesn't work too well on PowerPC).
- void SetExceptionNotifyProc(NotifyFailureProc notifyProc)
- {
- gNotifyProc = notifyProc;
- } // SetExceptionNotifyProc
-
-
- //--------------------------------------------------------------------------------
- // This routine is used by ReportError so that it knows whether or
- // not it should show the 'sc6' button
- Boolean ExceptionNotifyProcInstalled(void)
- {
- return gNotifyProc != nil;
- } // ExceptionNotifyProcInstalled
-
-
- //--------------------------------------------------------------------------------
- // Notify that an error occured
- void NotifyFailure(OSErr err)
- {
- #ifdef FAILMESSAGES
- DebugPrintf("Failure caused by an error %d", err);
- #endif
-
- // DebugStr("\pSomeone is about to fail...");
-
- if(gNotifyProc != nil)
- (*gNotifyProc)(err);
- } // NotifyFailure
-
-
- //--------------------------------------------------------------------------------
- // This routine doesn't actually do anything; it's just used
- // by the NOREGISTER macro
- void MakeVariableNoRegister( void* foo )
- {
-
- } // MakeVariableNoRegister
-
- #endif
-
-