enum: Allow specifying the name used when none of the flags are set

This commit is contained in:
Tobias Brunner 2021-12-17 14:25:44 +01:00
parent a5430e1601
commit 927103ece4
4 changed files with 14 additions and 11 deletions

View File

@ -42,6 +42,7 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
); );
ENUM_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES, ENUM_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES,
"NONE",
"REGISTERED", "REGISTERED",
"SA", "SA",
"POLICIES", "POLICIES",

View File

@ -70,15 +70,15 @@ enum {
} test_enum_flags; } test_enum_flags;
ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5, ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5,
"FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5"); "(unset)", "FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5");
ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4, ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4,
"FLAG3", "FLAG4"); "(unset)", "FLAG3", "FLAG4");
ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4, ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4,
"FLAG1", NULL, "FLAG3", NULL); "(unset)", "FLAG1", NULL, "FLAG3", NULL);
ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12, ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12, "(unset)",
"OVERFLOWFLAGLONGNAME1", "OVERFLOWFLAGLONGNAME2", "OVERFLOWFLAGLONGNAME3", "OVERFLOWFLAGLONGNAME1", "OVERFLOWFLAGLONGNAME2", "OVERFLOWFLAGLONGNAME3",
"OVERFLOWFLAGLONGNAME4", "OVERFLOWFLAGLONGNAME5", "OVERFLOWFLAGLONGNAME6", "OVERFLOWFLAGLONGNAME4", "OVERFLOWFLAGLONGNAME5", "OVERFLOWFLAGLONGNAME6",
"OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9", "OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9",

View File

@ -66,16 +66,17 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
/** /**
* Get the position of a flag name using offset calculation * Get the position of a flag name using offset calculation
*/ */
static int find_flag_pos(u_int val, u_int first) static int find_flag_pos(u_int first, u_int val)
{ {
int offset = 0; int offset = 0;
while (val != 0x01) while (first != 0x01)
{ {
val = val >> 1; first = first >> 1;
offset++; offset++;
} }
return first - offset; /* skip the first name as that's used if no flag is set */
return 1 + val - offset;
} }
/** /**
@ -95,7 +96,7 @@ char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
return buf; return buf;
} }
if (snprintf(buf, len, "(unset)") >= len) if (snprintf(buf, len, e->names[0]) >= len)
{ {
return NULL; return NULL;
} }

View File

@ -130,13 +130,14 @@ struct enum_name_t {
* @param name name of the enum_name list * @param name name of the enum_name list
* @param first enum value of the first enum string * @param first enum value of the first enum string
* @param last enum value of the last enum string * @param last enum value of the last enum string
* @param unset name used if no flags are set
* @param ... a list of strings * @param ... a list of strings
*/ */
#define ENUM_FLAGS(name, first, last, ...) \ #define ENUM_FLAGS(name, first, last, unset, ...) \
static enum_name_t name##last = {first, last + \ static enum_name_t name##last = {first, last + \
BUILD_ASSERT((__builtin_ffs(last)-__builtin_ffs(first)+1) == \ BUILD_ASSERT((__builtin_ffs(last)-__builtin_ffs(first)+1) == \
countof(((char*[]){__VA_ARGS__}))), \ countof(((char*[]){__VA_ARGS__}))), \
ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; ENUM_END(name, last) ENUM_FLAG_MAGIC, { unset, __VA_ARGS__ }}; ENUM_END(name, last)
/** /**
* Convert a enum value to its string representation. * Convert a enum value to its string representation.