]> git.mxchange.org Git - simgear.git/blobdiff - simgear/debug/logstream.hxx
Reduce compiler.h to almost nothing (but it's worth keeping around I think, for
[simgear.git] / simgear / debug / logstream.hxx
index ea35ee956c66d935ba575a23c8feab1feb35f060..80f1892c11e86056688233153f24f110b915f956 100644 (file)
 // 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 _MSC_VER
+#  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 <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
 
 //
 // TODO:
@@ -69,16 +52,13 @@ SG_USING_STD(iostream);
  * 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();
@@ -138,7 +118,11 @@ public:
      * Set the stream buffer
      * @param sb stream buffer
      */
-    void set_sb( streambuf* sb );
+    void set_sb( std::streambuf* sb );
+
+#ifdef _MSC_VER
+    static void has_no_console() { has_console = false; }
+#endif
 
 protected:
 
@@ -152,9 +136,12 @@ protected:
 private:
 
     // The streambuf used for actual output. Defaults to cerr.rdbuf().
-    static streambuf* sbuf;
+    static std::streambuf* sbuf;
 
     static bool logging_enabled;
+#ifdef _MSC_VER
+    static bool has_console;
+#endif
     static sgDebugClass logClass;
     static sgDebugPriority logPriority;
 
@@ -168,11 +155,7 @@ private:
 inline int
 logbuf::sync()
 {
-#ifdef SG_HAVE_STD_INCLUDES
        return sbuf->pubsync();
-#else
-       return sbuf->sync();
-#endif
 }
 
 inline void
@@ -184,7 +167,22 @@ logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
 inline logbuf::int_type
 logbuf::overflow( int c )
 {
+#ifdef _MSC_VER
+    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
 }
 
 /**
@@ -217,23 +215,23 @@ struct logstream_base
 /**
  * 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.
@@ -246,18 +244,20 @@ public:
      * 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();
+protected:
+    static logstream *global_logstream;
+    static void initGlobalLogstream();
 };
 
-inline ostream&
+inline std::ostream&
 logstream::operator<< ( const loglevel& l )
 {
     lbuf.set_log_state( l.logClass, l.logPriority );
     return *this;
 }
 
-extern logstream *global_logstream;
-
 /**
  * \relates logstream
  * Return the one and only logstream instance.
@@ -268,22 +268,10 @@ extern logstream *global_logstream;
 inline logstream&
 sglog()
 {
-  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);
+  if (logstream::global_logstream == NULL) {
+      logstream::initGlobalLogstream();
   }
-    
-  return *global_logstream;
+  return *logstream::global_logstream;
 }
 
 
@@ -295,12 +283,11 @@ sglog()
  */
 #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) sglog() << loglevel(C,P) << M << std::endl
 #endif
 
+#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)
 
 #endif // _LOGSTREAM_H