Jump to page: 1 2 3
Thread overview
C locale
Sep 27, 2013
Luís Marques
Sep 27, 2013
Walter Bright
Sep 27, 2013
Luís Marques
Sep 27, 2013
H. S. Teoh
Sep 27, 2013
Walter Bright
Sep 27, 2013
Luís Marques
Sep 28, 2013
Luís Marques
Sep 28, 2013
Walter Bright
Sep 28, 2013
Walter Bright
Sep 28, 2013
Luís Marques
Sep 28, 2013
Walter Bright
Sep 28, 2013
Jacob Carlborg
Sep 28, 2013
Walter Bright
Sep 28, 2013
Luís Marques
Sep 28, 2013
Walter Bright
Sep 28, 2013
Luís Marques
Sep 28, 2013
Walter Bright
Sep 28, 2013
Jacob Carlborg
Oct 18, 2013
Luís Marques
Sep 28, 2013
Jacob Carlborg
Sep 28, 2013
Jacob Carlborg
Sep 28, 2013
Jacob Carlborg
Sep 27, 2013
Jacob Carlborg
Sep 27, 2013
Luís Marques
September 27, 2013
On my OS X SDK, locale.h has:

    #define	LC_ALL		0
    #define	LC_COLLATE	1
    #define	LC_CTYPE	2
    #define	LC_MONETARY	3
    #define	LC_NUMERIC	4
    #define	LC_TIME		5
    #define	LC_MESSAGES	6

    #define	_LC_LAST	7		/* marks end */

On std.c.locate it has:

    enum LC_CTYPE          = 0;
    enum LC_NUMERIC        = 1;
    enum LC_TIME           = 2;
    enum LC_COLLATE        = 3;
    enum LC_MONETARY       = 4;
    enum LC_ALL            = 6;
    enum LC_PAPER          = 7;  // non-standard
    enum LC_NAME           = 8;  // non-standard
    enum LC_ADDRESS        = 9;  // non-standard
    enum LC_TELEPHONE      = 10; // non-standard
    enum LC_MEASUREMENT    = 11; // non-standard
    enum LC_IDENTIFICATION = 12; // non-standard

The mismatch of course causes problems.

Are the locale enumerate values supposed to be only source compatible? (not binary compatible). Should I send a patch for OS X? For what system are the current D values, Linux? (The author is Sean Kelly).
September 27, 2013
On 9/26/2013 7:38 PM, "Luís Marques" <luis@luismarques.eu>" wrote:
> The mismatch of course causes problems.

std.c.locale must match the values in the host system's <locale.h>. If it doesn't, it's a bug.

September 27, 2013
On 2013-09-27 04:38, "Luís Marques" <luis@luismarques.eu>" wrote:

> On std.c.locate it has:

You should be using core.stdc.locale, not that it does any difference in this case.

-- 
/Jacob Carlborg
September 27, 2013
On Friday, 27 September 2013 at 06:43:02 UTC, Jacob Carlborg wrote:
> You should be using core.stdc.locale, not that it does any difference in this case.

Sorry, that's what I meant.
September 27, 2013
On Friday, 27 September 2013 at 04:54:45 UTC, Walter Bright wrote:
> std.c.locale must match the values in the host system's <locale.h>. If it doesn't, it's a bug.

Well, I was trying to assess how exactly I should fix it. For instance, in my local copy I changed it to:

    version(linux)
    {
        enum LC_CTYPE          = 0;
        enum LC_NUMERIC        = 1;
        enum LC_TIME           = 2;
        enum LC_COLLATE        = 3;
        enum LC_MONETARY       = 4;
        enum LC_ALL            = 6;
        enum LC_PAPER          = 7;  // non-standard
        enum LC_NAME           = 8;  // non-standard
        enum LC_ADDRESS        = 9;  // non-standard
        enum LC_TELEPHONE      = 10; // non-standard
        enum LC_MEASUREMENT    = 11; // non-standard
        enum LC_IDENTIFICATION = 12; // non-standard
    }
    else version(OSX)
    {

        enum LC_ALL            = 0;
        enum LC_COLLATE        = 1;
        enum LC_CTYPE	       = 2;
        enum LC_MONETARY	   = 3;
        enum LC_NUMERIC	       = 4;
        enum LC_TIME		   = 5;
        enum LC_MESSAGES	   = 6;
    }
    else version(all)
    {
        static assert(false, "locales not specified for this system");
    }

I have that ready to push in my git repo, but I'm not very happy about it:

- I asked for what OS the current values were, but for now I assumed they were for Linux only. Does anyone besides Sean Kelly know? Is it reasonable to assert for the other systems? If not, what's the alternative? Let the compilation fail and people wonder why LC_* are not defined?

- Why, oh why, is "linux" the only OS version() identifier that is not capitalized? :-) I mean, if you get it wrong the compiler won't even warn you about it....

What should I do? Do you want me to submit this? Does anyone have another Posix system laying around and want to check the locale constants?
September 27, 2013
On Fri, Sep 27, 2013 at 07:25:14PM +0200, digitalmars-d-bounces@puremagic.com wrote:
> On Friday, 27 September 2013 at 04:54:45 UTC, Walter Bright wrote:
> >std.c.locale must match the values in the host system's <locale.h>. If it doesn't, it's a bug.
> 
> Well, I was trying to assess how exactly I should fix it. For instance, in my local copy I changed it to:
> 
>     version(linux)
>     {
>         enum LC_CTYPE          = 0;
>         enum LC_NUMERIC        = 1;
>         enum LC_TIME           = 2;
>         enum LC_COLLATE        = 3;
>         enum LC_MONETARY       = 4;
>         enum LC_ALL            = 6;
>         enum LC_PAPER          = 7;  // non-standard
>         enum LC_NAME           = 8;  // non-standard
>         enum LC_ADDRESS        = 9;  // non-standard
>         enum LC_TELEPHONE      = 10; // non-standard
>         enum LC_MEASUREMENT    = 11; // non-standard
>         enum LC_IDENTIFICATION = 12; // non-standard
>     }
>     else version(OSX)
>     {
> 
>         enum LC_ALL            = 0;
>         enum LC_COLLATE        = 1;
>         enum LC_CTYPE	       = 2;
>         enum LC_MONETARY	   = 3;
>         enum LC_NUMERIC	       = 4;
>         enum LC_TIME		   = 5;
>         enum LC_MESSAGES	   = 6;
>     }
>     else version(all)
>     {
>         static assert(false, "locales not specified for this
> system");
>     }
> 
> I have that ready to push in my git repo, but I'm not very happy about it:
> 
> - I asked for what OS the current values were, but for now I assumed they were for Linux only. Does anyone besides Sean Kelly know? Is it reasonable to assert for the other systems? If not, what's the alternative? Let the compilation fail and people wonder why LC_* are not defined?
[...]

Walter's stance, IIRC, is that this code should only compile for the platforms on which the values have been verified, and static assert(0) for everything else. Every other platform will break, of course, but that's what tells us what other OSes we need to verify the values for.

FWIW, I just verified the correctness of the version(linux) block above
against /usr/include/locale.h on my system (Linux 64-bit
Debian/unstable).

Sadly, I don't have access to other Posix OSes so I can't say much beyond this.


T

-- 
I'm still trying to find a pun for "punishment"...
September 27, 2013
On 9/27/2013 10:25 AM, "Luís Marques" <luis@luismarques.eu>" wrote:
> - I asked for what OS the current values were, but for now I assumed they were
> for Linux only. Does anyone besides Sean Kelly know? Is it reasonable to assert
> for the other systems? If not, what's the alternative? Let the compilation fail
> and people wonder why LC_* are not defined?

The idea is:

version (linux)
{
     ...
}
else version (Windows)
{
     ...
}
else version (OSX)
{
    ...
}
else
{
    static assert(0);
}

I.e. the values should be POSITIVELY set for each system, NOT defaulted. The advantages are:

1. when you port to a new system, you get compile time errors for every place where you need to check/fix the values

2. if you want to fix the values for one system, you don't muck up the values for any other system


> - Why, oh why, is "linux" the only OS version() identifier that is not
> capitalized?

Because "linux" is what gcc predefines for Linux. (gcc also sets __gnu_linux, __linux__, and __linux, none of which are capitalized. It's the Linux way, not some nefarious plot of mine to disparage it.)

September 27, 2013
On Friday, 27 September 2013 at 19:23:12 UTC, Walter Bright wrote:
>     static assert(0);

Do you prefer assert(0) instead of assert(false)? Is it not worth to put a message after the 0/false? (static assert(0, "foo missing"); )

I can send a pull request with the values filled-in for Windows and OS X.

>> - Why, oh why, is "linux" the only OS version() identifier that is not
>> capitalized?
>
> Because "linux" is what gcc predefines for Linux. (gcc also sets __gnu_linux, __linux__, and __linux, none of which are capitalized. It's the Linux way, not some nefarious plot of mine to disparage it.)

Haha :-) I understand, my remark was lighthearted. Still, it seems a bit inconsistent and error prone, given the other identifiers. I mean, I'm all in favor of using "darwin" for OS X (more technically correct, and allows your code to compile in a pure Darwin environment), but if you changed it to "OSX" because it was more discoverable then... that's the kind of usability issue I'm talking about.

BTW, does that mean that gcc also defines capitalized "OSX", "Posix", etc.? (otherwise I don't understand your argument)
September 28, 2013
BTW, I have for more than once wondered why there was no way to specify more than one version identifier (is there?), like this:

    version(Windows, OSX)
    {
        enum LC_ALL            = 0;
        enum LC_COLLATE        = 1;
        enum LC_CTYPE          = 2;
        enum LC_MONETARY       = 3;
        enum LC_NUMERIC        = 4;
        enum LC_TIME           = 5;
    }
    version(OSX)
    {

        enum LC_MESSAGES	   = 6;
    }

Is there a way to use version() that avoids having to repeat the equal declarations for both Windows and OSX?
September 28, 2013
On 9/27/2013 5:28 PM, "Luís Marques" <luis@luismarques.eu>" wrote:
> BTW, I have for more than once wondered why there was no way to specify more
> than one version identifier (is there?), like this:
>
>      version(Windows, OSX)
>      {

For the reason you mentioned earlier. If you are changing the OSX values, you'll likely mess up the Windows ones.

I've been at this for 30 years, and am quite fed up with the bugs from attempts to save a few keystrokes. The practice of separating the os sections into distinct ones has been a big win in reliability.

« First   ‹ Prev
1 2 3