]> sigrok.org Git - libsigrok.git/blobdiff - src/strutil.c
strutil: accept trailing whitespace after number text
[libsigrok.git] / src / strutil.c
index 5f0deb7708f374327b6c5d33e7649ca3da342948..5344ec2903218bef4c7e9baabd3412d10b7929e5 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <config.h>
+#include <ctype.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -67,6 +68,9 @@ SR_PRIV int sr_atol(const char *str, long *ret)
        errno = 0;
        tmp = strtol(str, &endptr, 10);
 
+       while (endptr && isspace(*endptr))
+               endptr++;
+
        if (!endptr || *endptr || errno) {
                if (!errno)
                        errno = EINVAL;
@@ -129,6 +133,9 @@ SR_PRIV int sr_atod(const char *str, double *ret)
        errno = 0;
        tmp = strtof(str, &endptr);
 
+       while (endptr && isspace(*endptr))
+               endptr++;
+
        if (!endptr || *endptr || errno) {
                if (!errno)
                        errno = EINVAL;
@@ -169,6 +176,38 @@ SR_PRIV int sr_atof(const char *str, float *ret)
        return SR_OK;
 }
 
+/**
+ * @private
+ *
+ * Convert a string representation of a numeric value to a double. The
+ * conversion is strict and will fail if the complete string does not represent
+ * a valid double. The function sets errno according to the details of the
+ * failure. This version ignores the locale.
+ *
+ * @param str The string representation to convert.
+ * @param ret Pointer to double where the result of the conversion will be stored.
+ *
+ * @retval SR_OK Conversion successful.
+ * @retval SR_ERR Failure.
+ */
+SR_PRIV int sr_atod_ascii(const char *str, double *ret)
+{
+       double tmp;
+       char *endptr = NULL;
+
+       errno = 0;
+       tmp = g_ascii_strtod(str, &endptr);
+
+       if (!endptr || *endptr || errno) {
+               if (!errno)
+                       errno = EINVAL;
+               return SR_ERR;
+       }
+
+       *ret = tmp;
+       return SR_OK;
+}
+
 /**
  * @private
  *
@@ -445,7 +484,8 @@ SR_API char *sr_voltage_string(uint64_t v_p, uint64_t v_q)
  */
 SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size)
 {
-       int multiplier, done;
+       uint64_t multiplier;
+       int done;
        double frac_part;
        char *s;
 
@@ -472,6 +512,18 @@ SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size)
                case 'G':
                        multiplier = SR_GHZ(1);
                        break;
+               case 't':
+               case 'T':
+                       multiplier = SR_GHZ(1000);
+                       break;
+               case 'p':
+               case 'P':
+                       multiplier = SR_GHZ(1000 * 1000);
+                       break;
+               case 'e':
+               case 'E':
+                       multiplier = SR_GHZ(1000 * 1000 * 1000);
+                       break;
                default:
                        done = TRUE;
                        s--;
@@ -481,8 +533,9 @@ SR_API int sr_parse_sizestring(const char *sizestring, uint64_t *size)
        if (multiplier > 0) {
                *size *= multiplier;
                *size += frac_part * multiplier;
-       } else
+       } else {
                *size += frac_part;
+       }
 
        if (s && *s && g_ascii_strcasecmp(s, "Hz"))
                return SR_ERR;