/* 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 #include #include #include #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> 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); }