Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/locale/locale.c')
-rw-r--r--newlib/libc/locale/locale.c1039
1 files changed, 0 insertions, 1039 deletions
diff --git a/newlib/libc/locale/locale.c b/newlib/libc/locale/locale.c
deleted file mode 100644
index 37ac5e947..000000000
--- a/newlib/libc/locale/locale.c
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
-FUNCTION
-<<setlocale>>, <<localeconv>>---select or query locale
-
-INDEX
- setlocale
-INDEX
- localeconv
-INDEX
- _setlocale_r
-INDEX
- _localeconv_r
-
-ANSI_SYNOPSIS
- #include <locale.h>
- char *setlocale(int <[category]>, const char *<[locale]>);
- lconv *localeconv(void);
-
- char *_setlocale_r(void *<[reent]>,
- int <[category]>, const char *<[locale]>);
- lconv *_localeconv_r(void *<[reent]>);
-
-TRAD_SYNOPSIS
- #include <locale.h>
- char *setlocale(<[category]>, <[locale]>)
- int <[category]>;
- char *<[locale]>;
-
- lconv *localeconv();
-
- char *_setlocale_r(<[reent]>, <[category]>, <[locale]>)
- char *<[reent]>;
- int <[category]>;
- char *<[locale]>;
-
- lconv *_localeconv_r(<[reent]>);
- char *<[reent]>;
-
-DESCRIPTION
-<<setlocale>> is the facility defined by ANSI C to condition the
-execution environment for international collating and formatting
-information; <<localeconv>> reports on the settings of the current
-locale.
-
-This is a minimal implementation, supporting only the required <<"POSIX">>
-and <<"C">> values for <[locale]>; strings representing other locales are not
-honored unless _MB_CAPABLE is defined.
-
-If _MB_CAPABLE is defined, POSIX locale strings are allowed, following
-the form
-
- language[_TERRITORY][.charset][@@modifier]
-
-<<"language">> is a two character string per ISO 639, or, if not available
-for a given language, a three character string per ISO 639-3.
-<<"TERRITORY">> is a country code per ISO 3166. For <<"charset">> and
-<<"modifier">> see below.
-
-Additionally to the POSIX specifier, the following extension is supported
-for backward compatibility with older implementations using newlib:
-<<"C-charset">>.
-Instead of <<"C-">>, you can also specify <<"C.">>. Both variations allow
-to specify language neutral locales while using other charsets than ASCII,
-for instance <<"C.UTF-8">>, which keeps all settings as in the C locale,
-but uses the UTF-8 charset.
-
-The following charsets are recognized:
-<<"UTF-8">>, <<"JIS">>, <<"EUCJP">>, <<"SJIS">>, <<"KOI8-R">>, <<"KOI8-U">>,
-<<"GEORGIAN-PS">>, <<"PT154">>, <<"TIS-620">>, <<"ISO-8859-x">> with
-1 <= x <= 16, or <<"CPxxx">> with xxx in [437, 720, 737, 775, 850, 852, 855,
-857, 858, 862, 866, 874, 932, 1125, 1250, 1251, 1252, 1253, 1254, 1255, 1256,
-1257, 1258].
-
-Charsets are case insensitive. For instance, <<"EUCJP">> and <<"eucJP">>
-are equivalent. Charset names with dashes can also be written without
-dashes, as in <<"UTF8">>, <<"iso88591">> or <<"koi8r">>. <<"EUCJP">> and
-<<"EUCKR">> are also recognized with dash, <<"EUC-JP">> and <<"EUC-KR">>.
-
-Full support for all of the above charsets requires that newlib has been
-build with multibyte support and support for all ISO and Windows Codepage.
-Otherwise all singlebyte charsets are simply mapped to ASCII. Right now,
-only newlib for Cygwin is built with full charset support by default.
-Under Cygwin, this implementation additionally supports the charsets
-<<"GBK">>, <<"GB2312">>, <<"eucCN">>, <<"eucKR">>, and <<"Big5">>. Cygwin
-does not support <<"JIS">>.
-
-Cygwin additionally supports locales from the file
-/usr/share/locale/locale.alias.
-
-(<<"">> is also accepted; if given, the settings are read from the
-corresponding LC_* environment variables and $LANG according to POSIX rules.
-
-This implementation also supports the modifier <<"cjknarrow">>, which
-affects how the functions <<wcwidth>> and <<wcswidth>> handle characters
-from the "CJK Ambiguous Width" category of characters described at
-http://www.unicode.org/reports/tr11/#Ambiguous. These characters have a width
-of 1 for singlebyte charsets and a width of 2 for multibyte charsets
-other than UTF-8. For UTF-8, their width depends on the language specifier:
-it is 2 for <<"zh">> (Chinese), <<"ja">> (Japanese), and <<"ko">> (Korean),
-and 1 for everything else. Specifying <<"cjknarrow">> forces a width of 1,
-independent of charset and language.
-
-If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns a
-pointer to the string representing the current locale. The acceptable
-values for <[category]> are defined in `<<locale.h>>' as macros
-beginning with <<"LC_">>.
-
-<<localeconv>> returns a pointer to a structure (also defined in
-`<<locale.h>>') describing the locale-specific conventions currently
-in effect.
-
-<<_localeconv_r>> and <<_setlocale_r>> are reentrant versions of
-<<localeconv>> and <<setlocale>> respectively. The extra argument
-<[reent]> is a pointer to a reentrancy structure.
-
-RETURNS
-A successful call to <<setlocale>> returns a pointer to a string
-associated with the specified category for the new locale. The string
-returned by <<setlocale>> is such that a subsequent call using that
-string will restore that category (or all categories in case of LC_ALL),
-to that state. The application shall not modify the string returned
-which may be overwritten by a subsequent call to <<setlocale>>.
-On error, <<setlocale>> returns <<NULL>>.
-
-<<localeconv>> returns a pointer to a structure of type <<lconv>>,
-which describes the formatting and collating conventions in effect (in
-this implementation, always those of the C locale).
-
-PORTABILITY
-ANSI C requires <<setlocale>>, but the only locale required across all
-implementations is the C locale.
-
-NOTES
-There is no ISO-8859-12 codepage. It's also refused by this implementation.
-
-No supporting OS subroutines are required.
-*/
-
-/* Parts of this code are originally taken from FreeBSD. */
-/*
- * Copyright (c) 1996 - 2002 FreeBSD Project
- * Copyright (c) 1991, 1993
- * 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.
- *
- * 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.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <newlib.h>
-#include <errno.h>
-#include <locale.h>
-#include <string.h>
-#include <limits.h>
-#include <reent.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include "lmessages.h"
-#include "lmonetary.h"
-#include "lnumeric.h"
-#include "lctype.h"
-#include "../stdlib/local.h"
-
-#define _LC_LAST 7
-#define ENCODING_LEN 31
-
-int __EXPORT __mb_cur_max = 1;
-
-int __nlocale_changed = 0;
-int __mlocale_changed = 0;
-char *_PathLocale = NULL;
-
-static
-struct lconv lconv =
-{
- ".", "", "", "", "", "", "", "", "", "",
- CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
- CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
- CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
- CHAR_MAX, CHAR_MAX
-};
-
-#ifdef _MB_CAPABLE
-/*
- * Category names for getenv()
- */
-static char *categories[_LC_LAST] = {
- "LC_ALL",
- "LC_COLLATE",
- "LC_CTYPE",
- "LC_MONETARY",
- "LC_NUMERIC",
- "LC_TIME",
- "LC_MESSAGES",
-};
-
-/*
- * Default locale per POSIX. Can be overridden on a per-target base.
- */
-#ifndef DEFAULT_LOCALE
-#define DEFAULT_LOCALE "C"
-#endif
-/*
- * This variable can be changed by any outside mechanism. This allows,
- * for instance, to load the default locale from a file.
- */
-char __default_locale[ENCODING_LEN + 1] = DEFAULT_LOCALE;
-
-/*
- * Current locales for each category
- */
-static char current_categories[_LC_LAST][ENCODING_LEN + 1] = {
- "C",
- "C",
- "C",
- "C",
- "C",
- "C",
- "C",
-};
-
-/*
- * The locales we are going to try and load
- */
-static char new_categories[_LC_LAST][ENCODING_LEN + 1];
-static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
-
-static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
-static char *currentlocale(void);
-static char *loadlocale(struct _reent *, int);
-static const char *__get_locale_env(struct _reent *, int);
-
-#endif /* _MB_CAPABLE */
-
-#if 0 /*def __CYGWIN__ TODO: temporarily(?) disable C == UTF-8 */
-static char lc_ctype_charset[ENCODING_LEN + 1] = "UTF-8";
-static char lc_message_charset[ENCODING_LEN + 1] = "UTF-8";
-#else
-static char lc_ctype_charset[ENCODING_LEN + 1] = "ASCII";
-static char lc_message_charset[ENCODING_LEN + 1] = "ASCII";
-#endif
-static int lc_ctype_cjk_lang = 0;
-
-char *
-_DEFUN(_setlocale_r, (p, category, locale),
- struct _reent *p _AND
- int category _AND
- _CONST char *locale)
-{
-#ifndef _MB_CAPABLE
- if (locale)
- {
- if (strcmp (locale, "POSIX") && strcmp (locale, "C")
- && strcmp (locale, ""))
- return NULL;
- }
- return "C";
-#else /* !_MB_CAPABLE */
- int i, j, len, saverr;
- const char *env, *r;
-
- if (category < LC_ALL || category >= _LC_LAST)
- {
- p->_errno = EINVAL;
- return NULL;
- }
-
- if (locale == NULL)
- return category != LC_ALL ? current_categories[category] : currentlocale();
-
- /*
- * Default to the current locale for everything.
- */
- for (i = 1; i < _LC_LAST; ++i)
- strcpy (new_categories[i], current_categories[i]);
-
- /*
- * Now go fill up new_categories from the locale argument
- */
- if (!*locale)
- {
- if (category == LC_ALL)
- {
- for (i = 1; i < _LC_LAST; ++i)
- {
- env = __get_locale_env (p, i);
- if (strlen (env) > ENCODING_LEN)
- {
- p->_errno = EINVAL;
- return NULL;
- }
- strcpy (new_categories[i], env);
- }
- }
- else
- {
- env = __get_locale_env (p, category);
- if (strlen (env) > ENCODING_LEN)
- {
- p->_errno = EINVAL;
- return NULL;
- }
- strcpy (new_categories[category], env);
- }
- }
- else if (category != LC_ALL)
- {
- if (strlen (locale) > ENCODING_LEN)
- {
- p->_errno = EINVAL;
- return NULL;
- }
- strcpy (new_categories[category], locale);
- }
- else
- {
- if ((r = strchr (locale, '/')) == NULL)
- {
- if (strlen (locale) > ENCODING_LEN)
- {
- p->_errno = EINVAL;
- return NULL;
- }
- for (i = 1; i < _LC_LAST; ++i)
- strcpy (new_categories[i], locale);
- }
- else
- {
- for (i = 1; r[1] == '/'; ++r)
- ;
- if (!r[1])
- {
- p->_errno = EINVAL;
- return NULL; /* Hmm, just slashes... */
- }
- do
- {
- if (i == _LC_LAST)
- break; /* Too many slashes... */
- if ((len = r - locale) > ENCODING_LEN)
- {
- p->_errno = EINVAL;
- return NULL;
- }
- strlcpy (new_categories[i], locale, len + 1);
- i++;
- while (*r == '/')
- r++;
- locale = r;
- while (*r && *r != '/')
- r++;
- }
- while (*locale);
- while (i < _LC_LAST)
- {
- strcpy (new_categories[i], new_categories[i-1]);
- i++;
- }
- }
- }
-
- if (category != LC_ALL)
- return loadlocale (p, category);
-
- for (i = 1; i < _LC_LAST; ++i)
- {
- strcpy (saved_categories[i], current_categories[i]);
- if (loadlocale (p, i) == NULL)
- {
- saverr = p->_errno;
- for (j = 1; j < i; j++)
- {
- strcpy (new_categories[j], saved_categories[j]);
- if (loadlocale (p, j) == NULL)
- {
- strcpy (new_categories[j], "C");
- loadlocale (p, j);
- }
- }
- p->_errno = saverr;
- return NULL;
- }
- }
- return currentlocale ();
-#endif /* !_MB_CAPABLE */
-}
-
-#ifdef _MB_CAPABLE
-static char *
-currentlocale()
-{
- int i;
-
- (void)strcpy(current_locale_string, current_categories[1]);
-
- for (i = 2; i < _LC_LAST; ++i)
- if (strcmp(current_categories[1], current_categories[i])) {
- for (i = 2; i < _LC_LAST; ++i) {
- (void)strcat(current_locale_string, "/");
- (void)strcat(current_locale_string,
- current_categories[i]);
- }
- break;
- }
- return (current_locale_string);
-}
-#endif /* _MB_CAPABLE */
-
-#ifdef _MB_CAPABLE
-#ifdef __CYGWIN__
-extern void __set_charset_from_locale (const char *locale, char *charset);
-extern int __set_locale_from_locale_alias (const char *, char *);
-extern int __collate_load_locale (const char *, void *, const char *);
-#endif /* __CYGWIN__ */
-
-extern void __set_ctype (const char *charset);
-
-static char *
-loadlocale(struct _reent *p, int category)
-{
- /* At this point a full-featured system would just load the locale
- specific data from the locale files.
- What we do here for now is to check the incoming string for correctness.
- The string must be in one of the allowed locale strings, either
- one in POSIX-style, or one in the old newlib style to maintain
- backward compatibility. If the local string is correct, the charset
- is extracted and stored in lc_ctype_charset or lc_message_charset
- dependent on the cateogry. */
- char *locale = NULL;
- char charset[ENCODING_LEN + 1];
- unsigned long val;
- char *end, *c = NULL;
- int mbc_max;
- int (*l_wctomb) (struct _reent *, char *, wchar_t, const char *, mbstate_t *);
- int (*l_mbtowc) (struct _reent *, wchar_t *, const char *, size_t,
- const char *, mbstate_t *);
- int cjknarrow = 0;
-
- /* Avoid doing everything twice if nothing has changed. */
- if (!strcmp (new_categories[category], current_categories[category]))
- return current_categories[category];
-
-#ifdef __CYGWIN__
- /* This additional code handles the case that the incoming locale string
- is not valid. If so, it calls the function __set_locale_from_locale_alias,
- which is only available on Cygwin right now. The function reads the
- file /usr/share/locale/locale.alias. The file contains locale aliases
- and their replacement locale. For instance, the alias "french" is
- translated to "fr_FR.ISO-8859-1", the alias "thai" is translated to
- "th_TH.TIS-620". If successful, the function returns with a pointer
- to the second argument, which is a buffer in which the replacement locale
- gets stored. Otherwise the function returns NULL. */
- char tmp_locale[ENCODING_LEN + 1];
- int ret = 0;
-
-restart:
- if (!locale)
- locale = new_categories[category];
- else if (locale != tmp_locale)
- {
- locale = __set_locale_from_locale_alias (locale, tmp_locale);
- if (!locale)
- return NULL;
- }
-# define FAIL goto restart
-#else
- locale = new_categories[category];
-# define FAIL return NULL
-#endif
-
- /* "POSIX" is translated to "C", as on Linux. */
- if (!strcmp (locale, "POSIX"))
- strcpy (locale, "C");
- if (!strcmp (locale, "C")) /* Default "C" locale */
-#if 0 /*def __CYGWIN__ TODO: temporarily(?) disable C == UTF-8 */
- strcpy (charset, "UTF-8");
-#else
- strcpy (charset, "ASCII");
-#endif
- else if (locale[0] == 'C'
- && (locale[1] == '-' /* Old newlib style */
- || locale[1] == '.')) /* Extension for the C locale to allow
- specifying different charsets while
- sticking to the C locale in terms
- of sort order, etc. Proposed in
- the Debian project. */
- {
- char *chp;
-
- c = locale + 2;
- strcpy (charset, c);
- if ((chp = strchr (charset, '@')))
- /* Strip off modifier */
- *chp = '\0';
- c += strlen (charset);
- }
- else /* POSIX style */
- {
- c = locale;
-
- /* Don't use ctype macros here, they might be localized. */
- /* Language */
- if (c[0] < 'a' || c[0] > 'z'
- || c[1] < 'a' || c[1] > 'z')
- FAIL;
- c += 2;
- /* Allow three character Language per ISO 639-3 */
- if (c[0] >= 'a' && c[0] <= 'z')
- ++c;
- if (c[0] == '_')
- {
- /* Territory */
- ++c;
- if (c[0] < 'A' || c[0] > 'Z'
- || c[1] < 'A' || c[1] > 'Z')
- FAIL;
- c += 2;
- }
- if (c[0] == '.')
- {
- /* Charset */
- char *chp;
-
- ++c;
- strcpy (charset, c);
- if ((chp = strchr (charset, '@')))
- /* Strip off modifier */
- *chp = '\0';
- c += strlen (charset);
- }
- else if (c[0] == '\0' || c[0] == '@')
- /* End of string or just a modifier */
-#ifdef __CYGWIN__
- /* The Cygwin-only function __set_charset_from_locale checks
- for the default charset which is connected to the given locale.
- The function uses Windows functions in turn so it can't be easily
- adapted to other targets. However, if any other target provides
- equivalent functionality, preferrably using the same function name
- it would be sufficient to change the guarding #ifdef. */
- __set_charset_from_locale (locale, charset);
-#else
- strcpy (charset, "ISO-8859-1");
-#endif
- else
- /* Invalid string */
- FAIL;
- }
- if (c && c[0] == '@')
- {
- /* Modifier */
- /* Only one modifier is recognized right now. "cjknarrow" is used
- to modify the behaviour of wcwidth() for East Asian languages.
- For details see the comment at the end of this function. */
- if (!strcmp (c + 1, "cjknarrow"))
- cjknarrow = 1;
- }
- /* We only support this subset of charsets. */
- switch (charset[0])
- {
- case 'U':
- case 'u':
- if (strcasecmp (charset, "UTF-8") && strcasecmp (charset, "UTF8"))
- FAIL;
- strcpy (charset, "UTF-8");
- mbc_max = 6;
- l_wctomb = __utf8_wctomb;
- l_mbtowc = __utf8_mbtowc;
- break;
-#ifndef __CYGWIN__
- /* Cygwin does not support JIS at all. */
- case 'J':
- case 'j':
- if (strcasecmp (charset, "JIS"))
- FAIL;
- strcpy (charset, "JIS");
- mbc_max = 8;
- l_wctomb = __jis_wctomb;
- l_mbtowc = __jis_mbtowc;
- break;
-#endif /* !__CYGWIN__ */
- case 'E':
- case 'e':
- if (strncasecmp (charset, "EUC", 3))
- FAIL;
- c = charset + 3;
- if (*c == '-')
- ++c;
- if (!strcasecmp (c, "JP"))
- {
- strcpy (charset, "EUCJP");
- mbc_max = 3;
- l_wctomb = __eucjp_wctomb;
- l_mbtowc = __eucjp_mbtowc;
- }
-#ifdef __CYGWIN__
- /* Newlib does neither provide EUC-KR nor EUC-CN, and Cygwin's
- implementation requires Windows support. */
- else if (!strcasecmp (c, "KR"))
- {
- strcpy (charset, "EUCKR");
- mbc_max = 2;
- l_wctomb = __kr_wctomb;
- l_mbtowc = __kr_mbtowc;
- }
- else if (!strcasecmp (c, "CN"))
- {
- strcpy (charset, "EUCCN");
- mbc_max = 2;
- l_wctomb = __gbk_wctomb;
- l_mbtowc = __gbk_mbtowc;
- }
-#endif /* __CYGWIN__ */
- else
- FAIL;
- break;
- case 'S':
- case 's':
- if (strcasecmp (charset, "SJIS"))
- FAIL;
- strcpy (charset, "SJIS");
- mbc_max = 2;
- l_wctomb = __sjis_wctomb;
- l_mbtowc = __sjis_mbtowc;
- break;
- case 'I':
- case 'i':
- /* Must be exactly one of ISO-8859-1, [...] ISO-8859-16, except for
- ISO-8859-12. This code also recognizes the aliases without dashes. */
- if (strncasecmp (charset, "ISO", 3))
- FAIL;
- c = charset + 3;
- if (*c == '-')
- ++c;
- if (strncasecmp (c, "8859", 4))
- FAIL;
- c += 4;
- if (*c == '-')
- ++c;
- val = _strtol_r (p, c, &end, 10);
- if (val < 1 || val > 16 || val == 12 || *end)
- FAIL;
- strcpy (charset, "ISO-8859-");
- c = charset + 9;
- if (val > 10)
- *c++ = '1';
- *c++ = val % 10 + '0';
- *c = '\0';
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_ISO
- l_wctomb = __iso_wctomb;
- l_mbtowc = __iso_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_ISO */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_ISO */
- break;
- case 'C':
- case 'c':
- if (charset[1] != 'P' && charset[1] != 'p')
- FAIL;
- strncpy (charset, "CP", 2);
- val = _strtol_r (p, charset + 2, &end, 10);
- if (*end)
- FAIL;
- switch (val)
- {
- case 437:
- case 720:
- case 737:
- case 775:
- case 850:
- case 852:
- case 855:
- case 857:
- case 858:
- case 862:
- case 866:
- case 874:
- case 1125:
- case 1250:
- case 1251:
- case 1252:
- case 1253:
- case 1254:
- case 1255:
- case 1256:
- case 1257:
- case 1258:
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
- l_wctomb = __cp_wctomb;
- l_mbtowc = __cp_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
- break;
- case 932:
- mbc_max = 2;
- l_wctomb = __sjis_wctomb;
- l_mbtowc = __sjis_mbtowc;
- break;
- default:
- FAIL;
- }
- break;
- case 'K':
- case 'k':
- /* KOI8-R, KOI8-U and the aliases without dash */
- if (strncasecmp (charset, "KOI8", 4))
- FAIL;
- c = charset + 4;
- if (*c == '-')
- ++c;
- if (*c == 'R' || *c == 'r')
- strcpy (charset, "CP20866");
- else if (*c == 'U' || *c == 'u')
- strcpy (charset, "CP21866");
- else
- FAIL;
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
- l_wctomb = __cp_wctomb;
- l_mbtowc = __cp_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
- break;
- case 'A':
- case 'a':
- if (strcasecmp (charset, "ASCII"))
- FAIL;
- strcpy (charset, "ASCII");
- mbc_max = 1;
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
- break;
- case 'G':
- case 'g':
-#ifdef __CYGWIN__
- /* Newlib does not provide GBK/GB2312 and Cygwin's implementation
- requires Windows support. */
- if (!strcasecmp (charset, "GBK")
- || !strcasecmp (charset, "GB2312"))
- {
- strcpy (charset, charset[2] == '2' ? "GB2312" : "GBK");
- mbc_max = 2;
- l_wctomb = __gbk_wctomb;
- l_mbtowc = __gbk_mbtowc;
- }
- else
-#endif /* __CYGWIN__ */
- /* GEORGIAN-PS and the alias without dash */
- if (!strncasecmp (charset, "GEORGIAN", 8))
- {
- c = charset + 8;
- if (*c == '-')
- ++c;
- if (strcasecmp (c, "PS"))
- FAIL;
- strcpy (charset, "CP101");
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
- l_wctomb = __cp_wctomb;
- l_mbtowc = __cp_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
- }
- else
- FAIL;
- break;
- case 'P':
- case 'p':
- /* PT154 */
- if (strcasecmp (charset, "PT154"))
- FAIL;
- strcpy (charset, "CP102");
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
- l_wctomb = __cp_wctomb;
- l_mbtowc = __cp_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
- break;
- case 'T':
- case 't':
- if (strncasecmp (charset, "TIS", 3))
- FAIL;
- c = charset + 3;
- if (*c == '-')
- ++c;
- if (strcasecmp (c, "620"))
- FAIL;
- strcpy (charset, "CP874");
- mbc_max = 1;
-#ifdef _MB_EXTENDED_CHARSETS_WINDOWS
- l_wctomb = __cp_wctomb;
- l_mbtowc = __cp_mbtowc;
-#else /* !_MB_EXTENDED_CHARSETS_WINDOWS */
- l_wctomb = __ascii_wctomb;
- l_mbtowc = __ascii_mbtowc;
-#endif /* _MB_EXTENDED_CHARSETS_WINDOWS */
- break;
-#ifdef __CYGWIN__
- /* Newlib does not provide Big5 and Cygwin's implementation
- requires Windows support. */
- case 'B':
- case 'b':
- if (strcasecmp (charset, "BIG5"))
- FAIL;
- strcpy (charset, "BIG5");
- mbc_max = 2;
- l_wctomb = __big5_wctomb;
- l_mbtowc = __big5_mbtowc;
- break;
-#endif /* __CYGWIN__ */
- default:
- FAIL;
- }
- switch (category)
- {
- case LC_CTYPE:
- strcpy (lc_ctype_charset, charset);
- __mb_cur_max = mbc_max;
- __wctomb = l_wctomb;
- __mbtowc = l_mbtowc;
- __set_ctype (charset);
- /* Determine the width for the "CJK Ambiguous Width" category of
- characters. This is used in wcwidth(). Assume single width for
- single-byte charsets, and double width for multi-byte charsets
- other than UTF-8. For UTF-8, use double width for the East Asian
- languages ("ja", "ko", "zh"), and single width for everything else.
- Single width can also be forced with the "@cjknarrow" modifier. */
- lc_ctype_cjk_lang = !cjknarrow
- && mbc_max > 1
- && (charset[0] != 'U'
- || strncmp (locale, "ja", 2) == 0
- || strncmp (locale, "ko", 2) == 0
- || strncmp (locale, "zh", 2) == 0);
-#ifdef __HAVE_LOCALE_INFO__
- ret = __ctype_load_locale (locale, (void *) l_wctomb, charset, mbc_max);
-#endif /* __HAVE_LOCALE_INFO__ */
- break;
- case LC_MESSAGES:
- strcpy (lc_message_charset, charset);
-#ifdef __HAVE_LOCALE_INFO__
- ret = __messages_load_locale (locale, (void *) l_wctomb, charset);
- if (!ret)
-#endif /* __HAVE_LOCALE_INFO__ */
- break;
-#ifdef __HAVE_LOCALE_INFO__
-#ifdef __CYGWIN__
- /* Right now only Cygwin supports a __collate_load_locale function at all. */
- case LC_COLLATE:
- ret = __collate_load_locale (locale, (void *) l_mbtowc, charset);
- break;
-#endif
- case LC_MONETARY:
- ret = __monetary_load_locale (locale, (void *) l_wctomb, charset);
- break;
- case LC_NUMERIC:
- ret = __numeric_load_locale (locale, (void *) l_wctomb, charset);
- break;
- case LC_TIME:
- ret = __time_load_locale (locale, (void *) l_wctomb, charset);
- break;
-#endif /* __HAVE_LOCALE_INFO__ */
- default:
- break;
- }
-#ifdef __HAVE_LOCALE_INFO__
- if (ret)
- FAIL;
-#endif /* __HAVE_LOCALE_INFO__ */
- return strcpy(current_categories[category], new_categories[category]);
-}
-
-static const char *
-__get_locale_env(struct _reent *p, int category)
-{
- const char *env;
-
- /* 1. check LC_ALL. */
- env = _getenv_r (p, categories[0]);
-
- /* 2. check LC_* */
- if (env == NULL || !*env)
- env = _getenv_r (p, categories[category]);
-
- /* 3. check LANG */
- if (env == NULL || !*env)
- env = _getenv_r (p, "LANG");
-
- /* 4. if none is set, fall to default locale */
- if (env == NULL || !*env)
- env = __default_locale;
-
- return env;
-}
-#endif /* _MB_CAPABLE */
-
-char *
-_DEFUN_VOID(__locale_charset)
-{
-#if 0//def __HAVE_LOCALE_INFO__
- return __get_current_ctype_locale ()->codeset;
-#else
- return lc_ctype_charset;
-#endif
-}
-
-int
-_DEFUN_VOID(__locale_mb_cur_max)
-{
-#if 0//def __HAVE_LOCALE_INFO__
- return __get_current_ctype_locale ()->mb_cur_max[0];
-#else
- return __mb_cur_max;
-#endif
-}
-
-
-char *
-_DEFUN_VOID(__locale_msgcharset)
-{
-#ifdef __HAVE_LOCALE_INFO__
- return __get_current_messages_locale ()->codeset;
-#else
- return lc_message_charset;
-#endif
-}
-
-int
-_DEFUN_VOID(__locale_cjk_lang)
-{
- return lc_ctype_cjk_lang;
-}
-
-struct lconv *
-_DEFUN(_localeconv_r, (data),
- struct _reent *data)
-{
-#ifdef __HAVE_LOCALE_INFO__
- if (__nlocale_changed)
- {
- struct lc_numeric_T *n = __get_current_numeric_locale ();
- lconv.decimal_point = n->decimal_point;
- lconv.thousands_sep = n->thousands_sep;
- lconv.grouping = n->grouping;
- __nlocale_changed = 0;
- }
- if (__mlocale_changed)
- {
- struct lc_monetary_T *m = __get_current_monetary_locale ();
- lconv.int_curr_symbol = m->int_curr_symbol;
- lconv.currency_symbol = m->currency_symbol;
- lconv.mon_decimal_point = m->mon_decimal_point;
- lconv.mon_thousands_sep = m->mon_thousands_sep;
- lconv.mon_grouping = m->mon_grouping;
- lconv.positive_sign = m->positive_sign;
- lconv.negative_sign = m->negative_sign;
- lconv.int_frac_digits = m->int_frac_digits[0];
- lconv.frac_digits = m->frac_digits[0];
- lconv.p_cs_precedes = m->p_cs_precedes[0];
- lconv.p_sep_by_space = m->p_sep_by_space[0];
- lconv.n_cs_precedes = m->n_cs_precedes[0];
- lconv.n_sep_by_space = m->n_sep_by_space[0];
- lconv.p_sign_posn = m->p_sign_posn[0];
- lconv.n_sign_posn = m->n_sign_posn[0];
-#ifdef __HAVE_LOCALE_INFO_EXTENDED__
- lconv.int_p_cs_precedes = m->int_p_cs_precedes[0];
- lconv.int_p_sep_by_space = m->int_p_sep_by_space[0];
- lconv.int_n_cs_precedes = m->int_n_cs_precedes[0];
- lconv.int_n_sep_by_space = m->int_n_sep_by_space[0];
- lconv.int_n_sign_posn = m->int_n_sign_posn[0];
- lconv.int_p_sign_posn = m->int_p_sign_posn[0];
-#else /* !__HAVE_LOCALE_INFO_EXTENDED__ */
- lconv.int_p_cs_precedes = m->p_cs_precedes[0];
- lconv.int_p_sep_by_space = m->p_sep_by_space[0];
- lconv.int_n_cs_precedes = m->n_cs_precedes[0];
- lconv.int_n_sep_by_space = m->n_sep_by_space[0];
- lconv.int_n_sign_posn = m->n_sign_posn[0];
- lconv.int_p_sign_posn = m->p_sign_posn[0];
-#endif /* !__HAVE_LOCALE_INFO_EXTENDED__ */
- __mlocale_changed = 0;
- }
-#endif /* __HAVE_LOCALE_INFO__ */
- return (struct lconv *) &lconv;
-}
-
-#ifndef _REENT_ONLY
-
-#ifndef __CYGWIN__
-/* Cygwin provides its own version of setlocale to perform some more
- initialization work. It calls _setlocale_r, though. */
-char *
-_DEFUN(setlocale, (category, locale),
- int category _AND
- _CONST char *locale)
-{
- return _setlocale_r (_REENT, category, locale);
-}
-#endif /* __CYGWIN__ */
-
-struct lconv *
-_DEFUN_VOID(localeconv)
-{
- return _localeconv_r (_REENT);
-}
-
-#endif