/src/spdlog/include/spdlog/cfg/helpers-inl.h
Line | Count | Source |
1 | | // Copyright(c) 2015-present, Gabi Melman & spdlog contributors. |
2 | | // Distributed under the MIT License (http://opensource.org/licenses/MIT) |
3 | | |
4 | | #pragma once |
5 | | |
6 | | #ifndef SPDLOG_HEADER_ONLY |
7 | | #include <spdlog/cfg/helpers.h> |
8 | | #endif |
9 | | |
10 | | #include <spdlog/details/os.h> |
11 | | #include <spdlog/details/registry.h> |
12 | | |
13 | | #include <algorithm> |
14 | | #include <sstream> |
15 | | #include <string> |
16 | | #include <utility> |
17 | | |
18 | | SPDLOG_NAMESPACE_BEGIN |
19 | | namespace cfg { |
20 | | namespace helpers { |
21 | | |
22 | | // inplace convert to lowercase |
23 | 71.0k | inline std::string &to_lower_(std::string &str) { |
24 | 2.35M | std::transform(str.begin(), str.end(), str.begin(), [](char ch) { |
25 | 2.35M | return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); |
26 | 2.35M | }); |
27 | 71.0k | return str; |
28 | 71.0k | } |
29 | | |
30 | | // inplace trim spaces |
31 | 206k | inline std::string &trim_(std::string &str) { |
32 | 206k | const char *spaces = " \n\r\t"; |
33 | 206k | str.erase(str.find_last_not_of(spaces) + 1); |
34 | 206k | str.erase(0, str.find_first_not_of(spaces)); |
35 | 206k | return str; |
36 | 206k | } |
37 | | |
38 | | // return (name,value) trimmed pair from the given "name = value" string. |
39 | | // return empty string on missing parts |
40 | | // "key=val" => ("key", "val") |
41 | | // " key = val " => ("key", "val") |
42 | | // "key=" => ("key", "") |
43 | | // "val" => ("", "val") |
44 | | |
45 | 103k | inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str) { |
46 | 103k | auto n = str.find(sep); |
47 | 103k | std::string k, v; |
48 | 103k | if (n == std::string::npos) { |
49 | 16.6k | v = str; |
50 | 86.6k | } else { |
51 | 86.6k | k = str.substr(0, n); |
52 | 86.6k | v = str.substr(n + 1); |
53 | 86.6k | } |
54 | 103k | return std::make_pair(trim_(k), trim_(v)); |
55 | 103k | } |
56 | | |
57 | | // return vector of key/value pairs from a sequence of "K1=V1,K2=V2,.." |
58 | | // "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...} |
59 | 7.47k | inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str) { |
60 | 7.47k | std::string token; |
61 | 7.47k | std::istringstream token_stream(str); |
62 | 7.47k | std::unordered_map<std::string, std::string> rv{}; |
63 | 117k | while (std::getline(token_stream, token, ',')) { |
64 | 110k | if (token.empty()) { |
65 | 7.19k | continue; |
66 | 7.19k | } |
67 | 103k | auto kv = extract_kv_('=', token); |
68 | 103k | rv[kv.first] = kv.second; |
69 | 103k | } |
70 | 7.47k | return rv; |
71 | 7.47k | } |
72 | | |
73 | 7.88k | SPDLOG_INLINE void load_levels(const std::string &levels_spec) { |
74 | 7.88k | if (levels_spec.empty() || levels_spec.size() >= 32768) { |
75 | 408 | return; |
76 | 408 | } |
77 | | |
78 | 7.47k | auto key_vals = extract_key_vals_(levels_spec); |
79 | 7.47k | std::unordered_map<std::string, level::level_enum> levels; |
80 | 7.47k | level::level_enum global_level = level::info; |
81 | 7.47k | bool global_level_found = false; |
82 | | |
83 | 71.0k | for (auto &name_level : key_vals) { |
84 | 71.0k | const auto &logger_name = name_level.first; |
85 | 71.0k | const auto &level_name = to_lower_(name_level.second); |
86 | 71.0k | const auto level = level::from_str(level_name); |
87 | | // ignore unrecognized level names |
88 | 71.0k | if (level == level::off && level_name != "off") { |
89 | 26.8k | continue; |
90 | 26.8k | } |
91 | 44.1k | if (logger_name.empty()) // no logger name indicates global level |
92 | 555 | { |
93 | 555 | global_level_found = true; |
94 | 555 | global_level = level; |
95 | 43.6k | } else { |
96 | 43.6k | levels[logger_name] = level; |
97 | 43.6k | } |
98 | 44.1k | } |
99 | | |
100 | 7.47k | details::registry::instance().set_levels(std::move(levels), |
101 | 7.47k | global_level_found ? &global_level : nullptr); |
102 | 7.47k | } |
103 | | |
104 | | } // namespace helpers |
105 | | } // namespace cfg |
106 | | SPDLOG_NAMESPACE_END |