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.8 2001/07/05 13:24:08 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.8  2001/07/05 13:24:08  warmerda
00031  * *** empty log message ***
00031  *
00032  * Revision 1.16  2001/02/15 16:30:57  warmerda
00033  * fixed initialization of fpLog
00034  *
00035  * Revision 1.15  2001/01/19 21:16:41  warmerda
00036  * expanded tabs
00037  *
00038  * Revision 1.14  2000/11/30 17:30:10  warmerda
00039  * added CPLGetLastErrorType
00040  *
00041  * Revision 1.13  2000/03/31 14:37:48  warmerda
00042  * only use vsnprintf where available
00043  *
00044  * Revision 1.12  2000/03/31 14:11:55  warmerda
00045  * added CPLErrorV
00046  *
00047  * Revision 1.11  2000/01/10 17:35:45  warmerda
00048  * added push down stack of error handlers
00049  *
00050  * Revision 1.10  1999/11/23 04:16:56  danmo
00051  * Fixed var. initialization that failed to compile as C
00052  *
00053  * Revision 1.9  1999/09/03 17:03:45  warmerda
00054  * Completed partial help line.
00055  *
00056  * Revision 1.8  1999/07/23 14:27:47  warmerda
00057  * CPLSetErrorHandler returns old handler
00058  *
00059  * Revision 1.7  1999/06/27 16:50:52  warmerda
00060  * added support for CPL_DEBUG and CPL_LOG variables
00061  *
00062  * Revision 1.6  1999/06/26 02:46:11  warmerda
00063  * Fixed initialization of debug messages.
00064  *
00065  * Revision 1.5  1999/05/20 14:59:05  warmerda
00066  * added CPLDebug()
00067  *
00068  * Revision 1.4  1999/05/20 02:54:38  warmerda
00069  * Added API documentation
00070  *
00071  * Revision 1.3  1998/12/15 19:02:27  warmerda
00072  * Avoid use of errno as a variable
00073  *
00074  * Revision 1.2  1998/12/06 02:52:52  warmerda
00075  * Implement assert support
00076  *
00077  * Revision 1.1  1998/12/03 18:26:02  warmerda
00078  * New
00079  *
00080  **********************************************************************/
00081 
00082 #include "cpl_error.h"
00083 #include "cpl_vsi.h"
00084 
00085 /* static buffer to store the last error message.  We'll assume that error
00086  * messages cannot be longer than 2000 chars... which is quite reasonable
00087  * (that's 25 lines of 80 chars!!!)
00088  */
00089 static char gszCPLLastErrMsg[2000] = "";
00090 static int  gnCPLLastErrNo = 0;
00091 static CPLErr geCPLLastErrType = CE_None;
00092 
00093 static CPLErrorHandler gpfnCPLErrorHandler = CPLDefaultErrorHandler;
00094 
00095 typedef struct errHandler
00096 {
00097     struct errHandler   *psNext;
00098     CPLErrorHandler     pfnHandler;
00099 } CPLErrorHandlerNode;
00100 
00101 static CPLErrorHandlerNode * psHandlerStack = NULL;
00102 
00103 /**********************************************************************
00104  *                          CPLError()
00105  **********************************************************************/
00106 
00139 void    CPLError(CPLErr eErrClass, int err_no, const char *fmt, ...)
00140 {
00141     va_list args;
00142 
00143     /* Expand the error message 
00144      */
00145     va_start(args, fmt);
00146     CPLErrorV( eErrClass, err_no, fmt, args );
00147     va_end(args);
00148 }
00149 
00150 /************************************************************************/
00151 /*                             CPLErrorV()                              */
00152 /************************************************************************/
00153 
00154 void    CPLErrorV(CPLErr eErrClass, int err_no, const char *fmt, va_list args )
00155 {
00156     /* Expand the error message 
00157      */
00158 #if defined(HAVE_VSNPRINTF)
00159     vsnprintf(gszCPLLastErrMsg, sizeof(gszCPLLastErrMsg), fmt, args);
00160 #else
00161     vsprintf(gszCPLLastErrMsg, fmt, args);
00162 #endif
00163 
00164     /* If the user provided his own error handling function, then call
00165      * it, otherwise print the error to stderr and return.
00166      */
00167     gnCPLLastErrNo = err_no;
00168     geCPLLastErrType = eErrClass;
00169 
00170     if( gpfnCPLErrorHandler )
00171         gpfnCPLErrorHandler(eErrClass, err_no, gszCPLLastErrMsg);
00172 
00173     if( eErrClass == CE_Fatal )
00174         abort();
00175 }
00176 
00177 /************************************************************************/
00178 /*                              CPLDebug()                              */
00179 /************************************************************************/
00180 
00202 void CPLDebug( const char * pszCategory, const char * pszFormat, ... )
00203 
00204 {
00205     char        *pszMessage;
00206     va_list args;
00207     const char      *pszDebug = getenv("CPL_DEBUG");
00208 
00209 /* -------------------------------------------------------------------- */
00210 /*      Does this message pass our current criteria?                    */
00211 /* -------------------------------------------------------------------- */
00212     if( pszDebug == NULL )
00213         return;
00214 
00215     if( !EQUAL(pszDebug,"ON") && !EQUAL(pszDebug,"") )
00216     {
00217         int            i, nLen = strlen(pszCategory);
00218 
00219         for( i = 0; pszDebug[i] != '\0'; i++ )
00220         {
00221             if( EQUALN(pszCategory,pszDebug+i,nLen) )
00222                 break;
00223         }
00224 
00225         if( pszDebug[i] == '\0' )
00226             return;
00227     }
00228 
00229 /* -------------------------------------------------------------------- */
00230 /*      Format the error message                                        */
00231 /* -------------------------------------------------------------------- */
00232     pszMessage = (char *) VSIMalloc(25000);
00233     if( pszMessage == NULL )
00234         return;
00235         
00236     strcpy( pszMessage, pszCategory );
00237     strcat( pszMessage, ": " );
00238     
00239     va_start(args, pszFormat);
00240     vsprintf(pszMessage+strlen(pszMessage), pszFormat, args);
00241     va_end(args);
00242 
00243 /* -------------------------------------------------------------------- */
00244 /*      If the user provided his own error handling function, then call */
00245 /*      it, otherwise print the error to stderr and return.             */
00246 /* -------------------------------------------------------------------- */
00247     if( gpfnCPLErrorHandler )
00248         gpfnCPLErrorHandler(CE_Debug, CPLE_None, pszMessage);
00249 
00250     VSIFree( pszMessage );
00251 }
00252 
00253 /**********************************************************************
00254  *                          CPLErrorReset()
00255  **********************************************************************/
00256 
00264 void    CPLErrorReset()
00265 {
00266     gnCPLLastErrNo = CPLE_None;
00267     gszCPLLastErrMsg[0] = '\0';
00268     geCPLLastErrType = CE_None;
00269 }
00270 
00271 
00272 /**********************************************************************
00273  *                          CPLGetLastErrorNo()
00274  **********************************************************************/
00275 
00285 int     CPLGetLastErrorNo()
00286 {
00287     return gnCPLLastErrNo;
00288 }
00289 
00290 /**********************************************************************
00291  *                          CPLGetLastErrorType()
00292  **********************************************************************/
00293 
00303 CPLErr CPLGetLastErrorType()
00304 {
00305     return geCPLLastErrType;
00306 }
00307 
00308 /**********************************************************************
00309  *                          CPLGetLastErrorMsg()
00310  **********************************************************************/
00311 
00323 const char* CPLGetLastErrorMsg()
00324 {
00325     return gszCPLLastErrMsg;
00326 }
00327 
00328 /************************************************************************/
00329 /*                       CPLDefaultErrorHandler()                       */
00330 /************************************************************************/
00331 
00332 void CPLDefaultErrorHandler( CPLErr eErrClass, int nError, 
00333                              const char * pszErrorMsg )
00334 
00335 {
00336     static int       bLogInit = FALSE;
00337     static FILE *    fpLog = stderr;
00338 
00339     if( !bLogInit )
00340     {
00341         bLogInit = TRUE;
00342 
00343         fpLog = stderr;
00344         if( getenv( "CPL_LOG" ) != NULL )
00345         {
00346             fpLog = fopen( getenv("CPL_LOG"), "wt" );
00347             if( fpLog == NULL )
00348                 fpLog = stderr;
00349         }
00350     }
00351 
00352     if( eErrClass == CE_Debug )
00353         fprintf( fpLog, "%s\n", pszErrorMsg );
00354     else if( eErrClass == CE_Warning )
00355         fprintf( fpLog, "Warning %d: %s\n", nError, pszErrorMsg );
00356     else
00357         fprintf( fpLog, "ERROR %d: %s\n", nError, pszErrorMsg );
00358 
00359     fflush( fpLog );
00360 }
00361 
00362 /************************************************************************/
00363 /*                        CPLQuietErrorHandler()                        */
00364 /************************************************************************/
00365 
00366 void CPLQuietErrorHandler( CPLErr eErrClass , int nError, 
00367                            const char * pszErrorMsg )
00368 
00369 {
00370     if( eErrClass == CE_Debug )
00371         CPLDefaultErrorHandler( eErrClass, nError, pszErrorMsg );
00372 }
00373 
00374 /**********************************************************************
00375  *                          CPLSetErrorHandler()
00376  **********************************************************************/
00377 
00407 CPLErrorHandler CPLSetErrorHandler( CPLErrorHandler pfnErrorHandler )
00408 {
00409     CPLErrorHandler     pfnOldHandler = gpfnCPLErrorHandler;
00410     
00411     gpfnCPLErrorHandler = pfnErrorHandler;
00412 
00413     return pfnOldHandler;
00414 }
00415 
00416 
00417 
00418 /************************************************************************/
00419 /*                        CPLPushErrorHandler()                         */
00420 /************************************************************************/
00421 
00433 void CPLPushErrorHandler( CPLErrorHandler pfnErrorHandler )
00434 
00435 {
00436     CPLErrorHandlerNode         *psNode;
00437 
00438     psNode = (CPLErrorHandlerNode *) VSIMalloc(sizeof(CPLErrorHandlerNode));
00439     psNode->psNext = psHandlerStack;
00440     psNode->pfnHandler = gpfnCPLErrorHandler;
00441 
00442     psHandlerStack = psNode;
00443 
00444     CPLSetErrorHandler( pfnErrorHandler );
00445 }
00446 
00447 /************************************************************************/
00448 /*                         CPLPopErrorHandler()                         */
00449 /************************************************************************/
00450 
00458 void CPLPopErrorHandler()
00459 
00460 {
00461     if( psHandlerStack != NULL )
00462     {
00463         CPLErrorHandlerNode     *psNode = psHandlerStack;
00464 
00465         psHandlerStack = psNode->psNext;
00466         CPLSetErrorHandler( psNode->pfnHandler );
00467         VSIFree( psNode );
00468     }
00469 }
00470 
00471 /************************************************************************/
00472 /*                             _CPLAssert()                             */
00473 /*                                                                      */
00474 /*      This function is called only when an assertion fails.           */
00475 /************************************************************************/
00476 
00489 void _CPLAssert( const char * pszExpression, const char * pszFile,
00490                  int iLine )
00491 
00492 {
00493     CPLError( CE_Fatal, CPLE_AssertionFailed,
00494               "Assertion `%s' failed\n"
00495               "in file `%s', line %d\n",
00496               pszExpression, pszFile, iLine );
00497 }
00498 

Generated at Thu Jul 5 09:16:11 2001 for GDAL by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000