CPLErrorHandler CPL_STDCALL CPLSetErrorHandlerEx( CPLErrorHandler pfnErrorHandlerNew, void* pUserData ) { 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; pErrorHandlerUserData = pUserData; } return pfnOldHandler; }
void CPL_STDCALL CPLErrorReset() { CPLErrorContext *psCtx = CPLGetErrorContext(); psCtx->nLastErrNo = CPLE_None; psCtx->szLastErrMsg[0] = '\0'; psCtx->eLastErrType = CE_None; }
void CPLTurnFailureIntoWarning(int bOn ) { CPLErrorContext *psCtx = CPLGetErrorContext(); psCtx->nFailureIntoWarning += (bOn) ? 1 : -1; if (psCtx->nFailureIntoWarning < 0) { CPLDebug("CPL", "Wrong nesting of CPLTurnFailureIntoWarning(TRUE) / CPLTurnFailureIntoWarning(FALSE)"); } }
void CPL_DLL CPLErrorSetState( CPLErr eErrClass, int err_no, const char* pszMsg ) { CPLErrorContext *psCtx = CPLGetErrorContext(); psCtx->nLastErrNo = err_no; strncpy(psCtx->szLastErrMsg, pszMsg, psCtx->nLastErrMsgMax); psCtx->szLastErrMsg[MAX(psCtx->nLastErrMsgMax-1, (int)strlen(pszMsg))] = '\0'; psCtx->eLastErrType = eErrClass; }
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; }
void CPL_STDCALL CPLPopErrorHandler() { CPLErrorContext *psCtx = CPLGetErrorContext(); if( psCtx->psHandlerStack != NULL ) { CPLErrorHandlerNode *psNode = psCtx->psHandlerStack; psCtx->psHandlerStack = psNode->psNext; VSIFree( psNode ); } }
/** * Push a new CPLError handler with user data on the error context. * * This pushes a new error handler on the thread-local error handler * stack. This handler will be used until removed with CPLPopErrorHandler(). * Obtain the user data back by using CPLGetErrorContext(). * * The CPLSetErrorHandler() docs have further information on how * CPLError handlers work. * * @param pfnErrorHandlerNew new error handler function. * @param pUserData User data to put on the error context. */ void CPL_STDCALL CPLPushErrorHandlerEx( CPLErrorHandler pfnErrorHandlerNew, void* pUserData ) { CPLErrorContext *psCtx = CPLGetErrorContext(); CPLErrorHandlerNode *psNode; psNode = (CPLErrorHandlerNode *) CPLMalloc(sizeof(CPLErrorHandlerNode)); psNode->psNext = psCtx->psHandlerStack; psNode->pfnHandler = pfnErrorHandlerNew; psNode->pUserData = pUserData; psCtx->psHandlerStack = psNode; }
const char* CPL_STDCALL CPLGetLastErrorMsg() { CPLErrorContext *psCtx = CPLGetErrorContext(); return psCtx->szLastErrMsg; }
CPLErr CPL_STDCALL CPLGetLastErrorType() { CPLErrorContext *psCtx = CPLGetErrorContext(); return psCtx->eLastErrType; }
int CPL_STDCALL CPLGetLastErrorNo() { CPLErrorContext *psCtx = CPLGetErrorContext(); return psCtx->nLastErrNo; }
void CPLDebug( const char * pszCategory, const char * pszFormat, ... ) { CPLErrorContext *psCtx = CPLGetErrorContext(); char *pszMessage; va_list args; const char *pszDebug = CPLGetConfigOption("CPL_DEBUG",NULL); #define ERROR_MAX 25000 /* -------------------------------------------------------------------- */ /* Does this message pass our current criteria? */ /* -------------------------------------------------------------------- */ if( pszDebug == NULL ) return; if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") ) { size_t i, nLen = strlen(pszCategory); for( i = 0; pszDebug[i] != '\0'; i++ ) { if( EQUALN(pszCategory,pszDebug+i,nLen) ) break; } if( pszDebug[i] == '\0' ) return; } /* -------------------------------------------------------------------- */ /* Allocate a block for the error. */ /* -------------------------------------------------------------------- */ pszMessage = (char *) VSIMalloc( ERROR_MAX ); if( pszMessage == NULL ) return; /* -------------------------------------------------------------------- */ /* Dal -- always log a timestamp as the first part of the line */ /* to ensure one is looking at what one should be looking at! */ /* -------------------------------------------------------------------- */ pszMessage[0] = '\0'; #ifdef TIMESTAMP_DEBUG if( CPLGetConfigOption( "CPL_TIMESTAMP", NULL ) != NULL ) { strcpy( pszMessage, VSICTime( VSITime(NULL) ) ); // On windows anyway, ctime puts a \n at the end, but I'm not // convinced this is standard behaviour, so we'll get rid of it // carefully if (pszMessage[strlen(pszMessage) -1 ] == '\n') { pszMessage[strlen(pszMessage) - 1] = 0; // blow it out } strcat( pszMessage, ": " ); } #endif /* -------------------------------------------------------------------- */ /* Add the process memory size. */ /* -------------------------------------------------------------------- */ #ifdef MEMORY_DEBUG char szVmSize[32]; CPLsprintf( szVmSize, "[VmSize: %d] ", CPLGetProcessMemorySize()); strcat( pszMessage, szVmSize ); #endif //sprintf(pszMessage,"[%d] ", (int)getpid()); /* -------------------------------------------------------------------- */ /* Add the category. */ /* -------------------------------------------------------------------- */ strcat( pszMessage, pszCategory ); strcat( pszMessage, ": " ); /* -------------------------------------------------------------------- */ /* Format the application provided portion of the debug message. */ /* -------------------------------------------------------------------- */ va_start(args, pszFormat); CPLvsnprintf(pszMessage+strlen(pszMessage), ERROR_MAX - strlen(pszMessage), pszFormat, args); va_end(args); /* -------------------------------------------------------------------- */ /* Obfuscate any password in error message */ /* -------------------------------------------------------------------- */ char* pszPassword = strstr(pszMessage, "password="******"password="); while( *pszIter != ' ' && *pszIter != '\0' ) { *pszIter = 'X'; pszIter ++; } } /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None, pszMessage ); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler( CE_Debug, CPLE_None, pszMessage ); } VSIFree( pszMessage ); }
void CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args ) { CPLErrorContext *psCtx = CPLGetErrorContext(); if (psCtx->nFailureIntoWarning > 0 && eErrClass == CE_Failure) eErrClass = CE_Warning; /* -------------------------------------------------------------------- */ /* Expand the error message */ /* -------------------------------------------------------------------- */ #if defined(HAVE_VSNPRINTF) { int nPR; va_list wrk_args; #ifdef va_copy va_copy( wrk_args, args ); #else wrk_args = args; #endif /* -------------------------------------------------------------------- */ /* If CPL_ACCUM_ERROR_MSG=ON accumulate the error messages, */ /* rather than just replacing the last error message. */ /* -------------------------------------------------------------------- */ int nPreviousSize = 0; if ( psCtx->psHandlerStack != NULL && EQUAL(CPLGetConfigOption( "CPL_ACCUM_ERROR_MSG", "" ), "ON")) { nPreviousSize = strlen(psCtx->szLastErrMsg); if (nPreviousSize) { if (nPreviousSize + 1 + 1 >= psCtx->nLastErrMsgMax) { psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } psCtx->szLastErrMsg[nPreviousSize] = '\n'; psCtx->szLastErrMsg[nPreviousSize+1] = '0'; nPreviousSize ++; } } while( ((nPR = CPLvsnprintf( psCtx->szLastErrMsg+nPreviousSize, psCtx->nLastErrMsgMax-nPreviousSize, fmt, wrk_args )) == -1 || nPR >= psCtx->nLastErrMsgMax-nPreviousSize-1) && psCtx->nLastErrMsgMax < 1000000 ) { #ifdef va_copy va_end( wrk_args ); va_copy( wrk_args, args ); #else wrk_args = args; #endif psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } va_end( wrk_args ); } #else // !HAVE_VSNPRINTF CPLvsnprintf( psCtx->szLastErrMsg, psCtx->nLastErrMsgMax, fmt, args); #endif /* -------------------------------------------------------------------- */ /* Obfuscate any password in error message */ /* -------------------------------------------------------------------- */ char* pszPassword = strstr(psCtx->szLastErrMsg, "password="******"password="******"CPL_LOG_ERRORS",NULL) != NULL ) CPLDebug( "CPLError", "%s", psCtx->szLastErrMsg ); /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler(eErrClass, err_no, psCtx->szLastErrMsg); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler(eErrClass, err_no, psCtx->szLastErrMsg); } if( eErrClass == CE_Fatal ) abort(); }
void* CPL_STDCALL CPLGetErrorHandlerUserData(void) { CPLErrorContext *psCtx = CPLGetErrorContext(); return (void*) psCtx->psHandlerStack ? psCtx->psHandlerStack->pUserData : pErrorHandlerUserData; }
void CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args ) { CPLErrorContext *psCtx = CPLGetErrorContext(); /* -------------------------------------------------------------------- */ /* Expand the error message */ /* -------------------------------------------------------------------- */ #if defined(HAVE_VSNPRINTF) { int nPR; va_list wrk_args; #ifdef va_copy va_copy( wrk_args, args ); #else wrk_args = args; #endif while( ((nPR = vsnprintf( psCtx->szLastErrMsg, psCtx->nLastErrMsgMax, fmt, wrk_args )) == -1 || nPR >= psCtx->nLastErrMsgMax-1) && psCtx->nLastErrMsgMax < 1000000 ) { #ifdef va_copy va_end( wrk_args ); va_copy( wrk_args, args ); #else wrk_args = args; #endif psCtx->nLastErrMsgMax *= 3; psCtx = (CPLErrorContext *) CPLRealloc(psCtx, sizeof(CPLErrorContext) - DEFAULT_LAST_ERR_MSG_SIZE + psCtx->nLastErrMsgMax + 1); CPLSetTLS( CTLS_ERRORCONTEXT, psCtx, TRUE ); } va_end( wrk_args ); } #else vsprintf( psCtx->szLastErrMsg, fmt, args); #endif /* -------------------------------------------------------------------- */ /* If the user provided his own error handling function, then */ /* call it, otherwise print the error to stderr and return. */ /* -------------------------------------------------------------------- */ psCtx->nLastErrNo = err_no; psCtx->eLastErrType = eErrClass; if( CPLGetConfigOption("CPL_LOG_ERRORS",NULL) != NULL ) CPLDebug( "CPLError", "%s", psCtx->szLastErrMsg ); /* -------------------------------------------------------------------- */ /* Invoke the current error handler. */ /* -------------------------------------------------------------------- */ if( psCtx->psHandlerStack != NULL ) { psCtx->psHandlerStack->pfnHandler(eErrClass, err_no, psCtx->szLastErrMsg); } else { CPLMutexHolderD( &hErrorMutex ); if( pfnErrorHandler != NULL ) pfnErrorHandler(eErrClass, err_no, psCtx->szLastErrMsg); } if( eErrClass == CE_Fatal ) abort(); }