From 5aa15d10e950aaed3453027853c0908934d520c1 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 14 May 2021 10:20:09 +1000 Subject: [PATCH] spa: add a new string helper with spa_strtol() Most of the time when we convert a string to an integer we only care about success. Let's wrap this with a helper function that sets the value to the result and returns true on success. --- spa/include/spa/utils/string.h | 67 ++++++++++++++++++++++++++++++++++ spa/tests/test-utils.c | 49 +++++++++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 spa/include/spa/utils/string.h diff --git a/spa/include/spa/utils/string.h b/spa/include/spa/utils/string.h new file mode 100644 index 000000000..eddffe948 --- /dev/null +++ b/spa/include/spa/utils/string.h @@ -0,0 +1,67 @@ +/* Simple Plugin API + * + * Copyright © 2021 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef SPA_UTILS_STRING_H +#define SPA_UTILS_STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * Convert \a str to an int32_t with the given \a base and store the + * result in \a val. + * + * On failure, the value of \a val is undefined. + * + * \return true on success, false otherwise + */ +static inline bool spa_atoi32(const char *str, int32_t *val, int base) +{ + char *endptr; + long v; + + if (!str || *str =='\0') + return false; + + errno = 0; + v = strtol(str, &endptr, base); + if (errno != 0 || *endptr != '\0') + return false; + + if (v != (int32_t)v) + return false; + + *val = v; + return true; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SPA_UTILS_STRING_H */ diff --git a/spa/tests/test-utils.c b/spa/tests/test-utils.c index 726e1209e..fdf75e678 100644 --- a/spa/tests/test-utils.c +++ b/spa/tests/test-utils.c @@ -28,6 +28,7 @@ #include #include #include +#include #include static void test_abi(void) @@ -429,6 +430,53 @@ static void test_ringbuffer(void) spa_assert(!memcmp(buffer, " !!!o pipewire rocks", 20)); } +static void test_strtol(void) +{ + int32_t v; + + spa_assert(spa_atoi32("0", &v, 0) && v == 0); + spa_assert(spa_atoi32("0", &v, 16) && v == 0); + spa_assert(spa_atoi32("0", &v, 32) && v == 0); + spa_assert(spa_atoi32("-1", &v, 0) && v == -1); + spa_assert(spa_atoi32("-1234", &v, 0) && v == -1234); + spa_assert(spa_atoi32("-2147483648", &v, 0) && v == -2147483648); + spa_assert(spa_atoi32("+1", &v, 0) && v == 1); + spa_assert(spa_atoi32("+1234", &v, 0) && v == 1234); + spa_assert(spa_atoi32("+2147483647", &v, 0) && v == 2147483647); + spa_assert(spa_atoi32("65535", &v, 0) && v == 0xffff); + spa_assert(spa_atoi32("65535", &v, 10) && v == 0xffff); + spa_assert(spa_atoi32("65535", &v, 16) && v == 0x65535); + spa_assert(spa_atoi32("0xff", &v, 0) && v == 0xff); + spa_assert(spa_atoi32("0xff", &v, 16) && v == 0xff); + + v = 0xabcd; + spa_assert(!spa_atoi32("0xff", &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32("fabc", &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32("fabc", &v, 0) && v == 0xabcd); + + spa_assert(!spa_atoi32("124bogus", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("124bogus", &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32("124bogus", &v, 16) && v == 0xabcd); + spa_assert(!spa_atoi32("0xbogus", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("bogus", &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32("bogus", &v, 16) && v == 0xabcd); + spa_assert(!spa_atoi32("", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("", &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32("", &v, 16) && v == 0xabcd); + spa_assert(!spa_atoi32(" ", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32(" ", &v, 0) && v == 0xabcd); + + spa_assert(!spa_atoi32("-2147483649", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("2147483648", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("9223372036854775807", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("-9223372036854775808", &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32("9223372036854775808999", &v, 0) && v == 0xabcd); + + spa_assert(!spa_atoi32(NULL, &v, 0) && v == 0xabcd); + spa_assert(!spa_atoi32(NULL, &v, 10) && v == 0xabcd); + spa_assert(!spa_atoi32(NULL, &v, 16) && v == 0xabcd); +} + int main(int argc, char *argv[]) { test_abi(); @@ -438,5 +486,6 @@ int main(int argc, char *argv[]) test_list(); test_hook(); test_ringbuffer(); + test_strtol(); return 0; }