diff --git a/include/villas/path.h b/include/villas/path.h index 8e47612cd..622c263a3 100644 --- a/include/villas/path.h +++ b/include/villas/path.h @@ -172,6 +172,8 @@ int path_uses_node(struct path *p, struct node *n); */ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes); +int path_is_simple(struct path *p); + /** @} */ #ifdef __cplusplus diff --git a/lib/path.c b/lib/path.c index 95af22e36..c1ffee1cd 100644 --- a/lib/path.c +++ b/lib/path.c @@ -921,50 +921,22 @@ int path_uses_node(struct path *p, struct node *n) return -1; } -int path_reverse(struct path *p, struct path *r) +int path_is_simple(struct path *p) { - if (vlist_length(&p->destinations) != 1 || vlist_length(&p->sources) != 1) - return -1; + int ret; + const char *in = NULL, *out = NULL; - /* General */ - r->enabled = p->enabled; + ret = json_unpack(p->cfg, "{ s: s, s: s }", "in", &in, "out", &out); + if (ret) + return ret; - /* Source / Destinations */ - struct path_destination *orig_pd = vlist_first(&p->destinations); - struct path_source *orig_ps = vlist_first(&p->sources); + ret = node_is_valid_name(in); + if (ret) + return ret; - struct path_destination *new_pd = (struct path_destination *) alloc(sizeof(struct path_destination)); - struct path_source *new_ps = (struct path_source *) alloc(sizeof(struct path_source)); - struct mapping_entry *new_me = alloc(sizeof(struct mapping_entry)); - new_pd->node = orig_ps->node; - new_ps->node = orig_pd->node; - new_ps->masked = true; - - new_me->node = new_ps->node; - new_me->type = MAPPING_TYPE_DATA; - new_me->data.offset = 0; - new_me->length = vlist_length(&new_me->node->in.signals); - - vlist_init(&new_ps->mappings); - vlist_push(&new_ps->mappings, new_me); - - vlist_push(&r->destinations, new_pd); - vlist_push(&r->sources, new_ps); - -#ifdef WITH_HOOKS - for (size_t i = 0; i < vlist_length(&p->hooks); i++) { - int ret; - - struct hook *h = (struct hook *) vlist_at(&p->hooks, i); - struct hook *g = (struct hook *) alloc(sizeof(struct hook)); - - ret = hook_init(g, h->_vt, r, NULL); - if (ret) - return ret; - - vlist_push(&r->hooks, g); - } -#endif /* WITH_HOOKS */ + ret = node_is_valid_name(out); + if (ret) + return ret; return 0; } diff --git a/lib/super_node.cpp b/lib/super_node.cpp index 313d131d9..180636f27 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -251,7 +251,7 @@ int SuperNode::parseJson(json_t *j) size_t i; json_t *json_path; json_array_foreach(json_paths, i, json_path) { - path *p = (path *) alloc(sizeof(path)); +parse: path *p = (path *) alloc(sizeof(path)); ret = path_init(p); if (ret) @@ -264,17 +264,25 @@ int SuperNode::parseJson(json_t *j) vlist_push(&paths, p); if (p->reverse) { - path *r = (path *) alloc(sizeof(path)); - - ret = path_init(r); + /* Only simple paths can be reversed */ + ret = path_is_simple(p); if (ret) - throw RuntimeError("Failed to init path"); + throw RuntimeError("Complex paths can not be reversed!"); - ret = path_reverse(p, r); - if (ret) - throw RuntimeError("Failed to reverse path {}", path_name(p)); + /* Parse a second time with in/out reversed */ + json_path = json_copy(json_path); - vlist_push(&paths, r); + json_t *json_in = json_object_get(json_path, "in"); + json_t *json_out = json_object_get(json_path, "out"); + + if (json_equal(json_in, json_out)) + throw RuntimeError("Can not reverse path with identical in/out nodes!"); + + json_object_set(json_path, "reverse", json_false()); + json_object_set(json_path, "in", json_out); + json_object_set(json_path, "out", json_in); + + goto parse; } } }