This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
neels gerrit-no-reply at lists.osmocom.orgneels has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/25345 ) Change subject: utils: add osmo_str_to_int() and osmo_str_to_int64() ...................................................................... utils: add osmo_str_to_int() and osmo_str_to_int64() Properly converting a string to an integer while validating against all possible errors is not trivial. It is a recurring theme in code review, and there are places in osmo code that do it wrong. End this by providing a simple API, if for nothing else then as an example of how to use strol() / strtoul() / strtoll() / strtoull() in an airtight way. A subsequent patch, adding stat items to the CTRL interface, uses this to properly validate indexes in CTRL variables and convert them to int. Related: SYS#5542 Change-Id: I4dac826aab00bc1780a5258b6b55d34ce7d50c60 --- M include/osmocom/core/utils.h M src/utils.c M tests/utils/utils_test.c M tests/utils/utils_test.ok 4 files changed, 413 insertions(+), 3 deletions(-) Approvals: dexter: Looks good to me, but someone else must approve neels: Looks good to me, approved; Verified laforge: Looks good to me, but someone else must approve diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h index 1c60390..85a8cb3 100644 --- a/include/osmocom/core/utils.h +++ b/include/osmocom/core/utils.h @@ -283,6 +283,9 @@ int osmo_int_to_float_str_buf(char *buf, size_t buflen, int64_t val, unsigned int precision); char *osmo_int_to_float_str_c(void *ctx, int64_t val, unsigned int precision); +int osmo_str_to_int64(int64_t *result, const char *str, int base, int64_t min_val, int64_t max_val); +int osmo_str_to_int(int *result, const char *str, int base, int min_val, int max_val); + /*! Translate a buffer function to a talloc context function. * This is the full function body of a char *foo_name_c(void *ctx, val...) function, implemented by an * int foo_name_buf(buf, buflen, val...) function: diff --git a/src/utils.c b/src/utils.c index 721c34a..2b21dcc 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1405,4 +1405,98 @@ OSMO_NAME_C_IMPL(ctx, 16, "ERROR", osmo_int_to_float_str_buf, val, precision) } +/*! Convert a string of a number to int64_t, including all common strtoll() validity checks. + * It's not so trivial to call strtoll() and properly verify that the input string was indeed a valid number string. + * \param[out] result Buffer for the resulting integer number, or NULL if the caller is only interested in the + * validation result (returned rc). + * \param[in] str The string to convert. + * \param[in] base The integer base, i.e. 10 for decimal numbers or 16 for hexadecimal, as in strtoll(). + * \param[in] min_val The smallest valid number expected in the string. + * \param[in] max_val The largest valid number expected in the string. + * \return 0 on success, -EOVERFLOW if the number in the string exceeds int64_t, -ENOTSUPP if the base is not supported, + * -ERANGE if the converted number exceeds the range [min_val..max_val] but is still within int64_t range, -E2BIG if + * surplus characters follow after the number, -EINVAL if the string does not contain a number. In case of -ERANGE and + * -E2BIG, the converted number is still accurately returned in result. In case of -EOVERFLOW, the returned value is + * clamped to INT64_MIN..INT64_MAX. + */ +int osmo_str_to_int64(int64_t *result, const char *str, int base, int64_t min_val, int64_t max_val) +{ + long long int val; + char *endptr; + if (result) + *result = 0; + if (!str || !*str) + return -EINVAL; + errno = 0; + val = strtoll(str, &endptr, base); + /* In case the number string exceeds long long int range, strtoll() clamps the returned value to LLONG_MIN or + * LLONG_MAX. Make sure of the same here with respect to int64_t. */ + if (val < INT64_MIN) { + if (result) + *result = INT64_MIN; + return -ERANGE; + } + if (val > INT64_MAX) { + if (result) + *result = INT64_MAX; + return -ERANGE; + } + if (result) + *result = (int64_t)val; + switch (errno) { + case 0: + break; + case ERANGE: + return -EOVERFLOW; + default: + case EINVAL: + return -ENOTSUP; + } + if (!endptr || *endptr) { + /* No chars were converted */ + if (endptr == str) + return -EINVAL; + /* Or there are surplus chars after the converted number */ + return -E2BIG; + } + if (val < min_val || val > max_val) + return -ERANGE; + return 0; +} + +/*! Convert a string of a number to int, including all common strtoll() validity checks. + * Same as osmo_str_to_int64() but using the plain int data type. + * \param[out] result Buffer for the resulting integer number, or NULL if the caller is only interested in the + * validation result (returned rc). + * \param[in] str The string to convert. + * \param[in] base The integer base, i.e. 10 for decimal numbers or 16 for hexadecimal, as in strtoll(). + * \param[in] min_val The smallest valid number expected in the string. + * \param[in] max_val The largest valid number expected in the string. + * \return 0 on success, -EOVERFLOW if the number in the string exceeds int range, -ENOTSUPP if the base is not supported, + * -ERANGE if the converted number exceeds the range [min_val..max_val] but is still within int range, -E2BIG if + * surplus characters follow after the number, -EINVAL if the string does not contain a number. In case of -ERANGE and + * -E2BIG, the converted number is still accurately returned in result. In case of -EOVERFLOW, the returned value is + * clamped to INT_MIN..INT_MAX. + */ +int osmo_str_to_int(int *result, const char *str, int base, int min_val, int max_val) +{ + int64_t val; + int rc = osmo_str_to_int64(&val, str, base, min_val, max_val); + /* In case the number string exceeds long long int range, strtoll() clamps the returned value to LLONG_MIN or + * LLONG_MAX. Make sure of the same here with respect to int. */ + if (val < INT_MIN) { + if (result) + *result = INT_MIN; + return -EOVERFLOW; + } + if (val > INT_MAX) { + if (result) + *result = INT_MAX; + return -EOVERFLOW; + } + if (result) + *result = (int)val; + return rc; +} + /*! @} */ diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c index 108bf5a..7e0e3d3 100644 --- a/tests/utils/utils_test.c +++ b/tests/utils/utils_test.c @@ -1694,11 +1694,18 @@ }; const char *errno_str(int rc) { - if (rc == -EINVAL) + switch (rc) { + case -EINVAL: return "=-EINVAL"; - if (rc == -ERANGE) + case -ERANGE: return "=-ERANGE"; - return ""; + case -E2BIG: + return "=-E2BIG"; + case -EOVERFLOW: + return "=-EOVERFLOW"; + default: + return ""; + } } void test_float_str_to_int() { @@ -1884,6 +1891,190 @@ } } +struct str_to_int_test { + const char *str; + int base; + int min_val; + int max_val; + int expect_rc; + int expect_val; +}; +/* Avoid using INT_MAX and INT_MIN because that would produce different test output on different architectures */ +struct str_to_int_test str_to_int_tests[] = { + { NULL, 10, -1000, 1000, -EINVAL, 0 }, + { "", 10, -1000, 1000, -EINVAL, 0 }, + { " ", 10, -1000, 1000, -EINVAL, 0 }, + { "-", 10, -1000, 1000, -EINVAL, 0 }, + { "--", 10, -1000, 1000, -EINVAL, 0 }, + { "+", 10, -1000, 1000, -EINVAL, 0 }, + { "++", 10, -1000, 1000, -EINVAL, 0 }, + + { "0", 10, -1000, 1000, 0, 0 }, + { "1", 10, -1000, 1000, 0, 1 }, + { "+1", 10, -1000, 1000, 0, 1 }, + { "-1", 10, -1000, 1000, 0, -1 }, + { "1000", 10, -1000, 1000, 0, 1000 }, + { "+1000", 10, -1000, 1000, 0, 1000 }, + { "-1000", 10, -1000, 1000, 0, -1000 }, + { "1001", 10, -1000, 1000, -ERANGE, 1001 }, + { "+1001", 10, -1000, 1000, -ERANGE, 1001 }, + { "-1001", 10, -1000, 1000, -ERANGE, -1001 }, + + { "0", 16, -1000, 1000, 0, 0 }, + { "1", 16, -1000, 1000, 0, 1 }, + { "0x1", 16, -1000, 1000, 0, 1 }, + { "+1", 16, -1000, 1000, 0, 1 }, + { "-1", 16, -1000, 1000, 0, -1 }, + { "+0x1", 16, -1000, 1000, 0, 1 }, + { "-0x1", 16, -1000, 1000, 0, -1 }, + { "3e8", 16, -1000, 1000, 0, 1000 }, + { "3E8", 16, -1000, 1000, 0, 1000 }, + { "0x3e8", 16, -1000, 1000, 0, 1000 }, + { "0x3E8", 16, -1000, 1000, 0, 1000 }, + { "+3e8", 16, -1000, 1000, 0, 1000 }, + { "+3E8", 16, -1000, 1000, 0, 1000 }, + { "+0x3e8", 16, -1000, 1000, 0, 1000 }, + { "+0x3E8", 16, -1000, 1000, 0, 1000 }, + { "-3e8", 16, -1000, 1000, 0, -1000 }, + { "-3E8", 16, -1000, 1000, 0, -1000 }, + { "-0x3e8", 16, -1000, 1000, 0, -1000 }, + { "-0x3E8", 16, -1000, 1000, 0, -1000 }, + { "3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "-3e9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-3E9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 }, + + { "garble", 10, -1000, 1000, -EINVAL, 0 }, + { "-garble", 10, -1000, 1000, -EINVAL, 0 }, + { "0x123", 10, -1000, 1000, -E2BIG, 0 }, + { "123potatoes", 10, -1000, 1000, -E2BIG, 123 }, + { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 }, + { "123 ", 10, -1000, 1000, -E2BIG, 123 }, + { "123.4", 10, -1000, 1000, -E2BIG, 123 }, +}; +void test_str_to_int() +{ + const struct str_to_int_test *t; + printf("--- %s\n", __func__); + for (t = str_to_int_tests; (t - str_to_int_tests) < ARRAY_SIZE(str_to_int_tests); t++) { + int rc; + int val; + rc = osmo_str_to_int(&val, t->str, t->base, t->min_val, t->max_val); + printf("osmo_str_to_int(%s, %d, %d, %d) -> rc=%d%s val=%d\n", + osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val); + + if (rc != t->expect_rc) + printf(" ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc)); + if (val != t->expect_val) + printf(" ERROR: expected val=%d\n", t->expect_val); + } +} + +struct str_to_int64_test { + const char *str; + int base; + int64_t min_val; + int64_t max_val; + int expect_rc; + int64_t expect_val; +}; +struct str_to_int64_test str_to_int64_tests[] = { + { NULL, 10, -1000, 1000, -EINVAL, 0 }, + { "", 10, -1000, 1000, -EINVAL, 0 }, + { " ", 10, -1000, 1000, -EINVAL, 0 }, + { "-", 10, -1000, 1000, -EINVAL, 0 }, + { "--", 10, -1000, 1000, -EINVAL, 0 }, + { "+", 10, -1000, 1000, -EINVAL, 0 }, + { "++", 10, -1000, 1000, -EINVAL, 0 }, + + { "0", 10, -1000, 1000, 0, 0 }, + { "1", 10, -1000, 1000, 0, 1 }, + { "+1", 10, -1000, 1000, 0, 1 }, + { "-1", 10, -1000, 1000, 0, -1 }, + { "1000", 10, -1000, 1000, 0, 1000 }, + { "+1000", 10, -1000, 1000, 0, 1000 }, + { "-1000", 10, -1000, 1000, 0, -1000 }, + { "1001", 10, -1000, 1000, -ERANGE, 1001 }, + { "+1001", 10, -1000, 1000, -ERANGE, 1001 }, + { "-1001", 10, -1000, 1000, -ERANGE, -1001 }, + + { "0", 16, -1000, 1000, 0, 0 }, + { "1", 16, -1000, 1000, 0, 1 }, + { "0x1", 16, -1000, 1000, 0, 1 }, + { "+1", 16, -1000, 1000, 0, 1 }, + { "-1", 16, -1000, 1000, 0, -1 }, + { "+0x1", 16, -1000, 1000, 0, 1 }, + { "-0x1", 16, -1000, 1000, 0, -1 }, + { "3e8", 16, -1000, 1000, 0, 1000 }, + { "3E8", 16, -1000, 1000, 0, 1000 }, + { "0x3e8", 16, -1000, 1000, 0, 1000 }, + { "0x3E8", 16, -1000, 1000, 0, 1000 }, + { "+3e8", 16, -1000, 1000, 0, 1000 }, + { "+3E8", 16, -1000, 1000, 0, 1000 }, + { "+0x3e8", 16, -1000, 1000, 0, 1000 }, + { "+0x3E8", 16, -1000, 1000, 0, 1000 }, + { "-3e8", 16, -1000, 1000, 0, -1000 }, + { "-3E8", 16, -1000, 1000, 0, -1000 }, + { "-0x3e8", 16, -1000, 1000, 0, -1000 }, + { "-0x3E8", 16, -1000, 1000, 0, -1000 }, + { "3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 }, + { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 }, + { "-3e9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-3E9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 }, + { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 }, + + { "garble", 10, -1000, 1000, -EINVAL, 0 }, + { "-garble", 10, -1000, 1000, -EINVAL, 0 }, + { "0x123", 10, -1000, 1000, -E2BIG, 0 }, + { "123potatoes", 10, -1000, 1000, -E2BIG, 123 }, + { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 }, + { "123 ", 10, -1000, 1000, -E2BIG, 123 }, + { "123.4", 10, -1000, 1000, -E2BIG, 123 }, + + { "-9223372036854775808", 10, INT64_MIN, INT64_MAX, 0, INT64_MIN }, + { "9223372036854775807", 10, INT64_MIN, INT64_MAX, 0, INT64_MAX }, + + { "-9223372036854775809", 10, INT64_MIN, INT64_MAX, -EOVERFLOW, INT64_MIN }, + { "9223372036854775808", 10, INT64_MIN, INT64_MAX, -EOVERFLOW, INT64_MAX }, + + { "-9223372036854775808", 10, -1000, 1000, -ERANGE, INT64_MIN }, + { "9223372036854775807", 10, -1000, 1000, -ERANGE, INT64_MAX }, + { "-9223372036854775809", 10, -1000, 1000, -EOVERFLOW, INT64_MIN }, + { "9223372036854775808", 10, -1000, 1000, -EOVERFLOW, INT64_MAX }, +}; +void test_str_to_int64() +{ + const struct str_to_int64_test *t; + printf("--- %s\n", __func__); + for (t = str_to_int64_tests; (t - str_to_int64_tests) < ARRAY_SIZE(str_to_int64_tests); t++) { + int rc; + int64_t val; + rc = osmo_str_to_int64(&val, t->str, t->base, t->min_val, t->max_val); + printf("osmo_str_to_int64(%s, %d, %"PRId64", %"PRId64") -> rc=%d%s val=%"PRId64"\n", + osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val); + + if (rc != t->expect_rc) + printf(" ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc)); + if (val != t->expect_val) + printf(" ERROR: expected val=%"PRId64"\n", t->expect_val); + } +} + int main(int argc, char **argv) { static const struct log_info log_info = {}; @@ -1911,5 +2102,7 @@ osmo_strnchr_test(); test_float_str_to_int(); test_int_to_float_str(); + test_str_to_int(); + test_str_to_int64(); return 0; } diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok index 0c71b8f..1409d81 100644 --- a/tests/utils/utils_test.ok +++ b/tests/utils/utils_test.ok @@ -869,3 +869,123 @@ osmo_int_to_float_str_buf(9223372036854775807, 23) -> rc=25 str="0.00009223372036854775807" osmo_int_to_float_str_buf(-9223372036854775807, 23) -> rc=26 str="-0.00009223372036854775807" osmo_int_to_float_str_buf(-9223372036854775808, 23) -> rc=4 str="-ERR" +--- test_str_to_int +osmo_str_to_int(NULL, 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int(" ", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("-", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("--", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("+", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("++", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("0", 10, -1000, 1000) -> rc=0 val=0 +osmo_str_to_int("1", 10, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("+1", 10, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("-1", 10, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int("1000", 10, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("+1000", 10, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("-1000", 10, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int("0", 16, -1000, 1000) -> rc=0 val=0 +osmo_str_to_int("1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("0x1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("+1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("-1", 16, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int("+0x1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int("-0x1", 16, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int("3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("0x3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("0x3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("+3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("+3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int("-3e8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int("-3E8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int("garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("-garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0 +osmo_str_to_int("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +--- test_str_to_int64 +osmo_str_to_int64(NULL, 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64(" ", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("-", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("--", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("+", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("++", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("0", 10, -1000, 1000) -> rc=0 val=0 +osmo_str_to_int64("1", 10, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("+1", 10, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("-1", 10, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int64("1000", 10, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("+1000", 10, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("-1000", 10, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int64("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int64("0", 16, -1000, 1000) -> rc=0 val=0 +osmo_str_to_int64("1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("0x1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("+1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("-1", 16, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int64("+0x1", 16, -1000, 1000) -> rc=0 val=1 +osmo_str_to_int64("-0x1", 16, -1000, 1000) -> rc=0 val=-1 +osmo_str_to_int64("3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("0x3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("0x3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("+3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("+3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000 +osmo_str_to_int64("-3e8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int64("-3E8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int64("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int64("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000 +osmo_str_to_int64("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001 +osmo_str_to_int64("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int64("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int64("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int64("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001 +osmo_str_to_int64("garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("-garble", 10, -1000, 1000) -> rc=-22=-EINVAL val=0 +osmo_str_to_int64("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0 +osmo_str_to_int64("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int64("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int64("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int64("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123 +osmo_str_to_int64("-9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=-9223372036854775808 +osmo_str_to_int64("9223372036854775807", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=9223372036854775807 +osmo_str_to_int64("-9223372036854775809", 10, -9223372036854775808, 9223372036854775807) -> rc=-75=-EOVERFLOW val=-9223372036854775808 +osmo_str_to_int64("9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=-75=-EOVERFLOW val=9223372036854775807 +osmo_str_to_int64("-9223372036854775808", 10, -1000, 1000) -> rc=-34=-ERANGE val=-9223372036854775808 +osmo_str_to_int64("9223372036854775807", 10, -1000, 1000) -> rc=-34=-ERANGE val=9223372036854775807 +osmo_str_to_int64("-9223372036854775809", 10, -1000, 1000) -> rc=-75=-EOVERFLOW val=-9223372036854775808 +osmo_str_to_int64("9223372036854775808", 10, -1000, 1000) -> rc=-75=-EOVERFLOW val=9223372036854775807 -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/25345 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I4dac826aab00bc1780a5258b6b55d34ce7d50c60 Gerrit-Change-Number: 25345 Gerrit-PatchSet: 4 Gerrit-Owner: neels <nhofmeyr at sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: dexter <pmaier at sysmocom.de> Gerrit-Reviewer: laforge <laforge at osmocom.org> Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de> Gerrit-Reviewer: pespin <pespin at sysmocom.de> Gerrit-CC: osmith <osmith at sysmocom.de> Gerrit-MessageType: merged -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210914/a773156a/attachment.htm>