From: poljar (Damir Jelić) Date: Thu, 16 Jan 2014 14:28:48 +0000 (+0100) Subject: strutil: Add function to parse floating point numbers while ignoring the locale. X-Git-Tag: libsigrok-0.3.0~274 X-Git-Url: http://sigrok.org/gitweb/?a=commitdiff_plain;h=9806c2d573a3fde4c26a38eaab265c7a78962e94;p=libsigrok.git strutil: Add function to parse floating point numbers while ignoring the locale. Most of the supported gear uses the ANSI C locale for communication, and if the client sets up an incompatible locale parsing would fail. This function ignores the client's locale and parses floating point numbers using the ANSI C locale. This function should be always used when parsing floating point numbers coming from the instrument. --- diff --git a/libsigrok-internal.h b/libsigrok-internal.h index ba00d9e4..df9bc0aa 100644 --- a/libsigrok-internal.h +++ b/libsigrok-internal.h @@ -273,6 +273,7 @@ SR_PRIV int sr_atol(const char *str, long *ret); 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); +SR_PRIV int sr_atof_ascii(const char *str, float *ret); /*--- hardware/common/serial.c ----------------------------------------------*/ diff --git a/strutil.c b/strutil.c index f4e48259..0438c5ec 100644 --- a/strutil.c +++ b/strutil.c @@ -169,6 +169,49 @@ SR_PRIV int sr_atof(const char *str, float *ret) return SR_OK; } +/** + * @private + * + * Convert a string representation of a numeric value to a float. The + * conversion is strict and will fail if the complete string does not represent + * a valid float. 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 float where the result of the conversion will be stored. + * + * @return SR_OK if conversion is successful, otherwise SR_ERR. + * + * @since 0.3.0 + */ +SR_PRIV int sr_atof_ascii(const char *str, float *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; + } + + /* FIXME This fails unexpectedly. Some other method to safel downcast + * needs to be found. Checking against FLT_MAX doesn't work as well. */ + /* + if ((float) tmp != tmp) { + errno = ERANGE; + sr_dbg("ERANGEEEE %e != %e", (float) tmp, tmp); + return SR_ERR; + } + */ + + *ret = (float) tmp; + return SR_OK; +} + /** * Convert a numeric value value to its "natural" string representation * in SI units.