// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the
-// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-// Boston, MA 02111-1307, USA.
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#include <simgear/compiler.h>
-// At least Irix needs this
-#ifdef SG_HAVE_NATIVE_SGI_COMPILERS
-#include <char_traits.h>
+#ifdef _WIN32
+# include <windows.h>
#endif
-#ifdef SG_HAVE_STD_INCLUDES
-# include <streambuf>
-# include <iostream>
-#else
-# include <iostream.h>
-# include <simgear/sg_traits.hxx>
-#endif
+#include <streambuf>
+#include <ostream>
+#include <cstdio>
#include <simgear/debug/debug_types.h>
-#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
-SG_USING_STD(streambuf);
-SG_USING_STD(ostream);
-SG_USING_STD(cerr);
-SG_USING_STD(endl);
-#else
-SG_USING_STD(char_traits);
-#endif
-
-#ifdef __MWERKS__
-SG_USING_STD(iostream);
-#endif
+using std::streambuf;
+using std::ostream;
//
// TODO:
* messages at runtime. Only messages with priority >= logbuf::logPriority
* and debugClass == logbuf::logClass are output.
*/
-class logbuf : public streambuf
+#ifdef SG_NEED_STREAMBUF_HACK
+class logbuf : public __streambuf
+#else
+class logbuf : public std::streambuf
+#endif
{
public:
-
-#ifndef SG_HAVE_STD_INCLUDES
- typedef char_traits<char> traits_type;
- typedef char_traits<char>::int_type int_type;
- // typedef char_traits<char>::pos_type pos_type;
- // typedef char_traits<char>::off_type off_type;
-#endif
// logbuf( streambuf* sb ) : sbuf(sb) {}
/** Constructor */
logbuf();
*/
void set_log_state( sgDebugClass c, sgDebugPriority p );
+ bool would_log( sgDebugClass c, sgDebugPriority p ) const;
+
/**
* Set the global logging level.
* @param c debug class
* Set the stream buffer
* @param sb stream buffer
*/
- void set_sb( streambuf* sb );
+ void set_sb( std::streambuf* sb );
+
+#ifdef _WIN32
+ static void has_no_console() { has_console = false; }
+#endif
protected:
private:
// The streambuf used for actual output. Defaults to cerr.rdbuf().
- static streambuf* sbuf;
+ static std::streambuf* sbuf;
static bool logging_enabled;
+#ifdef _WIN32
+ static bool has_console;
+#endif
static sgDebugClass logClass;
static sgDebugPriority logPriority;
inline int
logbuf::sync()
{
-#ifdef SG_HAVE_STD_INCLUDES
return sbuf->pubsync();
-#else
- return sbuf->sync();
-#endif
}
inline void
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}
+inline bool
+logbuf::would_log( sgDebugClass c, sgDebugPriority p ) const
+{
+ return ((c & logClass) != 0 && p >= logPriority);
+}
+
inline logbuf::int_type
logbuf::overflow( int c )
{
+#ifdef _WIN32
+ if ( logging_enabled ) {
+ if ( !has_console ) {
+ AllocConsole();
+ freopen("conin$", "r", stdin);
+ freopen("conout$", "w", stdout);
+ freopen("conout$", "w", stderr);
+ has_console = true;
+ }
+ return sbuf->sputc(c);
+ }
+ else
+ return EOF == 0 ? 1: 0;
+#else
return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
+#endif
}
/**
/**
* Class to manage the debug logging stream.
*/
-class logstream : private logstream_base, public ostream
+class logstream : private logstream_base, public std::ostream
{
public:
/**
* The default is to send messages to cerr.
* @param out output stream
*/
- logstream( ostream& out )
+ logstream( std::ostream& out )
// : logstream_base(out.rdbuf()),
: logstream_base(),
- ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
+ std::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() ); }
+ void set_output( std::ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
/**
* Set the global log class and priority level.
*/
void setLogLevels( sgDebugClass c, sgDebugPriority p );
+ bool would_log( sgDebugClass c, sgDebugPriority p ) const
+ {
+ return lbuf.would_log( c, p );
+ };
+
/**
* Output operator to capture the debug level and priority of a message.
* @param l log level
*/
- inline ostream& operator<< ( const loglevel& l );
+ inline std::ostream& operator<< ( const loglevel& l );
+ friend logstream& sglog();
+ static logstream *initGlobalLogstream();
+protected:
+ static logstream *global_logstream;
};
-inline ostream&
+inline std::ostream&
logstream::operator<< ( const loglevel& l )
{
lbuf.set_log_state( l.logClass, l.logPriority );
return *this;
}
-
/**
* \relates logstream
* Return the one and only logstream instance.
inline logstream&
sglog()
{
- static logstream logstrm( cerr );
- return logstrm;
+ return *logstream::initGlobalLogstream();
}
*/
#ifdef FG_NDEBUG
# define SG_LOG(C,P,M)
-#elif defined( __MWERKS__ )
-# define SG_LOG(C,P,M) ::sglog() << ::loglevel(C,P) << M << std::endl
#else
-# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
+# define SG_LOG(C,P,M) do { \
+ logstream& __tmplogstreamref(sglog()); \
+ if(__tmplogstreamref.would_log(C,P)) { \
+ __tmplogstreamref << loglevel(C,P) << M << std::endl; } \
+ } while(0)
#endif
+#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)
#endif // _LOGSTREAM_H