-// Created by Lars Gullik Bjønnes
-// Copyright 1999 Lars Gullik Bjønnes (larsbj@lyx.org)
-// Released into the public domain.
-
-// Primarily developed for use in the LyX Project http://www.lyx.org/
-// but should be adaptable to any project.
+/**
+ * \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
#ifdef MODERN_STL_STREAMS
#include <fstream>
#endif
+#include <iostream>
+using std::ostream;
using std::streambuf;
using std::streamsize;
using std::filebuf;
///
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
teebuf(streambuf * b1, streambuf * b2)
: streambuf(), sb1(b1), sb2(b2) {}
protected:
-#ifndef MODERN_STL_STREAMS
- typedef char char_type;
- typedef int int_type;
-#endif
+#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
-#ifdef MODERN_STL_STREAMS
sb2->pubsync();
return sb1->pubsync();
-#else
- sb2->sync();
- return sb1->sync();
-#endif
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
-#ifdef MODERN_STL_STREAMS
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);
-#endif
}
///
virtual int_type overflow(int_type c = EOF) {
-#ifdef MODERN_STL_STREAMS
- sb2->sputc(c);
- return sb1->sputc(c);
-#else
sb2->overflow(c);
return sb1->overflow(c);
-#endif
}
+#endif
private:
///
streambuf * sb1;
debugbuf(streambuf * b)
: streambuf(), sb(b) {}
protected:
-#ifndef MODERN_STL_STREAMS
- typedef char char_type;
- typedef int int_type;
-#endif
+#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
-#ifdef MODERN_STL_STREAMS
return sb->pubsync();
-#else
- return sb->sync();
-#endif
}
///
virtual streamsize xsputn(char_type const * p, streamsize n) {
-#ifdef MODERN_STL_STREAMS
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);
-#endif
}
///
virtual int_type overflow(int_type c = EOF) {
-#ifdef MODERN_STL_STREAMS
- return sb->sputc(c);
-#else
return sb->overflow(c);
-#endif
}
+#endif
private:
///
streambuf * sb;
: 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())),
{
delete nullstream.rdbuf(0); // Without this we leak
delete rdbuf(0); // Without this we leak
- if (internal)
- delete internal;
+ delete internal;
}
{
/**
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
+ 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
+ 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
+ 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
+ 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<<
+ 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.
*/
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 |
+ debugstream.addLevel(Debug::type(Debug::CRIT |
Debug::WARN));
debugstream << "Adding Debug::CRIT and Debug::WARN\n";
debugstream[Debug::WARN] << "more debug(WARN)\n";
// 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
+ debugstream << "automatic " << &i
<< ", free store " << p << endl;
delete p;
/*