spa: add locale independent spa_strtod/spa_strtod

Use those for spa_atof and spa_atod.
Use those for parsing json float.
This commit is contained in:
Wim Taymans 2022-03-21 10:38:00 +01:00
parent 6b423c3d25
commit 5f4d031db0
2 changed files with 50 additions and 11 deletions

View file

@ -34,9 +34,11 @@ extern "C" {
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <locale.h>
#include <math.h>
#include <float.h>
#include <spa/utils/defs.h>
#include <spa/utils/string.h>
/** \defgroup spa_json JSON
* Relaxed JSON variant parsing
@ -238,13 +240,7 @@ static inline bool spa_json_is_null(const char *val, int len)
static inline int spa_json_parse_float(const char *val, int len, float *result)
{
char *end;
static locale_t locale = NULL;
if (SPA_UNLIKELY(locale == NULL))
locale = newlocale(LC_ALL_MASK, "C", NULL);
if (locale != NULL)
*result = strtof_l(val, &end, locale);
else
*result = strtof(val, &end);
*result = spa_strtof(val, &end);
return len > 0 && end == val + len;
}

View file

@ -32,6 +32,8 @@ extern "C" {
#include <stdarg.h>
#include <stdbool.h>
#include <errno.h>
#include <stdlib.h>
#include <locale.h>
#include <spa/utils/defs.h>
@ -263,6 +265,27 @@ static inline int spa_scnprintf(char *buffer, size_t size, const char *format, .
return r;
}
/**
* Convert \a str to a float in the C locale.
*
* If \a endptr is not NULL, a pointer to the character after the last character
* used in the conversion is stored in the location referenced by endptr.
*
* \return the result float.
*/
static inline float spa_strtof(const char *str, char **endptr)
{
static locale_t locale = NULL;
float v;
if (SPA_UNLIKELY(locale == NULL))
locale = newlocale(LC_ALL_MASK, "C", NULL);
if (locale != NULL)
v = strtof_l(str, endptr, locale);
else
v = strtof(str, endptr);
return v;
}
/**
* Convert \a str to a float and store the result in \a val.
*
@ -277,9 +300,8 @@ static inline bool spa_atof(const char *str, float *val)
if (!str || *str =='\0')
return false;
errno = 0;
v = strtof(str, &endptr);
v = spa_strtof(str, &endptr);
if (errno != 0 || *endptr != '\0')
return false;
@ -287,6 +309,27 @@ static inline bool spa_atof(const char *str, float *val)
return true;
}
/**
* Convert \a str to a double in the C locale.
*
* If \a endptr is not NULL, a pointer to the character after the last character
* used in the conversion is stored in the location referenced by endptr.
*
* \return the result float.
*/
static inline double spa_strtod(const char *str, char **endptr)
{
static locale_t locale = NULL;
double v;
if (SPA_UNLIKELY(locale == NULL))
locale = newlocale(LC_ALL_MASK, "C", NULL);
if (locale != NULL)
v = strtod_l(str, endptr, locale);
else
v = strtod(str, endptr);
return v;
}
/**
* Convert \a str to a double and store the result in \a val.
*
@ -303,7 +346,7 @@ static inline bool spa_atod(const char *str, double *val)
return false;
errno = 0;
v = strtod(str, &endptr);
v = spa_strtod(str, &endptr);
if (errno != 0 || *endptr != '\0')
return false;