drivers: Fix locale dependent string to float conversion
Some drivers used locale dependent functions for converting strings to float/double values. These functions fail when the decimal mark is a "," in the locale settings but the string contains a ".". This fixes bug #1064.
This commit is contained in:
parent
688e44ae06
commit
4f0463a079
|
@ -44,7 +44,7 @@ SR_PRIV gboolean sr_m2110_packet_valid(const uint8_t *buf)
|
|||
if (!strncmp((const char *)buf, "OVERRNG", 7))
|
||||
return TRUE;
|
||||
|
||||
if (sscanf((const char *)buf, "%f", &val) == 1)
|
||||
if (sr_atof_ascii((const char *)buf, &val) == SR_OK)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -65,7 +65,7 @@ SR_PRIV int sr_m2110_parse(const uint8_t *buf, float *floatval,
|
|||
|
||||
if (!strncmp((const char *)buf, "OVERRNG", 7))
|
||||
*floatval = INFINITY;
|
||||
else if (sscanf((const char *)buf, "%f", &val) == 1) {
|
||||
else if (sr_atof_ascii((const char *)buf, &val) == SR_OK) {
|
||||
*floatval = val;
|
||||
dot_pos = strcspn((const char *)buf, ".");
|
||||
if (dot_pos < 7)
|
||||
|
|
|
@ -86,7 +86,7 @@ static int parse_value(const uint8_t *buf, struct metex14_info *info,
|
|||
return SR_OK;
|
||||
|
||||
/* Bytes 2-8: Sign, value (up to 5 digits) and decimal point */
|
||||
sscanf((const char *)&valstr, "%f", result);
|
||||
sr_atof_ascii((const char *)&valstr, result);
|
||||
|
||||
dot_pos = strcspn(valstr, ".");
|
||||
if (dot_pos < cnt)
|
||||
|
|
|
@ -87,7 +87,7 @@ static void process_line(struct sr_dev_inst *sdi)
|
|||
case AQ_U2:
|
||||
case AQ_I1:
|
||||
case AQ_I2:
|
||||
if (sr_atod(devc->buf, &dbl) != SR_OK) {
|
||||
if (sr_atod_ascii(devc->buf, &dbl) != SR_OK) {
|
||||
sr_err("Failed to convert '%s' to double, errno=%d %s",
|
||||
devc->buf, errno, g_strerror(errno));
|
||||
dbl = 0.0;
|
||||
|
|
|
@ -1010,6 +1010,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_atod_ascii(const char *str, double *ret);
|
||||
SR_PRIV int sr_atof_ascii(const char *str, float *ret);
|
||||
|
||||
/*--- soft-trigger.c --------------------------------------------------------*/
|
||||
|
|
|
@ -627,7 +627,7 @@ SR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi,
|
|||
if (ret != SR_OK && !response)
|
||||
return ret;
|
||||
|
||||
if (sr_atod(response, scpi_response) == SR_OK)
|
||||
if (sr_atod_ascii(response, scpi_response) == SR_OK)
|
||||
ret = SR_OK;
|
||||
else
|
||||
ret = SR_ERR_DATA;
|
||||
|
|
|
@ -169,6 +169,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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue