Author: bhavani Date: Tue Jan 31 15:50:57 2012 New Revision: 1238673 URL: http://svn.apache.org/viewvc?rev=1238673&view=rev Log: UIMA-2361 implemented uima exception addParam() as a template function.
Modified: uima/uimacpp/trunk/src/framework/exceptions.cpp (contents, props changed) uima/uimacpp/trunk/src/framework/uima/exceptions.hpp (contents, props changed) Modified: uima/uimacpp/trunk/src/framework/exceptions.cpp URL: http://svn.apache.org/viewvc/uima/uimacpp/trunk/src/framework/exceptions.cpp?rev=1238673&r1=1238672&r2=1238673&view=diff ============================================================================== --- uima/uimacpp/trunk/src/framework/exceptions.cpp (original) +++ uima/uimacpp/trunk/src/framework/exceptions.cpp Tue Jan 31 15:50:57 2012 @@ -1,744 +1,678 @@ -/* -------------------------------------------------------------------------------- - - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - -------------------------------------------------------------------------------- - - -------------------------------------------------------------------------------- -*/ - -#if defined(_MSC_VER) -#include <stdio.h> -#include <eh.h> -#include <windows.h> -#include <winbase.h> -#endif - -#include "uima/pragmas.hpp" //must be included first to disable warnings -#include "uima/msg.h" -#include <string> -#include <sstream> - -#include "uima/macros.h" -#include "uima/trace.hpp" - -#include "uima/strconvert.hpp" -#include "uima/unistrref.hpp" -#include "uima/comp_ids.h" -#include "uima/exceptions.hpp" -#include "uima/msgstrtab.h" - -using namespace std; - -namespace uima { - -///Constructor with just the message id - ErrorMessage::ErrorMessage( - TyMessageId utMsgId - ) : - iv_utMsgId(utMsgId) { - if ( iv_utMsgId == 0) { - iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE; - } - } -///Constructor with a single char * parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const char * cpszParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - iv_vecParams.push_back((string)cpszParam1); - } - -///Constructor with a single string parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const string & crstrParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - iv_vecParams.push_back(crstrParam1); - } - -///Constructor with a single UChar * parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const UChar * cpuszParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - UnicodeStringRef(cpuszParam1).extract(s); // Convert to default encoding for platform - iv_vecParams.push_back(s); - } - -///Constructor with a single UnicodeString parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const icu::UnicodeString & crustrParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - UnicodeStringRef(crustrParam1).extract(s); // Convert to default encoding for platform - iv_vecParams.push_back(s); - } - -///Constructor with a single int parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - int iParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - iv_vecParams.push_back(long2String(iParam1, s)); - } - -///Constructor with a single unsigned int parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - unsigned int uiParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - iv_vecParams.push_back(long2String((int) uiParam1, s)); - } - - -///Constructor with a single long parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - long lParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - iv_vecParams.push_back(long2String(lParam1, s)); - } - -///Constructor with a single unsigned long parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - unsigned long ulParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - iv_vecParams.push_back(long2String((long) ulParam1, s)); - } - -///Constructor with a single double parameter - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const double dParam1 - ) : - iv_utMsgId(utMsgId) { - assert( iv_utMsgId != 0 ); - string s; - iv_vecParams.push_back(double2String(dParam1, s)); - } - -///Constructor with a full parameter vector - ErrorMessage::ErrorMessage( - TyMessageId utMsgId, - const vector<string> & crvecParams - ) : - iv_utMsgId(utMsgId), - iv_vecParams(crvecParams) { - assert( iv_utMsgId != 0 ); - } - - - ///add parameter to message id - void - ErrorMessage::addParam(const char * cpsz) { - iv_vecParams.push_back(cpsz); - } - ///add parameter to message id - void - ErrorMessage::addParam(const string & str) { - iv_vecParams.push_back(str); - } - ///add parameter to message id - void - ErrorMessage::addParam(const UChar * cpuszParam) { - string s; - UnicodeStringRef(cpuszParam).extract(s); // Convert to default encoding for platform - iv_vecParams.push_back(s); - } - ///add parameter to message id - void - ErrorMessage::addParam(const icu::UnicodeString & crustrParam) { - string s; - UnicodeStringRef(crustrParam).extract(s); // Convert to default encoding for platform - iv_vecParams.push_back(s); - } - - void ErrorMessage::addParam(uima::UnicodeStringRef const & crParam) { - icu::UnicodeString str(crParam.getBuffer(), crParam.length() ); - addParam(str); - } - - ///add parameter to message id - void - ErrorMessage::addParam(long l) { - string str; - convertToString(l, str); - iv_vecParams.push_back(str); - } - ///add parameter to message id - void - ErrorMessage::addParam(unsigned long ul) { - string str; - convertToString(ul, str); - iv_vecParams.push_back(str); - } - ///add parameter to message id - void - ErrorMessage::addParam(int i) { - string str; - convertToString(i, str); - iv_vecParams.push_back(str); - } - ///add parameter to message id - void - ErrorMessage::addParam(unsigned int ui) { - string str; - convertToString(ui, str); - iv_vecParams.push_back(str); - } - ///add parameter to message id - void - ErrorMessage::addParam(double d) { - string str; - convertToString(d, str); - iv_vecParams.push_back(str); - } - - /*------------------------------- Constructors -------------------------------*/ - - ErrorContext::ErrorContext( - const ErrorMessage & crclMessage, - const char* pszFilename, - const char* pszFunction, - unsigned long ulLineNumber - ): - iv_clMessage(crclMessage), - iv_pszFilename(pszFilename), - iv_pszFunction(pszFunction), - iv_ulLineNo(ulLineNumber) {} - -#ifdef OS_STL - Exception::~Exception() -#else - Exception::~Exception() UIMA_THROW0() -#endif - {} - - /*------------------------------ Output Support ------------------------------*/ - - string - ErrorMessage::asString() const { - - size_t numparams = getMessageParams().size(); - - // Check for unknown message id - if (iv_utMsgId < 0 || iv_utMsgId > UIMA_MSG_ID_SIGNATURE_END) { - return string("Unknown message id " + iv_utMsgId); - } - - //parameter substitution - - //locate message in message table - const TCHAR ** messages = gs_aszMessageStringTable; - const TCHAR * msg = messages[iv_utMsgId]; - - TCHAR * buf = new TCHAR[UIMA_MSG_MAX_STR_LEN]; - memset(buf,'\0',UIMA_MSG_MAX_STR_LEN); - - int numwritten=0; - - TCHAR * trg = buf; - while (*msg) { - if (numwritten > UIMA_MSG_MAX_STR_LEN) { - break; - } - if (*msg == UIMA_MSG_REPLACE_CHAR) { - msg = msg+1; - if (*msg == UIMA_MSG_REPLACE_CHAR) { - *trg = *msg; - trg = trg +1; - ; - msg = msg+1; - numwritten++; - } else { //replace %n with the corresponding param - unsigned long index; - int len; - string arg; - // determine the number of the specified argument ... - index = (unsigned long) atol(msg); - if (index > numparams) // param not defined - { - arg = "???"; // replace it by "dont-know" - } else { - // ... the indexed argument ... - arg = iv_vecParams[index - 1]; // zero-based array! - //assert(arg.length() > 0); - } - len = arg.length(); - // ... and then copy the argument - if (UIMA_MSG_MAX_STR_LEN-numwritten < len) { - len = UIMA_MSG_MAX_STR_LEN - numwritten; - } - if (len > 0) { - strncpy(trg, arg.c_str(), len); - trg = trg+len; - } - msg = msg+1; - while ( isdigit(*msg) ) { //handle arg number 10 or more - msg = msg+1; - } - } - } else { - *trg = *msg; - trg = trg+1; - msg = msg+1; - } - } - //cout << buf << endl; - string target(buf); - delete[] buf ; - return target; - //string target; - //target.assign(buf, UIMA_MSG_MAX_STR_LEN); // Copy the result to the string - //delete buf; - //return target; - } - - ostream & - operator << ( - ostream & os, - const ErrorMessage & errorMsg - ) { - os << errorMsg.asString(); - return(os); - } - - string - ErrorContext::asString() const { - string s; - s += getMessage().asString(); - if (getFileName() != NULL) { - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " File : " + getFileName(); - } - if (getFunctionName() != NULL) { - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " Function : " + getFunctionName(); - } - if (getLineNumber() != 0) { - string sNum; - long2String(getLineNumber(), sNum); - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " Line : " + sNum; - } - - return(s); - } - - ostream & - operator << ( - ostream & os, - const ErrorContext & errContext - ) { - os << errContext.asString(); - return (os); - } - - void ErrorMessage::reset(void) { - iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE; - iv_vecParams.clear(); - } - - /* ----------------------------------------------------------------------- */ - /* ErrorInfo */ - /* ----------------------------------------------------------------------- */ - - /*------------------------------- Statics -----------------------------------*/ -//initialize static member var to an initial value - - const char * ErrorInfo::cv_cpszContextPrefix = " While : "; - const char * ErrorInfo::cv_cpszIndent = ""; - - - /*------------------------------- Constructors -------------------------------*/ - - ErrorInfo::ErrorInfo( - const ErrorMessage & rclMessage, - TyErrorId ulErrorId, - ErrorInfo::EnSeverity enSeverity - ) : - iv_clErrorMsg(rclMessage), - iv_ulErrorId(ulErrorId), - iv_enSeverity(enSeverity), - iv_vecContexts() {} - - ErrorInfo::ErrorInfo( void ) : - iv_clErrorMsg(), - iv_ulErrorId(UIMA_ERR_NONE), - iv_enSeverity(recoverable), - iv_vecContexts() {} - - ErrorInfo::~ErrorInfo() {} - -//constructor (copy) -//? Exception::Exception( -//? const Exception& rclException -//? ) -//? { -//? } - - /*---------------------------- Exception Context ----------------------------*/ - void - ErrorInfo::addContext( const ErrorContext & crclContext ) { - iv_vecContexts.push_back(crclContext); - } - - const ErrorContext * - ErrorInfo::contextPtrAtIndex( size_t uiContextIndex ) const { - if (uiContextIndex >= iv_vecContexts.size()) { - return(NULL); - } - return(&iv_vecContexts[uiContextIndex]); - } - - /*------------------------------ Output Support ------------------------------*/ - string - ErrorInfo::asString() const { - string s; - if (getErrorId() == UIMA_ERR_NONE) { - s += string("No Error\n"); - return (s); - } - if (getErrorId() != UIMA_ERR_NONE) { - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error number : "; - string sErr; - long2String( getErrorId(), sErr); - s += sErr; - } - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Recoverable : " + (isRecoverable() ? "Yes" : "No"); - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error : " + getMessage().asString(); - for (size_t i = 0; i < contextCount(); ++i) { - s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + ErrorInfo::getGlobalErrorInfoContextPrefix(); - assert(EXISTS(contextPtrAtIndex(i))); //lint !e666: Expression with side effects passed to repeated parameter 1 in macro EXISTS - s += contextPtrAtIndex(i)->asString(); - } - s += string("\n"); - - return (s); - } - -///output support for streams - ostream & - operator << ( - ostream & os, - const ErrorInfo & errInfo - ) { - os << errInfo.asString(); - return(os); - } - - void ErrorInfo::reset(void) { - iv_clErrorMsg.reset(); - iv_ulErrorId = UIMA_ERR_NONE; - iv_enSeverity = recoverable; - iv_vecContexts.clear(); - } - - /* ----------------------------------------------------------------------- */ - /* Exception */ - /* ----------------------------------------------------------------------- */ - - Exception::Exception( - const ErrorMessage & rclMessage, - TyErrorId ulErrorId, - ErrorInfo::EnSeverity enSeverity - ) : - EXCEPTION_BASE_CLASS(), - iv_clErrorInfo(rclMessage, ulErrorId, enSeverity) {} - - Exception::Exception( - const ErrorInfo & crclErrorInfo - ) : - EXCEPTION_BASE_CLASS(), - iv_clErrorInfo(crclErrorInfo) {} - - /*------------------------------ Exception Type ------------------------------*/ - - const char * Exception::getName() const { - return(_TEXT("unspecified exception")); - } - - /*------------------------- Application Termination --------------------------*/ - void Exception::terminate() { - exit(iv_clErrorInfo.getErrorId()); //lint !e713: Loss of precision (arg. no. 1) (unsigned long to int) - } - - /*------------------------------ Throw Support -------------------------------*/ - void Exception::assertParameter( - const char* /*exceptionText*/, - ErrorContext /*context*/ ) { - assert(false); - //not tested yet (and not used anywhere!) - } - - /*------------------------- Logging Support ----------------------------------*/ - - void Exception::logExceptionData() { - util::Trace clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_EXCEPTIONS); - - clTrace.dump(_TEXT("Exception occured"), asString().c_str()); - //not implemented yet - } - - /*------------------------------ Output Support ------------------------------*/ - string - Exception::asString() const { - //output the (class) name of the exception and its error info after it. - return string("\n") + - ErrorInfo::getGlobalErrorInfoIndent() + - "Exception : " + - getName() + - "\n" + - getErrorInfo().asString() + - "\n"; - } - - - - ostream & - operator << ( - ostream & os, - const Exception & exception - ) { - //output the (class) name of the exception and its error info after it. - os << exception.asString(); - return(os); - } - - /*------------------------------ Static Method -------------------------------*/ - - // Release contents of string container allocated by asString method - - void - Exception::release(std::string & msg) { - msg.clear(); // Empty string - msg.reserve(1); // Reduce capacity so will use internal buffer & free external one - } - -//private: - /*----------------------------- Hidden Functions -----------------------------*/ - Exception& Exception::operator=( const Exception& /*exc*/ ) { - assert(false); - return(*this); //lint !e527 unreachable - } //lint !e1745: member not assigned by private assignment operator - - /* ----------------------------------------------------------------------- */ - /* Implementations of predefined exceptions */ - /* ----------------------------------------------------------------------- */ - - - /* - The following classes reimplement the ANSI standard exception hierarchy from - stdexcept.h as UIMACPP exceptions with context and message id support - */ - UIMA_EXC_CLASSIMPLEMENT(Uima_logic_error ,Exception); - UIMA_EXC_CLASSIMPLEMENT(Uima_runtime_error ,Exception); - - UIMA_EXC_CLASSIMPLEMENT(Uima_domain_error ,Uima_logic_error); - UIMA_EXC_CLASSIMPLEMENT(Uima_invalid_argument ,Uima_logic_error); - UIMA_EXC_CLASSIMPLEMENT(Uima_length_error ,Uima_logic_error); - UIMA_EXC_CLASSIMPLEMENT(Uima_out_of_range ,Uima_logic_error); - - UIMA_EXC_CLASSIMPLEMENT(Uima_range_error ,Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(Uima_overflow_error ,Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(Uima_underflow_error ,Uima_runtime_error); - - - /** - The following exceptions are used by helper test classes that are no longer in the UIMACPP library: - CommandLineDriver DocBuffer ParseHandlers - */ - UIMA_EXC_CLASSIMPLEMENT(ConsoleAbortExc ,Exception); - UIMA_EXC_CLASSIMPLEMENT(ParseHandlerExc ,Exception); - UIMA_EXC_CLASSIMPLEMENT(ExcDocBuffer ,Uima_out_of_range); - - /** code page conversion errors */ - UIMA_EXC_CLASSIMPLEMENT(CodePageConversionException, uima::Exception); - /** - The following exception is used to report failures from APR functions - */ - UIMA_EXC_CLASSIMPLEMENT(AprFailureException, Exception); - - /* - The following classes provide a starting point for an exception hierarchy - */ -//? UIMA_EXC_CLASSIMPLEMENT(ExcAssertionFailure, Exception); - UIMA_EXC_CLASSIMPLEMENT(ExcIllFormedInputError , Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(ExcInvalidParameter , Uima_invalid_argument); - UIMA_EXC_CLASSIMPLEMENT(ExcIndexOutOfRange , Uima_out_of_range); -//? UIMA_EXC_CLASSIMPLEMENT(ExcDeviceError ,Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(ExcInvalidRequest , Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(ExcResourceExhausted , Uima_runtime_error); - UIMA_EXC_CLASSIMPLEMENT(ExcOutOfMemory , ExcResourceExhausted); -//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfSystemResource, ResourceExhausted); -//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfWindowResource, ResourceExhausted); - UIMA_EXC_CLASSIMPLEMENT(ExcFileNotFoundError , Uima_runtime_error); - -// Windows specific CException - ExcWinCException::ExcWinCException( - ErrorMessage clMessage, - TyErrorId ulErrorId, - ErrorInfo::EnSeverity enSeverity - ) - : Uima_runtime_error (clMessage, ulErrorId, enSeverity) { - ; - } - - const char* - ExcWinCException :: getName() const { - return( "ExcWinCException" ); - } - - ExcWinCException::~ExcWinCException () CHILD_DESTRUCT_THROW0() { - ; - } - - ExcWinCException::ExcWinCException (const ExcWinCException & a) : Uima_runtime_error (a) { - ; - } - - - // Windows exceptions can be mapped only when compiled with MS VC++ -#if defined(_MSC_VER) - - void translation_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) { - const char * cpszMsg = NULL; - switch (u) { - case EXCEPTION_ACCESS_VIOLATION: - cpszMsg ="\"ACCESS VIOLATION\""; - break; - case EXCEPTION_DATATYPE_MISALIGNMENT: - cpszMsg ="\"DATATYPE MISALIGNMENT\""; - break; - case EXCEPTION_BREAKPOINT: - cpszMsg ="\"BREAKPOINT\""; - break; - case EXCEPTION_SINGLE_STEP: - cpszMsg ="\"SINGLE STEP\""; - break; - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - cpszMsg ="\"ARRAY BOUNDS EXCEEDED\""; - break; - case EXCEPTION_FLT_DENORMAL_OPERAND: - cpszMsg ="\"FLT DENORMAL OPERAND\""; - break; - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - cpszMsg ="\"FLT DIVIDE_BY ZERO\""; - break; - case EXCEPTION_FLT_INEXACT_RESULT: - cpszMsg ="\"FLT INEXACT_RESULT\""; - break; - case EXCEPTION_FLT_INVALID_OPERATION: - cpszMsg ="\"FLT INVALID OPERATION\""; - break; - case EXCEPTION_FLT_OVERFLOW: - cpszMsg ="\"FLT OVERFLOW\""; - break; - case EXCEPTION_FLT_STACK_CHECK: - cpszMsg ="\"FLT STACK_CHECK\""; - break; - case EXCEPTION_FLT_UNDERFLOW: - cpszMsg ="\"FLT UNDERFLOW\""; - break; - case EXCEPTION_INT_DIVIDE_BY_ZERO: - cpszMsg ="\"INT DIVIDE BY ZERO\""; - break; - case EXCEPTION_INT_OVERFLOW: - cpszMsg ="\"INT OVERFLOW\""; - break; - case EXCEPTION_PRIV_INSTRUCTION: - cpszMsg ="\"PRIV INSTRUCTION\""; - break; - case EXCEPTION_IN_PAGE_ERROR: - cpszMsg ="\"IN PAGE_ERROR\""; - break; - case EXCEPTION_ILLEGAL_INSTRUCTION: - cpszMsg ="\"ILLEGAL INSTRUCTION\""; - break; - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - cpszMsg ="\"NONCONTINUABLE EXCEPTION\""; - break; - case EXCEPTION_STACK_OVERFLOW: - cpszMsg ="\"STACK OVERFLOW\""; - break; - case EXCEPTION_INVALID_DISPOSITION: - cpszMsg ="\"INVALID DISPOSITION\""; - break; - case EXCEPTION_GUARD_PAGE: - cpszMsg ="\"GUARD PAGE\""; - break; - case EXCEPTION_INVALID_HANDLE: - cpszMsg ="\"INVALID HANDLE\""; - break; - case CONTROL_C_EXIT: - cpszMsg ="\"CONTROL C EXIT\""; - break; - default: - cpszMsg = "Unknows Windows C Exception"; - break; - } - // throw our own type of exception so we know at least what was going on - // instead of just getting an unknown ... C++ excepition - throw ExcWinCException( ErrorMessage(UIMA_MSG_ID_EXC_WINDOWS_EXCEPTION, cpszMsg), - (TyErrorId)UIMA_ERR_ENGINE_WINDOWS_EXCEPTION, - ErrorInfo::unrecoverable); - } - -#define UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS "UIMA_DONT_MAP_WINDOWS_EXCEPTIONS" - - // _set_se_translator should be called at the beginning of main - // since we have no access to main here, we declare a static var of a dummy - // type which does the _set_se_translator call in it's constructor - // Note: this only works if the compiler properly executes the ctors of - // such static vars in DLLs - class Dummy { - public: - Dummy( void ) { - if ( getenv(UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS) == NULL) { - _set_se_translator( translation_func ); - } - } - }; - // static var of our dummy type - Dummy clDummy; -#endif - -} +/* +------------------------------------------------------------------------------- + + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + +------------------------------------------------------------------------------- + + +------------------------------------------------------------------------------- +*/ + +#if defined(_MSC_VER) +#include <stdio.h> +#include <eh.h> +#include <windows.h> +#include <winbase.h> +#endif + +#include "uima/pragmas.hpp" //must be included first to disable warnings +#include "uima/msg.h" +#include <string> +#include <sstream> + +#include "uima/macros.h" +#include "uima/trace.hpp" + +#include "uima/strconvert.hpp" +#include "uima/unistrref.hpp" +#include "uima/comp_ids.h" +#include "uima/exceptions.hpp" +#include "uima/msgstrtab.h" + +using namespace std; + +namespace uima { + +///Constructor with just the message id + ErrorMessage::ErrorMessage( + TyMessageId utMsgId + ) : + iv_utMsgId(utMsgId) { + if ( iv_utMsgId == 0) { + iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE; + } + } +///Constructor with a single char * parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const char * cpszParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + iv_vecParams.push_back((string)cpszParam1); + } + +///Constructor with a single string parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const string & crstrParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + iv_vecParams.push_back(crstrParam1); + } + +///Constructor with a single UChar * parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const UChar * cpuszParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + UnicodeStringRef(cpuszParam1).extract(s); // Convert to default encoding for platform + iv_vecParams.push_back(s); + } + +///Constructor with a single UnicodeString parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const icu::UnicodeString & crustrParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + UnicodeStringRef(crustrParam1).extract(s); // Convert to default encoding for platform + iv_vecParams.push_back(s); + } + +///Constructor with a single int parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + int iParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + iv_vecParams.push_back(long2String(iParam1, s)); + } + +///Constructor with a single unsigned int parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + unsigned int uiParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + iv_vecParams.push_back(long2String((int) uiParam1, s)); + } + + +///Constructor with a single long parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + long lParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + iv_vecParams.push_back(long2String(lParam1, s)); + } + +///Constructor with a single unsigned long parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + unsigned long ulParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + iv_vecParams.push_back(long2String((long) ulParam1, s)); + } + +///Constructor with a single double parameter + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const double dParam1 + ) : + iv_utMsgId(utMsgId) { + assert( iv_utMsgId != 0 ); + string s; + iv_vecParams.push_back(double2String(dParam1, s)); + } + +///Constructor with a full parameter vector + ErrorMessage::ErrorMessage( + TyMessageId utMsgId, + const vector<string> & crvecParams + ) : + iv_utMsgId(utMsgId), + iv_vecParams(crvecParams) { + assert( iv_utMsgId != 0 ); + } + + + /*------------------------------- Constructors -------------------------------*/ + + ErrorContext::ErrorContext( + const ErrorMessage & crclMessage, + const char* pszFilename, + const char* pszFunction, + unsigned long ulLineNumber + ): + iv_clMessage(crclMessage), + iv_pszFilename(pszFilename), + iv_pszFunction(pszFunction), + iv_ulLineNo(ulLineNumber) {} + +#ifdef OS_STL + Exception::~Exception() +#else + Exception::~Exception() UIMA_THROW0() +#endif + {} + + /*------------------------------ Output Support ------------------------------*/ + + string + ErrorMessage::asString() const { + + size_t numparams = getMessageParams().size(); + + // Check for unknown message id + if (iv_utMsgId < 0 || iv_utMsgId > UIMA_MSG_ID_SIGNATURE_END) { + return string("Unknown message id " + iv_utMsgId); + } + + //parameter substitution + + //locate message in message table + const TCHAR ** messages = gs_aszMessageStringTable; + const TCHAR * msg = messages[iv_utMsgId]; + + TCHAR * buf = new TCHAR[UIMA_MSG_MAX_STR_LEN]; + memset(buf,'\0',UIMA_MSG_MAX_STR_LEN); + + int numwritten=0; + + TCHAR * trg = buf; + while (*msg) { + if (numwritten > UIMA_MSG_MAX_STR_LEN) { + break; + } + if (*msg == UIMA_MSG_REPLACE_CHAR) { + msg = msg+1; + if (*msg == UIMA_MSG_REPLACE_CHAR) { + *trg = *msg; + trg = trg +1; + ; + msg = msg+1; + numwritten++; + } else { //replace %n with the corresponding param + unsigned long index; + int len; + string arg; + // determine the number of the specified argument ... + index = (unsigned long) atol(msg); + if (index > numparams) // param not defined + { + arg = "???"; // replace it by "dont-know" + } else { + // ... the indexed argument ... + arg = iv_vecParams[index - 1]; // zero-based array! + //assert(arg.length() > 0); + } + len = arg.length(); + // ... and then copy the argument + if (UIMA_MSG_MAX_STR_LEN-numwritten < len) { + len = UIMA_MSG_MAX_STR_LEN - numwritten; + } + if (len > 0) { + strncpy(trg, arg.c_str(), len); + trg = trg+len; + } + msg = msg+1; + while ( isdigit(*msg) ) { //handle arg number 10 or more + msg = msg+1; + } + } + } else { + *trg = *msg; + trg = trg+1; + msg = msg+1; + } + } + //cout << buf << endl; + string target(buf); + delete[] buf ; + return target; + //string target; + //target.assign(buf, UIMA_MSG_MAX_STR_LEN); // Copy the result to the string + //delete buf; + //return target; + } + + ostream & + operator << ( + ostream & os, + const ErrorMessage & errorMsg + ) { + os << errorMsg.asString(); + return(os); + } + + string + ErrorContext::asString() const { + string s; + s += getMessage().asString(); + if (getFileName() != NULL) { + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " File : " + getFileName(); + } + if (getFunctionName() != NULL) { + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " Function : " + getFunctionName(); + } + if (getLineNumber() != 0) { + string sNum; + long2String(getLineNumber(), sNum); + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + " Line : " + sNum; + } + + return(s); + } + + ostream & + operator << ( + ostream & os, + const ErrorContext & errContext + ) { + os << errContext.asString(); + return (os); + } + + void ErrorMessage::reset(void) { + iv_utMsgId = UIMA_MSG_ID_NO_MESSAGE_AVAILABLE; + iv_vecParams.clear(); + } + + /* ----------------------------------------------------------------------- */ + /* ErrorInfo */ + /* ----------------------------------------------------------------------- */ + + /*------------------------------- Statics -----------------------------------*/ +//initialize static member var to an initial value + + const char * ErrorInfo::cv_cpszContextPrefix = " While : "; + const char * ErrorInfo::cv_cpszIndent = ""; + + + /*------------------------------- Constructors -------------------------------*/ + + ErrorInfo::ErrorInfo( + const ErrorMessage & rclMessage, + TyErrorId ulErrorId, + ErrorInfo::EnSeverity enSeverity + ) : + iv_clErrorMsg(rclMessage), + iv_ulErrorId(ulErrorId), + iv_enSeverity(enSeverity), + iv_vecContexts() {} + + ErrorInfo::ErrorInfo( void ) : + iv_clErrorMsg(), + iv_ulErrorId(UIMA_ERR_NONE), + iv_enSeverity(recoverable), + iv_vecContexts() {} + + ErrorInfo::~ErrorInfo() {} + +//constructor (copy) +//? Exception::Exception( +//? const Exception& rclException +//? ) +//? { +//? } + + /*---------------------------- Exception Context ----------------------------*/ + void + ErrorInfo::addContext( const ErrorContext & crclContext ) { + iv_vecContexts.push_back(crclContext); + } + + const ErrorContext * + ErrorInfo::contextPtrAtIndex( size_t uiContextIndex ) const { + if (uiContextIndex >= iv_vecContexts.size()) { + return(NULL); + } + return(&iv_vecContexts[uiContextIndex]); + } + + /*------------------------------ Output Support ------------------------------*/ + string + ErrorInfo::asString() const { + string s; + if (getErrorId() == UIMA_ERR_NONE) { + s += string("No Error\n"); + return (s); + } + if (getErrorId() != UIMA_ERR_NONE) { + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error number : "; + string sErr; + long2String( getErrorId(), sErr); + s += sErr; + } + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Recoverable : " + (isRecoverable() ? "Yes" : "No"); + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + "Error : " + getMessage().asString(); + for (size_t i = 0; i < contextCount(); ++i) { + s += string("\n") + ErrorInfo::getGlobalErrorInfoIndent() + ErrorInfo::getGlobalErrorInfoContextPrefix(); + assert(EXISTS(contextPtrAtIndex(i))); //lint !e666: Expression with side effects passed to repeated parameter 1 in macro EXISTS + s += contextPtrAtIndex(i)->asString(); + } + s += string("\n"); + + return (s); + } + +///output support for streams + ostream & + operator << ( + ostream & os, + const ErrorInfo & errInfo + ) { + os << errInfo.asString(); + return(os); + } + + void ErrorInfo::reset(void) { + iv_clErrorMsg.reset(); + iv_ulErrorId = UIMA_ERR_NONE; + iv_enSeverity = recoverable; + iv_vecContexts.clear(); + } + + /* ----------------------------------------------------------------------- */ + /* Exception */ + /* ----------------------------------------------------------------------- */ + + Exception::Exception( + const ErrorMessage & rclMessage, + TyErrorId ulErrorId, + ErrorInfo::EnSeverity enSeverity + ) : + EXCEPTION_BASE_CLASS(), + iv_clErrorInfo(rclMessage, ulErrorId, enSeverity) {} + + Exception::Exception( + const ErrorInfo & crclErrorInfo + ) : + EXCEPTION_BASE_CLASS(), + iv_clErrorInfo(crclErrorInfo) {} + + /*------------------------------ Exception Type ------------------------------*/ + + const char * Exception::getName() const { + return(_TEXT("unspecified exception")); + } + + /*------------------------- Application Termination --------------------------*/ + void Exception::terminate() { + exit(iv_clErrorInfo.getErrorId()); //lint !e713: Loss of precision (arg. no. 1) (unsigned long to int) + } + + /*------------------------------ Throw Support -------------------------------*/ + void Exception::assertParameter( + const char* /*exceptionText*/, + ErrorContext /*context*/ ) { + assert(false); + //not tested yet (and not used anywhere!) + } + + /*------------------------- Logging Support ----------------------------------*/ + + void Exception::logExceptionData() { + util::Trace clTrace(util::enTraceDetailLow, UIMA_TRACE_ORIGIN, UIMA_TRACE_COMPID_EXCEPTIONS); + + clTrace.dump(_TEXT("Exception occured"), asString().c_str()); + //not implemented yet + } + + /*------------------------------ Output Support ------------------------------*/ + string + Exception::asString() const { + //output the (class) name of the exception and its error info after it. + return string("\n") + + ErrorInfo::getGlobalErrorInfoIndent() + + "Exception : " + + getName() + + "\n" + + getErrorInfo().asString() + + "\n"; + } + + + + ostream & + operator << ( + ostream & os, + const Exception & exception + ) { + //output the (class) name of the exception and its error info after it. + os << exception.asString(); + return(os); + } + + /*------------------------------ Static Method -------------------------------*/ + + // Release contents of string container allocated by asString method + + void + Exception::release(std::string & msg) { + msg.clear(); // Empty string + msg.reserve(1); // Reduce capacity so will use internal buffer & free external one + } + +//private: + /*----------------------------- Hidden Functions -----------------------------*/ + Exception& Exception::operator=( const Exception& /*exc*/ ) { + assert(false); + return(*this); //lint !e527 unreachable + } //lint !e1745: member not assigned by private assignment operator + + /* ----------------------------------------------------------------------- */ + /* Implementations of predefined exceptions */ + /* ----------------------------------------------------------------------- */ + + + /* + The following classes reimplement the ANSI standard exception hierarchy from + stdexcept.h as UIMACPP exceptions with context and message id support + */ + UIMA_EXC_CLASSIMPLEMENT(Uima_logic_error ,Exception); + UIMA_EXC_CLASSIMPLEMENT(Uima_runtime_error ,Exception); + + UIMA_EXC_CLASSIMPLEMENT(Uima_domain_error ,Uima_logic_error); + UIMA_EXC_CLASSIMPLEMENT(Uima_invalid_argument ,Uima_logic_error); + UIMA_EXC_CLASSIMPLEMENT(Uima_length_error ,Uima_logic_error); + UIMA_EXC_CLASSIMPLEMENT(Uima_out_of_range ,Uima_logic_error); + + UIMA_EXC_CLASSIMPLEMENT(Uima_range_error ,Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(Uima_overflow_error ,Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(Uima_underflow_error ,Uima_runtime_error); + + + /** + The following exceptions are used by helper test classes that are no longer in the UIMACPP library: + CommandLineDriver DocBuffer ParseHandlers + */ + UIMA_EXC_CLASSIMPLEMENT(ConsoleAbortExc ,Exception); + UIMA_EXC_CLASSIMPLEMENT(ParseHandlerExc ,Exception); + UIMA_EXC_CLASSIMPLEMENT(ExcDocBuffer ,Uima_out_of_range); + + /** code page conversion errors */ + UIMA_EXC_CLASSIMPLEMENT(CodePageConversionException, uima::Exception); + /** + The following exception is used to report failures from APR functions + */ + UIMA_EXC_CLASSIMPLEMENT(AprFailureException, Exception); + + /* + The following classes provide a starting point for an exception hierarchy + */ +//? UIMA_EXC_CLASSIMPLEMENT(ExcAssertionFailure, Exception); + UIMA_EXC_CLASSIMPLEMENT(ExcIllFormedInputError , Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(ExcInvalidParameter , Uima_invalid_argument); + UIMA_EXC_CLASSIMPLEMENT(ExcIndexOutOfRange , Uima_out_of_range); +//? UIMA_EXC_CLASSIMPLEMENT(ExcDeviceError ,Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(ExcInvalidRequest , Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(ExcResourceExhausted , Uima_runtime_error); + UIMA_EXC_CLASSIMPLEMENT(ExcOutOfMemory , ExcResourceExhausted); +//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfSystemResource, ResourceExhausted); +//? UIMA_EXC_CLASSIMPLEMENT(ExcOutOfWindowResource, ResourceExhausted); + UIMA_EXC_CLASSIMPLEMENT(ExcFileNotFoundError , Uima_runtime_error); + +// Windows specific CException + ExcWinCException::ExcWinCException( + ErrorMessage clMessage, + TyErrorId ulErrorId, + ErrorInfo::EnSeverity enSeverity + ) + : Uima_runtime_error (clMessage, ulErrorId, enSeverity) { + ; + } + + const char* + ExcWinCException :: getName() const { + return( "ExcWinCException" ); + } + + ExcWinCException::~ExcWinCException () CHILD_DESTRUCT_THROW0() { + ; + } + + ExcWinCException::ExcWinCException (const ExcWinCException & a) : Uima_runtime_error (a) { + ; + } + + + // Windows exceptions can be mapped only when compiled with MS VC++ +#if defined(_MSC_VER) + + void translation_func( unsigned int u, _EXCEPTION_POINTERS* pExp ) { + const char * cpszMsg = NULL; + switch (u) { + case EXCEPTION_ACCESS_VIOLATION: + cpszMsg ="\"ACCESS VIOLATION\""; + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + cpszMsg ="\"DATATYPE MISALIGNMENT\""; + break; + case EXCEPTION_BREAKPOINT: + cpszMsg ="\"BREAKPOINT\""; + break; + case EXCEPTION_SINGLE_STEP: + cpszMsg ="\"SINGLE STEP\""; + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + cpszMsg ="\"ARRAY BOUNDS EXCEEDED\""; + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + cpszMsg ="\"FLT DENORMAL OPERAND\""; + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + cpszMsg ="\"FLT DIVIDE_BY ZERO\""; + break; + case EXCEPTION_FLT_INEXACT_RESULT: + cpszMsg ="\"FLT INEXACT_RESULT\""; + break; + case EXCEPTION_FLT_INVALID_OPERATION: + cpszMsg ="\"FLT INVALID OPERATION\""; + break; + case EXCEPTION_FLT_OVERFLOW: + cpszMsg ="\"FLT OVERFLOW\""; + break; + case EXCEPTION_FLT_STACK_CHECK: + cpszMsg ="\"FLT STACK_CHECK\""; + break; + case EXCEPTION_FLT_UNDERFLOW: + cpszMsg ="\"FLT UNDERFLOW\""; + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + cpszMsg ="\"INT DIVIDE BY ZERO\""; + break; + case EXCEPTION_INT_OVERFLOW: + cpszMsg ="\"INT OVERFLOW\""; + break; + case EXCEPTION_PRIV_INSTRUCTION: + cpszMsg ="\"PRIV INSTRUCTION\""; + break; + case EXCEPTION_IN_PAGE_ERROR: + cpszMsg ="\"IN PAGE_ERROR\""; + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + cpszMsg ="\"ILLEGAL INSTRUCTION\""; + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + cpszMsg ="\"NONCONTINUABLE EXCEPTION\""; + break; + case EXCEPTION_STACK_OVERFLOW: + cpszMsg ="\"STACK OVERFLOW\""; + break; + case EXCEPTION_INVALID_DISPOSITION: + cpszMsg ="\"INVALID DISPOSITION\""; + break; + case EXCEPTION_GUARD_PAGE: + cpszMsg ="\"GUARD PAGE\""; + break; + case EXCEPTION_INVALID_HANDLE: + cpszMsg ="\"INVALID HANDLE\""; + break; + case CONTROL_C_EXIT: + cpszMsg ="\"CONTROL C EXIT\""; + break; + default: + cpszMsg = "Unknows Windows C Exception"; + break; + } + // throw our own type of exception so we know at least what was going on + // instead of just getting an unknown ... C++ excepition + throw ExcWinCException( ErrorMessage(UIMA_MSG_ID_EXC_WINDOWS_EXCEPTION, cpszMsg), + (TyErrorId)UIMA_ERR_ENGINE_WINDOWS_EXCEPTION, + ErrorInfo::unrecoverable); + } + +#define UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS "UIMA_DONT_MAP_WINDOWS_EXCEPTIONS" + + // _set_se_translator should be called at the beginning of main + // since we have no access to main here, we declare a static var of a dummy + // type which does the _set_se_translator call in it's constructor + // Note: this only works if the compiler properly executes the ctors of + // such static vars in DLLs + class Dummy { + public: + Dummy( void ) { + if ( getenv(UIMA_ENVVAR_DONT_MAP_WINDOWS_EXCEPTIONS) == NULL) { + _set_se_translator( translation_func ); + } + } + }; + // static var of our dummy type + Dummy clDummy; +#endif + +} Propchange: uima/uimacpp/trunk/src/framework/exceptions.cpp ('svn:eol-style' removed)