On 08/06/2012 11:13 AM, Michal Privoznik wrote: > On 06.08.2012 10:12, Martin Kletzander wrote: >> libvirt creates invalid commands if wrong locale is selected. For >> example with locale that uses comma as a decimal point, JSON commands >> created with decimal numbers are invalid because comma separates the >> entries in JSON. >> >> But even when decimal point is affected, grouping is not, because for >> grouping to be enabled with *printf, there has to be a apostrophe flag >> specified (and supported). >> --- >> Fortunately, there should be no other place where output-formatting is >> affected by this problem. >> >> I tried to change this in various ways with this posted one being the >> cleanest from my point of view, because: >> - setting locale is per-proccess, not per-thread (not thread-safe) >> - there is no number parsing that mangles the output number because >> of floating point precision >> >> src/util/json.c | 23 +++++++++++++++++++++-- >> 1 files changed, 21 insertions(+), 2 deletions(-) >> >> diff --git a/src/util/json.c b/src/util/json.c >> index 5132989..753a548 100644 >> --- a/src/util/json.c >> +++ b/src/util/json.c >> @@ -23,6 +23,8 @@ >> >> #include <config.h> >> >> +#include <locale.h> >> + >> #include "json.h" >> #include "memory.h" >> #include "virterror_internal.h" >> @@ -44,7 +46,6 @@ >> /* XXX fixme */ >> #define VIR_FROM_THIS VIR_FROM_NONE >> >> - >> typedef struct _virJSONParserState virJSONParserState; >> typedef virJSONParserState *virJSONParserStatePtr; >> struct _virJSONParserState { >> @@ -200,9 +201,27 @@ virJSONValuePtr virJSONValueNewNumberUlong(unsigned long long data) >> virJSONValuePtr virJSONValueNewNumberDouble(double data) >> { >> virJSONValuePtr val = NULL; >> - char *str; >> + char *str, *radix, *tmp; >> + >> if (virAsprintf(&str, "%lf", data) < 0) >> return NULL; >> + >> + /* because printing double is locale-dependent, we could end up >> + * with invalid JSON code, so we have to do something like this */ >> + radix = localeconv()->decimal_point; >> + tmp = strstr(str, radix); >> + if (tmp) { >> + *tmp = '.'; >> + if (strlen(radix) > 1) { >> + /* if the current locale specifies more characters as >> + * decimal point then cover the others with decimal >> + * numbers */ >> + memcpy(tmp + 1, >> + tmp + strlen(radix), >> + strlen(str) - (tmp - str)); >> + } >> + } >> + >> val = virJSONValueNewNumber(str); >> VIR_FREE(str); >> return val; >> -- > > When we are touching this - should we also care about thousand separator? > > Michal > Thousands are separated only if the apostrophe flag is specified (mentioned in the commit message). Martin -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list