enum: Add helper to parse enum flags from strings

Individual flag names are separated by |.
This commit is contained in:
Tobias Brunner
2022-04-14 18:42:01 +02:00
parent 4f4d4021b4
commit 7137fd96c2
3 changed files with 149 additions and 9 deletions
+49
View File
@@ -17,6 +17,7 @@
#include <stdio.h>
#include <library.h>
#include <collections/enumerator.h>
#include <utils/utils.h>
#include "enum.h"
@@ -135,6 +136,54 @@ char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
return buf;
}
/*
* Described in header
*/
bool enum_flags_from_string_as_int(enum_name_t *e, const char *str, u_int *val)
{
enumerator_t *enumerator;
char *name;
*val = 0;
if (!str || !*str)
{
return TRUE;
}
else if (e->next != ENUM_FLAG_MAGIC)
{
return enum_from_name_as_int(e, str, val);
}
enumerator = enumerator_create_token(str, "|", " ");
while (enumerator->enumerate(enumerator, &name))
{
u_int flag, i;
bool found = FALSE;
if (strcaseeq(name, e->names[0]))
{ /* accept name used if no flags are set */
continue;
}
for (i = 1, flag = e->first; flag <= e->last; i++, flag <<= 1)
{
if (e->names[i] && strcaseeq(name, e->names[i]))
{
*val |= flag;
found = TRUE;
break;
}
}
if (!found)
{
enumerator->destroy(enumerator);
return FALSE;
}
}
enumerator->destroy(enumerator);
return TRUE;
}
/**
* See header.
*/
+33 -3
View File
@@ -158,7 +158,7 @@ char *enum_to_name(enum_name_t *e, int val);
*/
#define enum_from_name(e, name, valp) ({ \
int _val; \
int _found = enum_from_name_as_int(e, name, &_val); \
bool _found = enum_from_name_as_int(e, name, &_val); \
if (_found) \
{ \
*(valp) = _val; \
@@ -168,13 +168,13 @@ char *enum_to_name(enum_name_t *e, int val);
/**
* Convert a enum string back to its enum value, integer pointer variant.
*
* This variant takes integer pointer only, use enum_from_name() to pass
* This variant takes an integer pointer, use enum_from_name() to pass
* enum type pointers for the result.
*
* @param e enum names for this enum value
* @param name name to get enum value for
* @param val integer pointer receiving value
* @return TRUE if enum name found, FALSE otherwise
* @return TRUE if all names found, FALSE otherwise
*/
bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val);
@@ -189,6 +189,36 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val);
*/
char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len);
/**
* Convert a string of flags separated by | to their combined value
*
* @param e enum names for this enum value
* @param str string to get enum value for
* @param valp variable sized pointer receiving value
* @return TRUE if all names found, FALSE otherwise
*/
#define enum_flags_from_string(e, str, valp) ({ \
u_int _val; \
bool _found = enum_flags_from_string_as_int(e, str, &_val); \
if (_found) \
{ \
*(valp) = _val; \
} \
_found; })
/**
* Convert a string of flags separated by | to their combined value.
*
* This variant takes an unsigned integer pointer, use enum_flags_from_names()
* to pass enum type pointers for the result.
*
* @param e enum names for this enum value
* @param str string to get enum value for
* @param val integer pointer receiving value
* @return TRUE if enum name found, FALSE otherwise
*/
bool enum_flags_from_string_as_int(enum_name_t *e, const char *str, u_int *val);
/**
* printf hook function for enum_names_t.
*