Print this page
2964 need POSIX 2008 locale object support
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/strftime.c
          +++ new/usr/src/lib/libc/port/locale/strftime.c
   1    1  /*
        2 + * Copyright 2013 Garrett D'Amore <garrett@damore.org>
   2    3   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3    4   * Copyright (c) 1989 The Regents of the University of California.
   4    5   * All rights reserved.
   5    6   *
   6    7   * Redistribution and use in source and binary forms are permitted
   7    8   * provided that the above copyright notice and this paragraph are
   8    9   * duplicated in all such forms and that any documentation,
   9   10   * advertising materials, and other materials related to such
  10   11   * distribution and use acknowledge that the software was developed
  11   12   * by the University of California, Berkeley. The name of the
↓ open down ↓ 3 lines elided ↑ open up ↑
  15   16   * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  16   17   * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  17   18   */
  18   19  
  19   20  #include "lint.h"
  20   21  #include "tzfile.h"
  21   22  #include <fcntl.h>
  22   23  #include <sys/stat.h>
  23   24  #include <string.h>
  24   25  #include <stdio.h>
       26 +#include <locale.h>
  25   27  #include "timelocal.h"
       28 +#include "localeimpl.h"
  26   29  
  27   30  static char *_add(const char *, char *, const char *);
  28   31  static char *_conv(int, const char *, char *, const char *);
  29      -static char *_fmt(const char *, const struct tm *, char *, const char * const);
       32 +static char *_fmt(locale_t, const char *, const struct tm *, char *,
       33 +    const char * const);
  30   34  static char *_yconv(int, int, int, int, char *, const char *);
  31   35  
  32   36  extern char *tzname[];
  33   37  
  34   38  #define IN_NONE 0
  35   39  #define IN_SOME 1
  36   40  #define IN_THIS 2
  37   41  #define IN_ALL  3
  38   42  
  39   43  #define PAD_DEFAULT     0
↓ open down ↓ 15 lines elided ↑ open up ↑
  55   59  #define PAD_FMT_SHMS            1
  56   60          { "%2d",        "%d",   "%2d",  "%02d" },
  57   61  #define PAD_FMT_DAYOFYEAR       2
  58   62          { "%03d",       "%d",   "%3d",  "%03d" },
  59   63  #define PAD_FMT_YEAR            3
  60   64          { "%04d",       "%d",   "%4d",  "%04d" }
  61   65  };
  62   66  
  63   67  
  64   68  size_t
  65      -strftime(char *_RESTRICT_KYWD s, size_t maxsize,
  66      -    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
       69 +strftime_l(char *_RESTRICT_KYWD s, size_t maxsize,
       70 +    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t,
       71 +    locale_t loc)
  67   72  {
  68   73          char *p;
  69   74  
  70   75          tzset();
  71      -        p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
       76 +        p = _fmt(loc, ((format == NULL) ? "%c" : format), t, s, s + maxsize);
  72   77          if (p == s + maxsize)
  73   78                  return (0);
  74   79          *p = '\0';
  75   80          return (p - s);
  76   81  }
  77   82  
       83 +size_t
       84 +strftime(char *_RESTRICT_KYWD s, size_t maxsize,
       85 +    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
       86 +{
       87 +        return (strftime_l(s, maxsize, format, t, uselocale(NULL)));
       88 +}
       89 +
  78   90  static char *
  79      -_fmt(const char *format, const struct tm *t, char *pt, const char * const ptlim)
       91 +_fmt(locale_t loc, const char *format, const struct tm *t, char *pt,
       92 +    const char * const ptlim)
  80   93  {
  81   94          int Ealternative, Oalternative, PadIndex;
  82      -        struct lc_time_T *tptr = __get_current_time_locale();
       95 +        const struct lc_time *tptr = loc->time;
  83   96  
  84   97  #define PADDING(x)      fmt_padding[x][PadIndex]
  85   98  
  86   99          for (; *format; ++format) {
  87  100                  if (*format == '%') {
  88  101                          Ealternative = 0;
  89  102                          Oalternative = 0;
  90  103                          PadIndex         = PAD_DEFAULT;
  91  104  label:
  92  105                          switch (*++format) {
↓ open down ↓ 30 lines elided ↑ open up ↑
 123  136                                   * %C used to do a...
 124  137                                   *      _fmt("%a %b %e %X %Y", t);
 125  138                                   * ...whereas now POSIX 1003.2 calls for
 126  139                                   * something completely different.
 127  140                                   * (ado, 1993-05-24)
 128  141                                   */
 129  142                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
 130  143                                      pt, ptlim);
 131  144                                  continue;
 132  145                          case 'c':
 133      -                                pt = _fmt(tptr->c_fmt, t, pt, ptlim);
      146 +                                pt = _fmt(loc, tptr->c_fmt, t, pt, ptlim);
 134  147                                  continue;
 135  148                          case 'D':
 136      -                                pt = _fmt("%m/%d/%y", t, pt, ptlim);
      149 +                                pt = _fmt(loc, "%m/%d/%y", t, pt, ptlim);
 137  150                                  continue;
 138  151                          case 'd':
 139  152                                  pt = _conv(t->tm_mday,
 140  153                                      PADDING(PAD_FMT_DAYOFMONTH), pt, ptlim);
 141  154                                  continue;
 142  155                          case 'E':
 143  156                                  if (Ealternative || Oalternative)
 144  157                                          break;
 145  158                                  Ealternative++;
 146  159                                  goto label;
↓ open down ↓ 9 lines elided ↑ open up ↑
 156  169                                   */
 157  170                                  if (Ealternative || Oalternative)
 158  171                                          break;
 159  172                                  Oalternative++;
 160  173                                  goto label;
 161  174                          case 'e':
 162  175                                  pt = _conv(t->tm_mday,
 163  176                                      PADDING(PAD_FMT_SDAYOFMONTH), pt, ptlim);
 164  177                                  continue;
 165  178                          case 'F':
 166      -                                pt = _fmt("%Y-%m-%d", t, pt, ptlim);
      179 +                                pt = _fmt(loc, "%Y-%m-%d", t, pt, ptlim);
 167  180                                  continue;
 168  181                          case 'H':
 169  182                                  pt = _conv(t->tm_hour, PADDING(PAD_FMT_HMS),
 170  183                                      pt, ptlim);
 171  184                                  continue;
 172  185                          case 'I':
 173  186                                  pt = _conv((t->tm_hour % 12) ?
 174  187                                      (t->tm_hour % 12) : 12,
 175  188                                      PADDING(PAD_FMT_HMS), pt, ptlim);
 176  189                                  continue;
↓ open down ↓ 39 lines elided ↑ open up ↑
 216  229                                      pt, ptlim);
 217  230                                  continue;
 218  231                          case 'n':
 219  232                                  pt = _add("\n", pt, ptlim);
 220  233                                  continue;
 221  234                          case 'p':
 222  235                                  pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
 223  236                                      tptr->pm : tptr->am, pt, ptlim);
 224  237                                  continue;
 225  238                          case 'R':
 226      -                                pt = _fmt("%H:%M", t, pt, ptlim);
      239 +                                pt = _fmt(loc, "%H:%M", t, pt, ptlim);
 227  240                                  continue;
 228  241                          case 'r':
 229      -                                pt = _fmt(tptr->ampm_fmt, t, pt, ptlim);
      242 +                                pt = _fmt(loc, tptr->ampm_fmt, t, pt, ptlim);
 230  243                                  continue;
 231  244                          case 'S':
 232  245                                  pt = _conv(t->tm_sec, PADDING(PAD_FMT_HMS),
 233  246                                      pt, ptlim);
 234  247                                  continue;
 235  248  
 236  249                          case 's':
 237  250                          {
 238  251                                  struct tm tm;
 239  252                                  char *buf;
 240  253  
 241  254                                  tm = *t;
 242  255                                  (void) asprintf(&buf, "%ld", mktime(&tm));
 243  256                                  pt = _add(buf, pt, ptlim);
 244  257                                  continue;
 245  258                          }
 246  259  
 247  260                          case 'T':
 248      -                                pt = _fmt("%H:%M:%S", t, pt, ptlim);
      261 +                                pt = _fmt(loc, "%H:%M:%S", t, pt, ptlim);
 249  262                                  continue;
 250  263                          case 't':
 251  264                                  pt = _add("\t", pt, ptlim);
 252  265                                  continue;
 253  266                          case 'U':
 254  267                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
 255  268                                      t->tm_wday) / DAYSPERWEEK,
 256  269                                      PADDING(PAD_FMT_WEEKOFYEAR),
 257  270                                      pt, ptlim);
 258  271                                  continue;
↓ open down ↓ 91 lines elided ↑ open up ↑
 350  363                                          pt = _yconv(year, base, 1, 1,
 351  364                                              pt, ptlim);
 352  365                          }
 353  366                                  continue;
 354  367                          case 'v':
 355  368                                  /*
 356  369                                   * From Arnold Robbins' strftime version 3.0:
 357  370                                   * "date as dd-bbb-YYYY"
 358  371                                   * (ado, 1993-05-24)
 359  372                                   */
 360      -                                pt = _fmt("%e-%b-%Y", t, pt, ptlim);
      373 +                                pt = _fmt(loc, "%e-%b-%Y", t, pt, ptlim);
 361  374                                  continue;
 362  375                          case 'W':
 363  376                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
 364  377                                      (t->tm_wday ?
 365  378                                      (t->tm_wday - 1) :
 366  379                                      (DAYSPERWEEK - 1))) / DAYSPERWEEK,
 367  380                                      PADDING(PAD_FMT_WEEKOFYEAR),
 368  381                                      pt, ptlim);
 369  382                                  continue;
 370  383                          case 'w':
 371  384                                  pt = _conv(t->tm_wday, "%d", pt, ptlim);
 372  385                                  continue;
 373  386                          case 'X':
 374      -                                pt = _fmt(tptr->X_fmt, t, pt, ptlim);
      387 +                                pt = _fmt(loc, tptr->X_fmt, t, pt, ptlim);
 375  388                                  continue;
 376  389                          case 'x':
 377      -                                pt = _fmt(tptr->x_fmt, t, pt, ptlim);
      390 +                                pt = _fmt(loc, tptr->x_fmt, t, pt, ptlim);
 378  391                                  continue;
 379  392                          case 'y':
 380  393                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
 381  394                                      pt, ptlim);
 382  395                                  continue;
 383  396                          case 'Y':
 384  397                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
 385  398                                      pt, ptlim);
 386  399                                  continue;
 387  400                          case 'Z':
↓ open down ↓ 43 lines elided ↑ open up ↑
 431  444                                          sign = "+";
 432  445                                  pt = _add(sign, pt, ptlim);
 433  446                                  diff /= SECSPERMIN;
 434  447                                  diff = (diff / MINSPERHOUR) * 100 +
 435  448                                      (diff % MINSPERHOUR);
 436  449                                  pt = _conv(diff, PADDING(PAD_FMT_YEAR),
 437  450                                      pt, ptlim);
 438  451                                  }
 439  452                                  continue;
 440  453                          case '+':
 441      -                                pt = _fmt(tptr->date_fmt, t, pt, ptlim);
      454 +                                pt = _fmt(loc, tptr->date_fmt, t, pt, ptlim);
 442  455                                  continue;
 443  456                          case '-':
 444  457                                  if (PadIndex != PAD_DEFAULT)
 445  458                                          break;
 446  459                                  PadIndex = PAD_LESS;
 447  460                                  goto label;
 448  461                          case '_':
 449  462                                  if (PadIndex != PAD_DEFAULT)
 450  463                                          break;
 451  464                                  PadIndex = PAD_SPACE;
↓ open down ↓ 76 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX