diff --git a/include/ucore/val_str.h b/include/ucore/val_str.h index a724439..ad126d1 100644 --- a/include/ucore/val_str.h +++ b/include/ucore/val_str.h @@ -24,7 +24,7 @@ struct UCStrStr { #define UC_VS_TERMINATOR {-1, NULL} #define UC_SS_TERMINATOR {NULL, NULL} -/** find @val in @array. +/** Find @val in @array. * the last .str in @array must be a null pointer. * (does a linear search) * @@ -34,6 +34,17 @@ struct UCStrStr { */ const char *uc_val_2_str(unsigned int val, const struct UCValStr *array); + +/** 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 found struct UCValStr, which will be the last senitel + * in the array if no match was found + */ +const struct UCValStr *uc_val_2_str_vs(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) @@ -46,7 +57,7 @@ const char *uc_val_2_str_bs(unsigned int val, const struct UCValStr *array, size_t array_len); -/** find @val in @array. +/** Find @val in @array. * the last .val in @array must be a null pointer. * (does a linear search) * @@ -56,4 +67,14 @@ const char *uc_val_2_str_bs(unsigned int val, */ const char *uc_str_2_str(const char *restrict val, const struct UCStrStr *array); +/** Find @val in @array, case insensitive + * the last .val in @array must be a null pointer. + * (does a linear search) + * + * @param val value to find, using strcasecmp + * @param array array to search + * @return the string associated with @val or null + */ +const char *uc_str_2_str_ci(const char *restrict val, const struct UCStrStr *array); + #endif diff --git a/src/val_str.c b/src/val_str.c index ea92321..a0faf3e 100644 --- a/src/val_str.c +++ b/src/val_str.c @@ -19,6 +19,21 @@ const char *uc_val_2_str(unsigned int val, const struct UCValStr *array) return found; } +const struct UCValStr *uc_val_2_str_vs(unsigned int val, const struct UCValStr *array) +{ + const struct UCValStr *found = NULL; + + while (array->str) { + if (array->val == val) { + found = array; + break; + } + array++; + } + + return found; +} + const char *uc_val_2_str_bs(unsigned int val, const struct UCValStr *array, size_t array_len) @@ -62,3 +77,19 @@ const char *uc_str_2_str(const char *restrict val, const struct UCStrStr *array) return found; } +const char *uc_str_2_str_ci(const char *restrict val, const struct UCStrStr *array) +{ + const char *found = NULL; + + while (array->val) { + if (strcasecmp(val, array->val) == 0) { + found = array->str; + break; + } + array++; + } + + return found; +} + + diff --git a/test/test_val_str.c b/test/test_val_str.c index fb104bd..d62cbdc 100644 --- a/test/test_val_str.c +++ b/test/test_val_str.c @@ -16,6 +16,20 @@ START_TEST (test_val_str_search) fail_if(uc_val_2_str(10, vals) != NULL); END_TEST +START_TEST (test_val_str_vs_search) + struct UCValStr vals[] = { + UC_VS_ENTRY(1), + UC_VS_ENTRY(5), + UC_VS_ENTRY(0), + UC_VS_TERMINATOR + }; + ck_assert_str_eq(uc_val_2_str_vs(0 , vals)->str , "0"); + ck_assert_str_eq(uc_val_2_str_vs(1 , vals)->str , "1"); + ck_assert_str_eq(uc_val_2_str_vs(5 , vals)->str , "5"); + + fail_if(uc_val_2_str(10, vals) != NULL); +END_TEST + START_TEST (test_val_str_bsearch_odd) struct UCValStr vals[] = { UC_VS_ENTRY(1), @@ -70,15 +84,30 @@ START_TEST (test_str_str_search) fail_if(uc_str_2_str("10", vals) != NULL); END_TEST +START_TEST (test_str_str_ci_search) + struct UCStrStr vals[] = { + {"A", "1"}, + {"az","2"}, + {"C", "3"}, + UC_SS_TERMINATOR + }; + ck_assert_str_eq(uc_str_2_str_ci("a" , vals) , "1"); + ck_assert_str_eq(uc_str_2_str_ci("aZ" , vals) ,"2"); + ck_assert_str_eq(uc_str_2_str_ci("C" , vals) , "3"); + + fail_if(uc_str_2_str_ci("aza", vals) != 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_vs_search); tcase_add_test(tc, test_val_str_bsearch_odd); tcase_add_test(tc, test_val_str_bsearch_even); tcase_add_test(tc, test_str_str_search); + tcase_add_test(tc, test_str_str_ci_search); suite_add_tcase(s, tc);