/***************************************************************************
 *
 * 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$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you 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.
 *
 * Copyright 2001-2008 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

#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


#if 6 == _RWSTD_HP_aCC_MAJOR && _RWSTD_HP_aCC_MINOR <= 1600
   // silence bogus HP aCC 6.16/cadvise warning #20200-D:
   // Potential null pointer dereference
#  pragma diag_suppress 20200
#endif


_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 _THROWS (())
{
    // 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) _THROWS (())
{
    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) _THROWS (())
{
    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 () _THROWS (())
{
    // 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) _THROWS (())
{
    _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) _THROWS (())
{
    _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) {

            // volatile to prevent optimizers from turning
            // the while statement below into an infinite loop
            static volatile int ginit /* = 0 */;

            // cast ginit to int& (STDCXX-792)
            // casting should be removed after fixing STDCXX-794
            if (!ginit && 1 == _RWSTD_ATOMIC_PREINCREMENT (
                    _RWSTD_CONST_CAST (int&, ginit), false)) {
                global  = _C_manage (0, "C");
                ginit  += 1000;
            }
            else {
                // ginit must be volatile to prevent optimizers
                // from turning this into an infinite loop
                while (ginit < 1000) { /* empty */ }
            }
        }

        // 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;

                    // point at the statically allocated buffer and reset
                    // the current capacity to the original capacity
                    locales        = locale_buf;
                    locale_bufsize = bufsize;
                }
                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 _THROWS (())
{
    // `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
