Following the GNU Documentation, functions to convert double/float to string
and vice versa, use the locale to set the mantissa separator. Some languages
use comma and other use dot as a separator.
For example: 1,212.67 (en_US) = 1.112,67 (pt_BR).
This can be used to parse values in float/double from XML and other definition
files.
Signed-off-by: Julio Faracco <jcfaracco(a)gmail.com>
---
src/libvirt_private.syms | 1 +
src/util/virstring.c | 31 +++++++++++++++++++++++++++++++
src/util/virstring.h | 4 ++++
3 files changed, 36 insertions(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 044510f..9d791e6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2659,6 +2659,7 @@ virStringTrimOptionalNewline;
virStrncpy;
virStrndup;
virStrToDouble;
+virStrToDoubleSafe;
virStrToLong_i;
virStrToLong_l;
virStrToLong_ll;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 089b539..6dad00f 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -537,6 +537,37 @@ virStrToDouble(char const *s,
}
int
+virStrToDoubleSafe(char const *s,
+ char **end_ptr,
+ double *result)
+{
+ char *cur_locale = NULL;
+ char *saved_locale = NULL;
+ int ret = -1;
+
+ cur_locale = setlocale (LC_ALL, NULL);
+ if (!cur_locale)
+ return ret;
+
+ if (VIR_STRDUP(saved_locale, cur_locale) < 0)
+ goto cleanup;
+
+ if (!setlocale (LC_ALL, "C"))
+ goto cleanup;
+
+ ret = virStrToDouble(s, end_ptr, result);
+
+ // Cannot restore the locale.
+ if (!setlocale (LC_ALL, saved_locale))
+ ret = -1;
+
+ cleanup:
+ VIR_FREE(saved_locale);
+ VIR_FREE(cur_locale);
+ return ret;
+}
+
+int
virVasprintfInternal(bool report,
int domcode,
const char *filename,
diff --git a/src/util/virstring.h b/src/util/virstring.h
index 0038a40..fa551b7 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -108,6 +108,10 @@ int virStrToDouble(char const *s,
char **end_ptr,
double *result)
ATTRIBUTE_RETURN_CHECK;
+int virStrToDoubleSafe(char const *s,
+ char **end_ptr,
+ double *result)
+ ATTRIBUTE_RETURN_CHECK;
void virSkipSpaces(const char **str) ATTRIBUTE_NONNULL(1);
void virSkipSpacesAndBackslash(const char **str) ATTRIBUTE_NONNULL(1);
--
2.7.4