*
* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+/* Dec 20, 2002
+ *
+ * Initial test implementation of strcoll, strxfrm, wcscoll, and wcsxfrm.
+ * The code needs to be cleaned up a good bit, but I'd like to see people
+ * test it out.
+ */
+
#define _STDIO_UTILITY
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
+#include <assert.h>
+#include <locale.h>
#ifdef WANT_WIDE
#include <wchar.h>
#include <wctype.h>
-#include <locale.h>
+#include <bits/uClibc_uwchar.h>
#define Wvoid wchar_t
#define Wchar wchar_t
#define _SYS_NERR 126
#endif
+#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
#define _SYS_ERRMSG_MAXLEN 50
+#else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+#define _SYS_ERRMSG_MAXLEN 0
+#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
extern const char _string_syserrmsgs[];
#define _SYS_NSIG 32
+
+#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
#define _SYS_SIGMSG_MAXLEN 25
+#else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
+#define _SYS_SIGMSG_MAXLEN 0
+#endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
extern const char _string_syssigmsgs[];
#define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
#endif
-#if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 14
-#define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 14)
+#if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15
+#define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15)
#else
#define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN
#endif
/**********************************************************************/
-#ifdef L__string_syserrmsgs
+#if defined(L__string_syserrmsgs) && defined(__UCLIBC_HAS_ERRNO_MESSAGES__)
const char _string_syserrmsgs[] = {
/* 0: 0, 8 */ "Success\0"
#endif
/**********************************************************************/
+#if defined(L_sys_errlist) && defined(__UCLIBC_HAS_SYS_ERRLIST__)
+
+link_warning(_sys_errlist, "sys_nerr and sys_errlist are obsolete and uClibc support for them (in at least some configurations) will probably be unavailable in the near future.")
+
+const char *const sys_errlist[] = {
+ [0] = _string_syserrmsgs + 0,
+ [EPERM] = _string_syserrmsgs + 8,
+ [ENOENT] = _string_syserrmsgs + 32,
+ [ESRCH] = _string_syserrmsgs + 58,
+ [EINTR] = _string_syserrmsgs + 74,
+ [EIO] = _string_syserrmsgs + 98,
+ [ENXIO] = _string_syserrmsgs + 117,
+ [E2BIG] = _string_syserrmsgs + 143,
+ [ENOEXEC] = _string_syserrmsgs + 166,
+ [EBADF] = _string_syserrmsgs + 184,
+ [ECHILD] = _string_syserrmsgs + 204,
+ [EAGAIN] = _string_syserrmsgs + 223,
+ [ENOMEM] = _string_syserrmsgs + 256,
+ [EACCES] = _string_syserrmsgs + 279,
+ [EFAULT] = _string_syserrmsgs + 297,
+ [ENOTBLK] = _string_syserrmsgs + 309,
+ [EBUSY] = _string_syserrmsgs + 331,
+ [EEXIST] = _string_syserrmsgs + 355,
+ [EXDEV] = _string_syserrmsgs + 367,
+ [ENODEV] = _string_syserrmsgs + 393,
+ [ENOTDIR] = _string_syserrmsgs + 408,
+ [EISDIR] = _string_syserrmsgs + 424,
+ [EINVAL] = _string_syserrmsgs + 439,
+ [ENFILE] = _string_syserrmsgs + 456,
+ [EMFILE] = _string_syserrmsgs + 486,
+ [ENOTTY] = _string_syserrmsgs + 506,
+ [ETXTBSY] = _string_syserrmsgs + 537,
+ [EFBIG] = _string_syserrmsgs + 552,
+ [ENOSPC] = _string_syserrmsgs + 567,
+ [ESPIPE] = _string_syserrmsgs + 591,
+ [EROFS] = _string_syserrmsgs + 604,
+ [EMLINK] = _string_syserrmsgs + 626,
+ [EPIPE] = _string_syserrmsgs + 641,
+ [EDOM] = _string_syserrmsgs + 653,
+ [ERANGE] = _string_syserrmsgs + 686,
+ [EDEADLK] = _string_syserrmsgs + 716,
+ [ENAMETOOLONG] = _string_syserrmsgs + 742,
+ [ENOLCK] = _string_syserrmsgs + 761,
+ [ENOSYS] = _string_syserrmsgs + 780,
+ [ENOTEMPTY] = _string_syserrmsgs + 805,
+ [ELOOP] = _string_syserrmsgs + 825,
+ /* _string_syserrmsgs + 859, */
+ [ENOMSG] = _string_syserrmsgs + 860,
+ [EIDRM] = _string_syserrmsgs + 887,
+ [ECHRNG] = _string_syserrmsgs + 906,
+ [EL2NSYNC] = _string_syserrmsgs + 934,
+ [EL3HLT] = _string_syserrmsgs + 959,
+ [EL3RST] = _string_syserrmsgs + 974,
+ [ELNRNG] = _string_syserrmsgs + 988,
+ [EUNATCH] = _string_syserrmsgs + 1013,
+ [ENOCSI] = _string_syserrmsgs + 1042,
+ [EL2HLT] = _string_syserrmsgs + 1069,
+ [EBADE] = _string_syserrmsgs + 1084,
+ [EBADR] = _string_syserrmsgs + 1101,
+ [EXFULL] = _string_syserrmsgs + 1128,
+ [ENOANO] = _string_syserrmsgs + 1142,
+ [EBADRQC] = _string_syserrmsgs + 1151,
+ [EBADSLT] = _string_syserrmsgs + 1172,
+ /* _string_syserrmsgs + 1185, */
+ [EBFONT] = _string_syserrmsgs + 1186,
+ [ENOSTR] = _string_syserrmsgs + 1207,
+ [ENODATA] = _string_syserrmsgs + 1227,
+ [ETIME] = _string_syserrmsgs + 1245,
+ [ENOSR] = _string_syserrmsgs + 1259,
+ [ENONET] = _string_syserrmsgs + 1284,
+ [ENOPKG] = _string_syserrmsgs + 1314,
+ [EREMOTE] = _string_syserrmsgs + 1336,
+ [ENOLINK] = _string_syserrmsgs + 1353,
+ [EADV] = _string_syserrmsgs + 1375,
+ [ESRMNT] = _string_syserrmsgs + 1391,
+ [ECOMM] = _string_syserrmsgs + 1405,
+ [EPROTO] = _string_syserrmsgs + 1433,
+ [EMULTIHOP] = _string_syserrmsgs + 1448,
+ [EDOTDOT] = _string_syserrmsgs + 1467,
+ [EBADMSG] = _string_syserrmsgs + 1486,
+ [EOVERFLOW] = _string_syserrmsgs + 1498,
+ [ENOTUNIQ] = _string_syserrmsgs + 1536,
+ [EBADFD] = _string_syserrmsgs + 1563,
+ [EREMCHG] = _string_syserrmsgs + 1592,
+ [ELIBACC] = _string_syserrmsgs + 1615,
+ [ELIBBAD] = _string_syserrmsgs + 1654,
+ [ELIBSCN] = _string_syserrmsgs + 1691,
+ [ELIBMAX] = _string_syserrmsgs + 1723,
+ [ELIBEXEC] = _string_syserrmsgs + 1771,
+ [EILSEQ] = _string_syserrmsgs + 1809,
+ [ERESTART] = _string_syserrmsgs + 1859,
+ [ESTRPIPE] = _string_syserrmsgs + 1903,
+ [EUSERS] = _string_syserrmsgs + 1922,
+ [ENOTSOCK] = _string_syserrmsgs + 1937,
+ [EDESTADDRREQ] = _string_syserrmsgs + 1968,
+ [EMSGSIZE] = _string_syserrmsgs + 1997,
+ [EPROTOTYPE] = _string_syserrmsgs + 2014,
+ [ENOPROTOOPT] = _string_syserrmsgs + 2045,
+ [EPROTONOSUPPORT] = _string_syserrmsgs + 2068,
+ [ESOCKTNOSUPPORT] = _string_syserrmsgs + 2091,
+ [EOPNOTSUPP] = _string_syserrmsgs + 2117,
+ [EPFNOSUPPORT] = _string_syserrmsgs + 2141,
+ [EAFNOSUPPORT] = _string_syserrmsgs + 2171,
+ [EADDRINUSE] = _string_syserrmsgs + 2212,
+ [EADDRNOTAVAIL] = _string_syserrmsgs + 2235,
+ [ENETDOWN] = _string_syserrmsgs + 2267,
+ [ENETUNREACH] = _string_syserrmsgs + 2283,
+ [ENETRESET] = _string_syserrmsgs + 2306,
+ [ECONNABORTED] = _string_syserrmsgs + 2342,
+ [ECONNRESET] = _string_syserrmsgs + 2375,
+ [ENOBUFS] = _string_syserrmsgs + 2400,
+ [EISCONN] = _string_syserrmsgs + 2426,
+ [ENOTCONN] = _string_syserrmsgs + 2466,
+ [ESHUTDOWN] = _string_syserrmsgs + 2502,
+ [ETOOMANYREFS] = _string_syserrmsgs + 2548,
+ [ETIMEDOUT] = _string_syserrmsgs + 2583,
+ [ECONNREFUSED] = _string_syserrmsgs + 2604,
+ [EHOSTDOWN] = _string_syserrmsgs + 2623,
+ [EHOSTUNREACH] = _string_syserrmsgs + 2636,
+ [EALREADY] = _string_syserrmsgs + 2653,
+ [EINPROGRESS] = _string_syserrmsgs + 2683,
+ [ESTALE] = _string_syserrmsgs + 2709,
+ [EUCLEAN] = _string_syserrmsgs + 2731,
+ [ENOTNAM] = _string_syserrmsgs + 2756,
+ [ENAVAIL] = _string_syserrmsgs + 2784,
+ [EISNAM] = _string_syserrmsgs + 2814,
+ [EREMOTEIO] = _string_syserrmsgs + 2835,
+ [EDQUOT] = _string_syserrmsgs + 2852,
+ [ENOMEDIUM] = _string_syserrmsgs + 2872,
+ [EMEDIUMTYPE] = _string_syserrmsgs + 2888,
+
+#if EDEADLOCK != EDEADLK
+ [EDEADLOCK] = _string_syserrmsgs + 2906,
+#endif
+
+#if EWOULDBLOCK != EAGAIN
+#error EWOULDBLOCK does not equal EAGAIN
+#endif
+
+ /* For now, ignore the other arch-specific errors. glibc only maps EPROCLIM. */
+
+ /* some other mips errors */
+#ifdef ECANCELED
+#endif
+#ifdef EINIT
+#endif
+#ifdef EREMDEV
+#endif
+
+ /* some other sparc errors */
+#ifdef EPROCLIM
+#endif
+#ifdef ERREMOTE
+#endif
+};
+
+int sys_nerr = sizeof(sys_errlist)/sizeof(sys_errlist[0]);
+
+#endif
+/**********************************************************************/
#ifdef L_wmemcpy
#define L_memcpy
#define Wmemcpy wmemcpy
#ifdef L_strcmp
-#ifndef L_wcscmp
-#warning implement strcoll and remove weak alias (or enable for C locale only)
+#ifdef __LOCALE_C_ONLY
+#ifdef L_wcscmp
+weak_alias(wcscmp,wcscoll);
+#else /* L_wcscmp */
weak_alias(strcmp,strcoll);
-#endif
+#endif /* L_wcscmp */
+#endif /* __LOCALE_C_ONLY */
int Wstrcmp(register const Wchar *s1, register const Wchar *s2)
{
}
#endif
/**********************************************************************/
-#ifdef L_strcoll
-#error implement strcoll and remove weak_alias!!
-
-#if 0
-extern unsigned char *_ctype_collate;
-int strcoll(register const char *s1, const char *s2)
-{
- int r;
-
- while (!(r = (_ctype_collate[(int)(*s1++)]-_ctype_collate[(int)(*s2++)])));
-
- return r;
-}
-#endif
-
-#endif
-/**********************************************************************/
#ifdef L_wcsncmp
#define L_strncmp
#define Wstrncmp wcsncmp
#endif
/**********************************************************************/
-#ifdef L_strxfrm
-#error implement strxfrm
-/* size_t strxfrm(char *dst, const char *src, size_t len); */
-#endif
-/**********************************************************************/
#ifdef L_wmemchr
#define L_memchr
#define Wmemchr wmemchr
#endif
/**********************************************************************/
-#ifdef L_wcscasecmp
-#define L_strcasecmp
-#define Wstrcasecmp wcscasecmp
+#if defined(L_strcasecmp) || defined(L_strcasecmp_l) || defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
+
+#if defined(L_wcscasecmp) || defined(L_wcscasecmp_l)
+
+#define strcasecmp wcscasecmp
+#define strcasecmp_l wcscasecmp_l
+#define __strcasecmp_l __wcscasecmp_l
+#ifdef __UCLIBC_DO_XLOCALE
+#define TOLOWER(C) __towlower_l((C), locale_arg)
+#else
+#define TOLOWER(C) towlower((C))
+#endif
+
+#else /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
+
+#ifdef __UCLIBC_DO_XLOCALE
+#define TOLOWER(C) __tolower_l((C), locale_arg)
#else
-#define Wstrcasecmp strcasecmp
+#define TOLOWER(C) tolower((C))
#endif
-#ifdef L_strcasecmp
+#endif /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
+
-int Wstrcasecmp(register const Wchar *s1, register const Wchar *s2)
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+int strcasecmp(register const Wchar *s1, register const Wchar *s2)
+{
+ return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
+}
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
+ __LOCALE_PARAM )
{
#ifdef WANT_WIDE
- while ((*s1 == *s2) || (towlower(*s1) == towlower(*s2))) {
+ while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) {
if (!*s1++) {
return 0;
}
++s2;
}
- return (((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1;
+ return (((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1;
/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
#else
int r = 0;
while ( ((s1 == s2) ||
- !(r = ((int)( tolower(*((Wuchar *)s1))))
- - tolower(*((Wuchar *)s2))))
+ !(r = ((int)( TOLOWER(*((Wuchar *)s1))))
+ - TOLOWER(*((Wuchar *)s2))))
&& (++s2, *s1++));
return r;
#endif
}
+__XL_ALIAS(strcasecmp)
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
#endif
/**********************************************************************/
-#ifdef L_wcsncasecmp
-#define L_strncasecmp
-#define Wstrncasecmp wcsncasecmp
+#if defined(L_strncasecmp) || defined(L_strncasecmp_l) || defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
+
+#if defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l)
+
+#define strncasecmp wcsncasecmp
+#define strncasecmp_l wcsncasecmp_l
+#define __strncasecmp_l __wcsncasecmp_l
+#ifdef __UCLIBC_DO_XLOCALE
+#define TOLOWER(C) __towlower_l((C), locale_arg)
#else
-#define Wstrncasecmp strncasecmp
+#define TOLOWER(C) towlower((C))
#endif
-#ifdef L_strncasecmp
+#else /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
+
+#ifdef __UCLIBC_DO_XLOCALE
+#define TOLOWER(C) __tolower_l((C), locale_arg)
+#else
+#define TOLOWER(C) tolower((C))
+#endif
+
+#endif /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
+
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+int strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+{
+ return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
+}
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-int Wstrncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+int __XL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
+ size_t n __LOCALE_PARAM )
{
#ifdef WANT_WIDE
- while (n && ((*s1 == *s2) || (towlower(*s1) == towlower(*s2)))) {
+ while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) {
if (!*s1++) {
return 0;
}
return (n == 0)
? 0
- : ((((Wuchar)towlower(*s1)) < ((Wuchar)towlower(*s2))) ? -1 : 1);
+ : ((((Wuchar)TOLOWER(*s1)) < ((Wuchar)TOLOWER(*s2))) ? -1 : 1);
/* TODO -- should wide cmp funcs do wchar or Wuchar compares? */
#else
int r = 0;
while ( n
&& ((s1 == s2) ||
- !(r = ((int)( tolower(*((unsigned char *)s1))))
- - tolower(*((unsigned char *)s2))))
+ !(r = ((int)( TOLOWER(*((unsigned char *)s1))))
+ - TOLOWER(*((unsigned char *)s2))))
&& (--n, ++s2, *s1++));
return r;
#endif
}
+
+__XL_ALIAS(strncasecmp)
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
#endif
/**********************************************************************/
#ifdef L_wcsnlen
char *strerror(int errnum)
{
- static char buf[_SYS_ERRMSG_MAXLEN];
+ static char buf[_STRERROR_BUFSIZE];
_susv3_strerror_r(errnum, buf, sizeof(buf));
/**********************************************************************/
#ifdef L__susv3_strerror_r
+#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
static const unsigned char estridx[] = {
#endif
-
int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
register char *s;
int i, retval;
- char buf[_SYS_ERRMSG_MAXLEN];
- static const char unknown[14] = {
+ char buf[_STRERROR_BUFSIZE];
+ static const char unknown[] = {
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
};
retval = EINVAL;
+#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
+
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
/* Need to translate errno to string index. */
for (i = 0 ; i < sizeof(estridx)/sizeof(estridx[0]) ; i++) {
}
}
+#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
memcpy(s, unknown, sizeof(unknown));
return retval;
}
+#else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
+int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+{
+ register char *s;
+ int i, retval;
+ char buf[_STRERROR_BUFSIZE];
+ static const char unknown[] = {
+ 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', ' '
+ };
+
+ s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
+ memcpy(s, unknown, sizeof(unknown));
+
+ if (!strerrbuf) { /* SUSv3 */
+ buflen = 0;
+ }
+
+ retval = EINVAL;
+
+ i = buf + sizeof(buf) - s;
+
+ if (i > buflen) {
+ i = buflen;
+ retval = ERANGE;
+ }
+
+ if (i) {
+ memcpy(strerrbuf, s, i);
+ strerrbuf[i-1] = 0; /* In case buf was too small. */
+ }
+
+ __set_errno(retval);
+
+ return retval;
+}
+
+#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
#endif
/**********************************************************************/
/* GNU extension functions. */
#endif
/**********************************************************************/
+#ifdef L_memmem
+
+void *memmem(const void *haystack, size_t haystacklen,
+ const void *needle, size_t needlelen)
+{
+ register const char *ph;
+ register const char *pn;
+ const char *plast;
+ size_t n;
+
+ if (needlelen == 0) {
+ return (void *) haystack;
+ }
+
+ if (haystacklen >= needlelen) {
+ ph = (const char *) haystack;
+ pn = (const char *) needle;
+ plast = ph + (haystacklen - needlelen);
+
+ do {
+ n = 0;
+ while (ph[n] == pn[n]) {
+ if (++n == needlelen) {
+ return (void *) ph;
+ }
+ }
+ } while (++ph <= plast);
+ }
+
+ return NULL;
+}
+
+#endif
+/**********************************************************************/
#ifdef L_wmempcpy
#define L_mempcpy
#define Wmempcpy wmempcpy
/**********************************************************************/
#ifdef L_wcschrnul
#define L_strchrnul
+#define __Wstrchrnul __wcschrnul
#define Wstrchrnul wcschrnul
#else
+#define __Wstrchrnul __strchrnul
#define Wstrchrnul strchrnul
#endif
#ifdef L_strchrnul
-Wchar *Wstrchrnul(register const Wchar *s, Wint c)
+extern Wchar *__Wstrchrnul(register const Wchar *s, Wint c);
+weak_alias(__Wstrchrnul, Wstrchrnul);
+
+Wchar *__Wstrchrnul(register const Wchar *s, Wint c)
{
--s;
while (*++s && (*s != ((Wchar)c)));
#endif
/**********************************************************************/
+#ifdef WANT_WIDE
+extern size_t __wcslcpy(wchar_t *__restrict dst,
+ const wchar_t *__restrict src,
+ size_t n);
+#endif
+
+
+#ifdef L___wcslcpy
+#define L_strlcpy
+#define Wstrlcpy __wcslcpy
+#ifdef __LOCALE_C_ONLY
+weak_alias(__wcslcpy,wcsxfrm);
+#endif
+#endif
+
#ifdef L_strlcpy
+#ifndef L___wcslcpy
+#define Wstrlcpy strlcpy
+#ifdef __LOCALE_C_ONLY
+weak_alias(strlcpy,strxfrm);
+#endif
+#endif
+
/* OpenBSD function:
* Copy at most n-1 chars from src to dst and nul-terminate dst.
* Returns strlen(src), so truncation occurred if the return value is >= n. */
-size_t strlcpy(register char *__restrict dst,
- register const char *__restrict src,
- size_t n)
+size_t Wstrlcpy(register Wchar *__restrict dst,
+ register const Wchar *__restrict src,
+ size_t n)
{
- const char *src0 = src;
- char dummy[1];
+ const Wchar *src0 = src;
+ Wchar dummy[1];
if (!n) {
dst = dummy;
#endif
/**********************************************************************/
-#ifdef L__string_syssigmsgs
+#if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__)
const char _string_syssigmsgs[] = {
/* 0: 0, 1 */ "\0"
#endif
/**********************************************************************/
-#ifdef L_sys_siglist
+#if defined(L_sys_siglist) && defined(__UCLIBC_HAS_SYS_SIGLIST__)
const char *const sys_siglist[_NSIG] = {
NULL,
/* TODO: make a threadsafe version? */
+#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
+
char *strsignal(int signum)
{
register char *s;
int i;
static char buf[_STRSIGNAL_BUFSIZE];
- static const char unknown[15] = {
+ static const char unknown[] = {
'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
};
return s;
}
+#else /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
+
+char *strsignal(int signum)
+{
+ static char buf[_STRSIGNAL_BUFSIZE];
+ static const char unknown[] = {
+ 'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
+ };
+
+ return (char *) memcpy(_int10tostr(buf+sizeof(buf)-1, signum)
+ - sizeof(unknown),
+ unknown, sizeof(unknown));
+}
+
+#endif /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
+
#endif
/**********************************************************************/
#ifdef L_psignal
#endif
/**********************************************************************/
+#ifndef __LOCALE_C_ONLY
+#if defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l)
+
+#ifdef L_strxfrm
+#ifndef WANT_WIDE
+#error WANT_WIDE should be defined for L_strxfrm
+#endif
+#ifdef L_wcsxfrm
+#error L_wcsxfrm already defined for L_strxfrm
+#endif
+#endif /* L_strxfrm */
+
+#if defined(L_strxfrm) || defined(L_strxfrm_l)
+
+#define wcscoll strcoll
+#define wcscoll_l strcoll_l
+#define __wcscoll_l __strcoll_l
+#define wcsxfrm strxfrm
+#define wcsxfrm_l strxfrm_l
+#define __wcsxfrm_l __strxfrm_l
+
+#undef WANT_WIDE
+#undef Wvoid
+#undef Wchar
+#undef Wuchar
+#undef Wint
+
+#define Wchar char
+
+#endif /* defined(L_strxfrm) || defined(L_strxfrm_l) */
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+int wcscoll (const Wchar *s0, const Wchar *s1)
+{
+ return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
+}
+
+size_t wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
+{
+ return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
+}
+
+#else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+
+#if 0
+#define CUR_COLLATE (&__UCLIBC_CURLOCALE_DATA.collate)
+#else
+#define CUR_COLLATE (& __LOCALE_PTR->collate)
+#endif
+
+#define MAX_PENDING 8
+
+typedef struct {
+ const Wchar *s;
+ const Wchar *eob; /* end of backward */
+
+ __uwchar_t weight;
+ __uwchar_t ui_weight; /* undefined or invalid */
+ int colitem;
+ int weightidx;
+ int rule;
+ size_t position;
+ /* should be wchar_t. if wchar < 0 do EILSEQ? */
+ __uwchar_t *cip;
+ __uwchar_t ci_pending[MAX_PENDING]; /* nul-terminated */
+
+ char *back_buf;
+ char *bbe; /* end of back_buf (actual last... not 1 past end) */
+ char *bp; /* ptr into backbuf, NULL if not in backward mode */
+ char ibb[128];
+ size_t bb_size;
+
+ int ru_pushed;
+} col_state_t;
+
+
+#define WEIGHT_MASK 0x3fffU
+#define RULE_MASK 0xc000U
+
+#define RULE_FORWARD (1 << 14)
+#define RULE_POSITION (1 << 15)
+
+#define UI_IDX (WEIGHT_MASK-6)
+#define POSIT_IDX (WEIGHT_MASK-5)
+#define RANGE_IDX (WEIGHT_MASK-4)
+#define UNDEF_IDX (WEIGHT_MASK-3)
+#define INVAL_IDX (WEIGHT_MASK-2)
+#define DITTO_IDX (WEIGHT_MASK-1)
+
+
+#undef TRACE
+#if 0
+#define TRACE(X) printf X
+#else
+#define TRACE(X) ((void)0)
+#endif
+
+static int lookup(wchar_t wc __LOCALE_PARAM )
+{
+ unsigned int sc, n, i0, i1;
+
+ if (((__uwchar_t) wc) > 0xffffU) {
+ return 0;
+ }
+
+ sc = wc & CUR_COLLATE->ti_mask;
+ wc >>= CUR_COLLATE->ti_shift;
+ n = wc & CUR_COLLATE->ii_mask;
+ wc >>= CUR_COLLATE->ii_shift;
+
+ i0 = CUR_COLLATE->wcs2colidt_tbl[wc];
+ i0 <<= CUR_COLLATE->ii_shift;
+ i1 = CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + i0 + n];
+ i1 <<= CUR_COLLATE->ti_shift;
+ return CUR_COLLATE->wcs2colidt_tbl[CUR_COLLATE->ii_len + CUR_COLLATE->ti_len + i1 + sc];
+
+}
+
+static void init_col_state(col_state_t *cs, const Wchar *wcs)
+{
+ memset(cs, 0, sizeof(col_state_t));
+ cs->s = wcs;
+ cs->bp = cs->back_buf = cs->ibb;
+ cs->bb_size = 128;
+ cs->bbe = cs->back_buf + (cs->bb_size -1);
+}
+
+static void next_weight(col_state_t *cs, int pass __LOCALE_PARAM )
+{
+ int r, w, ru, ri, popping_backup_stack;
+ ssize_t n;
+ const uint16_t *p;
+#ifdef WANT_WIDE
+#define WC (*cs->s)
+#define N (1)
+#else /* WANT_WIDE */
+ wchar_t WC;
+ size_t n0, nx;
+#define N n0
+
+#endif /* WANT_WIDE */
+
+ do {
+
+ if (cs->ru_pushed) {
+ ru = cs->ru_pushed;
+ TRACE(("ru_pushed = %d\n", ru));
+ cs->ru_pushed = 0;
+ goto POSITION_SKIP;
+ }
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning should we walk pendings backwards?
+#endif
+ if (cs->cip) { /* possible pending weight */
+ if ((r = *(cs->cip++)) == 0) {
+ cs->cip = NULL;
+ continue;
+ }
+ cs->weightidx = r & WEIGHT_MASK;
+ assert(cs->weightidx);
+/* assert(cs->weightidx != WEIGHT_MASK); */
+ } else { /* get the next collation item from the string */
+ TRACE(("clearing popping flag\n"));
+ popping_backup_stack = 0;
+
+ IGNORE_LOOP:
+ /* keep first pos as 0 for a sentinal */
+ if (*cs->bp) { /* pending backward chars */
+ POP_BACKUP:
+ popping_backup_stack = 1;
+ TRACE(("setting popping flag\n"));
+ n = 0;
+ if (*cs->bp > 0) { /* singles pending */
+ cs->s -= 1;
+ if ((*cs->bp -= 1) == 0) {
+ cs->bp -= 1;
+ }
+ } else { /* last was a multi */
+ cs->s += *cs->bp;
+ cs->bp -= 1;
+ }
+ } else if (!*cs->s) { /* not in backward mode and end of string */
+ cs->weight = 0;
+ return;
+ } else {
+ cs->position += 1;
+ }
+
+ BACK_LOOP:
+#ifdef WANT_WIDE
+ n = 1;
+ cs->colitem = r = lookup(*cs->s __LOCALE_ARG );
+#else /* WANT_WIDE */
+ n = n0 = __locale_mbrtowc_l(&WC, cs->s, __LOCALE_PTR);
+ if (n < 0) {
+ __set_errno(EILSEQ);
+ cs->weight = 0;
+ return;
+ }
+ cs->colitem = r = lookup(WC __LOCALE_ARG );
+#endif /* WANT_WIDE */
+
+ TRACE((" r=%d WC=%#lx\n", r, (unsigned long)(WC)));
+
+ if (r > CUR_COLLATE->max_col_index) { /* starting char for one or more sequences */
+ p = CUR_COLLATE->multistart_tbl;
+ p += p[r-CUR_COLLATE->max_col_index -1];
+ do {
+ n = N;
+ r = *p++;
+ do {
+ if (!*p) { /* found it */
+ cs->colitem = r;
+ TRACE((" found multi %d\n", n));
+ goto FOUND;
+ }
+#ifdef WANT_WIDE
+ /* the lookup check here is safe since we're assured that *p is a valid colidx */
+ if (!cs->s[n] || (lookup(cs->s[n] __LOCALE_ARG ) != *p)) {
+ do {} while (*p++);
+ break;
+ }
+ ++p;
+ ++n;
+#else /* WANT_WIDE */
+ if (cs->s[n]) {
+ nx = __locale_mbrtowc_l(&WC, cs->s + n, __LOCALE_PTR);
+ if (nx < 0) {
+ __set_errno(EILSEQ);
+ cs->weight = 0;
+ return;
+ }
+ }
+ if (!cs->s[n] || (lookup(WC __LOCALE_ARG ) != *p)) {
+ do {} while (*p++);
+ break;
+ }
+ ++p;
+ n += nx; /* Only gets here if cs->s[n] != 0, so nx is set. */
+#endif /* WANT_WIDE */
+ } while (1);
+ } while (1);
+ } else if (r == 0) { /* illegal, undefined, or part of a range */
+ if ((CUR_COLLATE->range_count)
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning .. need to introduce range as a collating item?
+#endif
+ && (((__uwchar_t)(WC - CUR_COLLATE->range_low)) <= CUR_COLLATE->range_count)
+ ) { /* part of a range */
+ /* Note: cs->colitem = 0 already. */
+ TRACE((" found range\n"));
+ ru = CUR_COLLATE->ruletable[CUR_COLLATE->range_rule_offset*CUR_COLLATE->MAX_WEIGHTS + pass];
+ assert((ru & WEIGHT_MASK) != DITTO_IDX);
+ if ((ru & WEIGHT_MASK) == WEIGHT_MASK) {
+ ru = (ru & RULE_MASK) | RANGE_IDX;
+ cs->weight = CUR_COLLATE->range_base_weight + (WC - CUR_COLLATE->range_low);
+ }
+ goto RANGE_SKIP_TO;
+ } else if (((__uwchar_t)(WC)) <= 0x7fffffffUL) { /* legal but undefined */
+ UNDEFINED:
+ /* Note: cs->colitem = 0 already. */
+ ri = CUR_COLLATE->undefined_idx;
+ assert(ri != 0); /* implicit undefined isn't supported */
+
+ TRACE((" found explicit UNDEFINED\n"));
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning right now single weight locales do not support ..
+#endif
+ if (CUR_COLLATE->num_weights == 1) {
+ TRACE((" single weight UNDEFINED\n"));
+ cs->weightidx = RANGE_IDX;
+ cs->weight = ri;
+ cs->s += n;
+ goto PROCESS_WEIGHT;
+ }
+
+ ri = CUR_COLLATE->index2ruleidx[ri - 1];
+ ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
+ assert((ru & WEIGHT_MASK) != WEIGHT_MASK); /* TODO: handle ".." */
+ if ((ru & WEIGHT_MASK) == DITTO_IDX) {
+ cs->colitem = CUR_COLLATE->undefined_idx;
+ }
+ goto RANGE_SKIP_TO;
+ } else { /* illegal */
+ TRACE((" found illegal\n"));
+ __set_errno(EINVAL);
+ /* We put all illegals in the same equiv class with maximal weight,
+ * and ignore them after the first pass. */
+ if (pass > 0) {
+ cs->s += n;
+ goto IGNORE_LOOP;
+ }
+ ru = (RULE_FORWARD | RANGE_IDX);
+ cs->weight = 0xffffU;
+ goto RANGE_SKIP_TO;
+ }
+ } else if (CUR_COLLATE->num_weights == 1) {
+ TRACE((" single weight\n"));
+ cs->weightidx = RANGE_IDX;
+ cs->weight = cs->colitem;
+ cs->s += n;
+ goto PROCESS_WEIGHT;
+ } else {
+ TRACE((" normal\n"));
+ }
+
+ /* if we get here, it is a normal char either singlely weighted, undefined, or in a range */
+ FOUND:
+ ri = CUR_COLLATE->index2ruleidx[cs->colitem - 1];
+ TRACE((" ri=%d ", ri));
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning make sure this is correct
+#endif
+ if (!ri) {
+ TRACE(("NOT IN THIS LOCALE\n"));
+ goto UNDEFINED;
+ }
+ ru = CUR_COLLATE->ruletable[ri * CUR_COLLATE->MAX_WEIGHTS + pass];
+
+ RANGE_SKIP_TO:
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning ignoreables probably should not interrupt backwards processing, but this is wrong
+#endif
+/* if (!(ru & WEIGHT_MASK)) { */
+/* TRACE(("IGNORE\n")); */
+/* cs->s += n; */
+/* continue; */
+/* } */
+
+
+ TRACE((" rule = %#x weight = %#x popping = %d s = %p eob = %p\n",
+ ru & RULE_MASK, ru & WEIGHT_MASK, popping_backup_stack,
+ cs->s, cs->eob));
+ /* now we need to check if we're going backwards... */
+
+ if (!popping_backup_stack) {
+ if (!(ru & RULE_MASK)) { /* backward */
+ TRACE(("backwards\n"));
+ assert(cs->bp <= cs->bbe);
+ if (cs->bp == cs->bbe) {
+ if (cs->back_buf == cs->ibb) { /* was using internal buffer */
+ cs->bp = malloc(cs->bb_size + 128);
+ if (!cs->bp) {
+ __set_errno(ENOMEM);
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning what to do here?
+#endif
+ cs->weight = 0;
+ return;
+ }
+ memcpy(cs->bp, cs->back_buf, cs->bb_size);
+
+ } else {
+ cs->bp = realloc(cs->back_buf, cs->bb_size + 128);
+ if (!cs->bp) {
+ __set_errno(ENOMEM);
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning what to do here?
+#endif
+ cs->weight = 0;
+ return;
+ }
+ }
+ cs->bb_size += 128;
+ cs->bbe = cs->bp + (cs->bbe - cs->back_buf);
+ cs->back_buf = cs->bp;
+ cs->bp = cs->bbe;
+
+ }
+ if (n==1) { /* single char */
+ if (*cs->bp && (((unsigned char)(*cs->bp)) < CHAR_MAX)) {
+ *cs->bp += 1; /* increment last single's count */
+ } else { /* last was a multi, or just starting */
+ if (!cs->bp) {
+ cs->bp = cs->back_buf;
+ } else {
+ assert(cs->bp < cs->bbe);
+ ++cs->bp;
+ }
+ *cs->bp = 1;
+ }
+ } else { /* multichar */
+ assert(n>1);
+ assert(cs->bp < cs->bbe);
+ *++cs->bp = -n;
+ }
+ cs->s += n;
+ if (*cs->s) {
+ goto BACK_LOOP;
+ }
+ /* end-of-string so start popping */
+ cs->eob = cs->s;
+ TRACE(("popping\n"));
+ goto POP_BACKUP;
+ } else if (*cs->bp) { /* was going backward but this element isn't */
+ /* discard current and use previous backward element */
+ assert(!cs->cip);
+ cs->eob = cs->s;
+ TRACE(("popping\n"));
+ goto POP_BACKUP;
+ } else { /* was and still going forward */
+ TRACE(("forwards\n"));
+ if ((ru & (RULE_POSITION|WEIGHT_MASK)) > RULE_POSITION) {
+ assert(ru & WEIGHT_MASK);
+ cs->ru_pushed = ru;
+ cs->weight = cs->position;
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning devel code
+#endif
+ cs->position = 0; /* reset to reduce size for strcoll? */
+ cs->s += n;
+ cs->weightidx = RANGE_IDX;
+ goto PROCESS_WEIGHT;
+ }
+ }
+ } else { /* popping backwards stack */
+ TRACE(("popping (continued)\n"));
+ if (!*cs->bp) {
+ cs->s = cs->eob;
+ }
+ cs->s -= n;
+ }
+
+ cs->s += n;
+ POSITION_SKIP:
+ cs->weightidx = ru & WEIGHT_MASK;
+ cs->rule = ru & RULE_MASK;
+ }
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning for pending we only want the weight... _not_ the rule
+#endif
+ if (!cs->weightidx) { /* ignore */
+ continue;
+ }
+
+ PROCESS_WEIGHT:
+ assert(cs->weightidx);
+
+
+ if (((unsigned int)(cs->weightidx - UI_IDX)) <= (INVAL_IDX-UI_IDX)) {
+ if (cs->weightidx == UI_IDX) {
+ cs->weight = cs->ui_weight;
+ }
+ return;
+ }
+
+ assert(cs->weightidx != WEIGHT_MASK);
+ if (cs->weightidx == DITTO_IDX) { /* want the weight of the current collating item */
+ TRACE(("doing ditto\n"));
+ w = CUR_COLLATE->index2weight[cs->colitem -1];
+ } else if (cs->weightidx <= CUR_COLLATE->max_col_index) { /* normal */
+ TRACE(("doing normal\n"));
+ w = CUR_COLLATE->index2weight[cs->weightidx -1];
+ } else { /* a string */
+ TRACE(("doing string\n"));
+ assert(!(cs->weightidx & RULE_MASK));
+ /* note: iso14561 allows null string here */
+ p = CUR_COLLATE->weightstr + (cs->weightidx - (CUR_COLLATE->max_col_index + 2));
+ if (*p & WEIGHT_MASK) {
+ r = 0;
+ do {
+ assert(r < MAX_PENDING);
+ cs->ci_pending[r++] = *p++;
+ } while (*p & WEIGHT_MASK);
+ cs->cip = cs->ci_pending;
+ }
+ continue;
+ }
+
+ cs->weight = w;
+ return;
+ } while (1);
+}
+
+int __XL(wcscoll) (const Wchar *s0, const Wchar *s1 __LOCALE_PARAM )
+{
+ col_state_t ws[2];
+ int pass;
+
+ if (!CUR_COLLATE->num_weights) { /* C locale */
+#ifdef WANT_WIDE
+ return wcscmp(s0, s1);
+#else /* WANT_WIDE */
+ return strcmp(s0, s1);
+#endif /* WANT_WIDE */
+ }
+
+ pass = 0;
+ do { /* loop through the weights levels */
+ init_col_state(ws, s0);
+ init_col_state(ws+1, s1);
+ do { /* loop through the strings */
+ /* for each string, get the next weight */
+ next_weight(ws, pass __LOCALE_ARG );
+ next_weight(ws+1, pass __LOCALE_ARG );
+ TRACE(("w0=%lu w1=%lu\n",
+ (unsigned long) ws[0].weight,
+ (unsigned long) ws[1].weight));
+
+ if (ws[0].weight != ws[1].weight) {
+ return ws[0].weight - ws[1].weight;
+ }
+ } while (ws[0].weight);
+ } while (++pass < CUR_COLLATE->num_weights);
+
+ return 0;
+}
+
+__XL_ALIAS(wcscoll)
+
+#ifdef WANT_WIDE
+
+size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
+ size_t n __LOCALE_PARAM )
+{
+ col_state_t cs;
+ size_t count;
+ int pass;
+
+ if (!CUR_COLLATE->num_weights) { /* C locale */
+ return __wcslcpy(ws1, ws2, n);
+ }
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning handle empty string as a special case
+#endif
+
+ count = pass = 0;
+ do { /* loop through the weights levels */
+ init_col_state(&cs, ws2);
+ do { /* loop through the string */
+ next_weight(&cs, pass __LOCALE_ARG );
+ TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
+ if (count < n) {
+ ws1[count] = cs.weight +1;
+ }
+ ++count;
+ TRACE(("--------------------------------------------\n"));
+ } while (cs.weight);
+ if (count <= n) { /* overwrite the trailing 0 end-of-pass marker */
+ ws1[count-1] = 1;
+ }
+ TRACE(("-------------------- pass %d --------------------\n", pass));
+ } while (++pass < CUR_COLLATE->num_weights);
+ if (count <= n) { /* oops... change it back */
+ ws1[count-1] = 0;
+ }
+ return count-1;
+}
+
+__XL_ALIAS(wcsxfrm)
+
+#else /* WANT_WIDE */
+
+static const unsigned long bound[] = {
+ 1UL << 7,
+ 1UL << 11,
+ 1UL << 16,
+ 1UL << 21,
+ 1UL << 26,
+};
+
+static unsigned char first[] = {
+ 0x0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+};
+
+/* Use an extension of UTF-8 to store a 32 bit val in max 6 bytes. */
+
+static size_t store(unsigned char *s, size_t count, size_t n, __uwchar_t weight)
+{
+ int i, r;
+
+ i = 0;
+ do {
+ if (weight < bound[i]) {
+ break;
+ }
+ } while (++i < sizeof(bound)/sizeof(bound[0]));
+
+ r = i+1;
+ if (i + count < n) {
+ s += count;
+ s[0] = first[i];
+ while (i) {
+ s[i] = 0x80 | (weight & 0x3f);
+ weight >>= 6;
+ --i;
+ }
+ s[0] |= weight;
+ }
+
+ return r;
+}
+
+size_t __XL(strxfrm)(char *__restrict ws1, const char *__restrict ws2, size_t n
+ __LOCALE_PARAM )
+{
+ col_state_t cs;
+ size_t count, inc;
+ int pass;
+
+ if (!CUR_COLLATE->num_weights) { /* C locale */
+ return strlcpy(ws1, ws2, n);
+ }
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning handle empty string as a special case
+#endif
+
+ inc = count = pass = 0;
+ do { /* loop through the weights levels */
+ init_col_state(&cs, ws2);
+ do { /* loop through the string */
+ next_weight(&cs, pass __LOCALE_ARG );
+ TRACE(("weight=%lu (%#lx)\n", (unsigned long) cs.weight, (unsigned long) cs.weight));
+ inc = store((unsigned char *)ws1, count, n, cs.weight + 1);
+ count += inc;
+ TRACE(("--------------------------------------------\n"));
+ } while (cs.weight);
+ /* overwrite the trailing 0 end-of-pass marker */
+ assert(inc == 1);
+ if (count <= n) {
+ ws1[count-1] = 1;
+ }
+ TRACE(("-------------------- pass %d --------------------\n", pass));
+ } while (++pass < CUR_COLLATE->num_weights);
+ if (count <= n) { /* oops... change it back */
+ ws1[count-1] = 0;
+ }
+ return count-1;
+}
+
+__XL_ALIAS(strxfrm)
+
+#endif /* WANT_WIDE */
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+#endif /* defined(L_strxfrm) || defined(L_strxfrm_l) || defined(L_wcsxfrm) || defined(L_wcsxfrm_l) */
+
+#endif /* __LOCALE_C_ONLY */
+/**********************************************************************/