Add an unsigned int/string pair type, modelled on the value string of
wireshark
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef UC_VAL_STR_H_
|
||||||
|
#define UC_VAL_STR_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct UCValStr {
|
||||||
|
unsigned int val;
|
||||||
|
const char *str;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UC_VS_ENTRY(constant) {constant, #constant}
|
||||||
|
#define UC_VS_TERMINATOR {-1, NULL}
|
||||||
|
|
||||||
|
/** Find @val in @array.
|
||||||
|
* The last .str in @array must be a NULL pointer.
|
||||||
|
* (does a linear search)
|
||||||
|
*
|
||||||
|
* @param val value to find
|
||||||
|
* @param array array to search
|
||||||
|
* @return the string associated with @val or NULL
|
||||||
|
*/
|
||||||
|
const char *uc_vs_search(unsigned int val, const struct UCValStr *array);
|
||||||
|
|
||||||
|
/** Find @val in @array.
|
||||||
|
* @array must be sorted on val and must not be empty
|
||||||
|
* (does a binary search)
|
||||||
|
*
|
||||||
|
* @param val value to find
|
||||||
|
* @param array array to search
|
||||||
|
* @return the string associated with @val or NULL
|
||||||
|
*/
|
||||||
|
const char *uc_vs_bsearch(unsigned int val,
|
||||||
|
const struct UCValStr *array,
|
||||||
|
size_t array_len);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "ucore/val_str.h"
|
||||||
|
#include "ucore/saturating_math.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char *uc_vs_search(unsigned int val, const struct UCValStr *array)
|
||||||
|
{
|
||||||
|
const char *found = NULL;
|
||||||
|
|
||||||
|
while (array->str) {
|
||||||
|
if (array->val == val) {
|
||||||
|
found = array->str;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
array++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *uc_vs_bsearch(unsigned int val,
|
||||||
|
const struct UCValStr *array,
|
||||||
|
size_t array_len)
|
||||||
|
{
|
||||||
|
size_t i = array_len;
|
||||||
|
const struct UCValStr *start = array;
|
||||||
|
|
||||||
|
while (i != 0) {
|
||||||
|
const struct UCValStr *curr;
|
||||||
|
curr = start + i / 2;
|
||||||
|
|
||||||
|
if (curr->val == val) {
|
||||||
|
return curr->str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr->val < val) {
|
||||||
|
start = curr + 1;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = i / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
+3
-1
@@ -29,6 +29,7 @@ extern Suite *ratelimit_suite(void);
|
|||||||
extern Suite *htable_suite(void);
|
extern Suite *htable_suite(void);
|
||||||
extern Suite *heapsort_suite(void);
|
extern Suite *heapsort_suite(void);
|
||||||
extern Suite *dstr_suite(void);
|
extern Suite *dstr_suite(void);
|
||||||
|
extern Suite *val_str_suite(void);
|
||||||
|
|
||||||
static suite_func suites[] = {
|
static suite_func suites[] = {
|
||||||
bitvec_suite,
|
bitvec_suite,
|
||||||
@@ -52,7 +53,8 @@ static suite_func suites[] = {
|
|||||||
clock_suite,
|
clock_suite,
|
||||||
threadqueue_suite,
|
threadqueue_suite,
|
||||||
heapsort_suite,
|
heapsort_suite,
|
||||||
dstr_suite
|
dstr_suite,
|
||||||
|
val_str_suite
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#include <check.h>
|
||||||
|
#include <ucore/val_str.h>
|
||||||
|
|
||||||
|
|
||||||
|
START_TEST (test_val_str_search)
|
||||||
|
struct UCValStr vals[] = {
|
||||||
|
UC_VS_ENTRY(1),
|
||||||
|
UC_VS_ENTRY(5),
|
||||||
|
UC_VS_ENTRY(0),
|
||||||
|
UC_VS_TERMINATOR
|
||||||
|
};
|
||||||
|
ck_assert_str_eq(uc_vs_search(0 , vals) , "0");
|
||||||
|
ck_assert_str_eq(uc_vs_search(1 , vals) , "1");
|
||||||
|
ck_assert_str_eq(uc_vs_search(5 , vals) , "5");
|
||||||
|
|
||||||
|
fail_if(uc_vs_search(10, vals) != NULL);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_val_str_bsearch_odd)
|
||||||
|
struct UCValStr vals[] = {
|
||||||
|
UC_VS_ENTRY(1),
|
||||||
|
UC_VS_ENTRY(2),
|
||||||
|
UC_VS_ENTRY(10),
|
||||||
|
UC_VS_ENTRY(100),
|
||||||
|
UC_VS_ENTRY(101),
|
||||||
|
};
|
||||||
|
const size_t len = sizeof vals/sizeof vals[0];
|
||||||
|
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(1 , vals , len) , "1");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(2 , vals , len) , "2");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(10 , vals , len) , "10");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(100 , vals , len) , "100");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(101 , vals , len) , "101");
|
||||||
|
|
||||||
|
fail_if(uc_vs_bsearch(0 , vals , len) != NULL);
|
||||||
|
fail_if(uc_vs_bsearch(55 , vals , len) != NULL);
|
||||||
|
fail_if(uc_vs_bsearch(999 , vals , len) != NULL);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST (test_val_str_bsearch_even)
|
||||||
|
struct UCValStr vals[] = {
|
||||||
|
UC_VS_ENTRY(1),
|
||||||
|
UC_VS_ENTRY(2),
|
||||||
|
UC_VS_ENTRY(10),
|
||||||
|
UC_VS_ENTRY(101),
|
||||||
|
};
|
||||||
|
const size_t len = sizeof vals/sizeof vals[0];
|
||||||
|
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(1 , vals , len) , "1");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(2 , vals , len) , "2");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(10 , vals , len) , "10");
|
||||||
|
ck_assert_str_eq(uc_vs_bsearch(101 , vals , len) , "101");
|
||||||
|
|
||||||
|
fail_if(uc_vs_bsearch(0 , vals , len) != NULL);
|
||||||
|
fail_if(uc_vs_bsearch(55 , vals , len) != NULL);
|
||||||
|
fail_if(uc_vs_bsearch(999 , vals , len) != NULL);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
|
||||||
|
Suite *val_str_suite(void)
|
||||||
|
{
|
||||||
|
Suite *s = suite_create("valstr");
|
||||||
|
TCase *tc = tcase_create("valstr tests");
|
||||||
|
tcase_add_test(tc, test_val_str_search);
|
||||||
|
tcase_add_test(tc, test_val_str_bsearch_odd);
|
||||||
|
tcase_add_test(tc, test_val_str_bsearch_even);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user