]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add alias auto-enumerator
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 1 Apr 2018 15:33:23 +0000 (16:33 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sun, 1 Apr 2018 15:34:29 +0000 (16:34 +0100)
src/lib/util/dict.c

index c1938457572392aa3b09bc535bb29071e6f7696d..581a2eb26e8a962e66db2e191ee423916ba9548c 100644 (file)
@@ -1884,6 +1884,85 @@ int fr_dict_enum_add_alias(fr_dict_attr_t const *da, char const *alias,
        return 0;
 }
 
+/** Add an alias to an integer attribute hashing the alias for the integer value
+ *
+ */
+int fr_dict_enum_add_alias_next(fr_dict_attr_t const *da, char const *alias)
+{
+       fr_value_box_t  v = {
+                               .type = da->type
+                       };
+       fr_value_box_t  s = {
+                               .type = da->type
+                       };
+
+       if (fr_dict_enum_by_alias(da, alias)) return 0;
+
+       switch (da->type) {
+       case FR_TYPE_INT8:
+               v.vb_int8 = s.vb_int8 = fr_hash_string(alias) & INT8_MAX;
+               break;
+
+       case FR_TYPE_INT16:
+               v.vb_int16 = s.vb_int16 = fr_hash_string(alias) & INT16_MAX;
+               break;
+
+       case FR_TYPE_INT32:
+               v.vb_int32 = s.vb_int32 = fr_hash_string(alias) & INT32_MAX;
+               break;
+
+       case FR_TYPE_INT64:
+               v.vb_int64 = s.vb_int64 = fr_hash_string(alias) & INT64_MAX;
+               break;
+
+       case FR_TYPE_UINT8:
+               v.vb_uint8 = s.vb_uint8 = fr_hash_string(alias) & UINT8_MAX;
+               break;
+
+       case FR_TYPE_UINT16:
+               v.vb_uint16 = s.vb_uint16 = fr_hash_string(alias) & UINT16_MAX;
+               break;
+
+       case FR_TYPE_UINT32:
+               v.vb_uint32 = s.vb_uint32 = fr_hash_string(alias) & UINT32_MAX;
+               break;
+
+       case FR_TYPE_UINT64:
+               v.vb_uint64 = s.vb_uint64 = fr_hash_string(alias) & UINT64_MAX;
+               break;
+
+       default:
+               fr_strerror_printf("Attribute is wrong type for auto-numbering, expected numeric type, got %s",
+                                  fr_int2str(dict_attr_types, da->type, "?Unknown?"));
+               return -1;
+       }
+
+       /*
+        *      If there's no existing value, add an enum
+        *      with the hash value of the alias.
+        *
+        *      This helps with debugging as the values
+        *      are consistent.
+        */
+       if (!fr_dict_enum_by_value(da, &v)) {
+       add:
+               return fr_dict_enum_add_alias(da, alias, &v, false, false);
+       }
+
+       for (;;) {
+               fr_value_box_increment(&v);
+
+               if (fr_value_box_cmp_op(T_OP_EQ, &v, &s) == 0) {
+                       fr_strerror_printf("No free integer values for enumeration");
+                       return -1;
+               }
+
+               if (!fr_dict_enum_by_value(da, &v)) goto add;
+       }
+
+       return 0;
+}
+
 /** Copy a known or unknown attribute to produce an unknown attribute
  *
  * Will copy the complete hierarchy down to the first known attribute.