Browse Source

merge l3pp branch

Former-commit-id: ee5ea9242d
tempestpy_adaptions
sjunges 9 years ago
parent
commit
d9d9007975
  1. 10
      CMakeLists.txt
  2. 13
      resources/3rdparty/CMakeLists.txt
  3. 21
      resources/3rdparty/l3pp/LICENSE
  4. 107
      resources/3rdparty/l3pp/Readme.md
  5. 158
      resources/3rdparty/l3pp/formatter.h
  6. 106
      resources/3rdparty/l3pp/impl/formatter.h
  7. 123
      resources/3rdparty/l3pp/impl/logger.h
  8. 32
      resources/3rdparty/l3pp/impl/logging.h
  9. 18
      resources/3rdparty/l3pp/impl/sink.h
  10. 165
      resources/3rdparty/l3pp/l3pp.h
  11. 179
      resources/3rdparty/l3pp/logger.h
  12. 108
      resources/3rdparty/l3pp/sink.h
  13. 2
      src/builder/ExplicitDFTModelBuilder.cpp
  14. 7
      src/cli/cli.cpp
  15. 2
      src/settings/modules/DebugSettings.cpp
  16. 33
      src/utility/initialize.cpp
  17. 7
      src/utility/initialize.h
  18. 23
      src/utility/logging.h
  19. 130
      src/utility/macros.h

10
CMakeLists.txt

@ -200,6 +200,16 @@ message(STATUS "StoRM - Using Compiler Configuration: ${STORM_COMPILED_BY}")
# in the the system does not have a library # in the the system does not have a library
add_subdirectory(resources/3rdparty) add_subdirectory(resources/3rdparty)
#############################################################
##
## l3pp
##
#############################################################
# l3pp is set up as external project
include_directories(${l3pp_INCLUDE})
add_dependencies(resources l3pp)
############################################################# #############################################################
## ##
## gmm ## gmm

13
resources/3rdparty/CMakeLists.txt

@ -81,3 +81,16 @@ set(GTEST_INCLUDE_DIR ${source_dir}/include PARENT_SCOPE)
# Specify MainTest's link libraries # Specify MainTest's link libraries
ExternalProject_Get_Property(googletest binary_dir) ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBRARIES ${binary_dir}/libgtest.a ${binary_dir}/libgtest_main.a PARENT_SCOPE) set(GTEST_LIBRARIES ${binary_dir}/libgtest.a ${binary_dir}/libgtest_main.a PARENT_SCOPE)
ExternalProject_Add(
l3pp
GIT_REPOSITORY https://github.com/hbruintjes/l3pp.git
GIT_TAG master
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/l3pp
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_INSTALL ON
)
ExternalProject_Get_Property(l3pp source_dir)
set(l3pp_INCLUDE "${source_dir}/" PARENT_SCOPE)

21
resources/3rdparty/l3pp/LICENSE

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 nafur
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

107
resources/3rdparty/l3pp/Readme.md

@ -0,0 +1,107 @@
L3++: Lightweight Logging Library for C++
=====
L3++ is a self-contained, single-header, cross-platform logging library for C++.
The main goals for this library are simplicity, modularity and ease of use.
This library is released under the MIT License.
Copyright (C) 2015 Gereon Kremer
Concepts
=====
L3++ is based on the following conceptual components:
* RecordInfo: A record info stores auxiliary information of a log message like the filename, line number and function name where the log message was emitted.
* Logger: A logger categorizes log messages, usually according to logical components or modules in the source code.
* Sink: A sink represents a logging output, for example the terminal or a log file.
* Formatter: A formatter is associated with a sink and converts a log message into an actual string.
Log levels
-----
The following log levels exist (from `l3pp::LogLevel`):
* ALL
* TRACE
* DEBUG
* INFO
* WARN
* ERR
* FATAL
* OFF
Hierarchical Loggers
-----
Loggers are hierarchically structured strings like `"app.module.submodule"`. In this example, `submodule` is considered a sublogger of `module` and `app` the parent of `module`. A sublogger implicitly inherits all sinks and the log level of the parent, unless explicitly configured otherwise.
The hierarchical tree of loggers always contains the root logger at the top. The root logger itself does not have a parent, nor a name. It can be accessed via `l3pp::Logging::getRootLogger()`.
Each logger is assigned a log level, or is configured to inherit the log level of the parent (with the special log level `l3pp::LogLevel::INHERIT`). Note that the root logger cannot inherit a log level. Any log entry with a lower level is filtered out and will not be logged.
A logger can also be assigned one or more sinks. By default, a logger will log to both the sinks of its parent, as well as its own sinks. Should a logger only use it own sinks, it should be set to non-additive (using `Logger::setAdditive(false)`).
Sinks
-----
A sink provides an output for loggers. Loggers may define multiple sinks, and sinks may be shared between loggers. Sinks are associated with a formatter and a log level. The log level specifies the minimum level of a message for it to be output (independent of the log level of a logger), and by default permits all log messages. A formatter formats the log messages before being output. By default, a simple formatter is used which prints the log level, message and a newline, but other formatters can be specified.
Formatters
-----
A formatter shapes a log message before being sent to its final destination. A non-configurable simple formatter exists, as well as a template-based formatter. The latter specifies the format of a message by means of its template arguments, see `l3pp::makeTemplateFormatter`.
Basic Usage
=====
A logger object can be accessed via `l3pp::Logger::getLogger()` or `l3pp::Logger::getRootLogger()`. By default, the root logger does not output anywhere. Therefore, a sink should be added. An initial configuration may look like this:
l3pp::Logger::initialize();
l3pp::SinkPtr sink = log4carl::StreamSink::create(std::clog);
l3pp::Logger::getRootLogger()->addSink(sink);
l3pp::Logger::getRootLogger()->setLevel(log4carl::LogLevel::INFO);
In this demo, a single sink is created that passes log messages to the standard logging stream `std::clog`. All messages must have at least level `LVL_INFO` before being printed.
The actual logging is performed using a handful of macros.
These macros
Considerations
=====
Performance
-----
While the use of hierarchical loggers and multiple sinks with associated formatters gives a lot of flexibility, it comes at a certain price. As the configuration is done at runtime (and may even change at runtime), the question whether a certain message is printed can only be answered at runtime. Therefore, every message, whether you will ever see it or not, has to pass through the logger and cost runtime.
To mitigate this, we suggest the following:
Create a preprocessor flag (like `ENABLE_LOGGING`) and define your own set of logging macros.
If this flag is defined, make your macros forward to the `L3PP_LOG_*` macros.
If this flag is not defined, make your macros do nothing.
Multiple usages in the same project
-----
Assume you have an application that uses L3++ for logging as well as some other library that also uses L3++.
L3++ will play nicely in this scenario (partly, it was designed for this case).
However, you should take care of a few things:
* Colliding loggers: Prefix your loggers with some unique prefix.
* Colliding macros: If you implement the aforementioned `ENABLE_LOGGING` macro, prefix your macros with your project name. Otherwise, these macros will collide.
Implementation Details
=====
Sinks
-----
A sink is a class that provides some `log` method. Any class that inherits from `l3pp::Sink` can be used.
As of now, two implementations are available:
* FileSink: Writes to a output file.
* StreamSink: Writes to any given `std::ostream`, for example to `std::cout`.
Formatters
-----
A formatter is a functor that given a log entry, provides a formatted string. The base class `Formatter` provides some very simple formatting, whereas `TemplateFormatter` provides more control over the shape. Internally, a `TemplateFormatter` streams its arguments to a stream before constructing the string. The special types `FieldStr` and `TimeStr` can be used to format particular attributes of a log entry.

158
resources/3rdparty/l3pp/formatter.h

@ -0,0 +1,158 @@
/**
* @file formatter.h
* @author Harold Bruintjes <h.bruintjes@cs.rwth-aachen.de>
*
* Define the Formatter class, used to format output of a sink
*/
#pragma once
#include <string>
#include <tuple>
namespace l3pp {
/**
* Formats a log messages. This is a base class that simply print the message
* with the log level prefix, see derived classes such as TemplatedFormatter
* for more interesting data.
*/
class Formatter {
friend class Logger;
static void initialize();
virtual std::string format(EntryContext const& context, std::string const& msg) const;
public:
virtual ~Formatter() {}
std::string operator()(EntryContext const& context, std::string const& msg) {
return format(context, msg);
}
};
typedef std::shared_ptr<Formatter> FormatterPtr;
/**
* Possible fields for FieldStr instance
*/
enum class Field {
/// Name of the file (everything following the last path separator)
FileName,
/// Full path of the file
FilePath,
/// Line number
Line,
/// Name of function currently executed
Function,
/// Name of the logger
LoggerName,
/// Message to be logged
Message,
/// Level of the log entry
LogLevel,
/// Number of milliseconds since the logger was initialized
WallTime,
};
/**
* Controls justification of formatted log fields.
*/
enum class Justification {
/// Left align field
LEFT,
/// Right align field
RIGHT
};
/**
* Formatter for log entry fields, with the exception of time stamp formatting
* (see TimeStr for that). The Field template argument determines which field
* is printed, see logging::Field.
* The other template arguments control the alignment of the output string.
*/
template<Field field, int Width = 0, Justification j = Justification::RIGHT, char Fill = ' '>
class FieldStr {
public:
void stream(std::ostream& os, EntryContext const& context, std::string const& msg) const;
};
/**
* Formatter for log time stamps. The constructor expects a single string
* argument which is a formatter for the time stamp. For the specification of
* this format string see the documentation for std::put_time . You can use for
* example "%c" or "%T".
* The template arguments control the alignment of the output string.
*/
class TimeStr {
std::string formatStr;
public:
TimeStr(char const* format) : formatStr(format) {
}
TimeStr(std::string const& format) : formatStr(format) {
}
void stream(std::ostream& os, EntryContext const& context, std::string const&) const;
};
/**
* Formatter which formats the output based on the (templated) arguments given.
* The arguments can be anything that implements the stream operator <<, but
* more interestingly also the various FormatField subclasses. These classes
* can output the various fields associated with a log entry.
*/
template<typename ... Formatters>
class TemplateFormatter : public Formatter {
std::tuple<Formatters...> formatters;
template <int N>
typename std::enable_if<N < (sizeof...(Formatters))>::type
formatTuple(EntryContext const& context, std::string const& msg, std::ostream& os) const {
formatElement(std::get<N>(formatters), os, context, msg);
formatTuple<N+1>(context, msg, os);
}
template <int N>
typename std::enable_if<(N >= sizeof...(Formatters))>::type
formatTuple(EntryContext const&, std::string const&, std::ostream&) const {
}
template<Field field, int Width, Justification j, char Fill>
void formatElement(FieldStr<field, Width, j, Fill> const& t, std::ostream& stream, EntryContext const& context, std::string const& msg) const {
t.stream(stream, context, msg);
}
void formatElement(TimeStr const& t, std::ostream& stream, EntryContext const& context, std::string const& msg) const {
t.stream(stream, context, msg);
}
template<typename T>
void formatElement(T const& t, std::ostream& stream, EntryContext const&, std::string const&) const {
stream << t;
}
public:
TemplateFormatter(Formatters ... formatters) :
formatters(std::forward<Formatters>(formatters)...)
{
}
std::string format(EntryContext const& context, std::string const& msg) const override;
};
/**
* Helper function to create a TemplateFormatter. Simply call with some
* formatable arguments, e.g.,
* @code{.cpp}
* logging::makeTemplateFormatter(
* logging::FieldStr<logging::Field::LogLevel>(), " - ",
* logging::FieldStr<logging::Field::Message>(), "\n");
* @endcode
*/
template<typename ... Formatters>
FormatterPtr makeTemplateFormatter(Formatters&& ... formatters) {
return std::make_shared<TemplateFormatter<Formatters...>>(std::forward<Formatters>(formatters)...);
}
}

106
resources/3rdparty/l3pp/impl/formatter.h

@ -0,0 +1,106 @@
/**
* @file formatter.h
* @author Harold Bruintjes <h.bruintjes@cs.rwth-aachen.de>
*
* Implementation of Formatter classes
*/
#pragma once
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <cstring> //strrchr
namespace l3pp {
namespace detail {
/**
* Internal function to get wall-time
*/
inline static std::chrono::system_clock::time_point GetStartTime() {
static std::chrono::system_clock::time_point startTime = std::chrono::system_clock::now();
return startTime;
}
}
inline void Formatter::initialize() {
// Init wall-time
detail::GetStartTime();
}
inline std::string Formatter::format(EntryContext const& context, std::string const& msg) const {
std::stringstream stream;
stream << context.level << " - " << msg << '\n';
return stream.str();
}
template<Field field, int Width, Justification j, char Fill>
inline void FieldStr<field, Width, j, Fill>::stream(std::ostream& os, EntryContext const& context, std::string const& msg) const {
os << std::setw(Width);
os << std::setfill(Fill);
switch(j) {
case Justification::LEFT:
os << std::left;
case Justification::RIGHT:
os << std::right;
}
switch(field) {
case Field::FileName:
#ifdef _WIN32
os << strrchr(context.filename, '\\')+1;
#else
os << strrchr(context.filename, '/')+1;
#endif
break;
case Field::FilePath:
os << context.filename;
break;
case Field::Line:
os << context.line;
break;
case Field::Function:
os << context.funcname;
break;
case Field::LoggerName:
os << context.logger->getName();
break;
case Field::Message:
os << msg;
break;
case Field::LogLevel:
os << context.level;
break;
case Field::WallTime:
auto runtime = context.timestamp - detail::GetStartTime();
os << std::chrono::duration_cast<std::chrono::milliseconds>(runtime).count();
break;
}
}
inline void TimeStr::stream(std::ostream& os, EntryContext const& context, std::string const&) const {
auto time = std::chrono::system_clock::to_time_t(context.timestamp);
auto timeinfo = localtime (&time);
#if __GNUC__ >= 5 || __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 7) || _MSC_VER >= 1700
//TODO: Need better way to detect thing
os << std::put_time(timeinfo, formatStr.c_str());
#else
char buffer[1024];
if (strftime(buffer, 1024, formatStr.c_str(), timeinfo)) {
os << buffer;
}
#endif
}
template<typename ... Formatters>
inline std::string TemplateFormatter<Formatters...>::format(EntryContext const& context, std::string const& msg) const {
std::stringstream stream;
formatTuple<0>(context, msg, stream);
return stream.str();
}
}

123
resources/3rdparty/l3pp/impl/logger.h

@ -0,0 +1,123 @@
/**
* @file logger.h
*
* Defines the base Logger class
*/
#pragma once
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
namespace l3pp {
namespace detail {
/**
* Internal function to get all configured loggers. Should not be used
* directly, see Logger::getLogger()
*/
static inline std::map<std::string, LogPtr>& GetLoggers() {
static std::map<std::string, LogPtr> loggers;
return loggers;
}
}
inline LogStream::~LogStream() {
if (level != LogLevel::OFF) {
logger.log(level, stream.str(), context);
}
}
inline void Logger::logEntry(EntryContext const& context, std::string const& msg) {
for(auto& sink: sinks) {
sink->log(context, msg);
}
if (additive && parent) {
parent->logEntry(context, msg);
}
}
inline void Logger::removeSink(SinkPtr sink) {
std::vector<SinkPtr>::iterator pos = std::find(sinks.begin(), sinks.end(), sink);
if (pos != sinks.end()) {
sinks.erase(pos);
}
}
inline void Logger::log(LogLevel level, std::string const& msg, EntryContext context) {
if (level < getLevel()) {
return;
}
context.level = level;
context.logger = this;
logEntry(context, msg);
}
inline LogStream Logger::log(LogLevel level, EntryContext context) {
if (level < getLevel()) {
// Effectively disables the stream
return LogStream(*this, LogLevel::OFF, context);
} else {
return LogStream(*this, level, context);
}
}
inline void Logger::initialize() {
// Setup root logger
getRootLogger();
// Set wall time
Formatter::initialize();
}
inline void Logger::deinitialize() {
detail::GetLoggers().clear();
getRootLogger()->sinks.clear();
}
inline LogPtr Logger::getRootLogger() {
static LogPtr rootLogger = LogPtr(new Logger());
return rootLogger;
}
inline LogPtr Logger::getLogger(std::string name) {
if (name.size() == 0) {
// Root logger
return getRootLogger();
}
auto& loggers = detail::GetLoggers();
auto it = loggers.find(name);
if (it != loggers.end()) {
return it->second;
} else {
auto n = name.rfind('.');
LogPtr parent;
if (n == std::string::npos) {
parent = getRootLogger();
} else{
parent = getLogger(name.substr(0, n));
}
LogPtr newLogger = LogPtr(new Logger(name, parent));
loggers.emplace(name, newLogger);
return newLogger;
}
}
template<typename T>
inline LogStream const& operator<<(LogStream const& stream, T const& val) {
if (stream.level != LogLevel::OFF) {
stream.stream << val;
}
return stream;
}
inline LogStream const& operator<<(LogStream const& stream, std::ostream& (*F)(std::ostream&)) {
if (stream.level != LogLevel::OFF) {
stream.stream << F;
}
return stream;
}
}

32
resources/3rdparty/l3pp/impl/logging.h

@ -0,0 +1,32 @@
/**
* @file logging.h
*
* Implementation of general logging functionality
*/
#pragma once
#include <ostream>
namespace l3pp {
/**
* Streaming operator for LogLevel.
* @param os Output stream.
* @param level LogLevel.
* @return os.
*/
inline std::ostream& operator<<(std::ostream& os, LogLevel level) {
switch (level) {
case LogLevel::TRACE: return os << "TRACE";
case LogLevel::DEBUG: return os << "DEBUG";
case LogLevel::INFO: return os << "INFO";
case LogLevel::WARN: return os << "WARN";
case LogLevel::ERR: return os << "ERROR";
case LogLevel::FATAL: return os << "FATAL";
case LogLevel::OFF: return os << "OFF";
default: return os << "???";
}
}
}

18
resources/3rdparty/l3pp/impl/sink.h

@ -0,0 +1,18 @@
/**
* @file sink.h
*
* Implementation for Sinks
*/
#pragma once
namespace l3pp {
inline void Sink::log(EntryContext const& context, std::string const& message) const {
if (context.level >= this->level) {
logEntry((*formatter)(context, message));
}
}
}

165
resources/3rdparty/l3pp/l3pp.h

@ -0,0 +1,165 @@
/**
* @file l3pp.h
* @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
* @author Harold Bruintjes <h.bruintjes@cs.rwth-aachen.de>
*
* The lightweight logging library for C++.
*
* This logging facility is fairly generic and is used as a simple and
* header-only alternative to more advanced solutions like log4cplus or
* boost::log.
*
* The basic components are Sinks, Formatters and Loggers.
*
* A Sink represents a logging output like a terminal or a log file.
* This implementation provides a FileSink and a StreamSink, but the basic
* Sink class can be extended as necessary.
*
* A Formatter is associated with a Sink and produces the actual string that is
* sent to the Sink.
* Usually, it adds auxiliary information like the current time, LogLevel and
* source location to the string logged by the user.
* The Formatter implements a reasonable default behavior for simple logging,
* but it can be subclassed and modified as necessary.
*
* The Logger class finally plugs all these components together.
* Individual loggers can log to one or more sinks (inheritable) and are
* associated with an (inheritable) log level.
*
* Initial configuration may look like this:
* @code{.cpp}
* l3pp::Logger::initialize();
* l3pp::SinkPtr sink = l3pp::StreamSink::create(std::clog);
* l3pp::Logger::getRootLogger()->addSink(sink);
* l3pp::Logger::getRootLogger()->setLevel(l3pp::LogLevel::INFO);
* @endcode
*
* Macro facilitate the usage:
* <ul>
* <li>`L3PP_LOG_<LVL>(logger, msg)` produces a normal log message where
* logger should be string identifying the logger (or a LogPtr) and msg is the
* message to be logged.</li>
* </ul>
* Any message (`msg`) can be an arbitrary expression that one would
* stream to an `std::ostream` like `stream << (msg);`. The default formatter
* adds newlines.
* Manipulators are generally supported. However, for performance avoid std::endl
* and use '\n' directly.
*/
#pragma once
#include <chrono>
#include <memory>
namespace l3pp {
/**
* Indicated which log messages should be forwarded to some sink.
*
* All messages which have a level that is equal or greater than the specified
* value will be forwarded.
*/
enum class LogLevel {
/// Log messages used for tracing the program flow in detail.
TRACE,
/// Log messages used for debugging.
DEBUG,
/// Log messages used for information.
INFO,
/// Log messages used to warn about an undesired state.
WARN,
/// Log messages used for errors that can be handled.
ERR,
/// Log messages used for errors that lead to program termination.
FATAL,
/// Log no messages.
OFF,
/// Parent level
INHERIT,
/// Default log level.
DEFAULT = WARN,
/// All log messages.
ALL = TRACE
};
/**
* Streaming operator for LogLevel.
* @param os Output stream.
* @param level LogLevel.
* @return os.
*/
inline std::ostream& operator<<(std::ostream& os, LogLevel level);
class Logger;
/**
* Contextual information for a new log entry, contains such this as location,
* log info (level, logger) and the time of the event.
* A context will be created automatically by using the macros
*/
struct EntryContext {
// Program location
const char* filename;
size_t line;
const char* funcname;
// Time of entry
std::chrono::system_clock::time_point timestamp;
// Log event info
Logger const* logger;
LogLevel level;
EntryContext(const char* filename, size_t line, const char* funcname) :
filename(filename), line(line), funcname(funcname),
timestamp(std::chrono::system_clock::now()), logger(nullptr),
level(LogLevel::OFF)
{
}
EntryContext() :
filename(""), line(0), funcname(""),
timestamp(std::chrono::system_clock::now()), logger(nullptr),
level(LogLevel::OFF)
{
}
};
}
#include "formatter.h"
#include "sink.h"
#include "logger.h"
#include "impl/logging.h"
#include "impl/logger.h"
#include "impl/formatter.h"
#include "impl/sink.h"
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
/// Create a record info.
#define __L3PP_LOG_RECORD l3pp::EntryContext(__FILE__, __LINE__, __func__)
/// Basic logging macro.
#define __L3PP_LOG(level, channel, expr) do { \
auto L3PP_channel = ::l3pp::Logger::getLogger(channel); \
if (L3PP_channel->getLevel() <= level) { \
L3PP_channel->log(level, __L3PP_LOG_RECORD) << expr; \
} \
} while(false)
/// Log with level TRACE.
#define L3PP_LOG_TRACE(channel, expr) __L3PP_LOG(::l3pp::LogLevel::TRACE, channel, expr)
/// Log with level DEBUG.
#define L3PP_LOG_DEBUG(channel, expr) __L3PP_LOG(::l3pp::LogLevel::DEBUG, channel, expr)
/// Log with level INFO.
#define L3PP_LOG_INFO(channel, expr) __L3PP_LOG(::l3pp::LogLevel::INFO, channel, expr)
/// Log with level WARN.
#define L3PP_LOG_WARN(channel, expr) __L3PP_LOG(::l3pp::LogLevel::WARN, channel, expr)
/// Log with level ERROR.
#define L3PP_LOG_ERROR(channel, expr) __L3PP_LOG(::l3pp::LogLevel::ERR, channel, expr)
/// Log with level FATAL.
#define L3PP_LOG_FATAL(channel, expr) __L3PP_LOG(::l3pp::LogLevel::FATAL, channel, expr)

179
resources/3rdparty/l3pp/logger.h

@ -0,0 +1,179 @@
/**
* @file logger.h
*
* Defines the base Logger class
*/
#pragma once
#include <vector>
#include <sstream>
namespace l3pp {
/**
* LogStream is a logger object that can be streamed into, writing an entry
* to the logger associated upon destruction. Instances of this classer are
* returned by Logger log() functions, so they can be used as such:
* logger->debug() << "Message";
*/
class LogStream {
friend class Logger;
Logger& logger;
LogLevel level;
EntryContext context;
mutable std::ostringstream stream;
LogStream(Logger& logger, LogLevel level, EntryContext context) :
logger(logger), level(level), context(context)
{
}
LogStream(const LogStream&) = delete;
LogStream& operator=(const LogStream&) = delete;
public:
LogStream(LogStream&& other) :
logger(other.logger), level(other.level), context(std::move(other.context))/*,
stream(std::move(other.stream))*/
{
stream.str(other.stream.str());
}
~LogStream();
template<typename T>
friend LogStream const& operator<<(LogStream const& stream, T const& val);
friend LogStream const& operator<<(LogStream const& stream, std::ostream& (*F)(std::ostream&));
};
/**
* Main logger class. Keeps track of all Logger instances, and can be used to
* log various messages. Before the logging library is used, make sure to
* call Logger::initialize(). Loggers are hierarchically nested, by means of
* names separated by a period. All loggers are a (indirect) child of the root
* logger, see Logger::getRootLogger() and Logger::getLogger().
* A logger is associated with a LogLevel. Any entry with a level below this
* level will be filtered out. A LogLevel of INHERIT means the parent log
* level will be compared against instead.
* A logger can be associated with 1 or more Sinks. A log entry is printed to
* each associated sink. If the Logger is set additive (see getAdditive(),
* setAdditive()) parent sinks are logged to as well (by default true).
* Logging can be performed either as a single string message, or by using a
* stream. The latter requires the end() method to be called before the entry
* is logged. For convenience, various logging macros are defined at the end
* of this header.
*/
class Logger {
friend class Formatter;
typedef std::shared_ptr<Logger> LogPtr;
LogPtr parent;
std::string name;
LogLevel level;
std::vector<SinkPtr> sinks;
bool additive;
// Logger constructors are private
Logger() : parent(nullptr), name(""), level(LogLevel::DEFAULT),
additive(true)
{
}
Logger(std::string const& name, LogPtr parent) : parent(parent), name(name),
level(LogLevel::INHERIT), additive(true)
{
}
void logEntry(EntryContext const& context, std::string const& msg);
public:
void addSink(SinkPtr sink) {
sinks.push_back(sink);
}
void removeSink(SinkPtr sink);
void setLevel(LogLevel level) {
if (level == LogLevel::INHERIT && !parent) {
return;
}
this->level = level;
}
LogLevel getLevel() const {
if (level == LogLevel::INHERIT) {
return parent->getLevel();
}
return level;
}
std::string const& getName() const {
return name;
}
bool getAdditive() const {
return additive;
}
void setAdditive(bool additive) {
this->additive = additive;
}
void log(LogLevel level, std::string const& msg, EntryContext context = EntryContext());
void trace(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::TRACE, msg, context);
}
void debug(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::DEBUG, msg, context);
}
void info(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::INFO, msg, context);
}
void warn(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::WARN, msg, context);
}
void error(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::ERR, msg, context);
}
void fatal(std::string const& msg, EntryContext context = EntryContext()) {
log(LogLevel::FATAL, msg, context);
}
LogStream log(LogLevel level, EntryContext context = EntryContext());
LogStream trace(EntryContext context = EntryContext()) {
return log(LogLevel::TRACE, context);
}
LogStream debug(EntryContext context = EntryContext()) {
return log(LogLevel::DEBUG, context);
}
LogStream info(EntryContext context = EntryContext()) {
return log(LogLevel::INFO, context);
}
LogStream warn(EntryContext context = EntryContext()) {
return log(LogLevel::WARN, context);
}
LogStream error(EntryContext context = EntryContext()) {
return log(LogLevel::ERR, context);
}
LogStream fatal(EntryContext context = EntryContext()) {
return log(LogLevel::FATAL, context);
}
static void initialize();
static void deinitialize();
static LogPtr getRootLogger();
static LogPtr getLogger(LogPtr logger) {
return logger;
}
static LogPtr getLogger(std::string name);
};
typedef std::shared_ptr<Logger> LogPtr;
}

108
resources/3rdparty/l3pp/sink.h

@ -0,0 +1,108 @@
/**
* @file sink.h
*
* Defines classes for log sinks (i.e. outputs)
*/
#pragma once
#include <ostream>
#include <fstream>
namespace l3pp {
/**
* Base class for a logging sink. It can only log some log entry to which some
* formatting is applied (see Formatter). A Sink may be given a log level,
* which filters out all entries below that level. By default is logs all
* entries.
*/
class Sink {
LogLevel level;
FormatterPtr formatter;
virtual void logEntry(std::string const& entry) const = 0;
public:
Sink() : level(LogLevel::ALL), formatter(std::make_shared<Formatter>()) {
}
Sink(FormatterPtr formatter) : level(LogLevel::ALL), formatter(formatter) {
}
/**
* Default destructor.
*/
virtual ~Sink() {}
LogLevel getLevel() const {
return level;
}
void setLevel(LogLevel level) {
this->level = level;
}
FormatterPtr getFormatter() const {
return formatter;
}
void setFormatter(FormatterPtr formatter) {
this->formatter = formatter;
}
/**
* Logs the given message with context info
*/
void log(EntryContext const& context, std::string const& message) const;
};
typedef std::shared_ptr<Sink> SinkPtr;
/**
* Logging sink that wraps an arbitrary `std::ostream`.
* It is meant to be used for streams like `std::cout` or `std::cerr`.
*/
class StreamSink: public Sink {
/// Output stream.
mutable std::ostream os;
void logEntry(std::string const& entry) const override {
os << entry << std::flush;
}
explicit StreamSink(std::ostream& _os) :
os(_os.rdbuf()) {}
public:
/**
* Create a StreamSink from some output stream.
* @param os Output stream.
*/
static SinkPtr create(std::ostream& os) {
return SinkPtr(new StreamSink(os));
}
};
/**
* Logging sink for file output.
*/
class FileSink: public Sink {
/// File output stream.
mutable std::ofstream os;
void logEntry(std::string const& entry) const override {
os << entry << std::flush;
}
explicit FileSink(const std::string& filename) :
os(filename, std::ios::out) {}
public:
/**
* Create a FileSink that logs to the specified file.
* The file is truncated upon construction.
* @param filename
*/
static SinkPtr create(const std::string& filename) {
return SinkPtr(new FileSink(filename));
}
};
}

2
src/builder/ExplicitDFTModelBuilder.cpp

@ -86,7 +86,7 @@ namespace storm {
} else { } else {
STORM_LOG_TRACE("Transition matrix: too big to print"); STORM_LOG_TRACE("Transition matrix: too big to print");
} }
STORM_LOG_TRACE("Exit rates: " << modelComponents.exitRates);
STORM_LOG_TRACE("Exit rates: " << storm::utility::vector::toString<ValueType>(modelComponents.exitRates));
STORM_LOG_TRACE("Markovian states: " << modelComponents.markovianStates); STORM_LOG_TRACE("Markovian states: " << modelComponents.markovianStates);
// Build state labeling // Build state labeling

7
src/cli/cli.cpp

@ -186,14 +186,13 @@ namespace storm {
} }
if (storm::settings::getModule<storm::settings::modules::GeneralSettings>().isVerboseSet()) { if (storm::settings::getModule<storm::settings::modules::GeneralSettings>().isVerboseSet()) {
STORM_GLOBAL_LOGLEVEL_INFO();
storm::utility::setLogLevel(l3pp::LogLevel::INFO);
} }
if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isDebugSet()) { if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isDebugSet()) {
STORM_GLOBAL_LOGLEVEL_DEBUG();
storm::utility::setLogLevel(l3pp::LogLevel::DEBUG);
} }
if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isTraceSet()) { if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isTraceSet()) {
STORM_GLOBAL_LOGLEVEL_TRACE();
storm::utility::setLogLevel(l3pp::LogLevel::TRACE);
} }
if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isLogfileSet()) { if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isLogfileSet()) {
storm::utility::initializeFileLogging(); storm::utility::initializeFileLogging();

2
src/settings/modules/DebugSettings.cpp

@ -38,7 +38,7 @@ namespace storm {
} }
std::string DebugSettings::getLogfilename() const { std::string DebugSettings::getLogfilename() const {
return this->getOption(traceOptionName).getArgumentByName("filename").getValueAsString();
return this->getOption(logfileOptionName).getArgumentByName("filename").getValueAsString();
} }
bool DebugSettings::isTestSet() const { bool DebugSettings::isTestSet() const {

33
src/utility/initialize.cpp

@ -1,16 +1,28 @@
#include "initialize.h" #include "initialize.h"
#include "src/utility/macros.h"
#include "src/settings/SettingsManager.h" #include "src/settings/SettingsManager.h"
#include "src/settings/modules/DebugSettings.h" #include "src/settings/modules/DebugSettings.h"
int storm_runtime_loglevel = STORM_LOGLEVEL_WARN;
#include <iostream>
#include <fstream>
namespace storm { namespace storm {
namespace utility { namespace utility {
void initializeLogger() { void initializeLogger() {
// Intentionally left empty.
l3pp::Logger::initialize();
// By default output to std::cout
l3pp::SinkPtr sink = l3pp::StreamSink::create(std::cout);
l3pp::Logger::getRootLogger()->addSink(sink);
// Default to warn, set by user to something else
l3pp::Logger::getRootLogger()->setLevel(l3pp::LogLevel::WARN);
l3pp::FormatterPtr fptr = l3pp::makeTemplateFormatter(
l3pp::FieldStr<l3pp::Field::LogLevel, 5, l3pp::Justification::LEFT>(),
" (", l3pp::FieldStr<l3pp::Field::FileName>(), ':', l3pp::FieldStr<l3pp::Field::Line>(), "): ",
l3pp::FieldStr<l3pp::Field::Message>(), '\n'
);
sink->setFormatter(fptr);
} }
void setUp() { void setUp() {
@ -22,8 +34,21 @@ namespace storm {
// Intentionally left empty. // Intentionally left empty.
} }
void setLogLevel(l3pp::LogLevel level) {
l3pp::Logger::getRootLogger()->setLevel(level);
if (level <= l3pp::LogLevel::DEBUG) {
#if STORM_LOG_DISABLE_DEBUG
std::cout << "***** warning ***** requested loglevel is not compiled\n";
#endif
}
}
void initializeFileLogging() { void initializeFileLogging() {
// FIXME.
if (storm::settings::getModule<storm::settings::modules::DebugSettings>().isLogfileSet()) {
std::string logFileName = storm::settings::getModule<storm::settings::modules::DebugSettings>().getLogfilename();
l3pp::SinkPtr sink = l3pp::FileSink::create(logFileName);
l3pp::Logger::getRootLogger()->addSink(sink);
}
} }
} }

7
src/utility/initialize.h

@ -1,6 +1,8 @@
#ifndef STORM_UTILITY_INITIALIZE_H #ifndef STORM_UTILITY_INITIALIZE_H
#define STORM_UTILITY_INITIALIZE_H #define STORM_UTILITY_INITIALIZE_H
#include "src/utility/logging.h"
namespace storm { namespace storm {
namespace utility { namespace utility {
/*! /*!
@ -17,6 +19,11 @@ namespace storm {
*/ */
void cleanUp(); void cleanUp();
/*!
* Set the global log level
*/
void setLogLevel(l3pp::LogLevel level);
/*! /*!
* Sets up the logging to file. * Sets up the logging to file.
*/ */

23
src/utility/logging.h

@ -0,0 +1,23 @@
#ifndef STORM_UTILITY_LOGGING_H_
#define STORM_UTILITY_LOGGING_H_
#include <l3pp.h>
#if !defined(STORM_LOG_DISABLE_DEBUG) && !defined(STORM_LOG_DISABLE_TRACE)
#define STORM_LOG_TRACE(message) L3PP_LOG_TRACE(l3pp::Logger::getRootLogger(), message)
#else
#define STORM_LOG_TRACE(message) (void)(0)
#endif
#if !defined(STORM_LOG_DISABLE_DEBUG)
#define STORM_LOG_DEBUG(message) L3PP_LOG_DEBUG(l3pp::Logger::getRootLogger(), message)
#else
#define STORM_LOG_DEBUG(message) (void)(0)
#endif
// Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels.
#define STORM_LOG_INFO(message) L3PP_LOG_INFO(l3pp::Logger::getRootLogger(), message)
#define STORM_LOG_WARN(message) L3PP_LOG_WARN(l3pp::Logger::getRootLogger(), message)
#define STORM_LOG_ERROR(message) L3PP_LOG_ERROR(l3pp::Logger::getRootLogger(), message)
#endif /* STORM_UTILITY_LOGGING_H_ */

130
src/utility/macros.h

@ -1,110 +1,38 @@
#ifndef STORM_UTILITY_MACROS_H_ #ifndef STORM_UTILITY_MACROS_H_
#define STORM_UTILITY_MACROS_H_ #define STORM_UTILITY_MACROS_H_
#include <cassert>
#include <string.h>
#include "storm-config.h"
#include "src/utility/logging.h"
#include <iostream> #include <iostream>
#include <sstream>
extern int storm_runtime_loglevel;
#define STORM_LOGLEVEL_ERROR 0
#define STORM_LOGLEVEL_WARN 1
#define STORM_LOGLEVEL_INFO 2
#define STORM_LOGLEVEL_DEBUG 3
#define STORM_LOGLEVEL_TRACE 4
#ifdef STORM_LOG_DISABLE_DEBUG
#define STORM_LOG_DISABLE_TRACE
#endif
#define __SHORT_FORM_OF_FILE__ \
(strrchr(__FILE__,'/') \
? strrchr(__FILE__,'/')+1 \
: __FILE__ \
)
#ifndef STORM_LOG_DISABLE_DEBUG
#define STORM_LOG_DEBUG(message) \
do { \
if(storm_runtime_loglevel >= STORM_LOGLEVEL_DEBUG) { \
std::stringstream __ss; \
__ss << message; \
std::cout << "DEBUG (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \
} \
} while (false)
#else
#define STORM_LOG_DEBUG(message) \
do { \
} while (false)
#endif
#ifndef STORM_LOG_DISABLE_TRACE
#define STORM_LOG_TRACE(message) \
do { \
if(storm_runtime_loglevel >= STORM_LOGLEVEL_TRACE) { \
std::stringstream __ss; \
__ss << message; \
std::cout << "TRACE (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \
} \
} while(false)
#else
#define STORM_LOG_TRACE(message) \
do { \
} while (false)
#endif
#include <cassert>
// Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set. // Define STORM_LOG_ASSERT which is only checked when NDEBUG is not set.
#ifndef NDEBUG #ifndef NDEBUG
#define STORM_LOG_ASSERT(cond, message) \ #define STORM_LOG_ASSERT(cond, message) \
do { \ do { \
if (!(cond)) { \
std::cout << "ASSERT FAILED (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << message << std::endl; \
assert(cond); \
} \
if (!(cond)) { \
STORM_LOG_ERROR(message); \
assert(cond); \
} \
} while (false) } while (false)
#else #else
#define STORM_LOG_ASSERT(cond, message) #define STORM_LOG_ASSERT(cond, message)
#endif #endif
// Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold. // Define STORM_LOG_THROW to always throw the exception with the given message if the condition fails to hold.
#define STORM_LOG_THROW(cond, exception, message) \ #define STORM_LOG_THROW(cond, exception, message) \
do { \ do { \
if (!(cond)) { \ if (!(cond)) { \
std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << message << std::endl; \
STORM_LOG_ERROR(message); \
throw exception() << message; \ throw exception() << message; \
} \ } \
} while (false) } while (false)
// Define STORM_LOG_WARN, STORM_LOG_ERROR and STORM_LOG_INFO to log the given message with the corresponding log levels.
#define STORM_LOG_WARN(message) \
do { \
if(storm_runtime_loglevel >= STORM_LOGLEVEL_WARN) { \
std::stringstream __ss; \
__ss << message; \
std::cout << "WARN (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \
} \
} while (false)
#define STORM_LOG_WARN_COND(cond, message) \ #define STORM_LOG_WARN_COND(cond, message) \
do { \ do { \
if (!(cond)) { \ if (!(cond)) { \
STORM_LOG_WARN(message); \
} \
} while (false)
#define STORM_LOG_INFO(message) \
do { \
if(storm_runtime_loglevel >= STORM_LOGLEVEL_INFO) { \
std::stringstream __ss; \
__ss << message; \
std::cout << "INFO (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \
STORM_LOG_WARN(message); \
} \ } \
} while (false) } while (false)
@ -115,15 +43,6 @@ do { \
} \ } \
} while (false) } while (false)
#define STORM_LOG_ERROR(message) \
do { \
if(storm_runtime_loglevel >= STORM_LOGLEVEL_ERROR) { \
std::stringstream __ss; \
__ss << message; \
std::cout << "ERROR (" << __SHORT_FORM_OF_FILE__ << ":" << __LINE__ << "): " << __ss.str() << std::endl; \
} \
} while (false) \
#define STORM_LOG_ERROR_COND(cond, message) \ #define STORM_LOG_ERROR_COND(cond, message) \
do { \ do { \
if (!(cond)) { \ if (!(cond)) { \
@ -131,37 +50,6 @@ do { \
} \ } \
} while (false) \ } while (false) \
#define STORM_GLOBAL_LOGLEVEL_ERROR() \
do { \
storm_runtime_loglevel = STORM_LOGLEVEL_ERROR; \
} while(false)
#define STORM_GLOBAL_LOGLEVEL_INFO() \
do { \
storm_runtime_loglevel = STORM_LOGLEVEL_INFO; \
} while (false)
#ifndef STORM_LOG_DISABLE_DEBUG
#define STORM_GLOBAL_LOGLEVEL_DEBUG() \
do { \
storm_runtime_loglevel = STORM_LOGLEVEL_DEBUG; \
} while(false)
#else
#define STORM_GLOBAL_LOGLEVEL_DEBUG() \
std::cout << "***** warning ***** loglevel debug is not compiled\n"
#endif
#ifndef STORM_LOG_DISABLE_TRACE
#define STORM_GLOBAL_LOGLEVEL_TRACE() \
do { \
storm_runtime_loglevel = STORM_LOGLEVEL_TRACE; \
} while(false)
#else
#define STORM_GLOBAL_LOGLEVEL_TRACE() \
std::cout << "***** warning ***** loglevel trace is not compiled\n"
#endif
/*! /*!
* Define the macros that print information and optionally also log it. * Define the macros that print information and optionally also log it.
*/ */

Loading…
Cancel
Save