/***************************************************************************
 *
 * locale_body.cpp - implementation of the std::locale and __rw_locale class
 *
 * This is an internal header file used to implement the C++ Standard
 * Library. It should never be #included directly by a program.
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Copyright 2005-2006 The Apache Software Foundation or its licensors,
 * as applicable.
 *
 * Copyright 2001-2006 Rogue Wave Software.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <rw/_defs.h>

#include <new>        // for placement new
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>   // for bsearch(), qsort()
#include <string.h>   // for memxxx() and strxxx() functions

#include <loc/_locale.h>

#include "access.h"
#include "locale_body.h"
#include "setlocale.h"


#ifdef _RWSTD_NO_LOCALE_NAME_FMAT

// pick an arbitrary order for categories in locale names
#  define _RWSTD_CAT_0(pfx) \
       { _RWSTD_LC_CTYPE, "LC_CTYPE", pfx::_C_ctype }
#  define _RWSTD_CAT_1(pfx) \
       { _RWSTD_LC_NUMERIC, "LC_NUMERIC", pfx::_C_numeric }
#  define _RWSTD_CAT_2(pfx) \
       { _RWSTD_LC_TIME, "LC_TIME", pfx::_C_time }
#  define _RWSTD_CAT_3(pfx) \
       { _RWSTD_LC_COLLATE, "LC_COLLATE", pfx::_C_collate }
#  define _RWSTD_CAT_4(pfx) \
       { _RWSTD_LC_MONETARY, "LC_MONETARY", pfx::_C_monetary }
#  define _RWSTD_CAT_5(pfx) \
       { _RWSTD_LC_MESSAGES, "LC_MESSAGES", pfx::_C_messages }

#endif   // _RWSTD_NO_LOCALE_NAME_FMAT


_RWSTD_NAMESPACE (__rw) {


// maps LC_XXX category values to their names
extern const __rw_cats_t
__rw_cats [] = {

    // expands to { LC_XXX, "LC_XXX", _RW::__rw_locale::_C_xxx }
    // the order of these is determined at config time and corresponds to
    // the order mixed/combined locale categories returned by setlocale()
    _RWSTD_CAT_0 (_RW::__rw_locale),
    _RWSTD_CAT_1 (_RW::__rw_locale),
    _RWSTD_CAT_2 (_RW::__rw_locale),
    _RWSTD_CAT_3 (_RW::__rw_locale),
    _RWSTD_CAT_4 (_RW::__rw_locale),

#ifdef _RWSTD_CAT_5
    _RWSTD_CAT_5 (_RW::__rw_locale)
#else   // if !defined (_RWSTD_CAT_5)
    // for Windoze (no LC_MESSAGES there)
    _RWSTD_CAT_0 (_RW::__rw_locale)
#endif   // _RWSTD_CAT_5

};


// fills provided buffer (if large anough) with the names of locales
// for each of the standard LC_XXX categories; if all categories come
// from the same locale, copies the name of the common locale into
// the provided buffer
//
// names of categories are in the following order:
//     LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME, LC_MESSAGES
//
// examples of output (assuming ';' as a separator):
//     "C"
//         all facets of all categories come from the "C" locale
//
//     "C;C;de_DE;C;C;C;"
//         all facets come from the "C" locale except those that belong
//         to the LC_MONETARY category, which all come from "de_DE"
// 
//     "C;en_US;*;*;*;*;"
//         facets the belong to the LC_COLLATE category come from the
//         "C" locale, those belonging to the LC_CTYPE category come
//         from "en_US", all others are from mixed locales within
//         their respective categories
//
//     "*"
//         facets belonging to each category come from all different
//         locales (e.g., ctype<char> might come from the "C" locale,
//         and ctype<wchar_t> from "ja_JP", etc.)

char* __rw_locale::
_C_get_cat_names (char *buf, size_t bufsize) const
{
    const size_t  savesize = bufsize;
    char         *savebuf  = buf;

    if (!buf)
        buf = new char [bufsize ? bufsize : (bufsize = 256)];

    *buf = '\0';

    // will point at the locale name common across all categories
    // if one such name exists; otherwise at "*" (mixed locale)
    const char *common_name = 0;

    // iterate over all categories, searching for all facets that belong
    // to that category and comparing their names. if all such facets come
    // from the same locale, the name of the category is the name of the
    // locale; otherwise "*"
    for (size_t i = 0; i != __rw_n_cats; ++i) {

        const char *cat_name = 0;

        for (size_t j = 0; j != _C_n_std_facets; ++j) {

            // verify that all facet pointers are set
            _RWSTD_ASSERT (_C_std_facets [j]);

            // ignore the non-localized {money,num}_{get,put} facets
            // and consider only moneypunct and numpunct for the
            // monetary category
            switch (_C_std_facets [j]->_C_type) {
            case __rw_facet::_C_num_get:
            case __rw_facet::_C_wnum_get:
            case __rw_facet::_C_num_put:
            case __rw_facet::_C_wnum_put:
            case __rw_facet::_C_money_get:
            case __rw_facet::_C_wmoney_get:
            case __rw_facet::_C_money_put:
            case __rw_facet::_C_wmoney_put:
                continue;
            default:
                break;
            }

            _RWSTD_ASSERT (0 != _C_std_facets [j]->_C_pid);

            // one category at a time
            if (   __rw_cats [i].cat
                != __rw_get_cat (int (*_C_std_facets [j]->_C_pid)))
                continue;

            // default facet name (if 0) is "C"
            const char *facet_name = _C_std_facets [j]->_C_name
                ? _C_std_facets [j]->_C_name : "C";

            if (cat_name && strcmp (cat_name, facet_name))
                cat_name = "*";
            else
                cat_name = facet_name;

            if (common_name) {
                // if the name of the locale for this category doesn't
                // match the common locale name so far, assign "*"
                if (strcmp (common_name, cat_name))
                    common_name = "*";
            }
            else
                common_name = cat_name;
        }

        // will be 0 iff all facets in a category are 0
        // (i.e., an internal logic error)
        _RWSTD_ASSERT (cat_name);

        if (   strlen (buf) + strlen (cat_name) + 2
            >= bufsize) {
            // reallocate buffer if necessary
            char *tmp = 0;

            _TRY {
                tmp = new char [bufsize *= 2];
            }
            _CATCH (...) {
                if (buf != savebuf)
                    delete[] buf;
                _RETHROW;
            }

            strcpy (tmp, buf);
            if (buf != savebuf)
                delete[] buf;
            buf = tmp;
        }

        strcat (buf, cat_name);
        strcat (buf, _RWSTD_CAT_SEP);
    }

    _RWSTD_ASSERT (common_name);

    if (__rw_facet::_C_opts & __rw_facet::_C_condensed_name) {
        // if all categories come from the same locale, copy the name
        // of that locale into the buffer
        if ('*' != common_name [0] || '\0' != common_name [1]) {
            if (   savebuf && buf != savebuf
                && savesize >= strlen (common_name)) {
                // delete allocated memory and repoint at original buffer
                delete[] buf;
                buf = savebuf;
            }
            strcpy (buf, common_name);
        }
    }

    // remove trailing separator
    const size_t len = strlen (buf);
    if (len && *_RWSTD_CAT_SEP == buf [len - 1])
        buf [len - 1] = '\0';

    return buf;
}


// returns a pointer to a character array containing locale names separated
// by _RWSTD_CAT_SEP corresponding to the named locale (typically all the
// names will be the same except possibly for the native locale which can
// consist of facets from different named locales specified by the LC_XXX
// environment variables)
static const char*
__rw_expand_name (__rw_chararray &namebuf, const char *name)
{
    const char *sep = strchr (name, *_RWSTD_CAT_SEP);

    if (sep == name) {
        // skip the first separator if it's at the beginning of `name'
        // (e.g., SunOS locale names have the format "/en/C/ja/C/it/de")
        sep = strchr (++name, *_RWSTD_CAT_SEP);
    }

    // true if all ctaegories are from the same locale, false otherwise
    bool same_cats = true;

    if (sep) {

        // `name' contains a locale category separator; iterate over
        // all locale categories to determine the name of the locale
        // for each one of them

        for (size_t i = 0; ; sep = strchr (name, *_RWSTD_CAT_SEP)) {

            if (!sep)
                sep = name + strlen (name);

            const size_t catlen = sep - name;

            // copy the read-only substring forming a locale name
            // into a writeable buffer so that it can be NUL-terminated
            const __rw_chararray shortname (name, catlen);

            __rw_chararray longname;

            // convert the (possibly abbreviated) name or a locale alias
            // into the full name uniquely identifying the locale (e.g.,
            // all of "de," "de_DE," and "german" can expand into the
            // full canonical name "de_DE.ISO-8869-1"; this is necessary
            // to guarantee that the internal locale repository doesn't
            // contain duplicate entries)
            const char* const fullname =
                __rw_locale_name (__rw_cats [i].cat, shortname.data (),
                                  longname);

            if (!fullname)
                return 0;

            const size_t namelen = strlen (fullname);

            _RWSTD_ASSERT (0 != namelen);

            // determine if the new category name is the same as the first
            // one (if it is, it is also the same as all subsequent ones,
            // otherwise `same_cats' is already set to false)
            if (same_cats && i)
                same_cats =    !memcmp (namebuf.data (), fullname, namelen)
                            && *_RWSTD_CAT_SEP == namebuf.data () [namelen];

            namebuf.append (fullname, namelen);

            if (++i == __rw_n_cats || !*sep)
                break;

            namebuf.append (_RWSTD_CAT_SEP, 1);

            name = sep + 1;
        }
    }
    else if ('\0' == *name) {

        // no separator found, set all categories
        const __rw_setlocale loc (name, _RWSTD_LC_ALL, 1 /* nothrow */);

        if (!loc.name ())
            return 0;

        // compose a string of category names separated by CAT_SEP
        for (size_t i = 0; ; ) {

            // retrieve the name of each idividual category
            const char* const fullname = setlocale (__rw_cats [i].cat, 0);

            // call to setlocale() must succeed if `loc' succeeded
            _RWSTD_ASSERT (0 != fullname);

            const size_t namelen = strlen (fullname);

            if (same_cats && i)
                same_cats =    !memcmp (namebuf.data (), fullname, namelen)
                            && *_RWSTD_CAT_SEP == namebuf.data () [namelen];

            namebuf.append (fullname, namelen);

            if (++i == __rw_n_cats)
                break;

            namebuf.append (_RWSTD_CAT_SEP, 1);
        }
    }
    
    if (*namebuf.data ()) {

        if (same_cats && __rw_facet::_C_opts & __rw_facet::_C_condensed_name) {

            // all categories were the same, store just the first one

            char* const  data   = namebuf.data ();
            const size_t sepinx = strchr (data, *_RWSTD_CAT_SEP) - data;

            // NUL-terminate at the first separator
            namebuf.acquire (data, sepinx);
            namebuf.append ("", 1);
        }
    }
    else {

        const char* const fullname =
            __rw_locale_name (_RWSTD_LC_ALL, name, namebuf);

        if (!fullname)
            return 0;
    }

    return namebuf.data ();

    
#if 0

    // points to the next category name
    const char *next = strchr (name, *_RWSTD_CAT_SEP);

    if (next && *next) {

            // save the end of the first name to detect combined locale
            // names composed of categories referring to the same locale
            char *first_end = bufbeg;

            // name is a string of locale category names; compose
            // an equivalent string obtained by concatenating the
            // results of calling setlocale() on each
            // substring

            const char *ps = name;

            size_t __i = 0;
            do {
                if (!next)
                    next = ps + strlen (ps);

                memcpy (pbuf, ps, next - ps);
                pbuf [next - ps] = '\0';

                if (__i < __rw_n_cats) {

                    const int cat = __rw_cats [__i++].cat;

                    // get the actual locale name for each category
                    // and append it to the end of the name buffer
                    if (!__rw_locale_name (cat, pbuf, pbuf, pbuf - bufbeg))
                        return 0;   // name not recognized
                }

                const size_t len = strlen (pbuf);

                if (first_end == bufbeg)
                    first_end = pbuf + len;
                else if (   first_end
                         && (   size_t (first_end - bufbeg) != len
                             || memcmp (bufbeg, pbuf, len))) {
                    // category name differs from the first (i.e., category
                    // names will be cobined) no need to check further
                    first_end = 0;
                }

                // advance to the next name
                pbuf    += len;
                *pbuf++  = *_RWSTD_CAT_SEP;

                // reached the end of the (not `sep'-terminated) list
                if ('\0' == *next)
                    break;

                ps    = next + 1;
                next  = strchr (ps, *_RWSTD_CAT_SEP);
            } while (*ps);

            *pbuf = '\0';

            // assume the native locale for all missing categories
            while (__i < __rw_n_cats) {

                const int cat = __rw_cats [__i++].cat;

                const __rw_setlocale loc ("", cat, 1 /* nothrow */);

                if (!loc.name ())
                    return 0;

                const char* catname = setlocale (cat, 0);

                _RWSTD_ASSERT (0 != catname);

                strcat (pbuf, catname);

                // compare the category name with the first one and remember
                // if they differ (to detect all the same category names)
                if (first_end && memcmp (bufbeg, name, first_end - name))
                    first_end = 0;

                pbuf    += strlen (pbuf);
                *pbuf++  = *_RWSTD_CAT_SEP;
            }

            // remove the last separator
            if (pbuf [-1] == *_RWSTD_CAT_SEP)
                pbuf [-1] = '\0';

            // if non-0, all categories come from the same locale
            // keep the first name and chop off the rest
            if (   __rw_facet::_C_opts & __rw_facet::_C_condensed_name
                && first_end)
                bufbeg [first_end - bufbeg] = '\0';
        }
        else {
            // all categories have the same name in named locales

            name = __rw_locale_name (_RWSTD_LC_ALL, name, bufbeg, bufsize);
            if (!name)
                return 0;
        }
    }

    return bufbeg;

#endif
}


size_t __rw_locale::
_C_get_facet_inx (size_t id) const
{
    // verify that facet's id is initialized
    _RWSTD_ASSERT (id);

    // standard facet's id are one greater than their index
    if (id <= _C_n_std_facets)
        return id - 1;

    _RWSTD_ASSERT (!_C_n_usr_facets || _C_usr_facets);

    // linear search through user-defined facets (if any)
    for (size_t i = 0; i != _C_n_usr_facets; ++i) {

        _RWSTD_ASSERT (_C_usr_facets [i]->_C_pid);

        if (*_C_usr_facets [i]->_C_pid == id)
            return i + _C_n_std_facets;
    }

    return _RWSTD_SIZE_MAX;
}


__rw_locale::
__rw_locale (const char *name)
    : _C_usr_facets (0), _C_n_usr_facets (0), _C_ref (1),
      _C_std_facet_bits (0), _C_byname_facet_bits (0)
{
    _RWSTD_ASSERT (name);

    // verify that name doesn't refer to an unnamed (combined) locale
    _RWSTD_ASSERT (!strchr (name, '*'));

    if ('\0' == *name) {

        __rw_chararray fullname;
        fullname.acquire (_C_namebuf, 0);

        // get the names of locales for all standard categories
        // avoiding dynamic memory allocation if possible
        _C_name = __rw_expand_name (fullname, name);

        fullname.release ();

        // caller must guarantee that `name' is valid
        _RWSTD_ASSERT (0 != _C_name);

        // note that `name' may not be the same as `_C_name' at this point
    }
    else {
        const size_t namelen = strlen (name) + 1;

        // assume name is well-formed and valid (checked by caller)
        char* const tmp = namelen < sizeof _C_namebuf
            ? _C_namebuf : new char [namelen];

        memcpy (tmp, name, namelen);

        _C_name = tmp;
    }

   // all facets are standard
   _C_std_facet_bits = _C_all;

   // byname facets determined below
   _C_byname_facet_bits = 0;

   if (strchr (_C_name, *_RWSTD_CAT_SEP)) {

       // name consist of multiple locale names; iterate over them all
       // setting byname facet bits for each named category
       size_t inx = 0;

       for (const char *nm = _C_name; *nm && inx != __rw_n_cats; ++nm) {

           if ('C' != nm [0] || *_RWSTD_CAT_SEP != nm [1])
               _C_byname_facet_bits |= __rw_cats [inx].facet_bits;

           nm = strchr (nm, *_RWSTD_CAT_SEP);
           if (!nm)
               break;

           ++inx;
       }
   }
   else {
       // all facets (except for num_{get,put}) are byname in non-C locales
       if (!__rw_is_C (_C_name))
           _C_byname_facet_bits = _C_all;
   }

#if defined (__i386__) || !defined (__GNUG__) || __GNUG__ < 3

   memset (_C_std_facets, 0, sizeof _C_std_facets);

#else   // !i86  || !gcc 3.x

   // Working around a gcc 3.1 optimizer bug on SPARC (and possibly
   // other RISC architectures) where, when generating PIC, _C_std_facets
   // ends up being 4-byte aligned and gcc replaces memset() with a series
   // of std %o1, [_C_std_facets + i] instructions with %o1 being 0 and i
   // being 0, 8, 16, etc. and std operating on 64-bit double words. The
   // first such misaligned std operation causes a SIGBUS

   for (size_t i = 0; i != _C_n_std_facets; ++i)
       _C_std_facets [i] = 0;

#endif   // i86/gcc 3.x

}


// convert a LC_XXX constant to a locale::category value
/* static */ int __rw_locale::
_C_LC2category (int cat)
{
    switch (cat) {
    case _RWSTD_LC_ALL:      cat = __rw_cat_all; break;
    case _RWSTD_LC_COLLATE:  cat = __rw_cat_collate; break;
    case _RWSTD_LC_CTYPE:    cat = __rw_cat_ctype; break;
    case _RWSTD_LC_MONETARY: cat = __rw_cat_monetary; break;
    case _RWSTD_LC_NUMERIC:  cat = __rw_cat_numeric; break;
    case _RWSTD_LC_TIME:     cat = __rw_cat_time; break;
#ifdef _RWSTD_LC_MESSAGES
    case _RWSTD_LC_MESSAGES: cat = __rw_cat_messages; break;
#endif

    default:
        // assume `cat' is already a locale::category value
        break;
    }
    return cat;
}


// convert a LC_XXX constant to an internal bitset of facets
/* static */ int __rw_locale::
_C_LC2facet_bits (int cat)
{
    int bits;

    switch (cat) {
    case _RWSTD_LC_ALL:      bits = __rw_locale::_C_all; break;
    case _RWSTD_LC_COLLATE:  bits = __rw_locale::_C_collate; break;
    case _RWSTD_LC_CTYPE:    bits = __rw_locale::_C_ctype; break;
    case _RWSTD_LC_MONETARY: bits = __rw_locale::_C_monetary; break;
    case _RWSTD_LC_NUMERIC:  bits = __rw_locale::_C_numeric; break;
    case _RWSTD_LC_TIME:     bits = __rw_locale::_C_time; break;
#ifdef _RWSTD_LC_MESSAGES
    case _RWSTD_LC_MESSAGES: bits = __rw_locale::_C_messages; break;
#endif

    default: {

        // assume `cat' is a locale::category value
        bits = 0;

        if (cat & __rw_cat_collate)
            bits |= _RW::__rw_locale::_C_collate;
        if (cat & __rw_cat_ctype)
            bits |= _RW::__rw_locale::_C_ctype;
        if (cat & __rw_cat_monetary)
            bits |= _RW::__rw_locale::_C_monetary;
        if (cat & __rw_cat_numeric)
            bits |= _RW::__rw_locale::_C_numeric;
        if (cat & __rw_cat_time)
            bits |= _RW::__rw_locale::_C_time;
        if (cat & __rw_cat_messages)
            bits |= _RW::__rw_locale::_C_messages;
        break;
    }

    }
    return bits;
}


__rw_locale::
~__rw_locale ()
{
    // verify that object isn't being destroyed prematurely
    _RWSTD_ASSERT (0 == _C_ref);

    if (_C_name != _C_namebuf)
        delete[] _RWSTD_CONST_CAST (char*, _C_name);

    // decrement the reference count of each installed facet
    // and delete each facet whose refcount drops to zero
    for (size_t i = 0; i != _C_n_std_facets; ++i) {

        if (!_C_std_facets [i])
            continue;

        _RWSTD_ASSERT (_C_std_facets [i]->_C_type != __rw_facet::_C_invalid);

        if (_C_std_facets [i]->_C_type) {

            // only standard facets (non-zero type) are managed
            // decrement the facet's reference count and remove
            // it from the global repository if it is 0
            const __rw_facet* const pfacet =
                __rw_facet::_C_manage (_C_std_facets [i],
                                       _C_std_facets [i]->_C_type,
                                       _C_std_facets [i]->_C_name,
                                       0);

            // verify that facet has been disposed of
            _RWSTD_ASSERT (0 == pfacet);
            _RWSTD_UNUSED (pfacet);
        }
        else {
            // decrement ref count (must not drop below 0)
            const size_t ref = _C_remove_ref (*_C_std_facets [i]);

            _RWSTD_ASSERT (ref + 1U != 0);

            if (0 == ref)
                delete _C_std_facets [i];
        }
    }

    // verify that either both are 0 or neither is 0
    _RWSTD_ASSERT (!_C_n_usr_facets == !_C_usr_facets);

    // decrement ref counts of user-defined facets and delete if necessary
    for (size_t j = 0; j != _C_n_usr_facets; ++j) {

        _RWSTD_ASSERT (_C_usr_facets [j]);

        _RWSTD_ASSERT (_C_usr_facets [j]->_C_type != __rw_facet::_C_invalid);

        // decrement ref count (must not drop below 0)
        const size_t ref = _C_remove_ref (*_C_usr_facets [j]);

        _RWSTD_ASSERT (ref + 1U != 0);

        if (0 == ref)
            delete _C_usr_facets [j];
    }

    delete[] _C_usr_facets;
}


extern "C" {

// compares two locales, returns 0 if equal, -1 if less, +1 otherwise
static int
cmplocales (const void *pv1, const void *pv2)
{
    _RWSTD_ASSERT (0 != pv1);
    _RWSTD_ASSERT (0 != pv2);

    const __rw_locale* const pl1 =
        *_RWSTD_STATIC_CAST (const __rw_locale* const*, pv1);
    const __rw_locale* const pl2 =
        *_RWSTD_STATIC_CAST (const __rw_locale* const*, pv2);

    _RWSTD_ASSERT (0 != pl1->_C_get_name ());
    _RWSTD_ASSERT (0 != pl1->_C_get_name ());

    return strcmp (pl1->_C_get_name (), pl2->_C_get_name ());
}


// compares a key to a locale, returns 0 if equal, -1 if less, +1 otherwise
static int
cmplocale (const void *pv1, const void *pv2)
{
    _RWSTD_ASSERT (0 != pv1);
    _RWSTD_ASSERT (0 != pv2);

    const char* const nm1 = _RWSTD_STATIC_CAST (const char*, pv1);

    const __rw_locale* const plocale =
        *_RWSTD_STATIC_CAST (const __rw_locale* const*, pv2);

    _RWSTD_ASSERT (0 != nm1);
    _RWSTD_ASSERT (0 != plocale->_C_get_name ());

    return strcmp (nm1, plocale->_C_get_name ());
}

}   // extern "C"


// manages a global, per-process repository of locale bodies according
// to the following table:

//     plocale   locname   algorithm
//        0         0      retrieve the global locale
//        0       non-0    find named locale in repository and increment
//                         its ref count if found, or construct it with
//                         ref count of 1 and add it otherwise
//      non-0       0      make `plocale' the new global locale and
//                         return the previous global locale
//      non-0     non-0    find locale in repository, decrement its ref
//                         count, and remove it if the ref count is 0

/* static */ __rw_locale*
__rw_locale::
_C_manage (__rw_locale *plocale, const char *locname)
{
    // a per-process array of locale body pointers
    static __rw_locale*  locale_buf [8];
    static __rw_locale** locales        = locale_buf;
    static __rw_locale*  classic        = 0;
    static size_t        n_locales      = 0;
    static size_t        locale_bufsize =
        sizeof locale_buf / sizeof *locale_buf;

    if (!locname) {

        // manage the global locale

        static __rw_locale* global = 0;

        if (!global) {

            static volatile long ginit /* = 0 */;

            if (!ginit && 1 == _RWSTD_ATOMIC_PREINCREMENT (ginit, false)) {
                global  = _C_manage (0, "C");
                ginit  += 1000;
            }
            else {
                while (ginit < 1000);
            }
        }

        // re-entrant
        _RWSTD_MT_STATIC_GUARD (_RW::__rw_locale);

        __rw_locale* const tmp = global;

        _RWSTD_ASSERT (0 != tmp);

        if (plocale) {
            // replace the global locale with `plocale'

            // increment the future global locale's ref count first
            _RWSTD_ATOMIC_PREINCREMENT (plocale->_C_ref, false);

            // and then set the global locale
            global = plocale;
        }
        else {

            // retrieve the global locale

            // always increment a ref count, even if `global' is being set
            // (and its ref count is > 0), to prevent its ref count from
            // dropping to 0
            _RWSTD_ATOMIC_PREINCREMENT (tmp->_C_ref, false);
        }

        return tmp;
    }


    // re-entrant to protect static local data structures
    // (not the locales themselves)
    _RWSTD_MT_STATIC_GUARD (_RW::__rw_locale);

    // determine whether `locname' refers to the classic C locale
    // (e.g., it could be any of "C", "POSIX", "C C C C C C", etc.)
    bool is_C_locale = __rw_is_C (locname);

    // substitute the fully expanded libc name for the classic C locale,
    // i.e., the result of calling std::setlocale ("C")
    if (is_C_locale)
        locname = __rw_C_locale_name;

    __rw_chararray fullname;

    if (!plocale && !is_C_locale) {
        // to avoid unnecessary calls to setlocale() only get cat names
        // when composing a locale name, otherwise the locale name is
        // assumed to be correct and complete
        locname = __rw_expand_name (fullname, locname);

        if (!locname)
            return 0;   // program error

        is_C_locale = __rw_is_C (locname);

        if (is_C_locale)
            locname = __rw_C_locale_name;
    }

    if (plocale) {
        // remove locale from the locale repository (if it is found) and
        // destroy it (the classic C locale is never destroyed)

        _RWSTD_ASSERT (0 != n_locales);

        const void* const pl =
            bsearch (locname, locales, n_locales, sizeof *locales, &cmplocale);
        if (pl) {

            const size_t inx =
                  _RWSTD_STATIC_CAST (const __rw_locale* const*, pl)
                - _RWSTD_CONST_CAST (const __rw_locale* const*, locales);

            plocale = locales [inx];

            const size_t ref =
                _RWSTD_ATOMIC_PREDECREMENT (plocale->_C_ref, false);

            _RWSTD_ASSERT (_RWSTD_SIZE_MAX != ref);

            if (0 == ref) {

                static const size_t bufsize =
                    sizeof locale_buf / sizeof *locale_buf;

                --n_locales;

                if (n_locales < bufsize / 2 && locales != locale_buf) {

                    _RWSTD_ASSERT (inx < bufsize);

                    // when the number of locales in the dynamically
                    // allocated repository drops below half the capacity
                    // of the statically allocated buffer, copy locales
                    // from the former into the latter and deallocate the
                    // former
                    memcpy (locale_buf, locales, inx * sizeof (*locales));

                    memcpy (locale_buf + inx, locales + inx + 1,
                            (n_locales - inx) * sizeof (*locales));

                    delete[] locales;
                    locales = locale_buf;
                }
                else {
                    // move facet pointers back
                    memmove (locales + inx, locales + inx + 1,
                             (n_locales - inx) * sizeof (*locales));
                }

                _RWSTD_ASSERT (0 != plocale->_C_name);

                // only named locales (i.e., other than the C locale) 
                // are deleted
                if (!__rw_is_C (plocale->_C_name))
                    delete plocale;
            }
        }
        else {

            // object is the classic C locale which is never destroyed
            _RWSTD_ASSERT (plocale->_C_name);
            _RWSTD_ASSERT (__rw_is_C (plocale->_C_name));

            const size_t ref =
                _RWSTD_ATOMIC_PREDECREMENT (plocale->_C_ref, false);

            _RWSTD_ASSERT (ref + 1U != 0);
            _RWSTD_UNUSED (ref);
         }
        
        plocale = 0;
    }
    else {

        // find locale in the repository or construct it if not found

        const void* const pcl =
            bsearch (locname, locales, n_locales, sizeof *locales, &cmplocale);

        if (pcl) {
            // facet already exists in the repository, bump up its ref count

            void* const pl = _RWSTD_CONST_CAST (void*, pcl);

            plocale  = *_RWSTD_STATIC_CAST (__rw_locale**, pl);

            _RWSTD_ASSERT (0 != plocale);

            _RWSTD_ATOMIC_PREINCREMENT (plocale->_C_ref, false);
        }
        else {

            if (n_locales == locale_bufsize) {

                // reallocate buffer of facet pointers
                __rw_locale** const tmp =
                    new __rw_locale* [n_locales * 2];

                memcpy (tmp, locales, n_locales * sizeof *tmp);

                if (locales != locale_buf)
                    delete[] locales;

                locales         = tmp;
                locale_bufsize *= 2;
            }

            if (__rw_is_C (locname)) {

                if (!classic) {

                    // the classic C locale is statically allocated
                    // and not destroyed during the lifetime of the process
                    static union {
                        void* _C_align;
                        char  _C_buf [sizeof (__rw_locale)];
                    } classic_body;

                    // construct a locale body in place
                    // with the initial reference count of 1
                    classic = new (&classic_body) __rw_locale (locname);

                    _RWSTD_ASSERT (1 == classic->_C_ref);
                }
                else {
                    _RWSTD_ASSERT (0 != classic);

                    _RWSTD_ATOMIC_PREINCREMENT (classic->_C_ref, false);
                }

                plocale = classic;
            }
            else {
                plocale = new __rw_locale (locname);

                _RWSTD_ASSERT (1 == plocale->_C_ref);
            }

            _RWSTD_ASSERT (plocale);

            // add locale body pointer to the end of the repository
            locales [n_locales++] = plocale;

            // sort pointers for fast access
            qsort (locales, n_locales, sizeof *locales, &cmplocales);
        }
    }

    return plocale;
}


// returns true iff all the facets in the given locale category
// installed in `*this' are being globally managed by the library
// if (cat == locale::none) holds, returns true iff the entire
// locale body is being managed
bool __rw_locale::
_C_is_managed (int cat) const
{
    // `cat' must be a valid category
    _RWSTD_ASSERT (_C_check_category (_C_LC2category (cat)));

    if (cat == __rw_cat_none) {

        // locales containing any user-defined facets are not globally managed
        if (_C_n_usr_facets) {
            _RWSTD_ASSERT (0 != _C_usr_facets);
            return false;
        }

        // unless all facets in the same category come either from
        // the C locale or from some named locale the locale object
        // containing the facets is not managed (this test doesn't
        // detect categores of all byname facets not all of which
        // belong to the same named locale)
        if (   (_C_std_facet_bits & _C_all) != _C_all
            || (_C_byname_facet_bits & _C_collate)
            && (_C_byname_facet_bits & _C_collate)  != _C_collate
            || (_C_byname_facet_bits & _C_ctype)
            && (_C_byname_facet_bits & _C_ctype)    != _C_ctype
            || (_C_byname_facet_bits & _C_monetary)
            && (_C_byname_facet_bits & _C_monetary) != _C_monetary
            || (_C_byname_facet_bits & _C_numeric)
            && (_C_byname_facet_bits & _C_numeric)  != _C_numeric
            || (_C_byname_facet_bits & _C_time)
            && (_C_byname_facet_bits & _C_time)     != _C_time
            || (_C_byname_facet_bits & _C_messages)
            && (_C_byname_facet_bits & _C_messages) != _C_messages)
            return false;

        // check whether all _byname facets in each category belong
        // to the same named locale; facets witout byname forms are
        // excluded from this test
        // note that the locale may have a combined name such as
        // "/de/en/fr/it/ja/ru"
        const char* locname = _C_name ? _C_name : "C";

        if (*_RWSTD_CAT_SEP == *locname)
            ++locname;

        // find the first category separator (if any) and compute
        // the length of the name of the first category's locale
        // (don't bother when combined locales don't exist, i.e.,
        // when no locale separator is defined)
        const char* next =
            *_RWSTD_CAT_SEP ? strchr (locname, *_RWSTD_CAT_SEP) : 0;

        size_t loclen = next ? next - locname : strlen (locname);

        // iterate over all standard facets, comparing the name of the
        // locale each comes from with the name of the category encoded
        // in the locale name for equality; a mismatch indicates that
        // the locale is not managed
        for (size_t i = 0, catinx = 0; i != _C_n_std_facets; ++i) {

            if (0 == _C_std_facets [i]) {
                // skip facets that are not installed
                continue;
            }

            const __rw_facet::_C_facet_type facet_type =
                _C_get_facet_type (*_C_std_facets [i]);

            switch (facet_type) {
            case __rw_facet::_C_money_get:
            case __rw_facet::_C_money_put:
            case __rw_facet::_C_num_get:
            case __rw_facet::_C_num_put:
            case __rw_facet::_C_wmoney_get:
            case __rw_facet::_C_wmoney_put:
            case __rw_facet::_C_wnum_get:
            case __rw_facet::_C_wnum_put:
                // skip facets with no _byname forms
                continue;
            default:
                break;
            }

            // iterate through the names of categories in the combined
            // locale name looking for one that the facet belongs to
            while (next && !(__rw_cats [catinx].facet_bits & (1 << i))) {

                if (*next) {
                    // advance past the category separator to the name
                    // of the next category in the (potentially combined)
                    // locale name
                    _RWSTD_ASSERT (*next == *_RWSTD_CAT_SEP);

                   locname = ++next;
                    ++catinx;
                }
                else {
                    // reset to the name of the first category
                    locname = _C_name ? _C_name : "C";
                    catinx  = 0;
                }

                // skip over the category separator
                if (*_RWSTD_CAT_SEP == *locname)
                    ++locname;

                next = strchr (locname, *_RWSTD_CAT_SEP);
                if (next)
                    loclen = next - locname;
                else {
                    loclen = strlen (locname);
                    next   = "";
                }
            }

            // get the facet name (or "C" if null)
            const char* const facet_name =
                _C_std_facets [i]->_C_get_name ();

            _RWSTD_ASSERT (0 != facet_name);
            _RWSTD_ASSERT (0 != locname);

            // mismatch indicates a combined category
            if (   strlen (facet_name) != loclen
                || memcmp (locname, facet_name, loclen)) {
                // locales with heterogeneous categories are not managed
                return false;
            }
        }

        // locales with all heterogeneous categories are managed
        return true;
    }

    // in order for the entire category to be considered globally managed,
    // all its facets must come from the same (named or unnamed) locale
    // i.e., if the LC_CTYPE category contains codecvt from "de_DE" and
    // ctype from "en_US", the category is not considered globally managed
    // because it doesn't have a unambiguous name
    const int bits = _C_LC2facet_bits (cat);

    const int std_bits = bits & int (_C_std_facet_bits);

    if (std_bits ? bits == std_bits
                 : bits == (bits & int (_C_byname_facet_bits)))
        return true;

    return false;
}


}   // namespace __rw


/***************************************************************************/


#include <memory>
#include <loc/_locale.h>

#include <rw/_defs.h>


_RWSTD_NAMESPACE (std) { 


const locale&
locale::
operator= (const locale &rhs) _THROWS (())
{
    // copy body and bump up a ref count in `rhs'
    _RW::__rw_locale* const body = rhs._C_body;

    _RWSTD_ATOMIC_PREINCREMENT (rhs._C_body->_C_ref, false);


    // _C_body is never 0 except in objects still being constructed by
    // the combining ctor locale::locale<Facet>(const locale&, Facet*)

    if (_C_body) {
        // dispose of old body (dtor decrements ref count and possibly deletes)
        locale destroy (*_C_body);

        _RWSTD_UNUSED (destroy);
    }

    // assign new body
    _C_body = body;

    return *this;
}


}   // namespace std
