wxFloatingPointValidator bug? when using setlocale(LC_NUMERIC, "C") after setting wxLocale

271 views
Skip to first unread message

zura.khe...@gmail.com

unread,
Nov 20, 2014, 1:15:50 PM11/20/14
to wx-u...@googlegroups.com
Hello,

I'm using a locale (by setting wxLocale) where the decimal separator is a comma (e.g. Spanish). Afterwards, I'm calling  setlocale(LC_NUMERIC, "C") in order to switch to dots for decimal separators. With this setup wxFloatingPointValidator doesn't accept neither `comma` nor `dot` for the corresponding textctrl.

I suppose wxFloatingPointValidator should respect C locale for numerics and ignore beforehand set wxLocale.

Best regards,
Zura

Zura Khetsuriani

unread,
Nov 24, 2014, 12:16:32 PM11/24/14
to wx-u...@googlegroups.com
Hello again,

Should I post this in wx-dev? (i.e. is the audience different there?)

Thanks,
Zura
> --
> Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.
>
> To unsubscribe, send email to wx-users+u...@googlegroups.com
> or visit http://groups.google.com/group/wx-users

Vadim Zeitlin

unread,
Nov 26, 2014, 2:02:20 PM11/26/14
to wx-u...@googlegroups.com
On Thu, 20 Nov 2014 10:15:50 -0800 (PST) you wrote:

> I'm using a locale (by setting wxLocale) where the decimal separator is a
> comma (e.g. Spanish). Afterwards, I'm calling setlocale(LC_NUMERIC, "C")
> in order to switch to dots for decimal separators. With this setup
> wxFloatingPointValidator doesn't accept neither `comma` nor `dot` for the
> corresponding textctrl.

Where (i.e. which platform) does this happen? Also, can it be reproduced
with minimal changes (e.g. just the addition of setlocale() call) in the
"validate" sample? If it can, please open a Trac ticket with a patch
(please see http://trac.wxwidgets.org/wiki/HowToSubmitPatches) doing this.

> I suppose wxFloatingPointValidator should respect C locale for numerics and
> ignore beforehand set wxLocale.

Yes, but it's supposed to already behave like this. If you can debug it
and find out why doesn't this work, it would be very welcome, of course.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

Zura Khetsuriani

unread,
Nov 27, 2014, 10:08:48 AM11/27/14
to wx-u...@googlegroups.com
Thank you for reply, Vadim,

It happens on Mac OS X 10.8.5, using xcode 3.2.5.

One additional fact I can provide at the moment: It seems the bug is in:

wxChar wxNumberFormatter::GetDecimalSeparator()

Even after setting C locale for numerics, it still returns `,` (comma)
when the system locale is set to Spanish or French. These locales by
default have comma's as a decimal separator. I also set `dot` for these
locales in OSX regional settings (i.e. used custom separator) - but
wxNumberFormatter::GetDecimalSeparator still returns `comma`.

Best regards,
Zura

Igor Korot

unread,
Nov 27, 2014, 10:20:28 AM11/27/14
to wx-u...@googlegroups.com
Zura,

On Thu, Nov 27, 2014 at 10:08 AM, Zura Khetsuriani
<zura.khe...@gmail.com> wrote:
> Thank you for reply, Vadim,
>
> It happens on Mac OS X 10.8.5, using xcode 3.2.5.
>
> One additional fact I can provide at the moment: It seems the bug is in:
>
> wxChar wxNumberFormatter::GetDecimalSeparator()
>
> Even after setting C locale for numerics, it still returns `,` (comma) when
> the system locale is set to Spanish or French. These locales by default have
> comma's as a decimal separator. I also set `dot` for these locales in OSX
> regional settings (i.e. used custom separator) - but
> wxNumberFormatter::GetDecimalSeparator still returns `comma`.

How did you compile the library?
Also, I would say that if changing the settings results in wrong
behavior it is a
bug in underlying OS implementation.
If you write simple C program and compile using XCode (BTW is it 3.2.5
or 4.2.5?)
with custom separator, what happen? Does it still give you "comma"?

Thank you.

>
> Best regards,
> Zura
>
>
>
> On 26.11.2014 23:02, Vadim Zeitlin wrote:
>>
>> On Thu, 20 Nov 2014 10:15:50 -0800 (PST) you wrote:
>>
>>> I'm using a locale (by setting wxLocale) where the decimal separator is a
>>> comma (e.g. Spanish). Afterwards, I'm calling setlocale(LC_NUMERIC, "C")
>>> in order to switch to dots for decimal separators. With this setup
>>> wxFloatingPointValidator doesn't accept neither `comma` nor `dot` for the
>>> corresponding textctrl.
>>
>>
>> Where (i.e. which platform) does this happen? Also, can it be reproduced
>> with minimal changes (e.g. just the addition of setlocale() call) in the
>> "validate" sample? If it can, please open a Trac ticket with a patch
>> (please see http://trac.wxwidgets.org/wiki/HowToSubmitPatches) doing this.
>>
>>> I suppose wxFloatingPointValidator should respect C locale for numerics
>>> and
>>> ignore beforehand set wxLocale.
>>
>>
>> Yes, but it's supposed to already behave like this. If you can debug it
>> and find out why doesn't this work, it would be very welcome, of course.
>>
>> Regards,
>> VZ
>>
>

Zura Khetsuriani

unread,
Nov 27, 2014, 10:46:00 AM11/27/14
to wx-u...@googlegroups.com
Igor,

It seems to be wxNumberFormatter::GetDecimalSeparato specific bug,
because while it incorrectly returns `comma`, std::sscanf and
wxString::ToDouble work fine on dot-containing strings (after setting C
locale for numerics only).

Thank you,
Zura

Igor Korot

unread,
Nov 27, 2014, 11:43:01 AM11/27/14
to wx-u...@googlegroups.com
Zura,

On Thu, Nov 27, 2014 at 10:45 AM, Zura Khetsuriani
<zura.khe...@gmail.com> wrote:
> Igor,
>
> It seems to be wxNumberFormatter::GetDecimalSeparato specific bug, because
> while it incorrectly returns `comma`, std::sscanf and wxString::ToDouble
> work fine on dot-containing strings (after setting C locale for numerics
> only).

So, what happens if you make simple C program trying to get the from the OS?
Does it work correctly? In both cases - ToDouble() and GetDecimalSeparator()?

Thank you.

Zura Khetsuriani

unread,
Nov 27, 2014, 12:02:27 PM11/27/14
to wx-u...@googlegroups.com
I think I've found the bug:

wxNumberFormatter::GetDecimalSeparator caches the separator (be it dot
or comma) in the static variable. And it only updates it if
LocaleId::NotInitializedOrHasChanged returns true.

BUT, this LocaleId::NotInitializedOrHasChanged only checks for LC_ALL
change, thus I suppose the change of only LC_NUMERIC is ignored.

The behavior is such:

1. initially, wxNumberFormatter::GetDecimalSeparator returns `dot`
2. setting wxLocale to system language (e.g. Spain), where separator `comma`
3. wxNumberFormatter::GetDecimalSeparator returns `comma`
4. setlocale(LC_NUMERIC, "C")

5. wxNumberFormatter::GetDecimalSeparator anyway returns `comma`, but
wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) returns
`dot` - which is correct, but wxNumberFormatter fails because it already
cached `comma` in the static var and failed to recognize a change to
update it.

Best regards,
Zura

Vadim Zeitlin

unread,
Nov 27, 2014, 7:07:48 PM11/27/14
to wx-u...@googlegroups.com
On Thu, 27 Nov 2014 21:02:16 +0400 Zura Khetsuriani wrote:

ZK> I think I've found the bug:
ZK>
ZK> wxNumberFormatter::GetDecimalSeparator caches the separator (be it dot
ZK> or comma) in the static variable. And it only updates it if
ZK> LocaleId::NotInitializedOrHasChanged returns true.
ZK>
ZK> BUT, this LocaleId::NotInitializedOrHasChanged only checks for LC_ALL
ZK> change, thus I suppose the change of only LC_NUMERIC is ignored.

This would be a bug in OS X setlocale() behaviour -- not that I'd be
really surprised by it, CRT under OS X is amazingly broken. Still, it would
be nice to confirm this, so could you please compile the following program:
---------------------------------- >8 --------------------------------------
#include <locale.h>
#include <stdio.h>
#include <langinfo.h>

int main(int argc, char **argv)
{
if ( argc != 2 ) {
fprintf(stderr, "Usage: %s <locale>\n", argv[0]);

return 1;
}

printf("LC_ALL=%s\nLC_NUM=%s\n", setlocale(LC_ALL, NULL), setlocale(LC_NUMERIC, NULL));

if ( !setlocale(LC_ALL, argv[1]) ) {
fprintf(stderr, "Locale %s is not supported by this system.\n", argv[1]);

return 2;
}

printf("LC_ALL=%s\nLC_NUM=%s\n", setlocale(LC_ALL, NULL), setlocale(LC_NUMERIC, NULL));
setlocale(LC_NUMERIC, "C");
printf("LC_ALL=%s\nLC_NUM=%s\n", setlocale(LC_ALL, NULL), setlocale(LC_NUMERIC, NULL));

return 0;
}
---------------------------------- >8 --------------------------------------
and run it with some locale your system supports?

Here is what it outputs for me under Linux, for example:

% ./a.out fr_FR
LC_ALL=C
LC_NUM=C
LC_ALL=fr_FR
LC_NUM=fr_FR
LC_ALL=LC_CTYPE=fr_FR;LC_NUMERIC=C;LC_TIME=fr_FR;LC_COLLATE=fr_FR;LC_MONETARY=fr_FR;LC_MESSAGES=fr_FR;LC_PAPER=fr_FR;LC_NAME=fr_FR;LC_ADDRESS=fr_FR;LC_TELEPHONE=fr_FR;LC_MEASUREMENT=fr_FR;LC_IDENTIFICATION=fr_FR
LC_NUM=C

As you can see, calling setlocale(LC_NUMERIC) does change the value
returned from setlocale(LC_ALL, NULL). Is this really not the case under OS
X?

Also, it looks like checking for LC_NUMERIC instead of LC_ALL in wx code
should fix the problem if you're correct, could you please try if it does?

Thanks,

Zura Khetsuriani

unread,
Nov 30, 2014, 11:50:05 AM11/30/14
to wx-u...@googlegroups.com
It actually changed the string:

Before:
LC_ALL=fr_FR
LC_NUM=fr_FR

After (calling of setlocale C for nums):
LC_ALL=fr_FR/fr_FR/fr_FR/C/fr_FR/fr_FR (note "C" in the middle)
LC_NUM=C

Unfortunately, I"m unable to step into wx part of the code at the
moment, but I believe it means the bug is in some other part of
wxNumberFormatter::GetDecimalSeparator, because as I mentioned
wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) returns a
correct one.

Thank you,
Zura

Vadim Zeitlin

unread,
Nov 30, 2014, 3:32:20 PM11/30/14
to wx-u...@googlegroups.com
On Sun, 30 Nov 2014 20:50:00 +0400 Zura Khetsuriani wrote:

ZK> It actually changed the string:
ZK>
ZK> Before:
ZK> LC_ALL=fr_FR
ZK> LC_NUM=fr_FR
ZK>
ZK> After (calling of setlocale C for nums):
ZK> LC_ALL=fr_FR/fr_FR/fr_FR/C/fr_FR/fr_FR (note "C" in the middle)
ZK> LC_NUM=C

This is reassuring, so the CRT is not buggy after all, this means we have
a chance.

ZK> Unfortunately, I"m unable to step into wx part of the code at the
ZK> moment, but I believe it means the bug is in some other part of
ZK> wxNumberFormatter::GetDecimalSeparator, because as I mentioned
ZK> wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER) returns a
ZK> correct one.

Unfortunately I don't see anything wrong with it just by looking at it. If
you can rebuild wx with debug info so that you could step into it and do
trace what's going on, it would be really helpful.
Reply all
Reply to author
Forward
0 new messages