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.
This commit is contained in:
poljar (Damir Jelić) 2014-01-16 15:28:48 +01:00 committed by Bert Vermeulen
parent 92b68bb5d6
commit 9806c2d573
2 changed files with 44 additions and 0 deletions

View File

@ -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 ----------------------------------------------*/

View File

@ -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.