// but should be adaptable to any project.
//#define TEST_DEBUGSTREAM
-//#define MODERN_STL
+
+#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.
-#ifdef MODERN_STL
+//#define MODERN_STL_STREAMS
+#ifdef MODERN_STL_STREAMS
#include <fstream>
#endif
+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);
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 std::streambuf {
+class nullbuf : public streambuf {
protected:
+#ifndef MODERN_STL_STREAMS
+ typedef char char_type;
+ typedef int int_type;
///
virtual int sync() { return 0; }
+#endif
///
- virtual std::streamsize xsputn(char const *, std::streamsize n) {
+ 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 overflow(int c = EOF) {
+ 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 std::streambuf {
+class teebuf : public streambuf {
public:
///
- teebuf(std::streambuf * b1, std::streambuf * b2)
- : std::streambuf(), sb1(b1), sb2(b2) {}
+ teebuf(streambuf * b1, streambuf * b2)
+ : streambuf(), sb1(b1), sb2(b2) {}
protected:
+#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
-#ifdef MODERN_STL
sb2->pubsync();
return sb1->pubsync();
-#else
- sb2->sync();
- return sb1->sync();
-#endif
}
///
- virtual std::streamsize xsputn(char const * p, std::streamsize n) {
-#ifdef MODERN_STL
+ virtual streamsize xsputn(char_type const * p, streamsize n) {
sb2->sputn(p, n);
return sb1->sputn(p, n);
-#else
- sb2->xsputn(p, n);
- return sb1->xsputn(p, n);
-#endif
}
///
- virtual int overflow(int c = EOF) {
-#ifdef MODERN_STL
+ 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
}
+#endif
private:
///
- std::streambuf * sb1;
+ streambuf * sb1;
///
- std::streambuf * sb2;
+ streambuf * sb2;
};
///
-class debugbuf : public std::streambuf {
+class debugbuf : public streambuf {
public:
///
- debugbuf(std::streambuf * b)
- : std::streambuf(), sb(b) {}
+ debugbuf(streambuf * b)
+ : streambuf(), sb(b) {}
protected:
+#ifdef MODERN_STL_STREAMS
///
virtual int sync() {
-#ifdef MODERN_STL
return sb->pubsync();
-#else
- return sb->sync();
-#endif
}
///
- virtual std::streamsize xsputn(char const * p, std::streamsize n) {
-#ifdef MODERN_STL
+ virtual streamsize xsputn(char_type const * p, streamsize n) {
return sb->sputn(p, n);
-#else
- return sb->xsputn(p, n);
-#endif
}
///
- virtual int overflow(int c = EOF) {
-#ifdef MODERN_STL
+ 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
}
+#endif
private:
///
- std::streambuf * sb;
+ streambuf * sb;
};
+
/// So that public parts of DebugStream does not need to know about filebuf
struct DebugStream::debugstream_internal {
/// Used when logging to file.
- std::filebuf fbuf;
+ filebuf fbuf;
};
+
/// Constructor, sets the debug level to t.
DebugStream::DebugStream(Debug::type t)
- : std::ostream(new debugbuf(std::cerr.rdbuf())),
+ : 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)
- : std::ostream(new debugbuf(std::cerr.rdbuf())),
+ : ostream(new debugbuf(cerr.rdbuf())),
dt(t), nullstream(new nullbuf),
internal(new debugstream_internal)
{
- internal->fbuf.open(f, std::ios::out|std::ios::app);
- delete rdbuf(new teebuf(std::cerr.rdbuf(),
+ internal->fbuf.open(f, ios::out|ios::app);
+ delete rdbuf(new teebuf(cerr.rdbuf(),
&internal->fbuf));
}
{
delete nullstream.rdbuf(0); // Without this we leak
delete rdbuf(0); // Without this we leak
- if (internal)
- delete internal;
+ delete internal;
}
+
/// Sets the debugstreams' logfile to f.
void DebugStream::logFile(char const * f)
{
} else {
internal = new debugstream_internal;
}
- internal->fbuf.open(f, std::ios::out|std::ios::app);
- delete rdbuf(new teebuf(std::cerr.rdbuf(),
+ internal->fbuf.open(f, ios::out|ios::app);
+ delete rdbuf(new teebuf(cerr.rdbuf(),
&internal->fbuf));
}
// support partial specialization. In egcs this should not be
// needed.
debugstream << "automatic " << &i
- << ", free store " << p << std::endl;
+ << ", free store " << p << endl;
delete p;
/*
for (int j = 0; j < 200000; ++j) {
DebugStream tmp;
- tmp << "Test" << std::endl;
+ tmp << "Test" << endl;
}
*/
}