X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fdebug%2Flogstream.hxx;h=4546a5e1d5cd6efbaa774eb475101a05584853af;hb=68eb7031e2dce999d112d0164fa28d4b8d66922e;hp=493138ed6a5186339cc3ee6287093bbd81e5d156;hpb=a86868526e163812eb286ea71fe9600df7deea4a;p=simgear.git diff --git a/simgear/debug/logstream.hxx b/simgear/debug/logstream.hxx index 493138ed..4546a5e1 100644 --- a/simgear/debug/logstream.hxx +++ b/simgear/debug/logstream.hxx @@ -1,5 +1,7 @@ -// Stream based logging mechanism. -// +/** \file logstream.hxx + * Stream based logging mechanism. + */ + // Written by Bernie Bright, 1998 // // Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au @@ -24,39 +26,30 @@ #ifndef _LOGSTREAM_H #define _LOGSTREAM_H -#ifdef HAVE_CONFIG_H -# include -#endif - - #include -// At least Irix needs this -#ifdef FG_HAVE_NATIVE_SGI_COMPILERS -#include +#ifdef _MSC_VER +# include #endif -#ifdef FG_HAVE_STD_INCLUDES +#ifdef SG_HAVE_STD_INCLUDES # include # include #else # include -# include +# include #endif #include -#ifndef FG_HAVE_NATIVE_SGI_COMPILERS -FG_USING_STD(streambuf); -FG_USING_STD(ostream); -FG_USING_STD(cerr); -FG_USING_STD(endl); -#else -FG_USING_STD(char_traits); -#endif +SG_USING_STD(streambuf); +SG_USING_STD(ostream); +SG_USING_STD(cout); +SG_USING_STD(cerr); +SG_USING_STD(endl); #ifdef __MWERKS__ -FG_USING_STD(iostream); +SG_USING_STD(iostream); #endif // @@ -67,43 +60,94 @@ FG_USING_STD(iostream); // 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. -// +/** + * 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. + */ +#ifdef SG_NEED_STREAMBUF_HACK +class logbuf : public __streambuf +#else class logbuf : public streambuf +#endif { public: -#ifndef FG_HAVE_STD_INCLUDES +#ifndef SG_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( streambuf* sb ) : sbuf(sb) {} + /** Constructor */ logbuf(); + + /** Destructor */ ~logbuf(); - // Is logging enabled? + /** + * Is logging enabled? + * @return true or false*/ bool enabled() { return logging_enabled; } - // Set the logging level of subsequent messages. - void set_log_state( fgDebugClass c, fgDebugPriority p ); + /** + * Set the logging level of subsequent messages. + * @param c debug class + * @param p priority + */ + void set_log_state( sgDebugClass c, sgDebugPriority p ); + + /** + * Set the global logging level. + * @param c debug class + * @param p priority + */ + static void set_log_level( sgDebugClass c, sgDebugPriority p ); + + + /** + * Set the allowed logging classes. + * @param c All enabled logging classes anded together. + */ + static void set_log_classes (sgDebugClass c); + + + /** + * Get the logging classes currently enabled. + * @return All enabled debug logging anded together. + */ + static sgDebugClass get_log_classes (); + - // Set the global logging level. - static void set_log_level( fgDebugClass c, fgDebugPriority p ); + /** + * Set the logging priority. + * @param c The priority cutoff for logging messages. + */ + static void set_log_priority (sgDebugPriority p); - // + + /** + * Get the current logging priority. + * @return The priority cutoff for logging messages. + */ + static sgDebugPriority get_log_priority (); + + + /** + * Set the stream buffer + * @param sb stream buffer + */ void set_sb( streambuf* sb ); protected: + /** sync/flush */ inline virtual int sync(); + + /** overflow */ int_type overflow( int ch ); -// int xsputn( const char* s, istreamsize n ); + // int xsputn( const char* s, istreamsize n ); private: @@ -111,8 +155,8 @@ private: static streambuf* sbuf; static bool logging_enabled; - static fgDebugClass logClass; - static fgDebugPriority logPriority; + static sgDebugClass logClass; + static sgDebugPriority logPriority; private: @@ -124,7 +168,7 @@ private: inline int logbuf::sync() { -#ifdef FG_HAVE_STD_INCLUDES +#ifdef SG_HAVE_STD_INCLUDES return sbuf->pubsync(); #else return sbuf->sync(); @@ -132,7 +176,7 @@ logbuf::sync() } inline void -logbuf::set_log_state( fgDebugClass c, fgDebugPriority p ) +logbuf::set_log_state( sgDebugClass c, sgDebugPriority p ) { logging_enabled = ((c & logClass) != 0 && p >= logPriority); } @@ -140,57 +184,84 @@ logbuf::set_log_state( fgDebugClass c, fgDebugPriority p ) inline logbuf::int_type logbuf::overflow( int c ) { +#ifdef _MSC_VER + static has_console = false; + if ( logging_enabled ) { + if ( !has_console ) { + AllocConsole(); + freopen("conin$", "r", stdin); + freopen("conout$", "w", stdout); + freopen("conout$", "w", stderr); + has_console = true; + } + sbuf->sputc(c); + } + else + return EOF == 0 ? 1: 0; +#else return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0); +#endif } -//----------------------------------------------------------------------------- -// -// logstream manipulator for setting the log level of a message. -// +/** + * logstream manipulator for setting the log level of a message. + */ struct loglevel { - loglevel( fgDebugClass c, fgDebugPriority p ) + loglevel( sgDebugClass c, sgDebugPriority p ) : logClass(c), logPriority(p) {} - fgDebugClass logClass; - fgDebugPriority logPriority; + sgDebugClass logClass; + sgDebugPriority 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. -// +/** + * 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( streambuf* sb ) : lbuf(sb) {} logstream_base() {} logbuf lbuf; }; -//----------------------------------------------------------------------------- -// -// -// +/** + * Class to manage the debug logging stream. + */ class logstream : private logstream_base, public ostream { public: - // The default is to send messages to cerr. + /** + * The default is to send messages to cerr. + * @param out output stream + */ logstream( ostream& out ) -// : logstream_base(out.rdbuf()), + // : logstream_base(out.rdbuf()), : logstream_base(), ostream(&lbuf) { lbuf.set_sb(out.rdbuf());} + /** + * Set the output stream + * @param out output stream + */ 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. + /** + * Set the global log class and priority level. + * @param c debug class + * @param p priority + */ + void setLogLevels( sgDebugClass c, sgDebugPriority p ); + + /** + * Output operator to capture the debug level and priority of a message. + * @param l log level + */ inline ostream& operator<< ( const loglevel& l ); }; @@ -201,26 +272,51 @@ logstream::operator<< ( const loglevel& l ) 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. -// +extern logstream *global_logstream; + +/** + * \relates logstream + * 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. + * @return current logstream + */ inline logstream& -fglog() +sglog() { - static logstream logstrm( cerr ); - return logstrm; + if (global_logstream == NULL) { + +#ifdef __APPLE__ + /** + * There appears to be a bug in the C++ runtime in Mac OS X that + * will crash if certain funtions are called (in this case + * cerr.rdbuf()) during static initialization of a class. This + * print statement is hack to kick the library in the pants so it + * won't crash when cerr.rdbuf() is first called -DW + **/ + cout << "Using Mac OS X hack for initializing C++ stdio..." << endl; +#endif + global_logstream = new logstream (cerr); + } + + return *global_logstream; } + +/** \def SG_LOG(C,P,M) + * Log a message. + * @param C debug class + * @param P priority + * @param M message + */ #ifdef FG_NDEBUG -# define FG_LOG(C,P,M) +# define SG_LOG(C,P,M) #elif defined( __MWERKS__ ) -# define FG_LOG(C,P,M) ::fglog() << ::loglevel(C,P) << M << std::endl +# define SG_LOG(C,P,M) ::sglog() << ::loglevel(C,P) << M << std::endl #else -# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl +# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl #endif + #endif // _LOGSTREAM_H