LibCudaOptimize
1.0
|
00001 //*************************************************************************// 00002 // // 00003 // LibCudaOptimize // 00004 // Copyright (C) 2012 Ibislab, University of Parma // 00005 // Authors: Youssef S.G. Nashed, Roberto Ugolotti // 00006 // // 00007 // You should have received a copy of the GNU General Public License // 00008 // along with this program. If not, see <http://www.gnu.org/licenses/> // 00009 // // 00010 //*************************************************************************// 00011 00012 /* http://www.drdobbs.com/cpp/logging-in-c/201804215 */ 00013 00014 #ifndef __LOG_H__ 00015 #define __LOG_H__ 00016 00018 #include <sstream> 00019 #include <string> 00020 #include <stdio.h> 00022 enum LOG_LEVEL {logERROR, logWARNING, logINFO, logINFOEXT, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, LOG_LEVEL_NUM}; 00023 00024 #ifndef PRIVATE_DOXYGEN 00025 00026 //only messages with a level lower than or equal to FILELOG_MAX_LEVEL will be shown 00027 #ifndef FILELOG_MAX_LEVEL 00028 #define FILELOG_MAX_LEVEL logDEBUG4 00029 #endif 00030 00031 template <typename T> 00032 class Log 00033 { 00034 public: 00035 Log(); 00036 virtual ~Log(); 00037 std::ostringstream& Get(LOG_LEVEL level = logINFO); 00038 public: 00039 static LOG_LEVEL& ReportingLevel(); 00040 static std::string ToString(LOG_LEVEL level); 00041 static LOG_LEVEL FromString(const std::string& level); 00042 protected: 00043 std::ostringstream os; 00044 private: 00045 Log(const Log&); 00046 Log& operator =(const Log&); 00047 }; 00048 00049 template <typename T> 00050 Log<T>::Log() 00051 { 00052 } 00053 00054 template <typename T> 00055 std::ostringstream& Log<T>::Get(LOG_LEVEL level) 00056 { 00057 os << ToString(level) << ": "; 00058 os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t'); 00059 return os; 00060 } 00061 00062 template <typename T> 00063 Log<T>::~Log() 00064 { 00065 os << std::endl; 00066 T::Output(os.str()); 00067 } 00068 00069 template <typename T> 00070 LOG_LEVEL& Log<T>::ReportingLevel() 00071 { 00072 static LOG_LEVEL reportingLevel = logDEBUG4; 00073 return reportingLevel; 00074 } 00075 00076 template <typename T> 00077 std::string Log<T>::ToString(LOG_LEVEL level) 00078 { 00079 static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "INFOEXT", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"}; 00080 return buffer[level]; 00081 } 00082 00083 template <typename T> 00084 LOG_LEVEL Log<T>::FromString(const std::string& level) 00085 { 00086 if (level == "DEBUG4") 00087 return logDEBUG4; 00088 if (level == "DEBUG3") 00089 return logDEBUG3; 00090 if (level == "DEBUG2") 00091 return logDEBUG2; 00092 if (level == "DEBUG1") 00093 return logDEBUG1; 00094 if (level == "DEBUG") 00095 return logDEBUG; 00096 if (level == "INFO") 00097 return logINFO; 00098 if (level == "INFOEXT") 00099 return logINFOEXT; 00100 if (level == "WARNING") 00101 return logWARNING; 00102 if (level == "ERROR") 00103 return logERROR; 00104 Log<T>().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default."; 00105 return logINFO; 00106 } 00107 #ifndef PRIVATE_DOXYGEN 00108 class Output2FILE 00109 { 00110 public: 00111 static FILE*& Stream(const std::string fOut=""); 00112 static void Output(const std::string& msg, const std::string fOut=""); 00113 }; 00114 00115 inline FILE*& Output2FILE::Stream(const std::string fOut) 00116 { 00117 static FILE* pStream = fOut.length() ? fopen(fOut.c_str(), "a+") : stderr; 00118 return pStream; 00119 } 00120 00121 inline void Output2FILE::Output(const std::string& msg, const std::string fOut) 00122 { 00123 FILE* pStream = Stream(fOut); 00124 if (!pStream) 00125 return; 00126 fprintf(pStream, "%s", msg.c_str()); 00127 fflush(pStream); 00128 } 00129 #endif 00130 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 00131 # if defined (BUILDING_FILELOG_DLL) 00132 # define FILELOG_DECLSPEC __declspec (dllexport) 00133 # elif defined (USING_FILELOG_DLL) 00134 # define FILELOG_DECLSPEC __declspec (dllimport) 00135 # else 00136 # define FILELOG_DECLSPEC 00137 # endif // BUILDING_DBSIMPLE_DLL 00138 #else 00139 # define FILELOG_DECLSPEC 00140 #endif // _WIN32 00141 00142 class FILELOG_DECLSPEC FILELog : public Log<Output2FILE> {}; 00143 00144 #endif //private doxygen 00145 00147 #define FILE_LOG(level, maxLevel, outFile) \ 00148 if (level > maxLevel) ;\ 00149 else if (level > FILELog::ReportingLevel() || !Output2FILE::Stream(outFile)) ; \ 00150 else FILELog().Get(level) 00151 00152 #endif //__LOG_H__