/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community. If not, see .
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see
* or contact Peter Baumann via .
/
/**
* INCLUDE: rmdebug.hh
*
* PURPOSE:
* Contains debug stuff.
*
* COMMENTS:
*
*/
#ifndef _RMDEBUG_
#define _RMDEBUG_
#ifdef __VISUALC__
#include
#else
#include
#endif
#include "raslib/rminit.hh"
#include "raslib/rm.hh"
extern int RManDebug;
extern int RManBenchmark;
#ifdef RMANDEBUG
#define RMDBGIF( levell, module, cls, text ) \
if (RMDebug::debugOutput( levell, module, cls )) { text }
#define RMDBGENTER( levell, module, cls, text ) \
RMCounter rmCounter(levell, module, cls); \
if (RMDebug::debugOutput( levell, module, cls )) { \
RMInit::dbgOut << "ENTER "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
}
#define RMDBGMIDDLE( levell, module, cls, text ) \
if (RMDebug::debugOutput( levell, module, cls )) { \
RMInit::dbgOut << "MIDDLE "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
}
#define RMDBGONCE( levell, module, cls, text ) \
RMCounter rmCounter(levell, module, cls); \
if (RMDebug::debugOutput(levell, module, cls)) \
{ \
RMInit::dbgOut << "ONCE "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; \
RMDebug::indentLine(); \
RMInit::dbgOut << text << endl << std::flush; \
}
#define RMDBGEXIT( levell, module, cls, text ) \
if (RMDebug::debugOutput( levell, module, cls )) { \
RMInit::dbgOut << "EXIT "; RMInit::dbgOut.width(18); RMInit::dbgOut.setf(ios::left, ios::adjustfield); RMInit::dbgOut << cls << " "; RMDebug::indentLine(); RMInit::dbgOut << text << endl << std::flush; \
}
#define RMDBCLASS( t1, t2, t3, t4, t5 ) RMDebug localRMDebug = RMDebug( t1, t2, t3, t4, t5 );
#else
// Note: some parts of the code rely on these to be terminated by a ';'!
#define RMDBGENTER( level, module, cls, text ) ;
#define RMDBGMIDDLE( level, module, cls, text ) ;
#define RMDBGONCE( level, module, cls, text ) ;
#define RMDBGEXIT( level, module, cls, text ) ;
#define RMDBGIF( level, module, cls, text) ;
#define RMDBCLASS( t1, t2, t3, t4, t5 ) ;
#endif
#ifdef RMANBENCHMARK
#define RMTIMER(class, func) RMTimer localRMTimer = RMTimer(class, func);
#else
#define RMTIMER(class, func)
#endif
//@ManMemo: Module: {\bf raslib}.
/*@Doc:
RMDebug is not strictly part of RasLib. It is a class used for
generating debug output if compiling with RMANDEBUG defined. One way
of using it is to put the following at the beginning of a function:
{\tt RMDebug localRMDebug = RMDebug("className", "functionName",
"moduleName", __FILE__, __LINE__");}
This can be patched in automatically by a modified funchead.pl script.
{\bf Functionality}
Debug output printing class name, function name, module name, file
name and line number given as parameters to the constructor is
created, whenever the constructor is called. The destructor
outputs class name and function name. If the static members {\tt
debugModules} or {\tt debugClasses} are set, then only modules
which are mentioned in the array of strings {\tt debugModules} or
classes which are mentioned {\tt debugClasses} give debug output.
{\tt debugModules} and {\tt debugClasses} can either be read from
files named "rmdbmodules" and "rmdbclasses" or from the environment
variables RMDBGMODULES and RMDBGCLASSES. The environment variables
override the files. The contents of the files / variables are the
names of the modules / classes separated by whitespace (space,
newlines, ...). In the case of the modules each modulename may
be followed by "," to set the debug level for that
module explizitly, otherwise the default is used.
{\bf Interdependencies}
If only certain modules or classes are to be debugged, RMDebug
has to be initialized in {\Ref RMInit}. This is done by reading
the files {\tt rmdbmodules} and {\tt rmdbclasses}. The files
should contain names of modules resp. classes to be debugged, each
(including the last one!) followed by end of line. */
/**
* \defgroup RMs RM Classes
*/
/**
* \ingroup RMs
*/
class RMDebug : public RM_Class
{
public:
/// constructor, initializes members and prints message.
RMDebug(const char* newClass, const char* newFunc, const char* newModule,
const char* newFile, int newLine);
/// constructor taking an identifier to the module for more efficiency
RMDebug(int newLevel, const char* newClass, const char* newFun, int newModuleNum,
const char* newFile, int newLine);
/// destructor, prints message.
~RMDebug(void);
/// for initializing modules and classes to debug.
static int initRMDebug(void);
/// get the debug level of a module by its number
static inline int getModuleDebugLevel(int modNum) {
return allModuleLevels[modNum];
}
/// get the name of a module by its number
static inline const char* getModuleName(int modNum) {
return allModuleNames[modNum];
}
/// indent by the amount specified by level
static inline void indentLine(void) {
for (int i=0; i