diff options
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/Makefile.am | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/Makefile.in | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.h | 72 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/locale_facets.tcc | 335 |
4 files changed, 294 insertions, 116 deletions
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index dd498befda2..da0bad83d7c 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -335,7 +335,6 @@ stamp-target: ${target_headers} ${target_builddir} @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h ;\ @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h ;\ @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h ;\ - @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h ;\ @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h ;\ echo `date` > stamp-target; \ fi diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 3c2f35f8e88..a7cca4cd966 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -78,7 +78,6 @@ CMESSAGES_H = @CMESSAGES_H@ CPP = @CPP@ CSHADOW_FLAGS = @CSHADOW_FLAGS@ CSTDIO_H = @CSTDIO_H@ -CTIME_H = @CTIME_H@ CXXCPP = @CXXCPP@ C_INCLUDE_DIR = @C_INCLUDE_DIR@ DATADIRNAME = @DATADIRNAME@ @@ -577,7 +576,6 @@ stamp-target: ${target_headers} ${target_builddir} @LN_S@ ${glibcpp_srcdir}/@CSTDIO_H@ c++io.h ;\ @LN_S@ ${glibcpp_srcdir}/@CLOCALE_H@ c++locale.h ;\ @LN_S@ ${glibcpp_srcdir}/@CMESSAGES_H@ messages_members.h ;\ - @LN_S@ ${glibcpp_srcdir}/@CTIME_H@ time_members.h ;\ @LN_S@ ${glibcpp_srcdir}/@CCODECVT_H@ codecvt_specializations.h ;\ echo `date` > stamp-target; \ fi diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 0d2cc70377d..11bf14b1f24 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -1078,9 +1078,12 @@ namespace std const _CharT* _M_date_era_format; const _CharT* _M_time_format; const _CharT* _M_time_era_format; + const _CharT* _M_date_time_format; + const _CharT* _M_date_time_era_format; const _CharT* _M_am; const _CharT* _M_pm; - + const _CharT* _M_am_pm_format; + // Day names, starting with "C"'s Sunday. const _CharT* _M_day1; const _CharT* _M_day2; @@ -1139,20 +1142,39 @@ namespace std { _M_initialize_timepunct(__cloc); } void - _M_put_helper(char* __s, size_t __maxlen, const char* __format, + _M_put_helper(_CharT* __s, size_t __maxlen, const _CharT* __format, const tm* __tm) const; - // Not used, at the moment. Likely to be strptime-ish. void - _M_get_helper(const char* __s, const char* __format, tm* __tm) const; + _M_date_formats(const _CharT** __date) const + { + // Always have default first. + __date[0] = _M_date_format; + __date[1] = _M_date_era_format; + } - const _CharT* - _M_date_formats() const - { return _M_date_format; } + void + _M_time_formats(const _CharT** __time) const + { + // Always have default first. + __time[0] = _M_time_format; + __time[1] = _M_time_era_format; + } - const _CharT* - _M_time_formats() const - { return _M_time_format; } + void + _M_ampm(const _CharT** __ampm) const + { + __ampm[0] = _M_am; + __ampm[1] = _M_pm; + } + + void + _M_date_time_formats(const _CharT** __dt) const + { + // Always have default first. + __dt[0] = _M_date_time_format; + __dt[1] = _M_date_time_era_format; + } void _M_days(const _CharT** __days) const @@ -1176,7 +1198,7 @@ namespace std __days[4] = _M_day_a5; __days[5] = _M_day_a6; __days[6] = _M_day_a7; - } + } void _M_months(const _CharT** __months) const @@ -1242,6 +1264,13 @@ namespace std __timepunct<_CharT>::_M_initialize_timepunct(__c_locale) { } + // NB: Cannot be made generic. + template<typename _CharT> + void + __timepunct<_CharT>::_M_put_helper(_CharT*, size_t, const _CharT*, + const tm*) const + { } + template<> void __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc); @@ -1327,14 +1356,12 @@ namespace std do_get_year(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const; - // Extract time component in the form of - // [digitdigit][separator], with a maximum of two digits per - // separator. Used by do_get_time. + // Extract numeric component of length __len. void - _M_extract_time(iter_type& __beg, iter_type& __end, int& __member, - int __min, int __max, const char_type __sep, - bool __extract, const ctype<_CharT>& __ctype, - ios_base::iostate& __err) const; + _M_extract_num(iter_type& __beg, iter_type& __end, int& __member, + int __min, int __max, size_t __len, + const ctype<_CharT>& __ctype, + ios_base::iostate& __err) const; // Extract day or month name, or any unique array of string // literals in a const _CharT* array. @@ -1342,6 +1369,12 @@ namespace std _M_extract_name(iter_type& __beg, iter_type& __end, int& __member, const _CharT** __names, size_t __indexlen, ios_base::iostate& __err) const; + + // Extract on a component-by-component basis, via __format argument. + void + _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const; }; template<typename _CharT, typename _InIter> @@ -1418,9 +1451,6 @@ namespace std ~time_put_byname() { } }; - // Include host and configuration specific messages virtual functions. - #include <bits/time_members.h> - struct money_base { diff --git a/libstdc++-v3/include/bits/locale_facets.tcc b/libstdc++-v3/include/bits/locale_facets.tcc index 0f54fa0700d..c4d972c6aeb 100644 --- a/libstdc++-v3/include/bits/locale_facets.tcc +++ b/libstdc++-v3/include/bits/locale_facets.tcc @@ -1328,45 +1328,232 @@ namespace std template<typename _CharT, typename _InIter> void time_get<_CharT, _InIter>:: - _M_extract_time(iter_type& __beg, iter_type& __end, int& __member, - int __min, int __max, const char_type __sep, - bool __extract, const ctype<_CharT>& __ctype, - ios_base::iostate& __err) const - { - if (__err == ios_base::goodbit) + _M_extract_via_format(iter_type& __beg, iter_type& __end, ios_base& __io, + ios_base::iostate& __err, tm* __tm, + const _CharT* __format) const + { + locale __loc = __io.getloc(); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); + size_t __len = char_traits<_CharT>::length(__format); + + for (size_t __i = 0; __beg != __end && __i < __len && !__err; ++__i) { - size_t __i = 0; - string __digits; - bool __testvalid = true; - const ctype_base::mask __digit = ctype_base::digit; - char_type __c = *__beg; - for (;__beg != __end && __ctype.is(__digit, __c) && __i < 2; ++__i) - { - __digits += __ctype.narrow(__c, 0); - __c = *(++__beg); - } - if (__i == 2) + char __c = __format[__i]; + if (__c == '%') { - int __value = atoi(__digits.c_str()); - if (__min <= __value && __value <= __max) - __member = __value; + // Verify valid formatting code, attempt to extract. + __c = __format[++__i]; + char __mod = 0; + int __mem = 0; + if (__c == 'E' || __c == 'O') + { + __mod = __c; + __c = __format[++__i]; + } + switch (__c) + { + const char* __cs; + _CharT __wcs[10]; + case 'a': + // Abbreviated weekday name [tm_wday] + const char_type* __days1[7]; + __tp._M_days_abbreviated(__days1); + _M_extract_name(__beg, __end, __tm->tm_wday, __days1, 7, + __err); + break; + case 'A': + // Weekday name [tm_wday]. + const char_type* __days2[7]; + __tp._M_days(__days2); + _M_extract_name(__beg, __end, __tm->tm_wday, __days2, 7, + __err); + break; + case 'h': + case 'b': + // Abbreviated month name [tm_mon] + const char_type* __months1[12]; + __tp._M_months_abbreviated(__months1); + _M_extract_name(__beg, __end, __tm->tm_mon, __months1, 12, + __err); + break; + case 'B': + // Month name [tm_mon]. + const char_type* __months2[12]; + __tp._M_months(__months2); + _M_extract_name(__beg, __end, __tm->tm_mon, __months2, 12, + __err); + break; + case 'c': + // Default time and date representation. + const char_type* __dt[2]; + __tp._M_date_time_formats(__dt); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __dt[0]); + break; + case 'd': + // Day [01, 31]. [tm_mday] + _M_extract_num(__beg, __end, __tm->tm_mday, 1, 31, 2, + __ctype, __err); + break; + case 'D': + // Equivalent to %m/%d/%y.[tm_mon, tm_mday, tm_year] + __cs = "%m/%d/%y"; + __ctype.widen(__cs, __cs + 9, __wcs); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __wcs); + break; + case 'H': + // Hour [00, 23]. [tm_hour] + _M_extract_num(__beg, __end, __tm->tm_hour, 0, 23, 2, + __ctype, __err); + break; + case 'I': + // Hour [01, 12]. [tm_hour] + _M_extract_num(__beg, __end, __tm->tm_hour, 1, 12, 2, + __ctype, __err); + break; + case 'm': + // Month [01, 12]. [tm_mon] + _M_extract_num(__beg, __end, __mem, 1, 12, 2, + __ctype, __err); + if (!__err) + __tm->tm_mon = __mem - 1; + break; + case 'M': + // Minute [00, 59]. [tm_min] + _M_extract_num(__beg, __end, __tm->tm_min, 0, 59, 2, + __ctype, __err); + break; + case 'n': + if (__ctype.narrow(*__beg, 0) == '\n') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'R': + // Equivalent to (%H:%M). + __cs = "%H:%M"; + __ctype.widen(__cs, __cs + 6, __wcs); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __wcs); + break; + case 'S': + // Seconds. + _M_extract_num(__beg, __end, __tm->tm_sec, 0, 59, 2, + __ctype, __err); + break; + case 't': + if (__ctype.narrow(*__beg, 0) == '\t') + ++__beg; + else + __err |= ios_base::failbit; + break; + case 'T': + // Equivalent to (%H:%M:%S). + __cs = "%H:%M:%S"; + __ctype.widen(__cs, __cs + 9, __wcs); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __wcs); + break; + case 'x': + // Locale's date. + const char_type* __dates[2]; + __tp._M_date_formats(__dates); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __dates[0]); + break; + case 'X': + // Locale's time. + const char_type* __times[2]; + __tp._M_time_formats(__times); + _M_extract_via_format(__beg, __end, __io, __err, __tm, + __times[0]); + break; + case 'y': + // Two digit year. [tm_year] + _M_extract_num(__beg, __end, __tm->tm_year, 0, 99, 2, + __ctype, __err); + break; + case 'Y': + // Year [1900). [tm_year] + _M_extract_num(__beg, __end, __mem, 0, + numeric_limits<int>::max(), 4, + __ctype, __err); + if (!__err) + __tm->tm_year = __mem - 1900; + break; + case 'Z': + // Timezone info. + if (__ctype.is(ctype_base::upper, *__beg)) + { + int __tmp; + _M_extract_name(__beg, __end, __tmp, + __timepunct<_CharT>::_S_timezones, + 14, __err); + + // GMT requires special effort. + char_type __c = *__beg; + if (!__err && __tmp == 0 + && (__c == __ctype.widen('-') + || __c == __ctype.widen('+'))) + { + _M_extract_num(__beg, __end, __tmp, 0, 23, 2, + __ctype, __err); + _M_extract_num(__beg, __end, __tmp, 0, 59, 2, + __ctype, __err); + } + } + else + __err |= ios_base::failbit; + break; + default: + // Not recognized. + __err |= ios_base::failbit; + } + } else - __testvalid = false; - } + { + // Verify format and input match, extract and discard. + if (__c == __ctype.narrow(*__beg, 0)) + ++__beg; + else + __err |= ios_base::failbit; + } + } + } + + template<typename _CharT, typename _InIter> + void + time_get<_CharT, _InIter>:: + _M_extract_num(iter_type& __beg, iter_type& __end, int& __member, + int __min, int __max, size_t __len, + const ctype<_CharT>& __ctype, + ios_base::iostate& __err) const + { + size_t __i = 0; + string __digits; + bool __testvalid = true; + char_type __c = *__beg; + while (__beg != __end && __i < __len + && __ctype.is(ctype_base::digit, __c)) + { + __digits += __ctype.narrow(__c, 0); + __c = *(++__beg); + ++__i; + } + if (__i == __len) + { + int __value = atoi(__digits.c_str()); + if (__min <= __value && __value <= __max) + __member = __value; else __testvalid = false; - - // Extract and discard separator. - if (__extract && __testvalid) - { - if (__c == __sep) - ++__beg; - else - __testvalid = false; - } - if (!__testvalid) - __err |= ios_base::failbit; - } + } + else + __testvalid = false; + if (!__testvalid) + __err |= ios_base::failbit; } // Assumptions: @@ -1439,51 +1626,12 @@ namespace std do_get_time(iter_type __beg, iter_type __end, ios_base& __io, ios_base::iostate& __err, tm* __tm) const { + _CharT __wcs[3]; + const char* __cs = "%X"; locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - - const char_type __sep = __ctype.widen(':'); - _M_extract_time(__beg, __end, __tm->tm_hour, 0, 23, __sep, true, - __ctype, __err); - _M_extract_time(__beg, __end, __tm->tm_min, 0, 59, __sep, true, - __ctype, __err); - _M_extract_time(__beg, __end, __tm->tm_sec, 0, 59, __sep, false, - __ctype, __err); - - // NB: Assume Ante- and Post-meridiem affixes not part of - // default time format. - - // NB: Some locales have a timezone component as part of the - // default time formatting. In these cases, attempt to extract - // timezone parts. - const __string_type __format = __tp._M_time_formats(); - if (__format.find(__ctype.widen('Z')) != __string_type::npos) - { - // Some valid timezone abbreviations are: - // HST, AKST, PST, MST, CST, EST, AST, NST, CET, IST, EET, CST, JST - // GMT, GMT[+-][hh:mm] - if (__ctype.is(ctype_base::space, *__beg)) - ++__beg; - - if (__ctype.is(ctype_base::upper, *__beg)) - { - int __tmp; - _M_extract_name(__beg, __end, __tmp, - __timepunct<_CharT>::_S_timezones, 14, __err); - - char_type __c = *__beg; - if (!__err && __tmp == 0 - &&(__c == __ctype.widen('-') || __c == __ctype.widen('-'))) - { - // GMT requires special effort. - _M_extract_time(__beg, __end, __tmp, 0, 23, __sep, true, - __ctype, __err); - _M_extract_time(__beg, __end, __tmp, 0, 59, __sep, false, - __ctype, __err); - } - } - } + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __ctype.widen(__cs, __cs + 3, __wcs); + _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1493,12 +1641,14 @@ namespace std _InIter time_get<_CharT, _InIter>:: do_get_date(iter_type __beg, iter_type __end, ios_base& __io, - ios_base::iostate& __err, tm* /*__tm*/) const + ios_base::iostate& __err, tm* __tm) const { + _CharT __wcs[3]; + const char* __cs = "%x"; locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __ctype.widen(__cs, __cs + 3, __wcs); + _M_extract_via_format(__beg, __end, __io, __err, __tm, __wcs); if (__beg == __end) __err |= ios_base::eofbit; return __beg; @@ -1663,39 +1813,40 @@ namespace std do_put(iter_type __s, ios_base& __io, char_type, const tm* __tm, char __format, char __mod) const { + locale __loc = __io.getloc(); + ctype<_CharT> const& __ctype = use_facet<ctype<_CharT> >(__loc); + __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); + // NB: This size is arbitrary. Should this be a data member, // initialized at construction? const size_t __maxlen = 64; - char* __res = static_cast<char*>(__builtin_alloca(__maxlen)); + char_type* __res = static_cast<char_type*>(__builtin_alloca(__maxlen)); // NB: In IEE 1003.1-200x, and perhaps other locale models, it // is possible that the format character will be longer than one // character. Possibilities include 'E' or 'O' followed by a // format charcter: if __mod is not the default argument, assume // it's a valid modifier. - char __fmt[4]; - __fmt[0] = '%'; + char_type __fmt[4]; + __fmt[0] = __ctype.widen('%'); if (!__mod) { __fmt[1] = __format; - __fmt[2] = '\0'; + __fmt[2] = char_type(); } else { __fmt[1] = __mod; __fmt[2] = __format; - __fmt[3] = '\0'; + __fmt[3] = char_type(); } - locale __loc = __io.getloc(); - __timepunct<_CharT> const& __tp = use_facet<__timepunct<_CharT> >(__loc); __tp._M_put_helper(__res, __maxlen, __fmt, __tm); // Write resulting, fully-formatted string to output iterator. - const ctype<_CharT>& __ctype = use_facet<ctype<_CharT> >(__loc); - size_t __len = strlen(__res); + size_t __len = char_traits<char_type>::length(__res); for (size_t __i = 0; __i < __len; ++__i) - __s = __ctype.widen(__res[__i]); + __s = __res[__i]; return __s; } |