Switch to side-by-side view

--- a/sc2src/log.h
+++ b/sc2src/log.h
@@ -17,74 +17,158 @@
 #ifndef _LOG_H_X_INCLUDED_
 #define _LOG_H_X_INCLUDED_
 
-#include <fstream>                      // for ofstream
-#include <iostream>                     // for cerr, ostream
-#include <string>                       // for string
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
+#include <fstream> 
+#include <iostream>
+#include <string>
+#include <mutex>
 
-    class Logger {
-    public:
-        static Logger *getTheLog(const std::string& fn);
-        std::ostream& getstream() {
-            return m_tocerr ? std::cerr : m_stream;
-        }
-        enum LogLevel {LLNON, LLFAT, LLERR, LLINF, LLDEB, LLDEB1};
-        void setLogLevel(LogLevel level) {
-            m_loglevel = level;
-        }
-        int getloglevel() {
-            return m_loglevel;
-        }
-        
-    private:
-        bool m_tocerr;
-        int m_loglevel;
-        std::ofstream m_stream;
-        
-        Logger(const std::string& fn);
-	Logger(const Logger &);
-	Logger& operator=(const Logger &);
-    };
-        
-#define DEBOUT (Logger::getTheLog("")->getstream())
-#define LOCAL_LOGINC 0
-#define LOGLEVEL (Logger::getTheLog("")->getloglevel()+LOCAL_LOGINC)
+#ifndef LOGGER_THREADSAFE
+#define LOGGER_THREADSAFE 1
+#endif
 
-#define LOGDEB1(X) {                                                    \
-        if (LOGLEVEL >= Logger::LLDEB1)                     \
-        {                                                               \
-            DEBOUT << __FILE__ << ":" << __LINE__<< "::"; DEBOUT << X;  \
+#if LOGGER_THREADSAFE
+#include <mutex>
+#endif
+
+// Can't use the symbolic Logger::LLXX names in preproc. 6 is LLDEB1
+#ifndef LOGGER_STATICVERBOSITY
+#define LOGGER_STATICVERBOSITY 6
+#endif
+
+class Logger {
+public:
+    /** Initialize logging to file name. Use "stderr" for stderr output */
+    static Logger *getTheLog(const std::string& fn);
+    std::ostream& getstream() {
+        return m_tocerr ? std::cerr : m_stream;
+    }
+    enum LogLevel {LLNON=0, LLFAT=1, LLERR=2, LLINF=3, LLDEB=4,
+                   LLDEB0=5, LLDEB1=6, LLDEB2=7};
+    void setLogLevel(LogLevel level) {
+        m_loglevel = level;
+    }
+    int getloglevel() {
+        return m_loglevel;
+    }
+
+#if LOGGER_THREADSAFE
+    std::mutex& getmutex() {
+        return m_mutex;
+    }
+#endif
+    
+private:
+    bool m_tocerr;
+    int m_loglevel;
+    std::ofstream m_stream;
+#if LOGGER_THREADSAFE
+    std::mutex m_mutex;
+#endif
+
+    Logger(const std::string& fn);
+    Logger(const Logger &);
+    Logger& operator=(const Logger &);
+};
+
+#define LOGGER_PRT (Logger::getTheLog("")->getstream())
+
+#if LOGGER_THREADSAFE
+#define LOGGER_LOCK \
+    std::unique_lock<std::mutex> lock(Logger::getTheLog("")->getmutex())
+#else
+#define LOGGER_LOCK
+#endif
+
+#ifndef LOGGER_LOCAL_LOGINC
+#define LOGGER_LOCAL_LOGINC 0
+#endif
+
+#define LOGGER_LEVEL (Logger::getTheLog("")->getloglevel() + \
+                      LOGGER_LOCAL_LOGINC)
+
+#define LOGGER_DOLOG(L,X) LOGGER_PRT << ":" << L << ":" <<            \
+                                  __FILE__ << ":" << __LINE__ << "::" << X
+
+#if LOGGER_STATICVERBOSITY >= 7
+#define LOGDEB2(X) {                                                    \
+        if (LOGGER_LEVEL >= Logger::LLDEB2) {                           \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLDEB2, X);                            \
         }                                                               \
     }
+#else
+#define LOGDEB2(X)
+#endif
 
-#define LOGDEB(X) {                                                     \
-        if (LOGLEVEL >= Logger::LLDEB)                      \
-        {                                                               \
-            DEBOUT << __FILE__ << ":" << __LINE__<< "::"; DEBOUT << X;  \
+#if LOGGER_STATICVERBOSITY >= 6
+#define LOGDEB1(X) {                                                    \
+        if (LOGGER_LEVEL >= Logger::LLDEB1) {                           \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLDEB1, X);                            \
         }                                                               \
     }
+#else
+#define LOGDEB1(X)
+#endif
 
-#define LOGINF(X) {                                                     \
-        if (LOGLEVEL >= Logger::LLINF)                      \
-        {                                                               \
-            DEBOUT << __FILE__ << ":" << __LINE__<< "::"; DEBOUT << X;  \
-        }                                                               \
-    }                                                                   
-
-#define LOGERR(X) {                                                     \
-        if (LOGLEVEL >= Logger::LLERR)                      \
-        {                                                               \
-            DEBOUT << __FILE__ << ":" << __LINE__<< "::"; DEBOUT << X;  \
+#if LOGGER_STATICVERBOSITY >= 5
+#define LOGDEB0(X) {                                                    \
+        if (LOGGER_LEVEL >= Logger::LLDEB0) {                           \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLDEB0, X);                            \
         }                                                               \
     }
+#else
+#define LOGDEB0(X)
+#endif
 
-#define LOGFAT(X) {                                                     \
-        if (LOGLEVEL >= Logger::LLFAT)                      \
-        {                                                               \
-            DEBOUT << __FILE__ << ":" << __LINE__<< "::"; DEBOUT << X;  \
+#if LOGGER_STATICVERBOSITY >= 4
+#define LOGDEB(X) {                                                     \
+        if (LOGGER_LEVEL >= Logger::LLDEB) {                            \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLDEB, X);                             \
         }                                                               \
     }
+#else
+#define LOGDEB(X)
+#endif
 
+#if LOGGER_STATICVERBOSITY >= 3
+#define LOGINF(X) {                                                     \
+        if (LOGGER_LEVEL >= Logger::LLINF) {                            \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLINF, X);                             \
+        }                                                               \
+    }
+#else
+#define LOGINF(X)
+#endif
+#define LOGINFO LOGINF
 
+#if LOGGER_STATICVERBOSITY >= 2
+#define LOGERR(X) {                                                     \
+        if (LOGGER_LEVEL >= Logger::LLERR) {                            \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLERR, X);                             \
+        }                                                               \
+    }
+#else
+#define LOGERR(X)
+#endif
+
+#if LOGGER_STATICVERBOSITY >= 1
+#define LOGFAT(X) {                                                     \
+        if (LOGGER_LEVEL >= Logger::LLFAT) {                            \
+            LOGGER_LOCK;                                                \
+            LOGGER_DOLOG(Logger::LLFAT, X);                             \
+        }                                                               \
+    }
+#else
+#define LOGFAT(X)
+#endif
 
 #endif /* _LOG_H_X_INCLUDED_ */