X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=src%2Fecoli_parse.c;h=7b36ed52e20db6df1cc3d76b2db17f671d107fbc;hb=b9bb9e5187b1530df9a0f22e734f4e2c546e439e;hp=e01ff0ae6c24ad74ad720bb0acf486ec9c0f08a5;hpb=41bf1ba66e15c00f38375d05e49b31aa70f92349;p=protos%2Flibecoli.git diff --git a/src/ecoli_parse.c b/src/ecoli_parse.c index e01ff0a..7b36ed5 100644 --- a/src/ecoli_parse.c +++ b/src/ecoli_parse.c @@ -23,23 +23,23 @@ 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,244 +220,243 @@ 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 = parse->node->id; - 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 && - iter->node->id != NULL && - !strcmp(iter->node->id, id)) + !strcmp(ec_node_id(iter->node), id)) return iter; } 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; @@ -472,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; @@ -488,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; @@ -537,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); @@ -553,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);