Details

[Home]

Issue of the Implementation # S0694

Brief

time_get<>::do_get_weekday does not always recognize full names of weekdays; similar problem with time_get<>::do_get_monthname too

Detailed Description

The description of time_get<>::do_get_weekday() and time_get<>::do_get_monthname() states (22.2.5.1.2):

Effects: Reads characters starting at s until it has extracted the (perhaps abbreviated) name of a weekday or month. If it finds an abbreviation that is followed by characters that could match a full name, it continues reading until it matches the full name or fails.

However, if the abbreviated name of a weekday is not a prefix of its full name, the full name is not recognized by the function.

For example, the Russian name of Monday (Ponedelnik) is not recognized as Monday (locale - ru_RU.iso88595) because of this. But if one replaces the 1st 3 symbols of this word with the abbreviated Russian name of Monday (Pnd), the resulting string (Pndedelnik) is recognized as the full name of Monday, which is wrong.

According to the source of time_get<>::do_get_weekday function's implementation as well as the comments in it, it is definitely assumed in the function that the abbreviated name of a weekday should be a prefix of its full name.

A similar problem takes place for time_get<>::do_get_monthname() function.

Problem location(s) in the standard

Linux Standard Base C++ Specification 3.2, Chapter 9. Libraries, 9.1. Interfaces for libstdcxx that refers ISO/IEC 14882: 2003 Programming languages --C++, section 22.2.5.1.2

Reproducing

  1. Make sure that "ru_RU.iso88595" locale is available on your system. If there is no such locale, please, install it manually.
  2. Build and execute the sample program given below.

Example

#include <stdio.h>
#include <locale>
#include <sstream>

using namespace std;
int main()
{
    tm t;
    t.tm_wday = -1;//initial value
    locale loc("ru_RU.iso88595");
    const time_get<char>& tg = use_facet<time_get<char> >(loc);
    
    // The 1st option    
    // Monday in Russian - it is not recognized
    // const char* input_string = "\xbf\xde\xdd\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda";

    // The 2nd option
    // Incorrect name of weekday, but it is recognized as Monday 
    // because it begins with the abbreviated Russian name of Monday
    const char* input_string = "\xbf\xdd\xd4\xd5\xd4\xd5\xdb\xec\xdd\xd8\xda";
    
    printf("Input string is '%s'.\n", input_string);
    istringstream is(input_string);
    
    ios_base::iostate err = (ios_base::iostate)0;
    ios_base& str = is;
    str.imbue(loc);
    istreambuf_iterator<char> s = is;
    istreambuf_iterator<char> end;
    //this function call protected virtual function do_get_weekday
    tg.get_weekday(s, end, str, err, &t);

    string rest;
    while(s != end) rest+= *s++;
    printf("Rest of the string after parsing is '%s'.\n", rest.c_str());
    printf("ios_base::failbit was%s set in err.\n",
        err & ios_base::failbit ? "" : "n't");
    printf("tm_wday became %d.\n", t.tm_wday);

    return 0;
}

Component

libstdc++

Accepted

GCC Bugzilla 38081

Status

Fixed in gcc-4.5.0

[Home]