Page MenuHomePhorge

No OneTemporary

Size
17 KB
Referenced Files
None
Subscribers
None
diff --git a/examples/simple/simple.cpp b/examples/simple/simple.cpp
index d4f6731..6dc00e8 100644
--- a/examples/simple/simple.cpp
+++ b/examples/simple/simple.cpp
@@ -1,25 +1,29 @@
/*******************************************************************************
*
* File: simple.cpp
*
* Contents: A very simple example to use RoSA Core library.
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#include "rosa/config/version.h"
#include "rosa/core/Unit.h"
+#include "rosa/support/log.h"
+#include "rosa/support/terminal_colors.h"
#include <iostream>
using namespace rosa;
+using namespace rosa::terminal;
int main(void) {
- std::cout << library_string() << " -- simple example" << std::endl;
- Unit unit1, unit2("Second"), unit3;
- std::cout << unit2 << std::endl;
+ LOG_INFO_STREAM << library_string() << " -- " << Color::Red
+ << "simple example" << Color::Default << std::endl;
+ Unit Unit1, Unit2("Second"), Unit3;
+ LOG_TRACE_STREAM << Unit2 << std::endl;
return 0;
}
diff --git a/include/rosa/support/debug.hpp b/include/rosa/support/debug.hpp
index 47e94de..a0c1727 100644
--- a/include/rosa/support/debug.hpp
+++ b/include/rosa/support/debug.hpp
@@ -1,82 +1,86 @@
/*******************************************************************************
*
* File: debug.hpp
*
* Contents: Facility for debugging
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
#ifndef ROSA_SUPPORT_DEBUG_HPP
#define ROSA_SUPPORT_DEBUG_HPP
#include "rosa/config/config.h"
#include "rosa/support/types.hpp"
+#include "rosa/support/terminal_colors.h"
#include <array>
#include <ostream>
namespace rosa {
// Returns an output stream to use for debugging.
std::ostream &dbgs(void);
// Prints an array to the ostream.
template <typename T, size_t size>
std::ostream &operator<<(std::ostream &os, const std::array<T, size> &arr) {
os << '[';
for (unsigned I = 0; I < size; ++I) {
if (I) {
os << ',';
}
os << (PRINTABLE(T)) arr[I];
}
os << ']';
return os;
}
} // End namespace rosa
#ifndef ROSA_ENABLE_ASSERTIONS
#define ASSERT(stmt) ROSA_IGNORE_UNUSED(stmt)
#elif defined(ROSA_WINDOWS)
#define ASSERT(stmt) \
if (static_cast<bool>(stmt) == false) { \
- rosa::dbgs() << __FILENAME__ << ":" << __LINE__ \
- << ": requirement failed: '" << #stmt << "'" << std::endl; \
+ rosa::dbgs() << rosa::terminal::Color::Default << __FILENAME__ << ":" \
+ << __LINE__ << ": requirement failed: '" << #stmt << "'" \
+ << std::endl; \
::abort(); \
} \
ROSA_VOID_STMT
#else // defined(ROSA_LINUX)
#include <execinfo.h>
#define ASSERT(stmt) \
if (static_cast<bool>(stmt) == false) { \
- rosa::dbgs() << __FILENAME__ << ":" << __LINE__ \
- << ": requirement failed: '" << #stmt << "'" << std::endl; \
+ rosa::dbgs() << rosa::terminal::Color::Default << __FILENAME__ << ":" \
+ << __LINE__ << ": requirement failed: '" << #stmt << "'" \
+ << std::endl; \
void *array[20]; \
auto bt_size = ::backtrace(array, 20); \
::backtrace_symbols_fd(array, bt_size, 2); \
::abort(); \
} \
ROSA_VOID_STMT
#endif // defined(ROSA_ENABLE_ASSERTIONS)
#ifndef NDEBUG
#define DEBUG(X) \
do { \
X; \
} while (false)
#define DEBUGVAR(V) \
do { \
- rosa::dbgs() << #V << " (" << __FILENAME__ << ":" << __LINE__ \
- << "): " << (V) << std::endl; \
+ rosa::dbgs() << rosa::terminal::Color::Default << #V << " (" \
+ << __FILENAME__ << ":" << __LINE__ << "): " << (V) \
+ << std::endl; \
} while (false)
#else // defined(NDEBUG)
#define DEBUG(X) ROSA_IGNORE_UNUSED(X)
#define DEBUGVAR(X) ROSA_IGNORE_UNUSED(X)
#endif // defined(NDEBUG)
#endif // ROSA_SUPPORT_DEBUG_HPP
diff --git a/include/rosa/support/log.h b/include/rosa/support/log.h
index e3bde38..7f1cce6 100644
--- a/include/rosa/support/log.h
+++ b/include/rosa/support/log.h
@@ -1,143 +1,148 @@
/*******************************************************************************
*
* 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 "rosa/config/config.h"
+#include "rosa/support/terminal_colors.h"
#include <iostream>
#include <string>
/* ****************************************************************************
* 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.
+// Type-safe definition of log levels, use this in code.
+// NOTE: Keep values in sync with the corresponding preprocessor definitions
+// below.
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
+ Error,
+ Warning,
+ Info,
+ Debug,
+ Trace,
+ // Number of log levels:
+ NumLogLevels
};
// Converts a LogLevel to its string representation.
std::string logLevelToString(const LogLevel logLevel);
+// Prints colorized tag for the given LogLevel.
+std::ostream &operator<<(std::ostream &os, const LogLevel logLevel);
+
} // End namespace rosa
+// 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
+
/* ****************************************************************************
* 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_LOG_OSTREAM << "[" << rosa::logLevelToString(level) << "] " \
- << __func__ << "@" << __FILENAME__ << ":" << __LINE__ \
- << ": " << (output) << std::endl; \
+ ROSA_LOG_OSTREAM << 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__ \
- << ": "; \
+ ROSA_LOG_OSTREAM << 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_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Warning)
#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_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Info)
#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/include/rosa/support/terminal_colors.h b/include/rosa/support/terminal_colors.h
new file mode 100644
index 0000000..fee3b4e
--- /dev/null
+++ b/include/rosa/support/terminal_colors.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ *
+ * File: terminal_colors.h
+ *
+ * Contents: Facility for printing colorized text to terminals supporting it.
+ *
+ * Copyright 2017
+ *
+ * Author: David Juhasz (david.juhasz@tuwien.ac.at)
+ *
+ ******************************************************************************/
+
+#ifndef ROSA_SUPPORT_TERMINAL_COLORS_H
+#define ROSA_SUPPORT_TERMINAL_COLORS_H
+
+#include <ostream>
+
+namespace rosa {
+namespace terminal {
+
+// Text colors for colorizable terminals.
+enum class Color {
+ Default,
+ Black,
+ Red,
+ Green,
+ Yellow,
+ Blue,
+ Magenta,
+ Cyan,
+ Lightgrey,
+ Darkgrey,
+ Lightred,
+ Lightgreen,
+ Lightyellow,
+ Lightblue,
+ LightMagenta,
+ Lightcyan,
+ White,
+ // Number of Color values:
+ NumColors
+};
+
+// Operator handling Color commands sent to output streams.
+std::ostream &operator<<(std::ostream &os, const Color color);
+
+} // End namespace terminal
+} // End namespace rosa
+
+#endif // ROSA_SUPPORT_TERMINAL_COLORS_H
+
diff --git a/lib/support/CMakeLists.txt b/lib/support/CMakeLists.txt
index 9d716be..410552a 100644
--- a/lib/support/CMakeLists.txt
+++ b/lib/support/CMakeLists.txt
@@ -1,5 +1,6 @@
add_library(ROSASupport
debug.cpp
+ terminal_colors.cpp
log.cpp
)
diff --git a/lib/support/log.cpp b/lib/support/log.cpp
index c0de18f..dcfe85c 100644
--- a/lib/support/log.cpp
+++ b/lib/support/log.cpp
@@ -1,31 +1,50 @@
/*******************************************************************************
*
* File: log.cpp
*
* Contents: Facility for logging
*
* Copyright 2017
*
* Author: David Juhasz (david.juhasz@tuwien.ac.at)
*
******************************************************************************/
+#include "rosa/support/debug.hpp"
#include "rosa/support/log.h"
+#include "rosa/support/terminal_colors.h"
+#include <array>
namespace rosa {
+// Textual representation of LogLevels.
+constexpr std::array<const char *, static_cast<size_t>(LogLevel::NumLogLevels)>
+ LogLevelStrings{{"ERROR", "WARNING", "INFO", "DEBUG", "TRACE"}};
+
+// Terminal colors associated to LogLevels.
+constexpr std::array<terminal::Color,
+ static_cast<size_t>(LogLevel::NumLogLevels)>
+ LogLevelColors{{
+ terminal::Color::Red, // LogLevel::Error
+ terminal::Color::Yellow, // LogLevel::Warning
+ terminal::Color::Green, // LogLevel::Info
+ terminal::Color::Blue, // LogLevel::Debug
+ terminal::Color::Default, // LogLevel::Trace
+ }};
+
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("Invalid LogLevel");
- }
+ ASSERT(logLevel != LogLevel::NumLogLevels);
+ return LogLevelStrings[static_cast<size_t>(logLevel)];
+}
+
+std::ostream &operator<<(std::ostream &os, const LogLevel logLevel) {
+ ASSERT(logLevel != LogLevel::NumLogLevels);
+ os << LogLevelColors[static_cast<size_t>(logLevel)] << "["
+ << logLevelToString(logLevel) << "]" << terminal::Color::Default;
+ return os;
}
std::ostream LogSink(nullptr);
} // End namespace rosa
diff --git a/lib/support/terminal_colors.cpp b/lib/support/terminal_colors.cpp
new file mode 100644
index 0000000..9a4c84f
--- /dev/null
+++ b/lib/support/terminal_colors.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ *
+ * File: terminal_colors.cpp
+ *
+ * Contents: Facility for printing colorized text to terminals supporting it.
+ *
+ * Copyright 2017
+ *
+ * Author: David Juhasz (david.juhasz@tuwien.ac.at)
+ *
+ ******************************************************************************/
+
+#include "rosa/support/terminal_colors.h"
+#include "rosa/support/debug.hpp"
+#include "rosa/config/config.h"
+#include <array>
+
+namespace rosa {
+namespace terminal {
+
+#ifdef ROSA_POSIX
+// ANSI color codes for POSIX terminals.
+// NOTE: Use std::array for runtime efficiency, though static casting is
+// necessary for indexing.
+constexpr std::array<const char *, static_cast<size_t>(Color::NumColors)>
+ ANSIColorCodes{{
+ "0", // Default - Attribute reset
+ "30", // Black
+ "31", // Red
+ "32", // Green
+ "33", // Yelow
+ "34", // Blue
+ "35", // Magenta
+ "36", // Cyan
+ "37", // Lightgrey
+ "90", // Darkgrey
+ "91", // Lightred
+ "92", // Lightgreen
+ "93", // Lightyellow
+ "94", // Lightblue
+ "95", // Lightmagenta
+ "96", // Lightcyan
+ "97" // White
+ }};
+#endif // defined ROSA_POSIX
+
+std::ostream &operator<<(std::ostream &os, const Color color) {
+ ASSERT(color != Color::NumColors);
+ // Handle color only when printing to terminal and it supports colors.
+#ifdef ROSA_POSIX
+ // FIXME: Make terminal identification more robust! What if rdbuf of a
+ // standard stream is changed in the software?
+ if (os.rdbuf() == std::cout.rdbuf() || os.rdbuf() == std::cerr.rdbuf() ||
+ os.rdbuf() == std::clog.rdbuf()) {
+ os << "\033[" << ANSIColorCodes[static_cast<size_t>(color)] << "m";
+ }
+#endif // defined ROSA_POSIX
+ return os;
+}
+
+} // End namespace terminal
+} // End namespace rosa
+

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 17, 7:30 AM (23 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
141519
Default Alt Text
(17 KB)

Event Timeline