diff --git a/CMakeLists.txt b/CMakeLists.txt index 90df337..a2b9597 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,87 +1,94 @@ project(specmicp) cmake_minimum_required(VERSION 2.8) ####################### External Package ##################################### set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") find_package(Eigen3 REQUIRED) # This module comes from the Eigen3 Package find_package(CxxTest) # Necessary if you want the tests ######################## Compilation flags ################################# if(UNIX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -std=c++11") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -pedantic") SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -DNDEBUG") message(STATUS "c++ flags ${CMAKE_CXX_FLAGS}") else() message(WARNING "not tested !") endif() ################ Directories ##################### set(PROJECT_TEST_DIR ${PROJECT_SOURCE_DIR}/tests) set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) # include include_directories(${EIGEN3_INCLUDE_DIR}) include_directories(${PROJECT_SOURCE_DIR}) ################ Modules ########################## # -------- MiCPSolver ---------------- set(MICPSOLVER_DIR ${PROJECT_SOURCE_DIR}/micpsolver) add_custom_target(specmisolver_inc SOURCES ${MICPSOLVER_DIR}/micpsolver.hpp ${MICPSOLVER_DIR}/micpsolver.inl ${MICPSOLVER_DIR}/micpprog.hpp ${MICPSOLVER_DIR}/ncp_function.hpp ${MICPSOLVER_DIR}/estimate_cond_number.hpp ) # ------- SpecMiCP --------------- set(SPECMICP_DIR ${PROJECT_SOURCE_DIR}/specmicp) add_custom_target(specmic_inc SOURCES #${SPECMICP_DIR}/specmicp.hpp ${SPECMICP_DIR}/thermodata.hpp ) set(SPECMICP_LIBFILE ${SPECMICP_DIR}/specmicp.cpp ) add_library(specmicp ${SPECMICP_LIBFILE}) +# ------- Utils ------------------ + +set(UTILS_DIR ${PROJECT_SOURCE_DIR}/utils) + +add_custom_target(utils_inc SOURCES + ${UTILS_DIR}/log.hpp) + # --------- Test ---------------------- # CXX Test # ======== if(CXXTEST_FOUND) set(CXXTEST_USE_PYTHON TRUE) include_directories(${CXXTEST_INCLUDE_DIR}) enable_testing() # MiCP Solver # ------------ CXXTEST_ADD_TEST(test_cond_number test_cond_number.cpp ${PROJECT_TEST_DIR}/micpsolver/test_cond_number.hpp) CXXTEST_ADD_TEST(test_ncp_funtion test_ncp_function.cpp ${PROJECT_TEST_DIR}/micpsolver/test_ncp_function.hpp) CXXTEST_ADD_TEST(test_micpsolver test_micpsolver.cpp ${PROJECT_TEST_DIR}/micpsolver/test_micpsolver.hpp) endif() # Test 'Perso' # ============ add_executable(thermocarbo ${PROJECT_TEST_DIR}/specmicp/thermocarbo.cpp) target_link_libraries(thermocarbo specmicp) diff --git a/src/utils/log.hpp b/src/utils/log.hpp new file mode 100644 index 0000000..5d681bc --- /dev/null +++ b/src/utils/log.hpp @@ -0,0 +1,131 @@ +/*------------------------------------------------------- + + - Module : utils + - File : log.hpp + - Author : Fabien Georget + + Copyright (c) 2014, Fabien Georget, Princeton University + +---------------------------------------------------------*/ + +#ifndef SPECMICP_UTILS_LOG_HPP +#define SPECMICP_UTILS_LOG_HPP + +//! \file log.hpp logger + +namespace specmicp { +namespace logger { +//! \enum LogLevel the different log level +//! +//! If changed, the function to_string must also be changed +enum LogLevel {Critical, Error, Warning, Info, Debug, Spam}; + +//! Format the log level into a string +inline std::string to_string(LogLevel); + +/*! \brief A log message + * + * The message is written during the destruction of the Log object. + * The stream which contain the message is accessed with the member get(Level) + */ +template +class Log +{ +public: + //! Constructor + Log() {} + //! Destructor - Output the message + ~Log(); + + //! \brief Return the steam so we can write the message + std::ostringstream& get(LogLevel level); + + //! \brief Return the report level + static LogLevel& ReportLevel(){ + static LogLevel report_level = Debug; + return report_level; + } +protected: + std::ostringstream msg; //!< the actual message +private: + // this are hidden on purpose, no need + Log(Log&); + Log& operator=(Log&); +}; + +template +std::ostringstream& Log::get(LogLevel level) +{ + msg << to_string(level) << " : "; + return msg; +} + +template +Log::~Log() +{ + outputPolicy::output(msg.str()); +} + +//! Output Policy to use for logging +class ErrFile +{ +public: + //! Return a pointer to the stream we want to write in + static std::ostream*& stream(); + //! Output the message to the stream + static void output(const std::string& msg); +}; + +inline std::ostream*& ErrFile::stream() +{ + static std::ostream* stream = nullptr; + return stream; +} + +inline void ErrFile::output(const std::string &msg) +{ + std::ostream* out = stream(); + (*out) << msg << std::endl; + out->flush(); +} + + +inline std::string to_string(LogLevel level) +{ + static const char* list_level[] = {"CRITICAL", "ERROR", "Warning", "info", "debug", "spam"}; + return list_level[level]; +} + + +} // end namespace logger + +//! Standard logger type +using stdlog = logger::Log; + +//! Filter logs to stdlog +#define FILTER(level) \ + if (level > stdlog::ReportLevel() || logger::ErrFile::stream() == nullptr) ;\ + else stdlog().get(level) + +//! Debug log to stdlog +#define SPAM FILTER(logger::Spam) + +//! Debug log to stdlog +#define DEBUG FILTER(logger::Debug) + +//! Debug log to stdlog +#define INFO FILTER(logger::Info) + +//! Warning log to stdlog +#define WARNING FILTER(logger::Warning) + +//! Error log to stdlog +#define ERROR FILTER(logger::Error) + +//! Critical log to stdlog +#define CRITICAL FILTER(logger::Critical) + + +} // end namespace specmicp + +#endif // SPECMICP_UTILS_LOG_HPP