Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ variables:
DOCKER_IMAGE_DEV: ${DOCKER_IMAGE}/dev-${DISTRO}
DOCKER_CLI_EXPERIMENTAL: enabled
CMAKE_BUILD_OPTS: "--parallel 16"
CMAKE_EXTRA_OPTS: "-DCMAKE_BUILD_TYPE=Release -DVILLAS_COMPILE_WARNING_AS_ERROR=ON"
CMAKE_EXTRA_OPTS: "-DCMAKE_BUILD_TYPE=Release"
CACHIX_CACHE_NAME: villas

stages:
Expand Down Expand Up @@ -101,8 +101,12 @@ build:source:
parallel:
matrix:
- DISTRO: [fedora, fedora-minimal, debian, rocky, ubuntu]
- DISTRO: fedora
CMAKE_EXTRA_OPTS: >
-DVILLAS_COMPILE_WARNING_AS_ERROR=ON
- DISTRO: fedora-minimal
CMAKE_EXTRA_OPTS: -DVILLAS_COMPILE_WARNING_AS_ERROR=ON
CMAKE_EXTRA_OPTS: >
-DVILLAS_COMPILE_WARNING_AS_ERROR=ON
-DWITH_API=OFF
-DWITH_CLIENTS=OFF
-DWITH_CONFIG=OFF
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set(PROJECT_COPYRIGHT "2014-2025 The VILLASframework Authors")

# Several CMake settings/defaults
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake;${PROJECT_SOURCE_DIR}/common/cmake")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Expand Down
40 changes: 13 additions & 27 deletions common/include/villas/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,17 @@ namespace villas {
class SystemError : public std::system_error {

public:
SystemError(const std::string &what)
: std::system_error(errno, std::system_category(), what) {}

template <typename... Args>
SystemError(const std::string &what, Args &&...args)
: SystemError(fmt::format(what, std::forward<Args>(args)...)) {}
SystemError(fmt::format_string<Args...> what, Args &&...args)
: std::system_error(errno, std::system_category(),
fmt::format(what, std::forward<Args>(args)...)) {}
};

class RuntimeError : public std::runtime_error {

public:
template <typename... Args>
RuntimeError(const std::string &what, Args &&...args)
RuntimeError(fmt::format_string<Args...> what, Args &&...args)
: std::runtime_error(fmt::format(what, std::forward<Args>(args)...)) {}
};

Expand Down Expand Up @@ -98,17 +96,10 @@ class ConfigError : public std::runtime_error {
}

template <typename... Args>
ConfigError(json_t *s, const std::string &i,
const std::string &what = "Failed to parse configuration")
: std::runtime_error(what), id(i), setting(s) {
error.position = -1;

msg = strdup(getMessage().c_str());
}

template <typename... Args>
ConfigError(json_t *s, const std::string &i, const std::string &what,
Args &&...args)
ConfigError(
json_t *s, const std::string &i,
fmt::format_string<Args...> what = "Failed to parse configuration",
Args &&...args)
: std::runtime_error(fmt::format(what, std::forward<Args>(args)...)),
id(i), setting(s) {
error.position = -1;
Expand All @@ -117,15 +108,10 @@ class ConfigError : public std::runtime_error {
}

template <typename... Args>
ConfigError(json_t *s, const json_error_t &e, const std::string &i,
const std::string &what = "Failed to parse configuration")
: std::runtime_error(what), id(i), setting(s), error(e) {
msg = strdup(getMessage().c_str());
}

template <typename... Args>
ConfigError(json_t *s, const json_error_t &e, const std::string &i,
const std::string &what, Args &&...args)
ConfigError(
json_t *s, const json_error_t &e, const std::string &i,
fmt::format_string<Args...> what = "Failed to parse configuration",
Args &&...args)
: std::runtime_error(fmt::format(what, std::forward<Args>(args)...)),
id(i), setting(s), error(e) {
msg = strdup(getMessage().c_str());
Expand All @@ -137,7 +123,7 @@ class ConfigError : public std::runtime_error {
return baseUri + id;
}

virtual const char *what() const noexcept { return msg; }
const char *what() const noexcept override { return msg; }
};

} // namespace villas
2 changes: 1 addition & 1 deletion common/lib/kernel/devices/ip_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ IpDevice IpDevice::from(const fs::path unsafe_path) {
if (!is_path_valid(unsafe_path))
throw RuntimeError(
"Path {} failed validation as IpDevicePath [adress in hex].[name] ",
unsafe_path.u8string());
unsafe_path.string());
return IpDevice(unsafe_path);
}

Expand Down
5 changes: 3 additions & 2 deletions common/lib/kernel/devices/linux_driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ void LinuxDriver::bind(const Device &device) const {
}

std::string LinuxDriver::name() const {
size_t pos = path.u8string().rfind('/');
return path.u8string().substr(pos + 1);
auto string = path.string();
size_t pos = string.rfind('/');
return string.substr(pos + 1);
}

void LinuxDriver::override(const Device &device) const {
Expand Down
6 changes: 3 additions & 3 deletions common/lib/kernel/devices/platform_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ std::optional<std::unique_ptr<Driver>> PlatformDevice::driver() const {
}

std::optional<int> PlatformDevice::iommu_group() const {
fs::path symlink = fs::path(this->m_path.u8string() + "/iommu_group");
fs::path symlink = fs::path(this->m_path.string() + "/iommu_group");

fs::path link = fs::read_symlink(symlink);
std::string delimiter = "iommu_groups/";
int pos = link.u8string().find(delimiter);
int iommu_group = std::stoi(link.u8string().substr(pos + delimiter.length()));
int pos = link.string().find(delimiter);
int iommu_group = std::stoi(link.string().substr(pos + delimiter.length()));
return std::make_optional<int>(iommu_group);
}

Expand Down
12 changes: 6 additions & 6 deletions common/lib/kernel/vfio_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ std::shared_ptr<Device> Container::attachDevice(devices::PciDevice &pdev) {
} catch (std::exception &e) {

throw RuntimeError(
e.what() +
std::string(
"\nBAR of device is in inconsistent state. Rewriting the BAR "
"failed. This can happend due to missing privileges or bad device "
"state. Consider running with root privileges or remove, rescan "
"and reset the device."));
"{}\n"
"BAR of device is in inconsistent state. Rewriting the BAR \n"
"failed. This can happen due to missing privileges or bad \n"
"device state. Consider running with root privileges or remove, \n"
"rescan and reset the device.\n",
e.what());
}

// Get IOMMU group of device
Expand Down
8 changes: 4 additions & 4 deletions common/lib/table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ void Table::header() {
auto &column = columns[i];

auto leftAligned = column.align == TableColumn::Alignment::LEFT;
line1 += fmt::format(leftAligned ? CLR_BLD(" {0:<{1}.{1}s}")
: CLR_BLD(" {0:>{1}.{1}s}"),
line1 += fmt::format(fmt::runtime(leftAligned ? CLR_BLD(" {0:<{1}.{1}s}")
: CLR_BLD(" {0:>{1}.{1}s}")),
column.title, column._width);
line2 += fmt::format(leftAligned ? CLR_YEL(" {0:<{1}.{1}s}")
: CLR_YEL(" {0:>{1}.{1}s}"),
line2 += fmt::format(fmt::runtime(leftAligned ? CLR_YEL(" {0:<{1}.{1}s}")
: CLR_YEL(" {0:>{1}.{1}s}")),
column.unit, column._width);

for (int j = 0; j < column._width + 2; j++) {
Expand Down
6 changes: 2 additions & 4 deletions common/lib/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
#include <cctype>
#include <cmath>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

Expand Down Expand Up @@ -355,8 +353,8 @@ bool isPrivileged() {
}

void write_to_file(std::string data, const fs::path file) {
villas::Log::get("Filewriter")->debug("{} > {}", data, file.u8string());
std::ofstream outputFile(file.u8string());
villas::Log::get("Filewriter")->debug("{} > {}", data, file.string());
std::ofstream outputFile(file.string());

if (outputFile.is_open()) {
outputFile << data;
Expand Down
6 changes: 3 additions & 3 deletions fpga/include/villas/fpga/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ class BufferedSampleFormatterShort : public BufferedSampleFormatter {
size_t chars;
if ((chars = std::snprintf(nextBufPos(), formatStringSize + 1, formatString,
value)) > (int)formatStringSize) {
throw RuntimeError("Output buffer too small. Expected " +
std::to_string(formatStringSize) +
" characters, got " + std::to_string(chars));
throw RuntimeError(
"Output buffer too small. Expected {} characters, got {}",
formatStringSize, chars);
}
}

Expand Down
8 changes: 2 additions & 6 deletions fpga/src/villas-fpga-ctrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <algorithm>
#include <bit>
#include <iostream>
#include <string>
#include <thread>
Expand Down Expand Up @@ -108,11 +108,7 @@ void readFromDmaToStdOut(
try {
for (size_t i = 0; i * 4 < c.bytes; i++) {
int32_t ival = mem[cur][i];
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
float fval =
*((float *)(&ival)); // cppcheck-suppress invalidPointerCast
#pragma GCC diagnostic pop
float fval = std::bit_cast<float>(ival);
formatter->format(fval);
printf("%d: %#x\n", cnt++, ival);
}
Expand Down
34 changes: 11 additions & 23 deletions include/villas/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,24 @@ class Error : public RuntimeError {

public:
template <typename... Args>
Error(int c = HTTP_STATUS_INTERNAL_SERVER_ERROR,
const std::string &msg = "Invalid API request", Args &&...args)
: RuntimeError(msg, std::forward<Args>(args)...), code(c), json(nullptr) {
}
Error(int c = HTTP_STATUS_INTERNAL_SERVER_ERROR, json_t *json = nullptr,
fmt::format_string<Args...> what = "Invalid API request",
Args &&...args)
: RuntimeError(what, std::forward<Args>(args)...), code(c), json(json) {}

template <typename... Args>
Error(int c = HTTP_STATUS_INTERNAL_SERVER_ERROR,
const std::string &msg = "Invalid API request",
const char *fmt = nullptr, Args &&...args)
: RuntimeError(msg), code(c),
json(fmt ? json_pack(fmt, std::forward<Args>(args)...) : nullptr) {}
static Error badRequest(json_t *json = nullptr,
fmt::format_string<Args...> what = "Bad API request",
Args &&...args) {
return {HTTP_STATUS_BAD_REQUEST, json, what, std::forward<Args>(args)...};
}

static Error invalidMethod(Request *req);

int code;
json_t *json;
};

class BadRequest : public Error {

public:
template <typename... Args>
BadRequest(const std::string &msg = "Bad API request", Args &&...args)
: Error(HTTP_STATUS_BAD_REQUEST, msg, std::forward<Args>(args)...) {}
};

class InvalidMethod : public BadRequest {

public:
InvalidMethod(Request *req);
};

} // namespace api

// Forward declarations
Expand Down
1 change: 0 additions & 1 deletion include/villas/config_class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

#include <cstdio>
#include <functional>
#include <regex>

#include <jansson.h>
#include <unistd.h>
Expand Down
9 changes: 5 additions & 4 deletions lib/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ using namespace villas;
using namespace villas::node;
using namespace villas::node::api;

InvalidMethod::InvalidMethod(Request *req)
: BadRequest("The '{}' API endpoint does not support {} requests",
req->factory->getName(),
Session::methodToString(req->method)) {}
Error Error::invalidMethod(Request *req) {
return badRequest(
nullptr, "The '{}' API endpoint does not support {} requests",
req->factory->getName(), Session::methodToString(req->method));
}

Api::Api(SuperNode *sn)
: logger(Log::get("api")), state(State::INITIALIZED), super_node(sn) {}
Expand Down
8 changes: 5 additions & 3 deletions lib/api/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using namespace villas::node::api;
void Request::decode() {
body = buffer.decode();
if (!body)
throw BadRequest("Failed to decode request payload");
throw Error::badRequest(nullptr, "Failed to decode request payload");
}

std::string Request::toString() {
Expand Down Expand Up @@ -46,6 +46,8 @@ Request *RequestFactory::create(Session *s, const std::string &uri,
return p;
}

throw BadRequest("Unknown API request", "{ s: s, s: s }", "uri", uri.c_str(),
"method", Session::methodToString(meth).c_str());
throw Error::badRequest(json_pack("{ s: s, s: s }", "uri", uri.c_str(),
"method",
Session::methodToString(meth).c_str()),
"Unknown API request");
}
5 changes: 3 additions & 2 deletions lib/api/requests/capabiltities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ class CapabilitiesRequest : public Request {

Response *execute() override {
if (method != Session::Method::GET)
throw InvalidMethod(this);
throw Error::invalidMethod(this);

if (body != nullptr)
throw BadRequest("Capabilities endpoint does not accept any body data");
throw Error::badRequest(
nullptr, "Capabilities endpoint does not accept any body data");

auto *json_capabilities = getCapabilities();

Expand Down
5 changes: 3 additions & 2 deletions lib/api/requests/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ class ConfigRequest : public Request {
json_t *json = session->getSuperNode()->getConfig();

if (method != Session::Method::GET)
throw InvalidMethod(this);
throw Error::invalidMethod(this);

if (body != nullptr)
throw BadRequest("Config endpoint does not accept any body data");
throw Error::badRequest(nullptr,
"Config endpoint does not accept any body data");

auto *json_config = json ? json_incref(json) : json_object();

Expand Down
9 changes: 5 additions & 4 deletions lib/api/requests/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ class GraphRequest : public Request {

Response *execute() override {
if (method != Session::Method::GET)
throw InvalidMethod(this);
throw Error::invalidMethod(this);

if (body != nullptr)
throw BadRequest("Status endpoint does not accept any body data");
throw Error::badRequest(nullptr,
"Status endpoint does not accept any body data");

auto *sn = session->getSuperNode();
auto *graph = sn->getGraph();
Expand All @@ -59,12 +60,12 @@ class GraphRequest : public Request {
auto lit =
std::find(supportedLayouts.begin(), supportedLayouts.end(), layout);
if (lit == supportedLayouts.end())
throw BadRequest("Unsupported layout: {}", layout);
throw Error::badRequest(nullptr, "Unsupported layout: {}", layout);

auto fit =
std::find(supportedFormats.begin(), supportedFormats.end(), format);
if (fit == supportedFormats.end())
throw BadRequest("Unsupported format: {}", format);
throw Error::badRequest(nullptr, "Unsupported format: {}", format);

std::string ct = "text/plain";
if (format == "svg")
Expand Down
Loading