mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
mapping: rewrote using std::regex
This commit is contained in:
parent
de2b2d627c
commit
a9eb2c1d67
4 changed files with 190 additions and 281 deletions
|
@ -28,6 +28,16 @@
|
|||
#include <villas/stats.hpp>
|
||||
#include <villas/common.hpp>
|
||||
|
||||
#define RE_MAPPING_INDEX "[a-zA-Z0-9_]+"
|
||||
#define RE_MAPPING_RANGE "(" RE_MAPPING_INDEX ")(?:-(" RE_MAPPING_INDEX "))?"
|
||||
|
||||
#define RE_MAPPING_STATS "stats\\.([a-z]+)\\.([a-z]+)"
|
||||
#define RE_MAPPING_HDR "hdr\\.(sequence|length)"
|
||||
#define RE_MAPPING_TS "ts\\.(origin|received)"
|
||||
#define RE_MAPPING_DATA1 "data\\[" RE_MAPPING_RANGE "\\]"
|
||||
#define RE_MAPPING_DATA2 "(?:data\\.)?(" RE_MAPPING_INDEX ")"
|
||||
#define RE_MAPPING "(?:(" RE_NODE_NAME ")\\.(?:" RE_MAPPING_STATS "|" RE_MAPPING_HDR "|" RE_MAPPING_TS "|" RE_MAPPING_DATA1 "|" RE_MAPPING_DATA2 ")|(" RE_NODE_NAME ")(?:\\[" RE_MAPPING_RANGE "\\])?)"
|
||||
|
||||
/* Forward declarations */
|
||||
struct vnode;
|
||||
struct sample;
|
||||
|
@ -52,6 +62,7 @@ enum class MappingTimestampType {
|
|||
};
|
||||
|
||||
struct mapping_entry {
|
||||
const char *node_name;
|
||||
struct vnode *node; /**< The node to which this mapping refers. */
|
||||
|
||||
enum MappingType type; /**< The mapping type. Selects one of the union fields below. */
|
||||
|
@ -67,6 +78,9 @@ struct mapping_entry {
|
|||
struct {
|
||||
int offset;
|
||||
struct signal *signal;
|
||||
|
||||
const char *first;
|
||||
const char *last;
|
||||
} data;
|
||||
|
||||
struct {
|
||||
|
@ -84,16 +98,18 @@ struct mapping_entry {
|
|||
};
|
||||
};
|
||||
|
||||
int mapping_update(const struct mapping_entry *e, struct sample *remapped, const struct sample *original);
|
||||
int mapping_entry_prepare(struct mapping_entry *me, struct vlist *nodes);
|
||||
|
||||
int mapping_parse(struct mapping_entry *e, json_t *cfg, struct vlist *nodes);
|
||||
int mapping_entry_update(const struct mapping_entry *e, struct sample *remapped, const struct sample *original);
|
||||
|
||||
int mapping_parse_str(struct mapping_entry *e, const char *str, struct vlist *nodes);
|
||||
int mapping_entry_parse(struct mapping_entry *e, json_t *cfg);
|
||||
|
||||
int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str);
|
||||
int mapping_entry_parse_str(struct mapping_entry *e, const std::string &str);
|
||||
|
||||
int mapping_list_parse(struct vlist *ml, json_t *cfg, struct vlist *nodes);
|
||||
int mapping_entry_to_str(const struct mapping_entry *me, unsigned index, char **str);
|
||||
|
||||
int mapping_list_prepare(struct vlist *ml);
|
||||
int mapping_list_parse(struct vlist *ml, json_t *cfg);
|
||||
|
||||
int mapping_list_prepare(struct vlist *ml, struct vlist *nodes);
|
||||
|
||||
int mapping_list_remap(const struct vlist *ml, struct sample *remapped, const struct sample *original);
|
||||
|
|
274
lib/mapping.cpp
274
lib/mapping.cpp
|
@ -20,7 +20,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <cstring>
|
||||
#include <regex>
|
||||
#include <iostream>
|
||||
|
||||
#include <villas/mapping.h>
|
||||
#include <villas/sample.h>
|
||||
|
@ -33,162 +34,83 @@
|
|||
using namespace villas;
|
||||
using namespace villas::utils;
|
||||
|
||||
int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *nodes)
|
||||
int mapping_entry_parse_str(struct mapping_entry *me, const std::string &str)
|
||||
{
|
||||
char *cpy, *node, *type, *field, *end, *lasts;
|
||||
std::smatch mr;
|
||||
std::regex re(RE_MAPPING);
|
||||
|
||||
cpy = strdup(str);
|
||||
if (!cpy)
|
||||
return -1;
|
||||
if (!std::regex_match(str, mr, re))
|
||||
goto invalid_format;
|
||||
|
||||
if (nodes) {
|
||||
node = strtok_r(cpy, ".", &lasts);
|
||||
if (!node) {
|
||||
warning("Missing node name");
|
||||
goto invalid_format;
|
||||
}
|
||||
if (mr[1].matched)
|
||||
me->node_name = strdup(mr.str(1).c_str());
|
||||
|
||||
if (mr[9].matched)
|
||||
me->node_name = strdup(mr.str(9).c_str());
|
||||
|
||||
me->node = vlist_lookup_name<struct vnode>(nodes, node);
|
||||
if (!me->node) {
|
||||
warning("Unknown node %s", node);
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
type = strtok_r(nullptr, ".[", &lasts);
|
||||
if (!type)
|
||||
type = strf("data");
|
||||
}
|
||||
else {
|
||||
me->node = nullptr;
|
||||
|
||||
type = strtok_r(cpy, ".[", &lasts);
|
||||
if (!type)
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
if (!strcmp(type, "stats")) {
|
||||
me->type = MappingType::STATS;
|
||||
me->length = 1;
|
||||
|
||||
char *metric = strtok_r(nullptr, ".", &lasts);
|
||||
if (!metric)
|
||||
goto invalid_format;
|
||||
|
||||
type = strtok_r(nullptr, ".", &lasts);
|
||||
if (!type)
|
||||
goto invalid_format;
|
||||
|
||||
me->stats.metric = Stats::lookupMetric(metric);
|
||||
me->stats.type = Stats::lookupType(type);
|
||||
}
|
||||
else if (!strcmp(type, "hdr")) {
|
||||
me->type = MappingType::HEADER;
|
||||
me->length = 1;
|
||||
|
||||
field = strtok_r(nullptr, ".", &lasts);
|
||||
if (!field) {
|
||||
warning("Missing header type");
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
if (!strcmp(field, "sequence"))
|
||||
me->header.type = MappingHeaderType::SEQUENCE;
|
||||
else if (!strcmp(field, "length"))
|
||||
me->header.type = MappingHeaderType::LENGTH;
|
||||
else {
|
||||
warning("Invalid header type");
|
||||
goto invalid_format;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type, "ts")) {
|
||||
me->type = MappingType::TIMESTAMP;
|
||||
me->length = 2;
|
||||
|
||||
field = strtok_r(nullptr, ".", &lasts);
|
||||
if (!field) {
|
||||
warning("Missing timestamp type");
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
if (!strcmp(field, "origin"))
|
||||
me->timestamp.type = MappingTimestampType::ORIGIN;
|
||||
else if (!strcmp(field, "received"))
|
||||
me->timestamp.type = MappingTimestampType::RECEIVED;
|
||||
else {
|
||||
warning("Invalid timestamp type");
|
||||
goto invalid_format;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type, "data")) {
|
||||
char *first_str, *last_str;
|
||||
int first = -1, last = -1;
|
||||
if (mr[6].matched) {
|
||||
me->data.first = strdup(mr.str(6).c_str());
|
||||
|
||||
if (mr[7].matched)
|
||||
me->data.last = strdup(mr.str(7).c_str());
|
||||
|
||||
me->type = MappingType::DATA;
|
||||
}
|
||||
else if (mr[10].matched) {
|
||||
me->data.first = strdup(mr.str(10).c_str());
|
||||
|
||||
if (mr[11].matched)
|
||||
me->data.last = strdup(mr.str(11).c_str());
|
||||
|
||||
first_str = strtok_r(nullptr, "-]", &lasts);
|
||||
if (first_str) {
|
||||
if (me->node)
|
||||
first = vlist_lookup_index<struct signal>(&me->node->in.signals, first_str);
|
||||
me->type = MappingType::DATA;
|
||||
}
|
||||
else if (mr[8].matched) {
|
||||
me->data.first = strdup(mr.str(8).c_str());
|
||||
|
||||
if (first < 0) {
|
||||
char *endptr;
|
||||
first = strtoul(first_str, &endptr, 10);
|
||||
if (endptr != first_str + strlen(first_str)) {
|
||||
warning("Failed to parse data range");
|
||||
goto invalid_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Map all signals */
|
||||
me->data.offset = 0;
|
||||
me->length = -1;
|
||||
goto end;
|
||||
}
|
||||
me->type = MappingType::DATA;
|
||||
}
|
||||
else if (mr[2].matched) {
|
||||
me->stats.type = Stats::lookupType(mr.str(3));
|
||||
me->stats.metric = Stats::lookupMetric(mr.str(2));
|
||||
|
||||
last_str = strtok_r(nullptr, "]", &lasts);
|
||||
if (last_str) {
|
||||
if (me->node)
|
||||
last = vlist_lookup_index<struct signal>(&me->node->in.signals, last_str);
|
||||
|
||||
if (last < 0) {
|
||||
char *endptr;
|
||||
last = strtoul(last_str, &endptr, 10);
|
||||
if (endptr != last_str + strlen(last_str)) {
|
||||
warning("Failed to parse data range");
|
||||
goto invalid_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
me->type = MappingType::STATS;
|
||||
}
|
||||
else if (mr[5].matched) {
|
||||
if (mr.str(5) == "origin")
|
||||
me->timestamp.type = MappingTimestampType::ORIGIN;
|
||||
else if (mr.str(5) == "received")
|
||||
me->timestamp.type = MappingTimestampType::RECEIVED;
|
||||
else
|
||||
last = first; /* single element: data[5] => data[5-5] */
|
||||
|
||||
if (last < first)
|
||||
goto invalid_format;
|
||||
|
||||
me->data.offset = first;
|
||||
me->length = last - first + 1;
|
||||
me->type = MappingType::TIMESTAMP;
|
||||
}
|
||||
else
|
||||
goto invalid_format;
|
||||
else if (mr[4].matched) {
|
||||
if (mr.str(4) == "sequence")
|
||||
me->header.type = MappingHeaderType::SEQUENCE;
|
||||
else if (mr.str(4) == "length")
|
||||
me->header.type = MappingHeaderType::LENGTH;
|
||||
else
|
||||
goto invalid_format;
|
||||
|
||||
end: /* Check that there is no garbage at the end */
|
||||
end = strtok_r(nullptr, "", &lasts);
|
||||
if (end)
|
||||
goto invalid_format;
|
||||
me->type = MappingType::HEADER;
|
||||
}
|
||||
/* Only node name given.. We map all data */
|
||||
else if (me->node_name) {
|
||||
me->data.first = nullptr;
|
||||
me->data.last = nullptr;
|
||||
|
||||
free(cpy);
|
||||
me->type = MappingType::DATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
invalid_format:
|
||||
|
||||
free(cpy);
|
||||
|
||||
return -1;
|
||||
|
||||
throw RuntimeError("Failed to parse mapping expression: {}", str);
|
||||
}
|
||||
|
||||
int mapping_parse(struct mapping_entry *me, json_t *cfg, struct vlist *nodes)
|
||||
int mapping_entry_parse(struct mapping_entry *me, json_t *cfg)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
|
@ -196,10 +118,10 @@ int mapping_parse(struct mapping_entry *me, json_t *cfg, struct vlist *nodes)
|
|||
if (!str)
|
||||
return -1;
|
||||
|
||||
return mapping_parse_str(me, str, nodes);
|
||||
return mapping_entry_parse_str(me, str);
|
||||
}
|
||||
|
||||
int mapping_list_parse(struct vlist *ml, json_t *cfg, struct vlist *nodes)
|
||||
int mapping_list_parse(struct vlist *ml, json_t *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -221,7 +143,7 @@ int mapping_list_parse(struct vlist *ml, json_t *cfg, struct vlist *nodes)
|
|||
if (!me)
|
||||
throw MemoryAllocationError();
|
||||
|
||||
ret = mapping_parse(me, json_entry, nodes);
|
||||
ret = mapping_entry_parse(me, json_entry);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -319,16 +241,76 @@ int mapping_list_remap(const struct vlist *ml, struct sample *remapped, const st
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mapping_list_prepare(struct vlist *ml)
|
||||
int mapping_entry_prepare(struct mapping_entry *me, struct vlist *nodes)
|
||||
{
|
||||
if (me->node_name && me->node == nullptr) {
|
||||
me->node = vlist_lookup_name<struct vnode>(nodes, me->node_name);
|
||||
if (!me->node)
|
||||
throw RuntimeError("Invalid node name in mapping: {}", me->node_name);
|
||||
}
|
||||
|
||||
if (me->type == MappingType::DATA) {
|
||||
int first = -1, last = -1;
|
||||
|
||||
if (me->data.first) {
|
||||
if (me->node)
|
||||
first = vlist_lookup_index<struct signal>(&me->node->in.signals, me->data.first);
|
||||
|
||||
if (first < 0) {
|
||||
char *endptr;
|
||||
first = strtoul(me->data.first, &endptr, 10);
|
||||
if (endptr != me->data.first + strlen(me->data.first))
|
||||
throw RuntimeError("Failed to parse data index in mapping: {}", me->data.first);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Map all signals */
|
||||
me->data.offset = 0;
|
||||
me->length = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (me->data.last) {
|
||||
if (me->node)
|
||||
last = vlist_lookup_index<struct signal>(&me->node->in.signals, me->data.last);
|
||||
|
||||
if (last < 0) {
|
||||
char *endptr;
|
||||
last = strtoul(me->data.last, &endptr, 10);
|
||||
if (endptr != me->data.last + strlen(me->data.last))
|
||||
throw RuntimeError("Failed to parse data index in mapping: {}", me->data.last);
|
||||
}
|
||||
}
|
||||
else
|
||||
last = first; /* single element: data[5] => data[5-5] */
|
||||
|
||||
if (last < first)
|
||||
throw RuntimeError("Invalid data range indices for mapping: {} < {}", last, first);
|
||||
|
||||
me->data.offset = first;
|
||||
me->length = last - first + 1;
|
||||
}
|
||||
|
||||
end:
|
||||
if (me->length < 0) {
|
||||
struct vlist *sigs = node_get_signals(me->node, NodeDir::IN);
|
||||
|
||||
me->length = vlist_length(sigs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mapping_list_prepare(struct vlist *ml, struct vlist *nodes)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (size_t i = 0, off = 0; i < vlist_length(ml); i++) {
|
||||
struct mapping_entry *me = (struct mapping_entry *) vlist_at(ml, i);
|
||||
|
||||
if (me->length < 0) {
|
||||
struct vlist *sigs = node_get_signals(me->node, NodeDir::IN);
|
||||
|
||||
me->length = vlist_length(sigs);
|
||||
}
|
||||
ret = mapping_entry_prepare(me, nodes);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
me->offset = off;
|
||||
off += me->length;
|
||||
|
@ -337,7 +319,7 @@ int mapping_list_prepare(struct vlist *ml)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str)
|
||||
int mapping_entry_to_str(const struct mapping_entry *me, unsigned index, char **str)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, u
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mapping_to_str(me, index, &s->name);
|
||||
ret = mapping_entry_to_str(me, index, &s->name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -34,155 +34,66 @@ Test(mapping, parse_nodes)
|
|||
{
|
||||
int ret;
|
||||
struct mapping_entry m;
|
||||
struct vlist nodes;
|
||||
|
||||
const char *node_names[3] = { "apple", "cherry", "carrot" };
|
||||
const char *signal_names[3][4] = {
|
||||
{ "abra", "kadabra", "simsala", "bimm" },
|
||||
{ "this", "is", "a", "test" },
|
||||
{ "o", "sole", "mio", "italia" }
|
||||
};
|
||||
|
||||
vlist_init(&nodes);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_LEN(node_names); i++) {
|
||||
struct vnode *n = new struct vnode;
|
||||
cr_assert_not_null(n);
|
||||
|
||||
n->name = strdup(node_names[i]);
|
||||
|
||||
vlist_init(&n->in.signals);
|
||||
|
||||
for (unsigned j = 0; j < ARRAY_LEN(signal_names[i]); j++) {
|
||||
struct signal *sig;
|
||||
|
||||
sig = signal_create(signal_names[i][j], nullptr, SignalType::FLOAT);
|
||||
cr_assert_not_null(sig);
|
||||
|
||||
vlist_push(&n->in.signals, sig);
|
||||
}
|
||||
|
||||
vlist_push(&nodes, n);
|
||||
}
|
||||
|
||||
ret = mapping_parse_str(&m, "apple.ts.origin", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "apple.ts.origin");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "apple"));
|
||||
cr_assert_str_eq(m.node_name, "apple");
|
||||
cr_assert_eq(m.type, MappingType::TIMESTAMP);
|
||||
cr_assert_eq(m.timestamp.type, MappingTimestampType::ORIGIN);
|
||||
|
||||
ret = mapping_parse_str(&m, "cherry.stats.owd.mean", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "cherry.stats.owd.mean");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "cherry"));
|
||||
cr_assert_str_eq(m.node_name, "cherry");
|
||||
cr_assert_eq(m.type, MappingType::STATS);
|
||||
cr_assert_eq(m.stats.metric, Stats::Metric::OWD);
|
||||
cr_assert_eq(m.stats.type, Stats::Type::MEAN);
|
||||
|
||||
ret = mapping_parse_str(&m, "carrot.data[1-2]", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "carrot.data[1-2]");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "carrot"));
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 1);
|
||||
cr_assert_eq(m.length, 2);
|
||||
cr_assert_str_eq(m.data.first, "1");
|
||||
cr_assert_str_eq(m.data.last, "2");
|
||||
|
||||
ret = mapping_parse_str(&m, "carrot", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "carrot");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "carrot"));
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 0);
|
||||
cr_assert_eq(m.length, -1);
|
||||
cr_assert_eq(m.data.first, nullptr);
|
||||
cr_assert_eq(m.data.last, nullptr);
|
||||
|
||||
ret = mapping_parse_str(&m, "carrot.data[sole]", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "carrot.data[sole]");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "carrot"));
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 1);
|
||||
cr_assert_eq(m.length, 1);
|
||||
cr_assert_str_eq(m.data.first, "sole");
|
||||
cr_assert_eq(m.data.last, nullptr);
|
||||
|
||||
ret = mapping_parse_str(&m, "carrot.data[sole-mio]", &nodes);
|
||||
ret = mapping_entry_parse_str(&m, "carrot.sole");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.node, vlist_lookup_name<struct vnode>(&nodes, "carrot"));
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 1);
|
||||
cr_assert_eq(m.length, 2);
|
||||
cr_assert_str_eq(m.data.first, "sole");
|
||||
cr_assert_eq(m.data.last, nullptr);
|
||||
|
||||
ret = vlist_destroy(&nodes, nullptr, true);
|
||||
ret = mapping_entry_parse_str(&m, "carrot.data.sole");
|
||||
cr_assert_eq(ret, 0);
|
||||
}
|
||||
|
||||
Test(mapping, parse)
|
||||
{
|
||||
int ret;
|
||||
struct mapping_entry m;
|
||||
|
||||
ret = mapping_parse_str(&m, "ts.origin", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::TIMESTAMP);
|
||||
cr_assert_eq(m.timestamp.type, MappingTimestampType::ORIGIN);
|
||||
|
||||
ret = mapping_parse_str(&m, "hdr.sequence", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::HEADER);
|
||||
cr_assert_eq(m.header.type, MappingHeaderType::SEQUENCE);
|
||||
|
||||
ret = mapping_parse_str(&m, "stats.owd.mean", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::STATS);
|
||||
cr_assert_eq(m.stats.metric, Stats::Metric::OWD);
|
||||
cr_assert_eq(m.stats.type, Stats::Type::MEAN);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[1-2]", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 1);
|
||||
cr_assert_eq(m.length, 2);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[5-5]", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 5);
|
||||
cr_assert_eq(m.length, 1);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[22]", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 22);
|
||||
cr_assert_eq(m.length, 1);
|
||||
|
||||
ret = mapping_parse_str(&m, "data", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 0);
|
||||
cr_assert_eq(m.length, -1);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[]", nullptr);
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_eq(m.data.offset, 0);
|
||||
cr_assert_eq(m.length, -1);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[1.1-2f]", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
/* Missing parts */
|
||||
ret = mapping_parse_str(&m, "stats.owd", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
/* This a type */
|
||||
ret = mapping_parse_str(&m, "hdr.sequences", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
/* Check for superfluous chars at the end */
|
||||
ret = mapping_parse_str(&m, "hdr.ts.origin.bla", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
ret = mapping_parse_str(&m, "hdr.ts.origin.", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
ret = mapping_parse_str(&m, "data[1-2]bla", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
|
||||
/* Negative length of chunk */
|
||||
ret = mapping_parse_str(&m, "data[5-3]", nullptr);
|
||||
cr_assert_neq(ret, 0);
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_str_eq(m.data.first, "sole");
|
||||
cr_assert_eq(m.data.last, nullptr);
|
||||
|
||||
ret = mapping_entry_parse_str(&m, "carrot.data[sole-mio]");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_str_eq(m.data.first, "sole");
|
||||
cr_assert_str_eq(m.data.last, "mio");
|
||||
|
||||
ret = mapping_entry_parse_str(&m, "carrot[sole-mio]");
|
||||
cr_assert_eq(ret, 0);
|
||||
cr_assert_str_eq(m.node_name, "carrot");
|
||||
cr_assert_eq(m.type, MappingType::DATA);
|
||||
cr_assert_str_eq(m.data.first, "sole");
|
||||
cr_assert_str_eq(m.data.last, "mio");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue