[libvirt] [PATCH v2] json: fix interface locale dependency
Martin Kletzander
mkletzan at redhat.com
Fri Aug 10 09:43:26 UTC 2012
On 08/09/2012 06:17 PM, Eric Blake wrote:
> virCasprintf() seems like overkill, for now. Since printing a floating
> point value is the only case where locale matters, we should be able to
> provide a single helper function that guarantees a formatted float,
> rather than trying to provide a generic virCasprintf that covers all
> possible format strings. I don't even think we need to worry about
> things like 0 padding, justification, or precision - either we are
> outputting things to the user (where alignment and precision make things
> look nice, but then we WANT to obey locale), or we are converting to an
> internal string (where we want the string to be reproducible, and
> worrying about formatting is unneeded bulk). That is, I think we are
> better off with this signature in util.c:
>
> /* Return a malloc'd string representing D in the C locale, or NULL on
> OOM. */
> char *virDoubleToStr(double d);
>
> (and possibly virFloatToStr and virLongDoubleToStr if we ever have
> reason for them later on; or even add an option argument to let the user
> choose between a, e, f, or g format). At any rate, the fallback code
> for replacing the decimal character should live in util.c, not in the
> clients.
>
I see I should've stuck with one of my versions and don't listen to guys
around here ;-) I'm with you on this one.
>> + if (ret == -1) {
>> return NULL;
>> + } else if (ret == -2) {
>> + char *radix, *tmp;
>> + struct lconv *lc;
>
> I'm still worried about whether 'struct lconv' will compile on mingw.
> Then again, any system that lacks localeconf() probably also lacks any
> locale that would use ',' for the decimal separator, so maybe
> appropriate ifdef protection is all we need.
>
As we based it on glib code, I'd say: "they have it like this" :)
>> @@ -2003,6 +2004,47 @@ virAsprintf(char **strp, const char *fmt, ...)
>> }
>>
>> /**
>> + * virCasprintf
>> + *
>> + * the same as virAsprintf, but with C locale (thread-safe)
>> + *
>> + * If thread-safe locales aren't supported, then the return value is -2,
>> + * no memory (or other vasnprintf errors) results in -1.
>> + * When successful, the value returned by virAsprintf is passed.
>> + */
>> +#if HAVE_XLOCALE_H
>
> And where does HAVE_XLOCALE_H get defined? Autoconf conventions say it
> would map to <xlocale.h> existing, but that is a non-standard header
> name. Not to mention that we really care about whether newlocale and
> setlocale exist.
>
I tried to create a have_xlocale with AC_COMPILE_IFELSE but since
uselocale, newlocale and freelocale are part of libc, I haven't managed
to make it fail. Even after removing all the header files the only
problem was with NULL, but no problem with these function. I'll recreate
what I threw away and I'll send it as a new version and in the meantime
I'll try to find a machine/configuration the test will fail on.
>> +int
>> +virCasprintf(char **strp, const char *fmt, ...)
>> +{
>> + va_list ap;
>> + int ret = -1;
>> + locale_t c_loc, old_loc;
>> + c_loc = newlocale(LC_ALL, "C", NULL);
>
> This is expensive to recreate on the fly for every caller; I think it
> should be a static variable and created only once (the virInitOnce stuff
> makes the most sense here).
>
OK, will do. Thanks for the review and ideas, I'll jump right on that ;)
Martin
More information about the libvir-list
mailing list