Print this page
2964 need POSIX 2008 locale object support

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libc/port/locale/setrunelocale.c
          +++ new/usr/src/lib/libc/port/locale/setrunelocale.c
   1    1  /*
   2    2   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
   3    3   * Copyright (c) 1993
   4    4   *      The Regents of the University of California.  All rights reserved.
   5    5   *
   6    6   * This code is derived from software contributed to Berkeley by
   7    7   * Paul Borman at Krystal Technologies.
   8    8   *
        9 + * Copyright (c) 2011 The FreeBSD Foundation
       10 + * All rights reserved.
       11 + * Portions of this software were developed by David Chisnall
       12 + * under sponsorship from the FreeBSD Foundation.
       13 + *
   9   14   * Redistribution and use in source and binary forms, with or without
  10   15   * modification, are permitted provided that the following conditions
  11   16   * are met:
  12   17   * 1. Redistributions of source code must retain the above copyright
  13   18   *    notice, this list of conditions and the following disclaimer.
  14   19   * 2. Redistributions in binary form must reproduce the above copyright
  15   20   *    notice, this list of conditions and the following disclaimer in the
  16   21   *    documentation and/or other materials provided with the distribution.
  17   22   * 4. Neither the name of the University nor the names of its contributors
  18   23   *    may be used to endorse or promote products derived from this software
↓ open down ↓ 21 lines elided ↑ open up ↑
  40   45  #include <stdlib.h>
  41   46  #include <unistd.h>
  42   47  #include <wchar.h>
  43   48  #include "runetype.h"
  44   49  #include "ldpart.h"
  45   50  #include "mblocal.h"
  46   51  #include "setlocale.h"
  47   52  #include "_ctype.h"
  48   53  #include "../i18n/_locale.h"
  49   54  
       55 +/*
       56 + * A cached version of the runes for this thread.  Used by ctype.h
       57 + */
       58 +__thread const _RuneLocale *_ThreadRuneLocale;
       59 +
  50   60  extern _RuneLocale      *_Read_RuneMagi(FILE *);
  51   61  extern unsigned char    __ctype_C[];
  52   62  
  53      -static int              __setrunelocale(const char *);
       63 +static int              __setrunelocale(struct xlocale_ctype *, const char *);
  54   64  
  55   65  static int
  56      -__setrunelocale(const char *encoding)
       66 +__setrunelocale(struct xlocale_ctype *l, const char *encoding)
  57   67  {
  58   68          FILE *fp;
  59   69          char name[PATH_MAX];
  60   70          _RuneLocale *rl;
  61   71          int saverr, ret;
       72 +        struct xlocale_ctype saved = *l; /* XXX DOUBLE NOT USED */
  62   73          size_t (*old__mbrtowc)(wchar_t *_RESTRICT_KYWD,
  63   74              const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
  64   75          size_t (*old__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
  65   76              mbstate_t *_RESTRICT_KYWD);
  66   77          int (*old__mbsinit)(const mbstate_t *);
  67   78          size_t (*old__mbsnrtowcs)(wchar_t *_RESTRICT_KYWD,
  68   79              const char **_RESTRICT_KYWD, size_t, size_t,
  69   80              mbstate_t *_RESTRICT_KYWD);
  70   81          size_t (*old__wcsnrtombs)(char *_RESTRICT_KYWD,
  71   82              const wchar_t **_RESTRICT_KYWD, size_t, size_t,
↓ open down ↓ 19 lines elided ↑ open up ↑
  91  102                  int i;
  92  103  
  93  104                  (void) memcpy(__ctype, __ctype_C, SZ_TOTAL);
  94  105  
  95  106                  for (i = 0; i < _CACHED_RUNES; i++) {
  96  107                          __ctype_mask[i] = _DefaultRuneLocale.__runetype[i];
  97  108                          __trans_upper[i] = _DefaultRuneLocale.__mapupper[i];
  98  109                          __trans_lower[i] = _DefaultRuneLocale.__maplower[i];
  99  110                  }
 100  111  
 101      -                (void) _none_init(&_DefaultRuneLocale);
      112 +                (void) _none_init(l, &_DefaultRuneLocale);
 102  113                  return (0);
 103  114          }
 104  115  
 105  116          /*
 106  117           * If the locale name is the same as our cache, use the cache.
 107  118           */
 108  119          if (CachedRuneLocale != NULL &&
 109  120              strcmp(encoding, ctype_encoding) == 0) {
 110      -                _CurrentRuneLocale = CachedRuneLocale;
 111      -                __mbrtowc = Cached__mbrtowc;
 112      -                __mbsinit = Cached__mbsinit;
 113      -                __mbsnrtowcs = Cached__mbsnrtowcs;
 114      -                __wcrtomb = Cached__wcrtomb;
 115      -                __wcsnrtombs = Cached__wcsnrtombs;
      121 +                l->runes = CachedRuneLocale;
      122 +                l->__mbrtowc = Cached__mbrtowc;
      123 +                l->__mbsinit = Cached__mbsinit;
      124 +                l->__mbsnrtowcs = Cached__mbsnrtowcs;
      125 +                l->__wcrtomb = Cached__wcrtomb;
      126 +                l->__wcsnrtombs = Cached__wcsnrtombs;
 116  127                  return (0);
 117  128          }
 118  129  
 119  130          /*
 120  131           * Slurp the locale file into the cache.
 121  132           */
 122  133  
 123  134          (void) snprintf(name, sizeof (name), "%s/%s/LC_CTYPE/LCL_DATA",
 124  135              _PathLocale, encoding);
 125  136  
↓ open down ↓ 6 lines elided ↑ open up ↑
 132  143                  return (saverr);
 133  144          }
 134  145          (void) fclose(fp);
 135  146  
 136  147          old__mbrtowc = __mbrtowc;
 137  148          old__mbsinit = __mbsinit;
 138  149          old__mbsnrtowcs = __mbsnrtowcs;
 139  150          old__wcrtomb = __wcrtomb;
 140  151          old__wcsnrtombs = __wcsnrtombs;
 141  152  
 142      -        __mbrtowc = NULL;
 143      -        __mbsinit = NULL;
 144      -        __mbsnrtowcs = __mbsnrtowcs_std;
 145      -        __wcrtomb = NULL;
 146      -        __wcsnrtombs = __wcsnrtombs_std;
      153 +        l->__mbrtowc = NULL;
      154 +        l->__mbsinit = NULL;
      155 +        l->__mbsnrtowcs = __mbsnrtowcs_std;
      156 +        l->__wcrtomb = NULL;
      157 +        l->__wcsnrtombs = __wcsnrtombs_std;
 147  158  
 148  159          if (strcmp(rl->__encoding, "NONE") == 0)
 149      -                ret = _none_init(rl);
      160 +                ret = _none_init(l, rl);
 150  161          else if (strcmp(rl->__encoding, "UTF-8") == 0)
 151  162                  ret = _UTF8_init(rl);
 152  163          else if (strcmp(rl->__encoding, "EUC-CN") == 0)
 153  164                  ret = _EUC_CN_init(rl);
 154  165          else if (strcmp(rl->__encoding, "EUC-JP") == 0)
 155  166                  ret = _EUC_JP_init(rl);
 156  167          else if (strcmp(rl->__encoding, "EUC-KR") == 0)
 157  168                  ret = _EUC_KR_init(rl);
 158  169          else if (strcmp(rl->__encoding, "EUC-TW") == 0)
 159  170                  ret = _EUC_TW_init(rl);
↓ open down ↓ 7 lines elided ↑ open up ↑
 167  178                  ret = _BIG5_init(rl);
 168  179          else if (strcmp(rl->__encoding, "MSKanji") == 0)
 169  180                  ret = _MSKanji_init(rl);
 170  181          else
 171  182                  ret = EINVAL;
 172  183  
 173  184          if (ret == 0) {
 174  185                  if (CachedRuneLocale != NULL) {
 175  186                          free(CachedRuneLocale);
 176  187                  }
 177      -                CachedRuneLocale = _CurrentRuneLocale;
 178      -                Cached__mbrtowc = __mbrtowc;
 179      -                Cached__mbsinit = __mbsinit;
 180      -                Cached__mbsnrtowcs = __mbsnrtowcs;
 181      -                Cached__wcrtomb = __wcrtomb;
 182      -                Cached__wcsnrtombs = __wcsnrtombs;
      188 +                CachedRuneLocale = l->runes;
      189 +                Cached__mbrtowc = l->__mbrtowc;
      190 +                Cached__mbsinit = l->__mbsinit;
      191 +                Cached__mbsnrtowcs = l->__mbsnrtowcs;
      192 +                Cached__wcrtomb = l->__wcrtomb;
      193 +                Cached__wcsnrtombs = l->__wcsnrtombs;
 183  194                  (void) strcpy(ctype_encoding, encoding);
 184  195  
 185  196                  /*
 186  197                   * We need to overwrite the _ctype array.  This requires
 187  198                   * some finagling.  This is because references to it may
 188  199                   * have been baked into applications.
 189  200                   *
 190  201                   * Note that it is interesting that toupper/tolower only
 191  202                   * produce defined results when the input is representable
 192  203                   * as a byte.
↓ open down ↓ 28 lines elided ↑ open up ↑
 221  232                          /* Don't forget these annoyances either! */
 222  233                          __trans_upper[i] = rl->__mapupper[i];
 223  234                          __trans_lower[i] = rl->__maplower[i];
 224  235                  }
 225  236  
 226  237                  /*
 227  238                   * Note that we expect the init code will have populated
 228  239                   * the CSWIDTH array (__ctype[514-520]) properly.
 229  240                   */
 230  241          } else {
 231      -                __mbrtowc = old__mbrtowc;
 232      -                __mbsinit = old__mbsinit;
 233      -                __mbsnrtowcs = old__mbsnrtowcs;
 234      -                __wcrtomb = old__wcrtomb;
 235      -                __wcsnrtombs = old__wcsnrtombs;
      242 +                l->__mbrtowc = old__mbrtowc;
      243 +                l->__mbsinit = old__mbsinit;
      244 +                l->__mbsnrtowcs = old__mbsnrtowcs;
      245 +                l->__wcrtomb = old__wcrtomb;
      246 +                l->__wcsnrtombs = old__wcsnrtombs;
 236  247                  free(rl);
 237  248          }
 238  249  
 239  250          return (ret);
 240  251  }
 241  252  
 242  253  int
 243  254  __wrap_setrunelocale(const char *locale)
 244  255  {
 245      -        int ret = __setrunelocale(locale);
      256 +        int ret = __setrunelocale(&__xlocale_global_ctype, locale);
 246  257  
 247  258          if (ret != 0) {
 248  259                  errno = ret;
 249  260                  return (_LDP_ERROR);
 250  261          }
      262 +        /* XXX */
      263 +//      __mb_cur_max = __xlocale_global_ctype.__mb_cur_max;
      264 +//      __mb_sb_limit = __xlocale_global_ctype.__mb_sb_limit;
      265 +        _CurrentRuneLocale = __xlocale_global_ctype.runes;
 251  266          return (_LDP_LOADED);
 252  267  }
      268 +
      269 +void
      270 +__set_thread_rune_locale(locale_t loc)
      271 +{
      272 +
      273 +        if (loc == NULL) {
      274 +                _ThreadRuneLocale = &_DefaultRuneLocale;
      275 +        } else {
      276 +                _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
      277 +        }
      278 +}
      279 +
      280 +void *
      281 +__ctype_load(const char *locale, locale_t unused)
      282 +{
      283 +        struct xlocale_ctype *l;
      284 +
      285 +        l = calloc(sizeof(struct xlocale_ctype), 1);
      286 +        /* XXX */
      287 +
      288 +        return (l);
      289 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX