diff --git a/third-party/easylogging++/easylogging++.cc b/third-party/easylogging++/easylogging++.cc index 16ceda2..686e695 100644 --- a/third-party/easylogging++/easylogging++.cc +++ b/third-party/easylogging++/easylogging++.cc @@ -4,17 +4,17 @@ // Easylogging++ v9.96.7 // Cross-platform logging library for C++ applications // -// Copyright (c) 2012-2018 Zuhd Web Services +// Copyright (c) 2012-2018 Amrayn Web Services // Copyright (c) 2012-2018 @abumusamq // // This library is released under the MIT Licence. -// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE +// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE // -// https://zuhd.org +// https://amrayn.com // http://muflihun.com // -#include +#include "easylogging++.h" #if defined(AUTO_INITIALIZE_EASYLOGGINGPP) INITIALIZE_EASYLOGGINGPP @@ -64,7 +64,7 @@ static const char* kDateTimeFormatSpecifierForFilename = "%datet // Date/time static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August", +static const char* kMonths[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; @@ -79,7 +79,7 @@ static const char* kNullPointer = "nullptr"; #if ELPP_VARIADIC_TEMPLATES_SUPPORTED #endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED static const base::type::VerboseLevel kMaxVerboseLevel = 9; -static const char* kUnknownUser = "user"; +static const char* kUnknownUser = "unknown-user"; static const char* kUnknownHost = "unknown-host"; @@ -292,7 +292,7 @@ Configurations::Configurations(const std::string& configurationFile, bool useDef } bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) { - // We initial assertion with true because if we have assertion diabled, we want to pass this + // We initial assertion with true because if we have assertion disabled, we want to pass this // check and if assertion is enabled we will have values re-assigned any way. bool assertionPassed = true; ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true, @@ -599,7 +599,7 @@ void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level lev // Logger -Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) : +Logger::Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference) : m_id(id), m_typedConfigurations(nullptr), m_parentApplicationName(std::string()), @@ -609,7 +609,7 @@ Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsRe } Logger::Logger(const std::string& id, const Configurations& configurations, - base::LogStreamsReferenceMap* logStreamsReference) : + base::LogStreamsReferenceMapPtr logStreamsReference) : m_id(id), m_typedConfigurations(nullptr), m_parentApplicationName(std::string()), @@ -794,22 +794,22 @@ bool File::createPath(const std::string& path) { if (path[0] == '/') { builtPath = "/"; } - currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0); + currPath = STRTOK(currPath, base::consts::kFilePathSeparator, 0); #elif ELPP_OS_WINDOWS // Use secure functions API char* nextTok_ = nullptr; - currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_); + currPath = STRTOK(currPath, base::consts::kFilePathSeparator, &nextTok_); ELPP_UNUSED(nextTok_); #endif // ELPP_OS_UNIX while (currPath != nullptr) { builtPath.append(currPath); - builtPath.append(base::consts::kFilePathSeperator); + builtPath.append(base::consts::kFilePathSeparator); #if ELPP_OS_UNIX status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS); - currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0); + currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, 0); #elif ELPP_OS_WINDOWS status = _mkdir(builtPath.c_str()); - currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_); + currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, &nextTok_); #endif // ELPP_OS_UNIX } if (status == -1) { @@ -1013,7 +1013,7 @@ char* Str::clearBuff(char buff[], std::size_t lim) { return buff; } -/// @brief Converst wchar* to char* +/// @brief Converts wchar* to char* /// NOTE: Need to free return value after use! char* Str::wcharPtrToCharPtr(const wchar_t* line) { std::size_t len_ = wcslen(line) + 1; @@ -1190,7 +1190,7 @@ std::string DateTime::timevalToString(struct timeval tval, const char* format, buildTimeInfo(&tval, &timeInfo); const int kBuffSize = 30; char buff_[kBuffSize] = ""; - parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast(static_cast(tval.tv_usec) / ssPrec->m_offset), + parseFormat(buff_, kBuffSize, format, &timeInfo, static_cast(tval.tv_usec / ssPrec->m_offset), ssPrec); return std::string(buff_); } @@ -1199,7 +1199,7 @@ base::type::string_t DateTime::formatTime(unsigned long long time, base::Timesta base::type::EnumType start = static_cast(timestampUnit); const base::type::char_t* unit = base::consts::kTimeFormats[start].unit; for (base::type::EnumType i = start; i < base::consts::kTimeFormatsCount - 1; ++i) { - if (static_cast(time) <= base::consts::kTimeFormats[i].value) { + if (time <= static_cast(base::consts::kTimeFormats[i].value)) { break; } if (base::consts::kTimeFormats[i].value == 1000.0 && static_cast(time) / 1000.0f < 1.9f) { @@ -1264,7 +1264,7 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co --format; break; case 'd': // Day - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_mday), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mday, 2, buf, bufLim); continue; case 'a': // Day of week (short) buf = base::utils::Str::addToBuff(base::consts::kDaysAbbrev[tInfo->tm_wday], buf, bufLim); @@ -1273,7 +1273,7 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co buf = base::utils::Str::addToBuff(base::consts::kDays[tInfo->tm_wday], buf, bufLim); continue; case 'M': // month - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_mon + 1), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_mon + 1, 2, buf, bufLim); continue; case 'b': // month (short) buf = base::utils::Str::addToBuff(base::consts::kMonthsAbbrev[tInfo->tm_mon], buf, bufLim); @@ -1282,22 +1282,22 @@ char* DateTime::parseFormat(char* buf, std::size_t bufSz, const char* format, co buf = base::utils::Str::addToBuff(base::consts::kMonths[tInfo->tm_mon], buf, bufLim); continue; case 'y': // year (two digits) - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_year + base::consts::kYearBase), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 2, buf, bufLim); continue; case 'Y': // year (four digits) - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_year + base::consts::kYearBase), 4, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_year + base::consts::kYearBase, 4, buf, bufLim); continue; case 'h': // hour (12-hour) buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour % 12, 2, buf, bufLim); continue; case 'H': // hour (24-hour) - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_hour), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_hour, 2, buf, bufLim); continue; case 'm': // minute - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_min), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_min, 2, buf, bufLim); continue; case 's': // second - buf = base::utils::Str::convertAndAddToBuff(static_cast(tInfo->tm_sec), 2, buf, bufLim); + buf = base::utils::Str::convertAndAddToBuff(tInfo->tm_sec, 2, buf, bufLim); continue; case 'z': // subsecond part case 'g': @@ -1524,7 +1524,7 @@ void LogFormat::parseFromFormat(const base::type::string_t& userFormat) { // For date/time we need to extract user's date format first std::size_t dateIndex = std::string::npos; if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) { - while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { + while (dateIndex != std::string::npos && dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) { dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1); } if (dateIndex != std::string::npos) { @@ -1553,7 +1553,7 @@ void LogFormat::updateDateFormat(std::size_t index, base::type::string_t& currFo } ss << static_cast(*ptr); } - currFormat.erase(index, static_cast(count)); + currFormat.erase(index, count); m_dateTimeFormat = ss.str(); } else { // No format provided, use default @@ -1615,7 +1615,7 @@ void LogFormat::updateFormatSpec(void) { // TypedConfigurations TypedConfigurations::TypedConfigurations(Configurations* configurations, - base::LogStreamsReferenceMap* logStreamsReference) { + LogStreamsReferenceMapPtr logStreamsReference) { m_configurations = configurations; m_logStreamsReference = logStreamsReference; build(m_configurations); @@ -1691,7 +1691,7 @@ void TypedConfigurations::build(Configurations* configurations) { // We do not yet configure filename but we will configure in another // loop. This is because if file cannot be created, we will force ToFile // to be false. Because configuring logger is not necessarily performance - // sensative operation, we can live with another loop; (by the way this loop + // sensitive operation, we can live with another loop; (by the way this loop // is not very heavy either) } else if (conf->configurationType() == ConfigurationType::Format) { setValue(conf->level(), base::LogFormat(conf->level(), @@ -1737,7 +1737,7 @@ unsigned long TypedConfigurations::getULong(std::string confVal) { ELPP_ASSERT(valid, "Configuration value not a valid integer [" << confVal << "]"); return 0; } - return static_cast(atol(confVal.c_str())); + return atol(confVal.c_str()); } std::string TypedConfigurations::resolveFilename(const std::string& filename) { @@ -1765,7 +1765,7 @@ std::string TypedConfigurations::resolveFilename(const std::string& filename) { } ss << *ptr; } - resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), static_cast(count)); + resultingFilename.erase(dateIndex + dateTimeFormatSpecifierStr.size(), count); fmt = ss.str(); } else { fmt = std::string(base::consts::kDefaultDateTimeFormatInFilename); @@ -1785,34 +1785,34 @@ void TypedConfigurations::insertFile(Level level, const std::string& fullFilenam std::cerr << "Could not load empty file for logging, please re-check your configurations for level [" << LevelHelper::convertToString(level) << "]"; } - std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator); + std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeparator); if (filePath.size() < resolvedFilename.size()) { base::utils::File::createPath(filePath); } - auto create = [&](Level level_var) { + auto create = [&](Level var_level) { base::LogStreamsReferenceMap::iterator filestreamIter = m_logStreamsReference->find(resolvedFilename); base::type::fstream_t* fs = nullptr; if (filestreamIter == m_logStreamsReference->end()) { // We need a completely new stream, nothing to share with fs = base::utils::File::newFileStream(resolvedFilename); - m_filenameMap.insert(std::make_pair(level_var, resolvedFilename)); - m_fileStreamMap.insert(std::make_pair(level_var, base::FileStreamPtr(fs))); - m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(level_var)))); + m_filenameMap.insert(std::make_pair(var_level, resolvedFilename)); + m_fileStreamMap.insert(std::make_pair(var_level, base::FileStreamPtr(fs))); + m_logStreamsReference->insert(std::make_pair(resolvedFilename, base::FileStreamPtr(m_fileStreamMap.at(var_level)))); } else { // Woops! we have an existing one, share it! - m_filenameMap.insert(std::make_pair(level_var, filestreamIter->first)); - m_fileStreamMap.insert(std::make_pair(level_var, base::FileStreamPtr(filestreamIter->second))); + m_filenameMap.insert(std::make_pair(var_level, filestreamIter->first)); + m_fileStreamMap.insert(std::make_pair(var_level, base::FileStreamPtr(filestreamIter->second))); fs = filestreamIter->second.get(); } if (fs == nullptr) { // We display bad file error from newFileStream() ELPP_INTERNAL_ERROR("Setting [TO_FILE] of [" - << LevelHelper::convertToString(level_var) << "] to FALSE", false); - setValue(level_var, false, &m_toFileMap); + << LevelHelper::convertToString(var_level) << "] to FALSE", false); + setValue(var_level, false, &m_toFileMap); } }; - // If we dont have file conf for any level, create it for Level::Global first - // otherwise create for specified level + // If we dont have file conf for any var_level, create it for Level::Global first + // otherwise create for specified var_level create(m_filenameMap.empty() && m_fileStreamMap.empty() ? Level::Global : level); } @@ -1885,6 +1885,7 @@ bool RegisteredHitCounters::validateNTimes(const char* filename, base::type::Lin RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) : m_defaultLogBuilder(defaultLogBuilder) { m_defaultConfigurations.setToDefault(); + m_logStreamsReference = std::make_shared(); } Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) { @@ -1896,11 +1897,11 @@ Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) { ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger."); return nullptr; } - logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference); + logger_ = new Logger(id, m_defaultConfigurations, m_logStreamsReference); logger_->m_logBuilder = m_defaultLogBuilder; registerNew(id, logger_); LoggerRegistrationCallback* callback = nullptr; - for (const std::pair& h + for (const std::pair h : m_loggerRegistrationCallbacks) { callback = h.second.get(); if (callback != nullptr && callback->enabled()) { @@ -1926,8 +1927,8 @@ bool RegisteredLoggers::remove(const std::string& id) { void RegisteredLoggers::unsafeFlushAll(void) { ELPP_INTERNAL_INFO(1, "Flushing all log files"); - for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin(); - it != m_logStreamsReference.end(); ++it) { + for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference->begin(); + it != m_logStreamsReference->end(); ++it) { if (it->second.get() == nullptr) continue; it->second->flush(); } @@ -2184,16 +2185,18 @@ void Storage::setApplicationArguments(int argc, char** argv) { } // namespace base // LogDispatchCallback -void LogDispatchCallback::handle(const LogDispatchData* data) { #if defined(ELPP_THREAD_SAFE) +void LogDispatchCallback::handle(const LogDispatchData* data) { base::threading::ScopedLock scopedLock(m_fileLocksMapLock); std::string filename = data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level()); auto lock = m_fileLocks.find(filename); if (lock == m_fileLocks.end()) { m_fileLocks.emplace(std::make_pair(filename, std::unique_ptr(new base::threading::Mutex))); } -#endif } +#else +void LogDispatchCallback::handle(const LogDispatchData* /*data*/) {} +#endif base::threading::Mutex& LogDispatchCallback::fileHandle(const LogDispatchData* data) { auto it = m_fileLocks.find(data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level())); @@ -2219,7 +2222,7 @@ void DefaultLogDispatchCallback::dispatch(base::type::string_t&& logLine) { base::type::fstream_t* fs = m_data->logMessage()->logger()->m_typedConfigurations->fileStream( m_data->logMessage()->level()); if (fs != nullptr) { - fs->write(logLine.c_str(), static_cast(logLine.size())); + fs->write(logLine.c_str(), logLine.size()); if (fs->fail()) { ELPP_INTERNAL_ERROR("Unable to write log to file [" << m_data->logMessage()->logger()->m_typedConfigurations->filename(m_data->logMessage()->level()) << "].\n" @@ -2480,7 +2483,7 @@ void LogDispatcher::dispatch(void) { } #ifndef ELPP_NO_GLOBAL_LOCK // see https://github.com/muflihun/easyloggingpp/issues/580 - // global lock is turned off by default unless + // global lock is turned on by default unless // ELPP_NO_GLOBAL_LOCK is defined base::threading::ScopedLock scopedLock(ELPP->lock()); #endif @@ -2490,7 +2493,7 @@ void LogDispatcher::dispatch(void) { } LogDispatchCallback* callback = nullptr; LogDispatchData data; - for (const std::pair& h + for (const std::pair h : ELPP->m_logDispatchCallbacks) { callback = h.second.get(); if (callback != nullptr && callback->enabled()) { @@ -2505,7 +2508,7 @@ void LogDispatcher::dispatch(void) { void MessageBuilder::initialize(Logger* logger) { m_logger = logger; - m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ? + m_containerLogSeparator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ? ELPP_LITERAL("\n ") : ELPP_LITERAL(", "); } @@ -2541,7 +2544,7 @@ Writer& Writer::construct(int count, const char* loggerIds, ...) { va_list loggersList; va_start(loggersList, loggerIds); const char* id = loggerIds; - m_loggerIds.reserve(static_cast(count)); + m_loggerIds.reserve(count); for (int i = 0; i < count; ++i) { m_loggerIds.push_back(std::string(id)); id = va_arg(loggersList, const char*); @@ -2625,30 +2628,37 @@ void Writer::processDispatch() { } void Writer::triggerDispatch(void) { - if (m_proceed) { - if (m_msg == nullptr) { - LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel, - m_logger); - base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch(); - } else { - base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch(); - } - } - if (m_logger != nullptr) { - m_logger->stream().str(ELPP_LITERAL("")); - m_logger->releaseLock(); - } - if (m_proceed && m_level == Level::Fatal - && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { - base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) - << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]"; - std::stringstream reasonStream; - reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" - << " If you wish to disable 'abort on fatal log' please use " - << "el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)"; - base::utils::abort(1, reasonStream.str()); - } - m_proceed = false; + try { + if (m_proceed) { + if (m_msg == nullptr) { + LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel, + m_logger); + base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch(); + } else { + base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch(); + } + } + if (m_logger != nullptr) { + m_logger->stream().str(ELPP_LITERAL("")); + m_logger->releaseLock(); + } + if (m_proceed && m_level == Level::Fatal + && !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) { + base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId) + << "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]"; + std::stringstream reasonStream; + reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]" + << " If you wish to disable 'abort on fatal log' please use " + << "el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)"; + base::utils::abort(1, reasonStream.str()); + } + m_proceed = false; + } + catch(std::exception & ex){ + // Unused variable. Errors on MSVC. + (void)ex; + // Extremely low memory situation; don't let exception be unhandled. + } } // PErrorWriter @@ -2677,7 +2687,7 @@ PerformanceTracker::PerformanceTracker(const std::string& blockName, m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) { #if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED // We store it locally so that if user happen to change configuration by the end of scope - // or before calling checkpoint, we still depend on state of configuraton at time of construction + // or before calling checkpoint, we still depend on state of configuration at time of construction el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false); m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level); if (m_enabled) { @@ -2786,7 +2796,7 @@ std::ostream& operator<<(std::ostream& os, const StackTrace& st) { } void StackTrace::generateNew(void) { -#if ELPP_STACKTRACE +#ifdef HAVE_EXECINFO m_stack.clear(); void* stack[kMaxStack]; unsigned int size = backtrace(stack, kMaxStack); @@ -3005,7 +3015,7 @@ const Configurations* Loggers::defaultConfigurations(void) { return ELPP->registeredLoggers()->defaultConfigurations(); } -const base::LogStreamsReferenceMap* Loggers::logStreamsReference(void) { +const base::LogStreamsReferenceMapPtr Loggers::logStreamsReference(void) { return ELPP->registeredLoggers()->logStreamsReference(); } diff --git a/third-party/easylogging++/easylogging++.h b/third-party/easylogging++/easylogging++.h index 688d537..a5c9acf 100644 --- a/third-party/easylogging++/easylogging++.h +++ b/third-party/easylogging++/easylogging++.h @@ -4,13 +4,13 @@ // Easylogging++ v9.96.7 // Single-header only, cross-platform logging library for C++ applications // -// Copyright (c) 2012-2018 Zuhd Web Services +// Copyright (c) 2012-2018 Amrayn Web Services // Copyright (c) 2012-2018 @abumusamq // // This library is released under the MIT Licence. -// https://github.com/zuhd-org/easyloggingpp/blob/master/LICENSE +// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE // -// https://zuhd.org +// https://amrayn.com // http://muflihun.com // @@ -119,8 +119,13 @@ #else # define ELPP_OS_EMSCRIPTEN 0 #endif +#if (defined(__QNX__) || defined(__QNXNTO__)) +# define ELPP_OS_QNX 1 +#else +# define ELPP_OS_QNX 0 +#endif // Unix -#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN) && (!ELPP_OS_WINDOWS)) +#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN || ELPP_OS_QNX) && (!ELPP_OS_WINDOWS)) # define ELPP_OS_UNIX 1 #else # define ELPP_OS_UNIX 0 @@ -205,7 +210,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre # define ELPP_INTERNAL_INFO(lvl, msg) #endif // (defined(ELPP_DEBUG_INFO)) #if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG)) -# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN) +# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_CYGWIN && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN && !ELPP_OS_QNX) # define ELPP_STACKTRACE 1 # else # if ELPP_COMPILER_MSVC @@ -360,10 +365,10 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre # include # endif // ELPP_OS_WINDOWS #endif // defined(ELPP_UNICODE) -#if ELPP_STACKTRACE +#ifdef HAVE_EXECINFO # include # include -#endif // ELPP_STACKTRACE +#endif // ENABLE_EXECINFO #if ELPP_OS_ANDROID # include #endif // ELPP_OS_ANDROID @@ -580,7 +585,7 @@ enum class Level : base::type::EnumType { Fatal = 8, /// @brief Information representing errors in application but application will keep running Error = 16, - /// @brief Useful when application has potentially harmful situtaions + /// @brief Useful when application has potentially harmful situations Warning = 32, /// @brief Information that can be highly useful and vary with verbose logging level. Verbose = 64, @@ -640,7 +645,7 @@ enum class ConfigurationType : base::type::EnumType { ToStandardOutput = 4, /// @brief Determines format of logging corresponding level and logger. Format = 8, - /// @brief Determines log file (full path) to write logs to for correponding level and logger + /// @brief Determines log file (full path) to write logs to for corresponding level and logger Filename = 16, /// @brief Specifies precision of the subsecond part. It should be within range (1-6). SubsecondPrecision = 32, @@ -671,7 +676,7 @@ class ConfigurationTypeHelper : base::StaticClass { static base::type::EnumType castToInt(ConfigurationType configurationType) { return static_cast(configurationType); } - /// @brief Casts int(ushort) to configurationt type, useful for iterating through enum. + /// @brief Casts int(ushort) to configuration type, useful for iterating through enum. static ConfigurationType castFromInt(base::type::EnumType c) { return static_cast(c); } @@ -700,7 +705,7 @@ enum class LoggingFlag : base::type::EnumType { LogDetailedCrashReason = 4, /// @brief Allows to disable application abortion when logged using FATAL level DisableApplicationAbortOnFatalLog = 8, - /// @brief Flushes log with every log-entry (performance sensative) - Disabled by default + /// @brief Flushes log with every log-entry (performance sensitive) - Disabled by default ImmediateFlush = 16, /// @brief Enables strict file rolling StrictLogFileSizeCheck = 32, @@ -753,9 +758,9 @@ static const char* kSysLogLoggerId = "syslog"; #endif // defined(ELPP_SYSLOG) #if ELPP_OS_WINDOWS -static const char* kFilePathSeperator = "\\"; +static const char* kFilePathSeparator = "\\"; #else -static const char* kFilePathSeperator = "/"; +static const char* kFilePathSeparator = "/"; #endif // ELPP_OS_WINDOWS static const std::size_t kSourceFilenameMaxLength = 100; @@ -765,12 +770,12 @@ const struct { double value; const base::type::char_t* unit; } kTimeFormats[] = { - { 1000.0f, ELPP_LITERAL("us") }, - { 1000.0f, ELPP_LITERAL("ms") }, - { 60.0f, ELPP_LITERAL("seconds") }, - { 60.0f, ELPP_LITERAL("minutes") }, - { 24.0f, ELPP_LITERAL("hours") }, - { 7.0f, ELPP_LITERAL("days") } + { 1000.0, ELPP_LITERAL("us") }, + { 1000.0, ELPP_LITERAL("ms") }, + { 60.0, ELPP_LITERAL("seconds") }, + { 60.0, ELPP_LITERAL("minutes") }, + { 24.0, ELPP_LITERAL("hours") }, + { 7.0, ELPP_LITERAL("days") } }; static const int kTimeFormatsCount = sizeof(kTimeFormats) / sizeof(kTimeFormats[0]); const struct { @@ -786,7 +791,7 @@ const struct { }, { SIGFPE, "SIGFPE", "Erroneous arithmetic operation", - "Arithemetic operation issue such as division by zero or operation resulting in overflow." + "Arithmetic operation issue such as division by zero or operation resulting in overflow." }, { SIGILL, "SIGILL", "Illegal instruction", @@ -1052,14 +1057,14 @@ class File : base::StaticClass { static bool createPath(const std::string& path); /// @brief Extracts path of filename with leading slash static std::string extractPathFromFilename(const std::string& fullPath, - const char* seperator = base::consts::kFilePathSeperator); + const char* separator = base::consts::kFilePathSeparator); /// @brief builds stripped filename and puts it in buff static void buildStrippedFilename(const char* filename, char buff[], std::size_t limit = base::consts::kSourceFilenameMaxLength); /// @brief builds base filename and puts it in buff static void buildBaseFilename(const std::string& fullPath, char buff[], std::size_t limit = base::consts::kSourceFilenameMaxLength, - const char* seperator = base::consts::kFilePathSeperator); + const char* separator = base::consts::kFilePathSeparator); }; /// @brief String utilities helper class used internally. You should not use it. class Str : base::StaticClass { @@ -1128,7 +1133,7 @@ class Str : base::StaticClass { static char* addToBuff(const char* str, char* buf, const char* bufLim); static char* clearBuff(char buff[], std::size_t lim); - /// @brief Converst wchar* to char* + /// @brief Converts wchar* to char* /// NOTE: Need to free return value after use! static char* wcharPtrToCharPtr(const wchar_t* line); }; @@ -1169,7 +1174,7 @@ class OS : base::StaticClass { /// @brief Gets current host name or computer name. /// - /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen + /// @detail For android systems this is device name with its manufacturer and model separated by hyphen static std::string currentHost(void); /// @brief Whether or not terminal supports colors static bool termSupportsColor(void); @@ -1179,7 +1184,7 @@ class DateTime : base::StaticClass { public: /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond. /// - /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided + /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a separate implementation is provided /// @param [in,out] tv Pointer that gets updated static void gettimeofday(struct timeval* tv); @@ -1225,7 +1230,7 @@ class CommandLineArgs { } /// @brief Sets arguments and parses them void setArgs(int argc, char** argv); - /// @brief Returns true if arguments contain paramKey with a value (seperated by '=') + /// @brief Returns true if arguments contain paramKey with a value (separated by '=') bool hasParamWithValue(const char* paramKey) const; /// @brief Returns value of arguments /// @see hasParamWithValue(const char*) @@ -1381,7 +1386,7 @@ class Registry : public AbstractRegistryreinitDeepCopy(sr); } - /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element /// @see unregisterAll() /// @see deepCopy(const AbstractRegistry&) Registry& operator=(const Registry& sr) { @@ -1462,7 +1467,7 @@ class RegistryWithPred : public AbstractRegistry> { this->reinitDeepCopy(sr); } - /// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element + /// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element /// @see unregisterAll() /// @see deepCopy(const AbstractRegistry&) RegistryWithPred& operator=(const RegistryWithPred& sr) { @@ -1509,7 +1514,7 @@ class RegistryWithPred : public AbstractRegistry> { this->list().push_back(ptr); } -/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate +/// @brief Gets pointer from repository with specified arguments. Arguments are passed to predicate /// in order to validate pointer. template T_Ptr* get(const T& arg1, const T2 arg2) { @@ -1893,6 +1898,7 @@ class Configurations : public base::utils::RegistryWithPred FileStreamPtr; typedef std::unordered_map LogStreamsReferenceMap; +typedef std::shared_ptr LogStreamsReferenceMapPtr; /// @brief Configurations with data types. /// /// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations. @@ -1904,7 +1910,7 @@ class TypedConfigurations : public base::threading::ThreadSafe { /// @brief Constructor to initialize (construct) the object off el::Configurations /// @param configurations Configurations pointer/reference to base this typed configurations off. /// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference() - TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference); + TypedConfigurations(Configurations* configurations, LogStreamsReferenceMapPtr logStreamsReference); TypedConfigurations(const TypedConfigurations& other); @@ -1939,7 +1945,7 @@ class TypedConfigurations : public base::threading::ThreadSafe { std::unordered_map m_fileStreamMap; std::unordered_map m_maxLogFileSizeMap; std::unordered_map m_logFlushThresholdMap; - base::LogStreamsReferenceMap* m_logStreamsReference; + LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; friend class el::Helpers; friend class el::base::MessageBuilder; @@ -2207,11 +2213,11 @@ class LogBuilder : base::NoCopy { typedef std::shared_ptr LogBuilderPtr; /// @brief Represents a logger holding ID and configurations we need to write logs /// -/// @detail This class does not write logs itself instead its used by writer to read configuations from. +/// @detail This class does not write logs itself instead its used by writer to read configurations from. class Logger : public base::threading::ThreadSafe, public Loggable { public: - Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference); - Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference); + Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference); + Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMapPtr logStreamsReference); Logger(const Logger& logger); Logger& operator=(const Logger& logger); @@ -2257,7 +2263,16 @@ class Logger : public base::threading::ThreadSafe, public Loggable { void flush(Level level, base::type::fstream_t* fs); inline bool isFlushNeeded(Level level) { +//If GCC, errors on MSVC. +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wnull-dereference" +#endif + // Causes an error on GCC. return ++m_unflushedCount.find(level)->second >= m_typedConfigurations->logFlushThreshold(level); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif } inline LogBuilder* logBuilder(void) const { @@ -2301,7 +2316,7 @@ inline void FUNCTION_NAME(const T&); bool m_isConfigured; Configurations m_configurations; std::unordered_map m_unflushedCount; - base::LogStreamsReferenceMap* m_logStreamsReference; + base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; LogBuilderPtr m_logBuilder; friend class el::LogMessage; @@ -2388,8 +2403,8 @@ class RegisteredLoggers : public base::utils::Registry { base::utils::Registry::unregister(logger->id()); } - inline base::LogStreamsReferenceMap* logStreamsReference(void) { - return &m_logStreamsReference; + inline LogStreamsReferenceMapPtr logStreamsReference(void) { + return m_logStreamsReference; } inline void flushAll(void) { @@ -2405,7 +2420,7 @@ class RegisteredLoggers : public base::utils::Registry { private: LogBuilderPtr m_defaultLogBuilder; Configurations m_defaultConfigurations; - base::LogStreamsReferenceMap m_logStreamsReference; + base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr; std::unordered_map m_loggerRegistrationCallbacks; friend class el::base::Storage; @@ -2859,7 +2874,7 @@ class IterableStack : public IterableContainer, public std::stack< // Log message builder class MessageBuilder { public: - MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {} + MessageBuilder(void) : m_logger(nullptr), m_containerLogSeparator(ELPP_LITERAL("")) {} void initialize(Logger* logger); # define ELPP_SIMPLE_LOG(LOG_TYPE)\ @@ -3047,7 +3062,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s m_logger->stream() << ELPP_LITERAL(", "); operator << (static_cast(map_.value(*begin))); m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL("")); } if (begin != end) { m_logger->stream() << ELPP_LITERAL("..."); @@ -3073,7 +3088,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s m_logger->stream() << ELPP_LITERAL(", "); operator << (static_cast(hash_.value(*begin))); m_logger->stream() << ELPP_LITERAL(")"); - m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL("")); + m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL("")); } if (begin != end) { m_logger->stream() << ELPP_LITERAL("..."); @@ -3104,7 +3119,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s /// have begin() and end() methods that return respective iterators /// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets /// @param SizeMethod Method used to get size of container. - /// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro + /// @param ElementInstance Instance of element to be fed out. Instance name is "elem". See WXELPP_ENABLED macro /// for an example usage #define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \ el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\ @@ -3146,14 +3161,14 @@ ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_L #undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG private: Logger* m_logger; - const base::type::char_t* m_containerLogSeperator; + const base::type::char_t* m_containerLogSeparator; template MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) { m_logger->stream() << ELPP_LITERAL("["); for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) { operator << (*begin_); - m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL("")); + m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeparator : ELPP_LITERAL("")); } if (begin_ != end_) { m_logger->stream() << ELPP_LITERAL("..."); @@ -3260,7 +3275,7 @@ class PErrorWriter : public base::Writer { // Logging from Logger class. Why this is here? Because we have Storage and Writer class available #if ELPP_VARIADIC_TEMPLATES_SUPPORTED template -void Logger::log_(Level level, int vlevel, const char* s, const T& value, const Args&... args) { +void Logger::log_(Level varlevel, int vlevel, const char* s, const T& value, const Args&... args) { base::MessageBuilder b; b.initialize(this); while (*s) { @@ -3271,7 +3286,7 @@ void Logger::log_(Level level, int vlevel, const char* s, const T& value, const if (*(s + 1) == base::consts::kFormatSpecifierCharValue) { ++s; b << value; - log_(level, vlevel, ++s, args...); + log_(varlevel, vlevel, ++s, args...); return; } } @@ -3281,28 +3296,28 @@ void Logger::log_(Level level, int vlevel, const char* s, const T& value, const ELPP_INTERNAL_ERROR("Too many arguments provided. Unable to handle. Please provide more format specifiers", false); } template -void Logger::log_(Level level, int vlevel, const T& log) { - if (level == Level::Verbose) { - if (ELPP->vRegistry()->allowed(vlevel, __FILE__)) { +void Logger::log_(Level varlevel, int vlevel, const T& vlog) { + if (varlevel == Level::Verbose) { + if (ELPP->vRegistry()->allowed(static_cast(vlevel), __FILE__)) { base::Writer(Level::Verbose, "FILE", 0, "FUNCTION", - base::DispatchAction::NormalLog, vlevel).construct(this, false) << log; + base::DispatchAction::NormalLog, vlevel).construct(this, false) << vlog; } else { stream().str(ELPP_LITERAL("")); releaseLock(); } } else { - base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log; + base::Writer(varlevel, "FILE", 0, "FUNCTION").construct(this, false) << vlog; } } template -inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) { +inline void Logger::log(Level varlevel, const char* s, const T& value, const Args&... args) { acquireLock(); // released in Writer! - log_(level, 0, s, value, args...); + log_(varlevel, 0, s, value, args...); } template -inline void Logger::log(Level level, const T& log) { +inline void Logger::log(Level varlevel, const T& vlog) { acquireLock(); // released in Writer! - log_(level, 0, log); + log_(varlevel, 0, vlog); } # if ELPP_VERBOSE_LOG template @@ -3311,9 +3326,9 @@ inline void Logger::verbose(int vlevel, const char* s, const T& value, const Arg log_(el::Level::Verbose, vlevel, s, value, args...); } template -inline void Logger::verbose(int vlevel, const T& log) { +inline void Logger::verbose(int vlevel, const T& vlog) { acquireLock(); // released in Writer! - log_(el::Level::Verbose, vlevel, log); + log_(el::Level::Verbose, vlevel, vlog); } # else template @@ -3632,6 +3647,7 @@ class SysLogInitializer { public: SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) { #if defined(ELPP_SYSLOG) + (void)base::consts::kSysLogLoggerId; openlog(processIdent, options, facility); #else ELPP_UNUSED(processIdent); @@ -3824,7 +3840,7 @@ class Loggers : base::StaticClass { /// @brief Returns current default static const Configurations* defaultConfigurations(void); /// @brief Returns log stream reference pointer if needed by user - static const base::LogStreamsReferenceMap* logStreamsReference(void); + static const base::LogStreamsReferenceMapPtr logStreamsReference(void); /// @brief Default typed configuration based on existing defaultConf static base::TypedConfigurations defaultTypedConfigurations(void); /// @brief Populates all logger IDs in current repository. @@ -3835,7 +3851,7 @@ class Loggers : base::StaticClass { /// @brief Configures loggers using command line arg. Ensure you have already set command line args, /// @return False if invalid argument or argument with no value provided, true if attempted to configure logger. /// If true is returned that does not mean it has been configured successfully, it only means that it - /// has attempeted to configure logger using configuration file provided in argument + /// has attempted to configure logger using configuration file provided in argument static bool configureFromArg(const char* argKey); /// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered static void flushAll(void);