mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-25 19:07:45 +00:00
New debugstream.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7832 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
fbdee86f79
commit
8d098dcb56
@ -1,3 +1,7 @@
|
||||
2003-09-26 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* boost/test/detail/nullstream.hpp: new file
|
||||
|
||||
2003-08-28 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* boost/config/compiler/gcc.hpp: allow for gcc 3.4
|
||||
|
85
boost/boost/test/detail/nullstream.hpp
Normal file
85
boost/boost/test/detail/nullstream.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
// (C) Copyright Gennadiy Rozental 2002.
|
||||
// (C) Copyright Daryle Walker 2000-2001.
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// File : $RCSfile: nullstream.hpp,v $
|
||||
//
|
||||
// Version : $Id: nullstream.hpp,v 1.3 2003/02/15 21:57:25 rogeeff Exp $
|
||||
//
|
||||
// Description : simulate /dev/null stream
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_NULLSTREAM_HPP
|
||||
#define BOOST_NULLSTREAM_HPP
|
||||
|
||||
#include <ostream> // for std::basic_ostream
|
||||
#include <streambuf> // for std::basic_streambuf
|
||||
#include <string> // for std::char_traits
|
||||
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** basic_nullbuf ************** //
|
||||
// ************************************************************************** //
|
||||
// Class for a buffer that reads nothing and writes to nothing.
|
||||
// Idea from an Usenet post by Tom <the_wid@my-deja.com> at
|
||||
// 27 Oct 2000 14:06:21 GMT on comp.lang.c++.
|
||||
|
||||
template<typename CharType, class CharTraits = ::std::char_traits<CharType> >
|
||||
class basic_nullbuf : public ::std::basic_streambuf<CharType, CharTraits> {
|
||||
typedef ::std::basic_streambuf<CharType, CharTraits> base_type;
|
||||
public:
|
||||
// Types
|
||||
typedef typename base_type::char_type char_type;
|
||||
typedef typename base_type::traits_type traits_type;
|
||||
typedef typename base_type::int_type int_type;
|
||||
typedef typename base_type::pos_type pos_type;
|
||||
typedef typename base_type::off_type off_type;
|
||||
|
||||
// Use automatic default constructor and destructor
|
||||
|
||||
protected:
|
||||
// The default implementations of the miscellaneous virtual
|
||||
// member functions are sufficient.
|
||||
|
||||
// The default implementations of the input & putback virtual
|
||||
// member functions, being nowhere but EOF, are sufficient.
|
||||
|
||||
// The output virtual member functions need to be changed to
|
||||
// accept anything without any problems, instead of being at EOF.
|
||||
virtual ::std::streamsize xsputn( char_type const* /*s*/, ::std::streamsize n ) { return n; } // "s" is unused
|
||||
virtual int_type overflow( int_type c = traits_type::eof() ) { return traits_type::not_eof( c ); }
|
||||
};
|
||||
|
||||
typedef basic_nullbuf<char> nullbuf;
|
||||
typedef basic_nullbuf<wchar_t> wnullbuf;
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** basic_onullstream ************** //
|
||||
// ************************************************************************** //
|
||||
// Output streams based on basic_nullbuf.
|
||||
|
||||
template< typename CharType, class CharTraits = ::std::char_traits<CharType> >
|
||||
class basic_onullstream : private boost::base_from_member<basic_nullbuf<CharType, CharTraits> >
|
||||
, public ::std::basic_ostream<CharType, CharTraits> {
|
||||
typedef boost::base_from_member<basic_nullbuf<CharType, CharTraits> > pbase_type;
|
||||
typedef ::std::basic_ostream<CharType, CharTraits> base_type;
|
||||
public:
|
||||
// Constructor
|
||||
basic_onullstream() : pbase_type(), base_type( &this->pbase_type::member ) {}
|
||||
};
|
||||
|
||||
typedef basic_onullstream<char> onullstream;
|
||||
typedef basic_onullstream<wchar_t> wonullstream;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_NULLSTREAM_HPP
|
@ -185,6 +185,7 @@ src/mathed/ref_inset.C
|
||||
src/paragraph.C
|
||||
src/paragraph_funcs.C
|
||||
src/rowpainter.C
|
||||
src/support/path_defines.C
|
||||
src/text.C
|
||||
src/text2.C
|
||||
src/text3.C
|
||||
|
@ -1,3 +1,12 @@
|
||||
2003-09-26 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* lyx_main.C: remove the glboal debug object
|
||||
|
||||
* debug.h: adjust for new debugstream
|
||||
|
||||
* debug.C: adjust for new debugstream and keep the global debug
|
||||
object here.
|
||||
|
||||
2003-09-22 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* paragraph_pimpl.h: add #include "lyxfont.h". Needed by earlier versions
|
||||
@ -20,13 +29,13 @@
|
||||
|
||||
* kbsequence.C (addkey): return a FuncRequest
|
||||
|
||||
* kbmap.h (kb_key): struct var FuncRequest instead of int action.
|
||||
* kbmap.h (kb_key): struct var FuncRequest instead of int action.
|
||||
|
||||
* kbmap.C (bind): take a FuncRequest as arg, adjust
|
||||
(read): adjust
|
||||
(lookup): adjust
|
||||
(defkey): change to take a FuncRequest as arg, adjust
|
||||
(findbinding): take a FuncRequest as arg, adjust.
|
||||
(findbinding): take a FuncRequest as arg, adjust.
|
||||
|
||||
* funcrequest.h (operator=): added
|
||||
|
||||
|
18
src/debug.C
18
src/debug.C
@ -16,6 +16,7 @@
|
||||
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
using lyx::support::ascii_lowercase;
|
||||
@ -71,16 +72,7 @@ int const numErrorTags = sizeof(errorTags)/sizeof(error_item);
|
||||
} // namespace anon
|
||||
|
||||
|
||||
Debug::type const Debug::ANY = Debug::type(
|
||||
Debug::INFO | Debug::INIT | Debug::KEY | Debug::GUI |
|
||||
Debug::PARSER | Debug::LYXRC | Debug::KBMAP | Debug::LATEX |
|
||||
Debug::MATHED | Debug::FONT | Debug::TCLASS | Debug::LYXVC |
|
||||
Debug::LYXSERVER | Debug::ROFF | Debug::ACTION | Debug::LYXLEX |
|
||||
Debug::DEPEND | Debug::INSETS | Debug::FILES | Debug::WORKAREA |
|
||||
Debug::INSETTEXT | Debug::GRAPHICS | Debug::CHANGES | Debug::EXTERNAL);
|
||||
|
||||
|
||||
Debug::type Debug::value(string const & val)
|
||||
lyx_debug_trait::type lyx_debug_trait::value(string const & val)
|
||||
{
|
||||
type l = Debug::NONE;
|
||||
string v(val);
|
||||
@ -106,7 +98,7 @@ Debug::type Debug::value(string const & val)
|
||||
}
|
||||
|
||||
|
||||
void Debug::showLevel(ostream & os, Debug::type level)
|
||||
void lyx_debug_trait::showLevel(ostream & os, lyx_debug_trait::type level)
|
||||
{
|
||||
// Show what features are traced
|
||||
for (int i = 0; i < numErrorTags ; ++i) {
|
||||
@ -122,7 +114,7 @@ void Debug::showLevel(ostream & os, Debug::type level)
|
||||
}
|
||||
|
||||
|
||||
void Debug::showTags(ostream & os)
|
||||
void lyx_debug_trait::showTags(ostream & os)
|
||||
{
|
||||
for (int i = 0; i < numErrorTags ; ++i)
|
||||
os << setw(7) << errorTags[i].level
|
||||
@ -130,3 +122,5 @@ void Debug::showTags(ostream & os)
|
||||
<< " " << _(errorTags[i].desc) << '\n';
|
||||
os.flush();
|
||||
}
|
||||
|
||||
LyXErr lyxerr(std::cerr.rdbuf());
|
||||
|
28
src/debug.h
28
src/debug.h
@ -15,12 +15,13 @@
|
||||
|
||||
|
||||
#include "support/std_string.h"
|
||||
#include "support/debugstream.h"
|
||||
|
||||
/** Ideally this should have been a namespace, but since we try to be
|
||||
compilable on older C++ compilators too, we use a struct instead.
|
||||
This is all the different debug levels that we have.
|
||||
*/
|
||||
struct Debug {
|
||||
struct lyx_debug_trait {
|
||||
///
|
||||
enum type {
|
||||
///
|
||||
@ -72,15 +73,19 @@ struct Debug {
|
||||
/// change tracking
|
||||
CHANGES = (1 << 22),
|
||||
///
|
||||
EXTERNAL = (1 << 23)
|
||||
EXTERNAL = (1 << 23),
|
||||
///
|
||||
ANY = 0xffffff
|
||||
};
|
||||
///
|
||||
static type const ANY;
|
||||
|
||||
static bool match(type a, type b) {
|
||||
return (a & b);
|
||||
}
|
||||
|
||||
/** A function to convert symbolic string names on debug levels
|
||||
to their numerical value.
|
||||
*/
|
||||
static Debug::type value(string const & val);
|
||||
static type value(string const & val);
|
||||
|
||||
/** Display the tags and descriptions of the current debug level
|
||||
of ds
|
||||
@ -95,18 +100,17 @@ struct Debug {
|
||||
|
||||
|
||||
inline
|
||||
void operator|=(Debug::type & d1, Debug::type d2)
|
||||
void operator|=(lyx_debug_trait::type & d1, lyx_debug_trait::type d2)
|
||||
{
|
||||
d1 = static_cast<Debug::type>(d1 | d2);
|
||||
d1 = static_cast<lyx_debug_trait::type>(d1 | d2);
|
||||
}
|
||||
|
||||
|
||||
#include "support/DebugStream.h"
|
||||
// std::ostream & operator<<(std::ostream & o, Debug::type t);
|
||||
|
||||
typedef basic_debugstream<lyx_debug_trait> LyXErr;
|
||||
typedef LyXErr::debug Debug;
|
||||
|
||||
|
||||
std::ostream & operator<<(std::ostream & o, Debug::type t);
|
||||
|
||||
extern DebugStream lyxerr;
|
||||
extern LyXErr lyxerr;
|
||||
|
||||
#endif
|
||||
|
@ -87,8 +87,6 @@ extern void QuitLyX();
|
||||
|
||||
extern LyXServer * lyxserver;
|
||||
|
||||
DebugStream lyxerr;
|
||||
|
||||
boost::scoped_ptr<LastFiles> lastfiles;
|
||||
|
||||
// This is the global bufferlist object
|
||||
|
@ -1,3 +1,9 @@
|
||||
2003-09-26 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* debugstream.h: add file, updated version of the DebugStream
|
||||
|
||||
* DebugStream.C,DebugStream.h: delete files
|
||||
|
||||
2003-09-25 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* filetools.C (ReplaceEnvironmentPath): rewrite to use boost::regex.
|
||||
|
@ -1,299 +0,0 @@
|
||||
/**
|
||||
* \file DebugStream.C
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Lars Gullik Bjønnes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
//#define TEST_DEBUGSTREAM
|
||||
|
||||
#include <config.h>
|
||||
|
||||
//#include "DebugStream.h"
|
||||
#include "debug.h"
|
||||
|
||||
// Since the current C++ lib in egcs does not have a standard implementation
|
||||
// of basic_streambuf and basic_filebuf we don't have to include this
|
||||
// header.
|
||||
//#define MODERN_STL_STREAMS
|
||||
#ifdef MODERN_STL_STREAMS
|
||||
#include <fstream>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
using std::ostream;
|
||||
using std::streambuf;
|
||||
using std::streamsize;
|
||||
using std::filebuf;
|
||||
using std::cerr;
|
||||
using std::ios;
|
||||
|
||||
ostream & operator<<(ostream & o, Debug::type t)
|
||||
{
|
||||
return o << int(t);
|
||||
}
|
||||
|
||||
/** This is a streambuffer that never prints out anything, at least
|
||||
that is the intention. You can call it a no-op streambuffer, and
|
||||
the ostream that uses it will be a no-op stream.
|
||||
*/
|
||||
class nullbuf : public streambuf {
|
||||
protected:
|
||||
#ifndef MODERN_STL_STREAMS
|
||||
typedef char char_type;
|
||||
typedef int int_type;
|
||||
///
|
||||
virtual int sync() { return 0; }
|
||||
#endif
|
||||
///
|
||||
virtual streamsize xsputn(char_type const *, streamsize n) {
|
||||
// fakes a purge of the buffer by returning n
|
||||
return n;
|
||||
}
|
||||
#ifdef MODERN_STL_STREAMS
|
||||
///
|
||||
virtual int_type overflow(int_type c = traits_type::eof()) {
|
||||
// fakes success by returning c
|
||||
return c == traits_type::eof() ? ' ' : c;
|
||||
}
|
||||
#else
|
||||
///
|
||||
virtual int_type overflow(int_type c = EOF) {
|
||||
// fakes success by returning c
|
||||
return c == EOF ? ' ' : c;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/** A streambuf that sends the output to two different streambufs. These
|
||||
can be any kind of streambufs.
|
||||
*/
|
||||
class teebuf : public streambuf {
|
||||
public:
|
||||
///
|
||||
teebuf(streambuf * b1, streambuf * b2)
|
||||
: streambuf(), sb1(b1), sb2(b2) {}
|
||||
protected:
|
||||
#ifdef MODERN_STL_STREAMS
|
||||
///
|
||||
virtual int sync() {
|
||||
sb2->pubsync();
|
||||
return sb1->pubsync();
|
||||
}
|
||||
///
|
||||
virtual streamsize xsputn(char_type const * p, streamsize n) {
|
||||
sb2->sputn(p, n);
|
||||
return sb1->sputn(p, n);
|
||||
}
|
||||
///
|
||||
virtual int_type overflow(int_type c = traits_type::eof()) {
|
||||
sb2->sputc(c);
|
||||
return sb1->sputc(c);
|
||||
}
|
||||
#else
|
||||
typedef char char_type;
|
||||
typedef int int_type;
|
||||
///
|
||||
virtual int sync() {
|
||||
sb2->sync();
|
||||
return sb1->sync();
|
||||
}
|
||||
///
|
||||
virtual streamsize xsputn(char_type const * p, streamsize n) {
|
||||
sb2->xsputn(p, n);
|
||||
return sb1->xsputn(p, n);
|
||||
}
|
||||
///
|
||||
virtual int_type overflow(int_type c = EOF) {
|
||||
sb2->overflow(c);
|
||||
return sb1->overflow(c);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
///
|
||||
streambuf * sb1;
|
||||
///
|
||||
streambuf * sb2;
|
||||
};
|
||||
|
||||
///
|
||||
class debugbuf : public streambuf {
|
||||
public:
|
||||
///
|
||||
debugbuf(streambuf * b)
|
||||
: streambuf(), sb(b) {}
|
||||
protected:
|
||||
#ifdef MODERN_STL_STREAMS
|
||||
///
|
||||
virtual int sync() {
|
||||
return sb->pubsync();
|
||||
}
|
||||
///
|
||||
virtual streamsize xsputn(char_type const * p, streamsize n) {
|
||||
return sb->sputn(p, n);
|
||||
}
|
||||
///
|
||||
virtual int_type overflow(int_type c = traits_type::eof()) {
|
||||
return sb->sputc(c);
|
||||
}
|
||||
#else
|
||||
typedef char char_type;
|
||||
typedef int int_type;
|
||||
///
|
||||
virtual int sync() {
|
||||
return sb->sync();
|
||||
}
|
||||
///
|
||||
virtual streamsize xsputn(char_type const * p, streamsize n) {
|
||||
return sb->xsputn(p, n);
|
||||
}
|
||||
///
|
||||
virtual int_type overflow(int_type c = EOF) {
|
||||
return sb->overflow(c);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
///
|
||||
streambuf * sb;
|
||||
};
|
||||
|
||||
|
||||
/// So that public parts of DebugStream does not need to know about filebuf
|
||||
struct DebugStream::debugstream_internal {
|
||||
/// Used when logging to file.
|
||||
filebuf fbuf;
|
||||
};
|
||||
|
||||
|
||||
/// Constructor, sets the debug level to t.
|
||||
DebugStream::DebugStream(Debug::type t)
|
||||
: ostream(new debugbuf(cerr.rdbuf())),
|
||||
dt(t), nullstream(new nullbuf), internal(0) {}
|
||||
|
||||
|
||||
/// Constructor, sets the log file to f, and the debug level to t.
|
||||
DebugStream::DebugStream(char const * f, Debug::type t)
|
||||
: ostream(new debugbuf(cerr.rdbuf())),
|
||||
dt(t), nullstream(new nullbuf),
|
||||
internal(new debugstream_internal)
|
||||
{
|
||||
internal->fbuf.open(f, ios::out|ios::app);
|
||||
delete rdbuf(new teebuf(cerr.rdbuf(),
|
||||
&internal->fbuf));
|
||||
}
|
||||
|
||||
|
||||
DebugStream::~DebugStream()
|
||||
{
|
||||
delete nullstream.rdbuf(0); // Without this we leak
|
||||
delete rdbuf(0); // Without this we leak
|
||||
delete internal;
|
||||
}
|
||||
|
||||
|
||||
/// Sets the debugstreams' logfile to f.
|
||||
void DebugStream::logFile(char const * f)
|
||||
{
|
||||
if (internal) {
|
||||
internal->fbuf.close();
|
||||
} else {
|
||||
internal = new debugstream_internal;
|
||||
}
|
||||
internal->fbuf.open(f, ios::out|ios::app);
|
||||
delete rdbuf(new teebuf(cerr.rdbuf(),
|
||||
&internal->fbuf));
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_DEBUGSTREAM
|
||||
|
||||
// Example debug stream
|
||||
DebugStream debugstream;
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
/**
|
||||
I have been running some tests on this to see how much overhead
|
||||
this kind of permanent debug code has. My conclusion is: not
|
||||
much. In all, but the most time critical code, this will have
|
||||
close to no impact at all.
|
||||
|
||||
In the tests that I have run the use of
|
||||
if (debugstream.debugging(DebugStream::INFO))
|
||||
debugstream << "some debug\n";
|
||||
has close to no overhead when the debug level is not
|
||||
DebugStream::INFO.
|
||||
|
||||
The overhead for
|
||||
debugstream.debug(DebugStream::INFO) << "some debug\n";
|
||||
is also very small when the debug level is not
|
||||
DebugStream::INFO. However the overhead for this will increase
|
||||
if complex debugging information is output.
|
||||
|
||||
The overhead when the debug level is DebugStream::INFO can be
|
||||
significant, but since we then are running in debug mode it is
|
||||
of no concern.
|
||||
|
||||
Why should we use this instead of the class Error that we already
|
||||
have? First of all it uses C++ iostream and constructs, secondly
|
||||
it will be a lot easier to output the debug info that we need
|
||||
without a lot of manual conversions, thirdly we can now use
|
||||
iomanipulators and the complete iostream formatting functions.
|
||||
pluss it will work for all types that have a operator<<
|
||||
defined, and can be used in functors that take a ostream & as
|
||||
parameter. And there should be less need for temporary objects.
|
||||
And one nice bonus is that we get a log file almost for
|
||||
free.
|
||||
|
||||
Some of the names are of course open to modifications. I will try
|
||||
to use the names we already use in LyX.
|
||||
*/
|
||||
// Just a few simple debugs to show how it can work.
|
||||
debugstream << "Debug level set to Debug::NONE\n";
|
||||
if (debugstream.debugging()) {
|
||||
debugstream << "Something must be debugged\n";
|
||||
}
|
||||
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
|
||||
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
|
||||
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
|
||||
debugstream.level(Debug::value("INFO"));
|
||||
debugstream << "Setting debug level to Debug::INFO\n";
|
||||
if (debugstream.debugging()) {
|
||||
debugstream << "Something must be debugged\n";
|
||||
}
|
||||
debugstream.debug(Debug::WARN) << "more debug(WARN)\n";
|
||||
debugstream.debug(Debug::INFO) << "even more debug(INFO)\n";
|
||||
debugstream.debug(Debug::CRIT) << "even more debug(CRIT)\n";
|
||||
debugstream.addLevel(Debug::type(Debug::CRIT |
|
||||
Debug::WARN));
|
||||
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
|
||||
debugstream[Debug::WARN] << "more debug(WARN)\n";
|
||||
debugstream[Debug::INFO] << "even more debug(INFO)\n";
|
||||
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
|
||||
debugstream.delLevel(Debug::INFO);
|
||||
debugstream << "Removing Debug::INFO\n";
|
||||
debugstream[Debug::WARN] << "more debug(WARN)\n";
|
||||
debugstream[Debug::INFO] << "even more debug(INFO)\n";
|
||||
debugstream[Debug::CRIT] << "even more debug(CRIT)\n";
|
||||
debugstream.logFile("logfile");
|
||||
debugstream << "Setting logfile to \"logfile\"\n";
|
||||
debugstream << "Value: " << 123 << " " << "12\n";
|
||||
int i = 0;
|
||||
int * p = new int;
|
||||
// note: the (void*) is needed on g++ 2.7.x since it does not
|
||||
// support partial specialization. In egcs this should not be
|
||||
// needed.
|
||||
debugstream << "automatic " << &i
|
||||
<< ", free store " << p << endl;
|
||||
delete p;
|
||||
/*
|
||||
for (int j = 0; j < 200000; ++j) {
|
||||
DebugStream tmp;
|
||||
tmp << "Test" << endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
#endif
|
@ -1,145 +0,0 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file DebugStream.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Lars Gullik Bjønnes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef DEBUGSTREAM_H
|
||||
#define DEBUGSTREAM_H
|
||||
|
||||
#include "std_ostream.h"
|
||||
|
||||
#ifdef TEST_DEBUGSTREAM
|
||||
#include <string>
|
||||
struct Debug {
|
||||
enum type {
|
||||
NONE = 0,
|
||||
INFO = (1 << 0), // 1
|
||||
WARN = (1 << 1), // 2
|
||||
CRIT = (1 << 2) // 4
|
||||
};
|
||||
static const type ANY = type(INFO | WARN | CRIT);
|
||||
static Debug::type value(string const & val) {
|
||||
if (val == "NONE") return Debug::NONE;
|
||||
if (val == "INFO") return Debug::INFO;
|
||||
if (val == "WARN") return Debug::WARN;
|
||||
if (val == "CRIT") return Debug::CRIT;
|
||||
return Debug::NONE;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/** DebugStream is a ostream intended for debug output.
|
||||
It has also support for a logfile. Debug output is output to cerr
|
||||
and if the logfile is set, to the logfile.
|
||||
|
||||
Example of Usage:
|
||||
DebugStream debug;
|
||||
debug.level(Debug::INFO);
|
||||
debug.debug(Debug::WARN) << "WARN\n";
|
||||
debug[Debug::INFO] << "INFO\n";
|
||||
debug << "Always\n";
|
||||
|
||||
Will output:
|
||||
INFO
|
||||
Always
|
||||
|
||||
If you want to have debug output from time critical code you should
|
||||
use this construct:
|
||||
if (debug.debugging(Debug::INFO)) {
|
||||
debug << "...debug output...\n";
|
||||
}
|
||||
|
||||
To give debug info even if no debug (NONE) is requested:
|
||||
debug << "... always output ...\n";
|
||||
|
||||
To give debug output regardless of what debug level is set (!NONE):
|
||||
debug.debug() << "...on debug output...\n";
|
||||
debug[Debug::ANY] << "...on debug output...\n";
|
||||
|
||||
To give debug output when a specific debug level is set (INFO):
|
||||
debug.debug(Debug::INFO) << "...info...\n";
|
||||
debug[Debug::INFO] << "...info...\n";
|
||||
|
||||
To give debug output when either on of debug levels is set (INFO or CRIT):
|
||||
debug.debug(Debug::type(Debug::INFO | Debug::CRIT)) << "...info/crit...\n";
|
||||
debug[Debug::type(Debug::INFO | Debug::CRIT)] << "...info/crit...\n";
|
||||
|
||||
*/
|
||||
class DebugStream : public std::ostream
|
||||
{
|
||||
public:
|
||||
/// Constructor, sets the debug level to t.
|
||||
explicit DebugStream(Debug::type t = Debug::NONE);
|
||||
|
||||
/// Constructor, sets the log file to f, and the debug level to t.
|
||||
explicit
|
||||
DebugStream(char const * f, Debug::type t = Debug::NONE);
|
||||
|
||||
///
|
||||
~DebugStream();
|
||||
|
||||
/// Sets the debug level to t.
|
||||
void level(Debug::type t) {
|
||||
dt = Debug::type(t & Debug::ANY);
|
||||
}
|
||||
|
||||
/// Returns the current debug level.
|
||||
Debug::type level() const {
|
||||
return dt;
|
||||
}
|
||||
|
||||
/// Adds t to the current debug level.
|
||||
void addLevel(Debug::type t) {
|
||||
dt = Debug::type(dt | t);
|
||||
}
|
||||
|
||||
/// Deletes t from the current debug level.
|
||||
void delLevel(Debug::type t) {
|
||||
dt = Debug::type(dt & ~t);
|
||||
}
|
||||
|
||||
/// Sets the debugstreams' logfile to f.
|
||||
void logFile(char const * f);
|
||||
|
||||
/// Returns true if t is part of the current debug level.
|
||||
bool debugging(Debug::type t = Debug::ANY) const
|
||||
{
|
||||
if (dt & t) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the no-op stream if t is not part of the
|
||||
current debug level otherwise the real debug stream
|
||||
is used.
|
||||
*/
|
||||
std::ostream & debug(Debug::type t = Debug::ANY) {
|
||||
if (dt & t) return *this;
|
||||
return nullstream;
|
||||
}
|
||||
|
||||
|
||||
/** This is an operator to give a more convenient use:
|
||||
dbgstream[Debug::INFO] << "Info!\n";
|
||||
*/
|
||||
std::ostream & operator[](Debug::type t) {
|
||||
return debug(t);
|
||||
}
|
||||
private:
|
||||
/// The current debug level
|
||||
Debug::type dt;
|
||||
/// The no-op stream.
|
||||
std::ostream nullstream;
|
||||
///
|
||||
struct debugstream_internal;
|
||||
///
|
||||
debugstream_internal * internal;
|
||||
};
|
||||
|
||||
#endif
|
@ -16,8 +16,6 @@ BUILT_SOURCES = path_defines.C
|
||||
|
||||
libsupport_la_SOURCES = \
|
||||
BoostFormat.h \
|
||||
DebugStream.C \
|
||||
DebugStream.h \
|
||||
FileInfo.C \
|
||||
FileInfo.h \
|
||||
FileMonitor.h \
|
||||
@ -29,6 +27,7 @@ libsupport_la_SOURCES = \
|
||||
copy.C \
|
||||
copied_ptr.h \
|
||||
cow_ptr.h \
|
||||
debugstream,h \
|
||||
filename.C \
|
||||
filename.h \
|
||||
filetools.C \
|
||||
|
87
src/support/debugstream.h
Normal file
87
src/support/debugstream.h
Normal file
@ -0,0 +1,87 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file debugStream.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Lars Gullik Bjønnes
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG_STREAM_HPP
|
||||
#define DEBUG_STREAM_HPP
|
||||
|
||||
#include <boost/test/detail/nullstream.hpp>
|
||||
|
||||
|
||||
struct debug_trait {
|
||||
enum type {
|
||||
NONE = 0,
|
||||
EMERG = 1,
|
||||
ALERT = 2,
|
||||
CRIT = 3,
|
||||
ERR = 4,
|
||||
WARN = 5,
|
||||
NOTICE = 6,
|
||||
INFO = 7,
|
||||
DEBUG = 8,
|
||||
ANY = 0xffffff
|
||||
};
|
||||
|
||||
static bool match(type a, type b) {
|
||||
return (b <= a || (b == ANY && a > NONE));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class dtrait,
|
||||
class charT = char,
|
||||
class traits = std::char_traits<charT> >
|
||||
class basic_debugstream : public std::basic_ostream<charT, traits> {
|
||||
public:
|
||||
typedef dtrait debug;
|
||||
typedef typename debug::type Type;
|
||||
|
||||
/// Constructor, sets the debug level to t.
|
||||
explicit basic_debugstream(std::basic_streambuf<charT, traits> * buf)
|
||||
: std::basic_ostream<charT, traits>(buf), dt(debug::NONE)
|
||||
{}
|
||||
|
||||
/// Sets the debug level to t.
|
||||
void level(Type t) {
|
||||
dt = t;
|
||||
}
|
||||
|
||||
/// Returns the current debug level.
|
||||
Type level() const {
|
||||
return dt;
|
||||
}
|
||||
|
||||
/// Returns true if t is part of the current debug level.
|
||||
bool debugging(Type t = debug::ANY) const
|
||||
{
|
||||
if (debug::match(dt, t)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns the no-op stream if t is not part of the
|
||||
current debug level otherwise the real debug stream
|
||||
is used.
|
||||
Use: dbgstream[Debug::INFO] << "Info!\n";
|
||||
*/
|
||||
std::basic_ostream<charT, traits> & operator[](Type t) {
|
||||
if (debug::match(dt, t))
|
||||
return *this;
|
||||
return nullstream;
|
||||
}
|
||||
private:
|
||||
/// The current debug level
|
||||
Type dt;
|
||||
/// The no-op stream.
|
||||
boost::basic_onullstream<charT, traits> nullstream;
|
||||
};
|
||||
|
||||
typedef basic_debugstream<debug_trait> debugstream;
|
||||
|
||||
#endif
|
@ -1,3 +1,7 @@
|
||||
2003-09-26 Lars Gullik Bjønnes <larsbj@gullik.net>
|
||||
|
||||
* tex2lyx.C: adjust for new debugstream.
|
||||
|
||||
2003-09-08 Angus Leeming <leeming@lyx.org>
|
||||
|
||||
* math.C:
|
||||
|
@ -41,8 +41,7 @@ using std::string;
|
||||
using std::vector;
|
||||
|
||||
// Hacks to allow the thing to link in the lyxlayout stuff
|
||||
Debug::type const Debug::ANY = Debug::type(0);
|
||||
DebugStream lyxerr;
|
||||
LyXErr lyxerr(std::cerr.rdbuf());
|
||||
|
||||
void LyX::emergencyCleanup() {}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user