You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2017/05/31 15:10:23 UTC
[03/10] nifi-minifi-cpp git commit: MINIFI-296 - Configurable logging,
spdlog 0.13.0
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/details/null_mutex.h
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/details/null_mutex.h b/thirdparty/spdlog-0.13.0/include/spdlog/details/null_mutex.h
new file mode 100644
index 0000000..67b0aee
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/details/null_mutex.h
@@ -0,0 +1,45 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+
+#pragma once
+
+#include <atomic>
+// null, no cost dummy "mutex" and dummy "atomic" int
+
+namespace spdlog
+{
+namespace details
+{
+struct null_mutex
+{
+ void lock() {}
+ void unlock() {}
+ bool try_lock()
+ {
+ return true;
+ }
+};
+
+struct null_atomic_int
+{
+ int value;
+ null_atomic_int() = default;
+
+ null_atomic_int(int val):value(val)
+ {}
+
+ int load(std::memory_order) const
+ {
+ return value;
+ }
+
+ void store(int val)
+ {
+ value = val;
+ }
+};
+
+}
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/details/os.h
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/details/os.h b/thirdparty/spdlog-0.13.0/include/spdlog/details/os.h
new file mode 100644
index 0000000..b63ce66
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/details/os.h
@@ -0,0 +1,406 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+#pragma once
+
+#include <spdlog/common.h>
+
+#include <cstdio>
+#include <ctime>
+#include <functional>
+#include <string>
+#include <chrono>
+#include <thread>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#ifdef _WIN32
+
+#ifndef NOMINMAX
+#define NOMINMAX //prevent windows redefining min/max
+#endif
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#include <process.h> // _get_pid support
+#include <io.h> // _get_osfhandle support
+
+#ifdef __MINGW32__
+#include <share.h>
+#endif
+
+#else // unix
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#ifdef __linux__
+#include <sys/syscall.h> //Use gettid() syscall under linux to get thread id
+
+#elif __FreeBSD__
+#include <sys/thr.h> //Use thr_self() syscall under FreeBSD to get thread id
+#endif
+
+#endif //unix
+
+#ifndef __has_feature // Clang - feature checking macros.
+#define __has_feature(x) 0 // Compatibility with non-clang compilers.
+#endif
+
+
+namespace spdlog
+{
+namespace details
+{
+namespace os
+{
+
+inline spdlog::log_clock::time_point now()
+{
+
+#if defined __linux__ && defined SPDLOG_CLOCK_COARSE
+ timespec ts;
+ ::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
+ return std::chrono::time_point<log_clock, typename log_clock::duration>(
+ std::chrono::duration_cast<typename log_clock::duration>(
+ std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
+
+
+#else
+ return log_clock::now();
+#endif
+
+}
+inline std::tm localtime(const std::time_t &time_tt)
+{
+
+#ifdef _WIN32
+ std::tm tm;
+ localtime_s(&tm, &time_tt);
+#else
+ std::tm tm;
+ localtime_r(&time_tt, &tm);
+#endif
+ return tm;
+}
+
+inline std::tm localtime()
+{
+ std::time_t now_t = time(nullptr);
+ return localtime(now_t);
+}
+
+
+inline std::tm gmtime(const std::time_t &time_tt)
+{
+
+#ifdef _WIN32
+ std::tm tm;
+ gmtime_s(&tm, &time_tt);
+#else
+ std::tm tm;
+ gmtime_r(&time_tt, &tm);
+#endif
+ return tm;
+}
+
+inline std::tm gmtime()
+{
+ std::time_t now_t = time(nullptr);
+ return gmtime(now_t);
+}
+inline bool operator==(const std::tm& tm1, const std::tm& tm2)
+{
+ return (tm1.tm_sec == tm2.tm_sec &&
+ tm1.tm_min == tm2.tm_min &&
+ tm1.tm_hour == tm2.tm_hour &&
+ tm1.tm_mday == tm2.tm_mday &&
+ tm1.tm_mon == tm2.tm_mon &&
+ tm1.tm_year == tm2.tm_year &&
+ tm1.tm_isdst == tm2.tm_isdst);
+}
+
+inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
+{
+ return !(tm1 == tm2);
+}
+
+// eol definition
+#if !defined (SPDLOG_EOL)
+#ifdef _WIN32
+#define SPDLOG_EOL "\r\n"
+#else
+#define SPDLOG_EOL "\n"
+#endif
+#endif
+
+SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL;
+SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1;
+
+inline void prevent_child_fd(FILE *f)
+{
+#ifdef _WIN32
+ auto file_handle = (HANDLE)_get_osfhandle(_fileno(f));
+ if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
+ throw spdlog_ex("SetHandleInformation failed", errno);
+#else
+ auto fd = fileno(f);
+ if(fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ throw spdlog_ex("fcntl with FD_CLOEXEC failed", errno);
+#endif
+}
+
+
+//fopen_s on non windows for writing
+inline int fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode)
+{
+#ifdef _WIN32
+#ifdef SPDLOG_WCHAR_FILENAMES
+ *fp = _wfsopen((filename.c_str()), mode.c_str(), _SH_DENYWR);
+#else
+ *fp = _fsopen((filename.c_str()), mode.c_str(), _SH_DENYWR);
+#endif
+#else //unix
+ *fp = fopen((filename.c_str()), mode.c_str());
+#endif
+
+#ifdef SPDLOG_PREVENT_CHILD_FD
+ if(*fp != nullptr)
+ prevent_child_fd(*fp);
+#endif
+ return *fp == nullptr;
+}
+
+
+inline int remove(const filename_t &filename)
+{
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+ return _wremove(filename.c_str());
+#else
+ return std::remove(filename.c_str());
+#endif
+}
+
+inline int rename(const filename_t& filename1, const filename_t& filename2)
+{
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+ return _wrename(filename1.c_str(), filename2.c_str());
+#else
+ return std::rename(filename1.c_str(), filename2.c_str());
+#endif
+}
+
+
+//Return if file exists
+inline bool file_exists(const filename_t& filename)
+{
+#ifdef _WIN32
+#ifdef SPDLOG_WCHAR_FILENAMES
+ auto attribs = GetFileAttributesW(filename.c_str());
+#else
+ auto attribs = GetFileAttributesA(filename.c_str());
+#endif
+ return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY));
+#else //common linux/unix all have the stat system call
+ struct stat buffer;
+ return (stat (filename.c_str(), &buffer) == 0);
+#endif
+}
+
+
+
+
+//Return file size according to open FILE* object
+inline size_t filesize(FILE *f)
+{
+ if (f == nullptr)
+ throw spdlog_ex("Failed getting file size. fd is null");
+#ifdef _WIN32
+ int fd = _fileno(f);
+#if _WIN64 //64 bits
+ struct _stat64 st;
+ if (_fstat64(fd, &st) == 0)
+ return st.st_size;
+
+#else //windows 32 bits
+ long ret = _filelength(fd);
+ if (ret >= 0)
+ return static_cast<size_t>(ret);
+#endif
+
+#else // unix
+ int fd = fileno(f);
+ //64 bits(but not in osx, where fstat64 is deprecated)
+#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__))
+ struct stat64 st;
+ if (fstat64(fd, &st) == 0)
+ return static_cast<size_t>(st.st_size);
+#else // unix 32 bits or osx
+ struct stat st;
+ if (fstat(fd, &st) == 0)
+ return static_cast<size_t>(st.st_size);
+#endif
+#endif
+ throw spdlog_ex("Failed getting file size from fd", errno);
+}
+
+
+
+
+//Return utc offset in minutes or throw spdlog_ex on failure
+inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
+{
+
+#ifdef _WIN32
+#if _WIN32_WINNT < _WIN32_WINNT_WS08
+ TIME_ZONE_INFORMATION tzinfo;
+ auto rv = GetTimeZoneInformation(&tzinfo);
+#else
+ DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
+ auto rv = GetDynamicTimeZoneInformation(&tzinfo);
+#endif
+ if (rv == TIME_ZONE_ID_INVALID)
+ throw spdlog::spdlog_ex("Failed getting timezone info. ", errno);
+
+ int offset = -tzinfo.Bias;
+ if (tm.tm_isdst)
+ offset -= tzinfo.DaylightBias;
+ else
+ offset -= tzinfo.StandardBias;
+ return offset;
+#else
+
+#if defined(sun) || defined(__sun)
+ // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
+ struct helper
+ {
+ static long int calculate_gmt_offset(const std::tm & localtm = details::os::localtime(), const std::tm & gmtm = details::os::gmtime())
+ {
+ int local_year = localtm.tm_year + (1900 - 1);
+ int gmt_year = gmtm.tm_year + (1900 - 1);
+
+ long int days = (
+ // difference in day of year
+ localtm.tm_yday - gmtm.tm_yday
+
+ // + intervening leap days
+ + ((local_year >> 2) - (gmt_year >> 2))
+ - (local_year / 100 - gmt_year / 100)
+ + ((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
+
+ // + difference in years * 365 */
+ + (long int)(local_year - gmt_year) * 365
+ );
+
+ long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour);
+ long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
+ long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec);
+
+ return secs;
+ }
+ };
+
+ long int offset_seconds = helper::calculate_gmt_offset(tm);
+#else
+ long int offset_seconds = tm.tm_gmtoff;
+#endif
+
+ return static_cast<int>(offset_seconds / 60);
+#endif
+}
+
+//Return current thread id as size_t
+//It exists because the std::this_thread::get_id() is much slower(espcially under VS 2013)
+inline size_t _thread_id()
+{
+#ifdef _WIN32
+ return static_cast<size_t>(::GetCurrentThreadId());
+#elif __linux__
+# if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
+# define SYS_gettid __NR_gettid
+# endif
+ return static_cast<size_t>(syscall(SYS_gettid));
+#elif __FreeBSD__
+ long tid;
+ thr_self(&tid);
+ return static_cast<size_t>(tid);
+#else //Default to standard C++11 (OSX and other Unix)
+ return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id()));
+#endif
+}
+
+//Return current thread id as size_t (from thread local storage)
+inline size_t thread_id()
+{
+#if defined(_MSC_VER) && (_MSC_VER < 1900) || defined(__clang__) && !__has_feature(cxx_thread_local)
+ return _thread_id();
+#else
+ static thread_local const size_t tid = _thread_id();
+ return tid;
+#endif
+}
+
+
+
+
+// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+#define SPDLOG_FILENAME_T(s) L ## s
+inline std::string filename_to_str(const filename_t& filename)
+{
+ std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> c;
+ return c.to_bytes(filename);
+}
+#else
+#define SPDLOG_FILENAME_T(s) s
+inline std::string filename_to_str(const filename_t& filename)
+{
+ return filename;
+}
+#endif
+
+
+// Return errno string (thread safe)
+inline std::string errno_str(int err_num)
+{
+ char buf[256];
+ SPDLOG_CONSTEXPR auto buf_size = sizeof(buf);
+
+#ifdef _WIN32
+ if(strerror_s(buf, buf_size, err_num) == 0)
+ return std::string(buf);
+ else
+ return "Unkown error";
+
+#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(ANDROID) || defined(__SUNPRO_CC) || \
+ ((_POSIX_C_SOURCE >= 200112L) && ! defined(_GNU_SOURCE)) // posix version
+
+ if (strerror_r(err_num, buf, buf_size) == 0)
+ return std::string(buf);
+ else
+ return "Unkown error";
+
+#else // gnu version (might not use the given buf, so its retval pointer must be used)
+ return std::string(strerror_r(err_num, buf, buf_size));
+#endif
+}
+
+inline int pid()
+{
+
+#ifdef _WIN32
+ return ::_getpid();
+#else
+ return static_cast<int>(::getpid());
+#endif
+
+}
+
+} //os
+} //details
+} //spdlog
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/details/pattern_formatter_impl.h
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/details/pattern_formatter_impl.h b/thirdparty/spdlog-0.13.0/include/spdlog/details/pattern_formatter_impl.h
new file mode 100644
index 0000000..70b9dc8
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/details/pattern_formatter_impl.h
@@ -0,0 +1,670 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+
+#pragma once
+
+#include <spdlog/formatter.h>
+#include <spdlog/details/log_msg.h>
+#include <spdlog/details/os.h>
+#include <spdlog/fmt/fmt.h>
+
+#include <chrono>
+#include <ctime>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+#include <utility>
+#include <vector>
+#include <array>
+
+namespace spdlog
+{
+namespace details
+{
+class flag_formatter
+{
+public:
+ virtual ~flag_formatter()
+ {}
+ virtual void format(details::log_msg& msg, const std::tm& tm_time) = 0;
+};
+
+///////////////////////////////////////////////////////////////////////
+// name & level pattern appenders
+///////////////////////////////////////////////////////////////////////
+namespace
+{
+class name_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << *msg.logger_name;
+ }
+};
+}
+
+// log level appender
+class level_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << level::to_str(msg.level);
+ }
+};
+
+// short log level appender
+class short_level_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << level::to_short_str(msg.level);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////
+// Date time pattern appenders
+///////////////////////////////////////////////////////////////////////
+
+static const char* ampm(const tm& t)
+{
+ return t.tm_hour >= 12 ? "PM" : "AM";
+}
+
+static int to12h(const tm& t)
+{
+ return t.tm_hour > 12 ? t.tm_hour - 12 : t.tm_hour;
+}
+
+//Abbreviated weekday name
+using days_array = std::array<std::string, 7>;
+static const days_array& days()
+{
+ static const days_array arr{ { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } };
+ return arr;
+}
+class a_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << days()[tm_time.tm_wday];
+ }
+};
+
+//Full weekday name
+static const days_array& full_days()
+{
+ static const days_array arr{ { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } };
+ return arr;
+}
+class A_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << full_days()[tm_time.tm_wday];
+ }
+};
+
+//Abbreviated month
+using months_array = std::array<std::string, 12>;
+static const months_array& months()
+{
+ static const months_array arr{ { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec" } };
+ return arr;
+}
+class b_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << months()[tm_time.tm_mon];
+ }
+};
+
+//Full month name
+static const months_array& full_months()
+{
+ static const months_array arr{ { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" } };
+ return arr;
+}
+class B_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << full_months()[tm_time.tm_mon];
+ }
+};
+
+
+//write 2 ints seperated by sep with padding of 2
+static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, char sep)
+{
+ w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0');
+ return w;
+}
+
+//write 3 ints seperated by sep with padding of 2
+static fmt::MemoryWriter& pad_n_join(fmt::MemoryWriter& w, int v1, int v2, int v3, char sep)
+{
+ w << fmt::pad(v1, 2, '0') << sep << fmt::pad(v2, 2, '0') << sep << fmt::pad(v3, 2, '0');
+ return w;
+}
+
+
+//Date and time representation (Thu Aug 23 15:35:46 2014)
+class c_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << days()[tm_time.tm_wday] << ' ' << months()[tm_time.tm_mon] << ' ' << tm_time.tm_mday << ' ';
+ pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << tm_time.tm_year + 1900;
+ }
+};
+
+
+// year - 2 digit
+class C_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_year % 100, 2, '0');
+ }
+};
+
+
+
+// Short MM/DD/YY date, equivalent to %m/%d/%y 08/23/01
+class D_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ pad_n_join(msg.formatted, tm_time.tm_mon + 1, tm_time.tm_mday, tm_time.tm_year % 100, '/');
+ }
+};
+
+
+// year - 4 digit
+class Y_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << tm_time.tm_year + 1900;
+ }
+};
+
+// month 1-12
+class m_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_mon + 1, 2, '0');
+ }
+};
+
+// day of month 1-31
+class d_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_mday, 2, '0');
+ }
+};
+
+// hours in 24 format 0-23
+class H_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_hour, 2, '0');
+ }
+};
+
+// hours in 12 format 1-12
+class I_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(to12h(tm_time), 2, '0');
+ }
+};
+
+// minutes 0-59
+class M_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_min, 2, '0');
+ }
+};
+
+// seconds 0-59
+class S_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << fmt::pad(tm_time.tm_sec, 2, '0');
+ }
+};
+
+// milliseconds
+class e_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ auto duration = msg.time.time_since_epoch();
+ auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000;
+ msg.formatted << fmt::pad(static_cast<int>(millis), 3, '0');
+ }
+};
+
+// microseconds
+class f_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ auto duration = msg.time.time_since_epoch();
+ auto micros = std::chrono::duration_cast<std::chrono::microseconds>(duration).count() % 1000000;
+ msg.formatted << fmt::pad(static_cast<int>(micros), 6, '0');
+ }
+};
+
+// nanoseconds
+class F_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ auto duration = msg.time.time_since_epoch();
+ auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % 1000000000;
+ msg.formatted << fmt::pad(static_cast<int>(ns), 9, '0');
+ }
+};
+
+// AM/PM
+class p_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ msg.formatted << ampm(tm_time);
+ }
+};
+
+
+// 12 hour clock 02:55:02 pm
+class r_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ pad_n_join(msg.formatted, to12h(tm_time), tm_time.tm_min, tm_time.tm_sec, ':') << ' ' << ampm(tm_time);
+ }
+};
+
+// 24-hour HH:MM time, equivalent to %H:%M
+class R_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, ':');
+ }
+};
+
+// ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S
+class T_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+ pad_n_join(msg.formatted, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec, ':');
+ }
+};
+
+
+// ISO 8601 offset from UTC in timezone (+-HH:MM)
+class z_formatter:public flag_formatter
+{
+public:
+ const std::chrono::seconds cache_refresh = std::chrono::seconds(5);
+
+ z_formatter():_last_update(std::chrono::seconds(0))
+ {}
+ z_formatter(const z_formatter&) = delete;
+ z_formatter& operator=(const z_formatter&) = delete;
+
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+#ifdef _WIN32
+ int total_minutes = get_cached_offset(msg, tm_time);
+#else
+ // No need to chache under gcc,
+ // it is very fast (already stored in tm.tm_gmtoff)
+ int total_minutes = os::utc_minutes_offset(tm_time);
+#endif
+ bool is_negative = total_minutes < 0;
+ char sign;
+ if (is_negative)
+ {
+ total_minutes = -total_minutes;
+ sign = '-';
+ }
+ else
+ {
+ sign = '+';
+ }
+
+ int h = total_minutes / 60;
+ int m = total_minutes % 60;
+ msg.formatted << sign;
+ pad_n_join(msg.formatted, h, m, ':');
+ }
+private:
+ log_clock::time_point _last_update;
+ int _offset_minutes;
+ std::mutex _mutex;
+
+ int get_cached_offset(const log_msg& msg, const std::tm& tm_time)
+ {
+ using namespace std::chrono;
+ std::lock_guard<std::mutex> l(_mutex);
+ if (msg.time - _last_update >= cache_refresh)
+ {
+ _offset_minutes = os::utc_minutes_offset(tm_time);
+ _last_update = msg.time;
+ }
+ return _offset_minutes;
+ }
+};
+
+
+
+// Thread id
+class t_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << msg.thread_id;
+ }
+};
+
+// Current pid
+class pid_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << details::os::pid();
+ }
+};
+
+
+class v_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size());
+ }
+};
+
+class ch_formatter:public flag_formatter
+{
+public:
+ explicit ch_formatter(char ch): _ch(ch)
+ {}
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << _ch;
+ }
+private:
+ char _ch;
+};
+
+
+//aggregate user chars to display as is
+class aggregate_formatter:public flag_formatter
+{
+public:
+ aggregate_formatter()
+ {}
+ void add_ch(char ch)
+ {
+ _str += ch;
+ }
+ void format(details::log_msg& msg, const std::tm&) override
+ {
+ msg.formatted << _str;
+ }
+private:
+ std::string _str;
+};
+
+// Full info formatter
+// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v
+class full_formatter:public flag_formatter
+{
+ void format(details::log_msg& msg, const std::tm& tm_time) override
+ {
+#ifndef SPDLOG_NO_DATETIME
+ auto duration = msg.time.time_since_epoch();
+ auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000;
+
+ /* Slower version(while still very fast - about 3.2 million lines/sec under 10 threads),
+ msg.formatted.write("[{:d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}.{:03d}] [{}] [{}] {} ",
+ tm_time.tm_year + 1900,
+ tm_time.tm_mon + 1,
+ tm_time.tm_mday,
+ tm_time.tm_hour,
+ tm_time.tm_min,
+ tm_time.tm_sec,
+ static_cast<int>(millis),
+ msg.logger_name,
+ level::to_str(msg.level),
+ msg.raw.str());*/
+
+
+ // Faster (albeit uglier) way to format the line (5.6 million lines/sec under 10 threads)
+ msg.formatted << '[' << static_cast<unsigned int>(tm_time.tm_year + 1900) << '-'
+ << fmt::pad(static_cast<unsigned int>(tm_time.tm_mon + 1), 2, '0') << '-'
+ << fmt::pad(static_cast<unsigned int>(tm_time.tm_mday), 2, '0') << ' '
+ << fmt::pad(static_cast<unsigned int>(tm_time.tm_hour), 2, '0') << ':'
+ << fmt::pad(static_cast<unsigned int>(tm_time.tm_min), 2, '0') << ':'
+ << fmt::pad(static_cast<unsigned int>(tm_time.tm_sec), 2, '0') << '.'
+ << fmt::pad(static_cast<unsigned int>(millis), 3, '0') << "] ";
+
+ //no datetime needed
+#else
+ (void)tm_time;
+#endif
+
+#ifndef SPDLOG_NO_NAME
+ msg.formatted << '[' << *msg.logger_name << "] ";
+#endif
+
+ msg.formatted << '[' << level::to_str(msg.level) << "] ";
+ msg.formatted << fmt::StringRef(msg.raw.data(), msg.raw.size());
+ }
+};
+
+
+
+}
+}
+///////////////////////////////////////////////////////////////////////////////
+// pattern_formatter inline impl
+///////////////////////////////////////////////////////////////////////////////
+inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern)
+{
+ compile_pattern(pattern);
+}
+
+inline void spdlog::pattern_formatter::compile_pattern(const std::string& pattern)
+{
+ auto end = pattern.end();
+ std::unique_ptr<details::aggregate_formatter> user_chars;
+ for (auto it = pattern.begin(); it != end; ++it)
+ {
+ if (*it == '%')
+ {
+ if (user_chars) //append user chars found so far
+ _formatters.push_back(std::move(user_chars));
+
+ if (++it != end)
+ handle_flag(*it);
+ else
+ break;
+ }
+ else // chars not following the % sign should be displayed as is
+ {
+ if (!user_chars)
+ user_chars = std::unique_ptr<details::aggregate_formatter>(new details::aggregate_formatter());
+ user_chars->add_ch(*it);
+ }
+ }
+ if (user_chars) //append raw chars found so far
+ {
+ _formatters.push_back(std::move(user_chars));
+ }
+
+}
+inline void spdlog::pattern_formatter::handle_flag(char flag)
+{
+ switch (flag)
+ {
+ // logger name
+ case 'n':
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::name_formatter()));
+ break;
+
+ case 'l':
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::level_formatter()));
+ break;
+
+ case 'L':
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::short_level_formatter()));
+ break;
+
+ case('t'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::t_formatter()));
+ break;
+
+ case('v'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::v_formatter()));
+ break;
+
+ case('a'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::a_formatter()));
+ break;
+
+ case('A'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::A_formatter()));
+ break;
+
+ case('b'):
+ case('h'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::b_formatter()));
+ break;
+
+ case('B'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::B_formatter()));
+ break;
+ case('c'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::c_formatter()));
+ break;
+
+ case('C'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::C_formatter()));
+ break;
+
+ case('Y'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::Y_formatter()));
+ break;
+
+ case('D'):
+ case('x'):
+
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::D_formatter()));
+ break;
+
+ case('m'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::m_formatter()));
+ break;
+
+ case('d'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::d_formatter()));
+ break;
+
+ case('H'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::H_formatter()));
+ break;
+
+ case('I'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::I_formatter()));
+ break;
+
+ case('M'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::M_formatter()));
+ break;
+
+ case('S'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::S_formatter()));
+ break;
+
+ case('e'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::e_formatter()));
+ break;
+
+ case('f'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::f_formatter()));
+ break;
+ case('F'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::F_formatter()));
+ break;
+
+ case('p'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::p_formatter()));
+ break;
+
+ case('r'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::r_formatter()));
+ break;
+
+ case('R'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::R_formatter()));
+ break;
+
+ case('T'):
+ case('X'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::T_formatter()));
+ break;
+
+ case('z'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::z_formatter()));
+ break;
+
+ case ('+'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::full_formatter()));
+ break;
+
+ case ('P'):
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::pid_formatter()));
+ break;
+
+ default: //Unkown flag appears as is
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter('%')));
+ _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter(flag)));
+ break;
+ }
+}
+
+
+inline void spdlog::pattern_formatter::format(details::log_msg& msg)
+{
+
+#ifndef SPDLOG_NO_DATETIME
+ auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time));
+#else
+ std::tm tm_time;
+#endif
+ for (auto &f : _formatters)
+ {
+ f->format(msg, tm_time);
+ }
+ //write eol
+ msg.formatted.write(details::os::eol, details::os::eol_size);
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/details/registry.h
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/details/registry.h b/thirdparty/spdlog-0.13.0/include/spdlog/details/registry.h
new file mode 100644
index 0000000..ee14adf
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/details/registry.h
@@ -0,0 +1,185 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+
+#pragma once
+
+// Loggers registy of unique name->logger pointer
+// An attempt to create a logger with an already existing name will be ignored
+// If user requests a non existing logger, nullptr will be returned
+// This class is thread safe
+
+#include <spdlog/details/null_mutex.h>
+#include <spdlog/logger.h>
+#include <spdlog/async_logger.h>
+#include <spdlog/common.h>
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+namespace spdlog
+{
+namespace details
+{
+template <class Mutex> class registry_t
+{
+public:
+
+ void register_logger(std::shared_ptr<logger> logger)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ auto logger_name = logger->name();
+ throw_if_exists(logger_name);
+ _loggers[logger_name] = logger;
+ }
+
+
+ std::shared_ptr<logger> get(const std::string& logger_name)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ auto found = _loggers.find(logger_name);
+ return found == _loggers.end() ? nullptr : found->second;
+ }
+
+ template<class It>
+ std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ throw_if_exists(logger_name);
+ std::shared_ptr<logger> new_logger;
+ if (_async_mode)
+ new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy, _worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb);
+ else
+ new_logger = std::make_shared<logger>(logger_name, sinks_begin, sinks_end);
+
+ if (_formatter)
+ new_logger->set_formatter(_formatter);
+
+ if (_err_handler)
+ new_logger->set_error_handler(_err_handler);
+
+ new_logger->set_level(_level);
+
+
+ //Add to registry
+ _loggers[logger_name] = new_logger;
+ return new_logger;
+ }
+
+ void apply_all(std::function<void(std::shared_ptr<logger>)> fun)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ for (auto &l : _loggers)
+ fun(l.second);
+ }
+
+ void drop(const std::string& logger_name)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _loggers.erase(logger_name);
+ }
+
+ void drop_all()
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _loggers.clear();
+ }
+ std::shared_ptr<logger> create(const std::string& logger_name, sinks_init_list sinks)
+ {
+ return create(logger_name, sinks.begin(), sinks.end());
+ }
+
+ std::shared_ptr<logger> create(const std::string& logger_name, sink_ptr sink)
+ {
+ return create(logger_name, { sink });
+ }
+
+
+ void formatter(formatter_ptr f)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _formatter = f;
+ for (auto& l : _loggers)
+ l.second->set_formatter(_formatter);
+ }
+
+ void set_pattern(const std::string& pattern)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _formatter = std::make_shared<pattern_formatter>(pattern);
+ for (auto& l : _loggers)
+ l.second->set_formatter(_formatter);
+ }
+
+ void set_level(level::level_enum log_level)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ for (auto& l : _loggers)
+ l.second->set_level(log_level);
+ _level = log_level;
+ }
+
+ void set_error_handler(log_err_handler handler)
+ {
+ for (auto& l : _loggers)
+ l.second->set_error_handler(handler);
+ _err_handler = handler;
+ }
+
+ void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _async_mode = true;
+ _async_q_size = q_size;
+ _overflow_policy = overflow_policy;
+ _worker_warmup_cb = worker_warmup_cb;
+ _flush_interval_ms = flush_interval_ms;
+ _worker_teardown_cb = worker_teardown_cb;
+ }
+
+ void set_sync_mode()
+ {
+ std::lock_guard<Mutex> lock(_mutex);
+ _async_mode = false;
+ }
+
+ static registry_t<Mutex>& instance()
+ {
+ static registry_t<Mutex> s_instance;
+ return s_instance;
+ }
+
+private:
+ registry_t<Mutex>() {}
+ registry_t<Mutex>(const registry_t<Mutex>&) = delete;
+ registry_t<Mutex>& operator=(const registry_t<Mutex>&) = delete;
+
+ void throw_if_exists(const std::string &logger_name)
+ {
+ if (_loggers.find(logger_name) != _loggers.end())
+ throw spdlog_ex("logger with name '" + logger_name + "' already exists");
+ }
+ Mutex _mutex;
+ std::unordered_map <std::string, std::shared_ptr<logger>> _loggers;
+ formatter_ptr _formatter;
+ level::level_enum _level = level::info;
+ log_err_handler _err_handler;
+ bool _async_mode = false;
+ size_t _async_q_size = 0;
+ async_overflow_policy _overflow_policy = async_overflow_policy::block_retry;
+ std::function<void()> _worker_warmup_cb = nullptr;
+ std::chrono::milliseconds _flush_interval_ms;
+ std::function<void()> _worker_teardown_cb = nullptr;
+};
+#ifdef SPDLOG_NO_REGISTRY_MUTEX
+typedef registry_t<spdlog::details::null_mutex> registry;
+#else
+typedef registry_t<std::mutex> registry;
+#endif
+}
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/details/spdlog_impl.h
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/details/spdlog_impl.h b/thirdparty/spdlog-0.13.0/include/spdlog/details/spdlog_impl.h
new file mode 100644
index 0000000..79d3ac4
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/details/spdlog_impl.h
@@ -0,0 +1,245 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+
+#pragma once
+
+//
+// Global registry functions
+//
+#include <spdlog/spdlog.h>
+#include <spdlog/details/registry.h>
+#include <spdlog/sinks/file_sinks.h>
+#include <spdlog/sinks/stdout_sinks.h>
+#ifdef SPDLOG_ENABLE_SYSLOG
+#include <spdlog/sinks/syslog_sink.h>
+#endif
+
+#ifdef _WIN32
+#include <spdlog/sinks/wincolor_sink.h>
+#else
+#include <spdlog/sinks/ansicolor_sink.h>
+#endif
+
+
+#ifdef __ANDROID__
+#include <spdlog/sinks/android_sink.h>
+#endif
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <string>
+
+inline void spdlog::register_logger(std::shared_ptr<logger> logger)
+{
+ return details::registry::instance().register_logger(logger);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name)
+{
+ return details::registry::instance().get(name);
+}
+
+inline void spdlog::drop(const std::string &name)
+{
+ details::registry::instance().drop(name);
+}
+
+// Create multi/single threaded simple file logger
+inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_mt(const std::string& logger_name, const filename_t& filename, bool truncate)
+{
+ return create<spdlog::sinks::simple_file_sink_mt>(logger_name, filename, truncate);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string& logger_name, const filename_t& filename, bool truncate)
+{
+ return create<spdlog::sinks::simple_file_sink_st>(logger_name, filename, truncate);
+}
+
+// Create multi/single threaded rotating file logger
+inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
+{
+ return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
+{
+ return create<spdlog::sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files);
+}
+
+// Create file logger which creates new file at midnight):
+inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(const std::string& logger_name, const filename_t& filename, int hour, int minute)
+{
+ return create<spdlog::sinks::daily_file_sink_mt>(logger_name, filename, hour, minute);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(const std::string& logger_name, const filename_t& filename, int hour, int minute)
+{
+ return create<spdlog::sinks::daily_file_sink_st>(logger_name, filename, hour, minute);
+}
+
+
+//
+// stdout/stderr loggers
+//
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string& logger_name)
+{
+ return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance());
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string& logger_name)
+{
+ return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance());
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string& logger_name)
+{
+ return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance());
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string& logger_name)
+{
+ return spdlog::details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance());
+}
+
+//
+// stdout/stderr color loggers
+//
+#ifdef _WIN32
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>();
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_st>();
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_mt>();
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::wincolor_stderr_sink_st>();
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+#else //ansi terminal colors
+
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_mt::instance());
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stdout_sink_st::instance());
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_mt::instance());
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+
+inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string& logger_name)
+{
+ auto sink = std::make_shared<spdlog::sinks::ansicolor_sink>(spdlog::sinks::stderr_sink_st::instance());
+ return spdlog::details::registry::instance().create(logger_name, sink);
+}
+#endif
+
+#ifdef SPDLOG_ENABLE_SYSLOG
+// Create syslog logger
+inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option)
+{
+ return create<spdlog::sinks::syslog_sink>(logger_name, syslog_ident, syslog_option);
+}
+#endif
+
+#ifdef __ANDROID__
+inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string& logger_name, const std::string& tag)
+{
+ return create<spdlog::sinks::android_sink>(logger_name, tag);
+}
+#endif
+
+// Create and register a logger a single sink
+inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const spdlog::sink_ptr& sink)
+{
+ return details::registry::instance().create(logger_name, sink);
+}
+
+//Create logger with multiple sinks
+
+inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks)
+{
+ return details::registry::instance().create(logger_name, sinks);
+}
+
+
+template <typename Sink, typename... Args>
+inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args)
+{
+ sink_ptr sink = std::make_shared<Sink>(args...);
+ return details::registry::instance().create(logger_name, { sink });
+}
+
+
+template<class It>
+inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
+{
+ return details::registry::instance().create(logger_name, sinks_begin, sinks_end);
+}
+
+inline void spdlog::set_formatter(spdlog::formatter_ptr f)
+{
+ details::registry::instance().formatter(f);
+}
+
+inline void spdlog::set_pattern(const std::string& format_string)
+{
+ return details::registry::instance().set_pattern(format_string);
+}
+
+inline void spdlog::set_level(level::level_enum log_level)
+{
+ return details::registry::instance().set_level(log_level);
+}
+
+inline void spdlog::set_error_handler(log_err_handler handler)
+{
+ return details::registry::instance().set_error_handler(handler);
+}
+
+
+inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
+{
+ details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
+}
+
+inline void spdlog::set_sync_mode()
+{
+ details::registry::instance().set_sync_mode();
+}
+
+inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun)
+{
+ details::registry::instance().apply_all(fun);
+}
+
+inline void spdlog::drop_all()
+{
+ details::registry::instance().drop_all();
+}
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/dummy.cpp
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/dummy.cpp b/thirdparty/spdlog-0.13.0/include/spdlog/dummy.cpp
new file mode 100644
index 0000000..6b2d4ab
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/dummy.cpp
@@ -0,0 +1,22 @@
+/**
+ * @file dummy.cpp
+ * MiNiFiMain implementation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Dummy CPP file to work around Cmake limitation on header only libraries
+
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/73ecc667/thirdparty/spdlog-0.13.0/include/spdlog/fmt/bundled/format.cc
----------------------------------------------------------------------
diff --git a/thirdparty/spdlog-0.13.0/include/spdlog/fmt/bundled/format.cc b/thirdparty/spdlog-0.13.0/include/spdlog/fmt/bundled/format.cc
new file mode 100644
index 0000000..2bd774e
--- /dev/null
+++ b/thirdparty/spdlog-0.13.0/include/spdlog/fmt/bundled/format.cc
@@ -0,0 +1,940 @@
+/*
+ Formatting library for C++
+
+ Copyright (c) 2012 - 2016, Victor Zverovich
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "format.h"
+
+#include <string.h>
+
+#include <cctype>
+#include <cerrno>
+#include <climits>
+#include <cmath>
+#include <cstdarg>
+#include <cstddef> // for std::ptrdiff_t
+
+#if defined(_WIN32) && defined(__MINGW32__)
+# include <cstring>
+#endif
+
+#if FMT_USE_WINDOWS_H
+# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
+# include <windows.h>
+# else
+# define NOMINMAX
+# include <windows.h>
+# undef NOMINMAX
+# endif
+#endif
+
+using fmt::internal::Arg;
+
+#if FMT_EXCEPTIONS
+# define FMT_TRY try
+# define FMT_CATCH(x) catch (x)
+#else
+# define FMT_TRY if (true)
+# define FMT_CATCH(x) if (false)
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+# pragma warning(disable: 4702) // unreachable code
+// Disable deprecation warning for strerror. The latter is not called but
+// MSVC fails to detect it.
+# pragma warning(disable: 4996)
+#endif
+
+// Dummy implementations of strerror_r and strerror_s called if corresponding
+// system functions are not available.
+static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
+ return fmt::internal::Null<>();
+}
+static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
+ return fmt::internal::Null<>();
+}
+
+namespace fmt {
+
+FMT_FUNC internal::RuntimeError::~RuntimeError() throw() {}
+FMT_FUNC FormatError::~FormatError() throw() {}
+FMT_FUNC SystemError::~SystemError() throw() {}
+
+namespace {
+
+#ifndef _MSC_VER
+# define FMT_SNPRINTF snprintf
+#else // _MSC_VER
+inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
+ va_end(args);
+ return result;
+}
+# define FMT_SNPRINTF fmt_snprintf
+#endif // _MSC_VER
+
+#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+# define FMT_SWPRINTF snwprintf
+#else
+# define FMT_SWPRINTF swprintf
+#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
+
+// Checks if a value fits in int - used to avoid warnings about comparing
+// signed and unsigned integers.
+template <bool IsSigned>
+struct IntChecker {
+ template <typename T>
+ static bool fits_in_int(T value) {
+ unsigned max = INT_MAX;
+ return value <= max;
+ }
+ static bool fits_in_int(bool) { return true; }
+};
+
+template <>
+struct IntChecker<true> {
+ template <typename T>
+ static bool fits_in_int(T value) {
+ return value >= INT_MIN && value <= INT_MAX;
+ }
+ static bool fits_in_int(int) { return true; }
+};
+
+const char RESET_COLOR[] = "\x1b[0m";
+
+typedef void (*FormatFunc)(Writer &, int, StringRef);
+
+// Portable thread-safe version of strerror.
+// Sets buffer to point to a string describing the error code.
+// This can be either a pointer to a string stored in buffer,
+// or a pointer to some static immutable string.
+// Returns one of the following values:
+// 0 - success
+// ERANGE - buffer is not large enough to store the error message
+// other - failure
+// Buffer should be at least of size 1.
+int safe_strerror(
+ int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
+ FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
+
+ class StrError {
+ private:
+ int error_code_;
+ char *&buffer_;
+ std::size_t buffer_size_;
+
+ // A noop assignment operator to avoid bogus warnings.
+ void operator=(const StrError &) {}
+
+ // Handle the result of XSI-compliant version of strerror_r.
+ int handle(int result) {
+ // glibc versions before 2.13 return result in errno.
+ return result == -1 ? errno : result;
+ }
+
+ // Handle the result of GNU-specific version of strerror_r.
+ int handle(char *message) {
+ // If the buffer is full then the message is probably truncated.
+ if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
+ return ERANGE;
+ buffer_ = message;
+ return 0;
+ }
+
+ // Handle the case when strerror_r is not available.
+ int handle(internal::Null<>) {
+ return fallback(strerror_s(buffer_, buffer_size_, error_code_));
+ }
+
+ // Fallback to strerror_s when strerror_r is not available.
+ int fallback(int result) {
+ // If the buffer is full then the message is probably truncated.
+ return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
+ ERANGE : result;
+ }
+
+ // Fallback to strerror if strerror_r and strerror_s are not available.
+ int fallback(internal::Null<>) {
+ errno = 0;
+ buffer_ = strerror(error_code_);
+ return errno;
+ }
+
+ public:
+ StrError(int err_code, char *&buf, std::size_t buf_size)
+ : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
+
+ int run() {
+ strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
+ return handle(strerror_r(error_code_, buffer_, buffer_size_));
+ }
+ };
+ return StrError(error_code, buffer, buffer_size).run();
+}
+
+void format_error_code(Writer &out, int error_code,
+ StringRef message) FMT_NOEXCEPT {
+ // Report error code making sure that the output fits into
+ // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
+ // bad_alloc.
+ out.clear();
+ static const char SEP[] = ": ";
+ static const char ERROR_STR[] = "error ";
+ // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
+ std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
+ typedef internal::IntTraits<int>::MainType MainType;
+ MainType abs_value = static_cast<MainType>(error_code);
+ if (internal::is_negative(error_code)) {
+ abs_value = 0 - abs_value;
+ ++error_code_size;
+ }
+ error_code_size += internal::count_digits(abs_value);
+ if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
+ out << message << SEP;
+ out << ERROR_STR << error_code;
+ assert(out.size() <= internal::INLINE_BUFFER_SIZE);
+}
+
+void report_error(FormatFunc func, int error_code,
+ StringRef message) FMT_NOEXCEPT {
+ MemoryWriter full_message;
+ func(full_message, error_code, message);
+ // Use Writer::data instead of Writer::c_str to avoid potential memory
+ // allocation.
+ std::fwrite(full_message.data(), full_message.size(), 1, stderr);
+ std::fputc('\n', stderr);
+}
+
+// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
+class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
+ public:
+ template <typename T>
+ bool visit_any_int(T value) { return value == 0; }
+};
+
+// Checks if an argument is a valid printf width specifier and sets
+// left alignment if it is negative.
+class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
+ private:
+ FormatSpec &spec_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
+
+ public:
+ explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
+
+ void report_unhandled_arg() {
+ FMT_THROW(FormatError("width is not integer"));
+ }
+
+ template <typename T>
+ unsigned visit_any_int(T value) {
+ typedef typename internal::IntTraits<T>::MainType UnsignedType;
+ UnsignedType width = static_cast<UnsignedType>(value);
+ if (internal::is_negative(value)) {
+ spec_.align_ = ALIGN_LEFT;
+ width = 0 - width;
+ }
+ if (width > INT_MAX)
+ FMT_THROW(FormatError("number is too big"));
+ return static_cast<unsigned>(width);
+ }
+};
+
+class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
+ public:
+ void report_unhandled_arg() {
+ FMT_THROW(FormatError("precision is not integer"));
+ }
+
+ template <typename T>
+ int visit_any_int(T value) {
+ if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
+ FMT_THROW(FormatError("number is too big"));
+ return static_cast<int>(value);
+ }
+};
+
+template <typename T, typename U>
+struct is_same {
+ enum { value = 0 };
+};
+
+template <typename T>
+struct is_same<T, T> {
+ enum { value = 1 };
+};
+
+// An argument visitor that converts an integer argument to T for printf,
+// if T is an integral type. If T is void, the argument is converted to
+// corresponding signed or unsigned type depending on the type specifier:
+// 'd' and 'i' - signed, other - unsigned)
+template <typename T = void>
+class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
+ private:
+ internal::Arg &arg_;
+ wchar_t type_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
+
+ public:
+ ArgConverter(internal::Arg &arg, wchar_t type)
+ : arg_(arg), type_(type) {}
+
+ void visit_bool(bool value) {
+ if (type_ != 's')
+ visit_any_int(value);
+ }
+
+ template <typename U>
+ void visit_any_int(U value) {
+ bool is_signed = type_ == 'd' || type_ == 'i';
+ using internal::Arg;
+ typedef typename internal::Conditional<
+ is_same<T, void>::value, U, T>::type TargetType;
+ if (sizeof(TargetType) <= sizeof(int)) {
+ // Extra casts are used to silence warnings.
+ if (is_signed) {
+ arg_.type = Arg::INT;
+ arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
+ } else {
+ arg_.type = Arg::UINT;
+ typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
+ arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
+ }
+ } else {
+ if (is_signed) {
+ arg_.type = Arg::LONG_LONG;
+ // glibc's printf doesn't sign extend arguments of smaller types:
+ // std::printf("%lld", -42); // prints "4294967254"
+ // but we don't have to do the same because it's a UB.
+ arg_.long_long_value = static_cast<LongLong>(value);
+ } else {
+ arg_.type = Arg::ULONG_LONG;
+ arg_.ulong_long_value =
+ static_cast<typename internal::MakeUnsigned<U>::Type>(value);
+ }
+ }
+ }
+};
+
+// Converts an integer argument to char for printf.
+class CharConverter : public ArgVisitor<CharConverter, void> {
+ private:
+ internal::Arg &arg_;
+
+ FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
+
+ public:
+ explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
+
+ template <typename T>
+ void visit_any_int(T value) {
+ arg_.type = internal::Arg::CHAR;
+ arg_.int_value = static_cast<char>(value);
+ }
+};
+} // namespace
+
+namespace internal {
+
+template <typename Char>
+class PrintfArgFormatter :
+ public ArgFormatterBase<PrintfArgFormatter<Char>, Char> {
+
+ void write_null_pointer() {
+ this->spec().type_ = 0;
+ this->write("(nil)");
+ }
+
+ typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base;
+
+ public:
+ PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
+ : ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {}
+
+ void visit_bool(bool value) {
+ FormatSpec &fmt_spec = this->spec();
+ if (fmt_spec.type_ != 's')
+ return this->visit_any_int(value);
+ fmt_spec.type_ = 0;
+ this->write(value);
+ }
+
+ void visit_char(int value) {
+ const FormatSpec &fmt_spec = this->spec();
+ BasicWriter<Char> &w = this->writer();
+ if (fmt_spec.type_ && fmt_spec.type_ != 'c')
+ w.write_int(value, fmt_spec);
+ typedef typename BasicWriter<Char>::CharPtr CharPtr;
+ CharPtr out = CharPtr();
+ if (fmt_spec.width_ > 1) {
+ Char fill = ' ';
+ out = w.grow_buffer(fmt_spec.width_);
+ if (fmt_spec.align_ != ALIGN_LEFT) {
+ std::fill_n(out, fmt_spec.width_ - 1, fill);
+ out += fmt_spec.width_ - 1;
+ } else {
+ std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
+ }
+ } else {
+ out = w.grow_buffer(1);
+ }
+ *out = static_cast<Char>(value);
+ }
+
+ void visit_cstring(const char *value) {
+ if (value)
+ Base::visit_cstring(value);
+ else if (this->spec().type_ == 'p')
+ write_null_pointer();
+ else
+ this->write("(null)");
+ }
+
+ void visit_pointer(const void *value) {
+ if (value)
+ return Base::visit_pointer(value);
+ this->spec().type_ = 0;
+ write_null_pointer();
+ }
+
+ void visit_custom(Arg::CustomValue c) {
+ BasicFormatter<Char> formatter(ArgList(), this->writer());
+ const Char format_str[] = {'}', 0};
+ const Char *format = format_str;
+ c.format(&formatter, c.value, &format);
+ }
+};
+} // namespace internal
+} // namespace fmt
+
+FMT_FUNC void fmt::SystemError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ internal::format_system_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+template <typename T>
+int fmt::internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, value) :
+ FMT_SNPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SNPRINTF(buffer, size, format, width, value) :
+ FMT_SNPRINTF(buffer, size, format, width, precision, value);
+}
+
+template <typename T>
+int fmt::internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, T value) {
+ if (width == 0) {
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, value) :
+ FMT_SWPRINTF(buffer, size, format, precision, value);
+ }
+ return precision < 0 ?
+ FMT_SWPRINTF(buffer, size, format, width, value) :
+ FMT_SWPRINTF(buffer, size, format, width, precision, value);
+}
+
+template <typename T>
+const char fmt::internal::BasicData<T>::DIGITS[] =
+ "0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899";
+
+#define FMT_POWERS_OF_10(factor) \
+ factor * 10, \
+ factor * 100, \
+ factor * 1000, \
+ factor * 10000, \
+ factor * 100000, \
+ factor * 1000000, \
+ factor * 10000000, \
+ factor * 100000000, \
+ factor * 1000000000
+
+template <typename T>
+const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
+ 0, FMT_POWERS_OF_10(1)
+};
+
+template <typename T>
+const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
+ 0,
+ FMT_POWERS_OF_10(1),
+ FMT_POWERS_OF_10(fmt::ULongLong(1000000000)),
+ // Multiply several constants instead of using a single long long constant
+ // to avoid warnings about C++98 not supporting long long.
+ fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10
+};
+
+FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
+ (void)type;
+ if (std::isprint(static_cast<unsigned char>(code))) {
+ FMT_THROW(fmt::FormatError(
+ fmt::format("unknown format code '{}' for {}", code, type)));
+ }
+ FMT_THROW(fmt::FormatError(
+ fmt::format("unknown format code '\\x{:02x}' for {}",
+ static_cast<unsigned>(code), type)));
+}
+
+#if FMT_USE_WINDOWS_H
+
+FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
+ static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
+ if (s.size() > INT_MAX)
+ FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
+ int s_size = static_cast<int>(s.size());
+ int length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_.resize(length + 1);
+ length = MultiByteToWideChar(
+ CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
+ if (length == 0)
+ FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
+ buffer_[length] = 0;
+}
+
+FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
+ if (int error_code = convert(s)) {
+ FMT_THROW(WindowsError(error_code,
+ "cannot convert string from UTF-16 to UTF-8"));
+ }
+}
+
+FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
+ if (s.size() > INT_MAX)
+ return ERROR_INVALID_PARAMETER;
+ int s_size = static_cast<int>(s.size());
+ int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
+ if (length == 0)
+ return GetLastError();
+ buffer_.resize(length + 1);
+ length = WideCharToMultiByte(
+ CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
+ if (length == 0)
+ return GetLastError();
+ buffer_[length] = 0;
+ return 0;
+}
+
+FMT_FUNC void fmt::WindowsError::init(
+ int err_code, CStringRef format_str, ArgList args) {
+ error_code_ = err_code;
+ MemoryWriter w;
+ internal::format_windows_error(w, err_code, format(format_str, args));
+ std::runtime_error &base = *this;
+ base = std::runtime_error(w.str());
+}
+
+FMT_FUNC void fmt::internal::format_windows_error(
+ fmt::Writer &out, int error_code,
+ fmt::StringRef message) FMT_NOEXCEPT {
+ FMT_TRY {
+ MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
+ buffer.resize(INLINE_BUFFER_SIZE);
+ for (;;) {
+ wchar_t *system_message = &buffer[0];
+ int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ system_message, static_cast<uint32_t>(buffer.size()), 0);
+ if (result != 0) {
+ UTF16ToUTF8 utf8_message;
+ if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
+ out << message << ": " << utf8_message;
+ return;
+ }
+ break;
+ }
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+#endif // FMT_USE_WINDOWS_H
+
+FMT_FUNC void fmt::internal::format_system_error(
+ fmt::Writer &out, int error_code,
+ fmt::StringRef message) FMT_NOEXCEPT {
+ FMT_TRY {
+ MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
+ buffer.resize(INLINE_BUFFER_SIZE);
+ for (;;) {
+ char *system_message = &buffer[0];
+ int result = safe_strerror(error_code, system_message, buffer.size());
+ if (result == 0) {
+ out << message << ": " << system_message;
+ return;
+ }
+ if (result != ERANGE)
+ break; // Can't get error message, report error code instead.
+ buffer.resize(buffer.size() * 2);
+ }
+ } FMT_CATCH(...) {}
+ fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
+}
+
+template <typename Char>
+void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
+ if (!map_.empty())
+ return;
+ typedef internal::NamedArg<Char> NamedArg;
+ const NamedArg *named_arg = 0;
+ bool use_values =
+ args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
+ if (use_values) {
+ for (unsigned i = 0;/*nothing*/; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ switch (arg_type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/;
+ }
+ }
+ return;
+ }
+ for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
+ internal::Arg::Type arg_type = args.type(i);
+ if (arg_type == internal::Arg::NAMED_ARG) {
+ named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ }
+ }
+ for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
+ switch (args.args_[i].type) {
+ case internal::Arg::NONE:
+ return;
+ case internal::Arg::NAMED_ARG:
+ named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
+ map_.push_back(Pair(named_arg->name, *named_arg));
+ break;
+ default:
+ /*nothing*/;
+ }
+ }
+}
+
+template <typename Char>
+void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
+ FMT_THROW(std::runtime_error("buffer overflow"));
+}
+
+FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
+ unsigned arg_index, const char *&error) {
+ Arg arg = args_[arg_index];
+ switch (arg.type) {
+ case Arg::NONE:
+ error = "argument index out of range";
+ break;
+ case Arg::NAMED_ARG:
+ arg = *static_cast<const internal::Arg*>(arg.pointer);
+ break;
+ default:
+ /*nothing*/;
+ }
+ return arg;
+}
+
+template <typename Char>
+void fmt::internal::PrintfFormatter<Char>::parse_flags(
+ FormatSpec &spec, const Char *&s) {
+ for (;;) {
+ switch (*s++) {
+ case '-':
+ spec.align_ = ALIGN_LEFT;
+ break;
+ case '+':
+ spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
+ break;
+ case '0':
+ spec.fill_ = '0';
+ break;
+ case ' ':
+ spec.flags_ |= SIGN_FLAG;
+ break;
+ case '#':
+ spec.flags_ |= HASH_FLAG;
+ break;
+ default:
+ --s;
+ return;
+ }
+ }
+}
+
+template <typename Char>
+Arg fmt::internal::PrintfFormatter<Char>::get_arg(
+ const Char *s, unsigned arg_index) {
+ (void)s;
+ const char *error = 0;
+ Arg arg = arg_index == UINT_MAX ?
+ next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
+ if (error)
+ FMT_THROW(FormatError(!*s ? "invalid format string" : error));
+ return arg;
+}
+
+template <typename Char>
+unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
+ const Char *&s, FormatSpec &spec) {
+ unsigned arg_index = UINT_MAX;
+ Char c = *s;
+ if (c >= '0' && c <= '9') {
+ // Parse an argument index (if followed by '$') or a width possibly
+ // preceded with '0' flag(s).
+ unsigned value = parse_nonnegative_int(s);
+ if (*s == '$') { // value is an argument index
+ ++s;
+ arg_index = value;
+ } else {
+ if (c == '0')
+ spec.fill_ = '0';
+ if (value != 0) {
+ // Nonzero value means that we parsed width and don't need to
+ // parse it or flags again, so return now.
+ spec.width_ = value;
+ return arg_index;
+ }
+ }
+ }
+ parse_flags(spec, s);
+ // Parse width.
+ if (*s >= '0' && *s <= '9') {
+ spec.width_ = parse_nonnegative_int(s);
+ } else if (*s == '*') {
+ ++s;
+ spec.width_ = WidthHandler(spec).visit(get_arg(s));
+ }
+ return arg_index;
+}
+
+template <typename Char>
+void fmt::internal::PrintfFormatter<Char>::format(
+ BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) {
+ const Char *start = format_str.c_str();
+ const Char *s = start;
+ while (*s) {
+ Char c = *s++;
+ if (c != '%') continue;
+ if (*s == c) {
+ write(writer, start, s);
+ start = ++s;
+ continue;
+ }
+ write(writer, start, s - 1);
+
+ FormatSpec spec;
+ spec.align_ = ALIGN_RIGHT;
+
+ // Parse argument index, flags and width.
+ unsigned arg_index = parse_header(s, spec);
+
+ // Parse precision.
+ if (*s == '.') {
+ ++s;
+ if ('0' <= *s && *s <= '9') {
+ spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
+ } else if (*s == '*') {
+ ++s;
+ spec.precision_ = PrecisionHandler().visit(get_arg(s));
+ }
+ }
+
+ Arg arg = get_arg(s, arg_index);
+ if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
+ spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
+ if (spec.fill_ == '0') {
+ if (arg.type <= Arg::LAST_NUMERIC_TYPE)
+ spec.align_ = ALIGN_NUMERIC;
+ else
+ spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
+ }
+
+ // Parse length and convert the argument to the required type.
+ switch (*s++) {
+ case 'h':
+ if (*s == 'h')
+ ArgConverter<signed char>(arg, *++s).visit(arg);
+ else
+ ArgConverter<short>(arg, *s).visit(arg);
+ break;
+ case 'l':
+ if (*s == 'l')
+ ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
+ else
+ ArgConverter<long>(arg, *s).visit(arg);
+ break;
+ case 'j':
+ ArgConverter<intmax_t>(arg, *s).visit(arg);
+ break;
+ case 'z':
+ ArgConverter<std::size_t>(arg, *s).visit(arg);
+ break;
+ case 't':
+ ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
+ break;
+ case 'L':
+ // printf produces garbage when 'L' is omitted for long double, no
+ // need to do the same.
+ break;
+ default:
+ --s;
+ ArgConverter<void>(arg, *s).visit(arg);
+ }
+
+ // Parse type.
+ if (!*s)
+ FMT_THROW(FormatError("invalid format string"));
+ spec.type_ = static_cast<char>(*s++);
+ if (arg.type <= Arg::LAST_INTEGER_TYPE) {
+ // Normalize type.
+ switch (spec.type_) {
+ case 'i': case 'u':
+ spec.type_ = 'd';
+ break;
+ case 'c':
+ // TODO: handle wchar_t
+ CharConverter(arg).visit(arg);
+ break;
+ }
+ }
+
+ start = s;
+
+ // Format argument.
+ internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
+ }
+ write(writer, start, s);
+}
+
+FMT_FUNC void fmt::report_system_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT {
+ // 'fmt::' is for bcc32.
+ fmt::report_error(internal::format_system_error, error_code, message);
+}
+
+#if FMT_USE_WINDOWS_H
+FMT_FUNC void fmt::report_windows_error(
+ int error_code, fmt::StringRef message) FMT_NOEXCEPT {
+ // 'fmt::' is for bcc32.
+ fmt::report_error(internal::format_windows_error, error_code, message);
+}
+#endif
+
+FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
+ MemoryWriter w;
+ w.write(format_str, args);
+ std::fwrite(w.data(), 1, w.size(), f);
+}
+
+FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
+ print(stdout, format_str, args);
+}
+
+FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
+ char escape[] = "\x1b[30m";
+ escape[3] = static_cast<char>('0' + c);
+ std::fputs(escape, stdout);
+ print(format, args);
+ std::fputs(RESET_COLOR, stdout);
+}
+
+FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
+ MemoryWriter w;
+ printf(w, format, args);
+ std::size_t size = w.size();
+ return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
+}
+
+#ifndef FMT_HEADER_ONLY
+
+template struct fmt::internal::BasicData<void>;
+
+// Explicit instantiations for char.
+
+template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
+
+template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args);
+
+template void fmt::internal::PrintfFormatter<char>::format(
+ BasicWriter<char> &writer, CStringRef format);
+
+template int fmt::internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, double value);
+
+template int fmt::internal::CharTraits<char>::format_float(
+ char *buffer, std::size_t size, const char *format,
+ unsigned width, int precision, long double value);
+
+// Explicit instantiations for wchar_t.
+
+template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t);
+
+template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args);
+
+template void fmt::internal::PrintfFormatter<wchar_t>::format(
+ BasicWriter<wchar_t> &writer, WCStringRef format);
+
+template int fmt::internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, double value);
+
+template int fmt::internal::CharTraits<wchar_t>::format_float(
+ wchar_t *buffer, std::size_t size, const wchar_t *format,
+ unsigned width, int precision, long double value);
+
+#endif // FMT_HEADER_ONLY
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif