mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
enum: Add functions to add and remove mappings from enum names
Co-authored-by: Thomas Egerer <thomas.egerer@secunet.com>
This commit is contained in:
parent
3cf5653640
commit
0de42047a9
@ -85,6 +85,13 @@ ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12, "(unset)",
|
|||||||
"OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9",
|
"OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9",
|
||||||
"OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12");
|
"OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12");
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* add_enum_names
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENUM_EXT(e1, 65000, 65001, "CONT65000", "CONT65001");
|
||||||
|
ENUM_EXT(e2, 62000, 62001, "CONT62000", "CONT62001");
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* enum_to_name
|
* enum_to_name
|
||||||
*/
|
*/
|
||||||
@ -172,6 +179,15 @@ static struct {
|
|||||||
{FALSE, 0, "asdf"},
|
{FALSE, 0, "asdf"},
|
||||||
{FALSE, 0, ""},
|
{FALSE, 0, ""},
|
||||||
{FALSE, 0, NULL},
|
{FALSE, 0, NULL},
|
||||||
|
}, enum_tests_ext[] = {
|
||||||
|
{TRUE, CONT1, "CONT1"},
|
||||||
|
{TRUE, 62000, "CONT62000"},
|
||||||
|
{TRUE, 62001, "CONT62001"},
|
||||||
|
{TRUE, 65000, "CONT65000"},
|
||||||
|
{TRUE, 65001, "CONT65001"},
|
||||||
|
{FALSE, 0, "CONT64000"},
|
||||||
|
{FALSE, 0, ""},
|
||||||
|
{FALSE, 0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
START_TEST(test_enum_from_name_cont)
|
START_TEST(test_enum_from_name_cont)
|
||||||
@ -196,6 +212,23 @@ START_TEST(test_enum_from_name_split)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_enum_from_name_ext)
|
||||||
|
{
|
||||||
|
int val = 0;
|
||||||
|
bool found;
|
||||||
|
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e1);
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e2);
|
||||||
|
|
||||||
|
found = enum_from_name(test_enum_cont_names, enum_tests_ext[_i].str, &val);
|
||||||
|
ck_assert(enum_tests_ext[_i].found == found);
|
||||||
|
ck_assert_int_eq(val, enum_tests_ext[_i].val);
|
||||||
|
|
||||||
|
enum_remove_enum_names(test_enum_cont_names, e1);
|
||||||
|
enum_remove_enum_names(test_enum_cont_names, e2);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* enum_printf_hook
|
* enum_printf_hook
|
||||||
*/
|
*/
|
||||||
@ -441,6 +474,51 @@ START_TEST(test_enum_printf_hook_width)
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_enum_printf_hook_add_enum_names)
|
||||||
|
{
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e1);
|
||||||
|
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, 65001);
|
||||||
|
ck_assert_str_eq("CONT65001", buf);
|
||||||
|
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e2);
|
||||||
|
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, 62001);
|
||||||
|
ck_assert_str_eq("CONT62001", buf);
|
||||||
|
|
||||||
|
/* adding the same list repeatedly should not result in an infinite loop */
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e2);
|
||||||
|
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, 62001);
|
||||||
|
ck_assert_str_eq("CONT62001", buf);
|
||||||
|
|
||||||
|
/* can also be defined inside a function as long as the same function is
|
||||||
|
* adding and removing it */
|
||||||
|
ENUM_EXT(e3, 64000, 64001, "CONT64000", "CONT64001");
|
||||||
|
enum_add_enum_names(test_enum_cont_names, e3);
|
||||||
|
snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, 64000);
|
||||||
|
ck_assert_str_eq("CONT64000", buf);
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%N, %N, %N", test_enum_cont_names, 62001,
|
||||||
|
test_enum_cont_names, 65000, test_enum_cont_names, 64000);
|
||||||
|
ck_assert_str_eq("CONT62001, CONT65000, CONT64000", buf);
|
||||||
|
|
||||||
|
enum_remove_enum_names(test_enum_cont_names, e2);
|
||||||
|
snprintf(buf, sizeof(buf), "%N, %N, %N", test_enum_cont_names, 62001,
|
||||||
|
test_enum_cont_names, 65000, test_enum_cont_names, 64000);
|
||||||
|
ck_assert_str_eq("(62001), CONT65000, CONT64000", buf);
|
||||||
|
|
||||||
|
enum_remove_enum_names(test_enum_cont_names, e3);
|
||||||
|
snprintf(buf, sizeof(buf), "%N, %N, %N", test_enum_cont_names, 62001,
|
||||||
|
test_enum_cont_names, 65000, test_enum_cont_names, 64000);
|
||||||
|
ck_assert_str_eq("(62001), CONT65000, (64000)", buf);
|
||||||
|
|
||||||
|
enum_remove_enum_names(test_enum_cont_names, e1);
|
||||||
|
snprintf(buf, sizeof(buf), "%N, %N, %N", test_enum_cont_names, 62001,
|
||||||
|
test_enum_cont_names, 65000, test_enum_cont_names, 64000);
|
||||||
|
ck_assert_str_eq("(62001), (65000), (64000)", buf);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
Suite *enum_suite_create()
|
Suite *enum_suite_create()
|
||||||
{
|
{
|
||||||
Suite *s;
|
Suite *s;
|
||||||
@ -456,6 +534,7 @@ Suite *enum_suite_create()
|
|||||||
tc = tcase_create("enum_from_name");
|
tc = tcase_create("enum_from_name");
|
||||||
tcase_add_loop_test(tc, test_enum_from_name_cont, 0, countof(enum_tests_cont));
|
tcase_add_loop_test(tc, test_enum_from_name_cont, 0, countof(enum_tests_cont));
|
||||||
tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
|
tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
|
||||||
|
tcase_add_loop_test(tc, test_enum_from_name_ext, 0, countof(enum_tests_ext));
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("enum_flags_to_string");
|
tc = tcase_create("enum_flags_to_string");
|
||||||
@ -478,6 +557,7 @@ Suite *enum_suite_create()
|
|||||||
tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow));
|
tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow));
|
||||||
tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum));
|
tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum));
|
||||||
tcase_add_test(tc, test_enum_printf_hook_width);
|
tcase_add_test(tc, test_enum_printf_hook_width);
|
||||||
|
tcase_add_test(tc, test_enum_printf_hook_add_enum_names);
|
||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2023 Tobias Brunner
|
||||||
* Copyright (C) 2006 Martin Willi
|
* Copyright (C) 2006 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@ -23,6 +24,49 @@
|
|||||||
|
|
||||||
#include "enum.h"
|
#include "enum.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header
|
||||||
|
*/
|
||||||
|
void enum_add_enum_names(enum_name_t *e, enum_name_t *names)
|
||||||
|
{
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!e->next)
|
||||||
|
{
|
||||||
|
e->next = names;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (e->next == names)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((e = e->next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header
|
||||||
|
*/
|
||||||
|
void enum_remove_enum_names(enum_name_t *e, enum_name_t *names)
|
||||||
|
{
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (e->next == names)
|
||||||
|
{
|
||||||
|
e->next = names->next;
|
||||||
|
names->next = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((e = e->next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header.
|
* See header.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2009-2019 Tobias Brunner
|
* Copyright (C) 2009-2023 Tobias Brunner
|
||||||
* Copyright (C) 2006-2008 Martin Willi
|
* Copyright (C) 2006-2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@ -140,6 +140,41 @@ struct enum_name_t {
|
|||||||
countof(((char*[]){__VA_ARGS__}))), \
|
countof(((char*[]){__VA_ARGS__}))), \
|
||||||
ENUM_FLAG_MAGIC, { unset, __VA_ARGS__ }}; ENUM_END(name, last)
|
ENUM_FLAG_MAGIC, { unset, __VA_ARGS__ }}; ENUM_END(name, last)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a static enum name that can be added and removed to an existing list
|
||||||
|
* via enum_add_enum_names() and enum_remove_enum_names(), respectively.
|
||||||
|
*
|
||||||
|
* @param name name of the static enum_name element
|
||||||
|
* @param first enum value of the first enum string
|
||||||
|
* @param last enum value of the last enum string
|
||||||
|
* @param ... a list of strings
|
||||||
|
*/
|
||||||
|
#define ENUM_EXT(name, first, last, ...) \
|
||||||
|
ENUM_BEGIN(name, first, last, __VA_ARGS__); static ENUM_END(name, last)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register enum names for additional enum values with an existing enum name.
|
||||||
|
*
|
||||||
|
* @note Must be called while running single-threaded, e.g. when plugins and
|
||||||
|
* their features are loaded. Use enum_remove_enum_names() to remove the names
|
||||||
|
* during deinitialization.
|
||||||
|
*
|
||||||
|
* @param e enum names to add new names to
|
||||||
|
* @param names additional enum names
|
||||||
|
*/
|
||||||
|
void enum_add_enum_names(enum_name_t *e, enum_name_t *names);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove previously registered enum names.
|
||||||
|
*
|
||||||
|
* @note Must be called while running single-threaded, e.g. when plugins and
|
||||||
|
* their features are unloaded.
|
||||||
|
*
|
||||||
|
* @param e enum names to remove previously added names from
|
||||||
|
* @param names additional enum names to remove
|
||||||
|
*/
|
||||||
|
void enum_remove_enum_names(enum_name_t *e, enum_name_t *names);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a enum value to its string representation.
|
* Convert a enum value to its string representation.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user