From patchwork Wed Apr 8 14:32:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 237413 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Wed, 8 Apr 2020 08:32:56 -0600 Subject: [PATCH v5 2/6] lib: Add a function to convert a string to upper case In-Reply-To: <20200408143300.52636-1-sjg@chromium.org> References: <20200408143300.52636-1-sjg@chromium.org> Message-ID: <20200408083251.v5.2.I1ca01985ee4914667e7a2ba006de71c2546eada3@changeid> Add a helper function for this operation. Update the strtoul() tests to check upper case as well. Signed-off-by: Simon Glass Reviewed-by: Heinrich Schuchardt --- Changes in v5: - Drop change to FAT - Add new tests for copying an empty string - Use size_t instead of int, require caller to use SIZE_MAX - Update the algorithm to avoid dealing with -1 Changes in v4: - Add a new patch to convert a string to upper case include/vsprintf.h | 12 +++++++ lib/strto.c | 8 +++++ test/str_ut.c | 78 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 15 deletions(-) diff --git a/include/vsprintf.h b/include/vsprintf.h index 56844dd2de8..d9fb68add0c 100644 --- a/include/vsprintf.h +++ b/include/vsprintf.h @@ -222,4 +222,16 @@ bool str2long(const char *p, ulong *num); * @hz: Value to convert */ char *strmhz(char *buf, unsigned long hz); + +/** + * str_to_upper() - Convert a string to upper case + * + * This simply uses toupper() on each character of the string. + * + * @in: String to convert (must be large enough to hold the output string) + * @out: Buffer to put converted string + * @len: Number of bytes available in @out (SIZE_MAX for all) + */ +void str_to_upper(const char *in, char *out, size_t len); + #endif diff --git a/lib/strto.c b/lib/strto.c index 55ff9f7437d..c00bb5895df 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -163,3 +163,11 @@ long trailing_strtol(const char *str) { return trailing_strtoln(str, NULL); } + +void str_to_upper(const char *in, char *out, size_t len) +{ + for (; len > 0 && *in; len--) + *out++ = toupper(*in++); + if (len) + *out = '\0'; +} diff --git a/test/str_ut.c b/test/str_ut.c index fab8de595cb..7c8015050ad 100644 --- a/test/str_ut.c +++ b/test/str_ut.c @@ -19,36 +19,84 @@ static const char str3[] = "0xbI'm sorry you're alive."; /* Declare a new str test */ #define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test) +static int str_test_upper(struct unit_test_state *uts) +{ + char out[TEST_STR_SIZE]; + + /* Make sure it adds a terminator */ + out[strlen(str1)] = 'a'; + str_to_upper(str1, out, SIZE_MAX); + ut_asserteq_str("I'M SORRY I'M LATE.", out); + + /* In-place operation */ + strcpy(out, str2); + str_to_upper(out, out, SIZE_MAX); + ut_asserteq_str("1099ABNO, DON'T BOTHER APOLOGISING.", out); + + /* Limited length */ + str_to_upper(str1, out, 7); + ut_asserteq_str("I'M SORO, DON'T BOTHER APOLOGISING.", out); + + /* In-place with limited length */ + strcpy(out, str2); + str_to_upper(out, out, 7); + ut_asserteq_str("1099ABNo, don't bother apologising.", out); + + /* Copy an empty string to a buffer with space*/ + out[1] = 0x7f; + str_to_upper("", out, SIZE_MAX); + ut_asserteq('\0', *out); + ut_asserteq(0x7f, out[1]); + + /* Copy an empty string to a buffer with no space*/ + out[0] = 0x7f; + str_to_upper("", out, 0); + ut_asserteq(0x7f, out[0]); + + return 0; +} +STR_TEST(str_test_upper, 0); + static int run_strtoul(struct unit_test_state *uts, const char *str, int base, - ulong expect_val, int expect_endp_offset) + ulong expect_val, int expect_endp_offset, bool upper) { + char out[TEST_STR_SIZE]; char *endp; ulong val; - val = simple_strtoul(str, &endp, base); + strcpy(out, str); + if (upper) + str_to_upper(out, out, -1); + + val = simple_strtoul(out, &endp, base); ut_asserteq(expect_val, val); - ut_asserteq(expect_endp_offset, endp - str); + ut_asserteq(expect_endp_offset, endp - out); return 0; } static int str_simple_strtoul(struct unit_test_state *uts) { - /* Base 10 and base 16 */ - ut_assertok(run_strtoul(uts, str2, 10, 1099, 4)); - ut_assertok(run_strtoul(uts, str2, 16, 0x1099ab, 6)); + int upper; + + /* Check that it is case-insentive */ + for (upper = 0; upper < 2; upper++) { + /* Base 10 and base 16 */ + ut_assertok(run_strtoul(uts, str2, 10, 1099, 4, upper)); + ut_assertok(run_strtoul(uts, str2, 16, 0x1099ab, 6, upper)); - /* Invalid string */ - ut_assertok(run_strtoul(uts, str1, 10, 0, 0)); + /* Invalid string */ + ut_assertok(run_strtoul(uts, str1, 10, 0, 0, upper)); - /* Base 0 */ - ut_assertok(run_strtoul(uts, str1, 0, 0, 0)); - ut_assertok(run_strtoul(uts, str2, 0, 1099, 4)); - ut_assertok(run_strtoul(uts, str3, 0, 0xb, 3)); + /* Base 0 */ + ut_assertok(run_strtoul(uts, str1, 0, 0, 0, upper)); + ut_assertok(run_strtoul(uts, str2, 0, 1099, 4, upper)); + ut_assertok(run_strtoul(uts, str3, 0, 0xb, 3, upper)); - /* Base 2 */ - ut_assertok(run_strtoul(uts, str1, 2, 0, 0)); - ut_assertok(run_strtoul(uts, str2, 2, 2, 2)); + /* Base 2 */ + ut_assertok(run_strtoul(uts, str1, 2, 0, 0, upper)); + ut_assertok(run_strtoul(uts, str2, 2, 2, 2, upper)); + } /* Check endp being NULL */ ut_asserteq(1099, simple_strtoul(str2, NULL, 0));