blob: 0d3a6d0351bbf69c01e074cb7eac240938a7e1cf [file] [log] [blame]
James Feist3cb5fec2018-01-23 14:41:51 -08001/*
2// Copyright (c) 2017 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
Brad Bishope45d8c72022-05-25 15:12:53 -040016/// \file utils.cpp
James Feist3cb5fec2018-01-23 14:41:51 -080017
Brad Bishope45d8c72022-05-25 15:12:53 -040018#include "utils.hpp"
James Feist481c5d52019-08-13 14:40:40 -070019
James Feist481c5d52019-08-13 14:40:40 -070020#include <boost/algorithm/string/classification.hpp>
21#include <boost/algorithm/string/find.hpp>
22#include <boost/algorithm/string/predicate.hpp>
23#include <boost/algorithm/string/replace.hpp>
24#include <boost/algorithm/string/split.hpp>
25#include <boost/container/flat_map.hpp>
26#include <boost/lexical_cast.hpp>
James Feist1df06a42019-04-11 14:23:04 -070027#include <sdbusplus/bus/match.hpp>
James Feist3cb5fec2018-01-23 14:41:51 -080028
James Feist8c505da2020-05-28 10:06:33 -070029#include <filesystem>
Christopher Meis59ef1e72025-04-16 08:53:25 +020030#include <iostream>
Andrew Jefferya9c58922021-06-01 09:28:59 +093031#include <map>
James Feist8c505da2020-05-28 10:06:33 -070032#include <regex>
33
Ed Tanous072e25d2018-12-16 21:45:20 -080034namespace fs = std::filesystem;
James Feist3cb5fec2018-01-23 14:41:51 -080035
James Feista465ccc2019-02-08 12:51:01 -080036bool findFiles(const fs::path& dirPath, const std::string& matchString,
37 std::vector<fs::path>& foundPaths)
James Feist3cb5fec2018-01-23 14:41:51 -080038{
James Feista3c180a2018-08-09 16:06:04 -070039 if (!fs::exists(dirPath))
Ed Tanous07d467b2021-02-23 14:48:37 -080040 {
James Feist3cb5fec2018-01-23 14:41:51 -080041 return false;
Ed Tanous07d467b2021-02-23 14:48:37 -080042 }
James Feist3cb5fec2018-01-23 14:41:51 -080043
James Feista3c180a2018-08-09 16:06:04 -070044 std::regex search(matchString);
James Feist3cb5fec2018-01-23 14:41:51 -080045 std::smatch match;
James Feista465ccc2019-02-08 12:51:01 -080046 for (const auto& p : fs::directory_iterator(dirPath))
James Feist3cb5fec2018-01-23 14:41:51 -080047 {
48 std::string path = p.path().string();
James Feistc95cb142018-02-26 10:41:42 -080049 if (std::regex_search(path, match, search))
James Feist3cb5fec2018-01-23 14:41:51 -080050 {
James Feista3c180a2018-08-09 16:06:04 -070051 foundPaths.emplace_back(p.path());
James Feist3cb5fec2018-01-23 14:41:51 -080052 }
53 }
54 return true;
James Feistb4383f42018-08-06 16:54:10 -070055}
56
Andrew Jefferya9c58922021-06-01 09:28:59 +093057bool findFiles(const std::vector<fs::path>&& dirPaths,
58 const std::string& matchString,
59 std::vector<fs::path>& foundPaths)
60{
61 std::map<fs::path, fs::path> paths;
62 std::regex search(matchString);
63 std::smatch match;
64 for (const auto& dirPath : dirPaths)
65 {
66 if (!fs::exists(dirPath))
Bruce Mitchella6d47332021-12-13 10:18:03 -060067 {
Andrew Jefferya9c58922021-06-01 09:28:59 +093068 continue;
Bruce Mitchella6d47332021-12-13 10:18:03 -060069 }
Andrew Jefferya9c58922021-06-01 09:28:59 +093070
Alexander Hansend8e86032025-04-25 14:49:15 +020071 for (const auto& p : fs::recursive_directory_iterator(dirPath))
Andrew Jefferya9c58922021-06-01 09:28:59 +093072 {
Alexander Hansend8e86032025-04-25 14:49:15 +020073 std::error_code ec;
74 if (p.is_directory(ec))
75 {
76 continue;
77 }
78
Andrew Jefferya9c58922021-06-01 09:28:59 +093079 std::string path = p.path().string();
80 if (std::regex_search(path, match, search))
81 {
82 paths[p.path().filename()] = p.path();
83 }
84 }
85 }
86
87 for (const auto& [key, value] : paths)
88 {
89 foundPaths.emplace_back(value);
90 }
91
92 return !foundPaths.empty();
93}
94
Nikhil Potaded8884f12019-03-27 13:27:13 -070095bool getI2cDevicePaths(const fs::path& dirPath,
96 boost::container::flat_map<size_t, fs::path>& busPaths)
97{
98 if (!fs::exists(dirPath))
99 {
100 return false;
101 }
102
103 // Regex for matching the path
104 std::regex searchPath(std::string(R"(i2c-\d+$)"));
105 // Regex for matching the bus numbers
106 std::regex searchBus(std::string(R"(\w[^-]*$)"));
107 std::smatch matchPath;
108 std::smatch matchBus;
109 for (const auto& p : fs::directory_iterator(dirPath))
110 {
111 std::string path = p.path().string();
112 if (std::regex_search(path, matchPath, searchPath))
113 {
114 if (std::regex_search(path, matchBus, searchBus))
115 {
116 size_t bus = stoul(*matchBus.begin());
117 busPaths.insert(std::pair<size_t, fs::path>(bus, p.path()));
118 }
119 }
120 }
121
122 return true;
123}
124
Brad Bishop5d525412020-08-26 08:50:50 -0400125/// \brief JSON/DBus matching Callable for std::variant (visitor)
126///
127/// Default match JSON/DBus match implementation
Andrew Jefferyeab49292022-04-05 14:42:20 +0930128/// \tparam T The concrete DBus value type from DBusValueVariant
Brad Bishop5d525412020-08-26 08:50:50 -0400129template <typename T>
130struct MatchProbe
131{
132 /// \param probe the probe statement to match against
133 /// \param value the property 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 T& value)
136 {
137 return probe == value;
138 }
139};
140
141/// \brief JSON/DBus matching Callable for std::variant (visitor)
142///
143/// std::string specialization of MatchProbe enabling regex matching
144template <>
145struct MatchProbe<std::string>
146{
147 /// \param probe the probe statement to match against
148 /// \param value the string value being matched to a probe
149 /// \return true if the dbusValue matched the probe otherwise false
150 static bool match(const nlohmann::json& probe, const std::string& value)
151 {
152 if (probe.is_string())
153 {
154 try
155 {
156 std::regex search(probe);
157 std::smatch regMatch;
158 return std::regex_search(value, regMatch, search);
159 }
160 catch (const std::regex_error&)
161 {
162 std::cerr << "Syntax error in regular expression: " << probe
163 << " will never match";
164 }
165 }
166
167 // Skip calling nlohmann here, since it will never match a non-string
168 // to a std::string
169 return false;
170 }
171};
172
173/// \brief Forwarding JSON/DBus matching Callable for std::variant (visitor)
174///
175/// Forward calls to the correct template instantiation of MatchProbe
176struct MatchProbeForwarder
177{
178 explicit MatchProbeForwarder(const nlohmann::json& probe) : probeRef(probe)
179 {}
180 const nlohmann::json& probeRef;
181
182 template <typename T>
183 bool operator()(const T& dbusValue) const
184 {
185 return MatchProbe<T>::match(probeRef, dbusValue);
186 }
187};
188
Andrew Jefferyeab49292022-04-05 14:42:20 +0930189bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue)
Brad Bishop3cb8a602020-08-25 17:40:54 -0400190{
Brad Bishop5d525412020-08-26 08:50:50 -0400191 return std::visit(MatchProbeForwarder(probe), dbusValue);
192}