[BACK]Return to strftime.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / time

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/libc/time/strftime.c between version 1.43 and 1.44

version 1.43, 2019/04/04 19:27:28 version 1.44, 2019/04/05 21:27:44
Line 87  __weak_alias(strftime_z, _strftime_z)
Line 87  __weak_alias(strftime_z, _strftime_z)
 enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };  enum warn { IN_NONE, IN_SOME, IN_THIS, IN_ALL };
   
 static char *   _add(const char *, char *, const char *);  static char *   _add(const char *, char *, const char *);
 static char *   _conv(int, const char *, char *, const char *);  static char *   _conv(int, const char *, char *, const char *, locale_t);
 static char *   _fmt(const timezone_t, const char *, const struct tm *, char *,  static char *   _fmt(const timezone_t, const char *, const struct tm *, char *,
                         const char *, enum warn *, locale_t);                          const char *, enum warn *, locale_t);
 static char *   _yconv(int, int, bool, bool, char *, const char *);  static char *   _yconv(int, int, bool, bool, char *, const char *, locale_t);
   
 #ifndef YEAR_2000_NAME  #ifndef YEAR_2000_NAME
 #define YEAR_2000_NAME  "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"  #define YEAR_2000_NAME  "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
 #endif /* !defined YEAR_2000_NAME */  #endif /* !defined YEAR_2000_NAME */
   
   #define IN_NONE 0
   #define IN_SOME 1
   #define IN_THIS 2
   #define IN_ALL  3
   
   #define PAD_DEFAULT     0
   #define PAD_LESS        1
   #define PAD_SPACE       2
   #define PAD_ZERO        3
   
   static const char fmt_padding[][4][5] = {
           /* DEFAULT,     LESS,   SPACE,  ZERO */
   #define PAD_FMT_MONTHDAY        0
   #define PAD_FMT_HMS             0
   #define PAD_FMT_CENTURY         0
   #define PAD_FMT_SHORTYEAR       0
   #define PAD_FMT_MONTH           0
   #define PAD_FMT_WEEKOFYEAR      0
   #define PAD_FMT_DAYOFMONTH      0
           { "%02d",       "%d",   "%2d",  "%02d" },
   #define PAD_FMT_SDAYOFMONTH     1
   #define PAD_FMT_SHMS            1
           { "%2d",        "%d",   "%2d",  "%02d" },
   #define PAD_FMT_DAYOFYEAR       2
           { "%03d",       "%d",   "%3d",  "%03d" },
   #define PAD_FMT_YEAR            3
           { "%04d",       "%d",   "%4d",  "%04d" }
   };
   
 size_t  size_t
 strftime_z(const timezone_t sp, char * __restrict s, size_t maxsize,  strftime_z(const timezone_t sp, char * __restrict s, size_t maxsize,
     const char * __restrict format, const struct tm * __restrict t)      const char * __restrict format, const struct tm * __restrict t)
Line 143  static char *
Line 172  static char *
 _fmt(const timezone_t sp, const char *format, const struct tm *t, char *pt,  _fmt(const timezone_t sp, const char *format, const struct tm *t, char *pt,
      const char *ptlim, enum warn *warnp, locale_t loc)       const char *ptlim, enum warn *warnp, locale_t loc)
 {  {
           int Ealternative, Oalternative, PadIndex;
           _TimeLocale *tptr = _TIME_LOCALE(loc);
   
         for ( ; *format; ++format) {          for ( ; *format; ++format) {
                 if (*format == '%') {                  if (*format == '%') {
                           Ealternative = 0;
                           Oalternative = 0;
                           PadIndex = PAD_DEFAULT;
 label:  label:
                         switch (*++format) {                          switch (*++format) {
                         case '\0':                          case '\0':
Line 153  label:
Line 188  label:
                         case 'A':                          case 'A':
                                 pt = _add((t->tm_wday < 0 ||                                  pt = _add((t->tm_wday < 0 ||
                                         t->tm_wday >= DAYSPERWEEK) ?                                          t->tm_wday >= DAYSPERWEEK) ?
                                         "?" : _TIME_LOCALE(loc)->day[t->tm_wday],                                          "?" : tptr->day[t->tm_wday],
                                         pt, ptlim);                                          pt, ptlim);
                                 continue;                                  continue;
                         case 'a':                          case 'a':
                                 pt = _add((t->tm_wday < 0 ||                                  pt = _add((t->tm_wday < 0 ||
                                         t->tm_wday >= DAYSPERWEEK) ?                                          t->tm_wday >= DAYSPERWEEK) ?
                                         "?" : _TIME_LOCALE(loc)->abday[t->tm_wday],                                          "?" : tptr->abday[t->tm_wday],
                                         pt, ptlim);                                          pt, ptlim);
                                 continue;                                  continue;
                         case 'B':                          case 'B':
                                 pt = _add((t->tm_mon < 0 ||                                  pt = _add((t->tm_mon < 0 ||
                                         t->tm_mon >= MONSPERYEAR) ?                                          t->tm_mon >= MONSPERYEAR) ?
                                         "?" : _TIME_LOCALE(loc)->mon[t->tm_mon],                                          "?" :
                                           /* no alt_month in _TimeLocale */
                                           (Oalternative ? tptr->mon/*alt_month*/:
                                           tptr->mon)[t->tm_mon],
                                         pt, ptlim);                                          pt, ptlim);
                                 continue;                                  continue;
                         case 'b':                          case 'b':
                         case 'h':                          case 'h':
                                 pt = _add((t->tm_mon < 0 ||                                  pt = _add((t->tm_mon < 0 ||
                                         t->tm_mon >= MONSPERYEAR) ?                                          t->tm_mon >= MONSPERYEAR) ?
                                         "?" : _TIME_LOCALE(loc)->abmon[t->tm_mon],                                          "?" : tptr->abmon[t->tm_mon],
                                         pt, ptlim);                                          pt, ptlim);
                                 continue;                                  continue;
                         case 'C':                          case 'C':
Line 184  label:
Line 222  label:
                                 ** (ado, 1993-05-24)                                  ** (ado, 1993-05-24)
                                 */                                  */
                                 pt = _yconv(t->tm_year, TM_YEAR_BASE,                                  pt = _yconv(t->tm_year, TM_YEAR_BASE,
                                             true, false, pt, ptlim);                                              true, false, pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'c':                          case 'c':
                                 {                                  {
                                 enum warn warn2 = IN_SOME;                                  enum warn warn2 = IN_SOME;
   
                                 pt = _fmt(sp, _TIME_LOCALE(loc)->c_fmt, t, pt,                                  pt = _fmt(sp, tptr->c_fmt, t, pt,
                                     ptlim, &warn2, loc);                                      ptlim, &warn2, loc);
                                 if (warn2 == IN_ALL)                                  if (warn2 == IN_ALL)
                                         warn2 = IN_THIS;                                          warn2 = IN_THIS;
Line 203  label:
Line 241  label:
                                     loc);                                      loc);
                                 continue;                                  continue;
                         case 'd':                          case 'd':
                                 pt = _conv(t->tm_mday, "%02d", pt, ptlim);                                  pt = _conv(t->tm_mday,
                                       fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'E':                          case 'E':
                                   if (Ealternative || Oalternative)
                                           break;
                                   Ealternative++;
                                   goto label;
                         case 'O':                          case 'O':
                                 /*                                  /*
                                 ** Locale modifiers of C99 and later.                                  ** Locale modifiers of C99 and later.
Line 216  label:
Line 260  label:
                                 ** are supposed to provide alternative                                  ** are supposed to provide alternative
                                 ** representations.                                  ** representations.
                                 */                                  */
                                   if (Ealternative || Oalternative)
                                           break;
                                   Oalternative++;
                                 goto label;                                  goto label;
                         case 'e':                          case 'e':
                                 pt = _conv(t->tm_mday, "%2d", pt, ptlim);                                  pt = _conv(t->tm_mday,
                                       fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'F':                          case 'F':
                                 pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp,                                  pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp,
                                     loc);                                      loc);
                                 continue;                                  continue;
                         case 'H':                          case 'H':
                                 pt = _conv(t->tm_hour, "%02d", pt, ptlim);                                  pt = _conv(t->tm_hour,
                                       fmt_padding[PAD_FMT_HMS][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'I':                          case 'I':
                                 pt = _conv((t->tm_hour % 12) ?                                  pt = _conv((t->tm_hour % 12) ?
                                         (t->tm_hour % 12) : 12,                                      (t->tm_hour % 12) : 12,
                                         "%02d", pt, ptlim);                                      fmt_padding[PAD_FMT_HMS][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'j':                          case 'j':
                                 pt = _conv(t->tm_yday + 1, "%03d", pt, ptlim);                                  pt = _conv(t->tm_yday + 1,
                                       fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'k':                          case 'k':
                                 /*                                  /*
Line 246  label:
Line 300  label:
                                 ** "%l" have been swapped.                                  ** "%l" have been swapped.
                                 ** (ado, 1993-05-24)                                  ** (ado, 1993-05-24)
                                 */                                  */
                                 pt = _conv(t->tm_hour, "%2d", pt, ptlim);                                  pt = _conv(t->tm_hour,
                                       fmt_padding[PAD_FMT_SHMS][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
 #ifdef KITCHEN_SINK  #ifdef KITCHEN_SINK
                         case 'K':                          case 'K':
Line 268  label:
Line 324  label:
                                 */                                  */
                                 pt = _conv((t->tm_hour % 12) ?                                  pt = _conv((t->tm_hour % 12) ?
                                         (t->tm_hour % 12) : 12,                                          (t->tm_hour % 12) : 12,
                                         "%2d", pt, ptlim);                                          fmt_padding[PAD_FMT_SHMS][PadIndex],
                                           pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'M':                          case 'M':
                                 pt = _conv(t->tm_min, "%02d", pt, ptlim);                                  pt = _conv(t->tm_min,
                                       fmt_padding[PAD_FMT_HMS][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'm':                          case 'm':
                                 pt = _conv(t->tm_mon + 1, "%02d", pt, ptlim);                                  pt = _conv(t->tm_mon + 1,
                                       fmt_padding[PAD_FMT_MONTH][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'n':                          case 'n':
                                 pt = _add("\n", pt, ptlim);                                  pt = _add("\n", pt, ptlim);
                                 continue;                                  continue;
                         case 'p':                          case 'p':
                                 pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?                                  pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
                                         _TIME_LOCALE(loc)->am_pm[1] :                                          tptr->am_pm[1] :
                                         _TIME_LOCALE(loc)->am_pm[0],                                          tptr->am_pm[0],
                                         pt, ptlim);                                          pt, ptlim);
                                 continue;                                  continue;
                         case 'R':                          case 'R':
Line 290  label:
Line 351  label:
                                     loc);                                      loc);
                                 continue;                                  continue;
                         case 'r':                          case 'r':
                                 pt = _fmt(sp, _TIME_LOCALE(loc)->t_fmt_ampm, t,                                  pt = _fmt(sp, tptr->t_fmt_ampm, t,
                                     pt, ptlim, warnp, loc);                                      pt, ptlim, warnp, loc);
                                 continue;                                  continue;
                         case 'S':                          case 'S':
                                 pt = _conv(t->tm_sec, "%02d", pt, ptlim);                                  pt = _conv(t->tm_sec,
                                       fmt_padding[PAD_FMT_HMS][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 's':                          case 's':
                                 {                                  {
Line 323  label:
Line 386  label:
                                 continue;                                  continue;
                         case 'U':                          case 'U':
                                 pt = _conv((t->tm_yday + DAYSPERWEEK -                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
                                         t->tm_wday) / DAYSPERWEEK,                                      t->tm_wday) / DAYSPERWEEK,
                                         "%02d", pt, ptlim);                                      fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'u':                          case 'u':
                                 /*                                  /*
Line 335  label:
Line 399  label:
                                 */                                  */
                                 pt = _conv((t->tm_wday == 0) ?                                  pt = _conv((t->tm_wday == 0) ?
                                         DAYSPERWEEK : t->tm_wday,                                          DAYSPERWEEK : t->tm_wday,
                                         "%d", pt, ptlim);                                          "%d", pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'V':       /* ISO 8601 week number */                          case 'V':       /* ISO 8601 week number */
                         case 'G':       /* ISO 8601 year (four digits) */                          case 'G':       /* ISO 8601 year (four digits) */
Line 415  label:
Line 479  label:
                                                         w = 53;                                                          w = 53;
 #endif /* defined XPG4_1994_04_09 */  #endif /* defined XPG4_1994_04_09 */
                                         if (*format == 'V')                                          if (*format == 'V')
                                                 pt = _conv(w, "%02d",                                                  pt = _conv(w,
                                                         pt, ptlim);                                                      fmt_padding[
                                                       PAD_FMT_WEEKOFYEAR][
                                                       PadIndex], pt, ptlim, loc);
                                         else if (*format == 'g') {                                          else if (*format == 'g') {
                                                 *warnp = IN_ALL;                                                  *warnp = IN_ALL;
                                                 pt = _yconv(year, base,                                                  pt = _yconv(year, base,
                                                         false, true,                                                          false, true,
                                                         pt, ptlim);                                                          pt, ptlim, loc);
                                         } else  pt = _yconv(year, base,                                          } else  pt = _yconv(year, base,
                                                         true, true,                                                          true, true,
                                                         pt, ptlim);                                                          pt, ptlim, loc);
                                 }                                  }
                                 continue;                                  continue;
                         case 'v':                          case 'v':
Line 438  label:
Line 504  label:
                                 continue;                                  continue;
                         case 'W':                          case 'W':
                                 pt = _conv((t->tm_yday + DAYSPERWEEK -                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
                                         (t->tm_wday ?                                      (t->tm_wday ?
                                         (t->tm_wday - 1) :                                      (t->tm_wday - 1) :
                                         (DAYSPERWEEK - 1))) / DAYSPERWEEK,                                      (DAYSPERWEEK - 1))) / DAYSPERWEEK,
                                         "%02d", pt, ptlim);                                      fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex],
                                       pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'w':                          case 'w':
                                 pt = _conv(t->tm_wday, "%d", pt, ptlim);                                  pt = _conv(t->tm_wday, "%d", pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'X':                          case 'X':
                                 pt = _fmt(sp, _TIME_LOCALE(loc)->t_fmt, t, pt,                                  pt = _fmt(sp, tptr->t_fmt, t, pt,
                                     ptlim, warnp, loc);                                      ptlim, warnp, loc);
                                 continue;                                  continue;
                         case 'x':                          case 'x':
                                 {                                  {
                                 enum warn warn2 = IN_SOME;                                  enum warn warn2 = IN_SOME;
   
                                 pt = _fmt(sp, _TIME_LOCALE(loc)->d_fmt, t, pt,                                  pt = _fmt(sp, tptr->d_fmt, t, pt,
                                     ptlim, &warn2, loc);                                      ptlim, &warn2, loc);
                                 if (warn2 == IN_ALL)                                  if (warn2 == IN_ALL)
                                         warn2 = IN_THIS;                                          warn2 = IN_THIS;
Line 466  label:
Line 533  label:
                                 *warnp = IN_ALL;                                  *warnp = IN_ALL;
                                 pt = _yconv(t->tm_year, TM_YEAR_BASE,                                  pt = _yconv(t->tm_year, TM_YEAR_BASE,
                                         false, true,                                          false, true,
                                         pt, ptlim);                                          pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'Y':                          case 'Y':
                                 pt = _yconv(t->tm_year, TM_YEAR_BASE,                                  pt = _yconv(t->tm_year, TM_YEAR_BASE,
                                         true, true,                                          true, true,
                                         pt, ptlim);                                          pt, ptlim, loc);
                                 continue;                                  continue;
                         case 'Z':                          case 'Z':
 #ifdef TM_ZONE  #ifdef TM_ZONE
Line 583  label:
Line 650  label:
                                 diff = (diff / MINSPERHOUR) * 100 +                                  diff = (diff / MINSPERHOUR) * 100 +
                                         (diff % MINSPERHOUR);                                          (diff % MINSPERHOUR);
                                 _DIAGASSERT(__type_fit(int, diff));                                  _DIAGASSERT(__type_fit(int, diff));
                                 pt = _conv((int)diff, "%04d", pt, ptlim);                                  pt = _conv((int)diff,
                                       fmt_padding[PAD_FMT_YEAR][PadIndex],
                                       pt, ptlim, loc);
                                 }                                  }
 #endif  #endif
                                 continue;                                  continue;
 #if 0  
                         case '+':                          case '+':
                                 pt = _fmt(sp, _TIME_LOCALE(loc)->date_fmt, t,  #ifdef notyet
                                   /* XXX: no date_fmt in _TimeLocale */
                                   pt = _fmt(sp, tptr->date_fmt, t,
                                       pt, ptlim, warnp, loc);
   #else
                                   pt = _fmt(sp, "%a %b %e %H:%M:%S %Z %Y", t,
                                     pt, ptlim, warnp, loc);                                      pt, ptlim, warnp, loc);
                                 continue;  
 #endif  #endif
                                   continue;
                           case '-':
                                   if (PadIndex != PAD_DEFAULT)
                                           break;
                                   PadIndex = PAD_LESS;
                                   goto label;
                           case '_':
                                   if (PadIndex != PAD_DEFAULT)
                                           break;
                                   PadIndex = PAD_SPACE;
                                   goto label;
                           case '0':
                                   if (PadIndex != PAD_DEFAULT)
                                           break;
                                   PadIndex = PAD_ZERO;
                                   goto label;
                         case '%':                          case '%':
                         /*                          /*
                         ** X311J/88-090 (4.12.3.5): if conversion char is                          ** X311J/88-090 (4.12.3.5): if conversion char is
Line 638  strftime_l(char * __restrict s, size_t m
Line 726  strftime_l(char * __restrict s, size_t m
 }  }
   
 static char *  static char *
 _conv(int n, const char *format, char *pt, const char *ptlim)  _conv(int n, const char *format, char *pt, const char *ptlim, locale_t loc)
 {  {
         char    buf[INT_STRLEN_MAXIMUM(int) + 1];          char    buf[INT_STRLEN_MAXIMUM(int) + 1];
   
         (void) snprintf(buf, sizeof(buf), format, n);          (void) snprintf_l(buf, sizeof(buf), loc, format, n);
         return _add(buf, pt, ptlim);          return _add(buf, pt, ptlim);
 }  }
   
Line 664  _add(const char *str, char *pt, const ch
Line 752  _add(const char *str, char *pt, const ch
   
 static char *  static char *
 _yconv(int a, int b, bool convert_top, bool convert_yy,  _yconv(int a, int b, bool convert_top, bool convert_yy,
     char *pt, const char * ptlim)      char *pt, const char * ptlim, locale_t loc)
 {  {
         int     lead;          int     lead;
         int     trail;          int     trail;
Line 683  _yconv(int a, int b, bool convert_top, b
Line 771  _yconv(int a, int b, bool convert_top, b
         if (convert_top) {          if (convert_top) {
                 if (lead == 0 && trail < 0)                  if (lead == 0 && trail < 0)
                         pt = _add("-0", pt, ptlim);                          pt = _add("-0", pt, ptlim);
                 else    pt = _conv(lead, "%02d", pt, ptlim);                  else    pt = _conv(lead, "%02d", pt, ptlim, loc);
         }          }
         if (convert_yy)          if (convert_yy)
                 pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);                  pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim,
                       loc);
         return pt;          return pt;
 }  }

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.44

CVSweb <webmaster@jp.NetBSD.org>