parse: attempt to enhance api
authorOlivier Matz <zer0@droids-corp.org>
Thu, 21 Mar 2019 19:22:43 +0000 (20:22 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 21 Mar 2019 19:25:01 +0000 (20:25 +0100)
examples/parse-yaml/parse-yaml.c
include/ecoli_parse.h
src/ecoli_node_dynamic.c
src/ecoli_parse.c

index 218fe78..fbe4065 100644 (file)
@@ -143,7 +143,7 @@ __dump_as_shell(FILE *f, const struct ec_parse *parse, size_t *seq)
                __dump_as_shell(f, child, seq);
        }
 
-       if (ec_parse_get_next(parse) != NULL) {
+       if (ec_parse_next(parse) != NULL) {
                fprintf(f, "ec_node%zu_next='ec_node%zu'\n",
                        cur_seq, *seq + 1);
        }
index a431ba2..9048808 100644 (file)
@@ -159,7 +159,7 @@ struct ec_parse *ec_parse_get_last_child(const struct ec_parse *parse);
  *
  *
  */
-struct ec_parse *ec_parse_get_next(const struct ec_parse *parse);
+struct ec_parse *ec_parse_next(const struct ec_parse *parse);
 
 /**
  *
@@ -168,8 +168,8 @@ struct ec_parse *ec_parse_get_next(const struct ec_parse *parse);
  */
 #define EC_PARSE_FOREACH_CHILD(child, parse)                   \
        for (child = ec_parse_get_first_child(parse);           \
-               child != NULL;                                  \
-               child = ec_parse_get_next(child))               \
+            child != NULL;                                     \
+            child = ec_parse_next(child))                      \
 
 /**
  *
@@ -211,16 +211,36 @@ void ec_parse_dump(FILE *out, const struct ec_parse *parse);
  *
  *
  */
-struct ec_parse *ec_parse_find_first(struct ec_parse *parse,
+struct ec_parse *ec_parse_find(struct ec_parse *parse,
        const char *id);
 
+/**
+ *
+ *
+ *
+ */
+struct ec_parse *ec_parse_find_next(struct ec_parse *root,
+                               struct ec_parse *start,
+                               const char *id, bool iter_children);
+
 /**
  * Iterate among parse tree
  *
  * Use it with:
- * for (iter = state; iter != NULL; iter = ec_parse_iter_next(iter))
+ * for (iter = state; iter != NULL; iter = EC_PARSE_ITER_NEXT(state, iter, 1))
  */
-struct ec_parse *ec_parse_iter_next(struct ec_parse *parse);
+struct ec_parse *__ec_parse_iter_next(const struct ec_parse *root,
+                               struct ec_parse *parse, bool iter_children);
+
+/* keep the const if any */
+#define EC_PARSE_ITER_NEXT(root, parse, iter_children) ({              \
+       const struct ec_parse *p_ = parse; /* check type */             \
+       struct ec_parse *parse_ = (struct ec_parse *)parse;             \
+       typeof(parse) res_;                                             \
+       (void)p_;                                                       \
+       res_ = __ec_parse_iter_next(root, parse_, iter_children);       \
+       res_;                                                           \
+})
 
 /**
  *
index 8a3edf3..7c73b65 100644 (file)
@@ -135,13 +135,14 @@ static struct ec_node *
 build_counter(struct ec_parse *parse, void *opaque)
 {
        const struct ec_node *node;
-       struct ec_parse *iter;
+       struct ec_parse *root, *iter;
        unsigned int count = 0;
        char buf[32];
 
        (void)opaque;
-       for (iter = ec_parse_get_root(parse); iter != NULL;
-            iter = ec_parse_iter_next(iter)) {
+       root = ec_parse_get_root(parse);
+       for (iter = root; iter != NULL;
+            iter = EC_PARSE_ITER_NEXT(root, iter, 1)) {
                node = ec_parse_get_node(iter);
                if (node->id && !strcmp(node->id, "my-id"))
                        count++;
index 3b27070..f224fda 100644 (file)
@@ -319,7 +319,7 @@ ec_parse_get_last_child(const struct ec_parse *parse)
        return TAILQ_LAST(&parse->children, ec_parse_list);
 }
 
-struct ec_parse *ec_parse_get_next(const struct ec_parse *parse)
+struct ec_parse *ec_parse_next(const struct ec_parse *parse)
 {
        return TAILQ_NEXT(parse, next);
 }
@@ -365,15 +365,18 @@ struct ec_parse *ec_parse_get_parent(const struct ec_parse *parse)
        return parse->parent;
 }
 
-struct ec_parse *ec_parse_iter_next(struct ec_parse *parse)
+struct ec_parse *__ec_parse_iter_next(const struct ec_parse *root,
+                               struct ec_parse *parse, bool iter_children)
 {
        struct ec_parse *child, *parent, *next;
 
-       child = TAILQ_FIRST(&parse->children);
-       if (child != NULL)
-               return child;
+       if (iter_children) {
+               child = TAILQ_FIRST(&parse->children);
+               if (child != NULL)
+                       return child;
+       }
        parent = parse->parent;
-       while (parent != NULL) {
+       while (parent != NULL && parse != root) {
                next = TAILQ_NEXT(parse, next);
                if (next != NULL)
                        return next;
@@ -383,15 +386,21 @@ struct ec_parse *ec_parse_iter_next(struct ec_parse *parse)
        return NULL;
 }
 
-struct ec_parse *ec_parse_find_first(struct ec_parse *parse,
-       const char *id)
+struct ec_parse *
+ec_parse_find_next(struct ec_parse *root, struct ec_parse *start,
+               const char *id, bool iter_children)
 {
        struct ec_parse *iter;
 
-       if (parse == NULL)
+       if (root == NULL)
                return NULL;
+       if (start == NULL)
+               start = root;
+       else
+               start = EC_PARSE_ITER_NEXT(root, start, iter_children);
 
-       for (iter = parse; iter != NULL; iter = ec_parse_iter_next(iter)) {
+       for (iter = start; iter != NULL;
+            iter = EC_PARSE_ITER_NEXT(root, iter, 1)) {
                if (iter->node != NULL &&
                                iter->node->id != NULL &&
                                !strcmp(iter->node->id, id))
@@ -401,6 +410,12 @@ struct ec_parse *ec_parse_find_first(struct ec_parse *parse,
        return NULL;
 }
 
+struct ec_parse *ec_parse_find(struct ec_parse *parse,
+       const char *id)
+{
+       return ec_parse_find_next(parse, NULL, id, 1);
+}
+
 struct ec_keyval *
 ec_parse_get_attrs(struct ec_parse *parse)
 {
@@ -493,16 +508,16 @@ static int ec_parse_testcase(void)
        ec_parse_free(p2);
        p2 = NULL;
 
-       pc = ec_parse_find_first(p, "id_x");
+       pc = ec_parse_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,
                "invalid parent\n");
 
-       pc = ec_parse_find_first(p, "id_y");
+       pc = ec_parse_find(p, "id_y");
        testres |= EC_TEST_CHECK(pc != NULL, "cannot find id_y");
-       pc = ec_parse_find_first(p, "id_dezdezdez");
+       pc = ec_parse_find(p, "id_dezdezdez");
        testres |= EC_TEST_CHECK(pc == NULL, "should not find bad id");