*/
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.
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.
/*
*/
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);
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
}
+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:
break;
default:
+ if (da->parent && da->parent->type == FR_TYPE_STRUCT) {
+ name = "MEMBER";
+ break;
+ }
+
name = "ATTRIBUTE";
break;
}
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);
}
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);
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");
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);
+}