summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2019-07-03 19:00:38 (GMT)
committerBrad King <brad.king@kitware.com>2019-10-02 13:33:54 (GMT)
commitc8f48069430cb286ca593a967e0c3b8e5ea842c4 (patch)
treef120fded0d29cd5e1a3caf48990897ad748f5f75 /Source
parentbb4a1410592342a824b1dd755b7ca8897deac65c (diff)
downloadCMake-c8f48069430cb286ca593a967e0c3b8e5ea842c4.zip
CMake-c8f48069430cb286ca593a967e0c3b8e5ea842c4.tar.gz
CMake-c8f48069430cb286ca593a967e0c3b8e5ea842c4.tar.bz2
CTest: Add parser for hardware spec file
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CTest/cmCTestHardwareSpec.cxx133
-rw-r--r--Source/CTest/cmCTestHardwareSpec.h40
3 files changed, 174 insertions, 0 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 9750d0b..8e38590 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -918,6 +918,7 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
+ CTest/cmCTestHardwareSpec.cxx
CTest/cmCTestLaunch.cxx
CTest/cmCTestMemCheckCommand.cxx
CTest/cmCTestMemCheckHandler.cxx
diff --git a/Source/CTest/cmCTestHardwareSpec.cxx b/Source/CTest/cmCTestHardwareSpec.cxx
new file mode 100644
index 0000000..137398a
--- /dev/null
+++ b/Source/CTest/cmCTestHardwareSpec.cxx
@@ -0,0 +1,133 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCTestHardwareSpec.h"
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/RegularExpression.hxx"
+
+#include "cm_jsoncpp_reader.h"
+#include "cm_jsoncpp_value.h"
+
+static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
+static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
+
+bool cmCTestHardwareSpec::ReadFromJSONFile(const std::string& filename)
+{
+ cmsys::ifstream fin(filename.c_str());
+ if (!fin) {
+ return false;
+ }
+
+ Json::Value root;
+ Json::CharReaderBuilder builder;
+ if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
+ return false;
+ }
+
+ if (!root.isObject()) {
+ return false;
+ }
+
+ auto const& local = root["local"];
+ if (!local.isArray()) {
+ return false;
+ }
+ if (local.size() > 1) {
+ return false;
+ }
+
+ if (local.empty()) {
+ this->LocalSocket.Resources.clear();
+ return true;
+ }
+
+ auto const& localSocket = local[0];
+ if (!localSocket.isObject()) {
+ return false;
+ }
+ std::map<std::string, std::vector<cmCTestHardwareSpec::Resource>> resources;
+ cmsys::RegularExpressionMatch match;
+ for (auto const& key : localSocket.getMemberNames()) {
+ if (IdentifierRegex.find(key.c_str(), match)) {
+ auto const& value = localSocket[key];
+ auto& r = resources[key];
+ if (value.isArray()) {
+ for (auto const& item : value) {
+ if (item.isObject()) {
+ cmCTestHardwareSpec::Resource resource;
+
+ if (!item.isMember("id")) {
+ return false;
+ }
+ auto const& id = item["id"];
+ if (!id.isString()) {
+ return false;
+ }
+ resource.Id = id.asString();
+ if (!IdRegex.find(resource.Id.c_str(), match)) {
+ return false;
+ }
+
+ if (item.isMember("slots")) {
+ auto const& capacity = item["slots"];
+ if (!capacity.isConvertibleTo(Json::uintValue)) {
+ return false;
+ }
+ resource.Capacity = capacity.asUInt();
+ } else {
+ resource.Capacity = 1;
+ }
+
+ r.push_back(resource);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ this->LocalSocket.Resources = std::move(resources);
+ return true;
+}
+
+bool cmCTestHardwareSpec::operator==(const cmCTestHardwareSpec& other) const
+{
+ return this->LocalSocket == other.LocalSocket;
+}
+
+bool cmCTestHardwareSpec::operator!=(const cmCTestHardwareSpec& other) const
+{
+ return !(*this == other);
+}
+
+bool cmCTestHardwareSpec::Socket::operator==(
+ const cmCTestHardwareSpec::Socket& other) const
+{
+ return this->Resources == other.Resources;
+}
+
+bool cmCTestHardwareSpec::Socket::operator!=(
+ const cmCTestHardwareSpec::Socket& other) const
+{
+ return !(*this == other);
+}
+
+bool cmCTestHardwareSpec::Resource::operator==(
+ const cmCTestHardwareSpec::Resource& other) const
+{
+ return this->Id == other.Id && this->Capacity == other.Capacity;
+}
+
+bool cmCTestHardwareSpec::Resource::operator!=(
+ const cmCTestHardwareSpec::Resource& other) const
+{
+ return !(*this == other);
+}
diff --git a/Source/CTest/cmCTestHardwareSpec.h b/Source/CTest/cmCTestHardwareSpec.h
new file mode 100644
index 0000000..a0b4cae
--- /dev/null
+++ b/Source/CTest/cmCTestHardwareSpec.h
@@ -0,0 +1,40 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCTestHardwareSpec_h
+#define cmCTestHardwareSpec_h
+
+#include <map>
+#include <string>
+#include <vector>
+
+class cmCTestHardwareSpec
+{
+public:
+ class Resource
+ {
+ public:
+ std::string Id;
+ unsigned int Capacity;
+
+ bool operator==(const Resource& other) const;
+ bool operator!=(const Resource& other) const;
+ };
+
+ class Socket
+ {
+ public:
+ std::map<std::string, std::vector<Resource>> Resources;
+
+ bool operator==(const Socket& other) const;
+ bool operator!=(const Socket& other) const;
+ };
+
+ Socket LocalSocket;
+
+ bool ReadFromJSONFile(const std::string& filename);
+
+ bool operator==(const cmCTestHardwareSpec& other) const;
+ bool operator!=(const cmCTestHardwareSpec& other) const;
+};
+
+#endif