[libvirt] [PATCH] json: fix interface locale dependency
Martin Kletzander
mkletzan at redhat.com
Mon Aug 6 09:15:35 UTC 2012
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
More information about the libvir-list
mailing list