diff --git a/include/rosa/config/config.h b/include/rosa/config/config.h index 5021e3c..7e627a5 100644 --- a/include/rosa/config/config.h +++ b/include/rosa/config/config.h @@ -1,55 +1,56 @@ /******************************************************************************* * * File: config.h * * Contents: Configuration nformation on the build of the library. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #ifndef ROSA_CONFIG_CONFIG_H #define ROSA_CONFIG_CONFIG_H #include // Various preprocessor macros containing config information. #include "rosa/config/rosa_config.h" // This OS-specific block defines one of the following: // - ROSA_LINUX // - ROSA_WINDOWS // It also defines ROSA_POSIX for POSIX-compatible systems #if defined(__linux__) #define ROSA_LINUX #elif defined(WIN32) || defined(_WIN32) #define ROSA_WINDOWS #else #error Platform and/or compiler not supported #endif #if defined(ROSA_LINUX) #define ROSA_POSIX #endif // Defining filenames in a project-relative way based on absolute paths. #include "rosa/config/project_path.hpp" #define __FILENAME__ (__FILE__ + project_relative_path_index(__FILE__)) // Convenience macros. #define ROSA_VOID_STMT static_cast(0) #define ROSA_IGNORE_UNUSED(x) static_cast(x) #define ROSA_CRITICAL(error) \ do { \ - std::cerr << "[FATAL] " << __FILENAME__ << ":" << __LINE__ \ - << ": critical error: '" << (error) << "'" << std::endl; \ + std::cerr << "[FATAL] " << __func__ << "@" << __FILENAME__ << ":" \ + << __LINE__ << ": critical error: '" << (error) << "'" \ + << std::endl; \ ::abort(); \ } while (false) #define ROSA_RAISE_ERROR(msg) throw std::runtime_error(msg) #endif // ROSA_CONFIG_CONFIG_H diff --git a/include/rosa/config/project_path.hpp b/include/rosa/config/project_path.hpp index 29f7273..e384fd1 100644 --- a/include/rosa/config/project_path.hpp +++ b/include/rosa/config/project_path.hpp @@ -1,50 +1,50 @@ /******************************************************************************* * * File: project_path.hpp * * Contents: Facility for compile-time manipulation of paths. * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ -#ifndef ROSA_SUPPORT_PROJECT_PATH_H -#define ROSA_SUPPORT_PROJECT_PATH_H +#ifndef ROSA_CONFIG_PROJECT_PATH_HPP +#define ROSA_CONFIG_PROJECT_PATH_HPP #include "rosa/config/rosa_config.h" namespace rosa { // Nested namespace containing the implementation of the provided features, // not supposed to be used directly. namespace impl { // Implementation of the static search for the project-relative part of an // absolute path. constexpr size_t project_relative_path_index_impl(const char *const path, const char *const project = ROSA_SRC_DIR, const size_t index = 0) { return project[index] == '\0' ? index // Found it. : (path[index] == '\0' || project[index] != path[index]) ? 0 // Path is not under project. : project_relative_path_index_impl( path, project, index + 1); // Continue searching... } } // End namespace impl // Staticaly finds the index of the project-relative part of a absolute path. // Returns 0 if the absolute path is not located under the project directory. constexpr size_t project_relative_path_index(const char * const path) { return impl::project_relative_path_index_impl(path); } } // End namespace rosa -#endif // ROSA_SUPPORT_PROJECT_PATH_H +#endif // ROSA_CONFIG_PROJECT_PATH_HPP diff --git a/include/rosa/support/log.h b/include/rosa/support/log.h index 315f096..e3bde38 100644 --- a/include/rosa/support/log.h +++ b/include/rosa/support/log.h @@ -1,98 +1,143 @@ /******************************************************************************* * * File: log.h * * Contents: Facility for logging * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #ifndef ROSA_SUPPORT_LOG_H #define ROSA_SUPPORT_LOG_H -#include "debug.hpp" +#include "rosa/config/config.h" +#include #include -// Valid log levels. +/* **************************************************************************** + * Log Levels * + * ****************************************************************************/ + +// Valid log levels, only for preprocessor definitions below. // NOTE: Keep in sync with the values of enum class rosa::LogLevel. #define ROSA_LOG_LEVEL_ERROR 0 #define ROSA_LOG_LEVEL_WARNING 1 #define ROSA_LOG_LEVEL_INFO 2 #define ROSA_LOG_LEVEL_DEBUG 3 #define ROSA_LOG_LEVEL_TRACE 4 namespace rosa { // Type-safe definition of log levels. // NOTE: Keep values in sync with the corresponding preprocessor definitions. enum class LogLevel { Error = ROSA_LOG_LEVEL_ERROR, Warning = ROSA_LOG_LEVEL_WARNING, Info = ROSA_LOG_LEVEL_INFO, Debug = ROSA_LOG_LEVEL_DEBUG, Trace = ROSA_LOG_LEVEL_TRACE }; // Converts a LogLevel to its string representation. std::string logLevelToString(const LogLevel logLevel); } // End namespace rosa -// Simple logging implementation. +/* **************************************************************************** + * Logger Implementation * + * ****************************************************************************/ + +// Stream to print logs to. +// FIXME: Make it configurable, e.g. printing into a file. +#define ROSA_LOG_OSTREAM std::clog + +// Simple logging implementation printing a string message. // FIXME: Make logging thread-safe. #define ROSA_LOG_IMPL(level, output) \ do { \ - rosa::dbgs() << "[" << rosa::logLevelToString(level) << "] " << __func__ \ - << "@" << __FILENAME__ << ":" << __LINE__ << ": " << (output) \ - << std::endl; \ + ROSA_LOG_OSTREAM << "[" << rosa::logLevelToString(level) << "] " \ + << __func__ << "@" << __FILENAME__ << ":" << __LINE__ \ + << ": " << (output) << std::endl; \ } while (false) +// Simple logging implementation providing a stream to print to. +// FIXME: Make logging thread-safe. +#define ROSA_LOG_STREAM_IMPL(level) \ + do { \ + ROSA_LOG_OSTREAM << "[" << rosa::logLevelToString(level) << "] " \ + << __func__ << "@" << __FILENAME__ << ":" << __LINE__ \ + << ": "; \ + } while (false); \ + ROSA_LOG_OSTREAM + +namespace rosa { +// Dummy ostream printing to nowhere. +extern std::ostream LogSink; +} // End namespace rosa + +// A stream ignoring all its input. +#define ROSA_LOG_STREAM_IGNORE rosa::LogSink + +/* **************************************************************************** + * Logging Interface * + * ****************************************************************************/ + // Define logging macros if logging is enabled. #ifdef ROSA_LOG_LEVEL +#define LOG_ERROR_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Error) #define LOG_ERROR(output) ROSA_LOG_IMPL(rosa::LogLevel::Error, output) #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_WARNING +#define LOG_WARNING_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Error) #define LOG_WARNING(output) ROSA_LOG_IMPL(rosa::LogLevel::Warning, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_INFO +#define LOG_INFO_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Error) #define LOG_INFO(output) ROSA_LOG_IMPL(rosa::LogLevel::Info, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_DEBUG +#define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Debug) #define LOG_DEBUG(output) ROSA_LOG_IMPL(rosa::LogLevel::Debug, output) #endif #if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_TRACE +#define LOG_TRACE_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Trace) #define LOG_TRACE(output) ROSA_LOG_IMPL(rosa::LogLevel::Trace, output) #endif #endif // defined ROSA_LOG_LEVEL // Define all disabled logging features as void. #ifndef LOG_ERROR +#define LOG_ERROR_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_ERROR(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_WARNING +#define LOG_WARNING_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_WARNING(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_INFO +#define LOG_INFO_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_INFO(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_DEBUG +#define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_DEBUG(output) ROSA_IGNORE_UNUSED(output) #endif #ifndef LOG_TRACE +#define LOG_TRACE_STREAM ROSA_LOG_STREAM_IGNORE #define LOG_TRACE(output) ROSA_IGNORE_UNUSED(output) #endif #endif // ROSA_SUPPORT_LOG_H diff --git a/lib/support/log.cpp b/lib/support/log.cpp index b9b8fc5..c0de18f 100644 --- a/lib/support/log.cpp +++ b/lib/support/log.cpp @@ -1,29 +1,31 @@ /******************************************************************************* * * File: log.cpp * * Contents: Facility for logging * * Copyright 2017 * * Author: David Juhasz (david.juhasz@tuwien.ac.at) * ******************************************************************************/ #include "rosa/support/log.h" namespace rosa { std::string logLevelToString(const LogLevel logLevel) { switch(logLevel) { case LogLevel::Error: return "ERROR"; case LogLevel::Warning: return "WARNING"; case LogLevel::Info: return "INFO"; case LogLevel::Debug: return "DEBUG"; case LogLevel::Trace: return "TRACE"; - default: ROSA_CRITICAL(""); + default: ROSA_CRITICAL("Invalid LogLevel"); } } +std::ostream LogSink(nullptr); + } // End namespace rosa