Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/logging.cpp185
-rw-r--r--base/logging.hpp110
-rw-r--r--qt/CMakeLists.txt2
-rw-r--r--qt/main.cpp50
-rw-r--r--qt/qt.pro4
5 files changed, 231 insertions, 120 deletions
diff --git a/base/logging.cpp b/base/logging.cpp
index 0f1e002a9b..1ceb63e2f7 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -1,5 +1,5 @@
-#include "base/assert.hpp"
#include "base/logging.hpp"
+#include "base/assert.hpp"
#include "base/macros.hpp"
#include "base/mutex.hpp"
#include "base/thread.hpp"
@@ -8,94 +8,139 @@
#include "std/target_os.hpp"
//#include "std/windows.hpp"
+#include <algorithm>
#include <iomanip>
#include <iostream>
+#include <iterator>
#include <mutex>
#include <sstream>
+#include <vector>
namespace my
{
- class LogHelper
- {
- int m_threadsCount;
- std::map<threads::ThreadID, int> m_threadID;
-
- int GetThreadID()
- {
- int & id = m_threadID[threads::GetCurrentThreadID()];
- if (id == 0)
- id = ++m_threadsCount;
- return id;
- }
-
- my::Timer m_timer;
-
- char const * m_names[5];
- size_t m_lens[5];
-
- public:
- LogHelper() : m_threadsCount(0)
- {
- m_names[0] = "DEBUG"; m_lens[0] = 5;
- m_names[1] = "INFO"; m_lens[1] = 4;
- m_names[2] = "WARNING"; m_lens[2] = 7;
- m_names[3] = "ERROR"; m_lens[3] = 5;
- m_names[4] = "CRITICAL"; m_lens[4] = 8;
- }
-
- void WriteProlog(std::ostream & s, LogLevel level)
- {
- s << "LOG";
-
- s << " TID(" << GetThreadID() << ")";
- s << " " << m_names[level];
-
- double const sec = m_timer.ElapsedSeconds();
- s << " " << std::setfill(' ') << std::setw(static_cast<int>(16 - m_lens[level])) << sec << " ";
- }
- };
-
- std::mutex g_logMutex;
-
- void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg)
- {
- std::lock_guard<std::mutex> lock(g_logMutex);
+std::string ToString(LogLevel level)
+{
+ auto const & names = GetLogLevelNames();
+ CHECK_LESS(level, names.size(), ());
+ return names[level];
+}
+
+bool FromString(std::string const & s, LogLevel & level)
+{
+ auto const & names = GetLogLevelNames();
+ auto it = std::find(names.begin(), names.end(), s);
+ if (it == names.end())
+ return false;
+ level = static_cast<LogLevel>(std::distance(names.begin(), it));
+ return true;
+}
+
+std::vector<std::string> const & GetLogLevelNames()
+{
+ static std::vector<std::string> const kNames = {
+ {"DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"}};
+ return kNames;
+}
- static LogHelper logger;
+class LogHelper
+{
+ int m_threadsCount;
+ std::map<threads::ThreadID, int> m_threadID;
+
+ int GetThreadID()
+ {
+ int & id = m_threadID[threads::GetCurrentThreadID()];
+ if (id == 0)
+ id = ++m_threadsCount;
+ return id;
+ }
- std::ostringstream out;
- logger.WriteProlog(out, level);
+ my::Timer m_timer;
- out << DebugPrint(srcPoint) << msg << std::endl;
- std::cerr << out.str();
+ char const * m_names[5];
+ size_t m_lens[5];
- CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level));
+public:
+ LogHelper() : m_threadsCount(0)
+ {
+ m_names[0] = "DEBUG";
+ m_lens[0] = 5;
+ m_names[1] = "INFO";
+ m_lens[1] = 4;
+ m_names[2] = "WARNING";
+ m_lens[2] = 7;
+ m_names[3] = "ERROR";
+ m_lens[3] = 5;
+ m_names[4] = "CRITICAL";
+ m_lens[4] = 8;
}
- void LogMessageTests(LogLevel level, SrcPoint const &, std::string const & msg)
+ void WriteProlog(std::ostream & s, LogLevel level)
{
- std::lock_guard<std::mutex> lock(g_logMutex);
+ s << "LOG";
- std::ostringstream out;
- out << msg << std::endl;
- std::cerr << out.str();
+ s << " TID(" << GetThreadID() << ")";
+ s << " " << m_names[level];
- CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level));
+ double const sec = m_timer.ElapsedSeconds();
+ s << " " << std::setfill(' ') << std::setw(static_cast<int>(16 - m_lens[level])) << sec << " ";
}
+};
- LogMessageFn LogMessage = &LogMessageDefault;
+std::mutex g_logMutex;
- LogMessageFn SetLogMessageFn(LogMessageFn fn)
- {
- std::swap(LogMessage, fn);
- return fn;
- }
+void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg)
+{
+ std::lock_guard<std::mutex> lock(g_logMutex);
-#ifdef DEBUG
- TLogLevel g_LogLevel = {LDEBUG};
- TLogLevel g_LogAbortLevel = {LERROR};
+ static LogHelper logger;
+
+ std::ostringstream out;
+ logger.WriteProlog(out, level);
+
+ out << DebugPrint(srcPoint) << msg << std::endl;
+ std::cerr << out.str();
+
+ CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level));
+}
+
+void LogMessageTests(LogLevel level, SrcPoint const &, std::string const & msg)
+{
+ std::lock_guard<std::mutex> lock(g_logMutex);
+
+ std::ostringstream out;
+ out << msg << std::endl;
+ std::cerr << out.str();
+
+ CHECK_LESS(level, g_LogAbortLevel, ("Abort. Log level is too serious", level));
+}
+
+LogMessageFn LogMessage = &LogMessageDefault;
+
+LogMessageFn SetLogMessageFn(LogMessageFn fn)
+{
+ std::swap(LogMessage, fn);
+ return fn;
+}
+
+LogLevel GetDefaultLogLevel()
+{
+#if defined(DEBUG)
+ return LDEBUG;
#else
- TLogLevel g_LogLevel = {LINFO};
- TLogLevel g_LogAbortLevel = {LCRITICAL};
-#endif
+ return LINFO;
+#endif // defined(DEBUG)
}
+
+LogLevel GetDefaultLogAbortLevel()
+{
+#if defined(DEBUG)
+ return LERROR;
+#else
+ return LCRITICAL;
+#endif // defined(DEBUG)
+}
+
+TLogLevel g_LogLevel = {GetDefaultLogLevel()};
+TLogLevel g_LogAbortLevel = {GetDefaultLogAbortLevel()};
+} // namespace my
diff --git a/base/logging.hpp b/base/logging.hpp
index 678a1b1685..fc9fd1d9f0 100644
--- a/base/logging.hpp
+++ b/base/logging.hpp
@@ -5,54 +5,62 @@
#include "base/src_point.hpp"
#include <atomic>
+#include <string>
namespace my
{
- enum LogLevel
- {
- LDEBUG,
- LINFO,
- LWARNING,
- LERROR,
- LCRITICAL
- };
+enum LogLevel
+{
+ LDEBUG,
+ LINFO,
+ LWARNING,
+ LERROR,
+ LCRITICAL
+};
- using TLogLevel = std::atomic<LogLevel>;
- typedef void (*LogMessageFn)(LogLevel level, SrcPoint const &, std::string const &);
+std::string ToString(LogLevel level);
+bool FromString(std::string const & s, LogLevel & level);
+std::vector<std::string> const & GetLogLevelNames();
- extern LogMessageFn LogMessage;
- extern TLogLevel g_LogLevel;
- extern TLogLevel g_LogAbortLevel;
+using TLogLevel = std::atomic<LogLevel>;
+typedef void (*LogMessageFn)(LogLevel level, SrcPoint const &, std::string const &);
- /// @return Pointer to previous message function.
- LogMessageFn SetLogMessageFn(LogMessageFn fn);
+LogLevel GetDefaultLogLevel();
+LogLevel GetDefaultLogAbortLevel();
- void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg);
- void LogMessageTests(LogLevel level, SrcPoint const & srcPoint, std::string const & msg);
+extern LogMessageFn LogMessage;
+extern TLogLevel g_LogLevel;
+extern TLogLevel g_LogAbortLevel;
- /// Scope Guard to temporarily suppress specific log level, for example, in unit tests:
- /// ...
- /// {
- /// LogLevelSuppressor onlyLERRORAndLCriticalLogsAreEnabled;
- /// TEST(SomeFunctionWhichHasDebugOrInfoOrWarningLogs(), ());
- /// }
- struct ScopedLogLevelChanger
- {
- LogLevel m_old = g_LogLevel;
- ScopedLogLevelChanger(LogLevel temporaryLogLevel = LERROR) { g_LogLevel = temporaryLogLevel; }
- ~ScopedLogLevelChanger() { g_LogLevel = m_old; }
- };
+/// @return Pointer to previous message function.
+LogMessageFn SetLogMessageFn(LogMessageFn fn);
+
+void LogMessageDefault(LogLevel level, SrcPoint const & srcPoint, std::string const & msg);
+void LogMessageTests(LogLevel level, SrcPoint const & srcPoint, std::string const & msg);
- struct ScopedLogAbortLevelChanger
+/// Scope Guard to temporarily suppress specific log level, for example, in unit tests:
+/// ...
+/// {
+/// LogLevelSuppressor onlyLERRORAndLCriticalLogsAreEnabled;
+/// TEST(SomeFunctionWhichHasDebugOrInfoOrWarningLogs(), ());
+/// }
+struct ScopedLogLevelChanger
+{
+ LogLevel m_old = g_LogLevel;
+ ScopedLogLevelChanger(LogLevel temporaryLogLevel = LERROR) { g_LogLevel = temporaryLogLevel; }
+ ~ScopedLogLevelChanger() { g_LogLevel = m_old; }
+};
+
+struct ScopedLogAbortLevelChanger
+{
+ LogLevel m_old = g_LogAbortLevel;
+ ScopedLogAbortLevelChanger(LogLevel temporaryLogAbortLevel = LCRITICAL)
{
- LogLevel m_old = g_LogAbortLevel;
- ScopedLogAbortLevelChanger(LogLevel temporaryLogAbortLevel = LCRITICAL)
- {
- g_LogAbortLevel = temporaryLogAbortLevel;
- }
- ~ScopedLogAbortLevelChanger() { g_LogAbortLevel = m_old; }
- };
-}
+ g_LogAbortLevel = temporaryLogAbortLevel;
+ }
+ ~ScopedLogAbortLevelChanger() { g_LogAbortLevel = m_old; }
+};
+} // namespace my
using ::my::LDEBUG;
using ::my::LINFO;
@@ -62,9 +70,27 @@ using ::my::LCRITICAL;
// Logging macro.
// Example usage: LOG(LINFO, (Calc(), m_Var, "Some string constant"));
-#define LOG(level, msg) do { if ((level) < ::my::g_LogLevel) {} \
- else { ::my::LogMessage(level, SRC(), ::my::impl::Message msg);} } while (false)
+#define LOG(level, msg) \
+ do \
+ { \
+ if ((level) < ::my::g_LogLevel) \
+ { \
+ } \
+ else \
+ { \
+ ::my::LogMessage(level, SRC(), ::my::impl::Message msg); \
+ } \
+ } while (false)
// Logging macro with short info (without entry point)
-#define LOG_SHORT(level, msg) do { if ((level) < ::my::g_LogLevel) {} \
- else { ::my::LogMessage(level, my::SrcPoint(), ::my::impl::Message msg);} } while (false)
+#define LOG_SHORT(level, msg) \
+ do \
+ { \
+ if ((level) < ::my::g_LogLevel) \
+ { \
+ } \
+ else \
+ { \
+ ::my::LogMessage(level, my::SrcPoint(), ::my::impl::Message msg); \
+ } \
+ } while (false)
diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt
index 0e33d333dc..6471c3970b 100644
--- a/qt/CMakeLists.txt
+++ b/qt/CMakeLists.txt
@@ -14,6 +14,7 @@ execute_process(
include_directories(
${OMIM_ROOT}/3party/glm
+ ${OMIM_ROOT}/3party/gflags/src
${CMAKE_CURRENT_BINARY_DIR}
)
@@ -74,6 +75,7 @@ omim_link_libraries(
base
freetype
expat
+ gflags
icu
jansson
protobuf
diff --git a/qt/main.cpp b/qt/main.cpp
index 3182646158..0cf3066611 100644
--- a/qt/main.cpp
+++ b/qt/main.cpp
@@ -13,8 +13,10 @@
#include "std/cstdio.hpp"
#include "std/cstdlib.hpp"
+#include "std/sstream.hpp"
#include "3party/Alohalytics/src/alohalytics.h"
+#include "3party/gflags/src/gflags/gflags.h"
#include <QtCore/QDir>
@@ -24,17 +26,44 @@
#include <QtWidgets/QApplication>
#endif
+DEFINE_string(log_abort_level, my::ToString(my::GetDefaultLogAbortLevel()),
+ "Log messages severity that causes termination.");
+
namespace
{
- class FinalizeBase
+bool ValidateLogAbortLevel(char const * flagname, string const & value)
+{
+ my::LogLevel level;
+ if (!my::FromString(value, level))
{
- public:
- ~FinalizeBase()
+ ostringstream os;
+ auto const & names = my::GetLogLevelNames();
+ for (size_t i = 0; i < names.size(); ++i)
{
- // optional - clean allocated data in protobuf library
- // useful when using memory and resource leak utilites
- //google::protobuf::ShutdownProtobufLibrary();
+ if (i != 0)
+ os << ", ";
+ os << names[i];
}
+
+ printf("Invalid value for --%s: %s, must be one of: %s\n", flagname, value.c_str(),
+ os.str().c_str());
+ return false;
+ }
+ return true;
+}
+
+bool const g_logAbortLevelDummy =
+ google::RegisterFlagValidator(&FLAGS_log_abort_level, &ValidateLogAbortLevel);
+
+class FinalizeBase
+{
+public:
+ ~FinalizeBase()
+ {
+ // optional - clean allocated data in protobuf library
+ // useful when using memory and resource leak utilites
+ // google::protobuf::ShutdownProtobufLibrary();
+ }
};
#if defined(OMIM_OS_WINDOWS) //&& defined(PROFILER_COMMON)
@@ -59,10 +88,17 @@ namespace
#else
typedef FinalizeBase InitializeFinalize;
#endif
-}
+} // namespace
int main(int argc, char * argv[])
{
+ google::SetUsageMessage("Desktop application.");
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ my::LogLevel level;
+ CHECK(my::FromString(FLAGS_log_abort_level, level), ());
+ my::g_LogAbortLevel = level;
+
Q_INIT_RESOURCE(resources_common);
// Our double parsing code (base/string_utils.hpp) needs dots as a floating point delimiters, not commas.
diff --git a/qt/qt.pro b/qt/qt.pro
index a5188f9133..5a46cbcb19 100644
--- a/qt/qt.pro
+++ b/qt/qt.pro
@@ -3,13 +3,15 @@ ROOT_DIR = ..
DEPENDENCIES = qt_common map drape_frontend openlr routing search storage tracking traffic routing_common \
indexer drape partners_api local_ads platform editor geometry \
- coding base freetype expat jansson protobuf osrm stats_client \
+ coding base freetype expat gflags jansson protobuf osrm stats_client \
minizip succinct pugixml oauthcpp stb_image sdf_image icu
DEPENDENCIES += opening_hours \
include($$ROOT_DIR/common.pri)
+INCLUDEPATH *= $$ROOT_DIR/3party/gflags/src
+
TARGET = MAPS.ME
TEMPLATE = app
CONFIG += warn_on