<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/25345">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">utils: add osmo_str_to_int() and osmo_str_to_int64()<br><br>Properly converting a string to an integer while validating against all<br>possible errors is not trivial. It is a recurring theme in code review,<br>and there are places in osmo code that do it wrong.<br>End this by providing a simple API, if for nothing else then as an<br>example of how to use strol() / strtoul() / strtoll() / strtoull()<br>in an airtight way.<br><br>A subsequent patch, adding stat items to the CTRL interface, uses this<br>to properly validate indexes in CTRL variables and convert them to int.<br><br>Related: SYS#5542<br>Change-Id: I4dac826aab00bc1780a5258b6b55d34ce7d50c60<br>---<br>M include/osmocom/core/utils.h<br>M src/utils.c<br>M tests/utils/utils_test.c<br>M tests/utils/utils_test.ok<br>4 files changed, 391 insertions(+), 3 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/25345/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/utils.h b/include/osmocom/core/utils.h</span><br><span>index 1c60390..85a8cb3 100644</span><br><span>--- a/include/osmocom/core/utils.h</span><br><span>+++ b/include/osmocom/core/utils.h</span><br><span>@@ -283,6 +283,9 @@</span><br><span> int osmo_int_to_float_str_buf(char *buf, size_t buflen, int64_t val, unsigned int precision);</span><br><span> char *osmo_int_to_float_str_c(void *ctx, int64_t val, unsigned int precision);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_str_to_int64(int64_t *result, const char *str, int base, int64_t min_val, int64_t max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_str_to_int(int *result, const char *str, int base, int min_val, int max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Translate a buffer function to a talloc context function.</span><br><span>  * This is the full function body of a char *foo_name_c(void *ctx, val...) function, implemented by an</span><br><span>  * int foo_name_buf(buf, buflen, val...) function:</span><br><span>diff --git a/src/utils.c b/src/utils.c</span><br><span>index 721c34a..260c4c0 100644</span><br><span>--- a/src/utils.c</span><br><span>+++ b/src/utils.c</span><br><span>@@ -1405,4 +1405,78 @@</span><br><span>        OSMO_NAME_C_IMPL(ctx, 16, "ERROR", osmo_int_to_float_str_buf, val, precision)</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert a string of a number to int64_t, including all common strtoll() validity checks.</span><br><span style="color: hsl(120, 100%, 40%);">+ * It's not so trivial to call strtoll() and properly verify that the input string was indeed a valid number string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] result  The resulting integer number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] str  The string to convert.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] base  The integer base, i.e. 10 for decimal numbers or 16 for hexadecimal, as in strtoll().</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] min_val  The smallest valid number expected in the string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] max_val  The largest valid number expected in the string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, positive errno on conversion error, -E2BIG if surplus characters follow after the number string</span><br><span style="color: hsl(120, 100%, 40%);">+ * or -ERANGE if the converted number exceeds the range [min_val..max_val]. In case of -E2BIG and -ERANGE, the converted</span><br><span style="color: hsl(120, 100%, 40%);">+ * number is still returned in result.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_str_to_int64(int64_t *result, const char *str, int base, int64_t min_val, int64_t max_val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      long long int val;</span><br><span style="color: hsl(120, 100%, 40%);">+    char *endptr;</span><br><span style="color: hsl(120, 100%, 40%);">+ *result = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!str || !*str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+        errno = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    val = strtoll(str, &endptr, base);</span><br><span style="color: hsl(120, 100%, 40%);">+        /* In case the number string exceeds long long int range, strtoll() clamps the returned value to LLONG_MIN or</span><br><span style="color: hsl(120, 100%, 40%);">+  * LLONG_MAX. Make sure of the same here with respect to int64_t. */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (val < INT64_MIN) {</span><br><span style="color: hsl(120, 100%, 40%);">+             *result = INT64_MIN;</span><br><span style="color: hsl(120, 100%, 40%);">+          return ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (val > INT64_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+             *result = INT64_MAX;</span><br><span style="color: hsl(120, 100%, 40%);">+          return ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     *result = (int64_t)val;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (errno)</span><br><span style="color: hsl(120, 100%, 40%);">+            return errno;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!endptr || *endptr) {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* No chars were converted */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (endptr == str)</span><br><span style="color: hsl(120, 100%, 40%);">+                    return EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+                /* Or there are surplus chars after the converted number */</span><br><span style="color: hsl(120, 100%, 40%);">+           return -E2BIG;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (val < min_val || val > max_val)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert a string of a number to int, including all common strtoll() validity checks.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Same as osmo_str_to_int64() but using the plain int data type.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] result  The resulting integer number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] str  The string to convert.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] base  The integer base, i.e. 10 for decimal numbers or 16 for hexadecimal, as in strtoll().</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] min_val  The smallest valid number expected in the string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] max_val  The largest valid number expected in the string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, positive errno on conversion error, -E2BIG if surplus characters follow after the number string</span><br><span style="color: hsl(120, 100%, 40%);">+ * or -ERANGE if the converted number exceeds the range [min_val..max_val]. In case of -E2BIG and -ERANGE, the converted</span><br><span style="color: hsl(120, 100%, 40%);">+ * number does not exceed [INT_MIN..INT_MAX] and is still returned in result.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_str_to_int(int *result, const char *str, int base, int min_val, int max_val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  int64_t val;</span><br><span style="color: hsl(120, 100%, 40%);">+  int rc = osmo_str_to_int64(&val, str, base, min_val, max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* In case the number string exceeds long long int range, strtoll() clamps the returned value to LLONG_MIN or</span><br><span style="color: hsl(120, 100%, 40%);">+  * LLONG_MAX. Make sure of the same here with respect to int. */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (val < INT_MIN) {</span><br><span style="color: hsl(120, 100%, 40%);">+               *result = INT_MIN;</span><br><span style="color: hsl(120, 100%, 40%);">+            return ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (val > INT_MAX) {</span><br><span style="color: hsl(120, 100%, 40%);">+               *result = INT_MAX;</span><br><span style="color: hsl(120, 100%, 40%);">+            return ERANGE;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     *result = (int)val;</span><br><span style="color: hsl(120, 100%, 40%);">+   return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/tests/utils/utils_test.c b/tests/utils/utils_test.c</span><br><span>index 108bf5a..f8fb273 100644</span><br><span>--- a/tests/utils/utils_test.c</span><br><span>+++ b/tests/utils/utils_test.c</span><br><span>@@ -1694,11 +1694,20 @@</span><br><span> };</span><br><span> const char *errno_str(int rc)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- if (rc == -EINVAL)</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case -EINVAL:</span><br><span>                return "=-EINVAL";</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc == -ERANGE)</span><br><span style="color: hsl(120, 100%, 40%);">+    case -ERANGE:</span><br><span>                return "=-ERANGE";</span><br><span style="color: hsl(0, 100%, 40%);">-    return "";</span><br><span style="color: hsl(120, 100%, 40%);">+  case -E2BIG:</span><br><span style="color: hsl(120, 100%, 40%);">+          return "=-E2BIG";</span><br><span style="color: hsl(120, 100%, 40%);">+   case EINVAL:</span><br><span style="color: hsl(120, 100%, 40%);">+          return "=EINVAL";</span><br><span style="color: hsl(120, 100%, 40%);">+   case ERANGE:</span><br><span style="color: hsl(120, 100%, 40%);">+          return "=ERANGE";</span><br><span style="color: hsl(120, 100%, 40%);">+   default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return "";</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span> }</span><br><span> void test_float_str_to_int()</span><br><span> {</span><br><span>@@ -1884,6 +1893,188 @@</span><br><span>        }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct str_to_int_test {</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *str;</span><br><span style="color: hsl(120, 100%, 40%);">+      int base;</span><br><span style="color: hsl(120, 100%, 40%);">+     int min_val;</span><br><span style="color: hsl(120, 100%, 40%);">+  int max_val;</span><br><span style="color: hsl(120, 100%, 40%);">+  int expect_rc;</span><br><span style="color: hsl(120, 100%, 40%);">+        int expect_val;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+/* Avoid using INT_MAX and INT_MIN because that would produce different test output on different architectures */</span><br><span style="color: hsl(120, 100%, 40%);">+struct str_to_int_test str_to_int_tests[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { NULL, 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { " ", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "--", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "++", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0", 10, -1000, 1000, 0, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1", 10, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "+1", 10, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-1", 10, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "1000", 10, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+1000", 10, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-1000", 10, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1001", 10, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+1001", 10, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-1001", 10, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0", 16, -1000, 1000, 0, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0x1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "+1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-1", 16, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "+0x1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "-0x1", 16, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "0x3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "0x3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "+3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+0x3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "+0x3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "-3e8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-3E8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-0x3e8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-0x3E8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "+3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "-3e9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-3E9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    { "garble", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "-garble", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "0x123", 10, -1000, 1000, -E2BIG, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "123potatoes", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "123 ", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "123.4", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+void test_str_to_int()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct str_to_int_test *t;</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("--- %s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       for (t = str_to_int_tests; (t - str_to_int_tests) < ARRAY_SIZE(str_to_int_tests); t++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+               int val;</span><br><span style="color: hsl(120, 100%, 40%);">+              rc = osmo_str_to_int(&val, t->str, t->base, t->min_val, t->max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("osmo_str_to_int(%s, %d, %d, %d) -> rc=%d%s val=%d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rc != t->expect_rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("  ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc));</span><br><span style="color: hsl(120, 100%, 40%);">+         if (val != t->expect_val)</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("  ERROR: expected val=%d\n", t->expect_val);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct str_to_int64_test {</span><br><span style="color: hsl(120, 100%, 40%);">+    const char *str;</span><br><span style="color: hsl(120, 100%, 40%);">+      int base;</span><br><span style="color: hsl(120, 100%, 40%);">+     int64_t min_val;</span><br><span style="color: hsl(120, 100%, 40%);">+      int64_t max_val;</span><br><span style="color: hsl(120, 100%, 40%);">+      int expect_rc;</span><br><span style="color: hsl(120, 100%, 40%);">+        int64_t expect_val;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+struct str_to_int64_test str_to_int64_tests[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+    { NULL, 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { " ", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "--", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "++", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0", 10, -1000, 1000, 0, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1", 10, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "+1", 10, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-1", 10, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "1000", 10, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+1000", 10, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-1000", 10, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1001", 10, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+1001", 10, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-1001", 10, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0", 16, -1000, 1000, 0, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "0x1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "+1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-1", 16, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "+0x1", 16, -1000, 1000, 0, 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "-0x1", 16, -1000, 1000, 0, -1 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "0x3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "0x3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "+3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+0x3e8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "+0x3E8", 16, -1000, 1000, 0, 1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "-3e8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-3E8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-0x3e8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "-0x3E8", 16, -1000, 1000, 0, -1000 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "0x3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "0x3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "+3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "+0x3e9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "+0x3E9", 16, -1000, 1000, -ERANGE, 1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+       { "-3e9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-3E9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-0x3e9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { "-0x3E9", 16, -1000, 1000, -ERANGE, -1001 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    { "garble", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "-garble", 10, -1000, 1000, EINVAL, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { "0x123", 10, -1000, 1000, -E2BIG, 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "123potatoes", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "123 potatoes", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "123 ", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+   { "123.4", 10, -1000, 1000, -E2BIG, 123 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-9223372036854775808", 10, INT64_MIN, INT64_MAX, 0, INT64_MIN },</span><br><span style="color: hsl(120, 100%, 40%);">+ { "9223372036854775807", 10, INT64_MIN, INT64_MAX, 0, INT64_MAX },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        { "-9223372036854775809", 10, INT64_MIN, INT64_MAX, ERANGE, INT64_MIN },</span><br><span style="color: hsl(120, 100%, 40%);">+    { "9223372036854775808", 10, INT64_MIN, INT64_MAX, ERANGE, INT64_MAX },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   { "-9223372036854775809", 10, -1000, 1000, ERANGE, INT64_MIN },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "9223372036854775808", 10, -1000, 1000, ERANGE, INT64_MAX },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+void test_str_to_int64()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct str_to_int64_test *t;</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("--- %s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       for (t = str_to_int64_tests; (t - str_to_int64_tests) < ARRAY_SIZE(str_to_int64_tests); t++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+               int64_t val;</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = osmo_str_to_int64(&val, t->str, t->base, t->min_val, t->max_val);</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("osmo_str_to_int64(%s, %d, %"PRId64", %"PRId64") -> rc=%d%s val=%"PRId64"\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                      osmo_quote_str(t->str, -1), t->base, t->min_val, t->max_val, rc, errno_str(rc), val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rc != t->expect_rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("  ERROR: expected rc=%d%s\n", t->expect_rc, errno_str(t->expect_rc));</span><br><span style="color: hsl(120, 100%, 40%);">+         if (val != t->expect_val)</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("  ERROR: expected val=%"PRId64"\n", t->expect_val);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span>       static const struct log_info log_info = {};</span><br><span>@@ -1911,5 +2102,7 @@</span><br><span>  osmo_strnchr_test();</span><br><span>         test_float_str_to_int();</span><br><span>     test_int_to_float_str();</span><br><span style="color: hsl(120, 100%, 40%);">+      test_str_to_int();</span><br><span style="color: hsl(120, 100%, 40%);">+    test_str_to_int64();</span><br><span>         return 0;</span><br><span> }</span><br><span>diff --git a/tests/utils/utils_test.ok b/tests/utils/utils_test.ok</span><br><span>index 0c71b8f..8bc2357 100644</span><br><span>--- a/tests/utils/utils_test.ok</span><br><span>+++ b/tests/utils/utils_test.ok</span><br><span>@@ -869,3 +869,121 @@</span><br><span> osmo_int_to_float_str_buf(9223372036854775807, 23) -> rc=25 str="0.00009223372036854775807"</span><br><span> osmo_int_to_float_str_buf(-9223372036854775807, 23) -> rc=26 str="-0.00009223372036854775807"</span><br><span> osmo_int_to_float_str_buf(-9223372036854775808, 23) -> rc=4 str="-ERR"</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_str_to_int</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int(NULL, 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int(" ", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("--", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("++", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0", 10, -1000, 1000) -> rc=0 val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("1", 10, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+1", 10, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-1", 10, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("1000", 10, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+1000", 10, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-1000", 10, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0", 16, -1000, 1000) -> rc=0 val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-1", 16, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+0x1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-0x1", 16, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-3e8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-3E8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("garble", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("-garble", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_str_to_int64</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64(NULL, 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64(" ", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("--", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("++", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0", 10, -1000, 1000) -> rc=0 val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("1", 10, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+1", 10, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-1", 10, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("1000", 10, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+1000", 10, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-1000", 10, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-1001", 10, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0", 16, -1000, 1000) -> rc=0 val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-1", 16, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+0x1", 16, -1000, 1000) -> rc=0 val=1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-0x1", 16, -1000, 1000) -> rc=0 val=-1</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+0x3e8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+0x3E8", 16, -1000, 1000) -> rc=0 val=1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-3e8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-3E8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-0x3e8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-0x3E8", 16, -1000, 1000) -> rc=0 val=-1000</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("+0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-0x3e9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-0x3E9", 16, -1000, 1000) -> rc=-34=-ERANGE val=-1001</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("garble", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-garble", 10, -1000, 1000) -> rc=22=EINVAL val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("0x123", 10, -1000, 1000) -> rc=-7=-E2BIG val=0</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("123potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("123 potatoes", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("123 ", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("123.4", 10, -1000, 1000) -> rc=-7=-E2BIG val=123</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=-9223372036854775808</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("9223372036854775807", 10, -9223372036854775808, 9223372036854775807) -> rc=0 val=9223372036854775807</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-9223372036854775809", 10, -9223372036854775808, 9223372036854775807) -> rc=34=ERANGE val=-9223372036854775808</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("9223372036854775808", 10, -9223372036854775808, 9223372036854775807) -> rc=34=ERANGE val=9223372036854775807</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("-9223372036854775809", 10, -1000, 1000) -> rc=34=ERANGE val=-9223372036854775808</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_str_to_int64("9223372036854775808", 10, -1000, 1000) -> rc=34=ERANGE val=9223372036854775807</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/25345">change 25345</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/25345"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I4dac826aab00bc1780a5258b6b55d34ce7d50c60 </div>
<div style="display:none"> Gerrit-Change-Number: 25345 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>