Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

cpl_error.cpp

00001 /**********************************************************************
00002  * $Id: cpl_error_cpp-source.html,v 1.6 2001/01/22 22:22:23 warmerda Exp $
00003  *
00004  * Name:     cpl_error.cpp
00005  * Project:  CPL - Common Portability Library
00006  * Purpose:  Error handling functions.
00007  * Author:   Daniel Morissette, danmo@videotron.ca
00008  *
00009  **********************************************************************
00010  * Copyright (c) 1998, Daniel Morissette
00011  *
00012  * Permission is hereby granted, free of charge, to any person obtaining a
00013  * copy of this software and associated documentation files (the "Software"),
00014  * to deal in the Software without restriction, including without limitation
00015  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00016  * and/or sell copies of the Software, and to permit persons to whom the
00017  * Software is furnished to do so, subject to the following conditions:
00018  * 
00019  * The above copyright notice and this permission notice shall be included
00020  * in all copies or substantial portions of the Software.
00021  * 
00022  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00023  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00024  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00025  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00026  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00027  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
00028  * DEALINGS IN THE SOFTWARE.
00029  **********************************************************************
00030  *
00031  * $Log: cpl_error_cpp-source.html,v $
00031  * Revision 1.6  2001/01/22 22:22:23  warmerda
00031  * *** empty log message ***
00031  *
00032  * Revision 1.14  2000/11/30 17:30:10  warmerda
00033  * added CPLGetLastErrorType
00034  *
00035  * Revision 1.13  2000/03/31 14:37:48  warmerda
00036  * only use vsnprintf where available
00037  *
00038  * Revision 1.12  2000/03/31 14:11:55  warmerda
00039  * added CPLErrorV
00040  *
00041  * Revision 1.11  2000/01/10 17:35:45  warmerda
00042  * added push down stack of error handlers
00043  *
00044  * Revision 1.10  1999/11/23 04:16:56  danmo
00045  * Fixed var. initialization that failed to compile as C
00046  *
00047  * Revision 1.9  1999/09/03 17:03:45  warmerda
00048  * Completed partial help line.
00049  *
00050  * Revision 1.8  1999/07/23 14:27:47  warmerda
00051  * CPLSetErrorHandler returns old handler
00052  *
00053  * Revision 1.7  1999/06/27 16:50:52  warmerda
00054  * added support for CPL_DEBUG and CPL_LOG variables
00055  *
00056  * Revision 1.6  1999/06/26 02:46:11  warmerda
00057  * Fixed initialization of debug messages.
00058  *
00059  * Revision 1.5  1999/05/20 14:59:05  warmerda
00060  * added CPLDebug()
00061  *
00062  * Revision 1.4  1999/05/20 02:54:38  warmerda
00063  * Added API documentation
00064  *
00065  * Revision 1.3  1998/12/15 19:02:27  warmerda
00066  * Avoid use of errno as a variable
00067  *
00068  * Revision 1.2  1998/12/06 02:52:52  warmerda
00069  * Implement assert support
00070  *
00071  * Revision 1.1  1998/12/03 18:26:02  warmerda
00072  * New
00073  *
00074  **********************************************************************/
00075 
00076 #include "cpl_error.h"
00077 #include "cpl_vsi.h"
00078 
00079 /* static buffer to store the last error message.  We'll assume that error
00080  * messages cannot be longer than 2000 chars... which is quite reasonable
00081  * (that's 25 lines of 80 chars!!!)
00082  */
00083 static char gszCPLLastErrMsg[2000] = "";
00084 static int  gnCPLLastErrNo = 0;
00085 static CPLErr geCPLLastErrType = CE_None;
00086 
00087 static CPLErrorHandler gpfnCPLErrorHandler = CPLDefaultErrorHandler;
00088 
00089 typedef struct errHandler
00090 {
00091     struct errHandler   *psNext;
00092     CPLErrorHandler     pfnHandler;
00093 } CPLErrorHandlerNode;
00094 
00095 static CPLErrorHandlerNode * psHandlerStack = NULL;
00096 
00097 /**********************************************************************
00098  *                          CPLError()
00099  **********************************************************************/
00100 
00133 void    CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...)
00134 {
00135     va_list args;
00136 
00137     /* Expand the error message 
00138      */
00139     va_start(args, fmt);
00140     CPLErrorV( eErrClass, err_no, fmt, args );
00141     va_end(args);
00142 }
00143 
00144 /************************************************************************/
00145 /*                             CPLErrorV()                              */
00146 /************************************************************************/
00147 
00148 void    CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args )
00149 {
00150     /* Expand the error message 
00151      */
00152 #if defined(HAVE_VSNPRINTF)
00153     vsnprintf(gszCPLLastErrMsg, sizeof(gszCPLLastErrMsg), fmt, args);
00154 #else
00155     vsprintf(gszCPLLastErrMsg, fmt, args);
00156 #endif
00157 
00158     /* If the user provided his own error handling function, then call
00159      * it, otherwise print the error to stderr and return.
00160      */
00161     gnCPLLastErrNo = err_no;
00162     geCPLLastErrType = eErrClass;
00163 
00164     if( gpfnCPLErrorHandler )
00165         gpfnCPLErrorHandler(eErrClass, err_no, gszCPLLastErrMsg);
00166 
00167     if( eErrClass == CE_Fatal )
00168         abort();
00169 }
00170 
00171 /************************************************************************/
00172 /*                              CPLDebug()                              */
00173 /************************************************************************/
00174 
00196 void CPLDebug( const char * pszCategory, const char * pszFormat, ... )
00197 
00198 {
00199     char        *pszMessage;
00200     va_list args;
00201     const char      *pszDebug = getenv("CPL_DEBUG");
00202 
00203 /* -------------------------------------------------------------------- */
00204 /*      Does this message pass our current criteria?                    */
00205 /* -------------------------------------------------------------------- */
00206     if( pszDebug == NULL )
00207         return;
00208 
00209     if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") )
00210     {
00211         int            i, nLen = strlen(pszCategory);
00212 
00213         for( i = 0; pszDebug[i] != '\0'; i++ )
00214         {
00215             if( EQUALN(pszCategory,pszDebug+i,nLen) )
00216                 break;
00217         }
00218 
00219         if( pszDebug[i] == '\0' )
00220             return;
00221     }
00222 
00223 /* -------------------------------------------------------------------- */
00224 /*      Format the error message                                        */
00225 /* -------------------------------------------------------------------- */
00226     pszMessage = (char *) VSIMalloc(25000);
00227     if( pszMessage == NULL )
00228         return;
00229         
00230     strcpy( pszMessage, pszCategory );
00231     strcat( pszMessage, ": " );
00232     
00233     va_start(args, pszFormat);
00234     vsprintf(pszMessage+strlen(pszMessage), pszFormat, args);
00235     va_end(args);
00236 
00237 /* -------------------------------------------------------------------- */
00238 /*      If the user provided his own error handling function, then call */
00239 /*      it, otherwise print the error to stderr and return.             */
00240 /* -------------------------------------------------------------------- */
00241     if( gpfnCPLErrorHandler )
00242         gpfnCPLErrorHandler(CE_Debug, CPLE_None, pszMessage);
00243 
00244     VSIFree( pszMessage );
00245 }
00246 
00247 /**********************************************************************
00248  *                          CPLErrorReset()
00249  **********************************************************************/
00250 
00258 void    CPLErrorReset()
00259 {
00260     gnCPLLastErrNo = CPLE_None;
00261     gszCPLLastErrMsg[0] = '\0';
00262     geCPLLastErrType = CE_None;
00263 }
00264 
00265 
00266 /**********************************************************************
00267  *                          CPLGetLastErrorNo()
00268  **********************************************************************/
00269 
00279 int     CPLGetLastErrorNo()
00280 {
00281     return gnCPLLastErrNo;
00282 }
00283 
00284 /**********************************************************************
00285  *                          CPLGetLastErrorType()
00286  **********************************************************************/
00287 
00297 CPLErr CPLGetLastErrorType()
00298 {
00299     return geCPLLastErrType;
00300 }
00301 
00302 /**********************************************************************
00303  *                          CPLGetLastErrorMsg()
00304  **********************************************************************/
00305 
00317 const char* CPLGetLastErrorMsg()
00318 {
00319     return gszCPLLastErrMsg;
00320 }
00321 
00322 /************************************************************************/
00323 /*                       CPLDefaultErrorHandler()                       */
00324 /************************************************************************/
00325 
00326 void CPLDefaultErrorHandler( CPLErr eErrClass, int nError, 
00327                              const char * pszErrorMsg )
00328 
00329 {
00330     static int       bLogInit = FALSE;
00331     static FILE *    fpLog;
00332     fpLog = stderr;
00333 
00334     if( !bLogInit )
00335     {
00336         bLogInit = TRUE;
00337 
00338         if( getenv( "CPL_LOG" ) != NULL )
00339         {
00340             fpLog = fopen( getenv("CPL_LOG"), "wt" );
00341             if( fpLog == NULL )
00342                 fpLog = stderr;
00343         }
00344     }
00345 
00346     if( eErrClass == CE_Debug )
00347         fprintf( fpLog, "%s\n", pszErrorMsg );
00348     else if( eErrClass == CE_Warning )
00349         fprintf( fpLog, "Warning %d: %s\n", nError, pszErrorMsg );
00350     else
00351         fprintf( fpLog, "ERROR %d: %s\n", nError, pszErrorMsg );
00352 
00353     fflush( fpLog );
00354 }
00355 
00356 /************************************************************************/
00357 /*                        CPLQuietErrorHandler()                        */
00358 /************************************************************************/
00359 
00360 void CPLQuietErrorHandler( CPLErr eErrClass , int nError, 
00361                            const char * pszErrorMsg )
00362 
00363 {
00364     if( eErrClass == CE_Debug )
00365         CPLDefaultErrorHandler( eErrClass, nError, pszErrorMsg );
00366 }
00367 
00368 /**********************************************************************
00369  *                          CPLSetErrorHandler()
00370  **********************************************************************/
00371 
00401 CPLErrorHandler CPLSetErrorHandler( CPLErrorHandler pfnErrorHandler )
00402 {
00403     CPLErrorHandler     pfnOldHandler = gpfnCPLErrorHandler;
00404     
00405     gpfnCPLErrorHandler = pfnErrorHandler;
00406 
00407     return pfnOldHandler;
00408 }
00409 
00410 
00411 
00412 /************************************************************************/
00413 /*                        CPLPushErrorHandler()                         */
00414 /************************************************************************/
00415 
00427 void CPLPushErrorHandler( CPLErrorHandler pfnErrorHandler )
00428 
00429 {
00430     CPLErrorHandlerNode         *psNode;
00431 
00432     psNode = (CPLErrorHandlerNode *) VSIMalloc(sizeof(CPLErrorHandlerNode));
00433     psNode->psNext = psHandlerStack;
00434     psNode->pfnHandler = gpfnCPLErrorHandler;
00435 
00436     psHandlerStack = psNode;
00437 
00438     CPLSetErrorHandler( pfnErrorHandler );
00439 }
00440 
00441 /************************************************************************/
00442 /*                         CPLPopErrorHandler()                         */
00443 /************************************************************************/
00444 
00452 void CPLPopErrorHandler()
00453 
00454 {
00455     if( psHandlerStack != NULL )
00456     {
00457         CPLErrorHandlerNode     *psNode = psHandlerStack;
00458 
00459         psHandlerStack = psNode->psNext;
00460         CPLSetErrorHandler( psNode->pfnHandler );
00461         VSIFree( psNode );
00462     }
00463 }
00464 
00465 /************************************************************************/
00466 /*                             _CPLAssert()                             */
00467 /*                                                                      */
00468 /*      This function is called only when an assertion fails.           */
00469 /************************************************************************/
00470 
00483 void _CPLAssert( const char * pszExpression, const char * pszFile,
00484                  int iLine )
00485 
00486 {
00487     CPLError( CE_Fatal, CPLE_AssertionFailed,
00488               "Assertion `%s' failed\n"
00489               "in file `%s', line %d\n",
00490               pszExpression, pszFile, iLine );
00491 }
00492 

Generated at Tue Jan 16 12:43:35 2001 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000