*
*
*/
-struct ec_parse *ec_parse_get_next(const struct ec_parse *parse);
+struct ec_parse *ec_parse_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)) \
/**
*
*
*
*/
-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_; \
+})
/**
*
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++;
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);
}
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;
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))
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)
{
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");