Print this page
2964 need POSIX 2008 locale object support

@@ -4,10 +4,15 @@
  *      The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * Paul Borman at Krystal Technologies.
  *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.

@@ -45,22 +50,28 @@
 #include "mblocal.h"
 #include "setlocale.h"
 #include "_ctype.h"
 #include "../i18n/_locale.h"
 
+/*
+ * A cached version of the runes for this thread.  Used by ctype.h
+ */
+__thread const _RuneLocale *_ThreadRuneLocale;
+
 extern _RuneLocale      *_Read_RuneMagi(FILE *);
 extern unsigned char    __ctype_C[];
 
-static int              __setrunelocale(const char *);
+static int              __setrunelocale(struct xlocale_ctype *, const char *);
 
 static int
-__setrunelocale(const char *encoding)
+__setrunelocale(struct xlocale_ctype *l, const char *encoding)
 {
         FILE *fp;
         char name[PATH_MAX];
         _RuneLocale *rl;
         int saverr, ret;
+        struct xlocale_ctype saved = *l; /* XXX DOUBLE NOT USED */
         size_t (*old__mbrtowc)(wchar_t *_RESTRICT_KYWD,
             const char *_RESTRICT_KYWD, size_t, mbstate_t *_RESTRICT_KYWD);
         size_t (*old__wcrtomb)(char *_RESTRICT_KYWD, wchar_t,
             mbstate_t *_RESTRICT_KYWD);
         int (*old__mbsinit)(const mbstate_t *);

@@ -96,25 +107,25 @@
                         __ctype_mask[i] = _DefaultRuneLocale.__runetype[i];
                         __trans_upper[i] = _DefaultRuneLocale.__mapupper[i];
                         __trans_lower[i] = _DefaultRuneLocale.__maplower[i];
                 }
 
-                (void) _none_init(&_DefaultRuneLocale);
+                (void) _none_init(l, &_DefaultRuneLocale);
                 return (0);
         }
 
         /*
          * If the locale name is the same as our cache, use the cache.
          */
         if (CachedRuneLocale != NULL &&
             strcmp(encoding, ctype_encoding) == 0) {
-                _CurrentRuneLocale = CachedRuneLocale;
-                __mbrtowc = Cached__mbrtowc;
-                __mbsinit = Cached__mbsinit;
-                __mbsnrtowcs = Cached__mbsnrtowcs;
-                __wcrtomb = Cached__wcrtomb;
-                __wcsnrtombs = Cached__wcsnrtombs;
+                l->runes = CachedRuneLocale;
+                l->__mbrtowc = Cached__mbrtowc;
+                l->__mbsinit = Cached__mbsinit;
+                l->__mbsnrtowcs = Cached__mbsnrtowcs;
+                l->__wcrtomb = Cached__wcrtomb;
+                l->__wcsnrtombs = Cached__wcsnrtombs;
                 return (0);
         }
 
         /*
          * Slurp the locale file into the cache.

@@ -137,18 +148,18 @@
         old__mbsinit = __mbsinit;
         old__mbsnrtowcs = __mbsnrtowcs;
         old__wcrtomb = __wcrtomb;
         old__wcsnrtombs = __wcsnrtombs;
 
-        __mbrtowc = NULL;
-        __mbsinit = NULL;
-        __mbsnrtowcs = __mbsnrtowcs_std;
-        __wcrtomb = NULL;
-        __wcsnrtombs = __wcsnrtombs_std;
+        l->__mbrtowc = NULL;
+        l->__mbsinit = NULL;
+        l->__mbsnrtowcs = __mbsnrtowcs_std;
+        l->__wcrtomb = NULL;
+        l->__wcsnrtombs = __wcsnrtombs_std;
 
         if (strcmp(rl->__encoding, "NONE") == 0)
-                ret = _none_init(rl);
+                ret = _none_init(l, rl);
         else if (strcmp(rl->__encoding, "UTF-8") == 0)
                 ret = _UTF8_init(rl);
         else if (strcmp(rl->__encoding, "EUC-CN") == 0)
                 ret = _EUC_CN_init(rl);
         else if (strcmp(rl->__encoding, "EUC-JP") == 0)

@@ -172,16 +183,16 @@
 
         if (ret == 0) {
                 if (CachedRuneLocale != NULL) {
                         free(CachedRuneLocale);
                 }
-                CachedRuneLocale = _CurrentRuneLocale;
-                Cached__mbrtowc = __mbrtowc;
-                Cached__mbsinit = __mbsinit;
-                Cached__mbsnrtowcs = __mbsnrtowcs;
-                Cached__wcrtomb = __wcrtomb;
-                Cached__wcsnrtombs = __wcsnrtombs;
+                CachedRuneLocale = l->runes;
+                Cached__mbrtowc = l->__mbrtowc;
+                Cached__mbsinit = l->__mbsinit;
+                Cached__mbsnrtowcs = l->__mbsnrtowcs;
+                Cached__wcrtomb = l->__wcrtomb;
+                Cached__wcsnrtombs = l->__wcsnrtombs;
                 (void) strcpy(ctype_encoding, encoding);
 
                 /*
                  * We need to overwrite the _ctype array.  This requires
                  * some finagling.  This is because references to it may

@@ -226,27 +237,53 @@
                 /*
                  * Note that we expect the init code will have populated
                  * the CSWIDTH array (__ctype[514-520]) properly.
                  */
         } else {
-                __mbrtowc = old__mbrtowc;
-                __mbsinit = old__mbsinit;
-                __mbsnrtowcs = old__mbsnrtowcs;
-                __wcrtomb = old__wcrtomb;
-                __wcsnrtombs = old__wcsnrtombs;
+                l->__mbrtowc = old__mbrtowc;
+                l->__mbsinit = old__mbsinit;
+                l->__mbsnrtowcs = old__mbsnrtowcs;
+                l->__wcrtomb = old__wcrtomb;
+                l->__wcsnrtombs = old__wcsnrtombs;
                 free(rl);
         }
 
         return (ret);
 }
 
 int
 __wrap_setrunelocale(const char *locale)
 {
-        int ret = __setrunelocale(locale);
+        int ret = __setrunelocale(&__xlocale_global_ctype, locale);
 
         if (ret != 0) {
                 errno = ret;
                 return (_LDP_ERROR);
         }
+        /* XXX */
+//      __mb_cur_max = __xlocale_global_ctype.__mb_cur_max;
+//      __mb_sb_limit = __xlocale_global_ctype.__mb_sb_limit;
+        _CurrentRuneLocale = __xlocale_global_ctype.runes;
         return (_LDP_LOADED);
 }
+
+void
+__set_thread_rune_locale(locale_t loc)
+{
+
+        if (loc == NULL) {
+                _ThreadRuneLocale = &_DefaultRuneLocale;
+        } else {
+                _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes;
+        }
+}
+
+void *
+__ctype_load(const char *locale, locale_t unused)
+{
+        struct xlocale_ctype *l;
+
+        l = calloc(sizeof(struct xlocale_ctype), 1);
+        /* XXX */
+
+        return (l);
+}