]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
enum: Chain enum_name_t elements to a fixed header
authorTobias Brunner <tobias@strongswan.org>
Wed, 8 Feb 2023 12:45:00 +0000 (13:45 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Feb 2023 15:00:11 +0000 (16:00 +0100)
src/libstrongswan/tests/suites/test_proposal.c
src/libstrongswan/utils/enum.c
src/libstrongswan/utils/enum.h

index c42f9e4a660b849a44aa0fab9f32ff915e80f287..7cf9966d8f9165f1364c93ef090e5994f9294db1 100644 (file)
@@ -20,7 +20,7 @@
 
 START_TEST(test_dh_group_mapping)
 {
-       enum_name_t *e = key_exchange_method_names_short;
+       enum_name_elem_t *e = key_exchange_method_names_short->elem;
        key_exchange_method_t ke;
        const proposal_token_t *token;
        char *name;
index 4f93e8c6d2f6c715e7bea1d6aa03e1960b5bc0bc..8fc2ab5955dc0599addb298ed45a3bf6ffc3db9f 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2022-2023 Tobias Brunner
  * Copyright (C) 2006 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
  */
 char *enum_to_name(enum_name_t *e, int val)
 {
+       enum_name_elem_t *cur;
+
        if (!e)
        {
                return NULL;
        }
-       do
+       for (cur = e->elem; cur; cur = cur->next)
        {
-               if (val >= e->first && val <= e->last)
+               if (val >= cur->first && val <= cur->last)
                {
-                       return e->names[val - e->first];
+                       return cur->names[val - cur->first];
                }
        }
-       while ((e = e->next));
        return NULL;
 }
 
@@ -48,20 +50,25 @@ char *enum_to_name(enum_name_t *e, int val)
  */
 bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
 {
-       do
+       enum_name_elem_t *cur;
+
+       if (!e)
+       {
+               return FALSE;
+       }
+       for (cur = e->elem; cur; cur = cur->next)
        {
-               int i, count = e->last - e->first + 1;
+               int i, count = cur->last - cur->first + 1;
 
                for (i = 0; i < count; i++)
                {
-                       if (name && strcaseeq(name, e->names[i]))
+                       if (name && strcaseeq(name, cur->names[i]))
                        {
-                               *val = e->first + i;
+                               *val = cur->first + i;
                                return TRUE;
                        }
                }
        }
-       while ((e = e->next));
        return FALSE;
 }
 
@@ -86,10 +93,16 @@ static int find_flag_pos(u_int first, u_int val)
  */
 char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
 {
+       enum_name_elem_t *cur;
        char *pos = buf, *delim = "";
        int i, wr;
 
-       if (e->next != ENUM_FLAG_MAGIC)
+       if (!e)
+       {
+               return NULL;
+       }
+       cur = e->elem;
+       if (cur->next != ENUM_FLAG_MAGIC)
        {
                if (snprintf(buf, len, "(%d)", (int)val) >= len)
                {
@@ -98,7 +111,7 @@ char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
                return buf;
        }
 
-       if (snprintf(buf, len, "%s", e->names[0]) >= len)
+       if (snprintf(buf, len, "%s", cur->names[0]) >= len)
        {
                return NULL;
        }
@@ -111,9 +124,9 @@ char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
                {
                        char *name = NULL, hex[32];
 
-                       if (flag >= (u_int)e->first && flag <= (u_int)e->last)
+                       if (flag >= (u_int)cur->first && flag <= (u_int)cur->last)
                        {
-                               name = e->names[find_flag_pos(e->first, i)];
+                               name = cur->names[find_flag_pos(cur->first, i)];
                        }
                        else
                        {
@@ -142,16 +155,18 @@ char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
  */
 bool enum_flags_from_string_as_int(enum_name_t *e, const char *str, u_int *val)
 {
+       enum_name_elem_t *cur;
        enumerator_t *enumerator;
        char *name;
 
        *val = 0;
 
-       if (!str || !*str)
+       if (!e || !str || !*str)
        {
                return TRUE;
        }
-       else if (e->next != ENUM_FLAG_MAGIC)
+       cur = e->elem;
+       if (cur->next != ENUM_FLAG_MAGIC)
        {
                return enum_from_name_as_int(e, str, val);
        }
@@ -162,13 +177,13 @@ bool enum_flags_from_string_as_int(enum_name_t *e, const char *str, u_int *val)
                u_int flag, i;
                bool found = FALSE;
 
-               if (strcaseeq(name, e->names[0]))
+               if (strcaseeq(name, cur->names[0]))
                {       /* accept name used if no flags are set */
                        continue;
                }
-               for (i = 1, flag = e->first; flag <= e->last; i++, flag <<= 1)
+               for (i = 1, flag = cur->first; flag <= cur->last; i++, flag <<= 1)
                {
-                       if (e->names[i] && strcaseeq(name, e->names[i]))
+                       if (cur->names[i] && strcaseeq(name, cur->names[i]))
                        {
                                *val |= flag;
                                found = TRUE;
@@ -195,7 +210,7 @@ int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
        int val = *((int*)(args[1]));
        char *name, buf[512];
 
-       if (ed && ed->next == ENUM_FLAG_MAGIC)
+       if (ed && ed->elem->next == ENUM_FLAG_MAGIC)
        {
                name = enum_flags_to_string(ed, val, buf, sizeof(buf));
                if (name == NULL)
index 45649224ea4944fdae531bcc44151f526084114e..95987449ca3d48f6a3cce65ea2221d8e612af104 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2019 Tobias Brunner
+ * Copyright (C) 2009-2023 Tobias Brunner
  * Copyright (C) 2006-2008 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
 #include <utils/printf_hook/printf_hook.h>
 
 typedef struct enum_name_t enum_name_t;
+typedef struct enum_name_elem_t enum_name_elem_t;
 
 /**
  * Magic enum_name_t pointer indicating this is an enum name for flags
  */
-#define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0)
+#define ENUM_FLAG_MAGIC ((enum_name_elem_t*)~(uintptr_t)0)
 
 /**
  * Struct to store names for enums.
@@ -60,13 +61,21 @@ typedef struct enum_name_t enum_name_t;
  * by the numerical enum value.
  */
 struct enum_name_t {
+       /** first enum_name_elem_t in chain */
+       enum_name_elem_t *elem;
+};
+
+/**
+ * Enum name element to chain to enum_name_t.
+ */
+struct enum_name_elem_t {
        /** value of the first enum string, values are expected to be (u_)int, using
         * int64_t here instead, however, avoids warnings for large unsigned ints */
        int64_t first;
        /** value of the last enum string */
        int64_t last;
-       /** next enum_name_t in list, or ENUM_FLAG_MAGIC */
-       enum_name_t *next;
+       /** next enum_name_elem_t in list, or ENUM_FLAG_MAGIC */
+       enum_name_elem_t *next;
        /** array of strings containing names from first to last */
        char *names[];
 };
@@ -80,7 +89,7 @@ struct enum_name_t {
  * @param ...  a list of strings
  */
 #define ENUM_BEGIN(name, first, last, ...) \
-       static enum_name_t name##last = {first, last + \
+       static enum_name_elem_t name##last = {first, last + \
                BUILD_ASSERT(((last)-(first)+1) == countof(((char*[]){__VA_ARGS__}))), \
                NULL, { __VA_ARGS__ }}
 
@@ -94,7 +103,7 @@ struct enum_name_t {
  * @param ...  a list of strings
  */
 #define ENUM_NEXT(name, first, last, prev, ...) \
-       static enum_name_t name##last = {first, last + \
+       static enum_name_elem_t name##last = {first, last + \
                BUILD_ASSERT(((last)-(first)+1) == countof(((char*[]){__VA_ARGS__}))), \
                &name##prev, { __VA_ARGS__ }}
 
@@ -104,7 +113,9 @@ struct enum_name_t {
  * @param name name of the enum_name list
  * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
  */
-#define ENUM_END(name, prev) enum_name_t *name = &name##prev;
+#define ENUM_END(name, prev) \
+       static enum_name_t name##head = { .elem = &name##prev }; \
+       enum_name_t *name = &name##head
 
 /**
  * Define a enum name with only one range.
@@ -135,7 +146,7 @@ struct enum_name_t {
  * @param ...  a list of strings
  */
 #define ENUM_FLAGS(name, first, last, unset, ...) \
-       static enum_name_t name##last = {first, last + \
+       static enum_name_elem_t name##last = {first, last + \
                BUILD_ASSERT((__builtin_ffs(last)-__builtin_ffs(first)+1) == \
                        countof(((char*[]){__VA_ARGS__}))), \
                ENUM_FLAG_MAGIC, { unset, __VA_ARGS__ }}; ENUM_END(name, last)