blob: b408aea2e307e7f0fae0263c399ee15a037594ff [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>
James Feist1df06a42019-04-11 14:23:04 -070012#include <sdbusplus/bus/match.hpp>
James Feist3cb5fec2018-01-23 14:41:51 -080013
James Feist8c505da2020-05-28 10:06:33 -070014#include <filesystem>
Christopher Meis59ef1e72025-04-16 08:53:25 +020015#include <iostream>
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 {
147 std::cerr << "Syntax error in regular expression: " << probe
148 << " will never match";
149 }
150 }
151
152 // Skip calling nlohmann here, since it will never match a non-string
153 // to a std::string
154 return false;
155 }
156};
157
158/// \brief Forwarding JSON/DBus matching Callable for std::variant (visitor)
159///
160/// Forward calls to the correct template instantiation of MatchProbe
161struct MatchProbeForwarder
162{
163 explicit MatchProbeForwarder(const nlohmann::json& probe) : probeRef(probe)
164 {}
165 const nlohmann::json& probeRef;
166
167 template <typename T>
168 bool operator()(const T& dbusValue) const
169 {
170 return MatchProbe<T>::match(probeRef, dbusValue);
171 }
172};
173
Andrew Jefferyeab49292022-04-05 14:42:20 +0930174bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue)
Brad Bishop3cb8a602020-08-25 17:40:54 -0400175{
Brad Bishop5d525412020-08-26 08:50:50 -0400176 return std::visit(MatchProbeForwarder(probe), dbusValue);
177}