Commits (52)
/build*/
......@@ -49,3 +49,28 @@ test:unit:
image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG_DEV}
tags:
- docker
test:cppcheck:
stage: test
script:
- cppcheck -j $(nproc)
--max-configs=32
--error-exitcode=1
--quiet
--inline-suppr
--enable=warning,performance,portability,information,missingInclude
--suppress=noValidConfiguration
--std=c++11
-I include
lib/
tests/unit/ | tee cppcheck.log
image: ${DOCKER_IMAGE_DEV}:${DOCKER_TAG_DEV}
dependencies:
- build:source
tags:
- docker
artifacts:
when: on_failure
paths:
- cppcheck.log
expose_as: cppcheck
## CMakeLists.txt
#
# @author Daniel Krebs <github@daniel-krebs.net>
# @copyright 2014-2020, RWTH Institute for Automation of Complex Power Systems (ACS)
# @copyright 2014-2021, RWTH Institute for Automation of Complex Power Systems (ACS)
# @license GNU General Public License (version 3)
#
# VILLAScommon
......@@ -28,7 +28,7 @@ project(villas-common
# Some more project settings
set(PROJECT_AUTHOR "Steffen Vogel")
set(PROJECT_COPYRIGHT "2014-2020, Institute for Automation of Complex Power Systems, RWTH Aachen University")
set(PROJECT_COPYRIGHT "2014-2021, Institute for Automation of Complex Power Systems, RWTH Aachen University")
set(PROJECT_HOMEPAGE_URL "https://git.rwth-aachen.de/acs/public/villas/VILLAScommon")
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
......@@ -61,6 +61,7 @@ find_package(Criterion)
pkg_check_modules(JANSSON IMPORTED_TARGET REQUIRED jansson>=2.7)
pkg_check_modules(LIBCONFIG IMPORTED_TARGET libconfig>=1.4.9)
pkg_check_modules(UUID IMPORTED_TARGET REQUIRED uuid>=2.23)
add_subdirectory(lib)
if(CRITERION_FOUND AND TOPLEVEL_PROJECT)
......
......@@ -9,7 +9,7 @@
# make docker
#
# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
# @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
# @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
# @license GNU General Public License (version 3)
#
# VILLAScommon
......@@ -28,7 +28,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
###################################################################################
FROM fedora:32
FROM fedora:33
LABEL \
org.label-schema.schema-version="1.0" \
......@@ -46,6 +46,7 @@ LABEL \
RUN dnf -y install \
gcc gcc-c++ \
make cmake \
cppcheck \
pkgconfig git curl tar
# Dependencies
......@@ -53,6 +54,9 @@ RUN dnf -y install \
jansson-devel \
libcurl-devel \
libconfig-devel \
libuuid-devel \
spdlog-devel \
fmt-devel \
openssl-devel openssl
# Build & Install Criterion
......@@ -63,22 +67,6 @@ RUN cd /tmp && \
cmake -DCMAKE_INSTALL_LIBDIR=/usr/local/lib64 .. && make install && \
rm -rf /tmp/*
# Build & Install Fmtlib
RUN cd /tmp && \
git clone --recursive https://github.com/fmtlib/fmt.git && \
mkdir -p fmt/build && cd fmt/build && \
git checkout 5.2.0 && \
cmake -DBUILD_SHARED_LIBS=1 .. && make install && \
rm -rf /tmp/*
# Build & Install spdlog
RUN cd /tmp && \
git clone --recursive https://github.com/gabime/spdlog.git && \
mkdir -p spdlog/build && cd spdlog/build && \
git checkout v1.3.1 && \
cmake -DSPDLOG_FMT_EXTERNAL=ON -DSPDLOG_BUILD_BENCH=OFF .. && make install && \
rm -rf /tmp/*
ENV LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib64
WORKDIR /villas
......@@ -10,7 +10,7 @@ User documentation is available here: <https://villas.fein-aachen.org/doc/>
## Copyright
2014-2020, Institute for Automation of Complex Power Systems, EONERC
2014-2021, Institute for Automation of Complex Power Systems, EONERC
## License
......
# CMakeLists.txt.
#
# @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
# @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
# @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
# @license GNU General Public License (version 3)
#
# VILLASnode
......
/** libcurl based advanced IO aka ADVIO.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#pragma once
#include <cstdio>
#include <curl/curl.h>
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
struct advio {
CURL *curl;
FILE *file;
long uploaded; /**< Upload progress. How much has already been uploaded to the remote file. */
long downloaded; /**< Download progress. How much has already been downloaded from the remote file. */
int completed:1; /**< Was the upload completd */
unsigned char hash[SHA_DIGEST_LENGTH];
char mode[3];
char *uri;
};
typedef struct advio AFILE;
/* The remaining functions from stdio are just replaced macros */
#define afeof(af) feof((af)->file)
#define afgets(ln, sz, af) fgets(ln, sz, (af)->file)
#define aftell(af) ftell((af)->file)
#define afileno(af) fileno((af)->file)
#define afread(ptr, sz, nitems, af) fread(ptr, sz, nitems, (af)->file)
#define afwrite(ptr, sz, nitems, af) fwrite(ptr, sz, nitems, (af)->file)
#define afputs(ptr, af) fputs(ptr, (af)->file)
#define afprintf(af, fmt, ...) fprintf((af)->file, fmt, __VA_ARGS__)
#define afscanf(af, fmt, ...) fprintf((af)->file, fmt, __VA_ARGS__)
#define agetline(linep, linecapp, af) getline(linep, linecapp, (af)->file)
/* Extensions */
#define auri(af) ((af)->uri)
#define ahash(af) ((af)->hash)
/** Check if a URI is pointing to a local file. */
int aislocal(const char *uri);
AFILE *afopen(const char *url, const char *mode);
int afclose(AFILE *file);
int afflush(AFILE *file);
int afseek(AFILE *file, long offset, int origin);
void arewind(AFILE *file);
/** Download contens from remote file
*
* @param resume Do a partial download and append to the local file
*/
int adownload(AFILE *af, int resume);
int aupload(AFILE *af, int resume);
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASnode
......@@ -65,4 +65,4 @@
#define BOX_UL "+" /**< Boxdrawing: ┘ */
#define BOX_DLR "+" /**< Boxdrawing: ┘ */
#define BOX_DL "+" /**< Boxdrawing: ┘ */
#endif
\ No newline at end of file
#endif
/** A simple growing buffer.
/** A simple buffer for encoding streamed JSON messages.
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......@@ -23,32 +23,38 @@
#pragma once
#include <vector>
#include <cstdlib>
#include <jansson.h>
#include <villas/common.hpp>
namespace villas {
class Buffer {
class Buffer : public std::vector<char> {
public:
char *buf;
size_t len;
size_t size;
protected:
static int callback(const char *data, size_t len, void *ctx);
Buffer(size_t size);
~Buffer();
public:
Buffer(const char *buf, size_type len) :
std::vector<char>(buf, buf+len)
{ }
void clear();
Buffer(size_type count = 0) :
std::vector<char>(count, 0)
{ }
int append(const char *data, size_t len);
/** Encode JSON document /p j and append it to the buffer */
int encode(json_t *j, int flags = 0);
int parseJson(json_t **j);
/** Decode JSON document from the beginning of the buffer */
json_t * decode();
int appendJson(json_t *j);
void append(const char *data, size_t len)
{
insert(end(), data, data + len);
}
};
} /* namespace villas */
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......
/** Compatability for different library versions.
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......
......@@ -5,7 +5,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......@@ -42,7 +42,8 @@
#define PROJECT_HOMEPAGE_URL "@CMAKE_PROJECT_HOMEPAGE_URL@"
#define PROJECT_NAME "@CMAKE_PROJECT_DESCRIPTION@"
#define USER_AGENT "@CMAKE_PROJECT_DESCRIPTION@ (@CMAKE_PROJECT_BUILD_ID@)"
#define HTTP_USER_AGENT PROJECT_NAME " (" PROJECT_BUILD_ID ")"
/* Paths */
#define PREFIX "@CMAKE_INSTALL_PREFIX@"
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <github@daniel-krebs.net>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......@@ -50,7 +50,7 @@ public:
setp = CPU_ALLOC(num_cpus);
if (!setp)
throw villas::RuntimeError("Failed to allocated memory");
throw MemoryAllocationError();
zero();
}
......@@ -167,17 +167,12 @@ public:
return lhs;
}
//bool& operator[](std::size_t cpu)
//{
// void cpuset_set_cpu(cpuset_t*setp, cpu_t cpu, int state)
//}
bool operator[](size_t cpu) const
{
return isset(cpu);
return isSet(cpu);
}
bool isset(size_t cpu) const
bool isSet(size_t cpu) const
{
return CPU_ISSET_S(cpu, sz, setp);
}
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......@@ -30,27 +30,27 @@ class PID {
protected:
double dt;
double max;
double min;
double Kp;
double Kd;
double Ki;
double pre_error;
double integral;
double max;
double min;
double Kp;
double Kd;
double Ki;
double pre_error;
double integral;
public:
/**
/**
* Kp - proportional gain
* Ki - Integral gain
* Kd - derivative gain
* dt - loop interval time
* max - maximum value of manipulated variable
* min - minimum value of manipulated variable
* Ki - Integral gain
* Kd - derivative gain
* dt - loop interval time
* max - maximum value of manipulated variable
* min - minimum value of manipulated variable
*/
PID(double _dt, double _max, double _min, double _Kp, double _Kd, double _Ki);
PID(double _dt, double _max, double _min, double _Kp, double _Kd, double _Ki);
/** Returns the manipulated variable given a setpoint and current process value */
double calculate(double setpoint, double pv);
/** Returns the manipulated variable given a setpoint and current process value */
double calculate(double setpoint, double pv);
};
} /* namespace dsp */
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLASnode
......@@ -62,6 +62,14 @@ public:
{ }
};
class MemoryAllocationError : public RuntimeError {
public:
MemoryAllocationError() :
RuntimeError("Failed to allocate memory")
{ }
};
class JsonError : public std::runtime_error {
protected:
......@@ -93,20 +101,54 @@ protected:
json_t *setting;
json_error_t error;
char *msg;
std::string getMessage() const
{
std::stringstream ss;
ss << std::runtime_error::what() << std::endl;
ss << std::endl << " Please consult the user documentation for details: " << std::endl;
ss << " " << docUri();
if (error.position >= 0) {
ss << std::endl;
ss << " " << error.text << " in " << error.source << ":" << error.line << ":" << error.column;
}
ss << std::endl;
return ss.str();
}
public:
~ConfigError()
{
if (msg)
free(msg);
}
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) :
std::runtime_error(fmt::format(what, std::forward<Args>(args)...)),
id(i),
setting(s)
{ }
{
error.position = -1;
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 = "Failed to parse configuration") :
......@@ -114,7 +156,11 @@ public:
id(i),
setting(s),
error(e)
{ }
{
error.position = -1;
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) :
......@@ -122,7 +168,11 @@ public:
id(i),
setting(s),
error(e)
{ }
{
error.position = -1;
msg = strdup(getMessage().c_str());
}
std::string docUri() const
{
......@@ -133,14 +183,7 @@ public:
virtual const char * what() const noexcept
{
std::stringstream ss;
ss << std::runtime_error::what() << std::endl;
ss << " Please consult the user documentation for details: " << docUri();
auto str = new std::string(ss.str());
return str->c_str();
return msg;
}
};
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Daniel Krebs <github@daniel-krebs.net>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......@@ -50,10 +50,10 @@ public:
using Path = std::list<EdgeIdentifier>;
DirectedGraph(const std::string &name = "DirectedGraph") :
lastVertexId(0), lastEdgeId(0)
{
logger = logging.get(name);
}
lastVertexId(0),
lastEdgeId(0),
logger(logging.get(name))
{ }
std::shared_ptr<VertexType> getVertex(VertexIdentifier vertexId) const
{
......
......@@ -2,7 +2,7 @@
*
* @file
* @author Daniel Krebs <github@daniel-krebs.net>
* @copyright 2014-2020, Institute for Automation of Complex Power Systems, EONERC
* @copyright 2014-2021, Institute for Automation of Complex Power Systems, EONERC
* @license GNU General Public License (version 3)
*
* VILLAScommon
......