From: Alan T. DeKok Date: Sat, 10 Oct 2020 14:48:10 +0000 (-0400) Subject: add and use fr_dict_walk() function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92fb2ce2ccc8998d6aeeecb4921b92c097fbbce6;p=thirdparty%2Ffreeradius-server.git add and use fr_dict_walk() function we will need this when each structural attribute has hash tables of child names / attributes --- diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index 7da16a7724a..f25d1354595 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -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 diff --git a/src/lib/util/dict_print.c b/src/lib/util/dict_print.c index 0104f8040e7..a729e8649d6 100644 --- a/src/lib/util/dict_print.c +++ b/src/lib/util/dict_print.c @@ -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); } diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index a0c890652de..7fc6f2dc64a 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -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, ""), 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); +}