Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
16
tools/EVerest-main/lib/everest/yaml/BUILD.bazel
Normal file
16
tools/EVerest-main/lib/everest/yaml/BUILD.bazel
Normal file
@@ -0,0 +1,16 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||
|
||||
cc_library(
|
||||
name = "everest_yaml",
|
||||
srcs = ["lib/yaml_loader.cpp"],
|
||||
hdrs = ["include/utils/yaml_loader.hpp"],
|
||||
strip_include_prefix = "include",
|
||||
cxxopts = ["-std=c++17"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//lib/everest/log:liblog",
|
||||
"@com_github_fmtlib_fmt//:fmt",
|
||||
"@com_github_nlohmann_json//:json",
|
||||
"@rapidyaml",
|
||||
],
|
||||
)
|
||||
48
tools/EVerest-main/lib/everest/yaml/CMakeLists.txt
Normal file
48
tools/EVerest-main/lib/everest/yaml/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
add_library(everest_yaml STATIC)
|
||||
add_library(everest::yaml ALIAS everest_yaml)
|
||||
ev_register_library_target(everest_yaml)
|
||||
|
||||
target_sources(everest_yaml
|
||||
PRIVATE
|
||||
lib/yaml_loader.cpp
|
||||
)
|
||||
|
||||
target_include_directories(everest_yaml
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/everest>
|
||||
)
|
||||
|
||||
target_compile_features(everest_yaml PUBLIC cxx_std_17)
|
||||
|
||||
set_target_properties(everest_yaml PROPERTIES
|
||||
EXPORT_NAME yaml
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
|
||||
target_link_libraries(everest_yaml
|
||||
PUBLIC
|
||||
nlohmann_json::nlohmann_json
|
||||
PRIVATE
|
||||
ryml::ryml
|
||||
fmt::fmt
|
||||
everest::log
|
||||
)
|
||||
|
||||
if (DISABLE_EDM)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(
|
||||
TARGETS everest_yaml
|
||||
EXPORT everest-core-targets
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/everest
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/everest
|
||||
FILES_MATCHING PATTERN "*.hpp"
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#ifndef UTILS_YAML_LOADER_HPP
|
||||
#define UTILS_YAML_LOADER_HPP
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace Everest {
|
||||
|
||||
/// \brief Read the YAML file at \p path and returns its content as JSON
|
||||
nlohmann::ordered_json load_yaml(const std::filesystem::path& path);
|
||||
|
||||
/// \brief Saves the JSON \p data to a YAML file at \p path
|
||||
void save_yaml(const nlohmann::ordered_json& data, const std::filesystem::path& path);
|
||||
|
||||
} // namespace Everest
|
||||
|
||||
#endif // UTILS_YAML_LOADER_HPP
|
||||
152
tools/EVerest-main/lib/everest/yaml/lib/yaml_loader.cpp
Normal file
152
tools/EVerest-main/lib/everest/yaml/lib/yaml_loader.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#include <utils/yaml_loader.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <ryml.hpp>
|
||||
#include <ryml_std.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace {
|
||||
template <typename T, typename U> T constexpr clamp_to(U len) {
|
||||
return (len <= std::numeric_limits<T>::max()) ? static_cast<T>(len) : std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
void yaml_error_handler(const char* msg, std::size_t len, ryml::Location loc, void*) {
|
||||
std::stringstream error_msg;
|
||||
error_msg << "YAML parsing error: ";
|
||||
|
||||
if (loc) {
|
||||
if (not loc.name.empty()) {
|
||||
error_msg.write(loc.name.str, clamp_to<std::streamsize>(loc.name.len));
|
||||
error_msg << ":";
|
||||
}
|
||||
error_msg << loc.line << ":";
|
||||
if (loc.col) {
|
||||
error_msg << loc.col << ":";
|
||||
}
|
||||
if (loc.offset) {
|
||||
error_msg << " (" << loc.offset << "B):";
|
||||
}
|
||||
}
|
||||
error_msg.write(msg, clamp_to<std::streamsize>(len));
|
||||
|
||||
throw std::runtime_error(error_msg.str());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
struct RymlCallbackInitializer {
|
||||
RymlCallbackInitializer() {
|
||||
ryml::set_callbacks({nullptr, nullptr, nullptr, yaml_error_handler});
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
// NOLINTNEXTLINE(misc-no-recursion): recursive parsing preferred for simplicity
|
||||
nlohmann::ordered_json ryml_to_nlohmann_json(const c4::yml::ConstNodeRef& ryml_node) {
|
||||
if (ryml_node.is_map()) {
|
||||
// handle object
|
||||
auto object = nlohmann::ordered_json::object();
|
||||
for (const auto& child : ryml_node) {
|
||||
object[std::string(child.key().data(), child.key().len)] = ryml_to_nlohmann_json(child);
|
||||
}
|
||||
return object;
|
||||
} else if (ryml_node.is_seq()) {
|
||||
// handle array
|
||||
auto array = nlohmann::ordered_json::array();
|
||||
for (const auto& child : ryml_node) {
|
||||
array.emplace_back(ryml_to_nlohmann_json(child));
|
||||
}
|
||||
return array;
|
||||
} else if (ryml_node.empty() or ryml_node.val_is_null()) {
|
||||
return nullptr;
|
||||
} else {
|
||||
// check type of data
|
||||
const auto& value = ryml_node.val();
|
||||
std::string value_string(value.data(), value.len);
|
||||
const auto value_quoted = ryml_node.is_val_quoted();
|
||||
if (!value_quoted) {
|
||||
// check for numbers and booleans
|
||||
if (ryml_node.val().is_integer()) {
|
||||
return std::stoi(value_string);
|
||||
} else if (ryml_node.val().is_number()) {
|
||||
return std::stod(value_string);
|
||||
} else if (value_string == "true") {
|
||||
return true;
|
||||
} else if (value_string == "false") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// nothing matched so far, should be string
|
||||
return value_string;
|
||||
}
|
||||
}
|
||||
|
||||
std::string load_yaml_content(std::filesystem::path path) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
if (path.extension().string() == ".json") {
|
||||
EVLOG_info << fmt::format("Deprecated: called load_yaml() with .json extension ('{}')", path.string());
|
||||
// try yaml first
|
||||
path.replace_extension(".yaml");
|
||||
} else if (path.extension().string() != ".yaml") {
|
||||
throw std::runtime_error(
|
||||
fmt::format("Trying to load a yaml file without yaml extension (path was '{}')", path.string()));
|
||||
}
|
||||
|
||||
// first check for yaml, if not found try fall back to json and evlog debug deprecated
|
||||
if (fs::exists(path)) {
|
||||
std::ifstream ifs(path.string());
|
||||
return std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
path.replace_extension(".json");
|
||||
|
||||
if (fs::exists(path)) {
|
||||
EVLOG_info << "Deprecated: loaded file in json format";
|
||||
std::ifstream ifs(path.string());
|
||||
return std::string(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
// failed to find yaml and json
|
||||
throw std::runtime_error(fmt::format("File '{}.(yaml|json)' does not exist", path.stem().string()));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace Everest {
|
||||
|
||||
nlohmann::ordered_json load_yaml(const std::filesystem::path& path) {
|
||||
// FIXME (aw): using the static here this isn't a perfect solution
|
||||
const static RymlCallbackInitializer ryml_callback_initializer;
|
||||
|
||||
const auto content = load_yaml_content(path);
|
||||
// FIXME (aw): using parse_in_place would be faster but that will need the file as a whole char buffer
|
||||
const auto tree = ryml::parse_in_arena(ryml::to_csubstr(content));
|
||||
return ryml_to_nlohmann_json(tree.rootref());
|
||||
}
|
||||
|
||||
void save_yaml(const nlohmann::ordered_json& data, const std::filesystem::path& path) {
|
||||
if (!std::filesystem::exists(path.parent_path())) {
|
||||
std::filesystem::create_directory(path.parent_path());
|
||||
}
|
||||
|
||||
// FIXME: saving yaml seems to be quite complicated, but we should be able to just emit json here...
|
||||
std::ofstream ofs(path);
|
||||
ofs << data << std::endl;
|
||||
ofs.close();
|
||||
|
||||
if (!ofs) {
|
||||
const int ec = errno;
|
||||
throw std::runtime_error(
|
||||
fmt::format("Writing user-config to '{}' failed with ec: {}", path.string(), std::strerror(ec)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Everest
|
||||
Reference in New Issue
Block a user