blob: f0e8d2575e0da005f0933be25f563111dcef255e [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>
8#include <boost/algorithm/string/predicate.hpp>
9#include <boost/algorithm/string/replace.hpp>
10#include <boost/algorithm/string/split.hpp>
11#include <boost/container/flat_map.hpp>
12#include <boost/lexical_cast.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>
Christopher Meis59ef1e72025-04-16 08:53:25 +020016#include <iostream>
Andrew Jefferya9c58922021-06-01 09:28:59 +093017#include <map>
James Feist8c505da2020-05-28 10:06:33 -070018#include <regex>
19
Ed Tanous072e25d2018-12-16 21:45:20 -080020namespace fs = std::filesystem;
James Feist3cb5fec2018-01-23 14:41:51 -080021
James Feista465ccc2019-02-08 12:51:01 -080022bool findFiles(const fs::path& dirPath, const std::string& matchString,
23 std::vector<fs::path>& foundPaths)
James Feist3cb5fec2018-01-23 14:41:51 -080024{
James Feista3c180a2018-08-09 16:06:04 -070025 if (!fs::exists(dirPath))
Ed Tanous07d467b2021-02-23 14:48:37 -080026 {
James Feist3cb5fec2018-01-23 14:41:51 -080027 return false;
Ed Tanous07d467b2021-02-23 14:48:37 -080028 }
James Feist3cb5fec2018-01-23 14:41:51 -080029
James Feista3c180a2018-08-09 16:06:04 -070030 std::regex search(matchString);
James Feist3cb5fec2018-01-23 14:41:51 -080031 std::smatch match;
James Feista465ccc2019-02-08 12:51:01 -080032 for (const auto& p : fs::directory_iterator(dirPath))
James Feist3cb5fec2018-01-23 14:41:51 -080033 {
34 std::string path = p.path().string();
James Feistc95cb142018-02-26 10:41:42 -080035 if (std::regex_search(path, match, search))
James Feist3cb5fec2018-01-23 14:41:51 -080036 {
James Feista3c180a2018-08-09 16:06:04 -070037 foundPaths.emplace_back(p.path());
James Feist3cb5fec2018-01-23 14:41:51 -080038 }
39 }
40 return true;
James Feistb4383f42018-08-06 16:54:10 -070041}
42
Andrew Jefferya9c58922021-06-01 09:28:59 +093043bool findFiles(const std::vector<fs::path>&& dirPaths,
44 const std::string& matchString,
45 std::vector<fs::path>& foundPaths)
46{
47 std::map<fs::path, fs::path> paths;
48 std::regex search(matchString);
49 std::smatch match;
50 for (const auto& dirPath : dirPaths)
51 {
52 if (!fs::exists(dirPath))
Bruce Mitchella6d47332021-12-13 10:18:03 -060053 {
Andrew Jefferya9c58922021-06-01 09:28:59 +093054 continue;
Bruce Mitchella6d47332021-12-13 10:18:03 -060055 }
Andrew Jefferya9c58922021-06-01 09:28:59 +093056
Alexander Hansend8e86032025-04-25 14:49:15 +020057 for (const auto& p : fs::recursive_directory_iterator(dirPath))
Andrew Jefferya9c58922021-06-01 09:28:59 +093058 {
Alexander Hansend8e86032025-04-25 14:49:15 +020059 std::error_code ec;
60 if (p.is_directory(ec))
61 {
62 continue;
63 }
64
Andrew Jefferya9c58922021-06-01 09:28:59 +093065 std::string path = p.path().string();
66 if (std::regex_search(path, match, search))
67 {
68 paths[p.path().filename()] = p.path();
69 }
70 }
71 }
72
73 for (const auto& [key, value] : paths)
74 {
75 foundPaths.emplace_back(value);
76 }
77
78 return !foundPaths.empty();
79}
80
Nikhil Potaded8884f12019-03-27 13:27:13 -070081bool getI2cDevicePaths(const fs::path& dirPath,
82 boost::container::flat_map<size_t, fs::path>& busPaths)
83{
84 if (!fs::exists(dirPath))
85 {
86 return false;
87 }
88
89 // Regex for matching the path
90 std::regex searchPath(std::string(R"(i2c-\d+$)"));
91 // Regex for matching the bus numbers
92 std::regex searchBus(std::string(R"(\w[^-]*$)"));
93 std::smatch matchPath;
94 std::smatch matchBus;
95 for (const auto& p : fs::directory_iterator(dirPath))
96 {
97 std::string path = p.path().string();
98 if (std::regex_search(path, matchPath, searchPath))
99 {
100 if (std::regex_search(path, matchBus, searchBus))
101 {
102 size_t bus = stoul(*matchBus.begin());
103 busPaths.insert(std::pair<size_t, fs::path>(bus, p.path()));
104 }
105 }
106 }
107
108 return true;
109}
110
Brad Bishop5d525412020-08-26 08:50:50 -0400111/// \brief JSON/DBus matching Callable for std::variant (visitor)
112///
113/// Default match JSON/DBus match implementation
Andrew Jefferyeab49292022-04-05 14:42:20 +0930114/// \tparam T The concrete DBus value type from DBusValueVariant
Brad Bishop5d525412020-08-26 08:50:50 -0400115template <typename T>
116struct MatchProbe
117{
118 /// \param probe the probe statement to match against
119 /// \param value the property value being matched to a probe
120 /// \return true if the dbusValue matched the probe otherwise false
121 static bool match(const nlohmann::json& probe, const T& value)
122 {
123 return probe == value;
124 }
125};
126
127/// \brief JSON/DBus matching Callable for std::variant (visitor)
128///
129/// std::string specialization of MatchProbe enabling regex matching
130template <>
131struct MatchProbe<std::string>
132{
133 /// \param probe the probe statement to match against
134 /// \param value the string value being matched to a probe
135 /// \return true if the dbusValue matched the probe otherwise false
136 static bool match(const nlohmann::json& probe, const std::string& value)
137 {
138 if (probe.is_string())
139 {
140 try
141 {
142 std::regex search(probe);
143 std::smatch regMatch;
144 return std::regex_search(value, regMatch, search);
145 }
146 catch (const std::regex_error&)
147 {
148 std::cerr << "Syntax error in regular expression: " << probe
149 << " will never match";
150 }
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}