]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add and use fr_dict_walk() function
authorAlan T. DeKok <aland@freeradius.org>
Sat, 10 Oct 2020 14:48:10 +0000 (10:48 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 10 Oct 2020 15:10:16 +0000 (11:10 -0400)
we will need this when each structural attribute has hash tables
of child names / attributes

src/lib/util/dict.h
src/lib/util/dict_print.c
src/lib/util/dict_util.c

index 7da16a7724a34bbed4f479697e0ecba8a512874f..f25d1354595e0726a64dca7ce6567599cc78626c 100644 (file)
@@ -113,6 +113,8 @@ extern const size_t dict_attr_sizes[FR_TYPE_MAX + 1][2];
  */
 struct dict_attr_s {
        unsigned int            attr;                           //!< Attribute number.
+       unsigned int            depth;                          //!< Depth of nesting for this attribute.
+
        fr_type_t               type;                           //!< Value type.
        char const              *name;                          //!< Attribute name.
 
@@ -120,8 +122,6 @@ struct dict_attr_s {
        fr_dict_attr_t const    *parent;                        //!< Immediate parent of this attribute.
        fr_dict_attr_t const    *next;                          //!< Next child in bin.
 
-       unsigned int            depth;                          //!< Depth of nesting for this attribute.
-
        fr_dict_attr_flags_t    flags;                          //!< Flags.
 
        /*
@@ -348,7 +348,7 @@ static inline  CC_HINT(nonnull) int8_t fr_dict_attr_cmp(fr_dict_attr_t const *a,
  */
 ssize_t                        fr_dict_snprint_flags(char *out, size_t outlen, fr_dict_t const *dict, fr_type_t type, fr_dict_attr_flags_t const *flags);
 
-void                   fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da, int depth);
+void                   fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da);
 
 fr_dict_attr_t const   *fr_dict_attr_common_parent(fr_dict_attr_t const *a, fr_dict_attr_t const *b, bool is_ancestor);
 
@@ -526,6 +526,10 @@ void                       fr_dict_verify(char const *file, int line, fr_dict_attr_t const *da);
 
 fr_dict_attr_t const   *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent, fr_dict_attr_t const **prev);
 
+typedef int            (*fr_dict_walk_t)(void *ctx, fr_dict_attr_t const *da, int depth);
+
+int                    fr_dict_walk(fr_dict_attr_t const *da, void *ctx, fr_dict_walk_t callback);
+
 /** @} */
 
 #undef _CONST
index 0104f8040e72ea8797047b2eeda54060c12bb480..a729e8649d624a1a3d291db2640b19b00252dc00 100644 (file)
@@ -157,14 +157,17 @@ size_t fr_dict_print_attr_oid(size_t *need, char *out, size_t outlen,
 }
 
 
+typedef struct {
+       fr_dict_t const *dict;
+       char buff[256];
+} fr_dict_print_t;
 
-void fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da, int depth)
+static int dict_print(void *ctx_in, fr_dict_attr_t const *da, int depth)
 {
-       char buff[256];
-       unsigned int i;
        char const *name;
+       fr_dict_print_t *ctx = (fr_dict_print_t *) ctx_in;
 
-       fr_dict_snprint_flags(buff, sizeof(buff), dict, da->type, &da->flags);
+       fr_dict_snprint_flags(ctx->buff, sizeof(ctx->buff), ctx->dict, da->type, &da->flags);
 
        switch (da->type) {
        case FR_TYPE_VSA:
@@ -188,6 +191,11 @@ void fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da, int depth)
                break;
 
        default:
+               if (da->parent && da->parent->type == FR_TYPE_STRUCT) {
+                       name = "MEMBER";
+                       break;
+               }
+
                name = "ATTRIBUTE";
                break;
        }
@@ -195,15 +203,17 @@ void fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da, int depth)
        printf("%u%.*s%s \"%s\" vendor: %x (%u), num: %x (%u), type: %s, flags: %s\n", da->depth, depth,
               "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", name, da->name,
               fr_dict_vendor_num_by_da(da), fr_dict_vendor_num_by_da(da), da->attr, da->attr,
-              fr_table_str_by_value(fr_value_box_type_table, da->type, "?Unknown?"), buff);
+              fr_table_str_by_value(fr_value_box_type_table, da->type, "?Unknown?"), ctx->buff);
 
-       if (!dict_attr_can_have_children(da)) return;
+       return 0;
+}
 
-       if (da->children) for (i = 0; i < talloc_array_length(da->children); i++) {
-               if (da->children[i]) {
-                       fr_dict_attr_t const *bin;
 
-                       for (bin = da->children[i]; bin; bin = bin->next) fr_dict_print(dict, bin, depth + 1);
-               }
-       }
+void fr_dict_print(fr_dict_t const *dict, fr_dict_attr_t const *da)
+{
+       fr_dict_print_t ctx;
+
+       ctx.dict = dict;
+
+       (void) fr_dict_walk(da, &ctx, dict_print);
 }
index a0c890652dee9c4dd6c142042fd69342ffb51f9b..7fc6f2dc64a6b9e3af1b357ac3a5ab41ce658b01 100644 (file)
@@ -2662,11 +2662,9 @@ int fr_dl_dict_attr_autoload(UNUSED dl_t const *module, void *symbol, UNUSED voi
        return 0;
 }
 
-static void _fr_dict_dump(fr_dict_t const *dict, fr_dict_attr_t const *da, unsigned int lvl)
+static int dict_dump(void *ctx, fr_dict_attr_t const *da, int lvl)
 {
-       unsigned int            i;
-       size_t                  len;
-       fr_dict_attr_t const    *p;
+       fr_dict_t const         *dict = (fr_dict_t const *) ctx;
        char                    flags[256];
 
        fr_dict_snprint_flags(flags, sizeof(flags), dict, da->type, &da->flags);
@@ -2674,22 +2672,18 @@ static void _fr_dict_dump(fr_dict_t const *dict, fr_dict_attr_t const *da, unsig
        printf("[%02i] 0x%016" PRIxPTR "%*s %s(%u) %s %s\n", lvl, (unsigned long)da, lvl * 2, " ",
               da->name, da->attr, fr_table_str_by_value(fr_value_box_type_table, da->type, "<INVALID>"), flags);
 
-       if (!dict_attr_can_have_children(da)) return;
-
-       len = talloc_array_length(da->children);
-       for (i = 0; i < len; i++) {
-               for (p = da->children[i]; p; p = p->next) {
-                       _fr_dict_dump(dict, p, lvl + 1);
-               }
-       }
+       return 0;
 }
 
 void fr_dict_dump(fr_dict_t const *dict)
 {
        fr_hash_iter_t          iter;
        fr_dict_enum_t const    *enumv;
+       void *ctx;
+
+       memcpy(&ctx, &dict, sizeof(ctx)); /* const issues */
 
-       _fr_dict_dump(dict, dict->root, 0);
+       (void) fr_dict_walk(dict->root, ctx, dict_dump);
 
        printf("Enumeration name -> value:\n");
 
@@ -3093,3 +3087,31 @@ fr_dict_attr_t const *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent
 
        return NULL;
 }
+
+static int dict_walk(fr_dict_attr_t const *da, void *ctx, fr_dict_walk_t callback, int depth)
+{
+       size_t i;
+
+       if (!dict_attr_can_have_children(da) || !da->children) {
+               return callback(ctx, da, depth);
+       }
+
+       for (i = 0; i < talloc_array_length(da->children); i++) {
+               int rcode;
+               fr_dict_attr_t const *bin;
+
+               if (!da->children[i]) continue;
+
+               for (bin = da->children[i]; bin; bin = bin->next) {
+                       rcode = dict_walk(bin, ctx, callback, depth);
+                       if (rcode < 0) return rcode;
+               }
+       }
+
+       return 0;
+}
+
+int fr_dict_walk(fr_dict_attr_t const *da, void *ctx, fr_dict_walk_t callback)
+{
+       return dict_walk(da, ctx, callback, 0);
+}