blob: 461a22d4f20a8958a6b646bc6bc4dbf31176e1d4 [file] [log] [blame]
Ratan Guptaed123a32017-06-15 09:07:31 +05301#pragma once
2
Manojkiran Edaa879baa2020-06-13 14:39:08 +05303#include <filesystem>
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -07004#include <functional>
William A. Kennington III150753f2022-08-05 15:20:54 -07005#include <optional>
William A. Kennington III0dd09372022-08-18 14:57:07 -07006#include <ostream>
Patrick Venture189d44e2018-07-09 12:30:59 -07007#include <string>
William A. Kennington III25511a12022-08-04 16:32:28 -07008#include <string_view>
Ratan Guptaed123a32017-06-15 09:07:31 +05309#include <unordered_map>
10#include <vector>
Ratan Guptaed123a32017-06-15 09:07:31 +053011
12namespace phosphor
13{
14namespace network
15{
16namespace config
17{
18
William A. Kennington III150753f2022-08-05 15:20:54 -070019/** @brief Compare in (case insensitive) vs expected (sensitive) */
20bool icaseeq(std::string_view in, std::string_view expected) noexcept;
21/** @brief Turns a systemd bool string into a c++ bool */
22std::optional<bool> parseBool(std::string_view in) noexcept;
23
William A. Kennington IIIa520a392022-08-08 12:17:34 -070024namespace fs = std::filesystem;
25
26fs::path pathForIntfConf(const fs::path& dir, std::string_view intf);
27fs::path pathForIntfDev(const fs::path& dir, std::string_view intf);
28
William A. Kennington III0dd09372022-08-18 14:57:07 -070029template <typename T, typename Check>
30class Checked
31{
32 public:
33 struct unchecked
34 {
35 };
36
37 template <typename... Args>
38 inline constexpr Checked(Args&&... args) :
39 t(conCheck(std::forward<Args>(args)...))
40 {
41 }
42
43 template <typename... Args>
44 inline constexpr Checked(unchecked, Args&&... args) :
45 t(std::forward<Args>(args)...)
46 {
47 }
48
49 inline const T& get() const noexcept
50 {
51 return t;
52 }
53
54 inline constexpr operator const T&() const noexcept
55 {
56 return t;
57 }
58
59 inline constexpr bool operator==(const auto& rhs) const
60 {
61 return t == rhs;
62 }
63
64 private:
65 T t;
66
67 template <typename... Args>
68 inline static constexpr T conCheck(Args&&... args)
69 {
70 T t(std::forward<Args>(args)...);
71 Check{}(t);
72 return t;
73 }
74};
75
76template <typename T, typename Check>
77inline constexpr bool operator==(const auto& lhs, const Checked<T, Check>& rhs)
78{
79 return lhs == rhs.get();
80}
81
82template <typename T, typename Check>
83inline constexpr std::ostream& operator<<(std::ostream& s,
84 const Checked<T, Check>& rhs)
85{
86 return s << rhs.get();
87}
88
89struct KeyCheck
90{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070091 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070092};
93struct SectionCheck
94{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070095 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070096};
97struct ValueCheck
98{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070099 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -0700100};
101
William A. Kennington III25511a12022-08-04 16:32:28 -0700102struct string_hash : public std::hash<std::string_view>
103{
104 using is_transparent = void;
William A. Kennington III0dd09372022-08-18 14:57:07 -0700105
106 template <typename T>
107 inline size_t operator()(const Checked<std::string, T>& t) const
108 {
109 return static_cast<const std::hash<std::string_view>&>(*this)(t.get());
110 }
111 template <typename T>
112 inline size_t operator()(const T& t) const
113 {
114 return static_cast<const std::hash<std::string_view>&>(*this)(t);
115 }
William A. Kennington III25511a12022-08-04 16:32:28 -0700116};
117
William A. Kennington III0dd09372022-08-18 14:57:07 -0700118using Key = Checked<std::string, KeyCheck>;
119using Section = Checked<std::string, SectionCheck>;
120using Value = Checked<std::string, ValueCheck>;
William A. Kennington III25511a12022-08-04 16:32:28 -0700121using ValueList = std::vector<Value>;
122using KeyValuesMap =
123 std::unordered_map<Key, ValueList, string_hash, std::equal_to<>>;
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700124using KeyValuesMapList = std::vector<KeyValuesMap>;
125using SectionMapInt =
126 std::unordered_map<Section, KeyValuesMapList, string_hash, std::equal_to<>>;
127
128class SectionMap : public SectionMapInt
129{
130 public:
131 const std::string* getLastValueString(std::string_view section,
132 std::string_view key) const noexcept;
133 inline auto getValues(std::string_view section, std::string_view key,
134 auto&& conv) const
135 {
136 std::vector<std::invoke_result_t<decltype(conv), const Value&>> values;
137 auto sit = find(section);
138 if (sit == end())
139 {
140 return values;
141 }
142 for (const auto& secv : sit->second)
143 {
144 auto kit = secv.find(key);
145 if (kit == secv.end())
146 {
147 continue;
148 }
149 for (auto v : kit->second)
150 {
151 values.push_back(conv(v));
152 }
153 }
154 return values;
155 }
156 std::vector<std::string> getValueStrings(std::string_view section,
157 std::string_view key) const;
158};
Ratan Guptac27170a2017-11-22 15:44:42 +0530159
Ratan Guptaed123a32017-06-15 09:07:31 +0530160class Parser
161{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500162 public:
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700163 SectionMap map;
164
Gunnar Mills57d9c502018-09-14 14:42:34 -0500165 Parser() = default;
Ratan Guptaed123a32017-06-15 09:07:31 +0530166
Gunnar Mills57d9c502018-09-14 14:42:34 -0500167 /** @brief Constructor
William A. Kennington III25511a12022-08-04 16:32:28 -0700168 * @param[in] filename - Absolute path of the file which will be parsed.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500169 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700170 Parser(const fs::path& filename);
Ratan Guptaed123a32017-06-15 09:07:31 +0530171
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700172 /** @brief Determine if there were warnings parsing the file
173 * @return The number of parsing issues in the file
174 */
175 inline const std::vector<std::string>& getWarnings() const noexcept
176 {
177 return warnings;
178 }
179
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700180 /** @brief Get the filename last parsed successfully
181 * @return file path
182 */
183 inline const fs::path& getFilename() const noexcept
184 {
185 return filename;
186 }
187
Gunnar Mills57d9c502018-09-14 14:42:34 -0500188 /** @brief Set the file name and parse it.
William A. Kennington III25511a12022-08-04 16:32:28 -0700189 * @param[in] filename - Absolute path of the file.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500190 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700191 void setFile(const fs::path& filename);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500192
William A. Kennington III409f1a62022-08-11 15:44:37 -0700193 /** @brief Write the current config to a file */
194 void writeFile() const;
195 void writeFile(const fs::path& filename);
196
Gunnar Mills57d9c502018-09-14 14:42:34 -0500197 private:
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700198 fs::path filename;
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700199 std::vector<std::string> warnings;
Ratan Guptaed123a32017-06-15 09:07:31 +0530200};
201
Gunnar Mills57d9c502018-09-14 14:42:34 -0500202} // namespace config
203} // namespace network
204} // namespace phosphor