fr_dict_attr_flags_t flags; //!< Flags.
- bool attr_set:1; //!< Attribute number has been set.
+ struct {
+ bool attr_set : 1; //!< Attribute number has been set.
//!< We need the full range of values 0-UINT32_MAX
///< so we can't use any attr values to indicate
///< "unsetness".
+ bool finalised : 1; //!< Attribute definition is complete and modifications
+ ///< that would change the address of the memory chunk
+ ///< of the attribute are no longer permitted.
+ } state;
+
char const *filename; //!< Where the attribute was defined.
///< this buffer's lifetime is bound to the
///< fr_dict_t.
return -1;
}
+ if (unlikely((*da_p)->state.finalised == true)) {
+ fr_strerror_const("Can't perform type initialisation on finalised attribute");
+ return -1;
+ }
+
/*
* Structural types can have children
* so add the extension for them.
{
fr_dict_attr_t *da = *da_p;
+
if (unlikely((*da_p)->type == FR_TYPE_NULL)) {
fr_strerror_const("Attribute type must be set before initialising parent. Use dict_attr_type_init() first");
return -1;
da->name, parent->name, da->parent->name);
return -1;
}
+
+ if (unlikely((*da_p)->state.finalised == true)) {
+ fr_strerror_printf("Attempting to set parent for '%s' to '%s', but attribute already finalised",
+ da->name, parent->name);
+ return -1;
+ }
+
da->parent = parent;
da->dict = parent->dict;
da->depth = parent->depth + 1;
*/
int dict_attr_num_init(fr_dict_attr_t *da, unsigned int num)
{
- if (da->attr_set) {
+ if (da->state.attr_set) {
fr_strerror_const("Attribute number already set");
return -1;
}
da->attr = num;
- da->attr_set = true;
+ da->state.attr_set = true;
return 0;
}
DA_VERIFY(*da_p);
+ (*da_p)->state.finalised = true;
+
return 0;
}
return -1;
}
+ if (unlikely(da->state.finalised == false)) {
+ fr_strerror_const("Attribute has not been finalised");
+ return -1;
+ }
+
/*
* Check that the definition is valid.
*/
* between auto-assigned and explkicitly assigned.
*/
if (da->flags.name_only) {
- if (da->attr_set) {
+ if (da->state.attr_set) {
fr_dict_attr_t *parent = fr_dict_attr_unconst(da->parent);
if (da->attr > da->parent->last_child_attr) {