/home/ntakagi/work/STLport-5.1.5/src/time_facets.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1999
00003  * Silicon Graphics Computer Systems, Inc.
00004  *
00005  * Copyright (c) 1999
00006  * Boris Fomitchev
00007  *
00008  * This material is provided "as is", with absolutely no warranty expressed
00009  * or implied. Any use is at your own risk.
00010  *
00011  * Permission to use or copy this software for any purpose is hereby granted
00012  * without fee, provided the above notices are retained on all copies.
00013  * Permission to modify the code and to distribute modified code is granted,
00014  * provided the above notices are retained, and a notice that the code was
00015  * modified is included with the above copyright notice.
00016  *
00017  */
00018 
00019 #include "stlport_prefix.h"
00020 
00021 #include <cstdio>
00022 #include <locale>
00023 #include <istream>
00024 #include <cstdio>
00025 
00026 #include "c_locale.h"
00027 
00028 _STLP_BEGIN_NAMESPACE
00029 
00030 _STLP_MOVE_TO_PRIV_NAMESPACE
00031 
00032 // default "C" values for month and day names
00033 
00034 const char default_dayname[][14] = {
00035   "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
00036   "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
00037   "Friday", "Saturday"};
00038 
00039 const char default_monthname[][24] = {
00040   "Jan", "Feb", "Mar", "Apr", "May", "Jun",
00041   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
00042   "January", "February", "March", "April", "May", "June",
00043   "July", "August", "September", "October", "November", "December"};
00044 
00045 // _Init_time_info: initialize table with
00046 // "C" values (note these are not defined in the C standard, so this
00047 // is somewhat arbitrary).
00048 
00049 void _STLP_CALL _Init_timeinfo(_Time_Info& table) {
00050   int i;
00051   for (i = 0; i < 14; ++i)
00052     table._M_dayname[i] = default_dayname[i];
00053   for (i = 0; i < 24; ++i)
00054     table._M_monthname[i] = default_monthname[i];
00055   table._M_am_pm[0] = "AM";
00056   table._M_am_pm[1] = "PM";
00057   table._M_time_format = "%H:%M:%S";
00058   table._M_date_format = "%m/%d/%y";
00059   table._M_date_time_format = "%m/%d/%y";
00060 }
00061 
00062 void _STLP_CALL _Init_timeinfo(_Time_Info& table, _Locale_time * time) {
00063   if(!time)
00064     locale::_M_throw_runtime_error();
00065 
00066   int i;
00067   for (i = 0; i < 7; ++i)
00068     table._M_dayname[i] = _Locale_abbrev_dayofweek(time, i);
00069   for (i = 0; i < 7; ++i)
00070     table._M_dayname[i+7] = _Locale_full_dayofweek(time, i);
00071   for (i = 0; i < 12; ++i)
00072     table._M_monthname[i] = _Locale_abbrev_monthname(time, i);
00073   for (i = 0; i < 12; ++i)
00074     table._M_monthname[i+12] = _Locale_full_monthname(time, i);
00075   table._M_am_pm[0] = _Locale_am_str(time);
00076   table._M_am_pm[1] = _Locale_pm_str(time);
00077   table._M_time_format = _Locale_t_fmt(time);
00078   if ( table._M_time_format == "%T" ) {
00079     table._M_time_format = "%H:%M:%S";
00080   } else if ( table._M_time_format == "%r" ) {
00081     table._M_time_format = "%I:%M:%S %p";
00082   } else if ( table._M_time_format == "%R" ) {
00083     table._M_time_format = "%H:%M";
00084   }
00085   table._M_date_format = _Locale_d_fmt(time);
00086   table._M_date_time_format = _Locale_d_t_fmt(time);
00087   table._M_long_date_format = _Locale_long_d_fmt(time);
00088   table._M_long_date_time_format = _Locale_long_d_t_fmt(time);
00089 }
00090 
00091 inline char* __subformat(const string& format, char*& buf, size_t buf_size,
00092                          const _Time_Info&  table, const tm* t) {
00093   const char * cp = format.data();
00094   const char * cp_end = cp + format.size();
00095   while (cp != cp_end) {
00096     if (*cp == '%') {
00097       char mod = 0;
00098       ++cp;
00099       if(*cp == '#') {
00100         mod = *cp; ++cp;
00101       }
00102       char *former_buf = buf;
00103       buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
00104       buf_size -= (buf - former_buf);
00105     } else
00106       *buf++ = *cp++;
00107   }
00108   return buf;
00109 }
00110 
00111 #if defined (__GNUC__)
00112 /* The number of days from the first day of the first ISO week of this
00113    year to the year day YDAY with week day WDAY.  ISO weeks start on
00114    Monday; the first ISO week has the year's first Thursday.  YDAY may
00115    be as small as YDAY_MINIMUM.  */
00116 #  define __ISO_WEEK_START_WDAY 1 /* Monday */
00117 #  define __ISO_WEEK1_WDAY 4 /* Thursday */
00118 #  define __YDAY_MINIMUM (-366)
00119 #  define __TM_YEAR_BASE 1900
00120 static int
00121 __iso_week_days(int yday, int wday) {
00122   /* Add enough to the first operand of % to make it nonnegative.  */
00123   int big_enough_multiple_of_7 = (-__YDAY_MINIMUM / 7 + 2) * 7;
00124   return (yday
00125           - (yday - wday + __ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
00126           + __ISO_WEEK1_WDAY - __ISO_WEEK_START_WDAY);
00127 }
00128 
00129 #  define __is_leap(year)\
00130   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
00131 
00132 #endif
00133 
00134 #define __hour12(hour) \
00135   (((hour) % 12 == 0) ? (12) : (hour) % 12)
00136 
00137 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
00138 #  define _STLP_SPRINTF(B, BS, F, D) sprintf(B, F, D)
00139 #else
00140 #  define _STLP_SPRINTF(B, BS, F, D) sprintf_s(B, BS, F, D)
00141 #endif
00142 
00143 char * _STLP_CALL __write_formatted_time(char* buf, size_t buf_size, char format, char modifier,
00144                                          const _Time_Info& table, const tm* t) {
00145   switch (format) {
00146     case 'a':
00147       return copy(table._M_dayname[t->tm_wday].begin(),
00148                   table._M_dayname[t->tm_wday].end(),
00149                   buf);
00150 
00151     case 'A':
00152       return copy(table._M_dayname[t->tm_wday+7].begin(),
00153                   table._M_dayname[t->tm_wday+7].end(),
00154                   buf);
00155 
00156     case 'b':
00157       return copy(table._M_monthname[t->tm_mon].begin(),
00158                   table._M_monthname[t->tm_mon].end(),
00159                   buf);
00160 
00161     case 'B':
00162       return copy(table._M_monthname[t->tm_mon+12].begin(),
00163                   table._M_monthname[t->tm_mon+12].end(),
00164                   buf);
00165 
00166     case 'c': {
00167       const char *cp = (modifier != '#') ?
00168         table._M_date_time_format.data() :
00169         table._M_long_date_time_format.data();
00170       const char* cp_end = cp +
00171         ((modifier != '#') ? table._M_date_time_format.size() :
00172          table._M_long_date_time_format.size() );
00173       char mod;
00174       while (cp != cp_end) {
00175         if (*cp == '%') {
00176           ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
00177           char *buf_pos = buf;
00178           buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
00179           buf_size -= (buf - buf_pos);
00180         }
00181         else {
00182           *buf++ = *cp++; --buf_size;
00183         }
00184       }
00185       return buf;
00186     }
00187 
00188     case 'd':
00189       _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mday);
00190       return ((long)t->tm_mday < 10L && modifier == '#')?buf+1:buf + 2;
00191 
00192     case 'e':
00193       _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday);
00194       return buf + 2;
00195 
00196     case 'H':
00197       _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_hour);
00198       return ((long)t->tm_hour < 10L && modifier == '#')?buf+1:buf + 2;
00199 
00200     case 'I':
00201       _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)__hour12(t->tm_hour));
00202       return ((long)__hour12(t->tm_hour) < 10L && modifier == '#')?buf+1:buf + 2;
00203 
00204     case 'j':
00205       return __write_integer(buf, 0, (long)((long)t->tm_yday + 1));
00206 
00207     case 'm':
00208       _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mon + 1);
00209       return ((long)(t->tm_mon + 1) < 10L && modifier == '#')?buf+1:buf + 2;
00210 
00211     case 'M':
00212       _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_min);
00213       return ((long)t->tm_min < 10L && modifier == '#')?buf+1:buf + 2;
00214 
00215     case 'p':
00216       return copy(table._M_am_pm[t->tm_hour/12].begin(),
00217                   table._M_am_pm[t->tm_hour/12].end(),
00218                   buf);
00219 
00220     case 'S': // pad with zeros
00221        _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_sec);
00222        return ((long)t->tm_sec < 10L && modifier == '#')?buf+1:buf + 2;
00223 
00224     case 'U':
00225       return __write_integer(buf, 0,
00226                              long((t->tm_yday - t->tm_wday + 7) / 7));
00227       //      break;
00228 
00229     case 'w':
00230       return __write_integer(buf, 0, (long)t->tm_wday);
00231       //      break;
00232 
00233     case 'W':
00234       return __write_integer(buf, 0,
00235                              (long)(t->tm_wday == 0 ? (t->tm_yday + 1) / 7 :
00236                                                       (t->tm_yday + 8 - t->tm_wday) / 7));
00237 
00238     case'x': {
00239       const char * cp = (modifier != '#') ? table._M_date_format.data():
00240                                             table._M_long_date_format.data();
00241       const char* cp_end = (modifier != '#') ? cp + table._M_date_format.size():
00242                                                cp + table._M_long_date_format.size();
00243       char mod;
00244       while (cp != cp_end) {
00245         if (*cp == '%') {
00246           ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
00247           char *buf_pos = buf;
00248           buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
00249           buf_size -= (buf - buf_pos);
00250         }
00251         else {
00252           *buf++ = *cp++; --buf_size;
00253         }
00254       }
00255       return buf;
00256     }
00257 
00258     case 'X': {
00259       const char * cp = table._M_time_format.data();
00260       const char* cp_end = cp + table._M_time_format.size();
00261       char mod;
00262       while (cp != cp_end) {
00263         if (*cp == '%') {
00264           ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
00265           char *buf_pos = buf;
00266           buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
00267           buf_size -= (buf - buf_pos);
00268         }
00269         else {
00270           *buf++ = *cp++; --buf_size;
00271         }
00272       }
00273       return buf;
00274     }
00275     case 'y':
00276       return __write_integer(buf, 0, (long)((long)(t->tm_year + 1900) % 100));
00277 
00278     case 'Y':
00279       return __write_integer(buf, 0, (long)((long)t->tm_year + 1900));
00280 
00281     case '%':
00282       *buf++ = '%';
00283       return buf;
00284 
00285 #if defined (__GNUC__)
00286       // fbp : at least on SUN
00287 #  if defined (_STLP_UNIX) && !defined (__linux__)
00288 #    define __USE_BSD 1
00289 #  endif
00290 
00291    /*********************************************
00292     *     JGS, handle various extensions        *
00293     *********************************************/
00294 
00295     case 'h': /* POSIX.2 extension */
00296       // same as 'b', abbrev month name
00297       return copy(table._M_monthname[t->tm_mon].begin(),
00298                   table._M_monthname[t->tm_mon].end(),
00299                   buf);
00300 
00301     case 'C': /* POSIX.2 extension */
00302       // same as 'd', the day
00303       _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday);
00304       return buf + 2;
00305 
00306     case 'D': /* POSIX.2 extension */
00307       // same as 'x'
00308       return __subformat(table._M_date_format, buf, buf_size, table, t);
00309 
00310     case 'k': /* GNU extension */
00311       _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour);
00312       return buf + 2;
00313 
00314     case 'l': /* GNU extension */
00315       _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour % 12);
00316       return buf + 2;
00317 
00318     case 'n': /* POSIX.2 extension */
00319       *buf++ = '\n';
00320       return buf;
00321 
00322     case 'R': /* GNU extension */
00323       return __subformat("%H:%M", buf, buf_size, table, t);
00324 
00325     case 'r': /* POSIX.2 extension */
00326       return __subformat("%I:%M:%S %p", buf, buf_size, table, t);
00327 
00328     case 'T': /* POSIX.2 extension.  */
00329       return __subformat("%H:%M:%S", buf, buf_size, table, t);
00330 
00331     case 't': /* POSIX.2 extension.  */
00332       *buf++ = '\t';
00333       return buf;
00334 
00335     case 'u': /* POSIX.2 extension.  */
00336       return __write_integer(buf, 0, long((t->tm_wday - 1 + 7)) % 7 + 1);
00337 
00338     case 's': {
00339       time_t __t;
00340       __t = mktime(__CONST_CAST(tm*, t));
00341       return __write_integer(buf, 0, (long)__t );
00342     }
00343     case 'g': /* GNU extension */
00344     case 'G': {
00345       int year = t->tm_year + __TM_YEAR_BASE;
00346       int days = __iso_week_days (t->tm_yday, t->tm_wday);
00347       if (days < 0) {
00348         /* This ISO week belongs to the previous year.  */
00349         year--;
00350         days = __iso_week_days (t->tm_yday + (365 + __is_leap (year)), t->tm_wday);
00351       }
00352       else {
00353         int d = __iso_week_days (t->tm_yday - (365 + __is_leap (year)), t->tm_wday);
00354         if (0 <= d) {
00355           /* This ISO week belongs to the next year.  */
00356           ++year;
00357           days = d;
00358         }
00359       }
00360       switch (format) {
00361       case 'g':
00362         return __write_integer(buf, 0, (long)(year % 100 + 100) % 100);
00363       case 'G':
00364         return __write_integer(buf, 0, (long)year);
00365       default:
00366         return __write_integer(buf, 0, (long)days / 7 + 1);
00367       }
00368     }
00369 
00370 #  if defined (_STLP_USE_GLIBC) && ! defined (__CYGWIN__)
00371     case 'z':   /* GNU extension.  */
00372       if (t->tm_isdst < 0)
00373         break;
00374       {
00375         int diff;
00376 #    if defined (__USE_BSD) || defined (__BEOS__)
00377         diff = t->tm_gmtoff;
00378 #    else
00379         diff = t->__tm_gmtoff;
00380 #    endif
00381         if (diff < 0) {
00382           *buf++ = '-';
00383           diff = -diff;
00384         } else
00385           *buf++ = '+';
00386         diff /= 60;
00387         _STLP_SPRINTF(buf, buf_size, "%.4d", (diff / 60) * 100 + diff % 60);
00388         return buf + 4;
00389       }
00390 #  endif /* __GLIBC__ */
00391 #endif /* __GNUC__ */
00392 
00393     default:
00394       //      return buf;
00395       break;
00396   }
00397   return buf;
00398 }
00399 
00400 time_base::dateorder _STLP_CALL
00401 __get_date_order(_Locale_time* time) {
00402   const char * fmt = _Locale_d_fmt(time);
00403   char first, second, third;
00404 
00405   while (*fmt != 0 && *fmt != '%') ++fmt;
00406   if (*fmt == 0)
00407     return time_base::no_order;
00408   first = *++fmt;
00409   while (*fmt != 0 && *fmt != '%') ++fmt;
00410   if (*fmt == 0)
00411     return time_base::no_order;
00412   second = *++fmt;
00413   while (*fmt != 0 && *fmt != '%') ++fmt;
00414   if (*fmt == 0)
00415     return time_base::no_order;
00416   third = *++fmt;
00417 
00418   switch (first) {
00419     case 'd':
00420       return (second == 'm' && third == 'y') ? time_base::dmy
00421                                              : time_base::no_order;
00422     case 'm':
00423       return (second == 'd' && third == 'y') ? time_base::mdy
00424                                              : time_base::no_order;
00425     case 'y':
00426       switch (second) {
00427         case 'd':
00428           return third == 'm' ? time_base::ydm : time_base::no_order;
00429         case 'm':
00430           return third == 'd' ? time_base::ymd : time_base::no_order;
00431         default:
00432           return time_base::no_order;
00433       }
00434     default:
00435       return time_base::no_order;
00436   }
00437 }
00438 
00439 _STLP_MOVE_TO_STD_NAMESPACE
00440 
00441 #if !defined(_STLP_NO_FORCE_INSTANTIATE)
00442 template class time_get<char, istreambuf_iterator<char, char_traits<char> > >;
00443 template class time_put<char, ostreambuf_iterator<char, char_traits<char> > >;
00444 
00445 #  if !defined (_STLP_NO_WCHAR_T)
00446 template class time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
00447 template class time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
00448 #  endif
00449 
00450 #endif
00451 
00452 _STLP_END_NAMESPACE



Generated on Mon Mar 10 15:32:17 2008 by  doxygen 1.5.1