blob: 116c484879d0c8439a62cd8d035631f30647a3e8 [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
71 for (const auto& p : fs::directory_iterator(dirPath))
72 {
73 std::string path = p.path().string();
74 if (std::regex_search(path, match, search))
75 {
76 paths[p.path().filename()] = p.path();
77 }
78 }
79 }
80
81 for (const auto& [key, value] : paths)
82 {
83 foundPaths.emplace_back(value);
84 }
85
86 return !foundPaths.empty();
87}
88
Nikhil Potaded8884f12019-03-27 13:27:13 -070089bool getI2cDevicePaths(const fs::path& dirPath,
90 boost::container::flat_map<size_t, fs::path>& busPaths)
91{
92 if (!fs::exists(dirPath))
93 {
94 return false;
95 }
96
97 // Regex for matching the path
98 std::regex searchPath(std::string(R"(i2c-\d+$)"));
99 // Regex for matching the bus numbers
100 std::regex searchBus(std::string(R"(\w[^-]*$)"));
101 std::smatch matchPath;
102 std::smatch matchBus;
103 for (const auto& p : fs::directory_iterator(dirPath))
104 {
105 std::string path = p.path().string();
106 if (std::regex_search(path, matchPath, searchPath))
107 {
108 if (std::regex_search(path, matchBus, searchBus))
109 {
110 size_t bus = stoul(*matchBus.begin());
111 busPaths.insert(std::pair<size_t, fs::path>(bus, p.path()));
112 }
113 }
114 }
115
116 return true;
117}
118
Brad Bishop5d525412020-08-26 08:50:50 -0400119/// \brief JSON/DBus matching Callable for std::variant (visitor)
120///
121/// Default match JSON/DBus match implementation
Andrew Jefferyeab49292022-04-05 14:42:20 +0930122/// \tparam T The concrete DBus value type from DBusValueVariant
Brad Bishop5d525412020-08-26 08:50:50 -0400123template <typename T>
124struct MatchProbe
125{
126 /// \param probe the probe statement to match against
127 /// \param value the property value being matched to a probe
128 /// \return true if the dbusValue matched the probe otherwise false
129 static bool match(const nlohmann::json& probe, const T& value)
130 {
131 return probe == value;
132 }
133};
134
135/// \brief JSON/DBus matching Callable for std::variant (visitor)
136///
137/// std::string specialization of MatchProbe enabling regex matching
138template <>
139struct MatchProbe<std::string>
140{
141 /// \param probe the probe statement to match against
142 /// \param value the string value being matched to a probe
143 /// \return true if the dbusValue matched the probe otherwise false
144 static bool match(const nlohmann::json& probe, const std::string& value)
145 {
146 if (probe.is_string())
147 {
148 try
149 {
150 std::regex search(probe);
151 std::smatch regMatch;
152 return std::regex_search(value, regMatch, search);
153 }
154 catch (const std::regex_error&)
155 {
156 std::cerr << "Syntax error in regular expression: " << probe
157 << " will never match";
158 }
159 }
160
161 // Skip calling nlohmann here, since it will never match a non-string
162 // to a std::string
163 return false;
164 }
165};
166
167/// \brief Forwarding JSON/DBus matching Callable for std::variant (visitor)
168///
169/// Forward calls to the correct template instantiation of MatchProbe
170struct MatchProbeForwarder
171{
172 explicit MatchProbeForwarder(const nlohmann::json& probe) : probeRef(probe)
173 {}
174 const nlohmann::json& probeRef;
175
176 template <typename T>
177 bool operator()(const T& dbusValue) const
178 {
179 return MatchProbe<T>::match(probeRef, dbusValue);
180 }
181};
182
Andrew Jefferyeab49292022-04-05 14:42:20 +0930183bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue)
Brad Bishop3cb8a602020-08-25 17:40:54 -0400184{
Brad Bishop5d525412020-08-26 08:50:50 -0400185 return std::visit(MatchProbeForwarder(probe), dbusValue);
186}