📄 cpl_error.cpp
字号:
psCtx->nLastErrNo = CPLE_None;
psCtx->szLastErrMsg[0] = '\0';
psCtx->eLastErrType = CE_None;
}
/**********************************************************************
* CPLGetLastErrorNo()
**********************************************************************/
/**
* Fetch the last error number.
*
* This is the error number, not the error class.
*
* @return the error number of the last error to occur, or CPLE_None (0)
* if there are no posted errors.
*/
int CPL_STDCALL CPLGetLastErrorNo()
{
CPLErrorContext *psCtx = CPLGetErrorContext();
return psCtx->nLastErrNo;
}
/**********************************************************************
* CPLGetLastErrorType()
**********************************************************************/
/**
* Fetch the last error type.
*
* This is the error class, not the error number.
*
* @return the error number of the last error to occur, or CE_None (0)
* if there are no posted errors.
*/
CPLErr CPL_STDCALL CPLGetLastErrorType()
{
CPLErrorContext *psCtx = CPLGetErrorContext();
return psCtx->eLastErrType;
}
/**********************************************************************
* CPLGetLastErrorMsg()
**********************************************************************/
/**
* Get the last error message.
*
* Fetches the last error message posted with CPLError(), that hasn't
* been cleared by CPLErrorReset(). The returned pointer is to an internal
* string that should not be altered or freed.
*
* @return the last error message, or NULL if there is no posted error
* message.
*/
const char* CPL_STDCALL CPLGetLastErrorMsg()
{
CPLErrorContext *psCtx = CPLGetErrorContext();
return psCtx->szLastErrMsg;
}
/************************************************************************/
/* CPLDefaultErrorHandler() */
/************************************************************************/
void CPL_STDCALL CPLDefaultErrorHandler( CPLErr eErrClass, int nError,
const char * pszErrorMsg )
{
static int bLogInit = FALSE;
static FILE * fpLog = stderr;
if( !bLogInit )
{
bLogInit = TRUE;
fpLog = stderr;
if( CPLGetConfigOption( "CPL_LOG", NULL ) != NULL )
{
fpLog = fopen( CPLGetConfigOption("CPL_LOG",""), "wt" );
if( fpLog == NULL )
fpLog = stderr;
}
}
if( eErrClass == CE_Debug )
fprintf( fpLog, "%s\n", pszErrorMsg );
else if( eErrClass == CE_Warning )
fprintf( fpLog, "Warning %d: %s\n", nError, pszErrorMsg );
else
fprintf( fpLog, "ERROR %d: %s\n", nError, pszErrorMsg );
fflush( fpLog );
}
/************************************************************************/
/* CPLQuietErrorHandler() */
/************************************************************************/
void CPL_STDCALL CPLQuietErrorHandler( CPLErr eErrClass , int nError,
const char * pszErrorMsg )
{
if( eErrClass == CE_Debug )
CPLDefaultErrorHandler( eErrClass, nError, pszErrorMsg );
}
/************************************************************************/
/* CPLLoggingErrorHandler() */
/************************************************************************/
void CPL_STDCALL CPLLoggingErrorHandler( CPLErr eErrClass, int nError,
const char * pszErrorMsg )
{
static int bLogInit = FALSE;
static FILE * fpLog = stderr;
if( !bLogInit )
{
const char *cpl_log = NULL;
CPLSetConfigOption( "CPL_TIMESTAMP", "ON" );
bLogInit = TRUE;
cpl_log = CPLGetConfigOption("CPL_LOG", NULL );
fpLog = stderr;
if( cpl_log != NULL && EQUAL(cpl_log,"OFF") )
{
fpLog = NULL;
}
else if( cpl_log != NULL )
{
char path[5000];
int i = 0;
strcpy( path, cpl_log );
while( (fpLog = fopen( path, "rt" )) != NULL )
{
fclose( fpLog );
/* generate sequenced log file names, inserting # before ext.*/
if (strrchr(cpl_log, '.') == NULL)
{
sprintf( path, "%s_%d%s", cpl_log, i++,
".log" );
}
else
{
size_t pos = 0;
char *cpl_log_base = strdup(cpl_log);
pos = strcspn(cpl_log_base, ".");
if (pos > 0)
{
cpl_log_base[pos] = '\0';
}
sprintf( path, "%s_%d%s", cpl_log_base,
i++, ".log" );
}
}
fpLog = fopen( path, "wt" );
}
}
if( fpLog == NULL )
return;
if( eErrClass == CE_Debug )
fprintf( fpLog, "%s\n", pszErrorMsg );
else if( eErrClass == CE_Warning )
fprintf( fpLog, "Warning %d: %s\n", nError, pszErrorMsg );
else
fprintf( fpLog, "ERROR %d: %s\n", nError, pszErrorMsg );
fflush( fpLog );
}
/**********************************************************************
* CPLSetErrorHandler()
**********************************************************************/
/**
* Install custom error handler.
*
* Allow the library's user to specify his own error handler function.
* A valid error handler is a C function with the following prototype:
*
* <pre>
* void MyErrorHandler(CPLErr eErrClass, int err_no, const char *msg)
* </pre>
*
* Pass NULL to come back to the default behavior. The default behaviour
* (CPLDefaultErrorHandler()) is to write the message to stderr.
*
* The msg will be a partially formatted error message not containing the
* "ERROR %d:" portion emitted by the default handler. Message formatting
* is handled by CPLError() before calling the handler. If the error
* handler function is passed a CE_Fatal class error and returns, then
* CPLError() will call abort(). Applications wanting to interrupt this
* fatal behaviour will have to use longjmp(), or a C++ exception to
* indirectly exit the function.
*
* Another standard error handler is CPLQuietErrorHandler() which doesn't
* make any attempt to report the passed error or warning messages but
* will process debug messages via CPLDefaultErrorHandler.
*
* Note that error handlers set with CPLSetErrorHandler() apply to all
* threads in an application, while error handlers set with CPLPushErrorHandler
* are thread-local. However, any error handlers pushed with
* CPLPushErrorHandler (and not removed with CPLPopErrorHandler) take
* precidence over the global error handlers set with CPLSetErrorHandler().
* Generally speaking CPLSetErrorHandler() would be used to set a desired
* global error handler, while CPLPushErrorHandler() would be used to install
* a temporary local error handler, such as CPLQuietErrorHandler() to suppress
* error reporting in a limited segment of code.
*
* @param pfnErrorHandlerNew new error handler function.
* @return returns the previously installed error handler.
*/
CPLErrorHandler CPL_STDCALL
CPLSetErrorHandler( CPLErrorHandler pfnErrorHandlerNew )
{
CPLErrorHandler pfnOldHandler = pfnErrorHandler;
CPLErrorContext *psCtx = CPLGetErrorContext();
if( psCtx->psHandlerStack != NULL )
{
CPLDebug( "CPL",
"CPLSetErrorHandler() called with an error handler on\n"
"the local stack. New error handler will not be used immediately.\n" );
}
{
CPLMutexHolderD( &hErrorMutex );
pfnOldHandler = pfnErrorHandler;
if( pfnErrorHandler == NULL )
pfnErrorHandler = CPLDefaultErrorHandler;
else
pfnErrorHandler = pfnErrorHandlerNew;
}
return pfnOldHandler;
}
/************************************************************************/
/* CPLPushErrorHandler() */
/************************************************************************/
/**
* Push a new CPLError handler.
*
* This pushes a new error handler on the thread-local error handler
* stack. This handler will be used untill removed with CPLPopErrorHandler().
*
* The CPLSetErrorHandler() docs have further information on how
* CPLError handlers work.
*
* @param pfnErrorHandlerNew new error handler function.
*/
void CPL_STDCALL CPLPushErrorHandler( CPLErrorHandler pfnErrorHandlerNew )
{
CPLErrorContext *psCtx = CPLGetErrorContext();
CPLErrorHandlerNode *psNode;
psNode = (CPLErrorHandlerNode *) VSIMalloc(sizeof(CPLErrorHandlerNode));
psNode->psNext = psCtx->psHandlerStack;
psNode->pfnHandler = pfnErrorHandlerNew;
psCtx->psHandlerStack = psNode;
}
/************************************************************************/
/* CPLPopErrorHandler() */
/************************************************************************/
/**
* Pop error handler off stack.
*
* Discards the current error handler on the error handler stack, and restores
* the one in use before the last CPLPushErrorHandler() call. This method
* has no effect if there are no error handlers on the current threads error
* handler stack.
*/
void CPL_STDCALL CPLPopErrorHandler()
{
CPLErrorContext *psCtx = CPLGetErrorContext();
if( psCtx->psHandlerStack != NULL )
{
CPLErrorHandlerNode *psNode = psCtx->psHandlerStack;
psCtx->psHandlerStack = psNode->psNext;
VSIFree( psNode );
}
}
/************************************************************************/
/* _CPLAssert() */
/* */
/* This function is called only when an assertion fails. */
/************************************************************************/
/**
* Report failure of a logical assertion.
*
* Applications would normally use the CPLAssert() macro which expands
* into code calling _CPLAssert() only if the condition fails. _CPLAssert()
* will generate a CE_Fatal error call to CPLError(), indicating the file
* name, and line number of the failed assertion, as well as containing
* the assertion itself.
*
* There is no reason for application code to call _CPLAssert() directly.
*/
void CPL_STDCALL _CPLAssert( const char * pszExpression, const char * pszFile,
int iLine )
{
CPLError( CE_Fatal, CPLE_AssertionFailed,
"Assertion `%s' failed\n"
"in file `%s', line %d\n",
pszExpression, pszFile, iLine );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -