Martin Sebor wrote:
>
>The C and C++ standards only specify the requirements on the "C"
>locale and leave the localized behavior unspecified. So pretty
>much anything goes.
>

I don't know how you can say that with a straight face. The C++ standard
says that time_put<>::put() treats the format string like strftime().
The C and POSIX specifications both define the output for strftime() for
each of the required format specifiers. The numeric values are pretty
strictly specified, and the non-numeric ones [%b as an example] are
supposed to be defined by the specified locales LC_TIME category.

It seems pretty well defined, it is just through three levels of
indirection. It makes sense to not define the behavior for all locales
explicitly in the C standard, since locale definition files can be
created by the user, and the system provided ones could be modified or
removed.

>
>There are some ground rules but I suspect
>you won't be able to tease the requirement on swallowing leading
>space for the %e directive out of them.
>

I wouldn't think so, but I might not need to. See below...

>
>> 
>> Well, there's the problem right there. The standard requires that the
>> time_put<> facet format its output according to the POSIX function
>> strftime(), with the option for supporting extensions. It makes no
>> indication that the time_get<> facet should read data in 
>such a way as
>> to be compatible with strptime(). The only thing I see that says
>> anything about the format expecte by time_get<> is here...
>[...]
>> 
>
>Right. Pretty vague.
>

I guess you could interpret that as vague. I mean they don't explicitly
say you can't try to emulate strptime(). Of course they don't explicitly
say you should attempt to either.

They do, on the other hand, say that the put() should behave
consistently with strftime(), and that get_*() should be able to read
the output of put() for a given format.

>> 
>>> Absolutely. The docs for POSIX strftime()...
>>> [...]
>>
>> So strftime() isn't even compatible with strptime() when it 
>> comes to '%e'.
>
>Hmm. That seems like a bug in POSIX then, unless we're missing
>something. You might want to create a POSIX-only test case to
>verify this and if I'm right open a discussion on the Austin
>Group list (http://www.opengroup.org/austin/lists.html).
>

Yeah, I've made a testcase using strptime(), but it passes on most
environments I've tested. Source...

    #include <stdio.h>
    #include <time.h>
    #include <assert.h>
    #include <string.h>

    int main (int argc, char* argv [])
    {
        const char* fmt = "-%H:%M:%S-%m/%e/%Y-";
        const char* buf = "-01:02:03-04/ 5/1906 -";

        struct tm r;
        memset (&r, 0, sizeof (r));

        strptime (buf, fmt, &r);
        fprintf (stderr, "%%H=%d %%M=%d %%S=%d %%m=%d %%e=%d %%Y=%d\n",
                 r.tm_hour, r.tm_min, r.tm_sec,
                 r.tm_mon, r.tm_mday, r.tm_year);

        assert (1 == r.tm_hour); // [01,12]
        assert (2 == r.tm_min);  // [00,59]
        assert (3 == r.tm_sec);  // [00,61]
        assert (3 == r.tm_mon);  // [00,11]
        assert (5 == r.tm_mday); // [01,31]
        assert (6 == r.tm_year); // [00,99]

        return 0;
    }

The strptime() function is clearly skipping leading whitespace with the
'%e' flag on those platforms that allow this test to pass. Here is a
quick test matrix

                   Pass |  Fail |
                    ----+-------+-------+
         Linux26/gcc346 |   X   |       |
     Solaris58/SunPro53 |   X   |       |
         HP-UX11/ACC373 |       |   X   |
           DEC5.1/C++71 |   X   |       |
                    ----+-------+-------+
            Win32/VC8   | no strptime() |


>> 
>My approach would be to detect locales with this
>problem and avoid using them. The test also doesn't need to
>be exhaustive, at least not in this iteration. I think
>exercising just the most common patterns should be good enough
>(although %X is pretty common :)

Yes, I could verify the locale doesn't use '%e' to represent weekdays
for the time being.

>
>Martin
>

Reply via email to