]> sigrok.org Git - libsigrok.git/commitdiff
strutil: introduce sr_atol_base() conversion helper (non-decimal)
authorGerhard Sittig <redacted>
Sun, 3 May 2020 14:38:13 +0000 (16:38 +0200)
committerGerhard Sittig <redacted>
Fri, 29 May 2020 04:12:50 +0000 (06:12 +0200)
Introduce a text to number conversion routine which is more general than
sr_atol() is. It accepts non-decimal numbers, with optional caller given
or automatic base, including 0b for binary. It is not as strict and can
return the position after the number, so that callers can optionally
support suffix notations (units, or scale factors, or multiple separated
numbers in the same text string).

src/libsigrok-internal.h
src/strutil.c

index 8925cbffbf78eb855d835354c66a7cca297862ad..5b20e54b7e5a3fc6a6d53fe262f799f240639bcc 100644 (file)
@@ -1501,6 +1501,7 @@ SR_PRIV void *sr_resource_load(struct sr_context *ctx, int type,
 /*--- strutil.c -------------------------------------------------------------*/
 
 SR_PRIV int sr_atol(const char *str, long *ret);
+SR_PRIV int sr_atol_base(const char *str, long *ret, char **end, int base);
 SR_PRIV int sr_atoi(const char *str, int *ret);
 SR_PRIV int sr_atod(const char *str, double *ret);
 SR_PRIV int sr_atof(const char *str, float *ret);
index 5ee680e50b1118fab817c07af542c0e03ddc2367..0dff3c4b48c0bf8df4014f73bddde9dd279644c3 100644 (file)
@@ -91,6 +91,60 @@ SR_PRIV int sr_atol(const char *str, long *ret)
        return SR_OK;
 }
 
+/**
+ * Convert a text to a number including support for non-decimal bases.
+ * Also optionally returns the position after the number, where callers
+ * can either error out, or support application specific suffixes.
+ *
+ * @param[in] str The input text to convert.
+ * @param[out] ret The conversion result.
+ * @param[out] end The position after the number.
+ * @param[in] base The number format's base, can be 0.
+ *
+ * @retval SR_OK Conversion successful.
+ * @retval SR_ERR Conversion failed.
+ *
+ * @private
+ *
+ * This routine is more general than @ref sr_atol(), which strictly
+ * expects the input text to contain just a decimal number, and nothing
+ * else in addition. The @ref sr_atol_base() routine accepts trailing
+ * text after the number, and supports non-decimal numbers (bin, hex),
+ * including automatic detection from prefix text.
+ */
+SR_PRIV int sr_atol_base(const char *str, long *ret, char **end, int base)
+{
+       long num;
+       char *endptr;
+
+       /* Add "0b" prefix support which strtol(3) may be missing. */
+       while (str && isspace(*str))
+               str++;
+       if (!base && strncmp(str, "0b", strlen("0b")) == 0) {
+               str += strlen("0b");
+               base = 2;
+       }
+
+       /* Run the number conversion. Quick bail out if that fails. */
+       errno = 0;
+       endptr = NULL;
+       num = strtol(str, &endptr, base);
+       if (!endptr || errno) {
+               if (!errno)
+                       errno = EINVAL;
+               return SR_ERR;
+       }
+       *ret = num;
+
+       /* Advance to optional non-space trailing suffix. */
+       while (endptr && isspace(*endptr))
+               endptr++;
+       if (end)
+               *end = endptr;
+
+       return SR_OK;
+}
+
 /**
  * Convert a string representation of a numeric value (base 10) to an integer. The
  * conversion is strict and will fail if the complete string does not represent