From 1217289737588e65b088b3535428b27c7287d699 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Fri, 1 Aug 2003 20:08:59 +0000 Subject: Add a new *scanf implementation, includeing the *wscanf functions. Should be standards compliant and with several optional features, including support for hexadecimal float notation, locale awareness, glibc-like locale-specific digit grouping with the `'' flag, and positional arg support. I tested it pretty well (finding several bugs in glibc's scanf in the process), but it is brand new so be aware. The *wprintf functions now support floating point output. Also, a couple of bugs were squashed. Finally, %a/%A conversions are now implemented. Implement the glibc xlocale interface for thread-specific locale support. Also add the various *_l(args, locale_t loc_arg) funcs. NOTE!!! setlocale() is NOT threadsafe! NOTE!!! The strto{floating point} conversion functions are now locale aware. The also now support hexadecimal floating point notation. Add the wcsto{floating point} conversion functions. Fix a bug in mktime() related to dst. Note that unlike glibc's mktime, uClibc's version always normalizes the struct tm before attempting to determine the correct dst setting if tm_isdst == -1 on entry. Add a stub version of the libintl functions. (untested) Fixed a known memory leak in setlocale() related to the collation data. Add lots of new config options (which Erik agreed to sort out :-), including finally exposing some of the stripped down stdio configs. Be careful with those though, as they haven't been tested in a long time. (temporary) GOTCHAs... The ctype functions are currently incorrect for 8-bit locales. They will be fixed shortly. The ctype functions are now table-based, resulting in larger staticly linked binaries. I'll be adding an option to use the old approach in the stub locale configuration. --- libc/inet/rpc/rcmd.c | 13 +- libc/misc/Makefile | 4 +- libc/misc/assert/__assert.c | 16 +- libc/misc/ctype/Makefile | 29 +- libc/misc/ctype/ctype.c | 1041 ++++++++-- libc/misc/intl/Makefile | 50 + libc/misc/intl/intl.c | 149 ++ libc/misc/locale/Makefile | 31 +- libc/misc/locale/locale.c | 1121 +++++++---- libc/misc/time/Makefile | 13 +- libc/misc/time/time.c | 245 ++- libc/misc/wchar/Makefile | 1 - libc/misc/wchar/wchar.c | 111 +- libc/misc/wchar/wstdio.c | 37 +- libc/misc/wctype/Makefile | 20 +- libc/misc/wctype/wctype.c | 661 +++++-- libc/stdio/Makefile | 12 +- libc/stdio/old_vfprintf.c | 9 +- libc/stdio/printf.c | 1151 ++++++++--- libc/stdio/scanf.c | 2404 ++++++++++++++++++----- libc/stdio/stdio.c | 200 +- libc/stdlib/Makefile | 48 +- libc/stdlib/stdlib.c | 252 ++- libc/stdlib/strtod.c | 711 +++++-- libc/string/Makefile | 32 +- libc/string/wstring.c | 262 ++- libc/sysdeps/linux/common/bits/uClibc_ctype.h | 2 + libc/sysdeps/linux/common/bits/uClibc_fpmax.h | 132 ++ libc/sysdeps/linux/common/bits/uClibc_locale.h | 129 +- libc/sysdeps/linux/common/bits/uClibc_stdio.h | 123 +- libc/sysdeps/linux/common/bits/uClibc_touplow.h | 44 + libc/sysdeps/linux/common/bits/uClibc_uwchar.h | 56 + libc/sysdeps/linux/common/bits/xopen_lim.h | 6 + libc/unistd/getopt.c | 6 + 34 files changed, 6929 insertions(+), 2192 deletions(-) create mode 100644 libc/misc/intl/Makefile create mode 100644 libc/misc/intl/intl.c create mode 100644 libc/sysdeps/linux/common/bits/uClibc_fpmax.h create mode 100644 libc/sysdeps/linux/common/bits/uClibc_touplow.h create mode 100644 libc/sysdeps/linux/common/bits/uClibc_uwchar.h (limited to 'libc') diff --git a/libc/inet/rpc/rcmd.c b/libc/inet/rpc/rcmd.c index b8138497c..618a6f1b2 100644 --- a/libc/inet/rpc/rcmd.c +++ b/libc/inet/rpc/rcmd.c @@ -38,11 +38,6 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #define __FORCE_GLIBC #include -#ifdef __UCLIBC_HAS_THREADS__ -#undef __UCLIBC_HAS_THREADS__ -#warning FIXME I am not reentrant yet... -#endif - #define __USE_GNU #include #include @@ -62,10 +57,10 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #include #include - - -/* hmm. uClibc seems to have that, but it doesn't work for some reason */ -#define getc_unlocked getc +#ifdef __UCLIBC_HAS_THREADS__ +#undef __UCLIBC_HAS_THREADS__ +#warning FIXME I am not reentrant yet... +#endif /* some forward declarations */ diff --git a/libc/misc/Makefile b/libc/misc/Makefile index 46de813da..037e2154d 100644 --- a/libc/misc/Makefile +++ b/libc/misc/Makefile @@ -26,8 +26,8 @@ include $(TOPDIR)Rules.mak DIRS = assert ctype dirent file fnmatch glob internals \ - mntent syslog time utmp locale sysvipc statfs \ - error ttyent gnu search + mntent syslog time utmp sysvipc statfs \ + error ttyent gnu search intl locale ifeq ($(strip $(UCLIBC_HAS_REGEX)),y) DIRS += regex endif diff --git a/libc/misc/assert/__assert.c b/libc/misc/assert/__assert.c index efffff1de..26bcc6516 100644 --- a/libc/misc/assert/__assert.c +++ b/libc/misc/assert/__assert.c @@ -37,15 +37,21 @@ #include #undef assert + +#define ASSERT_SHOW_PROGNAME 1 + +#ifdef ASSERT_SHOW_PROGNAME +extern const char *__progname; +#endif + #if 1 void __assert(const char *assertion, const char * filename, int linenumber, register const char * function) { fprintf(stderr, -#if 0 - /* TODO: support program_name like glibc? */ - "%s: %s: %d: %s: Assertion `%s' failed.\n", program_name, +#ifdef ASSERT_SHOW_PROGNAME + "%s: %s: %d: %s: Assertion `%s' failed.\n", __progname, #else "%s: %d: %s: Assertion `%s' failed.\n", #endif @@ -66,8 +72,8 @@ void __assert(const char *assertion, const char * filename, char buf[__BUFLEN_INT10TOSTR]; _stdio_fdout(STDERR_FILENO, -#if 0 - program_name, /* TODO: support program_name like glibc? */ +#ifdef ASSERT_SHOW_PROGNAME + __progname, ": ", #endif filename, diff --git a/libc/misc/ctype/Makefile b/libc/misc/ctype/Makefile index 1d7c24535..2f1dd65f0 100644 --- a/libc/misc/ctype/Makefile +++ b/libc/misc/ctype/Makefile @@ -25,17 +25,26 @@ TOPDIR=../../../ include $(TOPDIR)Rules.mak MSRC=ctype.c -MOBJ= isalnum.o isalpha.o isascii.o iscntrl.o isdigit.o isgraph.o \ - islower.o isprint.o ispunct.o isspace.o isupper.o isxdigit.o \ - isxlower.o isxupper.o toascii.o tolower.o toupper.o isblank.o \ - __isctype_loc.o +MOBJ= isalnum.o isalpha.o isascii.o iscntrl.o isdigit.o \ + isgraph.o islower.o isprint.o ispunct.o isspace.o \ + isupper.o isxdigit.o toascii.o tolower.o toupper.o \ + isblank.o isctype.o isxlower.o isxupper.o \ + __C_ctype_b.o __C_ctype_tolower.o __C_ctype_toupper.o \ + __ctype_b_loc.o __ctype_tolower_loc.o __ctype_toupper_loc.o \ + __ctype_assert.o -CSRC=junk.c -COBJS=$(patsubst %.c,%.o, $(CSRC)) +MOBJx= isalnum_l.o isalpha_l.o isascii_l.o iscntrl_l.o isdigit_l.o \ + isgraph_l.o islower_l.o isprint_l.o ispunct_l.o isspace_l.o \ + isupper_l.o isxdigit_l.o toascii_l.o tolower_l.o toupper_l.o \ + isblank_l.o # isxlower_l.o isxupper_l.o +OBJS=$(MOBJ) -OBJS=$(MOBJ) $(COBJS) -all: $(MOBJ) $(LIBC) +ifeq ($(UCLIBC_HAS_XLOCALE),y) + OBJS += $(MOBJx) +endif + +all: $(OBJS) $(LIBC) $(LIBC): ar-target @@ -46,8 +55,8 @@ $(MOBJ): $(MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o -$(COBJS): %.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ +$(MOBJx): $(MSRC) + $(CC) $(CFLAGS) -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o $(OBJS): Makefile diff --git a/libc/misc/ctype/ctype.c b/libc/misc/ctype/ctype.c index dedd5c00a..0eb97140d 100644 --- a/libc/misc/ctype/ctype.c +++ b/libc/misc/ctype/ctype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Manuel Novoa III +/* Copyright (C) 2003 Manuel Novoa III * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -31,299 +31,1026 @@ #include #include +#include #include +#include #include #include +#ifdef __UCLIBC_HAS_XLOCALE__ +#include +#endif /* __UCLIBC_HAS_XLOCALE__ */ + /**********************************************************************/ -extern int __isctype_loc(int c, int ct); +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ -/* Some macros used throughout the file. */ -#define U ((unsigned char)c) -/* #define LCT (__cur_locale->ctype) */ -#define LCT (&__global_locale) +#if EOF >= CHAR_MIN +#define CTYPE_DOMAIN_CHECK(C) \ + (((unsigned int)((C) - CHAR_MIN)) <= (UCHAR_MAX - CHAR_MIN)) +#else +#define CTYPE_DOMAIN_CHECK(C) \ + ((((unsigned int)((C) - CHAR_MIN)) <= (UCHAR_MAX - CHAR_MIN)) || ((C) == EOF)) +#endif -/**********************************************************************/ +#else /* __UCLIBC_HAS_CTYPE_SIGNED__ */ -#ifndef __PASTE -#define __PASTE(X,Y) X ## Y +#if EOF == -1 +#define CTYPE_DOMAIN_CHECK(C) \ + (((unsigned int)((C) - EOF)) <= (UCHAR_MAX - EOF)) +#else +#define CTYPE_DOMAIN_CHECK(C) \ + ((((unsigned int)(C)) <= UCHAR_MAX) || ((C) == EOF)) #endif -#define C_MACRO(X) __PASTE(__C_,X)(c) - -#define CT_MACRO(X) __PASTE(__ctype_,X)(c) +#endif /* __UCLIBC_HAS_CTYPE_SIGNED__ */ /**********************************************************************/ +#ifdef __UCLIBC_MJN3_ONLY__ +#ifdef L_isspace +/* emit only once */ +#warning CONSIDER: Should we assert when debugging and __UCLIBC_HAS_CTYPE_CHECKED? +#warning TODO: Fix asserts in to{upper|lower}{_l}. +#warning TODO: Optimize the isx*() funcs. +#endif +#endif /* __UCLIBC_MJN3_ONLY__ */ + +#undef CTYPE_NAME +#undef ISCTYPE +#undef CTYPE_ALIAS +#ifdef __UCLIBC_DO_XLOCALE +#define CTYPE_NAME(X) __is ## X ## _l +#define ISCTYPE(C,F) __isctype_l( C, F, locale_arg) +#define CTYPE_ALIAS(NAME) weak_alias( __is ## NAME ## _l , is ## NAME ## _l) +#else +#define CTYPE_NAME(X) is ## X +#define ISCTYPE(C,F) __isctype( C, F ) +#define CTYPE_ALIAS(NAME) +#endif +#undef PASTE2 +#define PASTE2(X,Y) X ## Y -#ifndef __CTYPE_HAS_8_BIT_LOCALES -#define IS_FUNC_BODY(NAME) \ -int NAME (int c) \ -{ \ - return C_MACRO(NAME); \ -} +#undef CTYPE_BODY + +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) +/* Make sure assert is active for to*() funcs below. */ +#undef NDEBUG +#include + +extern void __isctype_assert(int c, int mask) __attribute__ ((__noreturn__)); + +#define CTYPE_BODY(NAME,C,MASK) \ + if (CTYPE_DOMAIN_CHECK(C)) { \ + return ISCTYPE(C, MASK); \ + } \ + __isctype_assert(C, MASK); + +#elif defined(__UCLIBC_HAS_CTYPE_CHECKED__) + +#define CTYPE_BODY(NAME,C,MASK) \ + return CTYPE_DOMAIN_CHECK(C) \ + ? ISCTYPE(C, MASK) \ + : 0; + +#elif defined(__UCLIBC_HAS_CTYPE_UNSAFE__) + +#define CTYPE_BODY(NAME,C,MASK) \ + return ISCTYPE(C, MASK); + + +#else /* No checking done. */ + +#error Unknown type of ctype checking! + +#endif -#else -/* It may be worth defining __isctype_loc over the whole range of char. */ -/* #define IS_FUNC_BODY(NAME) \ */ -/* int NAME (int c) \ */ -/* { \ */ -/* return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \ */ -/* } */ #define IS_FUNC_BODY(NAME) \ -int NAME (int c) \ +int CTYPE_NAME(NAME) (int c __LOCALE_PARAM ) \ { \ - if (((unsigned int) c) <= 0x7f) { \ - return C_MACRO(NAME); \ - } \ - return __isctype_loc(c, __PASTE(_CTYPE_,NAME)); \ + CTYPE_BODY(NAME,c,PASTE2(_IS,NAME)) \ +} \ +CTYPE_ALIAS(NAME) + + +/**********************************************************************/ +#ifdef L___ctype_assert +#ifdef __UCLIBC_HAS_CTYPE_ENFORCED__ + +extern const char *__progname; + +void __isctype_assert(int c, int mask) +{ + fprintf(stderr, "%s: __is*{_l}(%d,%#x {locale})\n", __progname, c, mask); + abort(); } -#endif /* __CTYPE_HAS_8_BIT_LOCALES */ +#endif +#endif +/**********************************************************************/ +#if defined(L_isalnum) || defined(L_isalnum_l) + +IS_FUNC_BODY(alnum); + +#endif +/**********************************************************************/ +#if defined(L_isalpha) || defined(L_isalpha_l) +IS_FUNC_BODY(alpha); + +#endif /**********************************************************************/ -#ifdef L_isalnum +#if defined(L_isblank) || defined(L_isblank_l) -IS_FUNC_BODY(isalnum); +IS_FUNC_BODY(blank); #endif /**********************************************************************/ -#ifdef L_isalpha +#if defined(L_iscntrl) || defined(L_iscntrl_l) -IS_FUNC_BODY(isalpha); +IS_FUNC_BODY(cntrl); #endif /**********************************************************************/ -#ifdef L_isblank +#if defined(L_isdigit) || defined(L_isdigit_l) -/* Warning!!! This is correct for all the currently supported 8-bit locales. - * If any are added though, this will need to be verified. */ +/* The standards require EOF < 0. */ +#if EOF >= CHAR_MIN +#define __isdigit_char_or_EOF(C) __isdigit_char((C)) +#else +#define __isdigit_char_or_EOF(C) __isdigit_int((C)) +#endif -int isblank(int c) +int CTYPE_NAME(digit) (int C __LOCALE_PARAM) { - return __isblank(c); +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + if (CTYPE_DOMAIN_CHECK(C)) { + return __isdigit_char_or_EOF(C); /* C is (unsigned) char or EOF. */ + } + __isctype_assert(C, _ISdigit); +#else + return __isdigit_int(C); /* C could be invalid. */ +#endif } +CTYPE_ALIAS(digit) + #endif /**********************************************************************/ -#ifdef L_iscntrl +#if defined(L_isgraph) || defined(L_isgraph_l) -IS_FUNC_BODY(iscntrl); +IS_FUNC_BODY(graph); #endif /**********************************************************************/ -#ifdef L_isdigit +#if defined(L_islower) || defined(L_islower_l) -int isdigit(int c) -{ - return __isdigit(c); -} +IS_FUNC_BODY(lower); #endif /**********************************************************************/ -#ifdef L_isgraph +#if defined(L_isprint) || defined(L_isprint_l) -IS_FUNC_BODY(isgraph); +IS_FUNC_BODY(print); #endif /**********************************************************************/ -#ifdef L_islower +#if defined(L_ispunct) || defined(L_ispunct_l) -IS_FUNC_BODY(islower); +IS_FUNC_BODY(punct); #endif /**********************************************************************/ -#ifdef L_isprint +#if defined(L_isspace) || defined(L_isspace_l) -IS_FUNC_BODY(isprint); +IS_FUNC_BODY(space); #endif /**********************************************************************/ -#ifdef L_ispunct +#if defined(L_isupper) || defined(L_isupper_l) -IS_FUNC_BODY(ispunct); +IS_FUNC_BODY(upper); #endif /**********************************************************************/ -#ifdef L_isspace +#if defined(L_isxdigit) || defined(L_isxdigit_l) -/* Warning!!! This is correct for all the currently supported 8-bit locales. - * If any are added though, this will need to be verified. */ +IS_FUNC_BODY(xdigit); -int isspace(int c) +#endif +/**********************************************************************/ +#ifdef L_tolower + +int tolower(int c) { - return __isspace(c); +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(c)); +#endif + return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? (__UCLIBC_CTYPE_TOLOWER)[c] : c; } #endif /**********************************************************************/ -#ifdef L_isupper +#ifdef L_tolower_l + +#undef tolower_l -IS_FUNC_BODY(isupper); +int tolower_l(int c, __locale_t l) +{ +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(c)); +#endif + return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_tolower[c] : c; +} #endif /**********************************************************************/ -#ifdef L_isxdigit +#ifdef L_toupper -int isxdigit(int c) +int toupper(int c) { - return __isxdigit(c); +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(c)); +#endif + return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? (__UCLIBC_CTYPE_TOUPPER)[c] : c; } #endif /**********************************************************************/ -#ifdef L_tolower +#ifdef L_toupper_l -#ifdef __CTYPE_HAS_8_BIT_LOCALES +#undef toupper_l -int tolower(int c) +int toupper_l(int c, __locale_t l) { - return ((((unsigned int) c) <= 0x7f) - || (LCT->encoding != __ctype_encoding_8_bit)) - ? __C_tolower(c) - : ( __isctype_loc(c, _CTYPE_isupper) - ? (unsigned char) - ( U - LCT->tbl8uplow[ ((int) - (LCT->idx8uplow[(U & 0x7f) - >> Cuplow_IDX_SHIFT]) - << Cuplow_IDX_SHIFT) - + (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ]) - : c ); +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(c)); +#endif + return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_toupper[c] : c; } -#else /* __CTYPE_HAS_8_BIT_LOCALES */ +#endif +/**********************************************************************/ +#if defined(L_isascii) || defined(L_isascii_l) -int tolower(int c) +int __XL(isascii)(int c) { - return __C_tolower(c); + return __isascii(c); /* locale-independent */ } -#endif /* __CTYPE_HAS_8_BIT_LOCALES */ - #endif /**********************************************************************/ -#ifdef L_toupper - -#ifdef __CTYPE_HAS_8_BIT_LOCALES +#if defined(L_toascii) || defined(L_toascii_l) -int toupper(int c) +int __XL(toascii)(int c) { - return ((((unsigned int) c) <= 0x7f) - || (LCT->encoding != __ctype_encoding_8_bit)) - ? __C_toupper(c) - : ( __isctype_loc(c, _CTYPE_islower) - ? (unsigned char) - ( U + LCT->tbl8uplow[ ((int) - (LCT->idx8uplow[(U & 0x7f) - >> Cuplow_IDX_SHIFT]) - << Cuplow_IDX_SHIFT) - + (U & ((1 << Cuplow_IDX_SHIFT) - 1)) ]) - : c ); + return __toascii(c); /* locale-independent */ } -#else /* __CTYPE_HAS_8_BIT_LOCALES */ +#endif +/**********************************************************************/ +/* old uClibc extensions */ +/**********************************************************************/ +#ifdef L_isxlower -int toupper(int c) +int isxlower(int C) { - return __C_toupper(c); +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(C)); + return (__isctype(C, (_ISxdigit|_ISupper)) == _ISxdigit); +#elif defined(__UCLIBC_HAS_CTYPE_CHECKED__) + return CTYPE_DOMAIN_CHECK(C) + ? (__isctype(C, (_ISxdigit|_ISupper)) == _ISxdigit) + : 0; +#elif defined(__UCLIBC_HAS_CTYPE_UNSAFE__) + return (__isctype(C, (_ISxdigit|_ISupper)) == _ISxdigit); +#else /* No checking done. */ +#error Unknown type of ctype checking! +#endif } -#endif /* __CTYPE_HAS_8_BIT_LOCALES */ +#endif +/**********************************************************************/ +#ifdef L_isxupper + +int isxupper(int C) +{ +#if defined(__UCLIBC_HAS_CTYPE_ENFORCED__) + assert(CTYPE_DOMAIN_CHECK(C)); + return (__isctype(C, (_ISxdigit|_ISlower)) == _ISxdigit); +#elif defined(__UCLIBC_HAS_CTYPE_CHECKED__) + return CTYPE_DOMAIN_CHECK(C) + ? (__isctype(C, (_ISxdigit|_ISlower)) == _ISxdigit) + : 0; +#elif defined(__UCLIBC_HAS_CTYPE_UNSAFE__) + return (__isctype(C, (_ISxdigit|_ISlower)) == _ISxdigit); +#else /* No checking done. */ +#error Unknown type of ctype checking! +#endif +} #endif /**********************************************************************/ -#ifdef L_isascii +/* glibc extensions */ +/**********************************************************************/ +#ifdef L_isctype -int isascii(int c) +int isctype(int c, int mask) { - return __isascii(c); + CTYPE_BODY(NAME,c,mask) } #endif /**********************************************************************/ -#ifdef L_toascii +#if L___ctype_b_loc + +#ifdef __UCLIBC_HAS_XLOCALE__ -int toascii(int c) +const uint16_t **__ctype_b_loc(void) { - return __toascii(c); + return &(__UCLIBC_CURLOCALE_DATA).__ctype_b; } +#endif + #endif /**********************************************************************/ -#ifdef L_isxlower +#if L___ctype_tolower_loc + +#ifdef __UCLIBC_HAS_XLOCALE__ -int isxlower(int c) +const __ctype_touplow_t **__ctype_tolower_loc(void) { - return __isxlower(c); + return &(__UCLIBC_CURLOCALE_DATA).__ctype_tolower; } +#endif + #endif /**********************************************************************/ -#ifdef L_isxupper +#if L___ctype_toupper_loc + +#ifdef __UCLIBC_HAS_XLOCALE__ -int isxupper(int c) +const __ctype_touplow_t **__ctype_toupper_loc(void) { - return __isxupper(c); + return &(__UCLIBC_CURLOCALE_DATA).__ctype_toupper; } +#endif + #endif /**********************************************************************/ -#ifdef L___isctype_loc -#ifdef __CTYPE_HAS_8_BIT_LOCALES +#ifdef L___C_ctype_b + +const uint16_t __C_ctype_b_data[] = { +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + /* -128 M-^@ */ 0, + /* -127 M-^A */ 0, + /* -126 M-^B */ 0, + /* -125 M-^C */ 0, + /* -124 M-^D */ 0, + /* -123 M-^E */ 0, + /* -122 M-^F */ 0, + /* -121 M-^G */ 0, + /* -120 M-^H */ 0, + /* -119 M-^I */ 0, + /* -118 M-^J */ 0, + /* -117 M-^K */ 0, + /* -116 M-^L */ 0, + /* -115 M-^M */ 0, + /* -114 M-^N */ 0, + /* -113 M-^O */ 0, + /* -112 M-^P */ 0, + /* -111 M-^Q */ 0, + /* -110 M-^R */ 0, + /* -109 M-^S */ 0, + /* -108 M-^T */ 0, + /* -107 M-^U */ 0, + /* -106 M-^V */ 0, + /* -105 M-^W */ 0, + /* -104 M-^X */ 0, + /* -103 M-^Y */ 0, + /* -102 M-^Z */ 0, + /* -101 M-^[ */ 0, + /* -100 M-^\ */ 0, + /* -99 M-^] */ 0, + /* -98 M-^^ */ 0, + /* -97 M-^_ */ 0, + /* -96 M- */ 0, + /* -95 M-! */ 0, + /* -94 M-" */ 0, + /* -93 M-# */ 0, + /* -92 M-$ */ 0, + /* -91 M-% */ 0, + /* -90 M-& */ 0, + /* -89 M-' */ 0, + /* -88 M-( */ 0, + /* -87 M-) */ 0, + /* -86 M-* */ 0, + /* -85 M-+ */ 0, + /* -84 M-, */ 0, + /* -83 M-- */ 0, + /* -82 M-. */ 0, + /* -81 M-/ */ 0, + /* -80 M-0 */ 0, + /* -79 M-1 */ 0, + /* -78 M-2 */ 0, + /* -77 M-3 */ 0, + /* -76 M-4 */ 0, + /* -75 M-5 */ 0, + /* -74 M-6 */ 0, + /* -73 M-7 */ 0, + /* -72 M-8 */ 0, + /* -71 M-9 */ 0, + /* -70 M-: */ 0, + /* -69 M-; */ 0, + /* -68 M-< */ 0, + /* -67 M-= */ 0, + /* -66 M-> */ 0, + /* -65 M-? */ 0, + /* -64 M-@ */ 0, + /* -63 M-A */ 0, + /* -62 M-B */ 0, + /* -61 M-C */ 0, + /* -60 M-D */ 0, + /* -59 M-E */ 0, + /* -58 M-F */ 0, + /* -57 M-G */ 0, + /* -56 M-H */ 0, + /* -55 M-I */ 0, + /* -54 M-J */ 0, + /* -53 M-K */ 0, + /* -52 M-L */ 0, + /* -51 M-M */ 0, + /* -50 M-N */ 0, + /* -49 M-O */ 0, + /* -48 M-P */ 0, + /* -47 M-Q */ 0, + /* -46 M-R */ 0, + /* -45 M-S */ 0, + /* -44 M-T */ 0, + /* -43 M-U */ 0, + /* -42 M-V */ 0, + /* -41 M-W */ 0, + /* -40 M-X */ 0, + /* -39 M-Y */ 0, + /* -38 M-Z */ 0, + /* -37 M-[ */ 0, + /* -36 M-\ */ 0, + /* -35 M-] */ 0, + /* -34 M-^ */ 0, + /* -33 M-_ */ 0, + /* -32 M-` */ 0, + /* -31 M-a */ 0, + /* -30 M-b */ 0, + /* -29 M-c */ 0, + /* -28 M-d */ 0, + /* -27 M-e */ 0, + /* -26 M-f */ 0, + /* -25 M-g */ 0, + /* -24 M-h */ 0, + /* -23 M-i */ 0, + /* -22 M-j */ 0, + /* -21 M-k */ 0, + /* -20 M-l */ 0, + /* -19 M-m */ 0, + /* -18 M-n */ 0, + /* -17 M-o */ 0, + /* -16 M-p */ 0, + /* -15 M-q */ 0, + /* -14 M-r */ 0, + /* -13 M-s */ 0, + /* -12 M-t */ 0, + /* -11 M-u */ 0, + /* -10 M-v */ 0, + /* -9 M-w */ 0, + /* -8 M-x */ 0, + /* -7 M-y */ 0, + /* -6 M-z */ 0, + /* -5 M-{ */ 0, + /* -4 M-| */ 0, + /* -3 M-} */ 0, + /* -2 M-~ */ 0, +#endif /* __UCLIBC_HAS_CTYPE_SIGNED__*/ + /* -1 M-^? */ 0, + /* 0 ^@ */ _IScntrl, + /* 1 ^A */ _IScntrl, + /* 2 ^B */ _IScntrl, + /* 3 ^C */ _IScntrl, + /* 4 ^D */ _IScntrl, + /* 5 ^E */ _IScntrl, + /* 6 ^F */ _IScntrl, + /* 7 ^G */ _IScntrl, + /* 8 ^H */ _IScntrl, + /* 9 ^I */ _ISspace|_ISblank|_IScntrl, + /* 10 ^J */ _ISspace|_IScntrl, + /* 11 ^K */ _ISspace|_IScntrl, + /* 12 ^L */ _ISspace|_IScntrl, + /* 13 ^M */ _ISspace|_IScntrl, + /* 14 ^N */ _IScntrl, + /* 15 ^O */ _IScntrl, + /* 16 ^P */ _IScntrl, + /* 17 ^Q */ _IScntrl, + /* 18 ^R */ _IScntrl, + /* 19 ^S */ _IScntrl, + /* 20 ^T */ _IScntrl, + /* 21 ^U */ _IScntrl, + /* 22 ^V */ _IScntrl, + /* 23 ^W */ _IScntrl, + /* 24 ^X */ _IScntrl, + /* 25 ^Y */ _IScntrl, + /* 26 ^Z */ _IScntrl, + /* 27 ^[ */ _IScntrl, + /* 28 ^\ */ _IScntrl, + /* 29 ^] */ _IScntrl, + /* 30 ^^ */ _IScntrl, + /* 31 ^_ */ _IScntrl, + /* 32 */ _ISspace|_ISprint|_ISblank, + /* 33 ! */ _ISprint|_ISgraph|_ISpunct, + /* 34 " */ _ISprint|_ISgraph|_ISpunct, + /* 35 # */ _ISprint|_ISgraph|_ISpunct, + /* 36 $ */ _ISprint|_ISgraph|_ISpunct, + /* 37 % */ _ISprint|_ISgraph|_ISpunct, + /* 38 & */ _ISprint|_ISgraph|_ISpunct, + /* 39 ' */ _ISprint|_ISgraph|_ISpunct, + /* 40 ( */ _ISprint|_ISgraph|_ISpunct, + /* 41 ) */ _ISprint|_ISgraph|_ISpunct, + /* 42 * */ _ISprint|_ISgraph|_ISpunct, + /* 43 + */ _ISprint|_ISgraph|_ISpunct, + /* 44 , */ _ISprint|_ISgraph|_ISpunct, + /* 45 - */ _ISprint|_ISgraph|_ISpunct, + /* 46 . */ _ISprint|_ISgraph|_ISpunct, + /* 47 / */ _ISprint|_ISgraph|_ISpunct, + /* 48 0 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 49 1 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 50 2 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 51 3 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 52 4 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 53 5 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 54 6 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 55 7 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 56 8 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 57 9 */ _ISdigit|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 58 : */ _ISprint|_ISgraph|_ISpunct, + /* 59 ; */ _ISprint|_ISgraph|_ISpunct, + /* 60 < */ _ISprint|_ISgraph|_ISpunct, + /* 61 = */ _ISprint|_ISgraph|_ISpunct, + /* 62 > */ _ISprint|_ISgraph|_ISpunct, + /* 63 ? */ _ISprint|_ISgraph|_ISpunct, + /* 64 @ */ _ISprint|_ISgraph|_ISpunct, + /* 65 A */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 66 B */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 67 C */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 68 D */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 69 E */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 70 F */ _ISupper|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 71 G */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 72 H */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 73 I */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 74 J */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 75 K */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 76 L */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 77 M */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 78 N */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 79 O */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 80 P */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 81 Q */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 82 R */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 83 S */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 84 T */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 85 U */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 86 V */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 87 W */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 88 X */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 89 Y */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 90 Z */ _ISupper|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 91 [ */ _ISprint|_ISgraph|_ISpunct, + /* 92 \ */ _ISprint|_ISgraph|_ISpunct, + /* 93 ] */ _ISprint|_ISgraph|_ISpunct, + /* 94 ^ */ _ISprint|_ISgraph|_ISpunct, + /* 95 _ */ _ISprint|_ISgraph|_ISpunct, + /* 96 ` */ _ISprint|_ISgraph|_ISpunct, + /* 97 a */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 98 b */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 99 c */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 100 d */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 101 e */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 102 f */ _ISlower|_ISalpha|_ISxdigit|_ISprint|_ISgraph|_ISalnum, + /* 103 g */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 104 h */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 105 i */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 106 j */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 107 k */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 108 l */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 109 m */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 110 n */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 111 o */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 112 p */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 113 q */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 114 r */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 115 s */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 116 t */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 117 u */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 118 v */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 119 w */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 120 x */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 121 y */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 122 z */ _ISlower|_ISalpha|_ISprint|_ISgraph|_ISalnum, + /* 123 { */ _ISprint|_ISgraph|_ISpunct, + /* 124 | */ _ISprint|_ISgraph|_ISpunct, + /* 125 } */ _ISprint|_ISgraph|_ISpunct, + /* 126 ~ */ _ISprint|_ISgraph|_ISpunct, + /* 127 ^? */ _IScntrl, + /* 128 M-^@ */ 0, + /* 129 M-^A */ 0, + /* 130 M-^B */ 0, + /* 131 M-^C */ 0, + /* 132 M-^D */ 0, + /* 133 M-^E */ 0, + /* 134 M-^F */ 0, + /* 135 M-^G */ 0, + /* 136 M-^H */ 0, + /* 137 M-^I */ 0, + /* 138 M-^J */ 0, + /* 139 M-^K */ 0, + /* 140 M-^L */ 0, + /* 141 M-^M */ 0, + /* 142 M-^N */ 0, + /* 143 M-^O */ 0, + /* 144 M-^P */ 0, + /* 145 M-^Q */ 0, + /* 146 M-^R */ 0, + /* 147 M-^S */ 0, + /* 148 M-^T */ 0, + /* 149 M-^U */ 0, + /* 150 M-^V */ 0, + /* 151 M-^W */ 0, + /* 152 M-^X */ 0, + /* 153 M-^Y */ 0, + /* 154 M-^Z */ 0, + /* 155 M-^[ */ 0, + /* 156 M-^\ */ 0, + /* 157 M-^] */ 0, + /* 158 M-^^ */ 0, + /* 159 M-^_ */ 0, + /* 160 M- */ 0, + /* 161 M-! */ 0, + /* 162 M-" */ 0, + /* 163 M-# */ 0, + /* 164 M-$ */ 0, + /* 165 M-% */ 0, + /* 166 M-& */ 0, + /* 167 M-' */ 0, + /* 168 M-( */ 0, + /* 169 M-) */ 0, + /* 170 M-* */ 0, + /* 171 M-+ */ 0, + /* 172 M-, */ 0, + /* 173 M-- */ 0, + /* 174 M-. */ 0, + /* 175 M-/ */ 0, + /* 176 M-0 */ 0, + /* 177 M-1 */ 0, + /* 178 M-2 */ 0, + /* 179 M-3 */ 0, + /* 180 M-4 */ 0, + /* 181 M-5 */ 0, + /* 182 M-6 */ 0, + /* 183 M-7 */ 0, + /* 184 M-8 */ 0, + /* 185 M-9 */ 0, + /* 186 M-: */ 0, + /* 187 M-; */ 0, + /* 188 M-< */ 0, + /* 189 M-= */ 0, + /* 190 M-> */ 0, + /* 191 M-? */ 0, + /* 192 M-@ */ 0, + /* 193 M-A */ 0, + /* 194 M-B */ 0, + /* 195 M-C */ 0, + /* 196 M-D */ 0, + /* 197 M-E */ 0, + /* 198 M-F */ 0, + /* 199 M-G */ 0, + /* 200 M-H */ 0, + /* 201 M-I */ 0, + /* 202 M-J */ 0, + /* 203 M-K */ 0, + /* 204 M-L */ 0, + /* 205 M-M */ 0, + /* 206 M-N */ 0, + /* 207 M-O */ 0, + /* 208 M-P */ 0, + /* 209 M-Q */ 0, + /* 210 M-R */ 0, + /* 211 M-S */ 0, + /* 212 M-T */ 0, + /* 213 M-U */ 0, + /* 214 M-V */ 0, + /* 215 M-W */ 0, + /* 216 M-X */ 0, + /* 217 M-Y */ 0, + /* 218 M-Z */ 0, + /* 219 M-[ */ 0, + /* 220 M-\ */ 0, + /* 221 M-] */ 0, + /* 222 M-^ */ 0, + /* 223 M-_ */ 0, + /* 224 M-` */ 0, + /* 225 M-a */ 0, + /* 226 M-b */ 0, + /* 227 M-c */ 0, + /* 228 M-d */ 0, + /* 229 M-e */ 0, + /* 230 M-f */ 0, + /* 231 M-g */ 0, + /* 232 M-h */ 0, + /* 233 M-i */ 0, + /* 234 M-j */ 0, + /* 235 M-k */ 0, + /* 236 M-l */ 0, + /* 237 M-m */ 0, + /* 238 M-n */ 0, + /* 239 M-o */ 0, + /* 240 M-p */ 0, + /* 241 M-q */ 0, + /* 242 M-r */ 0, + /* 243 M-s */ 0, + /* 244 M-t */ 0, + /* 245 M-u */ 0, + /* 246 M-v */ 0, + /* 247 M-w */ 0, + /* 248 M-x */ 0, + /* 249 M-y */ 0, + /* 250 M-z */ 0, + /* 251 M-{ */ 0, + /* 252 M-| */ 0, + /* 253 M-} */ 0, + /* 254 M-~ */ 0, + /* 255 M-^? */ 0 +}; + +const uint16_t *__C_ctype_b = __C_ctype_b_data + 1 +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 127 +#endif + ; + +#ifndef __UCLIBC_HAS_XLOCALE__ + +const uint16_t *__ctype_b = __C_ctype_b_data + 1 +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 127 +#endif + ; -/* This internal routine is similar to iswctype(), but it doesn't - * work for any non-standard types, itdoesn't work for "xdigit"s, - * and it doesn't work for chars between 0 and 0x7f (although that - * may change). */ +#endif -static const char ctype_range[] = { - __CTYPE_RANGES +#endif +/**********************************************************************/ +#ifdef L___C_ctype_tolower + +const __ctype_touplow_t __C_ctype_tolower_data[] = { +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + -128, -127, -126, -125, + -124, -123, -122, -121, + -120, -119, -118, -117, + -116, -115, -114, -113, + -112, -111, -110, -109, + -108, -107, -106, -105, + -104, -103, -102, -101, + -100, -99, -98, -97, + -96, -95, -94, -93, + -92, -91, -90, -89, + -88, -87, -86, -85, + -84, -83, -82, -81, + -80, -79, -78, -77, + -76, -75, -74, -73, + -72, -71, -70, -69, + -68, -67, -66, -65, + -64, -63, -62, -61, + -60, -59, -58, -57, + -56, -55, -54, -53, + -52, -51, -50, -49, + -48, -47, -46, -45, + -44, -43, -42, -41, + -40, -39, -38, -37, + -36, -35, -34, -33, + -32, -31, -30, -29, + -28, -27, -26, -25, + -24, -23, -22, -21, + -20, -19, -18, -17, + -16, -15, -14, -13, + -12, -11, -10, -9, + -8, -7, -6, -5, + -4, -3, -2, -1, +#endif /* __UCLIBC_HAS_CTYPE_SIGNED__*/ + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 21, 22, 23, + 24, 25, 26, 27, + 28, 29, 30, 31, + 32, 33, 34, 35, + 36, 37, 38, 39, + 40, 41, 42, 43, + 44, 45, 46, 47, + 48, 49, 50, 51, + 52, 53, 54, 55, + 56, 57, 58, 59, + 60, 61, 62, 63, + 64, 97 /* a */, 98 /* b */, 99 /* c */, + 100 /* d */, 101 /* e */, 102 /* f */, 103 /* g */, + 104 /* h */, 105 /* i */, 106 /* j */, 107 /* k */, + 108 /* l */, 109 /* m */, 110 /* n */, 111 /* o */, + 112 /* p */, 113 /* q */, 114 /* r */, 115 /* s */, + 116 /* t */, 117 /* u */, 118 /* v */, 119 /* w */, + 120 /* x */, 121 /* y */, 122 /* z */, 91, + 92, 93, 94, 95, + 96, 97, 98, 99, + 100, 101, 102, 103, + 104, 105, 106, 107, + 108, 109, 110, 111, + 112, 113, 114, 115, + 116, 117, 118, 119, + 120, 121, 122, 123, + 124, 125, 126, 127, + 128, 129, 130, 131, + 132, 133, 134, 135, + 136, 137, 138, 139, + 140, 141, 142, 143, + 144, 145, 146, 147, + 148, 149, 150, 151, + 152, 153, 154, 155, + 156, 157, 158, 159, + 160, 161, 162, 163, + 164, 165, 166, 167, + 168, 169, 170, 171, + 172, 173, 174, 175, + 176, 177, 178, 179, + 180, 181, 182, 183, + 184, 185, 186, 187, + 188, 189, 190, 191, + 192, 193, 194, 195, + 196, 197, 198, 199, + 200, 201, 202, 203, + 204, 205, 206, 207, + 208, 209, 210, 211, + 212, 213, 214, 215, + 216, 217, 218, 219, + 220, 221, 222, 223, + 224, 225, 226, 227, + 228, 229, 230, 231, + 232, 233, 234, 235, + 236, 237, 238, 239, + 240, 241, 242, 243, + 244, 245, 246, 247, + 248, 249, 250, 251, + 252, 253, 254, 255 }; -int __isctype_loc(int c, int ct) -{ - unsigned char d; +const __ctype_touplow_t *__C_ctype_tolower = __C_ctype_tolower_data +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 128 +#endif + ; - assert(((unsigned int)ct) < _CTYPE_isxdigit); - assert(((unsigned int)c) > 0x7f); +#ifndef __UCLIBC_HAS_XLOCALE__ -#if (CHAR_MIN == 0) /* We don't have signed chars... */ - if ((LCT->encoding != __ctype_encoding_8_bit) - || (((unsigned int) c) > UCHAR_MAX) - ) { - return 0; - } -#else - /* Allow non-EOF negative char values for glibc compatiblity. */ - if ((LCT->encoding != __ctype_encoding_8_bit) || (c == EOF) - || ( ((unsigned int)(c - CHAR_MIN)) > (UCHAR_MAX - CHAR_MIN)) - ) { - return 0; - } +const __ctype_touplow_t *__ctype_tolower = __C_ctype_tolower_data +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 128 #endif + ; - /* TODO - test assumptions??? 8-bit chars -- or ensure in generator. */ +#endif -#define Cctype_TBL_MASK ((1 << Cctype_IDX_SHIFT) - 1) -#define Cctype_IDX_OFFSET (128 >> Cctype_IDX_SHIFT) +#endif +/**********************************************************************/ +#ifdef L___C_ctype_toupper + +const __ctype_touplow_t __C_ctype_toupper_data[] = { +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + -128, -127, -126, -125, + -124, -123, -122, -121, + -120, -119, -118, -117, + -116, -115, -114, -113, + -112, -111, -110, -109, + -108, -107, -106, -105, + -104, -103, -102, -101, + -100, -99, -98, -97, + -96, -95, -94, -93, + -92, -91, -90, -89, + -88, -87, -86, -85, + -84, -83, -82, -81, + -80, -79, -78, -77, + -76, -75, -74, -73, + -72, -71, -70, -69, + -68, -67, -66, -65, + -64, -63, -62, -61, + -60, -59, -58, -57, + -56, -55, -54, -53, + -52, -51, -50, -49, + -48, -47, -46, -45, + -44, -43, -42, -41, + -40, -39, -38, -37, + -36, -35, -34, -33, + -32, -31, -30, -29, + -28, -27, -26, -25, + -24, -23, -22, -21, + -20, -19, -18, -17, + -16, -15, -14, -13, + -12, -11, -10, -9, + -8, -7, -6, -5, + -4, -3, -2, -1, +#endif /* __UCLIBC_HAS_CTYPE_SIGNED__*/ + 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15, + 16, 17, 18, 19, + 20, 21, 22, 23, + 24, 25, 26, 27, + 28, 29, 30, 31, + 32, 33, 34, 35, + 36, 37, 38, 39, + 40, 41, 42, 43, + 44, 45, 46, 47, + 48, 49, 50, 51, + 52, 53, 54, 55, + 56, 57, 58, 59, + 60, 61, 62, 63, + 64, 65, 66, 67, + 68, 69, 70, 71, + 72, 73, 74, 75, + 76, 77, 78, 79, + 80, 81, 82, 83, + 84, 85, 86, 87, + 88, 89, 90, 91, + 92, 93, 94, 95, + 96, 65 /* A */, 66 /* B */, 67 /* C */, + 68 /* D */, 69 /* E */, 70 /* F */, 71 /* G */, + 72 /* H */, 73 /* I */, 74 /* J */, 75 /* K */, + 76 /* L */, 77 /* M */, 78 /* N */, 79 /* O */, + 80 /* P */, 81 /* Q */, 82 /* R */, 83 /* S */, + 84 /* T */, 85 /* U */, 86 /* V */, 87 /* W */, + 88 /* X */, 89 /* Y */, 90 /* Z */, 123, + 124, 125, 126, 127, + 128, 129, 130, 131, + 132, 133, 134, 135, + 136, 137, 138, 139, + 140, 141, 142, 143, + 144, 145, 146, 147, + 148, 149, 150, 151, + 152, 153, 154, 155, + 156, 157, 158, 159, + 160, 161, 162, 163, + 164, 165, 166, 167, + 168, 169, 170, 171, + 172, 173, 174, 175, + 176, 177, 178, 179, + 180, 181, 182, 183, + 184, 185, 186, 187, + 188, 189, 190, 191, + 192, 193, 194, 195, + 196, 197, 198, 199, + 200, 201, 202, 203, + 204, 205, 206, 207, + 208, 209, 210, 211, + 212, 213, 214, 215, + 216, 217, 218, 219, + 220, 221, 222, 223, + 224, 225, 226, 227, + 228, 229, 230, 231, + 232, 233, 234, 235, + 236, 237, 238, 239, + 240, 241, 242, 243, + 244, 245, 246, 247, + 248, 249, 250, 251, + 252, 253, 254, 255 +}; + +const __ctype_touplow_t *__C_ctype_toupper = __C_ctype_toupper_data +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 128 +#endif + ; + +#ifndef __UCLIBC_HAS_XLOCALE__ + +const __ctype_touplow_t *__ctype_toupper = __C_ctype_toupper_data +#ifdef __UCLIBC_HAS_CTYPE_SIGNED__ + + 128 +#endif + ; - c &= 0x7f; -#ifdef Cctype_PACKED - d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ]) - << (Cctype_IDX_SHIFT - 1)) - + ((U & Cctype_TBL_MASK) >> 1)]; - d = (U & 1) ? (d >> 4) : (d & 0xf); -#else - d = LCT->tbl8ctype[ ((int)(LCT->idx8ctype[(U >> Cctype_IDX_SHIFT) ]) - << Cctype_IDX_SHIFT) - + (U & Cctype_TBL_MASK) ]; #endif - return ( ((unsigned char)(d - ctype_range[2*ct])) <= ctype_range[2*ct+1] ); -} -#endif /* __CTYPE_HAS_8_BIT_LOCALES */ #endif /**********************************************************************/ diff --git a/libc/misc/intl/Makefile b/libc/misc/intl/Makefile new file mode 100644 index 000000000..75fbb321f --- /dev/null +++ b/libc/misc/intl/Makefile @@ -0,0 +1,50 @@ +# Makefile for uClibc +# +# Copyright (C) 2000 by Lineo, inc. +# Copyright (C) 2000,2001 Erik Andersen +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Library General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Derived in part from the Linux-8086 C library, the GNU C Library, and several +# other sundry sources. Files within this library are copyright by their +# respective copyright holders. + +TOPDIR=../../../ +include $(TOPDIR)Rules.mak + +MSRC= intl.c +MOBJ= gettext.o ngettext.o dgettext.o dcgettext.o dngettext.o dcngettext.o \ + textdomain.o bindtextdomain.o bind_textdomain_codeset.o + +OBJS=$(MOBJ) + +all: $(OBJS) $(LIBC) + +$(LIBC): ar-target + +ar-target: $(OBJS) + $(AR) $(ARFLAGS) $(LIBC) $(OBJS) + +$(MOBJ): $(MSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(STRIPTOOL) -x -R .note -R .comment $*.o + +$(COBJS): %.o : %.c + $(CC) $(CFLAGS) -c $< -o $@ + $(STRIPTOOL) -x -R .note -R .comment $*.o + +clean: + rm -f *.[oa] *~ core + diff --git a/libc/misc/intl/intl.c b/libc/misc/intl/intl.c new file mode 100644 index 000000000..183ffcc92 --- /dev/null +++ b/libc/misc/intl/intl.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2003 Manuel Novoa III + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Supply some weaks for gettext and friends. Used by strerror*(). + */ + +#include +#include +#include + +#undef __OPTIMIZE__ +#include + +/**********************************************************************/ +#ifdef L_gettext + +char *weak_function gettext(const char *msgid) +{ + return (char *) msgid; +} + +#endif +/**********************************************************************/ +#ifdef L_dgettext + +char *__uClibc_dgettext(const char *domainname, + const char *msgid) +{ + return (char *) msgid; +} + +weak_alias (__uClibc_dgettext, __dgettext) +weak_alias (__uClibc_dgettext, dgettext) + +#endif +/**********************************************************************/ +#ifdef L_dcgettext + +char * __uClibc_dcgettext(const char *domainname, + const char *msgid, int category) +{ + return (char *) msgid; +} + +weak_alias (__uClibc_dcgettext, __dcgettext) +weak_alias (__uClibc_dcgettext, dcgettext) + +#endif +/**********************************************************************/ +#ifdef L_ngettext + +char *weak_function ngettext(const char *msgid1, const char *msgid2, + unsigned long int n) +{ + return (char *) ((n == 1) ? msgid1 : msgid2); +} + +#endif +/**********************************************************************/ +#ifdef L_dngettext + +char *weak_function dngettext(const char *domainname, const char *msgid1, + const char *msgid2, unsigned long int n) +{ + return (char *) ((n == 1) ? msgid1 : msgid2); +} + +#endif +/**********************************************************************/ +#ifdef L_dcngettext + +char *weak_function dcngettext(const char *domainname, const char *msgid1, + const char *msgid2, unsigned long int n, + int category) +{ + return (char *) ((n == 1) ? msgid1 : msgid2); +} + +#endif +/**********************************************************************/ +#ifdef L_textdomain + +char *weak_function textdomain(const char *domainname) +{ + static const char default_str[] = "messages"; + + if (domainname && *domainname && strcmp(domainname, default_str)) { + __set_errno(EINVAL); + return NULL; + } + return (char *) default_str; +} + +#endif +/**********************************************************************/ +#ifdef L_bindtextdomain + +char *weak_function bindtextdomain(const char *domainname, const char *dirname) +{ + static const char dir[] = "/"; + + if (!domainname || !*domainname + || (dirname +#if 1 + && ((dirname[0] != '/') || dirname[1]) +#else + && strcmp(dirname, dir) +#endif + ) + ) { + __set_errno(EINVAL); + return NULL; + } + + return (char *) dir; +} + +#endif +/**********************************************************************/ +#ifdef L_bind_textdomain_codeset + +/* Specify the character encoding in which the messages from the + DOMAINNAME message catalog will be returned. */ +char *weak_function bind_textdomain_codeset(const char *domainname, + const char *codeset) +{ + if (!domainname || !*domainname || codeset) { + __set_errno(EINVAL); + } + return NULL; +} + +#endif +/**********************************************************************/ diff --git a/libc/misc/locale/Makefile b/libc/misc/locale/Makefile index 29c8cd5a0..8ad041e69 100644 --- a/libc/misc/locale/Makefile +++ b/libc/misc/locale/Makefile @@ -26,14 +26,29 @@ include $(TOPDIR)Rules.mak MSRC= locale.c MOBJ= setlocale.o localeconv.o _locale_init.o nl_langinfo.o +MOBJx= -OBJS= $(MOBJ) +ifeq ($(UCLIBC_HAS_LOCALE),y) + MOBJ += newlocale.o __locale_mbrtowc_l.o +endif + +ifeq ($(UCLIBC_HAS_XLOCALE),y) + MOBJx += nl_langinfo_l.o duplocale.o freelocale.o uselocale.o __curlocale.o +endif + +OBJS= $(MOBJ) $(MOBJx) ifeq ($(UCLIBC_HAS_LOCALE),y) - OBJS += locale_data.o + OBJS += $(COBJS) locale_data.o endif -all: data $(OBJS) $(LIBC) +DATA= +ifeq ($(UCLIBC_HAS_LOCALE),y) + DATA += locale_data.o +endif + +all: $(DATA) $(OBJS) $(LIBC) + $(LIBC): ar-target @@ -44,12 +59,14 @@ $(MOBJ): $(MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o +$(MOBJx): $(MSRC) + $(CC) $(CFLAGS) -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o + $(STRIPTOOL) -x -R .note -R .comment $*.o + $(OBJS): Makefile -data: -ifeq ($(UCLIBC_HAS_LOCALE),y) - make -C $(TOPDIR)/extra/locale -endif +# locale_data.o: +# make -C $(TOPDIR)/extra/locale clean: rm -f *.[oa] *~ core diff --git a/libc/misc/locale/locale.c b/libc/misc/locale/locale.c index 9c162a980..071a8df71 100644 --- a/libc/misc/locale/locale.c +++ b/libc/misc/locale/locale.c @@ -36,28 +36,94 @@ */ #define _GNU_SOURCE -#include + +#define __CTYPE_HAS_8_BIT_LOCALES 1 + + #include #include #include #include #include #include +#include +#include + +#undef __LOCALE_C_ONLY +#ifndef __UCLIBC_HAS_LOCALE__ +#define __LOCALE_C_ONLY +#endif /* __UCLIBC_HAS_LOCALE__ */ + + +#ifdef __LOCALE_C_ONLY + +#include + +#else /* __LOCALE_C_ONLY */ + +#ifdef __UCLIBC_MJN3_ONLY__ +#ifdef L_setlocale +#warning TODO: Fix the __CTYPE_HAS_8_BIT_LOCALES define at the top of the file. +#warning TODO: Fix __WCHAR_ENABLED. +#endif +#endif -#ifndef __LOCALE_C_ONLY +/* Need to include this before locale.h and xlocale.h! */ +#include -#define CUR_LOCALE_SPEC (__global_locale.cur_locale) #undef CODESET_LIST #define CODESET_LIST (__locale_mmap->codeset_list) +#ifdef __UCLIBC_HAS_XLOCALE__ +#include +#include +#else /* __UCLIBC_HAS_XLOCALE__ */ +/* We need this internally... */ +#define __UCLIBC_HAS_XLOCALE__ 1 +#include +#include +#undef __UCLIBC_HAS_XLOCALE__ +#endif /* __UCLIBC_HAS_XLOCALE__ */ + +#include + +#define LOCALE_NAMES (__locale_mmap->locale_names5) +#define LOCALES (__locale_mmap->locales) +#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers) +#define CATEGORY_NAMES (__locale_mmap->lc_names) + +#ifdef __UCLIBC_MJN3_ONLY__ +#warning REMINDER: redo the MAX_LOCALE_STR stuff... +#endif +#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */ +#define MAX_LOCALE_CATEGORY_STR 32 /* TODO: Only sufficient for current case. */ +/* Note: Best if MAX_LOCALE_CATEGORY_STR is a power of 2. */ + +extern int _locale_set_l(const unsigned char *p, __locale_t base); +extern void _locale_init_l(__locale_t base); + #endif /* __LOCALE_C_ONLY */ +#undef LOCALE_STRING_SIZE +#define LOCALE_SELECTOR_SIZE (2 * __LC_ALL + 2) + +#ifdef __UCLIBC_MJN3_ONLY__ +#ifdef L_setlocale +#warning TODO: Create a C locale selector string. +#endif +#endif +#define C_LOCALE_SELECTOR "\x23\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" + + +#include +#include + /**********************************************************************/ #ifdef L_setlocale #ifdef __LOCALE_C_ONLY -link_warning(setlocale,"the 'setlocale' function supports only C|POSIX locales") +link_warning(setlocale,"REMINDER: The 'setlocale' function supports only C|POSIX locales.") static const char C_string[] = "C"; @@ -74,273 +140,125 @@ char *setlocale(int category, register const char *locale) #else /* ---------------------------------------------- __LOCALE_C_ONLY */ -#if !defined(NUM_LOCALES) || (NUM_LOCALES <= 1) -#error locales enabled, but not data other than for C locale! +#ifdef __UCLIBC_HAS_THREADS__ +link_warning(setlocale,"REMINDER: The 'setlocale' function is _not_ threadsafe except for simple queries.") #endif -#define LOCALE_NAMES (__locale_mmap->locale_names5) -#define LOCALES (__locale_mmap->locales) -#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers) -#define CATEGORY_NAMES (__locale_mmap->lc_names) +#if !defined(__LOCALE_DATA_NUM_LOCALES) || (__LOCALE_DATA_NUM_LOCALES <= 1) +#error locales enabled, but not data other than for C locale! +#endif +#ifdef __UCLIBC_MJN3_ONLY__ +#warning TODO: Move posix and utf8 strings. +#endif static const char posix[] = "POSIX"; static const char utf8[] = "UTF-8"; #ifdef __UCLIBC_MJN3_ONLY__ -#warning REMINDER: redo the MAX_LOCALE_STR stuff... +#warning TODO: Fix dimensions of hr_locale. #endif -#define MAX_LOCALE_STR 256 /* TODO: Only sufficient for current case. */ - -static char hr_locale[MAX_LOCALE_STR]; +/* Individual category strings start at hr_locale + category * MAX_LOCALE_CATEGORY. + * This holds for LC_ALL as well. + */ +static char hr_locale[(MAX_LOCALE_CATEGORY_STR * LC_ALL) + MAX_LOCALE_STR]; -static __inline char *human_readable_locale(int category, const unsigned char *s) +static void update_hr_locale(const unsigned char *spec) { const unsigned char *loc; + const unsigned char *s; char *n; - int i; - - ++s; - - if (category == LC_ALL) { - for (i = 0 ; i < LC_ALL-1 ; i += 2) { - if ((s[i] != s[i+2]) || (s[i+1] != s[i+3])) { - goto SKIP; - } - } - /* All categories the same, so simplify string by using a single - * category. */ - category = LC_CTYPE; - } - - SKIP: - i = (category == LC_ALL) ? 0 : category; - s += 2*i; - n = hr_locale; + int i, category, done; + done = category = 0; do { - if ((*s != 0xff) || (s[1] != 0xff)) { - loc = LOCALES + WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7) + (s[1] & 0x7f)); - if (category == LC_ALL) { - n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]); - *n++ = '='; - } - if (*loc == 0) { - *n++ = 'C'; - *n = 0; - } else { - char at = 0; - memcpy(n, LOCALE_NAMES + 5*((*loc)-1), 5); - if (n[2] != '_') { - at = n[2]; - n[2] = '_'; - } - n += 5; - *n++ = '.'; - if (loc[2] == 2) { - n = stpcpy(n, utf8); - } else if (loc[2] >= 3) { - n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3])); - } - if (at) { - const char *q; - *n++ = '@'; - q = LOCALE_AT_MODIFIERS; - do { - if (q[1] == at) { - n = stpcpy(n, q+2); - break; - } - q += 2 + *q; - } while (*q); + s = spec + 1; + n = hr_locale + category * MAX_LOCALE_CATEGORY_STR; + + if (category == LC_ALL) { + done = 1; + for (i = 0 ; i < LC_ALL-1 ; i += 2) { + if ((s[i] != s[i+2]) || (s[i+1] != s[i+3])) { + goto SKIP; } } - *n++ = ';'; + /* All categories the same, so simplify string by using a single + * category. */ + category = LC_CTYPE; } - s += 2; - } while (++i < category); - - *--n = 0; /* Remove trailing ';' and nul-terminate. */ - assert(n-hr_locale < MAX_LOCALE_STR); - return hr_locale; -} - -static int find_locale(int category, const char *p, unsigned char *new_locale) -{ - int i; - const unsigned char *s; - uint16_t n; - unsigned char lang_cult, codeset; - -#if defined(LOCALE_AT_MODIFIERS_LENGTH) && 1 - /* Support standard locale handling for @-modifiers. */ -#ifdef __UCLIBC_MJN3_ONLY__ -#warning REMINDER: fix buf size in find_locale -#endif - char buf[18]; /* TODO: 7+{max codeset name length} */ - const char *q; + SKIP: + i = (category == LC_ALL) ? 0 : category; + s += 2*i; - if ((q = strchr(p,'@')) != NULL) { - if ((((size_t)((q-p)-5)) > (sizeof(buf) - 5)) || (p[2] != '_')) { - return 0; - } - /* locale name at least 5 chars long and 3rd char is '_' */ - s = LOCALE_AT_MODIFIERS; do { - if (!strcmp(s+2, q+1)) { - break; - } - s += 2 + *s; /* TODO - fix this throughout */ - } while (*s); - if (!*s) { - return 0; - } - assert(q - p < sizeof(buf)); - memcpy(buf, p, q-p); - buf[q-p] = 0; - buf[2] = s[1]; - p = buf; - } -#endif - - lang_cult = codeset = 0; /* Assume C and default codeset. */ - if (((*p == 'C') && !p[1]) || !strcmp(p, posix)) { - goto FIND_LOCALE; - } - - if ((strlen(p) > 5) && (p[5] == '.')) { /* Codeset in locale name? */ - /* TODO: maybe CODESET_LIST + *s ??? */ - /* 7bit is 1, UTF-8 is 2, 8-bit is >= 3 */ - codeset = 2; - if (strcmp(utf8,p+6) != 0) {/* TODO - fix! */ - s = CODESET_LIST; - do { - ++codeset; /* Increment codeset first. */ - if (!strcmp(CODESET_LIST+*s, p+6)) { - goto FIND_LANG_CULT; + if ((*s != 0xff) || (s[1] != 0xff)) { + loc = LOCALES + + __LOCALE_DATA_WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7) + + (s[1] & 0x7f)); + if (category == LC_ALL) { + n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]); + *n++ = '='; } - } while (*++s); - return 0; /* No matching codeset! */ - } - } - - FIND_LANG_CULT: /* Find language_culture number. */ - s = LOCALE_NAMES; - do { /* TODO -- do a binary search? */ - /* TODO -- fix gen_mmap!*/ - ++lang_cult; /* Increment first since C/POSIX is 0. */ - if (!strncmp(s,p,5)) { /* Found a matching locale name; */ - goto FIND_LOCALE; - } - s += 5; - } while (lang_cult < NUM_LOCALE_NAMES); - return 0; /* No matching language_culture! */ - - FIND_LOCALE: /* Find locale row matching name and codeset */ - s = LOCALES; - n = 0; - do { /* TODO -- do a binary search? */ - if ((lang_cult == *s) && ((codeset == s[1]) || (codeset == s[2]))) { - i = ((category == LC_ALL) ? 0 : category); - s = new_locale + 2*i; - do { - /* Encode current locale row number. */ - *((unsigned char *) ++s) = (n >> 7) | 0x80; - *((unsigned char *) ++s) = (n & 0x7f) | 0x80; - } while (++i < category); - - return i; /* Return non-zero */ - } - s += WIDTH_LOCALES; - ++n; - } while (n <= NUM_LOCALES); /* We started at 1!!! */ - - return 0; /* Unsupported locale. */ -} - -static unsigned char *composite_locale(int category, const char *locale, unsigned char *new_locale) -{ - char buf[MAX_LOCALE_STR]; - char *t; - char *e; - int c; - - if (!strchr(locale,'=')) { - if (!find_locale(category, locale, new_locale)) { - return NULL; - } - return new_locale; - } - - if (strlen(locale) >= sizeof(buf)) { - return NULL; - } - stpcpy(buf, locale); - - t = strtok_r(buf, "=", &e); /* This can't fail because of strchr test above. */ - do { - for (c = 0 ; c < LC_ALL ; c++) { /* Find the category... */ - if (!strcmp(CATEGORY_NAMES + (int) CATEGORY_NAMES[c], t)) { - break; - } - } - t = strtok_r(NULL, ";", &e); - if ((category == LC_ALL) || (c == category)) { - if (!t || !find_locale(c, t, new_locale)) { - return NULL; + if (*loc == 0) { + *n++ = 'C'; + *n = 0; + } else { + char at = 0; + memcpy(n, LOCALE_NAMES + 5*((*loc)-1), 5); + if (n[2] != '_') { + at = n[2]; + n[2] = '_'; + } + n += 5; + *n++ = '.'; + if (loc[2] == 2) { + n = stpcpy(n, utf8); + } else if (loc[2] >= 3) { + n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3])); + } + if (at) { + const char *q; + *n++ = '@'; + q = LOCALE_AT_MODIFIERS; + do { + if (q[1] == at) { + n = stpcpy(n, q+2); + break; + } + q += 2 + *q; + } while (*q); + } + } + *n++ = ';'; } - } - } while ((t = strtok_r(NULL, "=", &e)) != NULL); + s += 2; + } while (++i < category); + *--n = 0; /* Remove trailing ';' and nul-terminate. */ - return new_locale; + ++category; + } while (!done); } char *setlocale(int category, const char *locale) { - const unsigned char *p; - int i; - unsigned char new_locale[LOCALE_STRING_SIZE]; - if (((unsigned int)(category)) > LC_ALL) { - /* TODO - set errno? SUSv3 doesn't say too. */ +#if 0 + __set_errno(EINVAL); /* glibc sets errno -- SUSv3 doesn't say. */ +#endif return NULL; /* Illegal/unsupported category. */ } - if (locale != NULL) { /* Not just a query... */ - stpcpy(new_locale, CUR_LOCALE_SPEC); /* Start with current. */ - - if (!*locale) { /* locale == "", so check environment. */ - i = ((category == LC_ALL) ? 0 : category); - do { - /* Note: SUSv3 doesn't define a fallback mechanism here. So, - * if LC_ALL is invalid, we do _not_ continue trying the other - * environment vars. */ - if (!(p = getenv("LC_ALL"))) { - if (!(p = getenv(CATEGORY_NAME