A debug output API with indentation and block timing. Closes #1889.

This commit is contained in:
imonroe 2006-10-25 06:34:45 +00:00
parent 1df4de1571
commit 39ea53366b
1 changed files with 242 additions and 0 deletions

View File

@ -0,0 +1,242 @@
/*------------------------------------------------------------------------------
Copyright (c) 2003-2005 Max Howell <max.howell@methylblue.com>
(c) 2006 Media Development Loan Fund
This file is part of the Campcaster project.
http://campcaster.campware.org/
To report bugs, send an e-mail to bugs@campware.org
Campcaster 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 2 of the License, or
(at your option) any later version.
Campcaster 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 Campcaster; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: fgerlits $
Version : $Revision: 2329 $
Location : $URL: svn://code.campware.org/campcaster/trunk/campcaster/src/products/scheduler/src/PlaylistEvent.cxx $
------------------------------------------------------------------------------*/
#include "configure.h"
#include <iostream>
#include <sys/time.h>
#ifndef DEBUG_PREFIX
#define CMP_PREFIX ""
#else
#define CMP_PREFIX "[" DEBUG_PREFIX "] "
#endif
/**
* @namespace LiveSupport::Core::Debug
* @short A debug output API with indentation and block timing.
* @author Max Howell <max.howell@methylblue.com>
* @author Ian Monroe <ian@monroe.nu>
*/
namespace LiveSupport {
namespace Core {
namespace Debug {
int indentAmount = 0;
}
}
}
using namespace LiveSupport;
using namespace LiveSupport::Core;
#ifndef YDEBUG
class NoDebugStream;
typedef NoDebugStream & (*NDBGFUNC)(NoDebugStream &);
class NoDebugStream {
public:
/// Default constructor.
NoDebugStream() {}
~NoDebugStream() {}
NoDebugStream& operator<<(NDBGFUNC) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(short int ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(unsigned short int ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(char ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(unsigned char ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(int ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(unsigned int ) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream &operator<<(const char *) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream& operator<<(const void *) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream& operator<<(void *) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream& operator<<(double) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream& operator<<(long) { return *this; }
/**
* Does nothing.
* @return this stream
*/
NoDebugStream& operator<<(unsigned long) { return *this; }
NoDebugStream& operator<<(std::string) { return *this; }
};
NoDebugStream debug() { return NoDebugStream(); }
NoDebugStream warning() { return NoDebugStream(); }
NoDebugStream error() { return NoDebugStream(); }
inline NoDebugStream &endl( NoDebugStream & s) { return s; }
#else
std::ostream& debug() { return std::cout << std::string(Debug::indentAmount, ' ') << CMP_PREFIX; }
std::ostream& warning() { return std::cout << std::string(Debug::indentAmount, ' ') << CMP_PREFIX << "[WARNING!] "; }
std::ostream& error() { return std::cout << std::string(Debug::indentAmount, ' ') << CMP_PREFIX << "[ERROR!] "; }
#endif
using std::endl;
namespace LiveSupport { namespace Core {
namespace Debug
{
/**
* @class Debug::Block
* @short Use this to label sections of your code
*
* Usage:
* #define DEBUG_PREFIX "Prefix"
* #include "LiveSupport/Core/Debug.h"
*
* void function()
* {
* ...
* {
* Debug::Block myBlock( "section" );
*
* debug() << "output1" << endl;
* debug() << "output2" << endl;
* }
* ...
* }
*
* Will output:
*
* BEGIN: section
* [prefix] output1
* [prefix] output2
* END: section - Took 0.1s
*
* Its not thread-safe with the indentation count. But a race condition
* involving indentation width isn't a big deal.
*/
class Block
{
public:
Block( std::string label )
: m_label( label )
{
gettimeofday( &m_start, 0 );
debug() << "BEGIN: " << m_label << endl;
indentAmount += 2; //critical section
}
~Block()
{
timeval end;
gettimeofday( &end, 0 );
end.tv_sec -= m_start.tv_sec;
if( end.tv_usec < m_start.tv_usec) {
// Manually carry a one from the seconds field.
end.tv_usec += 1000000;
end.tv_sec--;
}
end.tv_usec -= m_start.tv_usec;
double duration = double(end.tv_sec) + (double(end.tv_usec) / 1000000.0);
indentAmount -= 2; //critical section
debug() << "END__: " << m_label << " - Took " << duration << "s\n";
}
private:
const std::string m_label;
timeval m_start;
};
/**
* @name Debug::stamp()
* @short To facilitate crash/freeze bugs, by making it easy to mark code that has been processed
*
* Usage:
*
* {
* Debug::stamp();
* function1();
* Debug::stamp();
* function2();
* Debug::stamp();
* }
*
* Will output (assuming the crash occurs in function2()
*
* app: Stamp: 1
* app: Stamp: 2
*
*/
inline void stamp()
{
static int n = 0;
debug() << "| Stamp: " << ++n << endl;
}
}
} } //LiveSupport and Core namespaces
#define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( __PRETTY_FUNCTION__ );