fr_dict_attr_t *dict_attr_alloc_null(TALLOC_CTX *ctx);
+/** Optional arguments for initialising/allocating attributes
+ *
+ */
+typedef struct {
+ fr_dict_attr_flags_t const *flags; //!< Any flags to assign to the attribute.
+
+ fr_dict_attr_t const *ref; //!< This attribute is a reference to another attribute.
+} dict_attr_args_t;
+
int dict_attr_init(fr_dict_attr_t **da_p,
fr_dict_attr_t const *parent,
char const *name, int attr,
- fr_type_t type, fr_dict_attr_flags_t const *flags);
+ fr_type_t type, dict_attr_args_t const *args);
fr_dict_attr_t *dict_attr_alloc(TALLOC_CTX *ctx,
fr_dict_attr_t const *parent,
char const *name, int attr,
- fr_type_t type, fr_dict_attr_flags_t const *flags);
+ fr_type_t type, dict_attr_args_t const *args);
fr_dict_attr_t *dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in, char const *new_name);
return -1;
}
- da = dict_attr_alloc(dict->pool, NULL, name, proto_number, FR_TYPE_TLV, &flags);
+ da = dict_attr_alloc(dict->pool, NULL, name, proto_number, FR_TYPE_TLV,
+ &(dict_attr_args_t){ .flags = &flags });
if (unlikely(!da)) return -1;
dict->root = da;
* i.e. you can lookup the ALIAS by "name", but you
* actually get returned "ref".
*/
- self = dict_attr_alloc(ctx->dict->pool, parent, argv[0], da->attr, da->type, &da->flags);
+ self = dict_attr_alloc(ctx->dict->pool, parent, argv[0], da->attr, da->type,
+ &(dict_attr_args_t){ .flags = &da->flags });
if (unlikely(!self)) return -1;
self->dict = ctx->dict;
}
new = dict_attr_alloc(ctx->dict->pool,
- vsa_da, argv[1], vendor->pen, FR_TYPE_VENDOR, &flags);
+ vsa_da, argv[1], vendor->pen, FR_TYPE_VENDOR,
+ &(dict_attr_args_t){ .flags = &flags });
if (unlikely(!new)) goto error;
if (dict_attr_child_add(UNCONST(fr_dict_attr_t *, vsa_da), new) < 0) {
type_name = talloc_typed_asprintf(NULL, "Tmp-Cast-%s", p->name.str);
n = dict_attr_alloc(dict->pool, dict->root, type_name,
- FR_CAST_BASE + p->value, p->value, &flags);
+ FR_CAST_BASE + p->value, p->value, &(dict_attr_args_t){ .flags = &flags});
if (!n) {
talloc_free(type_name);
goto error;
if (dict_vendor_add(dict, unknown->name, unknown->attr) < 0) return NULL;
- n = dict_attr_alloc(dict->pool, parent, unknown->name, unknown->attr, unknown->type, &flags);
+ n = dict_attr_alloc(dict->pool, parent, unknown->name, unknown->attr, unknown->type,
+ &(dict_attr_args_t){ .flags = &flags });
if (unlikely(!n)) return NULL;
/*
if (da) {
fr_dict_attr_t *n;
- n = dict_attr_alloc(dict->pool, parent, unknown->name, unknown->attr, unknown->type, &flags);
+ n = dict_attr_alloc(dict->pool, parent, unknown->name, unknown->attr, unknown->type,
+ &(dict_attr_args_t){ .flags = &flags });
if (!n) return NULL;
/*
/*
* Initialize the rest of the fields.
*/
- dict_attr_init(&n, parent, da->name, da->attr, type, &flags);
+ dict_attr_init(&n, parent, da->name, da->attr, type, &(dict_attr_args_t){ .flags = &flags });
dict_attr_ext_copy_all(&n, da);
DA_VERIFY(n);
switch (parent->type) {
case FR_TYPE_VSA:
if (!fr_cond_assert(!parent->flags.is_unknown)) return NULL;
- return dict_attr_alloc(ctx, parent, NULL, vendor, FR_TYPE_VENDOR, &flags);
+ return dict_attr_alloc(ctx, parent, NULL, vendor, FR_TYPE_VENDOR,
+ &(dict_attr_args_t){ .flags = &flags });
case FR_TYPE_VENDOR:
if (!fr_cond_assert(!parent->flags.is_unknown)) return NULL;
return NULL;
}
- return dict_attr_alloc(ctx, parent, NULL, num, FR_TYPE_TLV, &flags);
+ return dict_attr_alloc(ctx, parent, NULL, num, FR_TYPE_TLV,
+ &(dict_attr_args_t){ .flags = &flags });
}
/** Initialise a fr_dict_attr_t from a number
return NULL;
}
- return dict_attr_alloc(ctx, parent, NULL, num, FR_TYPE_OCTETS, &flags);
+ return dict_attr_alloc(ctx, parent, NULL, num, FR_TYPE_OCTETS,
+ &(dict_attr_args_t){ .flags = &flags });
}
/** Initialise an octets type attribute from a da
/*
* Initialize the rest of the fields.
*/
- dict_attr_init(&n, parent, da->name, da->attr, FR_TYPE_OCTETS, &flags);
+ dict_attr_init(&n, parent, da->name, da->attr, FR_TYPE_OCTETS, &(dict_attr_args_t){ .flags = &flags });
DA_VERIFY(n);
return n;
our_parent = ni;
continue;
}
- if (dict_attr_init(&n, our_parent, NULL, num, FR_TYPE_VENDOR, &flags) < 0) goto error;
+ if (dict_attr_init(&n, our_parent, NULL, num, FR_TYPE_VENDOR,
+ &(dict_attr_args_t){ .flags = &flags }) < 0) goto error;
}
break;
goto error;
}
flags.is_raw = is_raw;
- if (dict_attr_init(&n, our_parent, NULL, num, FR_TYPE_OCTETS, &flags) < 0) goto error;
+ if (dict_attr_init(&n, our_parent, NULL, num, FR_TYPE_OCTETS,
+ &(dict_attr_args_t){ .flags = &flags }) < 0) goto error;
break;
}
break;
return 0;
}
-/** Set a reference for a grouping attribute
+/** Set a reference for a grouping attribute or an alias attribute
*
* @note This function can only be used _before_ the attribute is inserted into the dictionary.
*
- * @param[in] da_p to set a group reference for.
+ * @param[in] da_p to set reference for.
+ * @param[in] ref The attribute referred to by this attribute.
*/
-static inline CC_HINT(always_inline) int dict_attr_ref_init(fr_dict_attr_t **da_p)
+static inline CC_HINT(always_inline) int dict_attr_ref_init(fr_dict_attr_t **da_p, fr_dict_attr_t const *ref)
{
fr_dict_attr_ext_ref_t *ext;
ext = dict_attr_ext_alloc(da_p, FR_DICT_ATTR_EXT_REF);
if (unlikely(!ext)) return -1;
+ ext->ref = ref;
+
return 0;
}
* @param[in] name of attribute. Pass NULL for auto-generated name.
* @param[in] attr number.
* @param[in] type of the attribute.
- * @param[in] flags to assign.
+ * @param[in] args optional initialisation arguments.
*/
int dict_attr_init(fr_dict_attr_t **da_p,
fr_dict_attr_t const *parent,
char const *name, int attr,
- fr_type_t type, fr_dict_attr_flags_t const *flags)
+ fr_type_t type, dict_attr_args_t const *args)
{
+ static dict_attr_args_t default_args;
+
+ if (!args) args = &default_args;
+
**da_p = (fr_dict_attr_t) {
.attr = attr,
.type = type,
- .flags = *flags,
+ .flags = *args->flags,
.parent = parent,
};
switch (type) {
case FR_TYPE_STRUCTURAL:
structural:
- if (dict_attr_ref_init(da_p) < 0) return -1;
+ if (dict_attr_ref_init(da_p, NULL) < 0) return -1; /* Just allocate space */
/*
* Groups don't have children or
break;
}
+ /*
+ * This attribute is just a reference to another.
+ */
+ if (args->ref) if (dict_attr_ref_init(da_p, args->ref) < 0) return -1;
+
/*
* Name is a separate talloc chunk. We allocate
* it last because we cache the pointer value.
* will be created and set as the name.
* @param[in] attr number.
* @param[in] type of the attribute.
- * @param[in] flags to assign.
+ * @param[in] args optional initialisation arguments.
* @return
* - A new fr_dict_attr_t on success.
* - NULL on failure.
fr_dict_attr_t *dict_attr_alloc(TALLOC_CTX *ctx,
fr_dict_attr_t const *parent,
char const *name, int attr,
- fr_type_t type, fr_dict_attr_flags_t const *flags)
+ fr_type_t type, dict_attr_args_t const *args)
{
fr_dict_attr_t *n;
n = dict_attr_alloc_null(ctx);
if (unlikely(!n)) return NULL;
- if (dict_attr_init(&n, parent, name, attr, type, flags) < 0) {
+ if (dict_attr_init(&n, parent, name, attr, type, args) < 0) {
talloc_free(n);
return NULL;
}
{
fr_dict_attr_t *n;
- n = dict_attr_alloc(ctx, in->parent, new_name ? new_name : in->name, in->attr, in->type, &in->flags);
+ n = dict_attr_alloc(ctx, in->parent, new_name ? new_name : in->name,
+ in->attr, in->type, &(dict_attr_args_t){ .flags = &in->flags });
if (unlikely(!n)) return NULL;
if (dict_attr_ext_copy_all(&n, in) < 0) {
*/
if (!dict_attr_fields_valid(dict, parent, name, &attr, type, &our_flags)) return -1;
- n = dict_attr_alloc(dict->pool, parent, name, attr, type, &our_flags);
+ n = dict_attr_alloc(dict->pool, parent, name, attr, type, &(dict_attr_args_t){ .flags = &our_flags});
if (!n) return -1;
#define FLAGS_EQUAL(_x) (old->flags._x == flags->_x)