Print this page
2964 need POSIX 2008 locale object support

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    2   * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
   3    3   * Copyright (c) 1989 The Regents of the University of California.
   4    4   * All rights reserved.
   5    5   *
        6 + * Copyright (c) 2011 The FreeBSD Foundation
        7 + * All rights reserved.
        8 + * Portions of this software were developed by David Chisnall
        9 + * under sponsorship from the FreeBSD Foundation.
       10 + *
   6   11   * Redistribution and use in source and binary forms are permitted
   7   12   * provided that the above copyright notice and this paragraph are
   8   13   * duplicated in all such forms and that any documentation,
   9   14   * advertising materials, and other materials related to such
  10   15   * distribution and use acknowledge that the software was developed
  11   16   * by the University of California, Berkeley. The name of the
  12   17   * University may not be used to endorse or promote products derived
  13   18   * from this software without specific prior written permission.
  14   19   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  15   20   * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
↓ open down ↓ 3 lines elided ↑ open up ↑
  19   24  #include "lint.h"
  20   25  #include "tzfile.h"
  21   26  #include <fcntl.h>
  22   27  #include <sys/stat.h>
  23   28  #include <string.h>
  24   29  #include <stdio.h>
  25   30  #include "timelocal.h"
  26   31  
  27   32  static char *_add(const char *, char *, const char *);
  28   33  static char *_conv(int, const char *, char *, const char *);
  29      -static char *_fmt(const char *, const struct tm *, char *, const char * const);
       34 +static char *_fmt(const char *, const struct tm *, char *, const char * const,
       35 +    int *, locale_t);
  30   36  static char *_yconv(int, int, int, int, char *, const char *);
  31   37  
  32   38  extern char *tzname[];
  33   39  
  34   40  #define IN_NONE 0
  35   41  #define IN_SOME 1
  36   42  #define IN_THIS 2
  37   43  #define IN_ALL  3
  38   44  
  39   45  #define PAD_DEFAULT     0
↓ open down ↓ 15 lines elided ↑ open up ↑
  55   61  #define PAD_FMT_SHMS            1
  56   62          { "%2d",        "%d",   "%2d",  "%02d" },
  57   63  #define PAD_FMT_DAYOFYEAR       2
  58   64          { "%03d",       "%d",   "%3d",  "%03d" },
  59   65  #define PAD_FMT_YEAR            3
  60   66          { "%04d",       "%d",   "%4d",  "%04d" }
  61   67  };
  62   68  
  63   69  
  64   70  size_t
  65      -strftime(char *_RESTRICT_KYWD s, size_t maxsize,
  66      -    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
       71 +strftime_l(char *_RESTRICT_KYWD s, size_t maxsize,
       72 +    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t,
       73 +    locale_t loc)
  67   74  {
  68      -        char *p;
       75 +        char    *p;
       76 +        int     warn;
       77 +        FIX_LOCALE(loc);
  69   78  
  70   79          tzset();
  71      -        p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize);
       80 +        warn = IN_NONE;
       81 +        p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize,
       82 +            &warn, loc);
       83 +        /* XXX YEAR_2000 */
  72   84          if (p == s + maxsize)
  73   85                  return (0);
  74   86          *p = '\0';
  75   87          return (p - s);
  76   88  }
  77   89  
       90 +size_t
       91 +strftime(char *_RESTRICT_KYWD s, size_t maxsize,
       92 +    const char *_RESTRICT_KYWD format, const struct tm *_RESTRICT_KYWD t)
       93 +{
       94 +        return (strftime_l(s, maxsize, format, t, __get_locale()));
       95 +}
       96 +
  78   97  static char *
  79      -_fmt(const char *format, const struct tm *t, char *pt, const char * const ptlim)
       98 +_fmt(const char *format, const struct tm *t, char *pt, const char * const ptlim,
       99 +    int *warnp, locale_t loc)
  80  100  {
  81  101          int Ealternative, Oalternative, PadIndex;
  82      -        struct lc_time_T *tptr = __get_current_time_locale();
      102 +        struct lc_time_T *tptr = __get_current_time_locale(loc);
  83  103  
  84  104  #define PADDING(x)      fmt_padding[x][PadIndex]
  85  105  
  86  106          for (; *format; ++format) {
  87  107                  if (*format == '%') {
  88  108                          Ealternative = 0;
  89  109                          Oalternative = 0;
  90  110                          PadIndex         = PAD_DEFAULT;
  91  111  label:
  92  112                          switch (*++format) {
↓ open down ↓ 30 lines elided ↑ open up ↑
 123  143                                   * %C used to do a...
 124  144                                   *      _fmt("%a %b %e %X %Y", t);
 125  145                                   * ...whereas now POSIX 1003.2 calls for
 126  146                                   * something completely different.
 127  147                                   * (ado, 1993-05-24)
 128  148                                   */
 129  149                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0,
 130  150                                      pt, ptlim);
 131  151                                  continue;
 132  152                          case 'c':
 133      -                                pt = _fmt(tptr->c_fmt, t, pt, ptlim);
      153 +                        {
      154 +                                int warn2 = IN_SOME;
      155 +
      156 +                                pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2,
      157 +                                    loc);
      158 +                                /* XXX */
      159 +                        }
 134  160                                  continue;
 135  161                          case 'D':
 136      -                                pt = _fmt("%m/%d/%y", t, pt, ptlim);
      162 +                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp,
      163 +                                    loc);
 137  164                                  continue;
 138  165                          case 'd':
 139  166                                  pt = _conv(t->tm_mday,
 140  167                                      PADDING(PAD_FMT_DAYOFMONTH), pt, ptlim);
 141  168                                  continue;
 142  169                          case 'E':
 143  170                                  if (Ealternative || Oalternative)
 144  171                                          break;
 145  172                                  Ealternative++;
 146  173                                  goto label;
↓ open down ↓ 9 lines elided ↑ open up ↑
 156  183                                   */
 157  184                                  if (Ealternative || Oalternative)
 158  185                                          break;
 159  186                                  Oalternative++;
 160  187                                  goto label;
 161  188                          case 'e':
 162  189                                  pt = _conv(t->tm_mday,
 163  190                                      PADDING(PAD_FMT_SDAYOFMONTH), pt, ptlim);
 164  191                                  continue;
 165  192                          case 'F':
 166      -                                pt = _fmt("%Y-%m-%d", t, pt, ptlim);
      193 +                                pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp,
      194 +                                    loc);
 167  195                                  continue;
 168  196                          case 'H':
 169  197                                  pt = _conv(t->tm_hour, PADDING(PAD_FMT_HMS),
 170  198                                      pt, ptlim);
 171  199                                  continue;
 172  200                          case 'I':
 173  201                                  pt = _conv((t->tm_hour % 12) ?
 174  202                                      (t->tm_hour % 12) : 12,
 175  203                                      PADDING(PAD_FMT_HMS), pt, ptlim);
 176  204                                  continue;
↓ open down ↓ 39 lines elided ↑ open up ↑
 216  244                                      pt, ptlim);
 217  245                                  continue;
 218  246                          case 'n':
 219  247                                  pt = _add("\n", pt, ptlim);
 220  248                                  continue;
 221  249                          case 'p':
 222  250                                  pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
 223  251                                      tptr->pm : tptr->am, pt, ptlim);
 224  252                                  continue;
 225  253                          case 'R':
 226      -                                pt = _fmt("%H:%M", t, pt, ptlim);
      254 +                                pt = _fmt("%H:%M", t, pt, ptlim, warnp, loc);
 227  255                                  continue;
 228  256                          case 'r':
 229      -                                pt = _fmt(tptr->ampm_fmt, t, pt, ptlim);
      257 +                                pt = _fmt(tptr->ampm_fmt, t, pt, ptlim,
      258 +                                    warnp, loc);
 230  259                                  continue;
 231  260                          case 'S':
 232  261                                  pt = _conv(t->tm_sec, PADDING(PAD_FMT_HMS),
 233  262                                      pt, ptlim);
 234  263                                  continue;
 235  264  
 236  265                          case 's':
 237  266                          {
 238  267                                  struct tm tm;
 239  268                                  char *buf;
 240      -
      269 +/* XXX */
 241  270                                  tm = *t;
 242  271                                  (void) asprintf(&buf, "%ld", mktime(&tm));
 243  272                                  pt = _add(buf, pt, ptlim);
 244      -                                continue;
 245  273                          }
 246      -
      274 +                                continue;
 247  275                          case 'T':
 248      -                                pt = _fmt("%H:%M:%S", t, pt, ptlim);
      276 +                                pt = _fmt("%H:%M:%S", t, pt, ptlim,
      277 +                                    warnp, loc);
 249  278                                  continue;
 250  279                          case 't':
 251  280                                  pt = _add("\t", pt, ptlim);
 252  281                                  continue;
 253  282                          case 'U':
 254  283                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
 255  284                                      t->tm_wday) / DAYSPERWEEK,
 256  285                                      PADDING(PAD_FMT_WEEKOFYEAR),
 257  286                                      pt, ptlim);
 258  287                                  continue;
↓ open down ↓ 91 lines elided ↑ open up ↑
 350  379                                          pt = _yconv(year, base, 1, 1,
 351  380                                              pt, ptlim);
 352  381                          }
 353  382                                  continue;
 354  383                          case 'v':
 355  384                                  /*
 356  385                                   * From Arnold Robbins' strftime version 3.0:
 357  386                                   * "date as dd-bbb-YYYY"
 358  387                                   * (ado, 1993-05-24)
 359  388                                   */
 360      -                                pt = _fmt("%e-%b-%Y", t, pt, ptlim);
      389 +                                pt = _fmt("%e-%b-%Y", t, pt, ptlim,
      390 +                                    warnp, loc);
 361  391                                  continue;
 362  392                          case 'W':
 363  393                                  pt = _conv((t->tm_yday + DAYSPERWEEK -
 364  394                                      (t->tm_wday ?
 365  395                                      (t->tm_wday - 1) :
 366  396                                      (DAYSPERWEEK - 1))) / DAYSPERWEEK,
 367  397                                      PADDING(PAD_FMT_WEEKOFYEAR),
 368  398                                      pt, ptlim);
 369  399                                  continue;
 370  400                          case 'w':
 371  401                                  pt = _conv(t->tm_wday, "%d", pt, ptlim);
 372  402                                  continue;
 373  403                          case 'X':
 374      -                                pt = _fmt(tptr->X_fmt, t, pt, ptlim);
      404 +                                pt = _fmt(tptr->X_fmt, t, pt, ptlim,
      405 +                                    warnp, loc);
 375  406                                  continue;
 376  407                          case 'x':
 377      -                                pt = _fmt(tptr->x_fmt, t, pt, ptlim);
      408 +                        {
      409 +                                int     warn2 = IN_SOME;
      410 +
      411 +                                pt = _fmt(tptr->x_fmt, t, pt, ptlim,
      412 +                                    &warn2, loc);
      413 +                        }
 378  414                                  continue;
 379  415                          case 'y':
 380  416                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1,
 381  417                                      pt, ptlim);
 382  418                                  continue;
 383  419                          case 'Y':
 384  420                                  pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1,
 385  421                                      pt, ptlim);
 386  422                                  continue;
 387  423                          case 'Z':
↓ open down ↓ 43 lines elided ↑ open up ↑
 431  467                                          sign = "+";
 432  468                                  pt = _add(sign, pt, ptlim);
 433  469                                  diff /= SECSPERMIN;
 434  470                                  diff = (diff / MINSPERHOUR) * 100 +
 435  471                                      (diff % MINSPERHOUR);
 436  472                                  pt = _conv(diff, PADDING(PAD_FMT_YEAR),
 437  473                                      pt, ptlim);
 438  474                                  }
 439  475                                  continue;
 440  476                          case '+':
 441      -                                pt = _fmt(tptr->date_fmt, t, pt, ptlim);
      477 +                                pt = _fmt(tptr->date_fmt, t, pt, ptlim,
      478 +                                    warnp, loc);
 442  479                                  continue;
 443  480                          case '-':
 444  481                                  if (PadIndex != PAD_DEFAULT)
 445  482                                          break;
 446  483                                  PadIndex = PAD_LESS;
 447  484                                  goto label;
 448  485                          case '_':
 449  486                                  if (PadIndex != PAD_DEFAULT)
 450  487                                          break;
 451  488                                  PadIndex = PAD_SPACE;
↓ open down ↓ 76 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX