diff --git a/src/lib/core/util.c b/src/lib/core/util.c index 0576574b0d684543f52ed99369b4135d1f8220e6..5970fdf81ea518be4dfa39ed670f9f43ab08e001 100644 --- a/src/lib/core/util.c +++ b/src/lib/core/util.c @@ -510,3 +510,22 @@ strtolowerdup(const char *s) lowercase[len] = '\0'; return lowercase; } + +char * +strtoupper(char *s) +{ + for (size_t i = 0; s[i] != '\0'; ++i) + s[i] = (char)toupper(s[i]); + return s; +} + +char * +strtoupperdup(const char *s) +{ + size_t len = strlen(s); + char *uppercase = xmalloc(len + 1); + for (size_t i = 0; i < len; ++i) + uppercase[i] = (char)toupper(s[i]); + uppercase[len] = '\0'; + return uppercase; +} diff --git a/src/trivia/util.h b/src/trivia/util.h index 70477c8cc1bfdc1512e89e9f20736068bc69e69e..ccfc9cd40df98bc0e64603e62f5be24be0d9dbb5 100644 --- a/src/trivia/util.h +++ b/src/trivia/util.h @@ -748,6 +748,17 @@ strtolower(char *s); char * strtolowerdup(const char *s); +/** Returns the null-terminated string converted to upper case in-place. */ +char * +strtoupper(char *s); + +/** + * Returns a copy of the null-terminated string converted to upper case. The + * result is dynamically allocated using `xmalloc`. + */ +char * +strtoupperdup(const char *s); + #if !defined(__cplusplus) && !defined(static_assert) # define static_assert _Static_assert #endif diff --git a/test/unit/string.c b/test/unit/string.c index 467e72809675d0b722f937757d7b86c778f79b23..312143501ca19f4fdea5b0fa7e0cc7a558aa3ae9 100644 --- a/test/unit/string.c +++ b/test/unit/string.c @@ -5,7 +5,8 @@ #include "unit.h" static const char *const test_lower_case_conv_expected = "str"; -static const char *const test_lower_case_conv_input[] = { +static const char *const test_upper_case_conv_expected = "STR"; +static const char *const test_case_conv_input[] = { "str", "Str", "sTr", "stR", "STr", "sTR", "StR", "STR" }; @@ -50,15 +51,15 @@ static void test_strtolowerdup(void) { header(); - plan(lengthof(test_lower_case_conv_input) * 2); + plan(lengthof(test_case_conv_input) * 2); - for (size_t i = 0; i < lengthof(test_lower_case_conv_input); ++i) { - char *test = strtolowerdup(test_lower_case_conv_input[i]); - isnt(test, test_lower_case_conv_input[i], - "a copy of %s is returned", test_lower_case_conv_input[i]); + for (size_t i = 0; i < lengthof(test_case_conv_input); ++i) { + char *test = strtolowerdup(test_case_conv_input[i]); + isnt(test, test_case_conv_input[i], + "a copy of %s is returned", test_case_conv_input[i]); is(strcmp(test_lower_case_conv_expected, test), 0, "%s is converted to lower case correctly", - test_lower_case_conv_input[i]); + test_case_conv_input[i]); free(test); } @@ -70,15 +71,55 @@ static void test_strtolower(void) { header(); - plan(lengthof(test_lower_case_conv_input) * 2); + plan(lengthof(test_case_conv_input) * 2); - for (size_t i = 0; i < lengthof(test_lower_case_conv_input); ++i) { - char *cp = xstrdup(test_lower_case_conv_input[i]); + for (size_t i = 0; i < lengthof(test_case_conv_input); ++i) { + char *cp = xstrdup(test_case_conv_input[i]); char *test = strtolower(cp); is(test, cp, "%s is converted in-place", cp); is(strcmp(test_lower_case_conv_expected, test), 0, "%s is converted to lower case correctly", - test_lower_case_conv_input[i]); + test_case_conv_input[i]); + free(cp); + } + + footer(); + check_plan(); +} + +static void +test_strtoupperdup(void) +{ + header(); + plan(lengthof(test_case_conv_input) * 2); + + for (size_t i = 0; i < lengthof(test_case_conv_input); ++i) { + char *test = strtoupperdup(test_case_conv_input[i]); + isnt(test, test_case_conv_input[i], + "a copy of %s is returned", test_case_conv_input[i]); + is(strcmp(test_upper_case_conv_expected, test), 0, + "%s is converted to upper case correctly", + test_case_conv_input[i]); + free(test); + } + + footer(); + check_plan(); +} + +static void +test_strtoupper(void) +{ + header(); + plan(lengthof(test_case_conv_input) * 2); + + for (size_t i = 0; i < lengthof(test_case_conv_input); ++i) { + char *cp = xstrdup(test_case_conv_input[i]); + char *test = strtoupper(cp); + is(test, cp, "%s is converted in-place", cp); + is(strcmp(test_upper_case_conv_expected, test), 0, + "%s is converted to upper case correctly", + test_case_conv_input[i]); free(cp); } @@ -89,12 +130,14 @@ test_strtolower(void) int main(void) { - plan(3); + plan(5); header(); test_strlcat(); test_strtolowerdup(); test_strtolower(); + test_strtoupperdup(); + test_strtoupper(); footer(); return check_plan();