From 4fb45c478392ff43c167d1c87269516130f43cdf Mon Sep 17 00:00:00 2001 From: curt Date: Fri, 6 Nov 1998 21:20:41 +0000 Subject: [PATCH 1/1] Initial revision. --- Debug/debug_types.h | 35 ++++++++ Debug/logstream.cxx | 68 +++++++++++++++ Debug/logstream.hxx | 195 ++++++++++++++++++++++++++++++++++++++++++++ Debug/logtest.cxx | 34 ++++++++ 4 files changed, 332 insertions(+) create mode 100644 Debug/debug_types.h create mode 100644 Debug/logstream.cxx create mode 100644 Debug/logstream.hxx create mode 100644 Debug/logtest.cxx diff --git a/Debug/debug_types.h b/Debug/debug_types.h new file mode 100644 index 000000000..65e6fe912 --- /dev/null +++ b/Debug/debug_types.h @@ -0,0 +1,35 @@ +// NB: To add a dbg_class, add it here, and add it to the structure in +// fg_debug.c + +typedef enum { + FG_NONE = 0x00000000, + + FG_TERRAIN = 0x00000001, + FG_ASTRO = 0x00000002, + FG_FLIGHT = 0x00000004, + FG_INPUT = 0x00000008, + FG_GL = 0x00000010, + FG_VIEW = 0x00000020, + FG_COCKPIT = 0x00000040, + FG_GENERAL = 0x00000080, + FG_MATH = 0x00000100, + FG_EVENT = 0x00000200, + FG_AIRCRAFT = 0x00000400, + FG_AUTOPILOT = 0x00000800, + FG_UNDEFD = 0x00001000, // For range checking + + FG_ALL = 0xFFFFFFFF +} fgDebugClass; + + +// NB: To add a priority, add it here. +typedef enum { + FG_BULK, // For frequent messages + FG_DEBUG, // Less frequent debug type messages + FG_INFO, // Informatory messages + FG_WARN, // Possible impending problem + FG_ALERT // Very possible impending problem + // FG_EXIT, // Problem (no core) + // FG_ABORT // Abandon ship (core) +} fgDebugPriority; + diff --git a/Debug/logstream.cxx b/Debug/logstream.cxx new file mode 100644 index 000000000..708bd660a --- /dev/null +++ b/Debug/logstream.cxx @@ -0,0 +1,68 @@ +// Stream based logging mechanism. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program 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. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#include "logstream.hxx" + +bool logbuf::logging_enabled = true; +fgDebugClass logbuf::logClass = FG_NONE; +fgDebugPriority logbuf::logPriority = FG_INFO; +streambuf* logbuf::sbuf = NULL; + +logbuf::logbuf() +{ +// if ( sbuf == NULL ) +// sbuf = cerr.rdbuf(); +} + +logbuf::~logbuf() +{ + if ( sbuf ) + sbuf->sync(); +} + +void +logbuf::set_sb( streambuf* sb ) +{ + if ( sbuf ) + sbuf->sync(); + + sbuf = sb; +} + +void +logbuf::set_log_level( fgDebugClass c, fgDebugPriority p ) +{ + logClass = c; + logPriority = p; +} + +void +logstream::setLogLevels( fgDebugClass c, fgDebugPriority p ) +{ + logbuf::set_log_level( c, p ); +} + +// $Log$ +// Revision 1.1 1998/11/06 21:20:41 curt +// Initial revision. +// diff --git a/Debug/logstream.hxx b/Debug/logstream.hxx new file mode 100644 index 000000000..5c51aa530 --- /dev/null +++ b/Debug/logstream.hxx @@ -0,0 +1,195 @@ +// Stream based logging mechanism. +// +// Written by Bernie Bright, 1998 +// +// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au +// +// This program 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. +// +// This program 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 this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ +// (Log is kept at end of this file) + +#ifndef _LOGSTREAM_H +#define _LOGSTREAM_H + +#include "Include/compiler.h" + +#ifdef FG_HAVE_STD_INCLUDES +# include +# include +#else +# include +# include "Include/fg_traits.hxx" +#endif + +#include "debug_types.h" + +// +// TODO: +// +// 1. Change output destination. Done. +// 2. Make logbuf thread safe. +// 3. Read environment for default debugClass and debugPriority. +// + +//----------------------------------------------------------------------------- +// +// logbuf is an output-only streambuf with the ability to disable sets of +// messages at runtime. Only messages with priority >= logbuf::logPriority +// and debugClass == logbuf::logClass are output. +// +class logbuf : public streambuf +{ +public: + +#ifndef FG_HAVE_STD_INCLUDES + typedef char_traits traits_type; + typedef char_traits::int_type int_type; + typedef char_traits::pos_type pos_type; + typedef char_traits::off_type off_type; +#endif +// logbuf( streambuf* sb ) : sbuf(sb) {} + logbuf(); + ~logbuf(); + + // Is logging enabled? + bool enabled() { return logging_enabled; } + + // Set the logging level of subsequent messages. + void set_log_state( fgDebugClass c, fgDebugPriority p ); + + // Set the global logging level. + static void set_log_level( fgDebugClass c, fgDebugPriority p ); + + // + void set_sb( streambuf* sb ); + +protected: + + int sync() { return sbuf->sync(); } + int_type overflow( int ch ); +// int xsputn( const char* s, istreamsize n ); + +private: + + // The streambuf used for actual output. Defaults to cerr.rdbuf(). + static streambuf* sbuf; + + static bool logging_enabled; + static fgDebugClass logClass; + static fgDebugPriority logPriority; + +private: + + // Not defined. + logbuf( const logbuf& ); + void operator= ( const logbuf& ); +}; + +inline void +logbuf::set_log_state( fgDebugClass c, fgDebugPriority p ) +{ + logging_enabled = ((c & logClass) != 0 && p >= logPriority); +} + +inline logbuf::int_type +logbuf::overflow( int c ) +{ + return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0); +} + +//----------------------------------------------------------------------------- +// +// logstream manipulator for setting the log level of a message. +// +struct loglevel +{ + loglevel( fgDebugClass c, fgDebugPriority p ) + : logClass(c), logPriority(p) {} + + fgDebugClass logClass; + fgDebugPriority logPriority; +}; + +//----------------------------------------------------------------------------- +// +// A helper class that ensures a streambuf and ostream are constructed and +// destroyed in the correct order. The streambuf must be created before the +// ostream but bases are constructed before members. Thus, making this class +// a private base of logstream, declared to the left of ostream, we ensure the +// correct order of construction and destruction. +// +struct logstream_base +{ +// logstream_base( streambuf* sb ) : lbuf(sb) {} + logstream_base() {} + + logbuf lbuf; +}; + +//----------------------------------------------------------------------------- +// +// +// +class logstream : private logstream_base, public ostream +{ +public: + // The default is to send messages to cerr. + logstream( ostream& out ) +// : logstream_base(out.rdbuf()), + : logstream_base(), + ostream(&lbuf) { lbuf.set_sb(out.rdbuf());} + + void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); } + + // Set the global log class and priority level. + void setLogLevels( fgDebugClass c, fgDebugPriority p ); + + // Output operator to capture the debug level and priority of a message. + inline ostream& operator<< ( const loglevel& l ); +}; + +inline ostream& +logstream::operator<< ( const loglevel& l ) +{ + lbuf.set_log_state( l.logClass, l.logPriority ); + return *this; +} + +//----------------------------------------------------------------------------- +// +// Return the one and only logstream instance. +// We use a function instead of a global object so we are assured that cerr +// has been initialised. +// +inline logstream& +fglog() +{ + static logstream logstrm( cerr ); + return logstrm; +} + +#ifdef FG_NDEBUG +# define FG_LOG(C,P,M) +#else +# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl +#endif + +#endif // _LOGSTREAM_H + +// $Log$ +// Revision 1.1 1998/11/06 21:20:42 curt +// Initial revision. +// diff --git a/Debug/logtest.cxx b/Debug/logtest.cxx new file mode 100644 index 000000000..b02c6b086 --- /dev/null +++ b/Debug/logtest.cxx @@ -0,0 +1,34 @@ +#include +#include "Debug/logstream.hxx" + +int +main( int argc, char* argv[] ) +{ + fglog().setLogLevels( FG_ALL, FG_INFO ); + + FG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear + FG_LOG( FG_TERRAIN, FG_DEBUG, "terrain::debug" ); // shouldnt appear + FG_LOG( FG_TERRAIN, FG_INFO, "terrain::info" ); + FG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" ); + FG_LOG( FG_TERRAIN, FG_ALERT, "terrain::alert" ); + + int i = 12345; + long l = 54321L; + double d = 3.14159; + string s = "Hello world!"; + + FG_LOG( FG_EVENT, FG_INFO, "event::info " + << "i=" << i + << ", l=" << l + << ", d=" << d + << ", d*l=" << d*l + << ", s=\"" << s << "\"" ); + + // This shouldn't appear in log output: + FG_LOG( FG_EVENT, FG_DEBUG, "event::debug " + << "- this should be seen - " + << "d=" << d + << ", s=\"" << s << "\"" ); + + return 0; +} -- 2.39.2