api documentation for ec_parse
[protos/libecoli.git] / src / ecoli_parse.c
index b32dafb..7b36ed5 100644 (file)
 
 EC_LOG_TYPE_REGISTER(parse);
 
-TAILQ_HEAD(ec_parse_list, ec_parse);
+TAILQ_HEAD(ec_pnode_list, ec_pnode);
 
-struct ec_parse {
-       TAILQ_ENTRY(ec_parse) next;
-       struct ec_parse_list children;
-       struct ec_parse *parent;
+struct ec_pnode {
+       TAILQ_ENTRY(ec_pnode) next;
+       struct ec_pnode_list children;
+       struct ec_pnode *parent;
        const struct ec_node *node;
        struct ec_strvec *strvec;
        struct ec_dict *attrs;
 };
 
-static int __ec_node_parse_child(const struct ec_node *node,
-                               struct ec_parse *state,
+static int __ec_parse_child(const struct ec_node *node,
+                               struct ec_pnode *pstate,
                                bool is_root, const struct ec_strvec *strvec)
 {
        struct ec_strvec *match_strvec;
-       struct ec_parse *child = NULL;
+       struct ec_pnode *child = NULL;
        int ret;
 
        // XXX limit max number of recursions to avoid segfault
@@ -50,13 +50,13 @@ static int __ec_node_parse_child(const struct ec_node *node,
        }
 
        if (!is_root) {
-               child = ec_parse(node);
+               child = ec_pnode(node);
                if (child == NULL)
                        return -1;
 
-               ec_parse_link_child(state, child);
+               ec_pnode_link_child(pstate, child);
        } else {
-               child = state;
+               child = pstate;
        }
        ret = ec_node_type(node)->parse(node, child, strvec);
        if (ret < 0)
@@ -64,8 +64,8 @@ static int __ec_node_parse_child(const struct ec_node *node,
 
        if (ret == EC_PARSE_NOMATCH) {
                if (!is_root) {
-                       ec_parse_unlink_child(state, child);
-                       ec_parse_free(child);
+                       ec_pnode_unlink_child(child);
+                       ec_pnode_free(child);
                }
                return ret;
        }
@@ -80,42 +80,41 @@ static int __ec_node_parse_child(const struct ec_node *node,
 
 fail:
        if (!is_root) {
-               ec_parse_unlink_child(state, child);
-               ec_parse_free(child);
+               ec_pnode_unlink_child(child);
+               ec_pnode_free(child);
        }
        return -1;
 }
 
-int ec_node_parse_child(const struct ec_node *node, struct ec_parse *state,
+int ec_parse_child(const struct ec_node *node, struct ec_pnode *pstate,
                        const struct ec_strvec *strvec)
 {
-       assert(state != NULL);
-       return __ec_node_parse_child(node, state, false, strvec);
+       assert(pstate != NULL);
+       return __ec_parse_child(node, pstate, false, strvec);
 }
 
-// XXX what is returned if no match ??
-struct ec_parse *ec_node_parse_strvec(const struct ec_node *node,
+struct ec_pnode *ec_parse_strvec(const struct ec_node *node,
                                const struct ec_strvec *strvec)
 {
-       struct ec_parse *parse = ec_parse(node);
+       struct ec_pnode *pnode = ec_pnode(node);
        int ret;
 
-       if (parse == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       ret = __ec_node_parse_child(node, parse, true, strvec);
+       ret = __ec_parse_child(node, pnode, true, strvec);
        if (ret < 0) {
-               ec_parse_free(parse);
+               ec_pnode_free(pnode);
                return NULL;
        }
 
-       return parse;
+       return pnode;
 }
 
-struct ec_parse *ec_node_parse(const struct ec_node *node, const char *str)
+struct ec_pnode *ec_parse(const struct ec_node *node, const char *str)
 {
        struct ec_strvec *strvec = NULL;
-       struct ec_parse *parse = NULL;
+       struct ec_pnode *pnode = NULL;
 
        errno = ENOMEM;
        strvec = ec_strvec();
@@ -125,56 +124,56 @@ struct ec_parse *ec_node_parse(const struct ec_node *node, const char *str)
        if (ec_strvec_add(strvec, str) < 0)
                goto fail;
 
-       parse = ec_node_parse_strvec(node, strvec);
-       if (parse == NULL)
+       pnode = ec_parse_strvec(node, strvec);
+       if (pnode == NULL)
                goto fail;
 
        ec_strvec_free(strvec);
-       return parse;
+       return pnode;
 
  fail:
        ec_strvec_free(strvec);
-       ec_parse_free(parse);
+       ec_pnode_free(pnode);
        return NULL;
 }
 
-struct ec_parse *ec_parse(const struct ec_node *node)
+struct ec_pnode *ec_pnode(const struct ec_node *node)
 {
-       struct ec_parse *parse = NULL;
+       struct ec_pnode *pnode = NULL;
 
-       parse = ec_calloc(1, sizeof(*parse));
-       if (parse == NULL)
+       pnode = ec_calloc(1, sizeof(*pnode));
+       if (pnode == NULL)
                goto fail;
 
-       TAILQ_INIT(&parse->children);
+       TAILQ_INIT(&pnode->children);
 
-       parse->node = node;
-       parse->attrs = ec_dict();
-       if (parse->attrs == NULL)
+       pnode->node = node;
+       pnode->attrs = ec_dict();
+       if (pnode->attrs == NULL)
                goto fail;
 
-       return parse;
+       return pnode;
 
  fail:
-       if (parse != NULL)
-               ec_dict_free(parse->attrs);
-       ec_free(parse);
+       if (pnode != NULL)
+               ec_dict_free(pnode->attrs);
+       ec_free(pnode);
 
        return NULL;
 }
 
-static struct ec_parse *
-__ec_parse_dup(const struct ec_parse *root, const struct ec_parse *ref,
-               struct ec_parse **new_ref)
+static struct ec_pnode *
+__ec_pnode_dup(const struct ec_pnode *root, const struct ec_pnode *ref,
+               struct ec_pnode **new_ref)
 {
-       struct ec_parse *dup = NULL;
-       struct ec_parse *child, *dup_child;
+       struct ec_pnode *dup = NULL;
+       struct ec_pnode *child, *dup_child;
        struct ec_dict *attrs = NULL;
 
        if (root == NULL)
                return NULL;
 
-       dup = ec_parse(root->node);
+       dup = ec_pnode(root->node);
        if (dup == NULL)
                return NULL;
 
@@ -194,26 +193,26 @@ __ec_parse_dup(const struct ec_parse *root, const struct ec_parse *ref,
        }
 
        TAILQ_FOREACH(child, &root->children, next) {
-               dup_child = __ec_parse_dup(child, ref, new_ref);
+               dup_child = __ec_pnode_dup(child, ref, new_ref);
                if (dup_child == NULL)
                        goto fail;
-               ec_parse_link_child(dup, dup_child);
+               ec_pnode_link_child(dup, dup_child);
        }
 
        return dup;
 
 fail:
-       ec_parse_free(dup);
+       ec_pnode_free(dup);
        return NULL;
 }
 
-struct ec_parse *ec_parse_dup(const struct ec_parse *parse)
+struct ec_pnode *ec_pnode_dup(const struct ec_pnode *pnode)
 {
-       const struct ec_parse *root;
-       struct ec_parse *dup_root, *dup = NULL;
+       const struct ec_pnode *root;
+       struct ec_pnode *dup_root, *dup = NULL;
 
-       root = ec_parse_get_root(parse);
-       dup_root = __ec_parse_dup(root, parse, &dup);
+       root = EC_PNODE_GET_ROOT(pnode);
+       dup_root = __ec_pnode_dup(root, pnode, &dup);
        if (dup_root == NULL)
                return NULL;
        assert(dup != NULL);
@@ -221,186 +220,187 @@ struct ec_parse *ec_parse_dup(const struct ec_parse *parse)
        return dup;
 }
 
-void ec_parse_free_children(struct ec_parse *parse)
+void ec_pnode_free_children(struct ec_pnode *pnode)
 {
-       struct ec_parse *child;
+       struct ec_pnode *child;
 
-       if (parse == NULL)
+       if (pnode == NULL)
                return;
 
-       while (!TAILQ_EMPTY(&parse->children)) {
-               child = TAILQ_FIRST(&parse->children);
-               TAILQ_REMOVE(&parse->children, child, next);
+       while (!TAILQ_EMPTY(&pnode->children)) {
+               child = TAILQ_FIRST(&pnode->children);
+               TAILQ_REMOVE(&pnode->children, child, next);
                child->parent = NULL;
-               ec_parse_free(child);
+               ec_pnode_free(child);
        }
 }
 
-void ec_parse_free(struct ec_parse *parse)
+void ec_pnode_free(struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return;
 
-       ec_assert_print(parse->parent == NULL,
-                       "parent not NULL in ec_parse_free()");
+       ec_assert_print(pnode->parent == NULL,
+                       "parent not NULL in ec_pnode_free()");
 
-       ec_parse_free_children(parse);
-       ec_strvec_free(parse->strvec);
-       ec_dict_free(parse->attrs);
-       ec_free(parse);
+       ec_pnode_free_children(pnode);
+       ec_strvec_free(pnode->strvec);
+       ec_dict_free(pnode->attrs);
+       ec_free(pnode);
 }
 
-static void __ec_parse_dump(FILE *out,
-       const struct ec_parse *parse, size_t indent)
+static void __ec_pnode_dump(FILE *out,
+       const struct ec_pnode *pnode, size_t indent)
 {
-       struct ec_parse *child;
+       struct ec_pnode *child;
        const struct ec_strvec *vec;
        const char *id = "none", *typename = "none";
 
        /* node can be null when parsing is incomplete */
-       if (parse->node != NULL) {
-               id = ec_node_id(parse->node);
-               typename = ec_node_type(parse->node)->name;
+       if (pnode->node != NULL) {
+               id = ec_node_id(pnode->node);
+               typename = ec_node_type(pnode->node)->name;
        }
 
        fprintf(out, "%*s" "type=%s id=%s vec=",
                (int)indent * 4, "", typename, id);
-       vec = ec_parse_strvec(parse);
+       vec = ec_pnode_get_strvec(pnode);
        ec_strvec_dump(out, vec);
 
-       TAILQ_FOREACH(child, &parse->children, next)
-               __ec_parse_dump(out, child, indent + 1);
+       TAILQ_FOREACH(child, &pnode->children, next)
+               __ec_pnode_dump(out, child, indent + 1);
 }
 
-void ec_parse_dump(FILE *out, const struct ec_parse *parse)
+// XXX dump in other formats? yaml? json?
+void ec_pnode_dump(FILE *out, const struct ec_pnode *pnode)
 {
        fprintf(out, "------------------- parse dump:\n");
 
-       if (parse == NULL) {
-               fprintf(out, "parse is NULL\n");
+       if (pnode == NULL) {
+               fprintf(out, "pnode is NULL\n");
                return;
        }
 
-       /* only exist if it does not match (strvec == NULL) and if it
-        * does not have children: an incomplete parse, like those
-        * generated by complete() don't match but have children that
-        * may match. */
-       if (!ec_parse_matches(parse) && TAILQ_EMPTY(&parse->children)) {
+       /* Do not dump if it does not match (strvec == NULL) and if it
+        * does not have children. Note that an incomplete parsing tree,
+        * like those generated by complete(), don't match but have
+        * children that may match, and we want to dump them. */
+       if (!ec_pnode_matches(pnode) && TAILQ_EMPTY(&pnode->children)) {
                fprintf(out, "no match\n");
                return;
        }
 
-       __ec_parse_dump(out, parse, 0);
+       __ec_pnode_dump(out, pnode, 0);
 }
 
-void ec_parse_link_child(struct ec_parse *parse,
-       struct ec_parse *child)
+void ec_pnode_link_child(struct ec_pnode *pnode,
+       struct ec_pnode *child)
 {
-       TAILQ_INSERT_TAIL(&parse->children, child, next);
-       child->parent = parse;
+       TAILQ_INSERT_TAIL(&pnode->children, child, next);
+       child->parent = pnode;
 }
 
-void ec_parse_unlink_child(struct ec_parse *parse,
-       struct ec_parse *child)
+void ec_pnode_unlink_child(struct ec_pnode *child)
 {
-       TAILQ_REMOVE(&parse->children, child, next);
-       child->parent = NULL;
-}
+       struct ec_pnode *parent = child->parent;
 
-struct ec_parse *
-ec_parse_get_first_child(const struct ec_parse *parse)
-{
-       return TAILQ_FIRST(&parse->children);
+       if (parent != NULL) {
+               TAILQ_REMOVE(&parent->children, child, next);
+               child->parent = NULL;
+       }
 }
 
-struct ec_parse *
-ec_parse_get_last_child(const struct ec_parse *parse)
+struct ec_pnode *
+ec_pnode_get_first_child(const struct ec_pnode *pnode)
 {
-       return TAILQ_LAST(&parse->children, ec_parse_list);
+       return TAILQ_FIRST(&pnode->children);
 }
 
-struct ec_parse *ec_parse_next(const struct ec_parse *parse)
+struct ec_pnode *
+ec_pnode_get_last_child(const struct ec_pnode *pnode)
 {
-       return TAILQ_NEXT(parse, next);
+       return TAILQ_LAST(&pnode->children, ec_pnode_list);
 }
 
-bool ec_parse_has_child(const struct ec_parse *parse)
+struct ec_pnode *ec_pnode_next(const struct ec_pnode *pnode)
 {
-       return !TAILQ_EMPTY(&parse->children);
+       return TAILQ_NEXT(pnode, next);
 }
 
-const struct ec_node *ec_parse_get_node(const struct ec_parse *parse)
+const struct ec_node *ec_pnode_get_node(const struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       return parse->node;
+       return pnode->node;
 }
 
-void ec_parse_del_last_child(struct ec_parse *parse)
+void ec_pnode_del_last_child(struct ec_pnode *pnode)
 {
-       struct ec_parse *child;
+       struct ec_pnode *child;
 
-       child = ec_parse_get_last_child(parse);
-       ec_parse_unlink_child(parse, child);
-       ec_parse_free(child);
+       child = ec_pnode_get_last_child(pnode);
+       if (child != NULL) {
+               ec_pnode_unlink_child(child);
+               ec_pnode_free(child);
+       }
 }
 
-struct ec_parse *__ec_parse_get_root(struct ec_parse *parse)
+struct ec_pnode *ec_pnode_get_root(struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       while (parse->parent != NULL)
-               parse = parse->parent;
+       while (pnode->parent != NULL)
+               pnode = pnode->parent;
 
-       return parse;
+       return pnode;
 }
 
-struct ec_parse *ec_parse_get_parent(const struct ec_parse *parse)
+struct ec_pnode *ec_pnode_get_parent(const struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       return parse->parent;
+       return pnode->parent;
 }
 
-struct ec_parse *__ec_parse_iter_next(const struct ec_parse *root,
-                               struct ec_parse *parse, bool iter_children)
+struct ec_pnode *__ec_pnode_iter_next(const struct ec_pnode *root,
+                               struct ec_pnode *pnode, bool iter_children)
 {
-       struct ec_parse *child, *parent, *next;
+       struct ec_pnode *child, *parent, *next;
 
        if (iter_children) {
-               child = TAILQ_FIRST(&parse->children);
+               child = TAILQ_FIRST(&pnode->children);
                if (child != NULL)
                        return child;
        }
-       parent = parse->parent;
-       while (parent != NULL && parse != root) {
-               next = TAILQ_NEXT(parse, next);
+       parent = pnode->parent;
+       while (parent != NULL && pnode != root) {
+               next = TAILQ_NEXT(pnode, next);
                if (next != NULL)
                        return next;
-               parse = parent;
-               parent = parse->parent;
+               pnode = parent;
+               parent = pnode->parent;
        }
        return NULL;
 }
 
-struct ec_parse *
-ec_parse_find_next(struct ec_parse *root, struct ec_parse *start,
+struct ec_pnode *
+ec_pnode_find_next(struct ec_pnode *root, struct ec_pnode *prev,
                const char *id, bool iter_children)
 {
-       struct ec_parse *iter;
+       struct ec_pnode *iter;
 
        if (root == NULL)
                return NULL;
-       if (start == NULL)
-               start = root;
+       if (prev == NULL)
+               prev = root;
        else
-               start = EC_PARSE_ITER_NEXT(root, start, iter_children);
+               prev = EC_PNODE_ITER_NEXT(root, prev, iter_children);
 
-       for (iter = start; iter != NULL;
-            iter = EC_PARSE_ITER_NEXT(root, iter, 1)) {
+       for (iter = prev; iter != NULL;
+            iter = EC_PNODE_ITER_NEXT(root, iter, 1)) {
                if (iter->node != NULL &&
                                !strcmp(ec_node_id(iter->node), id))
                        return iter;
@@ -409,55 +409,54 @@ ec_parse_find_next(struct ec_parse *root, struct ec_parse *start,
        return NULL;
 }
 
-struct ec_parse *ec_parse_find(struct ec_parse *parse,
-       const char *id)
+struct ec_pnode *ec_pnode_find(struct ec_pnode *root, const char *id)
 {
-       return ec_parse_find_next(parse, NULL, id, 1);
+       return ec_pnode_find_next(root, NULL, id, 1);
 }
 
 struct ec_dict *
-ec_parse_get_attrs(struct ec_parse *parse)
+ec_pnode_get_attrs(struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       return parse->attrs;
+       return pnode->attrs;
 }
 
-const struct ec_strvec *ec_parse_strvec(const struct ec_parse *parse)
+const struct ec_strvec *ec_pnode_get_strvec(const struct ec_pnode *pnode)
 {
-       if (parse == NULL || parse->strvec == NULL)
+       if (pnode == NULL)
                return NULL;
 
-       return parse->strvec;
+       return pnode->strvec;
 }
 
-/* number of strings in the parse vector */
-size_t ec_parse_len(const struct ec_parse *parse)
+/* number of strings in the parsed string vector */
+size_t ec_pnode_len(const struct ec_pnode *pnode)
 {
-       if (parse == NULL || parse->strvec == NULL)
+       if (pnode == NULL || pnode->strvec == NULL)
                return 0;
 
-       return ec_strvec_len(parse->strvec);
+       return ec_strvec_len(pnode->strvec);
 }
 
-size_t ec_parse_matches(const struct ec_parse *parse)
+size_t ec_pnode_matches(const struct ec_pnode *pnode)
 {
-       if (parse == NULL)
+       if (pnode == NULL)
                return 0;
 
-       if (parse->strvec == NULL)
+       if (pnode->strvec == NULL)
                return 0;
 
        return 1;
 }
 
 /* LCOV_EXCL_START */
-static int ec_parse_testcase(void)
+static int ec_pnode_testcase(void)
 {
        struct ec_node *node = NULL;
-       struct ec_parse *p = NULL, *p2 = NULL;
-       const struct ec_parse *pc;
+       struct ec_pnode *p = NULL, *p2 = NULL;
+       const struct ec_pnode *pc;
        FILE *f = NULL;
        char *buf = NULL;
        size_t buflen = 0;
@@ -471,15 +470,15 @@ static int ec_parse_testcase(void)
        if (node == NULL)
                goto fail;
 
-       p = ec_node_parse(node, "xcdscds");
+       p = ec_parse(node, "xcdscds");
        testres |= EC_TEST_CHECK(
-               p != NULL && !ec_parse_matches(p),
+               p != NULL && !ec_pnode_matches(p),
                "parse should not match\n");
 
        f = open_memstream(&buf, &buflen);
        if (f == NULL)
                goto fail;
-       ec_parse_dump(f, p);
+       ec_pnode_dump(f, p);
        fclose(f);
        f = NULL;
 
@@ -487,43 +486,43 @@ static int ec_parse_testcase(void)
                strstr(buf, "no match"), "bad dump\n");
        free(buf);
        buf = NULL;
-       ec_parse_free(p);
+       ec_pnode_free(p);
 
-       p = ec_node_parse(node, "x y");
+       p = ec_parse(node, "x y");
        testres |= EC_TEST_CHECK(
-               p != NULL && ec_parse_matches(p),
+               p != NULL && ec_pnode_matches(p),
                "parse should match\n");
        testres |= EC_TEST_CHECK(
-               ec_parse_len(p) == 1, "bad parse len\n");
+               ec_pnode_len(p) == 1, "bad parse len\n");
 
-       ret = ec_dict_set(ec_parse_get_attrs(p), "key", "val", NULL);
+       ret = ec_dict_set(ec_pnode_get_attrs(p), "key", "val", NULL);
        testres |= EC_TEST_CHECK(ret == 0,
                "cannot set parse attribute\n");
 
-       p2 = ec_parse_dup(p);
+       p2 = ec_pnode_dup(p);
        testres |= EC_TEST_CHECK(
-               p2 != NULL && ec_parse_matches(p2),
+               p2 != NULL && ec_pnode_matches(p2),
                "parse should match\n");
-       ec_parse_free(p2);
+       ec_pnode_free(p2);
        p2 = NULL;
 
-       pc = ec_parse_find(p, "id_x");
+       pc = ec_pnode_find(p, "id_x");
        testres |= EC_TEST_CHECK(pc != NULL, "cannot find id_x");
        testres |= EC_TEST_CHECK(pc != NULL &&
-               ec_parse_get_parent(pc) != NULL &&
-               ec_parse_get_parent(ec_parse_get_parent(pc)) == p,
+               ec_pnode_get_parent(pc) != NULL &&
+               ec_pnode_get_parent(ec_pnode_get_parent(pc)) == p,
                "invalid parent\n");
 
-       pc = ec_parse_find(p, "id_y");
+       pc = ec_pnode_find(p, "id_y");
        testres |= EC_TEST_CHECK(pc != NULL, "cannot find id_y");
-       pc = ec_parse_find(p, "id_dezdezdez");
+       pc = ec_pnode_find(p, "id_dezdezdez");
        testres |= EC_TEST_CHECK(pc == NULL, "should not find bad id");
 
 
        f = open_memstream(&buf, &buflen);
        if (f == NULL)
                goto fail;
-       ec_parse_dump(f, p);
+       ec_pnode_dump(f, p);
        fclose(f);
        f = NULL;
 
@@ -536,13 +535,13 @@ static int ec_parse_testcase(void)
        free(buf);
        buf = NULL;
 
-       ec_parse_free(p);
+       ec_pnode_free(p);
        ec_node_free(node);
        return testres;
 
 fail:
-       ec_parse_free(p2);
-       ec_parse_free(p);
+       ec_pnode_free(p2);
+       ec_pnode_free(p);
        ec_node_free(node);
        if (f != NULL)
                fclose(f);
@@ -552,9 +551,9 @@ fail:
 }
 /* LCOV_EXCL_STOP */
 
-static struct ec_test ec_parse_test = {
+static struct ec_test ec_pnode_test = {
        .name = "parse",
-       .test = ec_parse_testcase,
+       .test = ec_pnode_testcase,
 };
 
-EC_TEST_REGISTER(ec_parse_test);
+EC_TEST_REGISTER(ec_pnode_test);