Skip to content
Permalink
Browse files

make the stack a structure

in preparation for nested 'struct', and for better handling
of manual vs automatic BEGIN / END things
  • Loading branch information
alandekok committed Aug 9, 2019
1 parent 807aa61 commit e330e88be440e30a943047963365a28b98a9e4d6
Showing with 30 additions and 24 deletions.
  1. +30 −24 src/lib/util/dict.c
@@ -3831,11 +3831,17 @@ static int dict_read_sscanf_i(unsigned int *pvalue, char const *str)
* Allows vendor and TLV context to persist across $INCLUDEs
*/
#define MAX_STACK (32)
typedef struct dict_ctx_stack_frame_t {
fr_dict_attr_t const *da; //!< the da we care about
fr_type_t nest; //!< for manual vs automatic begin / end things
int member_num; //!< structure member numbers
} dict_ctx_stack_frame_t;

typedef struct {
fr_dict_t *dict; //!< Protocol dictionary we're inserting attributes into.
fr_dict_t *old_dict; //!< The dictionary before the current BEGIN-PROTOCOL block.

fr_dict_attr_t const *stack[MAX_STACK]; //!< stack of attributes to track
dict_ctx_stack_frame_t stack[MAX_STACK]; //!< stack of attributes to track
int stack_depth; //!< points to the last used stack frame

fr_dict_attr_t const *value_attr; //!< Cache of last attribute to speed up
@@ -4233,7 +4239,7 @@ static int dict_process_flag_field(dict_from_file_ctx_t *ctx, char *name, fr_typ
/*
* Check that the flags are valid.
*/
if (!dict_attr_flags_valid(ctx->dict, ctx->stack[ctx->stack_depth], name, NULL, type, flags)) return -1;
if (!dict_attr_flags_valid(ctx->dict, ctx->stack[ctx->stack_depth].da, name, NULL, type, flags)) return -1;

return 0;
}
@@ -4246,21 +4252,21 @@ static int dict_ctx_push(dict_from_file_ctx_t *ctx, fr_dict_attr_t const *da)
return -1;
}

ctx->stack[++ctx->stack_depth] = da;
ctx->stack[++ctx->stack_depth].da = da;

return 0;
}

static fr_dict_attr_t const *dict_ctx_unwind(dict_from_file_ctx_t *ctx)
{
while ((ctx->stack_depth > 0) &&
!ctx->stack[ctx->stack_depth]->flags.is_root &&
(ctx->stack[ctx->stack_depth]->type != FR_TYPE_VENDOR)) {
!ctx->stack[ctx->stack_depth].da->flags.is_root &&
(ctx->stack[ctx->stack_depth].da->type != FR_TYPE_VENDOR)) {
ctx->stack_depth--;
}


return ctx->stack[ctx->stack_depth];
return ctx->stack[ctx->stack_depth].da;
}

/*
@@ -4307,7 +4313,7 @@ static int dict_read_process_attribute(dict_from_file_ctx_t *ctx, char **argv, i
* in order to define this attribute.
*/
if (argv[1][0] != '.') {
parent = ctx->stack[ctx->stack_depth];
parent = ctx->stack[ctx->stack_depth].da;

/*
* Allow '0xff00' as attribute numbers, but only
@@ -4439,7 +4445,7 @@ static int dict_read_process_member(dict_from_file_ctx_t *ctx, char **argv, int
return -1;
}

if (ctx->stack[ctx->stack_depth]->type != FR_TYPE_STRUCT) {
if (ctx->stack[ctx->stack_depth].da->type != FR_TYPE_STRUCT) {
fr_strerror_printf("MEMBER can only be used for ATTRIBUTEs of type 'struct'");
return -1;
}
@@ -4468,7 +4474,7 @@ static int dict_read_process_member(dict_from_file_ctx_t *ctx, char **argv, int
/*
* Add the MEMBER to the parent.
*/
if (fr_dict_attr_add(ctx->dict, ctx->stack[ctx->stack_depth], argv[0], ++ctx->member_num, type, &flags) < 0) return -1;
if (fr_dict_attr_add(ctx->dict, ctx->stack[ctx->stack_depth].da, argv[0], ++ctx->member_num, type, &flags) < 0) return -1;

/*
* A 'struct' can have a MEMBER of type 'tlv', but ONLY
@@ -4479,8 +4485,8 @@ static int dict_read_process_member(dict_from_file_ctx_t *ctx, char **argv, int
* to them.
*/
if (type == FR_TYPE_TLV) {
ctx->relative_attr = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth], ctx->member_num);
ctx->stack[++ctx->stack_depth] = ctx->relative_attr;
ctx->relative_attr = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, ctx->member_num);
ctx->stack[++ctx->stack_depth].da = ctx->relative_attr;
}

return 0;
@@ -5014,7 +5020,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
*/
fr_dict_attr_flags_t base_flags;

if (!fr_cond_assert(!ctx->dict->root || ctx->stack[ctx->stack_depth])) return -1;
if (!fr_cond_assert(!ctx->dict->root || ctx->stack[ctx->stack_depth].da)) return -1;

if ((strlen(dir_name) + 3 + strlen(filename)) > sizeof(dir)) {
fr_strerror_printf_push("%s: Filename name too long", "Error reading dictionary");
@@ -5377,11 +5383,11 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
goto error;
}

common = fr_dict_parent_common(ctx->stack[ctx->stack_depth], da, true);
common = fr_dict_parent_common(ctx->stack[ctx->stack_depth].da, da, true);
if (!common ||
(common->type == FR_TYPE_VSA)) {
fr_strerror_printf_push("Attribute '%s' should be a child of '%s'",
argv[1], ctx->stack[ctx->stack_depth]->name);
argv[1], ctx->stack[ctx->stack_depth].da->name);
goto error;
}

@@ -5404,9 +5410,9 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
goto error;
}

if ((da != ctx->stack[ctx->stack_depth]) || (ctx->stack_depth == 0)) {
if ((da != ctx->stack[ctx->stack_depth].da) || (ctx->stack_depth == 0)) {
fr_strerror_printf_push("END-TLV %s does not match previous BEGIN-TLV %s", argv[1],
ctx->stack[ctx->stack_depth]->name);
ctx->stack[ctx->stack_depth].da->name);
goto error;
}
ctx->stack_depth--;
@@ -5475,18 +5481,18 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
* the RFC dictionaries we need to add it in the case
* it doesn't.
*/
vsa_da = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth], FR_VENDOR_SPECIFIC);
vsa_da = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, FR_VENDOR_SPECIFIC);
if (!vsa_da) {
memset(&flags, 0, sizeof(flags));

if (fr_dict_attr_add(ctx->dict, ctx->stack[ctx->stack_depth], "Vendor-Specific",
if (fr_dict_attr_add(ctx->dict, ctx->stack[ctx->stack_depth].da, "Vendor-Specific",
FR_VENDOR_SPECIFIC, FR_TYPE_VSA, &flags) < 0) {
fr_strerror_printf_push("Failed adding Vendor-Specific for Vendor %s",
vendor->name);
goto error;
}

vsa_da = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth], FR_VENDOR_SPECIFIC);
vsa_da = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, FR_VENDOR_SPECIFIC);
if (!vsa_da) {
fr_strerror_printf_push("Failed finding Vendor-Specific for Vendor %s",
vendor->name);
@@ -5525,7 +5531,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
}

memcpy(&mutable, &vsa_da, sizeof(mutable));
new = dict_attr_alloc(mutable, ctx->stack[ctx->stack_depth], argv[1],
new = dict_attr_alloc(mutable, ctx->stack[ctx->stack_depth].da, argv[1],
vendor->pen, FR_TYPE_VENDOR, &flags);
if (dict_attr_child_add(mutable, new) < 0) {
talloc_free(new);
@@ -5560,7 +5566,7 @@ static int _dict_from_file(dict_from_file_ctx_t *ctx,
goto error;
}

da = ctx->stack[ctx->stack_depth];
da = ctx->stack[ctx->stack_depth].da;
if (da->type != FR_TYPE_VENDOR) goto no_matching_vendor;

if (vendor->pen != da->attr) {
@@ -5592,7 +5598,7 @@ static int dict_from_file(fr_dict_t *dict,

memset(&ctx, 0, sizeof(ctx));
ctx.dict = dict;
ctx.stack[0] = dict->root;
ctx.stack[0].da = dict->root;

rcode = _dict_from_file(&ctx,
dir_name, filename, src_file, src_line);
@@ -6010,7 +6016,7 @@ int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent)

memset(&ctx, 0, sizeof(ctx));
ctx.dict = dict;
ctx.stack[0] = dict->root;
ctx.stack[0].da = dict->root;

ctx.fixup_pool = talloc_pool(NULL, DICT_FIXUP_POOL_SIZE);
if (!ctx.fixup_pool) return -1;
@@ -6032,7 +6038,7 @@ int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent)
if (ret < 0) goto error;

} else if (strcasecmp(argv[0], "ATTRIBUTE") == 0) {
if (parent && (parent != dict->root)) ctx.stack[++ctx.stack_depth] = parent;
if (parent && (parent != dict->root)) ctx.stack[++ctx.stack_depth].da = parent;

memset(&base_flags, 0, sizeof(base_flags));

0 comments on commit e330e88

Please sign in to comment.
You can’t perform that action at this time.