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:
68
tools/EVerest-main/lib/everest/log/lib/CMakeLists.txt
Normal file
68
tools/EVerest-main/lib/everest/log/lib/CMakeLists.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
add_library(everest_log)
|
||||
add_library(everest::log ALIAS everest_log)
|
||||
|
||||
target_sources(everest_log
|
||||
PRIVATE
|
||||
logging.cpp
|
||||
trace.cpp
|
||||
)
|
||||
|
||||
target_include_directories(everest_log
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
set_target_properties(everest_log
|
||||
PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
|
||||
target_link_libraries(everest_log
|
||||
PUBLIC
|
||||
Boost::log
|
||||
PRIVATE
|
||||
Boost::log_setup
|
||||
)
|
||||
|
||||
if (LIBLOG_USE_BOOST_FILESYSTEM)
|
||||
target_link_libraries(everest_log
|
||||
PRIVATE
|
||||
Boost::filesystem
|
||||
)
|
||||
target_compile_definitions(everest_log
|
||||
PRIVATE
|
||||
LIBLOG_USE_BOOST_FILESYSTEM
|
||||
)
|
||||
endif()
|
||||
|
||||
# FIXME (aw): in case FindBoost.cmake was used we need to add things
|
||||
# this should be removed no support for Boost < 1.74 is needed
|
||||
if (NOT Boost_DIR)
|
||||
target_compile_definitions(everest_log
|
||||
PUBLIC
|
||||
BOOST_LOG_DYN_LINK
|
||||
)
|
||||
target_link_libraries(everest_log
|
||||
PUBLIC
|
||||
rt dl
|
||||
)
|
||||
endif()
|
||||
|
||||
if (BUILD_BACKTRACE_SUPPORT)
|
||||
target_link_libraries(everest_log
|
||||
PRIVATE
|
||||
backtrace
|
||||
)
|
||||
target_compile_definitions(everest_log PRIVATE WITH_LIBBACKTRACE)
|
||||
endif()
|
||||
|
||||
if (EVEREST_DISABLE_VERBOSE_LOGGING)
|
||||
target_compile_definitions(everest_log PUBLIC EVEREST_DISABLE_VERBOSE_LOGGING)
|
||||
endif ()
|
||||
|
||||
if (EVEREST_DISABLE_DEBUG_LOGGING)
|
||||
target_compile_definitions(everest_log PUBLIC EVEREST_DISABLE_DEBUG_LOGGING)
|
||||
endif ()
|
||||
|
||||
target_compile_features(everest_log PUBLIC cxx_std_17)
|
||||
241
tools/EVerest-main/lib/everest/log/lib/logging.cpp
Normal file
241
tools/EVerest-main/lib/everest/log/lib/logging.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#ifdef LIBLOG_USE_BOOST_FILESYSTEM
|
||||
#include <boost/filesystem.hpp>
|
||||
#else
|
||||
#include <filesystem>
|
||||
#endif
|
||||
#include <boost/log/attributes/current_process_id.hpp>
|
||||
#include <boost/log/attributes/current_process_name.hpp>
|
||||
#include <boost/log/attributes/current_thread_id.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/expressions/attr.hpp>
|
||||
#include <boost/log/expressions/formatter.hpp>
|
||||
#include <boost/log/expressions/formatters/c_decorator.hpp>
|
||||
#include <boost/log/expressions/formatters/format.hpp>
|
||||
#include <boost/log/expressions/formatters/stream.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/utility/setup/filter_parser.hpp>
|
||||
#include <boost/log/utility/setup/formatter_parser.hpp>
|
||||
#include <boost/log/utility/setup/from_settings.hpp>
|
||||
#include <boost/log/utility/setup/from_stream.hpp>
|
||||
#include <boost/log/utility/setup/settings.hpp>
|
||||
#include <boost/log/utility/setup/settings_parser.hpp>
|
||||
#include <fstream>
|
||||
|
||||
#include <everest/exceptions.hpp>
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
// this will only be used while bootstrapping our logging (e.g. the logging settings aren't yet applied)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define EVEREST_INTERNAL_LOG_AND_THROW(exception) \
|
||||
do { \
|
||||
BOOST_LOG_TRIVIAL(fatal) << (exception).what(); \
|
||||
throw(exception); \
|
||||
} while (0);
|
||||
|
||||
#ifdef LIBLOG_USE_BOOST_FILESYSTEM
|
||||
namespace fs = boost::filesystem;
|
||||
#else
|
||||
namespace fs = std::filesystem;
|
||||
#endif
|
||||
namespace logging = boost::log::BOOST_LOG_VERSION_NAMESPACE;
|
||||
namespace attrs = logging::attributes;
|
||||
namespace expr = logging::expressions;
|
||||
|
||||
namespace Everest {
|
||||
namespace Logging {
|
||||
namespace {
|
||||
bool is_initialized = false;
|
||||
}
|
||||
|
||||
std::array<std::string, 6> severity_strings = {
|
||||
"VERB", //
|
||||
"DEBG", //
|
||||
"INFO", //
|
||||
"WARN", //
|
||||
"ERRO", //
|
||||
"CRIT", //
|
||||
};
|
||||
|
||||
std::array<std::string, 6> severity_strings_colors = {
|
||||
"", //
|
||||
"", //
|
||||
"", //
|
||||
"", //
|
||||
"", //
|
||||
"", //
|
||||
};
|
||||
|
||||
std::string process_name_padding(const std::string& process_name) {
|
||||
const unsigned int process_name_padding_length = 15;
|
||||
std::string padded_process_name = process_name;
|
||||
if (process_name_padding_length > padded_process_name.size())
|
||||
padded_process_name.insert(padded_process_name.size(), process_name_padding_length, ' ');
|
||||
if (padded_process_name.size() > process_name_padding_length)
|
||||
padded_process_name = padded_process_name.substr(0, process_name_padding_length);
|
||||
return padded_process_name;
|
||||
}
|
||||
|
||||
attrs::mutable_constant<std::string> current_process_name(process_name_padding(logging::aux::get_process_name()));
|
||||
|
||||
// The operator puts a human-friendly representation of the severity level to the stream
|
||||
std::ostream& operator<<(std::ostream& strm, severity_level level) {
|
||||
if (static_cast<std::size_t>(level) < severity_strings.size()) {
|
||||
strm << severity_strings_colors.at(level) << severity_strings.at(level) << "\033[0m";
|
||||
} else {
|
||||
strm << static_cast<int>(level);
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
// The operator parses the severity level from the stream
|
||||
std::istream& operator>>(std::istream& strm, severity_level& level) {
|
||||
if (strm.good()) {
|
||||
std::string str;
|
||||
strm >> str;
|
||||
|
||||
for (unsigned int i = 0; i < severity_strings.size(); ++i) {
|
||||
if (str == severity_strings.at(i)) {
|
||||
level = static_cast<severity_level>(i);
|
||||
return strm;
|
||||
}
|
||||
}
|
||||
|
||||
strm.setstate(std::ios_base::failbit);
|
||||
}
|
||||
|
||||
return strm;
|
||||
}
|
||||
|
||||
/// Custom formatter for escaped messages.
|
||||
///
|
||||
/// Not really clear but just a wrapper around the c_decor formatter.
|
||||
struct escaped_message_formatter {
|
||||
explicit escaped_message_formatter(logging::attribute_name const& name) :
|
||||
f_{expr::stream << expr::c_decor[expr::stream << expr::smessage]} {
|
||||
}
|
||||
void operator()(logging::record_view const& rec, logging::formatting_ostream& strm) const {
|
||||
f_(rec, strm);
|
||||
}
|
||||
|
||||
private:
|
||||
/// @brief The formatter itself.
|
||||
boost::log::formatter f_;
|
||||
};
|
||||
|
||||
/// The factory for the EscMessage formatter.
|
||||
struct escaped_message_formatter_factory : public logging::formatter_factory<char> {
|
||||
formatter_type create_formatter(logging::attribute_name const& attr_name, args_map const& args) {
|
||||
return formatter_type(escaped_message_formatter(attr_name));
|
||||
}
|
||||
};
|
||||
|
||||
int init() {
|
||||
logging::core::get()->remove_all_sinks();
|
||||
logging::core::get()->set_logging_enabled(false);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int init(const std::string& logconf) {
|
||||
return init(logconf, "");
|
||||
}
|
||||
|
||||
int init(const std::string& logconf, std::string process_name) {
|
||||
BOOST_LOG_FUNCTION();
|
||||
|
||||
if (is_initialized) {
|
||||
// this prevents us from registering the sinks multiple times which would lead to duplicate output
|
||||
logging::core::get()->remove_all_sinks();
|
||||
}
|
||||
|
||||
// First thing - register the custom formatter for EscMessage
|
||||
logging::register_formatter_factory("EscapedMessage", boost::make_shared<escaped_message_formatter_factory>());
|
||||
|
||||
// add useful attributes
|
||||
logging::add_common_attributes();
|
||||
|
||||
std::string padded_process_name;
|
||||
|
||||
if (!process_name.empty()) {
|
||||
padded_process_name = process_name_padding(process_name);
|
||||
}
|
||||
|
||||
logging::core::get()->add_global_attribute("Process", current_process_name);
|
||||
if (!padded_process_name.empty()) {
|
||||
current_process_name.set(padded_process_name);
|
||||
}
|
||||
logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
|
||||
|
||||
// Before initializing the library from settings, we need to register any custom filter and formatter factories
|
||||
logging::register_simple_filter_factory<severity_level>("Severity");
|
||||
logging::register_simple_formatter_factory<severity_level, char>("Severity");
|
||||
|
||||
// open logging.ini config file located at our base_dir and use it to configure boost::log logging (filters and
|
||||
// format)
|
||||
fs::path logging_path = fs::path(logconf);
|
||||
std::ifstream logging_config(logging_path.c_str());
|
||||
if (!logging_config.is_open()) {
|
||||
EVEREST_INTERNAL_LOG_AND_THROW(EverestConfigError(std::string("Could not open logging config file at ") +
|
||||
std::string(fs::absolute(logging_path).c_str())));
|
||||
}
|
||||
|
||||
auto settings = logging::parse_settings(logging_config);
|
||||
|
||||
auto sink = settings["Sinks.Console"].get_section();
|
||||
|
||||
severity_strings_colors[severity_level::verbose] =
|
||||
sink["SeverityStringColorTrace"].get<std::string>().get_value_or("");
|
||||
severity_strings_colors[severity_level::debug] =
|
||||
sink["SeverityStringColorDebug"].get<std::string>().get_value_or("");
|
||||
severity_strings_colors[severity_level::info] = sink["SeverityStringColorInfo"].get<std::string>().get_value_or("");
|
||||
severity_strings_colors[severity_level::warning] =
|
||||
sink["SeverityStringColorWarning"].get<std::string>().get_value_or("");
|
||||
severity_strings_colors[severity_level::error] =
|
||||
sink["SeverityStringColorError"].get<std::string>().get_value_or("");
|
||||
severity_strings_colors[severity_level::critical] =
|
||||
sink["SeverityStringColorCritical"].get<std::string>().get_value_or("");
|
||||
|
||||
logging::init_from_settings(settings);
|
||||
logging::core::get()->set_logging_enabled(true);
|
||||
|
||||
EVLOG_debug << "Logger " << (is_initialized ? "re" : "") << "initialized (using " << logconf << ")...";
|
||||
is_initialized = true;
|
||||
|
||||
// Probe the installed filter to find the minimum accepted severity level.
|
||||
for (int level = static_cast<int>(verbose); level <= static_cast<int>(critical); ++level) {
|
||||
auto rec =
|
||||
global_logger::get().open_record(boost::log::keywords::severity = static_cast<severity_level>(level));
|
||||
if (rec) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void update_process_name(std::string process_name) {
|
||||
if (!process_name.empty()) {
|
||||
std::string padded_process_name;
|
||||
|
||||
padded_process_name = process_name_padding(process_name);
|
||||
current_process_name.set(padded_process_name);
|
||||
}
|
||||
}
|
||||
|
||||
void ffi_log(int level, int line, const std::string& file, const std::string& message) {
|
||||
// Logging is off.
|
||||
if (level < 0) {
|
||||
return;
|
||||
}
|
||||
const auto logging_level = static_cast<severity_level>(level);
|
||||
BOOST_LOG_SEV(::global_logger::get(), logging_level)
|
||||
<< boost::log::BOOST_LOG_VERSION_NAMESPACE::add_value("file", file)
|
||||
<< boost::log::BOOST_LOG_VERSION_NAMESPACE::add_value("line", line) << message;
|
||||
}
|
||||
|
||||
} // namespace Logging
|
||||
} // namespace Everest
|
||||
90
tools/EVerest-main/lib/everest/log/lib/trace.cpp
Normal file
90
tools/EVerest-main/lib/everest/log/lib/trace.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2022 Pionix GmbH and Contributors to EVerest
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#ifdef WITH_LIBBACKTRACE
|
||||
#include <backtrace/backtrace-supported.h>
|
||||
#include <backtrace/backtrace.h>
|
||||
#include <cxxabi.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
static backtrace_state* bt_state;
|
||||
static bool tried_to_initialize;
|
||||
static std::mutex init_mtx;
|
||||
|
||||
struct StackTrace {
|
||||
int frame_count{0};
|
||||
std::string info;
|
||||
};
|
||||
|
||||
inline int frame_handler(void* data, uintptr_t pc, const char* filename, int lineno, const char* function) {
|
||||
// FIXME(aw): we might have unknown frames everywhere in the call
|
||||
// stack, it probably only make sense to skip the
|
||||
// contigeous set of the top/root frames, that are all
|
||||
// unknown
|
||||
// if ((filename == nullptr) && (lineno == 0) && (function == nullptr)) {
|
||||
// return 1; // stop backtracing
|
||||
// }
|
||||
auto& trace = *static_cast<StackTrace*>(data);
|
||||
|
||||
std::string function_name = "<function unknown>";
|
||||
if (function != nullptr) {
|
||||
// try to demangle
|
||||
int status;
|
||||
size_t length;
|
||||
|
||||
auto demangled_function = __cxxabiv1::__cxa_demangle(function, nullptr, &length, &status);
|
||||
if (status == 0) {
|
||||
// successfully demangled
|
||||
function_name = std::string(demangled_function);
|
||||
} else {
|
||||
function_name = std::string(function);
|
||||
}
|
||||
}
|
||||
|
||||
trace.info += ("#" + std::to_string(trace.frame_count) + ": ");
|
||||
trace.info += (function_name + " at ");
|
||||
trace.info += (filename != nullptr) ? filename : "<filename unknown>";
|
||||
trace.info += (":" + std::to_string(lineno));
|
||||
|
||||
trace.info += "\n";
|
||||
|
||||
trace.frame_count++;
|
||||
|
||||
return 0; // continue backtracing
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace Everest {
|
||||
namespace Logging {
|
||||
std::string trace() {
|
||||
#ifdef WITH_LIBBACKTRACE
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(init_mtx);
|
||||
if (!tried_to_initialize) {
|
||||
// 1 means support threaded
|
||||
bt_state = backtrace_create_state(nullptr, 1, nullptr, nullptr);
|
||||
tried_to_initialize = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bt_state == nullptr) {
|
||||
return "Backtrace functionality not available\n";
|
||||
}
|
||||
|
||||
StackTrace trace;
|
||||
|
||||
// FIXME (aw): 1 means we're skipping this functions frame, can this
|
||||
// be optimized away by the compiler, so we are going to
|
||||
// miss the first frame?
|
||||
backtrace_full(bt_state, 1, frame_handler, nullptr, &trace);
|
||||
|
||||
return trace.info;
|
||||
#else
|
||||
return "Backtrace functionality not built in\n";
|
||||
#endif
|
||||
}
|
||||
} // namespace Logging
|
||||
} // namespace Everest
|
||||
Reference in New Issue
Block a user