Added "walk" function to conditions
authorAlan T. DeKok <aland@freeradius.org>
Mon, 2 Sep 2013 13:30:51 +0000 (09:30 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 3 Sep 2013 12:02:52 +0000 (08:02 -0400)
So that we can do post-processing

src/include/parser.h
src/main/parser.c

index 9ee29a6..310264b 100644 (file)
@@ -82,6 +82,8 @@ struct fr_cond_t {
 ssize_t fr_condition_tokenize(TALLOC_CTX *ctx, char const *start, fr_cond_t **head, char const **error);
 size_t fr_cond_sprint(char *buffer, size_t bufsize, fr_cond_t const *c);
 
+bool fr_condition_walk(fr_cond_t *head, bool (*callback)(void *, fr_cond_t *), void *ctx);
+
 /*
  *     In xlat.c for now
  */
index 1cb89d5..19c91db 100644 (file)
@@ -1037,3 +1037,47 @@ ssize_t fr_condition_tokenize(TALLOC_CTX *ctx, char const *start, fr_cond_t **he
 {
        return condition_tokenize(ctx, start, false, head, error);
 }
+
+/*
+ *     Walk in order.
+ */
+bool fr_condition_walk(fr_cond_t *c, bool (*callback)(void *, fr_cond_t *), void *ctx)
+{
+       while (c) {
+               /*
+                *      Process this one, exit on error.
+                */
+               if (!callback(ctx, c)) return false;
+
+               switch (c->type) {
+               case COND_TYPE_INVALID:
+                       return false;
+
+               case COND_TYPE_EXISTS:
+               case COND_TYPE_MAP:
+               case COND_TYPE_TRUE:
+               case COND_TYPE_FALSE:
+                       break;
+
+               case COND_TYPE_CHILD:
+                       /*
+                        *      Walk over the child.
+                        */
+                       if (!fr_condition_walk(c->data.child, callback, ctx)) {
+                               return false;
+                       }
+               }
+
+               /*
+                *      No sibling, stop.
+                */
+               if (c->next_op == COND_NONE) break;
+
+               /*
+                *      process the next sibling
+                */
+               c = c->next;
+       }
+
+       return true;
+}