TeAgnostic.h

Go to the documentation of this file.
00001 /************************************************************************************
00002 TerraLib - a library for developing GIS applications.
00003 Copyright � 2001-2007 INPE and Tecgraf/PUC-Rio.
00004 
00005 This code is part of the TerraLib library.
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Lesser General Public
00008 License as published by the Free Software Foundation; either
00009 version 2.1 of the License, or (at your option) any later version.
00010 
00011 You should have received a copy of the GNU Lesser General Public
00012 License along with this library.
00013 
00014 The authors reassure the license terms regarding the warranties.
00015 They specifically disclaim any warranties, including, but not limited to,
00016 the implied warranties of merchantability and fitness for a particular purpose.
00017 The library provided hereunder is on an "as is" basis, and the authors have no
00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00020 indirect, special, incidental, or consequential damages arising out of the use
00021 of this library and its documentation.
00022 *************************************************************************************/
00023 
00024 /**
00025  * @file TeAgnostic.h
00026  * @brief This file contains a set of macros, routines and classes to deal with
00027  * system checking and logging facility.
00028  * They should NOT be used by anyone because the support and interfaces 
00029  * can be changed in future. THIS IS FOR INTERNAL USE ONLY.
00030  * @author Emiliano F. Castejon <castejon@dpi.inpe.br>
00031  *
00032  * @note The following macros will be used:
00033  * 
00034  * @param TEAGN_DEBUG_MODE If defined, debug code macros will be compiled and
00035  * used or if not defined the compiler debug flag will be used.
00036  * @param TEAGN_ENABLE_STDOUT_LOG If defined, messages also will be logged
00037  * to STDOUT ( otherwise only TeErrorLog will log messages )
00038  * or if not defined the compiler debug flag will be used.
00039  */
00040 
00041 #ifndef TEAGNOSTIC_H
00042   #define TEAGNOSTIC_H
00043 
00044   #include <sstream>
00045   #include <string>
00046   #include <iostream>
00047   
00048   #include "TeException.h"
00049   #include "TeErrorLog.h"   
00050 
00051   /**
00052    * @brief TeAgnostic debug mode selection based on NDEBUG define.
00053    */
00054   #ifndef TEAGN_DEBUG_MODE
00055     #ifndef NDEBUG
00056       /** @brief Debug mode selection flag. */
00057       #define TEAGN_DEBUG_MODE
00058       
00059       /** @brief STDOUT logging selection flag. */
00060       #ifndef TEAGN_ENABLE_STDOUT_LOG
00061         #define TEAGN_ENABLE_STDOUT_LOG
00062       #endif
00063     #endif
00064   #endif   
00065 
00066   /**
00067    * @brief Logs a message to stdout
00068    *
00069    * @param message Message to be logged.
00070    */
00071   #ifdef TEAGN_ENABLE_STDOUT_LOG
00072     #define TEAGN_LOGMSG_STDOUT( message ) \
00073       std::cout << std::endl << "Message : " \
00074         << __FILE__ \
00075         << ":" << __LINE__ \
00076         << " - " << TeAgnostic::to_string( message ) \
00077         << std::endl;
00078   #else
00079     #define TEAGN_LOGMSG_STDOUT( message ) {};
00080   #endif
00081 
00082     /**
00083     * @brief Logs a error message to stderr
00084     *
00085     * @param message Message to be logged.
00086     */
00087   #ifdef TEAGN_ENABLE_STDOUT_LOG
00088     #define TEAGN_LOGERR_STDOUT( message ) \
00089       std::cerr << std::endl << "Error : " \
00090         << __FILE__ \
00091         << ":" << __LINE__ \
00092         << " - " << TeAgnostic::to_string( message ) \
00093         << std::endl;
00094   #else
00095     #define TEAGN_LOGERR_STDOUT( message ) {};
00096   #endif
00097 
00098     /**
00099     * @brief Logs a warning message to stdout
00100     *
00101     * @param message Message to be logged.
00102     */
00103   #ifdef TEAGN_ENABLE_STDOUT_LOG
00104     #define TEAGN_LOGWARN_STDOUT( message ) \
00105       std::cout << std::endl << "Warning : " \
00106         << __FILE__ \
00107         << ":" << __LINE__ \
00108         << " - " << TeAgnostic::to_string( message ) \
00109         << std::endl;
00110   #else
00111     #define TEAGN_LOGWARN_STDOUT( message ) {};
00112   #endif
00113         
00114 
00115   /**
00116    * @brief Logs a message.
00117    *
00118    * @param message Message to be logged.
00119    */
00120   #define TEAGN_LOGMSG( message ) \
00121   { \
00122     TeErrorLog::instance().insert( LOG_MESSAGE, \
00123       TeAgnostic::to_string( message ) ); \
00124     TEAGN_LOGMSG_STDOUT( message ); \
00125   };
00126 
00127   /**
00128    * @brief Logs a message.
00129    *
00130    * @param message Message to be logged.
00131    */
00132   #define TEAGN_LOGERR( message ) \
00133   { \
00134     TeErrorLog::instance().insert( UNKNOWN_ERROR_TYPE, \
00135       TeAgnostic::to_string( message ) ); \
00136     TEAGN_LOGERR_STDOUT( message ); \
00137   };
00138       
00139   /**
00140    * @brief Logs a warning message.
00141    *
00142    * @param message Message to be logged.
00143    */
00144   #define TEAGN_LOGWARN( message ) \
00145   { \
00146     TeErrorLog::instance().insert( LOG_MESSAGE, \
00147      TeAgnostic::to_string( message ) ); \
00148     TEAGN_LOGWARN_STDOUT( message ); \
00149   };
00150       
00151   /**
00152    * @brief Logs a message to stderr and throws.
00153    *
00154    * @param message Message to be logged.
00155    */
00156   #define TEAGN_LOG_AND_THROW( message ) \
00157   { \
00158     TEAGN_LOGERR_STDOUT( message ); \
00159     throw TeException( UNKNOWN_ERROR_TYPE, \
00160       TeAgnostic::to_string( message ), false ); \
00161   };
00162       
00163   /**
00164    * @brief Checks if value is true and throws an exception if not.
00165    *
00166    * @param value Value to be checked.
00167    * @param message Message to be logged.
00168    */
00169   #define TEAGN_TRUE_OR_THROW( value , message ) \
00170     if( ( value ) == 0 ) { \
00171       TEAGN_LOGERR_STDOUT( TeAgnostic::to_string( message ) + \
00172         " - " + TeAgnostic::to_string( #value ) ); \
00173       throw TeException( UNKNOWN_ERROR_TYPE, \
00174         TeAgnostic::to_string( message ), false ); \
00175     };      
00176 
00177   /**
00178    * @brief Variable watching.
00179    *
00180    * @param variable Variable to be logged.
00181    */
00182   #define TEAGN_WATCH( variable ) \
00183     { \
00184       TEAGN_LOGMSG( "WATCH - " + TeAgnostic::to_string( #variable ) + \
00185         "=[" + TeAgnostic::to_string( variable ) +"]" ); \
00186     };
00187 
00188   /**
00189    * @brief Checks if value is true and logs an warning message if not.
00190    *
00191    * @param value Value to be checked.
00192    * @param message Message to be logged.
00193    */
00194   #define TEAGN_TRUE_OR_LOG( value , message ) \
00195     if( ( value ) == 0 ) { \
00196       TEAGN_LOGWARN( TeAgnostic::to_string( message ) + \
00197         " - " + TeAgnostic::to_string( #value ) ); \
00198     };
00199 
00200   /**
00201    * @brief Checks if value is true. For false values a warning message will be logged 
00202    * and a return of context with false value will be done.
00203    *
00204    * @param value Value to be checked.
00205    * @param message Message to be logged.
00206    */
00207   #define TEAGN_TRUE_OR_RETURN( value , message ) \
00208     if( ( value ) == 0 ) { \
00209       TEAGN_LOGWARN( TeAgnostic::to_string( message ) + \
00210         " - " + TeAgnostic::to_string( #value ) ); \
00211       return false; \
00212     };
00213     
00214   /**
00215    * @brief Checks if value is false. For true values a warning message 
00216    * will be logged 
00217    * and a return of context with false value will be done.
00218    *
00219    * @param value Value to be checked.
00220    * @param message Message to be logged.
00221    */
00222   #define TEAGN_FALSE_OR_RETURN( value , message ) \
00223     if( ( value ) != 0 ) { \
00224       TEAGN_LOGWARN( TeAgnostic::to_string( message ) + \
00225         " - " + TeAgnostic::to_string( #value ) ); \
00226       return false; \
00227     };    
00228 
00229   /**
00230    * @brief Logs a warning message will and return false.
00231    *
00232    * @param message Message to be logged.
00233    */
00234   #define TEAGN_LOG_AND_RETURN( message ) \
00235     { \
00236       TEAGN_LOGWARN( message ); \
00237       return false; \
00238     };
00239 
00240   /**
00241    * @brief Checks if value is false and logs an warning message if not.
00242    *
00243    * @param value Value to be checked.
00244    * @param message Message to be logged.
00245    */
00246   #define TEAGN_FALSE_OR_LOG( value , message ) \
00247     if( ( value ) != 0 ) { \
00248       TEAGN_LOGWARN( TeAgnostic::to_string( message ) + \
00249         " - " + TeAgnostic::to_string( #value ) ); \
00250     };
00251 
00252   /**
00253    * @brief Checks if two values are equal and throws an exception if not.
00254    *
00255    * @param value1 Value to be checked.
00256    * @param value2 Value to be checked.
00257    * @param message Message to be logged.
00258    */
00259   #define TEAGN_CHECK_EQUAL( value1 , value2 , message ) \
00260     TEAGN_TRUE_OR_THROW( ( ((double)( value1 ) ) == ((double)( value2 ) ) ), \
00261     std::string( "Values must be equal [" ) + \
00262     TeAgnostic::to_string( value1 ) + "!=" + \
00263     TeAgnostic::to_string( value2 ) + "] - " + \
00264     TeAgnostic::to_string( message ) );
00265 
00266   /**
00267    * @brief Checks if two values are diferent and throws an exception if not.
00268    *
00269    * @param value1 Value to be checked.
00270    * @param value2 Value to be checked.
00271    * @param message Message to be logged.
00272    */
00273   #define TEAGN_CHECK_NOTEQUAL( value1 , value2 , message ) \
00274     TEAGN_TRUE_OR_THROW( ( ((double)( value1 )) != ((double)( value2 )) ), \
00275     std::string( "Values can't be equal [" ) + \
00276     TeAgnostic::to_string( #value1 ) + std::string( "==" ) + \
00277     TeAgnostic::to_string( #value2 ) + std::string( "==" ) + \
00278     TeAgnostic::to_string( value1 ) + std::string( "]" ) );
00279 
00280   /**
00281    * @brief  Checks if two values are equal ( within an EPS ) and
00282    *  throws an exception if not.
00283    *
00284    * @param value1 Value to be checked.
00285    * @param value2 Value to be checked.
00286    * @param eps EPS ( threshold )
00287    * @param message Message to be logged.
00288    */
00289   #define TEAGN_CHECK_EPS( value1 , value2 , eps , message ) \
00290     { \
00291       TEAGN_TRUE_OR_THROW( ( (eps) >= 0), "Invalid eps" ); \
00292       double TEAGN_CHECK_EPS_double_diff = 0; \
00293       double TEAGN_CHECK_EPS_double_value1 = (double)(value1); \
00294       double TEAGN_CHECK_EPS_double_value2 = (double)(value2); \
00295       double TEAGN_CHECK_EPS_double_eps = (double)(eps); \
00296       if( TEAGN_CHECK_EPS_double_value1 < TEAGN_CHECK_EPS_double_value2 ) { \
00297         TEAGN_CHECK_EPS_double_diff = ( TEAGN_CHECK_EPS_double_value2 - \
00298           TEAGN_CHECK_EPS_double_value1 ); \
00299       } else { \
00300         TEAGN_CHECK_EPS_double_diff = ( TEAGN_CHECK_EPS_double_value1 - \
00301           TEAGN_CHECK_EPS_double_value2 ); \
00302       }; \
00303       TEAGN_TRUE_OR_THROW( \
00304         TEAGN_CHECK_EPS_double_diff <= TEAGN_CHECK_EPS_double_eps, \
00305         std::string( "Values are not equal: " ) + \
00306         TeAgnostic::to_string( #value1 ) + \
00307         std::string( "=[") + \
00308         TeAgnostic::to_string( TEAGN_CHECK_EPS_double_value1 ) + \
00309         std::string( "] " ) + \
00310         TeAgnostic::to_string( #value2 ) + \
00311         std::string( "=[") + \
00312         TeAgnostic::to_string( TEAGN_CHECK_EPS_double_value2 ) + \
00313         std::string( "] eps=[") + \
00314         TeAgnostic::to_string( TEAGN_CHECK_EPS_double_eps ) + \
00315         std::string( "] diff=[") + \
00316         TeAgnostic::to_string( TEAGN_CHECK_EPS_double_diff ) + \
00317         std::string( "] - " ) + \
00318         TeAgnostic::to_string( message ) \
00319         ); \
00320     };
00321 
00322   /**
00323    * @brief Throws an exception for not implemented source.
00324    */
00325   #define TEAGN_NOT_IMPLEMENTED \
00326     TEAGN_LOG_AND_THROW( "Not Implemented." );
00327 
00328   /**
00329    *  @brief Checks if Debug mode is enabled and throws an exception if not.
00330    */
00331   #define TEAGN_DEBUG_MODE_CHECK \
00332     TEAGN_TRUE_OR_THROW( TeAgnostic::debugModeCheck() , \
00333     "Code not compiled with debug" );
00334     
00335   /**
00336    * @brief Checks if value is true and throws an exception if not.
00337    *
00338    * @note This macro will be disabled for non debug mode.
00339    *
00340    * @param value Value to be checked.
00341    * @param message Message to be logged.
00342    */
00343   #ifdef TEAGN_DEBUG_MODE
00344     #define TEAGN_DEBUG_CONDITION( value , message ) \
00345       TEAGN_TRUE_OR_THROW( value , message );
00346   #else
00347     #define TEAGN_DEBUG_CONDITION( value , message );
00348   #endif
00349   
00350   /**
00351    * @brief Checks if value is true. For false values a warning message will be logged 
00352    * and a return of context with false value will be done.
00353    *
00354    * @note This macro will be disabled for non debug mode.
00355    *
00356    * @param value Value to be checked.
00357    * @param message Message to be logged.
00358    */
00359   #ifdef TEAGN_DEBUG_MODE
00360     #define TEAGN_DEBUG_RETURN( value , message ) \
00361       TEAGN_TRUE_OR_RETURN( value , message );
00362   #else
00363     #define TEAGN_DEBUG_RETURN( value , message );
00364   #endif  
00365 
00366   /**
00367    * @brief This namespace contains a set of routines and classes to deal with
00368    *  system checking and logging facility.
00369    * @ingroup Utils
00370    */
00371   namespace TeAgnostic{
00372 
00373     /**
00374      * @brief Data conversion to string.
00375      *
00376      * @param data Data to be converted.
00377      * @return The converted string.
00378      */
00379      template< class T >
00380      std::string to_string( const T& data )
00381      {
00382         std::stringstream temp_ss;
00383         temp_ss.setf(std::ios_base::fixed);
00384         temp_ss << data;
00385         return temp_ss.str();
00386      }
00387 
00388     /**
00389      * @brief Checks if the code was compiled with debug mode.
00390      *
00391      * @return true if debug mode was used at compilation time. false if not.
00392      */
00393      TL_DLL bool debugModeCheck();
00394 
00395   };
00396 
00397 #endif

Generated on Sun Jul 29 04:01:18 2012 for TerraLib - Development Source by  doxygen 1.5.3