blob: 4a35756d4f0405e0ace57a8b3f56707afd129dbc [file] [log] [blame]
Alexander Hansen4e1142d2025-07-25 17:07:27 +02001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright 2017 Intel Corporation
James Feist3cb5fec2018-01-23 14:41:51 -08003
Brad Bishope45d8c72022-05-25 15:12:53 -04004#include "utils.hpp"
James Feist481c5d52019-08-13 14:40:40 -07005
James Feist481c5d52019-08-13 14:40:40 -07006#include <boost/algorithm/string/classification.hpp>
7#include <boost/algorithm/string/find.hpp>
James Feist481c5d52019-08-13 14:40:40 -07008#include <boost/algorithm/string/replace.hpp>
9#include <boost/algorithm/string/split.hpp>
10#include <boost/container/flat_map.hpp>
11#include <boost/lexical_cast.hpp>
Alexander Hansen8feb0452025-09-15 14:29:20 +020012#include <phosphor-logging/lg2.hpp>
James Feist1df06a42019-04-11 14:23:04 -070013#include <sdbusplus/bus/match.hpp>
James Feist3cb5fec2018-01-23 14:41:51 -080014
James Feist8c505da2020-05-28 10:06:33 -070015#include <filesystem>
Andrew Jefferya9c58922021-06-01 09:28:59 +093016#include <map>
James Feist8c505da2020-05-28 10:06:33 -070017#include <regex>
18
Ed Tanous072e25d2018-12-16 21:45:20 -080019namespace fs = std::filesystem;
James Feist3cb5fec2018-01-23 14:41:51 -080020
James Feista465ccc2019-02-08 12:51:01 -080021bool findFiles(const fs::path& dirPath, const std::string& matchString,
22 std::vector<fs::path>& foundPaths)
James Feist3cb5fec2018-01-23 14:41:51 -080023{
James Feista3c180a2018-08-09 16:06:04 -070024 if (!fs::exists(dirPath))
Ed Tanous07d467b2021-02-23 14:48:37 -080025 {
James Feist3cb5fec2018-01-23 14:41:51 -080026 return false;
Ed Tanous07d467b2021-02-23 14:48:37 -080027 }
James Feist3cb5fec2018-01-23 14:41:51 -080028
James Feista3c180a2018-08-09 16:06:04 -070029 std::regex search(matchString);
James Feist3cb5fec2018-01-23 14:41:51 -080030 std::smatch match;
James Feista465ccc2019-02-08 12:51:01 -080031 for (const auto& p : fs::directory_iterator(dirPath))
James Feist3cb5fec2018-01-23 14:41:51 -080032 {
33 std::string path = p.path().string();
James Feistc95cb142018-02-26 10:41:42 -080034 if (std::regex_search(path, match, search))
James Feist3cb5fec2018-01-23 14:41:51 -080035 {
James Feista3c180a2018-08-09 16:06:04 -070036 foundPaths.emplace_back(p.path());
James Feist3cb5fec2018-01-23 14:41:51 -080037 }
38 }
39 return true;
James Feistb4383f42018-08-06 16:54:10 -070040}
41
Andrew Jefferya9c58922021-06-01 09:28:59 +093042bool findFiles(const std::vector<fs::path>&& dirPaths,
43 const std::string& matchString,
44 std::vector<fs::path>& foundPaths)
45{
46 std::map<fs::path, fs::path> paths;
47 std::regex search(matchString);
48 std::smatch match;
49 for (const auto& dirPath : dirPaths)
50 {
51 if (!fs::exists(dirPath))
Bruce Mitchella6d47332021-12-13 10:18:03 -060052 {
Andrew Jefferya9c58922021-06-01 09:28:59 +093053 continue;
Bruce Mitchella6d47332021-12-13 10:18:03 -060054 }
Andrew Jefferya9c58922021-06-01 09:28:59 +093055
Alexander Hansend8e86032025-04-25 14:49:15 +020056 for (const auto& p : fs::recursive_directory_iterator(dirPath))
Andrew Jefferya9c58922021-06-01 09:28:59 +093057 {
Alexander Hansend8e86032025-04-25 14:49:15 +020058 std::error_code ec;
59 if (p.is_directory(ec))
60 {
61 continue;
62 }
63
Andrew Jefferya9c58922021-06-01 09:28:59 +093064 std::string path = p.path().string();
65 if (std::regex_search(path, match, search))
66 {
67 paths[p.path().filename()] = p.path();
68 }
69 }
70 }
71
72 for (const auto& [key, value] : paths)
73 {
74 foundPaths.emplace_back(value);
75 }
76
77 return !foundPaths.empty();
78}
79
Nikhil Potaded8884f12019-03-27 13:27:13 -070080bool getI2cDevicePaths(const fs::path& dirPath,
81 boost::container::flat_map<size_t, fs::path>& busPaths)
82{
83 if (!fs::exists(dirPath))
84 {
85 return false;
86 }
87
88 // Regex for matching the path
89 std::regex searchPath(std::string(R"(i2c-\d+$)"));
90 // Regex for matching the bus numbers
91 std::regex searchBus(std::string(R"(\w[^-]*$)"));
92 std::smatch matchPath;
93 std::smatch matchBus;
94 for (const auto& p : fs::directory_iterator(dirPath))
95 {
96 std::string path = p.path().string();
97 if (std::regex_search(path, matchPath, searchPath))
98 {
99 if (std::regex_search(path, matchBus, searchBus))
100 {
101 size_t bus = stoul(*matchBus.begin());
102 busPaths.insert(std::pair<size_t, fs::path>(bus, p.path()));
103 }
104 }
105 }
106
107 return true;
108}
109
Brad Bishop5d525412020-08-26 08:50:50 -0400110/// \brief JSON/DBus matching Callable for std::variant (visitor)
111///
112/// Default match JSON/DBus match implementation
Andrew Jefferyeab49292022-04-05 14:42:20 +0930113/// \tparam T The concrete DBus value type from DBusValueVariant
Brad Bishop5d525412020-08-26 08:50:50 -0400114template <typename T>
115struct MatchProbe
116{
117 /// \param probe the probe statement to match against
118 /// \param value the property value being matched to a probe
119 /// \return true if the dbusValue matched the probe otherwise false
120 static bool match(const nlohmann::json& probe, const T& value)
121 {
122 return probe == value;
123 }
124};
125
126/// \brief JSON/DBus matching Callable for std::variant (visitor)
127///
128/// std::string specialization of MatchProbe enabling regex matching
129template <>
130struct MatchProbe<std::string>
131{
132 /// \param probe the probe statement to match against
133 /// \param value the string value being matched to a probe
134 /// \return true if the dbusValue matched the probe otherwise false
135 static bool match(const nlohmann::json& probe, const std::string& value)
136 {
137 if (probe.is_string())
138 {
139 try
140 {
141 std::regex search(probe);
142 std::smatch regMatch;
143 return std::regex_search(value, regMatch, search);
144 }
145 catch (const std::regex_error&)
146 {
Alexander Hansen8feb0452025-09-15 14:29:20 +0200147 lg2::error(
148 "Syntax error in regular expression: {PROBE} will never match",
149 "PROBE", probe);
Brad Bishop5d525412020-08-26 08:50:50 -0400150 }
151 }
152
153 // Skip calling nlohmann here, since it will never match a non-string
154 // to a std::string
155 return false;
156 }
157};
158
159/// \brief Forwarding JSON/DBus matching Callable for std::variant (visitor)
160///
161/// Forward calls to the correct template instantiation of MatchProbe
162struct MatchProbeForwarder
163{
164 explicit MatchProbeForwarder(const nlohmann::json& probe) : probeRef(probe)
165 {}
166 const nlohmann::json& probeRef;
167
168 template <typename T>
169 bool operator()(const T& dbusValue) const
170 {
171 return MatchProbe<T>::match(probeRef, dbusValue);
172 }
173};
174
Andrew Jefferyeab49292022-04-05 14:42:20 +0930175bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue)
Brad Bishop3cb8a602020-08-25 17:40:54 -0400176{
Brad Bishop5d525412020-08-26 08:50:50 -0400177 return std::visit(MatchProbeForwarder(probe), dbusValue);
178}