blob: 2d0bb1f9b2c6e7476e08b28269cc8081e4096d78 [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
Patrick Williams89d734b2023-05-10 07:50:25 -050034 {};
William A. Kennington III0dd09372022-08-18 14:57:07 -070035
36 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070037 constexpr Checked(Args&&... args) : t(conCheck(std::forward<Args>(args)...))
Patrick Williams89d734b2023-05-10 07:50:25 -050038 {}
William A. Kennington III0dd09372022-08-18 14:57:07 -070039
40 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070041 constexpr Checked(unchecked, Args&&... args) :
William A. Kennington III0dd09372022-08-18 14:57:07 -070042 t(std::forward<Args>(args)...)
Patrick Williams89d734b2023-05-10 07:50:25 -050043 {}
William A. Kennington III0dd09372022-08-18 14:57:07 -070044
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070045 constexpr const T& get() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070046 {
47 return t;
48 }
49
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070050 constexpr operator const T&() const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070051 {
52 return t;
53 }
54
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070055 constexpr bool operator==(const auto& rhs) const noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070056 {
57 return t == rhs;
58 }
59
60 private:
61 T t;
62
63 template <typename... Args>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070064 static constexpr T conCheck(Args&&... args)
William A. Kennington III0dd09372022-08-18 14:57:07 -070065 {
66 T t(std::forward<Args>(args)...);
67 Check{}(t);
68 return t;
69 }
70};
71
72template <typename T, typename Check>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070073constexpr bool operator==(const auto& lhs,
74 const Checked<T, Check>& rhs) noexcept
William A. Kennington III0dd09372022-08-18 14:57:07 -070075{
76 return lhs == rhs.get();
77}
78
79template <typename T, typename Check>
William A. Kennington IIIf55b7d82022-10-25 14:21:46 -070080inline std::ostream& operator<<(std::ostream& s, const Checked<T, Check>& rhs)
William A. Kennington III0dd09372022-08-18 14:57:07 -070081{
82 return s << rhs.get();
83}
84
85struct KeyCheck
86{
William A. Kennington IIIbe3bd2f2022-10-11 14:11:27 -070087 void operator()(std::string_view s);
William A. Kennington III0dd09372022-08-18 14:57:07 -070088};
89struct SectionCheck
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 ValueCheck
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};
97
William A. Kennington III25511a12022-08-04 16:32:28 -070098struct string_hash : public std::hash<std::string_view>
99{
100 using is_transparent = void;
William A. Kennington III0dd09372022-08-18 14:57:07 -0700101
102 template <typename T>
103 inline size_t operator()(const Checked<std::string, T>& t) const
104 {
105 return static_cast<const std::hash<std::string_view>&>(*this)(t.get());
106 }
107 template <typename T>
108 inline size_t operator()(const T& t) const
109 {
110 return static_cast<const std::hash<std::string_view>&>(*this)(t);
111 }
William A. Kennington III25511a12022-08-04 16:32:28 -0700112};
113
William A. Kennington III0dd09372022-08-18 14:57:07 -0700114using Key = Checked<std::string, KeyCheck>;
115using Section = Checked<std::string, SectionCheck>;
116using Value = Checked<std::string, ValueCheck>;
William A. Kennington III25511a12022-08-04 16:32:28 -0700117using ValueList = std::vector<Value>;
118using KeyValuesMap =
119 std::unordered_map<Key, ValueList, string_hash, std::equal_to<>>;
William A. Kennington IIIe21a5cf2022-08-09 12:19:14 -0700120using KeyValuesMapList = std::vector<KeyValuesMap>;
121using SectionMapInt =
122 std::unordered_map<Section, KeyValuesMapList, string_hash, std::equal_to<>>;
123
124class SectionMap : public SectionMapInt
125{
126 public:
127 const std::string* getLastValueString(std::string_view section,
128 std::string_view key) const noexcept;
129 inline auto getValues(std::string_view section, std::string_view key,
130 auto&& conv) const
131 {
132 std::vector<std::invoke_result_t<decltype(conv), const Value&>> values;
133 auto sit = find(section);
134 if (sit == end())
135 {
136 return values;
137 }
138 for (const auto& secv : sit->second)
139 {
140 auto kit = secv.find(key);
141 if (kit == secv.end())
142 {
143 continue;
144 }
145 for (auto v : kit->second)
146 {
147 values.push_back(conv(v));
148 }
149 }
150 return values;
151 }
152 std::vector<std::string> getValueStrings(std::string_view section,
153 std::string_view key) const;
154};
Ratan Guptac27170a2017-11-22 15:44:42 +0530155
Ratan Guptaed123a32017-06-15 09:07:31 +0530156class Parser
157{
Gunnar Mills57d9c502018-09-14 14:42:34 -0500158 public:
William A. Kennington III34bb3e22022-08-18 15:17:22 -0700159 SectionMap map;
160
Gunnar Mills57d9c502018-09-14 14:42:34 -0500161 Parser() = default;
Ratan Guptaed123a32017-06-15 09:07:31 +0530162
Gunnar Mills57d9c502018-09-14 14:42:34 -0500163 /** @brief Constructor
William A. Kennington III25511a12022-08-04 16:32:28 -0700164 * @param[in] filename - Absolute path of the file which will be parsed.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500165 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700166 Parser(const fs::path& filename);
Ratan Guptaed123a32017-06-15 09:07:31 +0530167
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800168 /** @brief Determine if the loaded file exists */
169 inline bool getFileExists() const noexcept
170 {
171 return fileExists;
172 }
173
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700174 /** @brief Determine if there were warnings parsing the file
175 * @return The number of parsing issues in the file
176 */
177 inline const std::vector<std::string>& getWarnings() const noexcept
178 {
179 return warnings;
180 }
181
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700182 /** @brief Get the filename last parsed successfully
183 * @return file path
184 */
185 inline const fs::path& getFilename() const noexcept
186 {
187 return filename;
188 }
189
Gunnar Mills57d9c502018-09-14 14:42:34 -0500190 /** @brief Set the file name and parse it.
William A. Kennington III25511a12022-08-04 16:32:28 -0700191 * @param[in] filename - Absolute path of the file.
Gunnar Mills57d9c502018-09-14 14:42:34 -0500192 */
William A. Kennington III25511a12022-08-04 16:32:28 -0700193 void setFile(const fs::path& filename);
Gunnar Mills57d9c502018-09-14 14:42:34 -0500194
William A. Kennington III409f1a62022-08-11 15:44:37 -0700195 /** @brief Write the current config to a file */
196 void writeFile() const;
197 void writeFile(const fs::path& filename);
198
Gunnar Mills57d9c502018-09-14 14:42:34 -0500199 private:
William A. Kennington III301e8ad2022-11-15 15:45:32 -0800200 bool fileExists = false;
William A. Kennington IIIa520a392022-08-08 12:17:34 -0700201 fs::path filename;
William A. Kennington IIIbc52d932022-08-18 16:34:02 -0700202 std::vector<std::string> warnings;
Ratan Guptaed123a32017-06-15 09:07:31 +0530203};
204
Gunnar Mills57d9c502018-09-14 14:42:34 -0500205} // namespace config
206} // namespace network
207} // namespace phosphor