Travis Vitek
Sat, 18 Aug 2007 23:57:46 -0700
Travis Vitek wrote: > >Travis Vitek wrote: >> >>The problem is that some locales pad their date/time output with >>whitespace [like '7. 6. 1988' or ' 7.6.1988'] and I'm unable to use >>num_get<>::get_[time,date] to read what is written by >>num_put<>::put. It >>is my understanding that I should be able to do so. Is this a bug, a >>known issue, or is it acceptable behavior that I need to code >around in >>the test? > >Whoops, obviously I am talking about the time_[get,put] facets here. >
Okay, so I've done the required research. These are the relevant
sections of the standard that I was able to find.
[22.2.5.1 p1] Each get member parses a format as produced by a
corresponding format specifier to time_put<>::put. If the sequence
being parsed maches the correct format, the corresponding members of
the struct tm argument are set to the values used to produce the
sequence; otherwise either an error is reported or unspecified values
are assigned.
[22.2.5.1.2 p2] Effects: Reads characters starting at s until it has
extracted those struct tm members, and remaining format characters,
used by time_put<>::put to produce the format specified by 'X' or
until it encounters an error.
Unless I'm missing something obvious, it appears that the output of the
time_put<> facet is required to be parseable by the time_get<> facet. Of
course that isn't what I'm seeing.
One case that fails is the weekday '%e'. With some locales '%x' expands
out to '%m/%e/%Y'. Anyways, when putting the data,
__rw_get_time_put_data() correctly sets the field width to 2. When we
attempt to get the data back out of the stream, no width is specified.
There is no code in place in the get_date() call stack to deal with
width, and the block of code that does the actual parsing doesn't have
any concept of field width either [_time_get.cc:284].
Worse yet is that the tests actually verify this bad behavior. The
22.locale.time.get test verifies that the '%e' format fails if there is
any leading whitespace.
// %e Equivalent to %d; leading zeros are permitted but not required.
STEP ("%e: equivalent to %d");
TEST (T (0, 0, 0, 1), "01", 2, "e", 0, Eof);
TEST (T (0, 0, 0, 9), "9", 1, "e", 0, Eof);
TEST (T (0, 0, 0, 31), "31", 2, "e", 0, Eof);
TEST (T (0, 0, 0, 0), "0", 1, "e", 0, Eof | Fail);
// leading whitespace not allowed
TEST (T (0, 0, 0, 0), " 2", 0, "e", 0, Fail); // *** problem
TEST (T (0, 0, 0, 0), "99", 2, "e", 0, Eof | Fail);
The 22.locale.time.put test verifies the leading space is there when
writing the '%e' format.
// %e: the day of the month as a decimal number (1-31);
// a single digit is preceded by a space. [tm_mday]
rw_info (0, 0, __LINE__, "%%e: the day of the month as a decimal
number");
TEST (T (), "%e", 0, 0, ' ', "%e");
TEST (T (), "%e", 0, 0, ' ', " 1"); // *** problem
TEST (T (), " 1", 0, 0, ' ', "%e"); // *** problem
TEST (T (-1), "%e", 0, 0, ' ', "%e");
Feedback?
Travis