302 lines
7.7 KiB
C
302 lines
7.7 KiB
C
/*
|
|
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 <<"C">>
|
|
value for <[locale]>; strings representing other locales are not
|
|
honored unless _MB_CAPABLE is defined in which case three new
|
|
extensions are allowed for LC_CTYPE or LC_MESSAGES only: <<"C-JIS">>,
|
|
<<"C-EUCJP">>, <<"C-SJIS">>, or <<"C-ISO-8859-1">>. (<<"">> is
|
|
also accepted; it represents the default locale
|
|
for an implementation, here equivalent to <<"C">>.)
|
|
|
|
If you use <<NULL>> as the <[locale]> argument, <<setlocale>> returns
|
|
a pointer to the string representing the current locale (always
|
|
<<"C">> in this implementation). The acceptable values for
|
|
<[category]> are defined in `<<locale.h>>' as macros beginning with
|
|
<<"LC_">>, but this implementation does not check the values you pass
|
|
in the <[category]> argument.
|
|
|
|
<<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
|
|
<<setlocale>> returns either a pointer to a string naming the locale
|
|
currently in effect (always <<"C">> for this implementation, or, if
|
|
the locale request cannot be honored, <<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.
|
|
|
|
No supporting OS subroutines are required.
|
|
*/
|
|
|
|
/*
|
|
* setlocale, localeconv : internationalize your locale.
|
|
* (Only "C" or null supported).
|
|
*/
|
|
|
|
#include <newlib.h>
|
|
#include <locale.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <reent.h>
|
|
|
|
#ifdef __CYGWIN__
|
|
int __declspec(dllexport) __mb_cur_max = 1;
|
|
#else
|
|
int __mb_cur_max = 1;
|
|
#endif
|
|
|
|
int __nlocale_changed = 0;
|
|
int __mlocale_changed = 0;
|
|
char *_PathLocale = NULL;
|
|
|
|
static _CONST struct lconv lconv =
|
|
{
|
|
".", "", "", "", "", "", "", "", "", "",
|
|
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
|
CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX,
|
|
};
|
|
|
|
|
|
char * _EXFUN(__locale_charset,(_VOID));
|
|
|
|
static char *charset = "ISO-8859-1";
|
|
char __lc_ctype[12] = "C";
|
|
|
|
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, "C") && strcmp (locale, ""))
|
|
return 0;
|
|
p->_current_category = category;
|
|
p->_current_locale = locale;
|
|
}
|
|
return "C";
|
|
#else
|
|
static char last_lc_ctype[12] = "C";
|
|
static char lc_messages[12] = "C";
|
|
static char last_lc_messages[12] = "C";
|
|
|
|
if (locale)
|
|
{
|
|
char *locale_name = (char *)locale;
|
|
if (category != LC_CTYPE && category != LC_MESSAGES)
|
|
{
|
|
if (strcmp (locale, "C") && strcmp (locale, ""))
|
|
return 0;
|
|
if (category == LC_ALL)
|
|
{
|
|
strcpy (last_lc_ctype, __lc_ctype);
|
|
strcpy (__lc_ctype, "C");
|
|
strcpy (last_lc_messages, lc_messages);
|
|
strcpy (lc_messages, "C");
|
|
__mb_cur_max = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (locale[0] == 'C' && locale[1] == '-')
|
|
{
|
|
switch (locale[2])
|
|
{
|
|
case 'U':
|
|
if (strcmp (locale, "C-UTF-8"))
|
|
return 0;
|
|
break;
|
|
case 'J':
|
|
if (strcmp (locale, "C-JIS"))
|
|
return 0;
|
|
break;
|
|
case 'E':
|
|
if (strcmp (locale, "C-EUCJP"))
|
|
return 0;
|
|
break;
|
|
case 'S':
|
|
if (strcmp (locale, "C-SJIS"))
|
|
return 0;
|
|
break;
|
|
case 'I':
|
|
if (strcmp (locale, "C-ISO-8859-1"))
|
|
return 0;
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (strcmp (locale, "C") && strcmp (locale, ""))
|
|
return 0;
|
|
locale_name = "C"; /* C is always the default locale */
|
|
}
|
|
|
|
if (category == LC_CTYPE)
|
|
{
|
|
strcpy (last_lc_ctype, __lc_ctype);
|
|
strcpy (__lc_ctype, locale_name);
|
|
|
|
__mb_cur_max = 1;
|
|
if (locale[1] == '-')
|
|
{
|
|
switch (locale[2])
|
|
{
|
|
case 'U':
|
|
__mb_cur_max = 6;
|
|
break;
|
|
case 'J':
|
|
__mb_cur_max = 8;
|
|
break;
|
|
case 'E':
|
|
__mb_cur_max = 2;
|
|
break;
|
|
case 'S':
|
|
__mb_cur_max = 2;
|
|
break;
|
|
case 'I':
|
|
default:
|
|
__mb_cur_max = 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strcpy (last_lc_messages, lc_messages);
|
|
strcpy (lc_messages, locale_name);
|
|
|
|
charset = "ISO-8859-1";
|
|
if (locale[1] == '-')
|
|
{
|
|
switch (locale[2])
|
|
{
|
|
case 'U':
|
|
charset = "UTF-8";
|
|
break;
|
|
case 'J':
|
|
charset = "JIS";
|
|
break;
|
|
case 'E':
|
|
charset = "EUCJP";
|
|
break;
|
|
case 'S':
|
|
charset = "SJIS";
|
|
break;
|
|
case 'I':
|
|
charset = "ISO-8859-1";
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
p->_current_category = category;
|
|
p->_current_locale = locale;
|
|
|
|
if (category == LC_CTYPE)
|
|
return last_lc_ctype;
|
|
else if (category == LC_MESSAGES)
|
|
return last_lc_messages;
|
|
}
|
|
else
|
|
{
|
|
if (category == LC_CTYPE)
|
|
return __lc_ctype;
|
|
else if (category == LC_MESSAGES)
|
|
return lc_messages;
|
|
}
|
|
|
|
return "C";
|
|
#endif
|
|
|
|
}
|
|
|
|
char *
|
|
_DEFUN_VOID(__locale_charset)
|
|
{
|
|
return charset;
|
|
}
|
|
|
|
struct lconv *
|
|
_DEFUN(_localeconv_r, (data),
|
|
struct _reent *data)
|
|
{
|
|
return (struct lconv *) &lconv;
|
|
}
|
|
|
|
#ifndef _REENT_ONLY
|
|
|
|
char *
|
|
_DEFUN(setlocale, (category, locale),
|
|
int category _AND
|
|
_CONST char *locale)
|
|
{
|
|
return _setlocale_r (_REENT, category, locale);
|
|
}
|
|
|
|
|
|
struct lconv *
|
|
_DEFUN_VOID(localeconv)
|
|
{
|
|
return _localeconv_r (_REENT);
|
|
}
|
|
|
|
#endif
|