Print this page
2964 need POSIX 2008 locale object support

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/strptime.c
          +++ new/usr/src/lib/libc/port/locale/strptime.c
   1    1  /*
   2    2   * Copyright 2011, Nexenta Systems, Inc.  All rights reserved.
   3    3   * Copyright (c) 1994 Powerdog Industries.  All rights reserved.
   4    4   *
        5 + * Copyright (c) 2011 The FreeBSD Foundation
        6 + * All rights reserved.
        7 + * Portions of this software were developed by David Chisnall
        8 + * under sponsorship from the FreeBSD Foundation.
        9 + *
   5   10   * Redistribution and use in source and binary forms, with or without
   6   11   * modification, are permitted provided that the following conditions
   7   12   * are met:
   8   13   *
   9   14   * 1. Redistributions of source code must retain the above copyright
  10   15   *    notice, this list of conditions and the following disclaimer.
  11   16   *
  12   17   * 2. Redistributions in binary form must reproduce the above copyright
  13   18   *    notice, this list of conditions and the following disclaimer
  14   19   *    in the documentation and/or other materials provided with the
↓ open down ↓ 26 lines elided ↑ open up ↑
  41   46  #include <alloca.h>
  42   47  #include "timelocal.h"
  43   48  
  44   49  #define asizeof(a)      (sizeof (a) / sizeof ((a)[0]))
  45   50  
  46   51  #define F_GMT           (1 << 0)
  47   52  #define F_ZERO          (1 << 1)
  48   53  #define F_RECURSE       (1 << 2)
  49   54  
  50   55  static char *
  51      -__strptime(const char *buf, const char *fmt, struct tm *tm, int *flagsp)
       56 +__strptime(const char *buf, const char *fmt, struct tm *tm, int *flagsp,
       57 +    int *GMTp, locale_t locale)
  52   58  {
  53   59          char    c;
  54   60          const char *ptr;
  55   61          int     i, len, recurse = 0;
  56   62          int Ealternative, Oalternative;
  57      -        struct lc_time_T *tptr = __get_current_time_locale();
       63 +        struct lc_time_T *tptr = __get_current_time_locale(locale);
  58   64  
  59   65          if (*flagsp & F_RECURSE)
  60   66                  recurse = 1;
  61   67          *flagsp |= F_RECURSE;
  62   68  
  63   69          if (*flagsp & F_ZERO)
  64   70                  (void) memset(tm, 0, sizeof (*tm));
  65   71          *flagsp &= ~F_ZERO;
  66   72  
  67   73          ptr = fmt;
↓ open down ↓ 17 lines elided ↑ open up ↑
  85   91  label:
  86   92                  c = *ptr++;
  87   93                  switch (c) {
  88   94                  case 0:
  89   95                  case '%':
  90   96                          if (*buf++ != '%')
  91   97                                  return (NULL);
  92   98                          break;
  93   99  
  94  100                  case '+':
  95      -                        buf = __strptime(buf, tptr->date_fmt, tm, flagsp);
      101 +                        buf = __strptime(buf, tptr->date_fmt, tm, flagsp,
      102 +                            GMTp, locale);
  96  103                          if (buf == NULL)
  97  104                                  return (NULL);
  98  105                          break;
  99  106  
 100  107                  case 'C':
 101  108                          if (!isdigit(*buf))
 102  109                                  return (NULL);
 103  110  
 104  111                          /* XXX This will break for 3-digit centuries. */
 105  112                          len = 2;
↓ open down ↓ 2 lines elided ↑ open up ↑
 108  115                                  i += *buf - '0';
 109  116                                  len--;
 110  117                          }
 111  118                          if (i < 19)
 112  119                                  return (NULL);
 113  120  
 114  121                          tm->tm_year = i * 100 - 1900;
 115  122                          break;
 116  123  
 117  124                  case 'c':
 118      -                        buf = __strptime(buf, tptr->c_fmt, tm, flagsp);
      125 +                        buf = __strptime(buf, tptr->c_fmt, tm, flagsp,
      126 +                            GMTp, locale);
 119  127                          if (buf == NULL)
 120  128                                  return (NULL);
 121  129                          break;
 122  130  
 123  131                  case 'D':
 124      -                        buf = __strptime(buf, "%m/%d/%y", tm, flagsp);
      132 +                        buf = __strptime(buf, "%m/%d/%y", tm, flagsp,
      133 +                            GMTp, locale);
 125  134                          if (buf == NULL)
 126  135                                  return (NULL);
 127  136                          break;
 128  137  
 129  138                  case 'E':
 130  139                          if (Ealternative || Oalternative)
 131  140                                  break;
 132  141                          Ealternative++;
 133  142                          goto label;
 134  143  
 135  144                  case 'O':
 136  145                          if (Ealternative || Oalternative)
 137  146                                  break;
 138  147                          Oalternative++;
 139  148                          goto label;
 140  149  
 141  150                  case 'F':
 142      -                        buf = __strptime(buf, "%Y-%m-%d", tm, flagsp);
      151 +                        buf = __strptime(buf, "%Y-%m-%d", tm, flagsp,
      152 +                            GMTp, locale);
 143  153                          if (buf == NULL)
 144  154                                  return (NULL);
 145  155                          break;
 146  156  
 147  157                  case 'R':
 148      -                        buf = __strptime(buf, "%H:%M", tm, flagsp);
      158 +                        buf = __strptime(buf, "%H:%M", tm, flagsp,
      159 +                            GMTp, locale);
 149  160                          if (buf == NULL)
 150  161                                  return (NULL);
 151  162                          break;
 152  163  
 153  164                  case 'r':
 154      -                        buf = __strptime(buf, tptr->ampm_fmt, tm, flagsp);
      165 +                        buf = __strptime(buf, tptr->ampm_fmt, tm, flagsp,
      166 +                            GMTp, locale);
 155  167                          if (buf == NULL)
 156  168                                  return (NULL);
 157  169                          break;
 158  170  
 159  171                  case 'T':
 160      -                        buf = __strptime(buf, "%H:%M:%S", tm, flagsp);
      172 +                        buf = __strptime(buf, "%H:%M:%S", tm, flagsp,
      173 +                            GMTp, locale);
 161  174                          if (buf == NULL)
 162  175                                  return (NULL);
 163  176                          break;
 164  177  
 165  178                  case 'X':
 166      -                        buf = __strptime(buf, tptr->X_fmt, tm, flagsp);
      179 +                        buf = __strptime(buf, tptr->X_fmt, tm, flagsp,
      180 +                            GMTp, locale);
 167  181                          if (buf == NULL)
 168  182                                  return (NULL);
 169  183                          break;
 170  184  
 171  185                  case 'x':
 172      -                        buf = __strptime(buf, tptr->x_fmt, tm, flagsp);
      186 +                        buf = __strptime(buf, tptr->x_fmt, tm, flagsp,
      187 +                            GMTp, locale);
 173  188                          if (buf == NULL)
 174  189                                  return (NULL);
 175  190                          break;
 176  191  
 177  192                  case 'j':
 178  193                          if (!isdigit(*buf))
 179  194                                  return (NULL);
 180  195  
 181  196                          len = 3;
 182  197                          for (i = 0; len && isdigit(*buf); buf++) {
↓ open down ↓ 345 lines elided ↑ open up ↑
 528  543                  if (buf && (*flagsp & F_GMT)) {
 529  544                          time_t t = timegm(tm);
 530  545                          (void) localtime_r(&t, tm);
 531  546                  }
 532  547          }
 533  548  
 534  549          return ((char *)buf);
 535  550  }
 536  551  
 537  552  char *
      553 +strptime_l(const char * __restrict buf, const char * __restrict fmt,
      554 +    struct tm * __restrict tm, locale_t loc)
      555 +{
      556 +        char *ret;
      557 +        int gmt;
      558 +        int flags = F_ZERO;
      559 +        FIX_LOCALE(loc);
      560 +
      561 +        gmt = 0;
      562 +        ret = __strptime(buf, fmt, tm, &flags, &gmt, loc);
      563 +        if (ret && gmt) {
      564 +                time_t t = timegm(tm);
      565 +                localtime_r(&t, tm);
      566 +        }
      567 +
      568 +        return (ret);
      569 +}
      570 +
      571 +char *
 538  572  strptime(const char *buf, const char *fmt, struct tm *tm)
 539  573  {
 540  574          int     flags = F_ZERO;
 541  575  
 542      -        return (__strptime(buf, fmt, tm, &flags));
      576 +        return (strptime_l(buf, fmt, tm, __get_locale()));
      577 +        // XXX return (__strptime(buf, fmt, tm, &flags));
 543  578  }
 544  579  
 545  580  /*
 546  581   * This is used by Solaris, and is a variant that does not clear the
 547  582   * incoming tm.  It is triggered by -D_STRPTIME_DONTZERO.
 548  583   */
 549  584  char *
 550  585  __strptime_dontzero(const char *buf, const char *fmt, struct tm *tm)
 551  586  {
 552  587          int     flags = 0;
      588 +        int     gmt = 0;
 553  589  
 554      -        return (__strptime(buf, fmt, tm, &flags));
      590 +        return (__strptime(buf, fmt, tm, &flags, &gmt, __get_locale()));
      591 +        /* XXX */
 555  592  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX