plogr/0000755000176200001440000000000013255737547011417 5ustar liggesusersplogr/inst/0000755000176200001440000000000012771313036012355 5ustar liggesusersplogr/inst/include/0000755000176200001440000000000013255420714014000 5ustar liggesusersplogr/inst/include/plogr.h0000644000176200001440000000165413255426462015310 0ustar liggesusers#ifndef plogr_plogr_H #define plogr_plogr_H #include "plog/Log.h" #include "plog/Formatters/FuncMessageFormatter.h" #include namespace plog { template class RAppender : public IAppender { public: virtual void write(const Record& record) { util::nstring str = Formatter::format(record); // Use the formatter to get a string from a record. REprintf("%s", str.c_str()); } }; inline void init_r(Severity maxSeverity = none) { if (!_PLOGR_ENABLE) { Rf_warning("Logging not enabled, #define PLOGR_ENABLE when compiling the package"); return; } static bool initialized = false; static RAppender appender; if (!initialized) { init(maxSeverity, &appender); initialized = true; } else { init(maxSeverity); } } inline void init_r(const std::string& maxSeverity = "NONE") { init_r(getSeverityCode(maxSeverity)); } } #endif // #ifndef plogr_plogr_H plogr/inst/include/plog/0000755000176200001440000000000013255420714014741 5ustar liggesusersplogr/inst/include/plog/Formatters/0000755000176200001440000000000012771313746017077 5ustar liggesusersplogr/inst/include/plog/Formatters/FuncMessageFormatter.h0000644000176200001440000000074512771313746023342 0ustar liggesusers#pragma once #include namespace plog { class FuncMessageFormatter { public: static util::nstring header() { return util::nstring(); } static util::nstring format(const Record& record) { util::nstringstream ss; ss << record.getFunc().c_str() << "@" << record.getLine() << ": "; ss << record.getMessage().c_str() << "\n"; return ss.str(); } }; } plogr/inst/include/plog/Record.h0000644000176200001440000000345312772241625016342 0ustar liggesusers#pragma once #include #include #include namespace plog { class Record { public: Record(Severity severity, const char* func, size_t line, const void* object) : m_severity(severity), m_object(object), m_line(line), m_func(func) { util::ftime(&m_time); } ////////////////////////////////////////////////////////////////////////// // Stream output operators Record& operator<<(char data) { char str[] = { data, 0 }; *this << str; return *this; } Record& operator<<(wchar_t data) { wchar_t str[] = { data, 0 }; *this << str; return *this; } template Record& operator<<(const T& data) { m_message << data; return *this; } ////////////////////////////////////////////////////////////////////////// // Getters const util::Time& getTime() const { return m_time; } Severity getSeverity() const { return m_severity; } const void* getObject() const { return m_object; } size_t getLine() const { return m_line; } const util::nstring getMessage() const { return m_message.str(); } std::string getFunc() const { return util::processFuncName(m_func); } private: util::Time m_time; const Severity m_severity; const void* const m_object; const size_t m_line; util::nstringstream m_message; const char* const m_func; }; } plogr/inst/include/plog/Util.h0000644000176200001440000000431613255420714016033 0ustar liggesusers#pragma once #include #include #ifdef _WIN32 # include #else # include #endif #ifdef _WIN32 # define _PLOG_NSTR(x) L##x # define PLOG_NSTR(x) _PLOG_NSTR(x) #else # define PLOG_NSTR(x) x #endif namespace plog { namespace util { typedef std::string nstring; typedef std::stringstream nstringstream; typedef char nchar; inline void localtime_s(struct tm* t, const time_t* time) { #ifdef _WIN32 ::localtime_s(t, time); #else ::localtime_r(time, t); #endif } #ifdef _WIN32 typedef timeb Time; inline void ftime(Time* t) { ::ftime(t); } #else struct Time { time_t time; unsigned short millitm; }; inline void ftime(Time* t) { timeval tv; ::gettimeofday(&tv, NULL); t->time = tv.tv_sec; t->millitm = static_cast(tv.tv_usec / 1000); } #endif inline std::string processFuncName(const char* func) { #if (defined(_WIN32) && !defined(__MINGW32__)) || defined(__OBJC__) return std::string(func); #else const char* funcBegin = func; const char* funcEnd = ::strchr(funcBegin, '('); return std::string(funcBegin, funcEnd); #endif } class NonCopyable { protected: NonCopyable() { } private: NonCopyable(const NonCopyable&); NonCopyable& operator=(const NonCopyable&); }; template class Singleton : NonCopyable { public: Singleton() { assert(!m_instance); m_instance = static_cast(this); } ~Singleton() { assert(m_instance); m_instance = 0; } static T* getInstance() { return m_instance; } private: static T* m_instance; }; template T* Singleton::m_instance = NULL; } } plogr/inst/include/plog/Appenders/0000755000176200001440000000000012771313746016672 5ustar liggesusersplogr/inst/include/plog/Appenders/ConsoleAppender.h0000644000176200001440000000074712771313746022134 0ustar liggesusers#pragma once #include namespace plog { template class ConsoleAppender : public IAppender { public: ConsoleAppender() { #ifdef _WIN32 ::setlocale(LC_ALL, ""); #endif } virtual void write(const Record& record) { #ifdef _WIN32 std::wcout << Formatter::format(record) << std::flush; #else std::cout << Formatter::format(record) << std::flush; #endif } }; } plogr/inst/include/plog/Appenders/IAppender.h0000644000176200001440000000026612771313746020716 0ustar liggesusers#pragma once namespace plog { class IAppender { public: virtual ~IAppender() { } virtual void write(const Record& record) = 0; }; } plogr/inst/include/plog/Appenders/ColorConsoleAppender.h0000644000176200001440000000560612771313746023132 0ustar liggesusers#pragma once #include "ConsoleAppender.h" namespace plog { template class ColorConsoleAppender : public ConsoleAppender { public: #ifdef _WIN32 ColorConsoleAppender() : m_isatty(!!::_isatty(::_fileno(stdout))), m_stdoutHandle(), m_originalAttr() { if (m_isatty) { m_stdoutHandle = ::GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbiInfo; ::GetConsoleScreenBufferInfo(m_stdoutHandle, &csbiInfo); m_originalAttr = csbiInfo.wAttributes; } } #else ColorConsoleAppender() : m_isatty(!!::isatty(::fileno(stdout))) {} #endif virtual void write(const Record& record) { setColor(record.getSeverity()); ConsoleAppender::write(record); resetColor(); } private: void setColor(Severity severity) { if (m_isatty) { switch (severity) { #ifdef _WIN32 case fatal: ::SetConsoleTextAttribute(m_stdoutHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY | BACKGROUND_RED); // white on red background break; case error: ::SetConsoleTextAttribute(m_stdoutHandle, FOREGROUND_RED | FOREGROUND_INTENSITY | (m_originalAttr & 0xf0)); // red break; case warning: ::SetConsoleTextAttribute(m_stdoutHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | (m_originalAttr & 0xf0)); // yellow break; case debug: case verbose: ::SetConsoleTextAttribute(m_stdoutHandle, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY | (m_originalAttr & 0xf0)); // cyan break; #else case fatal: std::cout << "\x1B[97m\x1B[41m"; // white on red background break; case error: std::cout << "\x1B[91m"; // red break; case warning: std::cout << "\x1B[93m"; // yellow break; case debug: case verbose: std::cout << "\x1B[96m"; // cyan break; #endif default: break; } } } void resetColor() { if (m_isatty) { #ifdef _WIN32 ::SetConsoleTextAttribute(m_stdoutHandle, m_originalAttr); #else std::cout << "\x1B[0m\x1B[0K"; #endif } } private: bool m_isatty; #ifdef _WIN32 HANDLE m_stdoutHandle; WORD m_originalAttr; #endif }; } plogr/inst/include/plog/Logger.h0000644000176200001440000000276212771322435016343 0ustar liggesusers#pragma once #include #include #include namespace plog { template class Logger : public util::Singleton >, public IAppender { public: Logger() : m_maxSeverity(none) { } Logger& addAppender(IAppender* appender) { assert(appender != this); m_appenders.push_back(appender); return *this; } Severity getMaxSeverity() const { return m_maxSeverity; } void setMaxSeverity(Severity severity) { m_maxSeverity = severity; } bool checkSeverity(Severity severity) const { return severity <= m_maxSeverity; } virtual void write(const Record& record) { if (checkSeverity(record.getSeverity())) { *this += record; } } void operator+=(const Record& record) { for (std::vector::iterator it = m_appenders.begin(); it != m_appenders.end(); ++it) { (*it)->write(record); } } private: Severity m_maxSeverity; std::vector m_appenders; }; template inline Logger* get() { return Logger::getInstance(); } inline Logger<0>* get() { return Logger<0>::getInstance(); } } plogr/inst/include/plog/Log.h0000644000176200001440000001234113255420714015634 0ustar liggesusers////////////////////////////////////////////////////////////////////////// // Plog - portable and simple log for C++ // Documentation and sources: https://github.com/SergiusTheBest/plog // License: MPL 2.0, http://mozilla.org/MPL/2.0/ #pragma once #include #include #include ////////////////////////////////////////////////////////////////////////// // Helper macros that get context info #ifdef _MSC_BUILD # if _MSC_VER >= 1600 && !defined(__INTELLISENSE__) // >= Visual Studio 2010 and skip IntelliSense # define PLOG_GET_THIS() __if_exists(this) { this } __if_not_exists(this) { 0 } # else # define PLOG_GET_THIS() 0 # endif # define PLOG_GET_FUNC() __FUNCTION__ #else # define PLOG_GET_THIS() 0 # define PLOG_GET_FUNC() __PRETTY_FUNCTION__ #endif ////////////////////////////////////////////////////////////////////////// // Global switch #ifdef PLOGR_ENABLE #define _PLOGR_ENABLE 1 #else #define _PLOGR_ENABLE 0 #endif // PLOGR_ENABLE ////////////////////////////////////////////////////////////////////////// // Log severity level checker #define IF_LOG_(instance, severity) if (_PLOGR_ENABLE && plog::get() && plog::get()->checkSeverity(severity)) #define IF_LOG(severity) IF_LOG_(0, severity) ////////////////////////////////////////////////////////////////////////// // Main logging macros #define LOG_(instance, severity) IF_LOG_(instance, severity) (*plog::get()) += plog::Record(severity, PLOG_GET_FUNC(), __LINE__, PLOG_GET_THIS()) #define LOG(severity) LOG_(0, severity) #define LOG_VERBOSE LOG(plog::verbose) #define LOG_DEBUG LOG(plog::debug) #define LOG_INFO LOG(plog::info) #define LOG_WARNING LOG(plog::warning) #define LOG_ERROR LOG(plog::error) #define LOG_FATAL LOG(plog::fatal) #define LOG_VERBOSE_(instance) LOG_(instance, plog::verbose) #define LOG_DEBUG_(instance) LOG_(instance, plog::debug) #define LOG_INFO_(instance) LOG_(instance, plog::info) #define LOG_WARNING_(instance) LOG_(instance, plog::warning) #define LOG_ERROR_(instance) LOG_(instance, plog::error) #define LOG_FATAL_(instance) LOG_(instance, plog::fatal) #define LOGV LOG_VERBOSE #define LOGD LOG_DEBUG #define LOGI LOG_INFO #define LOGW LOG_WARNING #define LOGE LOG_ERROR #define LOGF LOG_FATAL #define LOGV_(instance) LOG_VERBOSE_(instance) #define LOGD_(instance) LOG_DEBUG_(instance) #define LOGI_(instance) LOG_INFO_(instance) #define LOGW_(instance) LOG_WARNING_(instance) #define LOGE_(instance) LOG_ERROR_(instance) #define LOGF_(instance) LOG_FATAL_(instance) ////////////////////////////////////////////////////////////////////////// // Conditional logging macros #define LOG_IF_(instance, severity, condition) if (condition) LOG_(instance, severity) #define LOG_IF(severity, condition) LOG_IF_(0, severity, condition) #define LOG_VERBOSE_IF(condition) LOG_IF(plog::verbose, condition) #define LOG_DEBUG_IF(condition) LOG_IF(plog::debug, condition) #define LOG_INFO_IF(condition) LOG_IF(plog::info, condition) #define LOG_WARNING_IF(condition) LOG_IF(plog::warning, condition) #define LOG_ERROR_IF(condition) LOG_IF(plog::error, condition) #define LOG_FATAL_IF(condition) LOG_IF(plog::fatal, condition) #define LOG_VERBOSE_IF_(instance, condition) LOG_IF_(instance, plog::verbose, condition) #define LOG_DEBUG_IF_(instance, condition) LOG_IF_(instance, plog::debug, condition) #define LOG_INFO_IF_(instance, condition) LOG_IF_(instance, plog::info, condition) #define LOG_WARNING_IF_(instance, condition) LOG_IF_(instance, plog::warning, condition) #define LOG_ERROR_IF_(instance, condition) LOG_IF_(instance, plog::error, condition) #define LOG_FATAL_IF_(instance, condition) LOG_IF_(instance, plog::fatal, condition) #define LOGV_IF(condition) LOG_VERBOSE_IF(condition) #define LOGD_IF(condition) LOG_DEBUG_IF(condition) #define LOGI_IF(condition) LOG_INFO_IF(condition) #define LOGW_IF(condition) LOG_WARNING_IF(condition) #define LOGE_IF(condition) LOG_ERROR_IF(condition) #define LOGF_IF(condition) LOG_FATAL_IF(condition) #define LOGV_IF_(instance, condition) LOG_VERBOSE_IF_(instance, condition) #define LOGD_IF_(instance, condition) LOG_DEBUG_IF_(instance, condition) #define LOGI_IF_(instance, condition) LOG_INFO_IF_(instance, condition) #define LOGW_IF_(instance, condition) LOG_WARNING_IF_(instance, condition) #define LOGE_IF_(instance, condition) LOG_ERROR_IF_(instance, condition) #define LOGF_IF_(instance, condition) LOG_FATAL_IF_(instance, condition) plogr/inst/include/plog/Severity.h0000644000176200001440000000206112771322435016726 0ustar liggesusers#pragma once namespace plog { enum Severity { none = 0, fatal = 1, error = 2, warning = 3, info = 4, debug = 5, verbose = 6 }; inline const char* getSeverityName(Severity severity) { switch (severity) { case fatal: return "FATAL"; case error: return "ERROR"; case warning: return "WARN"; case info: return "INFO"; case debug: return "DEBUG"; case verbose: return "VERB"; default: return "NONE"; } } inline Severity getSeverityCode(const std::string& name) { if (name == "FATAL") return fatal; if (name == "ERROR") return error; if (name == "WARN") return warning; if (name == "INFO") return info; if (name == "DEBUG") return debug; if (name == "VERB") return verbose; return none; } } plogr/inst/include/plog/Init.h0000644000176200001440000000123212771322435016016 0ustar liggesusers#pragma once #include #include #include namespace plog { ////////////////////////////////////////////////////////////////////////// // Empty initializer / one appender template inline Logger& init(Severity maxSeverity = none, IAppender* appender = NULL) { static Logger logger; logger.setMaxSeverity(maxSeverity); return appender ? logger.addAppender(appender) : logger; } inline Logger<0>& init(Severity maxSeverity = none, IAppender* appender = NULL) { return init<0>(maxSeverity, appender); } } plogr/NAMESPACE0000644000176200001440000000005612771311027012616 0ustar liggesusers# Generated by roxygen2: do not edit by hand plogr/NEWS.md0000644000176200001440000000111413255425224012474 0ustar liggesusers# plogr 0.2.0 (2018-03-24) - The `PLOGR_ENABLE` macro needs to be enabled at compilation time for the library to have any effect (#3) - In GCC builds, the function is now shown with its return type; stripping the return type failed for functions in template clases with more than one template argument. # plogr 0.1-1 (2016-09-24) - Using a stripped version of plog 1.0-1. - Works on Linux, OS X, and Windows. - Log items are printed using `REprintf()`. - New `plog::init_r()` to initialize logging via `REprintf()`, allows changing the log level and passing the log level as string. plogr/R/0000755000176200001440000000000012771322435011604 5ustar liggesusersplogr/R/plogr-package.R0000644000176200001440000000065612771322435014452 0ustar liggesusers#' @examples #' plogr_demo <- Rcpp::cppFunction(depends = "plogr", ' #' // C++ code begin #' #include #' #' RObject plogr_demo() { #' plog::init_r(plog::info); #' LOG_INFO << "shown"; #' LOG_DEBUG << "not shown"; #' plog::init_r("DEBUG"); #' LOG_DEBUG << "shown now"; #' return R_NilValue; #' } #' #' #include // not necessary to use plogr #' // C++ code end #' ' #' ) #' #' plogr_demo() "_PACKAGE" plogr/README.md0000644000176200001440000000643313255420714012665 0ustar liggesusers plogr [![Travis-CI Build Status](https://travis-ci.org/krlmlr/plogr.svg?branch=master)](https://travis-ci.org/krlmlr/plogr) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/krlmlr/plogr?branch=master&svg=true)](https://ci.appveyor.com/project/krlmlr/plogr) ============================================================================================================================================================================================================================================================================================ Provides the header files for a stripped-down version of the [plog](https://github.com/SergiusTheBest/plog) header-only C++ logging library, and a method to log to R's standard error stream. Installation ------------ You can install `plogr` from GitHub with: ``` r # install.packages("devtools") devtools::install_github("krlmlr/plogr") ``` Usage ----- Add `LinkingTo: plogr` to your `DESCRIPTION`, and add `#include ` to all modules where you want to access the logging. If your package has a universal header file which you include from all modules, it's probably a good idea to insert the `#include` directive there, so that all of your code has access to logging. The following system header files will be included: - `sstream` - `iostream` - `vector` - `cassert` - `cstring` - `time.h` (on Linux/OS X) - `sys/time.h` (on Windows) - `R.h` Example ------- The code shows a small usage example and a demo which we'll call from R below. (`Rcpp` is *not* necessary to use `plogr`, it is only needed to run the C++ code chunk.) The `init_r()` function is the only new function added by the R package, and initializes a logger that logs to R's standard error stream. For further details consult the [plog documentation](https://github.com/SergiusTheBest/plog#readme); for compatibility reasons you won't find the file appenders in this package. ``` cpp // If we omit this, logging is disabled altogether. // In a package, you would probably add -DPLOGR_ENABLE to PKG_CPPFLAGS. #define PLOGR_ENABLE // [[Rcpp::depends(plogr)]] #include // [[Rcpp::export]] void plogr_demo() { LOG_INFO << "test 1"; plog::init_r(plog::info); LOG_INFO << "test 2"; LOG_DEBUG << "test 3"; plog::init_r("DEBUG"); // You can also pass a string LOG_INFO << "test 4"; LOG_DEBUG << "test 5"; } #include // not necessary to use plogr ``` The R code below calls the `plogr_demo()` C++ function defined above. Currently, the messages are printed straight to the standard error stream, so the message capturing mechanisms employed by `knitr` don't work. We use a sink with a text connection to capture the messages, and print the contents of the variable to which the text connection assigns. ``` r output <- character() con <- textConnection("output", "a") withr::with_message_sink(con, plogr_demo()) close(con) cat(output, sep = "\n") #> void plogr_demo@12: test 2 #> void plogr_demo@15: test 4 #> void plogr_demo@16: test 5 ``` Nothing is printed before we actually initialize the logger. Because it is initialized to the `info` level, the debug log message is not shown, and only "test 2" comes through. After changing the log level, the debug message is also shown. plogr/MD50000644000176200001440000000205213255737547011726 0ustar liggesusersd89446b1de7333c3f8a6ee7eb1b54ac3 *DESCRIPTION 79a530ad02c67c61317228e9b1ffadfc *LICENSE dc21c19f0d6968ee25d441b2cf46017d *NAMESPACE 7386ca54661ad9cc415bdf292967c784 *NEWS.md cbd1a36ca99d14682d9240d6c0f7cf2e *R/plogr-package.R 0710e4bfd233913547cc43cf390a409d *README.md 93068ec6c9320f5672c2a7dd0944830f *inst/include/plog/Appenders/ColorConsoleAppender.h 212f37e372f00972a3c4b16f295789c0 *inst/include/plog/Appenders/ConsoleAppender.h ffc24c1e15a5bd226534ebf74f8e6445 *inst/include/plog/Appenders/IAppender.h bb505ee61650e93389cecf4508fb0b7d *inst/include/plog/Formatters/FuncMessageFormatter.h 7e5c2d6e546594d0b03bc5e2cb45da0e *inst/include/plog/Init.h 7da1798654a8b9259b15e04de2753466 *inst/include/plog/Log.h 85ffbe6c9063ccdd24b540230e36ec24 *inst/include/plog/Logger.h 119bb25733f63c1da2b26933ea8032d4 *inst/include/plog/Record.h aa8f12ddb28fe989c9310cef9c73fb03 *inst/include/plog/Severity.h a6f0c5e3c5ae2def02facc46f1fbc334 *inst/include/plog/Util.h 7275f6b09b0fde68a786e2751215a7a7 *inst/include/plogr.h 3a789c9231d02e399aba9a2dca85e660 *man/plogr-package.Rd plogr/DESCRIPTION0000644000176200001440000000160613255737547013130 0ustar liggesusersPackage: plogr Title: The 'plog' C++ Logging Library Version: 0.2.0 Date: 2018-03-24 Authors@R: c( person("Kirill", "Müller", role = c("aut", "cre"), email = "krlmlr+r@mailbox.org"), person("Sergey", "Podobry", role = "cph", comment = "Author of the bundled plog library")) Description: A simple header-only logging library for C++. Add 'LinkingTo: plogr' to 'DESCRIPTION', and '#include ' in your C++ modules to use it. Suggests: Rcpp License: MIT + file LICENSE Encoding: UTF-8 LazyData: true URL: https://github.com/krlmlr/plogr#readme BugReports: https://github.com/krlmlr/plogr/issues RoxygenNote: 6.0.1.9000 NeedsCompilation: no Packaged: 2018-03-24 11:02:06 UTC; muelleki Author: Kirill Müller [aut, cre], Sergey Podobry [cph] (Author of the bundled plog library) Maintainer: Kirill Müller Repository: CRAN Date/Publication: 2018-03-25 15:25:27 UTC plogr/man/0000755000176200001440000000000013255420714012153 5ustar liggesusersplogr/man/plogr-package.Rd0000644000176200001440000000210013255420714015147 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/plogr-package.R \docType{package} \name{plogr-package} \alias{plogr} \alias{plogr-package} \title{plogr: The 'plog' C++ Logging Library} \description{ A simple header-only logging library for C++. Add 'LinkingTo: plogr' to 'DESCRIPTION', and '#include ' in your C++ modules to use it. } \examples{ plogr_demo <- Rcpp::cppFunction(depends = "plogr", ' // C++ code begin #include RObject plogr_demo() { plog::init_r(plog::info); LOG_INFO << "shown"; LOG_DEBUG << "not shown"; plog::init_r("DEBUG"); LOG_DEBUG << "shown now"; return R_NilValue; } #include // not necessary to use plogr // C++ code end ' ) plogr_demo() } \seealso{ Useful links: \itemize{ \item \url{https://github.com/krlmlr/plogr#readme} \item Report bugs at \url{https://github.com/krlmlr/plogr/issues} } } \author{ \strong{Maintainer}: Kirill Müller \email{krlmlr+r@mailbox.org} Other contributors: \itemize{ \item Sergey Podobry (Author of the bundled plog library) [copyright holder] } } plogr/LICENSE0000644000176200001440000000007412771465222012413 0ustar liggesusersYEAR: 2016 COPYRIGHT HOLDER: Kirill Müller, Sergey Podobry