Browse Source

Complete split of all the string functions. Hope haven't broken too much. wcscoll/strcoll needs some love ...

Peter S. Mazinger 18 năm trước cách đây
mục cha
commit
167d5e33fc
93 tập tin đã thay đổi với 3253 bổ sung3702 xóa
  1. 37 80
      libc/string/Makefile.in
  2. 19 0
      libc/string/__glibc_strerror_r.c
  3. 35 0
      libc/string/__xpg_basename.c
  4. 273 0
      libc/string/__xpg_strerror_r.c
  5. 686 0
      libc/string/_collate.c
  6. 33 0
      libc/string/_string.h
  7. 146 0
      libc/string/_string_syserrmsgs.c
  8. 50 0
      libc/string/_string_syssigmsgs.c
  9. 35 0
      libc/string/_syserrmsg.h
  10. 26 0
      libc/string/basename.c
  11. 53 0
      libc/string/bcopy.c
  12. 31 0
      libc/string/bzero.c
  13. 43 0
      libc/string/dirname.c
  14. 54 0
      libc/string/ffs.c
  15. 22 0
      libc/string/memccpy.c
  16. 31 5
      libc/string/memchr.c
  17. 33 6
      libc/string/memcmp.c
  18. 28 5
      libc/string/memcpy.c
  19. 40 0
      libc/string/memmem.c
  20. 48 5
      libc/string/memmove.c
  21. 28 5
      libc/string/mempcpy.c
  22. 33 0
      libc/string/memrchr.c
  23. 28 5
      libc/string/memset.c
  24. 30 0
      libc/string/psignal.c
  25. 19 0
      libc/string/rawmemchr.c
  26. 22 5
      libc/string/stpcpy.c
  27. 32 5
      libc/string/stpncpy.c
  28. 75 0
      libc/string/strcasecmp.c
  29. 8 0
      libc/string/strcasecmp_l.c
  30. 51 0
      libc/string/strcasestr.c
  31. 20 5
      libc/string/strcat.c
  32. 23 6
      libc/string/strchr.c
  33. 16 5
      libc/string/strchrnul.c
  34. 38 8
      libc/string/strcmp.c
  35. 24 5
      libc/string/strcpy.c
  36. 23 5
      libc/string/strcspn.c
  37. 24 9
      libc/string/strdup.c
  38. 21 0
      libc/string/strerror.c
  39. 46 0
      libc/string/strlcat.c
  40. 46 9
      libc/string/strlcpy.c
  41. 18 5
      libc/string/strlen.c
  42. 78 0
      libc/string/strncasecmp.c
  43. 8 0
      libc/string/strncasecmp_l.c
  44. 29 5
      libc/string/strncat.c
  45. 33 5
      libc/string/strncmp.c
  46. 30 5
      libc/string/strncpy.c
  47. 25 0
      libc/string/strndup.c
  48. 28 5
      libc/string/strnlen.c
  49. 22 5
      libc/string/strpbrk.c
  50. 25 6
      libc/string/strrchr.c
  51. 31 0
      libc/string/strsep.c
  52. 144 0
      libc/string/strsignal.c
  53. 23 5
      libc/string/strspn.c
  54. 36 5
      libc/string/strstr.c
  55. 22 0
      libc/string/strtok.c
  56. 45 9
      libc/string/strtok_r.c
  57. 9 0
      libc/string/strxfrm.c
  58. 10 0
      libc/string/strxfrm_l.c
  59. 171 0
      libc/string/sys_errlist.c
  60. 57 0
      libc/string/sys_siglist.c
  61. 1 8
      libc/string/wcpcpy.c
  62. 1 8
      libc/string/wcpncpy.c
  63. 8 0
      libc/string/wcscasecmp.c
  64. 9 0
      libc/string/wcscasecmp_l.c
  65. 1 8
      libc/string/wcscat.c
  66. 1 8
      libc/string/wcschr.c
  67. 1 8
      libc/string/wcschrnul.c
  68. 1 13
      libc/string/wcscmp.c
  69. 1 8
      libc/string/wcscpy.c
  70. 1 8
      libc/string/wcscspn.c
  71. 1 13
      libc/string/wcsdup.c
  72. 1 10
      libc/string/wcslcpy.c
  73. 1 8
      libc/string/wcslen.c
  74. 8 0
      libc/string/wcsncasecmp.c
  75. 9 0
      libc/string/wcsncasecmp_l.c
  76. 1 8
      libc/string/wcsncat.c
  77. 1 8
      libc/string/wcsncmp.c
  78. 1 8
      libc/string/wcsncpy.c
  79. 1 8
      libc/string/wcsnlen.c
  80. 1 8
      libc/string/wcspbrk.c
  81. 1 8
      libc/string/wcsrchr.c
  82. 1 8
      libc/string/wcsspn.c
  83. 1 10
      libc/string/wcsstr.c
  84. 1 13
      libc/string/wcstok.c
  85. 9 0
      libc/string/wcsxfrm.c
  86. 10 0
      libc/string/wcsxfrm_l.c
  87. 1 8
      libc/string/wmemchr.c
  88. 1 8
      libc/string/wmemcmp.c
  89. 1 8
      libc/string/wmemcpy.c
  90. 1 8
      libc/string/wmemmove.c
  91. 1 8
      libc/string/wmempcpy.c
  92. 1 8
      libc/string/wmemset.c
  93. 0 3247
      libc/string/wstring.c

+ 37 - 80
libc/string/Makefile.in

@@ -9,112 +9,69 @@
 -include $(top_srcdir)libc/string/$(TARGET_ARCH)/Makefile.arch
 include $(top_srcdir)libc/string/generic/Makefile.in
 
-MSRC:=wstring.c
-MOBJ:=	basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o \
-	memrchr.o rawmemchr.o strcasecmp.o strcasestr.o \
-	strncasecmp.o strndup.o strsep.o \
-	strtok.o strerror.o __xpg_strerror_r.o \
-	_string_syserrmsgs.o __glibc_strerror_r.o \
-	_string_syssigmsgs.o sys_siglist.o strsignal.o psignal.o \
-	 __xpg_basename.o strlcat.o sys_errlist.o memmem.o
+STRING_DIR:=$(top_srcdir)libc/string
+STRING_OUT:=$(top_builddir)libc/string
 
-MOBJW:=
-ifeq ($(UCLIBC_HAS_WCHAR),y)
-MOBJW:=	wcscasecmp.o wcsncasecmp.o \
-	wcsxfrm.o strxfrm.o # wcscoll strcoll.o
+STRING_ALL_WXSRC:=$(wildcard $(STRING_DIR)/w*_l.c)
+ifeq ($(UCLIBC_HAS_LOCALE),y)
+STRING_WXSRC:=$(STRING_ALL_WXSRC)
+else
+# wcscoll_l
+STRING_WXSRC:=$(filter-out $(STRING_DIR)/wcsxfrm_l.c,$(STRING_ALL_WXSRC))
 endif
 
-MOBJx:=
-MOBJWx:=
-ifeq ($(UCLIBC_HAS_XLOCALE),y)
-MOBJx:=strcasecmp_l.o strncasecmp_l.o
-ifeq ($(UCLIBC_HAS_WCHAR),y)
-MOBJWx:=wcscasecmp_l.o wcsncasecmp_l.o wcsxfrm_l.o strxfrm_l.o
+STRING_ALL_XLSRC:=$(filter-out $(STRING_ALL_WXSRC),$(wildcard $(STRING_DIR)/*_l.c))
+ifeq ($(UCLIBC_HAS_LOCALE),y)
+STRING_XLSRC:=$(STRING_ALL_XLSRC)
+else
+# strcoll_l
+STRING_XLSRC:=$(filter-out $(STRING_DIR)/strxfrm_l.c,$(STRING_ALL_XLSRC))
 endif
-endif
-
-#ffsl ffsll
 
-ifeq ($(UCLIBC_HAS_STRING_ARCH_OPT),y)
-ifneq ($(strip $(STRING_ARCH_OBJS)),)
-MOBJ:=$(filter-out $(notdir $(STRING_ARCH_OBJS)),$(MOBJ))
+STRING_ALL_WSRC:=$(filter-out $(STRING_ALL_WXSRC),$(wildcard $(STRING_DIR)/w*.c))
+ifeq ($(UCLIBC_HAS_LOCALE),y)
+STRING_WSRC:=$(STRING_ALL_WSRC)
+else
+# wcscoll
+STRING_WSRC:=$(filter-out $(STRING_DIR)/wcsxfrm.c,$(STRING_ALL_WSRC))
 endif
+
+STRING_ALL_CSRC:=$(filter-out $(STRING_ALL_WXSRC) $(STRING_ALL_XLSRC) $(STRING_ALL_WSRC) $(STRING_DIR)/_collate.c,$(wildcard $(STRING_DIR)/*.c))
+ifeq ($(UCLIBC_HAS_LOCALE),y)
+STRING_CSRC:=$(STRING_ALL_CSRC)
+else
+# strcoll
+STRING_CSRC:=$(filter-out $(STRING_DIR)/strxfrm.c,$(STRING_ALL_CSRC))
 endif
 
-ifeq ($(UCLIBC_HAS_STRING_GENERIC_OPT),y)
-ifneq ($(strip $(STRING_GENERIC_OBJS)),)
-MOBJ:=$(filter-out $(notdir $(STRING_GENERIC_OBJS)),$(MOBJ))
+ifeq ($(UCLIBC_HAS_WCHAR),y)
+STRING_CSRC+=$(STRING_WSRC)
+endif
+ifeq ($(UCLIBC_HAS_XLOCALE),y)
+STRING_CSRC+=$(STRING_XLSRC)
+ifeq ($(UCLIBC_HAS_WCHAR),y)
+STRING_CSRC+=$(STRING_WXSRC)
 endif
 endif
-
-STRING_DIR:=$(top_srcdir)libc/string
-STRING_OUT:=$(top_builddir)libc/string
-
-STRING_WSRC:=$(filter-out $(STRING_DIR)/wstring.c,$(wildcard $(STRING_DIR)/w*.c))
-STRING_CSRC:=$(filter-out $(STRING_DIR)/wstring.c $(STRING_WSRC),$(wildcard $(STRING_DIR)/*.c))
 
 ifeq ($(UCLIBC_HAS_STRING_ARCH_OPT),y)
 ifneq ($(strip $(STRING_ARCH_OBJS)),)
-MOBJ:=$(filter-out $(notdir $(STRING_ARCH_OBJS)),$(MOBJ))
 STRING_CSRC:=$(filter-out $(patsubst %.o,$(STRING_DIR)/%.c,$(notdir $(STRING_ARCH_OBJS))),$(STRING_CSRC))
-STRING_WSRC:=$(filter-out $(patsubst %.o,$(STRING_DIR)/%.c,$(notdir $(STRING_ARCH_OBJS))),$(STRING_WSRC))
 endif
 endif
 
 ifeq ($(UCLIBC_HAS_STRING_GENERIC_OPT),y)
 ifneq ($(strip $(STRING_GENERIC_OBJS)),)
-MOBJ:=$(filter-out $(notdir $(STRING_GENERIC_OBJS)),$(MOBJ))
 STRING_CSRC:=$(filter-out $(patsubst %.o,$(STRING_DIR)/%.c,$(notdir $(STRING_GENERIC_OBJS))),$(STRING_CSRC))
-STRING_WSRC:=$(filter-out $(patsubst %.o,$(STRING_DIR)/%.c,$(notdir $(STRING_GENERIC_OBJS))),$(STRING_WSRC))
 endif
 endif
 
-
 STRING_COBJ:=$(patsubst $(STRING_DIR)/%.c,$(STRING_OUT)/%.o,$(STRING_CSRC))
-ifeq ($(UCLIBC_HAS_WCHAR),y)
-STRING_WOBJ:=$(patsubst $(STRING_DIR)/%.c,$(STRING_OUT)/%.o,$(STRING_WSRC))
-endif
-STRING_MSRC:=$(patsubst %.c,$(STRING_DIR)/%.c,$(MSRC))
-STRING_MOBJ:=$(patsubst %.o,$(STRING_OUT)/%.o,$(MOBJ))
-STRING_MOBJW:=$(patsubst %.o,$(STRING_OUT)/%.o,$(MOBJW))
-STRING_MOBJx:=$(patsubst %.o,$(STRING_OUT)/%.o,$(MOBJx))
-STRING_MOBJWx:=$(patsubst %.o,$(STRING_OUT)/%.o,$(MOBJWx))
-
-STRING_DEF:=$(patsubst %,-DL_%,$(subst .o,,$(notdir $(STRING_MOBJ))))
-
-STRING_Wx:=$(STRING_MOBJW) $(STRING_MOBJx) $(STRING_MOBJWx)
-STRING_OBJS:=$(STRING_COBJ) $(STRING_WOBJ) $(STRING_MOBJ) $(STRING_Wx)
-
-$(STRING_MOBJ): $(STRING_MSRC)
-	$(compile.m)
-
-$(STRING_MOBJ:.o=.os): $(STRING_MSRC)
-	$(compile.m)
-
-$(STRING_MOBJW): $(STRING_MSRC)
-	$(compile.m) -DWANT_WIDE
-
-$(STRING_MOBJW:.o=.os): $(STRING_MSRC)
-	$(compile.m) -DWANT_WIDE
-
-$(STRING_MOBJx): $(STRING_MSRC)
-	$(compile.m) -D__UCLIBC_DO_XLOCALE
-
-$(STRING_MOBJx:.o=.os): $(STRING_MSRC)
-	$(compile.m) -D__UCLIBC_DO_XLOCALE
-
-$(STRING_MOBJWx): $(STRING_MSRC)
-	$(compile.m) -DWANT_WIDE -D__UCLIBC_DO_XLOCALE
-
-$(STRING_MOBJWx:.o=.os): $(STRING_MSRC)
-	$(compile.m) -DWANT_WIDE -D__UCLIBC_DO_XLOCALE
 
-libc-a-y+=$(STRING_OBJS)
-libc-so-y+=$(STRING_OBJS:.o=.os)
+libc-a-y+=$(STRING_COBJ)
+libc-so-y+=$(STRING_COBJ:.o=.os)
 
-CFLAGS-multi-y+=$(STRING_DEF)
-libc-multi-y+=$(STRING_MSRC) $(STRING_CSRC) $(STRING_WSRC)
-libc-nomulti-y+=$(STRING_Wx)
+libc-multi-y+=$(STRING_CSRC)
 
 objclean-y+=string_objclean
 

+ 19 - 0
libc/string/__glibc_strerror_r.c

@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <string.h>
+
+char attribute_hidden *__glibc_strerror_r_internal(int errnum, char *strerrbuf, size_t buflen)
+{
+    __xpg_strerror_r_internal(errnum, strerrbuf, buflen);
+
+    return strerrbuf;
+}
+
+strong_alias(__glibc_strerror_r_internal,__glibc_strerror_r)
+/*hidden_weak_alias(__glibc_strerror_r_internal,__strerror_r)*/

+ 35 - 0
libc/string/__xpg_basename.c

@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+char *__xpg_basename(register char *path)
+{
+	static const char null_or_empty[] = ".";
+	char *first;
+	register char *last;
+
+	first = (char *) null_or_empty;
+
+	if (path && *path) {
+		first = path;
+		last = path - 1;
+
+		do {
+			if ((*path != '/') && (path > ++last)) {
+				last = first = path;
+			}
+		} while (*++path);
+
+		if (*first == '/') {
+			last = first;
+		}
+		last[1] = 0;
+	}
+
+	return first;
+}

+ 273 - 0
libc/string/__xpg_strerror_r.c

@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define _GNU_SOURCE
+#include <features.h>
+#include <errno.h>
+#include <bits/uClibc_uintmaxtostr.h>
+#include "_syserrmsg.h"
+
+#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
+
+extern const char _string_syserrmsgs[];
+
+#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
+
+static const unsigned char estridx[] = {
+	0,							/* success is always 0 */
+	EPERM,
+	ENOENT,
+	ESRCH,
+	EINTR,
+	EIO,
+	ENXIO,
+	E2BIG,
+	ENOEXEC,
+	EBADF,
+	ECHILD,
+	EAGAIN,
+	ENOMEM,
+	EACCES,
+	EFAULT,
+	ENOTBLK,
+	EBUSY,
+	EEXIST,
+	EXDEV,
+	ENODEV,
+	ENOTDIR,
+	EISDIR,
+	EINVAL,
+	ENFILE,
+	EMFILE,
+	ENOTTY,
+	ETXTBSY,
+	EFBIG,
+	ENOSPC,
+	ESPIPE,
+	EROFS,
+	EMLINK,
+	EPIPE,
+	EDOM,
+	ERANGE,
+	EDEADLK,
+	ENAMETOOLONG,
+	ENOLCK,
+	ENOSYS,
+	ENOTEMPTY,
+	ELOOP,
+	0,
+	ENOMSG,
+	EIDRM,
+	ECHRNG,
+	EL2NSYNC,
+	EL3HLT,
+	EL3RST,
+	ELNRNG,
+	EUNATCH,
+	ENOCSI,
+	EL2HLT,
+	EBADE,
+	EBADR,
+	EXFULL,
+	ENOANO,
+	EBADRQC,
+	EBADSLT,
+	0,
+	EBFONT,
+	ENOSTR,
+	ENODATA,
+	ETIME,
+	ENOSR,
+	ENONET,
+	ENOPKG,
+	EREMOTE,
+	ENOLINK,
+	EADV,
+	ESRMNT,
+	ECOMM,
+	EPROTO,
+	EMULTIHOP,
+	EDOTDOT,
+	EBADMSG,
+	EOVERFLOW,
+	ENOTUNIQ,
+	EBADFD,
+	EREMCHG,
+	ELIBACC,
+	ELIBBAD,
+	ELIBSCN,
+	ELIBMAX,
+	ELIBEXEC,
+	EILSEQ,
+	ERESTART,
+	ESTRPIPE,
+	EUSERS,
+	ENOTSOCK,
+	EDESTADDRREQ,
+	EMSGSIZE,
+	EPROTOTYPE,
+	ENOPROTOOPT,
+	EPROTONOSUPPORT,
+	ESOCKTNOSUPPORT,
+	EOPNOTSUPP,
+	EPFNOSUPPORT,
+	EAFNOSUPPORT,
+	EADDRINUSE,
+	EADDRNOTAVAIL,
+	ENETDOWN,
+	ENETUNREACH,
+	ENETRESET,
+	ECONNABORTED,
+	ECONNRESET,
+	ENOBUFS,
+	EISCONN,
+	ENOTCONN,
+	ESHUTDOWN,
+	ETOOMANYREFS,
+	ETIMEDOUT,
+	ECONNREFUSED,
+	EHOSTDOWN,
+	EHOSTUNREACH,
+	EALREADY,
+	EINPROGRESS,
+	ESTALE,
+	EUCLEAN,
+	ENOTNAM,
+	ENAVAIL,
+	EISNAM,
+	EREMOTEIO,
+#ifdef __mips__
+	0,							/* mips has an outrageous value for this... */
+#else
+	EDQUOT,
+#endif
+	ENOMEDIUM,
+	EMEDIUMTYPE,
+#if defined(__mips__) || defined(__sparc__)
+	EDEADLOCK,
+#endif
+};
+
+#endif
+
+/* __xpg_strerror_r is used in header */
+int attribute_hidden __xpg_strerror_r_internal(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', ' '
+    };
+
+    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++) {
+		if (estridx[i] == errnum) {
+			goto GOT_ESTRIDX;
+		}
+	}
+	i = INT_MAX;	/* Failed, but may need to check mips special case. */
+#ifdef __mips__
+	if (errnum == EDQUOT) {	/* Deal with large EDQUOT value on mips */
+		i = 122;
+	}
+#endif /* __mips__ */
+ GOT_ESTRIDX:
+#else
+	/* No errno to string index translation needed. */
+	i = errnum;
+#endif
+
+    if (((unsigned int) i) < _SYS_NERR) {
+		/* Trade time for space.  This function should rarely be called
+		 * so rather than keeping an array of pointers for the different
+		 * messages, just run through the buffer until we find the
+		 * correct string. */
+		for (s = (char *) _string_syserrmsgs ; i ; ++s) {
+			if (!*s) {
+				--i;
+			}
+		}
+		if (*s) {		/* Make sure we have an actual message. */
+			retval = 0;
+			goto GOT_MESG;
+		}
+    }
+
+#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
+    s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
+    __memcpy(s, unknown, sizeof(unknown));
+
+ GOT_MESG:
+    if (!strerrbuf) {		/* SUSv3  */
+		buflen = 0;
+    }
+    i = __strlen(s) + 1;
+    if (i > buflen) {
+		i = buflen;
+		retval = ERANGE;
+    }
+
+    if (i) {
+		__memcpy(strerrbuf, s, i);
+		strerrbuf[i-1] = 0;	/* In case buf was too small. */
+    }
+
+    if (retval) {
+		__set_errno(retval);
+    }
+
+    return retval;
+}
+
+#else  /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
+
+int attribute_hidden __xpg_strerror_r_internal(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__ */
+
+strong_alias(__xpg_strerror_r_internal,__xpg_strerror_r)

+ 686 - 0
libc/string/_collate.c

@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*  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.
+ *
+ */
+
+#include "_string.h"
+#include <ctype.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <assert.h>
+
+extern size_t __strlcpy(char *__restrict dst, const char *__restrict src,
+                      size_t n) attribute_hidden;
+
+#ifdef WANT_WIDE
+extern int __wcscmp (__const wchar_t *__s1, __const wchar_t *__s2) attribute_hidden;
+extern size_t __wcsxfrm (wchar_t *__restrict __s1,
+		       __const wchar_t *__restrict __s2, size_t __n) attribute_hidden;
+#endif
+#ifdef __UCLIBC_HAS_XLOCALE__
+extern int __strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l) attribute_hidden;
+extern size_t __strxfrm_l (char *__dest, __const char *__src, size_t __n, __locale_t __l) attribute_hidden;
+extern int __wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2, __locale_t __loc) attribute_hidden;
+extern size_t __wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2, size_t __n, __locale_t __loc) attribute_hidden;
+#endif
+
+#ifdef __UCLIBC_HAS_LOCALE__
+#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   __strcoll
+#define wcscoll_l strcoll_l
+#define __wcscoll_l __strcoll_l
+#define wcsxfrm   strxfrm
+#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 attribute_hidden __wcscoll (const Wchar *s0, const Wchar *s1)
+{
+	return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
+}
+strong_alias(__wcscoll,wcscoll)
+
+size_t attribute_hidden __wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
+{
+	return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
+}
+strong_alias(__wcsxfrm,wcsxfrm)
+
+#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 attribute_hidden __UCXL(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;
+}
+__UCXL_ALIAS(wcscoll)
+
+#ifdef WANT_WIDE
+
+size_t attribute_hidden __UCXL(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 __wcsxfrm(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;
+}
+
+__UCXL_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 attribute_hidden __UCXL(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;
+}
+
+__UCXL_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 /* __UCLIBC_HAS_LOCALE__ */
+/**********************************************************************/

+ 33 - 0
libc/string/_string.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef __STRING_H
+#define __STRING_H
+
+#define _GNU_SOURCE
+#include <features.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+
+#ifdef WANT_WIDE
+# include <wchar.h>
+# include <wctype.h>
+# include <bits/uClibc_uwchar.h>
+# define Wvoid			wchar_t
+# define Wchar			wchar_t
+# define Wuchar			__uwchar_t
+# define Wint			wchar_t
+#else
+# define Wvoid			void
+# define Wchar			char
+typedef unsigned char		__string_uchar_t;
+# define Wuchar			__string_uchar_t
+# define Wint			int
+#endif
+
+#endif /* __STRING_H */

+ 146 - 0
libc/string/_string_syserrmsgs.c

@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+
+#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
+
+const char _string_syserrmsgs[] = {
+	/*   0:    0,  8 */ "Success\0"
+	/*   1:    8, 24 */ "Operation not permitted\0"
+	/*   2:   32, 26 */ "No such file or directory\0"
+	/*   3:   58, 16 */ "No such process\0"
+	/*   4:   74, 24 */ "Interrupted system call\0"
+	/*   5:   98, 19 */ "Input/output error\0"
+	/*   6:  117, 26 */ "No such device or address\0"
+	/*   7:  143, 23 */ "Argument list too long\0"
+	/*   8:  166, 18 */ "Exec format error\0"
+	/*   9:  184, 20 */ "Bad file descriptor\0"
+	/*  10:  204, 19 */ "No child processes\0"
+	/*  11:  223, 33 */ "Resource temporarily unavailable\0"
+	/*  12:  256, 23 */ "Cannot allocate memory\0"
+	/*  13:  279, 18 */ "Permission denied\0"
+	/*  14:  297, 12 */ "Bad address\0"
+	/*  15:  309, 22 */ "Block device required\0"
+	/*  16:  331, 24 */ "Device or resource busy\0"
+	/*  17:  355, 12 */ "File exists\0"
+	/*  18:  367, 26 */ "Invalid cross-device link\0"
+	/*  19:  393, 15 */ "No such device\0"
+	/*  20:  408, 16 */ "Not a directory\0"
+	/*  21:  424, 15 */ "Is a directory\0"
+	/*  22:  439, 17 */ "Invalid argument\0"
+	/*  23:  456, 30 */ "Too many open files in system\0"
+	/*  24:  486, 20 */ "Too many open files\0"
+	/*  25:  506, 31 */ "Inappropriate ioctl for device\0"
+	/*  26:  537, 15 */ "Text file busy\0"
+	/*  27:  552, 15 */ "File too large\0"
+	/*  28:  567, 24 */ "No space left on device\0"
+	/*  29:  591, 13 */ "Illegal seek\0"
+	/*  30:  604, 22 */ "Read-only file system\0"
+	/*  31:  626, 15 */ "Too many links\0"
+	/*  32:  641, 12 */ "Broken pipe\0"
+	/*  33:  653, 33 */ "Numerical argument out of domain\0"
+	/*  34:  686, 30 */ "Numerical result out of range\0"
+	/*  35:  716, 26 */ "Resource deadlock avoided\0"
+	/*  36:  742, 19 */ "File name too long\0"
+	/*  37:  761, 19 */ "No locks available\0"
+	/*  38:  780, 25 */ "Function not implemented\0"
+	/*  39:  805, 20 */ "Directory not empty\0"
+	/*  40:  825, 34 */ "Too many levels of symbolic links\0"
+	/*  41:  859,  1 */ "\0"
+	/*  42:  860, 27 */ "No message of desired type\0"
+	/*  43:  887, 19 */ "Identifier removed\0"
+	/*  44:  906, 28 */ "Channel number out of range\0"
+	/*  45:  934, 25 */ "Level 2 not synchronized\0"
+	/*  46:  959, 15 */ "Level 3 halted\0"
+	/*  47:  974, 14 */ "Level 3 reset\0"
+	/*  48:  988, 25 */ "Link number out of range\0"
+	/*  49: 1013, 29 */ "Protocol driver not attached\0"
+	/*  50: 1042, 27 */ "No CSI structure available\0"
+	/*  51: 1069, 15 */ "Level 2 halted\0"
+	/*  52: 1084, 17 */ "Invalid exchange\0"
+	/*  53: 1101, 27 */ "Invalid request descriptor\0"
+	/*  54: 1128, 14 */ "Exchange full\0"
+	/*  55: 1142,  9 */ "No anode\0"
+	/*  56: 1151, 21 */ "Invalid request code\0"
+	/*  57: 1172, 13 */ "Invalid slot\0"
+	/*  58: 1185,  1 */ "\0"
+	/*  59: 1186, 21 */ "Bad font file format\0"
+	/*  60: 1207, 20 */ "Device not a stream\0"
+	/*  61: 1227, 18 */ "No data available\0"
+	/*  62: 1245, 14 */ "Timer expired\0"
+	/*  63: 1259, 25 */ "Out of streams resources\0"
+	/*  64: 1284, 30 */ "Machine is not on the network\0"
+	/*  65: 1314, 22 */ "Package not installed\0"
+	/*  66: 1336, 17 */ "Object is remote\0"
+	/*  67: 1353, 22 */ "Link has been severed\0"
+	/*  68: 1375, 16 */ "Advertise error\0"
+	/*  69: 1391, 14 */ "Srmount error\0"
+	/*  70: 1405, 28 */ "Communication error on send\0"
+	/*  71: 1433, 15 */ "Protocol error\0"
+	/*  72: 1448, 19 */ "Multihop attempted\0"
+	/*  73: 1467, 19 */ "RFS specific error\0"
+	/*  74: 1486, 12 */ "Bad message\0"
+	/*  75: 1498, 38 */ "Value too large for defined data type\0"
+	/*  76: 1536, 27 */ "Name not unique on network\0"
+	/*  77: 1563, 29 */ "File descriptor in bad state\0"
+	/*  78: 1592, 23 */ "Remote address changed\0"
+	/*  79: 1615, 39 */ "Can not access a needed shared library\0"
+	/*  80: 1654, 37 */ "Accessing a corrupted shared library\0"
+	/*  81: 1691, 32 */ ".lib section in a.out corrupted\0"
+	/*  82: 1723, 48 */ "Attempting to link in too many shared libraries\0"
+	/*  83: 1771, 38 */ "Cannot exec a shared library directly\0"
+	/*  84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0"
+	/*  85: 1859, 44 */ "Interrupted system call should be restarted\0"
+	/*  86: 1903, 19 */ "Streams pipe error\0"
+	/*  87: 1922, 15 */ "Too many users\0"
+	/*  88: 1937, 31 */ "Socket operation on non-socket\0"
+	/*  89: 1968, 29 */ "Destination address required\0"
+	/*  90: 1997, 17 */ "Message too long\0"
+	/*  91: 2014, 31 */ "Protocol wrong type for socket\0"
+	/*  92: 2045, 23 */ "Protocol not available\0"
+	/*  93: 2068, 23 */ "Protocol not supported\0"
+	/*  94: 2091, 26 */ "Socket type not supported\0"
+	/*  95: 2117, 24 */ "Operation not supported\0"
+	/*  96: 2141, 30 */ "Protocol family not supported\0"
+	/*  97: 2171, 41 */ "Address family not supported by protocol\0"
+	/*  98: 2212, 23 */ "Address already in use\0"
+	/*  99: 2235, 32 */ "Cannot assign requested address\0"
+	/* 100: 2267, 16 */ "Network is down\0"
+	/* 101: 2283, 23 */ "Network is unreachable\0"
+	/* 102: 2306, 36 */ "Network dropped connection on reset\0"
+	/* 103: 2342, 33 */ "Software caused connection abort\0"
+	/* 104: 2375, 25 */ "Connection reset by peer\0"
+	/* 105: 2400, 26 */ "No buffer space available\0"
+	/* 106: 2426, 40 */ "Transport endpoint is already connected\0"
+	/* 107: 2466, 36 */ "Transport endpoint is not connected\0"
+	/* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0"
+	/* 109: 2548, 35 */ "Too many references: cannot splice\0"
+	/* 110: 2583, 21 */ "Connection timed out\0"
+	/* 111: 2604, 19 */ "Connection refused\0"
+	/* 112: 2623, 13 */ "Host is down\0"
+	/* 113: 2636, 17 */ "No route to host\0"
+	/* 114: 2653, 30 */ "Operation already in progress\0"
+	/* 115: 2683, 26 */ "Operation now in progress\0"
+	/* 116: 2709, 22 */ "Stale NFS file handle\0"
+	/* 117: 2731, 25 */ "Structure needs cleaning\0"
+	/* 118: 2756, 28 */ "Not a XENIX named type file\0"
+	/* 119: 2784, 30 */ "No XENIX semaphores available\0"
+	/* 120: 2814, 21 */ "Is a named type file\0"
+	/* 121: 2835, 17 */ "Remote I/O error\0"
+	/* 122: 2852, 20 */ "Disk quota exceeded\0"
+	/* 123: 2872, 16 */ "No medium found\0"
+	/* 124: 2888, 18 */ "Wrong medium type"
+#if defined(__mips__) || defined(__sparc__)
+	"\0"
+	/* 125: 2906, 28 */ "File locking deadlock error"
+#endif
+	/* Note: for mips we are ignoring ECANCELED since glibc doesn't have a
+	 * corresponsding message.*/
+};
+
+#endif

+ 50 - 0
libc/string/_string_syssigmsgs.c

@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+
+#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
+
+const char _string_syssigmsgs[] = {
+	/*   0:    0,  1 */ "\0"
+	/*   1:    1,  7 */ "Hangup\0"
+	/*   2:    8, 10 */ "Interrupt\0"
+	/*   3:   18,  5 */ "Quit\0"
+	/*   4:   23, 20 */ "Illegal instruction\0"
+	/*   5:   43, 22 */ "Trace/breakpoint trap\0"
+	/*   6:   65,  8 */ "Aborted\0"
+	/*   7:   73, 10 */ "Bus error\0"
+	/*   8:   83, 25 */ "Floating point exception\0"
+	/*   9:  108,  7 */ "Killed\0"
+	/*  10:  115, 22 */ "User defined signal 1\0"
+	/*  11:  137, 19 */ "Segmentation fault\0"
+	/*  12:  156, 22 */ "User defined signal 2\0"
+	/*  13:  178, 12 */ "Broken pipe\0"
+	/*  14:  190, 12 */ "Alarm clock\0"
+	/*  15:  202, 11 */ "Terminated\0"
+	/*  16:  213, 12 */ "Stack fault\0"
+	/*  17:  225, 13 */ "Child exited\0"
+	/*  18:  238, 10 */ "Continued\0"
+	/*  19:  248, 17 */ "Stopped (signal)\0"
+	/*  20:  265,  8 */ "Stopped\0"
+	/*  21:  273, 20 */ "Stopped (tty input)\0"
+	/*  22:  293, 21 */ "Stopped (tty output)\0"
+	/*  23:  314, 21 */ "Urgent I/O condition\0"
+	/*  24:  335, 24 */ "CPU time limit exceeded\0"
+	/*  25:  359, 25 */ "File size limit exceeded\0"
+	/*  26:  384, 22 */ "Virtual timer expired\0"
+	/*  27:  406, 24 */ "Profiling timer expired\0"
+	/*  28:  430, 15 */ "Window changed\0"
+	/*  29:  445, 13 */ "I/O possible\0"
+	/*  30:  458, 14 */ "Power failure\0"
+	/*  31:  472, 16 */ "Bad system call"
+#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
+	/*  32:  488,  9 */ "\0EMT trap"
+#endif
+};
+
+#endif

+ 35 - 0
libc/string/_syserrmsg.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#ifndef __SYSERRMSG_H
+#define __SYSERRMSG_H 1
+
+/**********************************************************************/
+/* NOTE: If we ever do internationalized syserr messages, this will
+ * have to be changed! */
+
+#if defined(__mips__) || defined(__sparc__)
+/* sparce and mips have an extra error entry, as EDEADLK and EDEADLOCK have
+ * different meanings on those platforms. */
+# define _SYS_NERR			126
+#else
+# define _SYS_NERR			125
+#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__ */
+
+#if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14
+# define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14)
+#else
+# define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
+#endif
+
+#endif

+ 26 - 0
libc/string/basename.c

@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+char attribute_hidden *__basename(const char *path)
+{
+	register const char *s;
+	register const char *p;
+
+	p = s = path;
+
+	while (*s) {
+		if (*s++ == '/') {
+			p = s;
+		}
+	}
+
+	return (char *) p;
+}
+
+strong_alias(__basename,basename)

+ 53 - 0
libc/string/bcopy.c

@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+void attribute_hidden __bcopy(const void *s2, void *s1, size_t n)
+{
+#if 1
+	__memmove(s1, s2, n);
+#else
+#ifdef __BCC__
+	register char *s;
+	register const char *p;
+
+	s = s1;
+	p = s2;
+	if (p >= s) {
+		while (n--) {
+			*s++ = *p++;
+		}
+	} else {
+		s += n;
+		p += n;
+		while (n--) {
+			*--s = *--p;
+		}
+	}
+#else
+	register char *s;
+	register const char *p;
+
+	s = s1;
+	p = s2;
+	if (p >= s) {
+		while (n) {
+			*s++ = *p++;
+			--n;
+		}
+	} else {
+		while (n) {
+			--n;
+			s[n] = p[n];
+		}
+	}
+#endif
+#endif
+}
+
+strong_alias(__bcopy,bcopy)

+ 31 - 0
libc/string/bzero.c

@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+void attribute_hidden __bzero(void *s, size_t n)
+{
+#if 1
+	(void)__memset(s, 0, n);
+#else
+	register unsigned char *p = s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+
+	while (np) {
+		*p++ = 0;
+		--np;
+	}
+#endif
+}
+#undef np
+
+strong_alias(__bzero,bzero)

+ 43 - 0
libc/string/dirname.c

@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+char *dirname(char *path)
+{
+	static const char null_or_empty_or_noslash[] = ".";
+	register char *s;
+	register char *last;
+	char *first;
+
+	last = s = path;
+
+	if (s != NULL) {
+
+	LOOP:
+		while (*s && (*s != '/')) ++s;
+		first = s;
+		while (*s == '/') ++s;
+		if (*s) {
+			last = first;
+			goto LOOP;
+		}
+
+		if (last == path) {
+			if (*last != '/') {
+				goto DOT;
+			}
+			if ((*++last == '/') && (last[1] == 0)) {
+				++last;
+			}
+		}
+		*last = 0;
+		return path;
+	}
+ DOT:
+	return (char *) null_or_empty_or_noslash;
+}

+ 54 - 0
libc/string/ffs.c

@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* ffsl,ffsll */
+
+#include "_string.h"
+
+int attribute_hidden __ffs(int i)
+{
+#if 1
+	/* inlined binary search method */
+	char n = 1;
+#if UINT_MAX == 0xffffU
+	/* nothing to do here -- just trying to avoiding possible problems */
+#elif UINT_MAX == 0xffffffffU
+	if (!(i & 0xffff)) {
+		n += 16;
+		i >>= 16;
+	}
+#else
+#error ffs needs rewriting!
+#endif
+
+	if (!(i & 0xff)) {
+		n += 8;
+		i >>= 8;
+	}
+	if (!(i & 0x0f)) {
+		n += 4;
+		i >>= 4;
+	}
+	if (!(i & 0x03)) {
+		n += 2;
+		i >>= 2;
+	}
+	return (i) ? (n + ((i+1) & 0x01)) : 0;
+
+#else
+	/* linear search -- slow, but small */
+	int n;
+
+	for (n = 0 ; i ; ++n) {
+		i >>= 1;
+	}
+	
+	return n;
+#endif
+}
+
+strong_alias(__ffs,ffs)

+ 22 - 0
libc/string/memccpy.c

@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* No wide analog. */
+
+#include "_string.h"
+
+void attribute_hidden *__memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
+{
+	register char *r1 = s1;
+	register const char *r2 = s2;
+
+	while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
+
+	return (n == (size_t) -1) ? NULL : r1;
+}
+
+strong_alias(__memccpy,memccpy)

+ 31 - 5
libc/string/memchr.c

@@ -1,14 +1,40 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memchr
-#define Wmemchr __memchr
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmemchr __wmemchr
+# define Wmemchr wmemchr
+#else
+# define __Wmemchr __memchr
+# define Wmemchr memchr
+#endif
 
-strong_alias(__memchr, memchr)
+Wvoid attribute_hidden *__Wmemchr(const Wvoid *s, Wint c, size_t n)
+{
+	register const Wuchar *r = (const Wuchar *) s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+# define np n
+#endif
 
-#undef L_memchr
+	while (np) {
+		if (*r == ((Wuchar)c)) {
+			return (Wvoid *) r;	/* silence the warning */
+		}
+		++r;
+		--np;
+	}
+
+	return NULL;
+}
+#undef np
+
+strong_alias(__Wmemchr,Wmemchr)

+ 33 - 6
libc/string/memcmp.c

@@ -1,16 +1,43 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memcmp
-#define Wmemcmp __memcmp
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmemcmp __wmemcmp
+# define Wmemcmp wmemcmp
+#else
+# define __Wmemcmp __memcmp
+# define Wmemcmp memcmp
+#endif
 
-strong_alias(__memcmp, memcmp)
+int attribute_hidden __Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
+{
+	register const Wuchar *r1 = (const Wuchar *) s1;
+	register const Wuchar *r2 = (const Wuchar *) s2;
 
-weak_alias(memcmp, bcmp)
+#ifdef WANT_WIDE
+	while (n && (*r1 == *r2)) {
+		++r1;
+		++r2;
+		--n;
+	}
 
-#undef L_memcmp
+	return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
+#else
+	int r = 0;
+
+	while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0));
+
+	return r;
+#endif
+}
+
+strong_alias(__Wmemcmp,Wmemcmp)
+#ifndef WANT_WIDE
+strong_alias(__memcmp,bcmp)
+#endif

+ 28 - 5
libc/string/memcpy.c

@@ -1,14 +1,37 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memcpy
-#define Wmemcpy __memcpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmemcpy __wmemcpy
+# define Wmemcpy wmemcpy
+#else
+# define __Wmemcpy __memcpy
+# define Wmemcpy memcpy
+#endif
 
-strong_alias(__memcpy, memcpy)
+Wvoid attribute_hidden *__Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
+{
+	register Wchar *r1 = s1;
+	register const Wchar *r2 = s2;
 
-#undef L_memcpy
+#ifdef __BCC__
+	while (n--) {
+		*r1++ = *r2++;
+	}
+#else
+	while (n) {
+		*r1++ = *r2++;
+		--n;
+	}
+#endif
+
+	return s1;
+}
+
+strong_alias(__Wmemcpy,Wmemcpy)

+ 40 - 0
libc/string/memmem.c

@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+void attribute_hidden *__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;
+}
+
+strong_alias(__memmem,memmem)

+ 48 - 5
libc/string/memmove.c

@@ -1,14 +1,57 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memmove
-#define Wmemmove __memmove
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmemmove __wmemmove
+# define Wmemmove wmemmove
+#else
+# define __Wmemmove __memmove
+# define Wmemmove memmove
+#endif
 
-strong_alias(__memmove, memmove)
+Wvoid attribute_hidden *__Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
+{
+#ifdef __BCC__
+	register Wchar *s = (Wchar *) s1;
+	register const Wchar *p = (const Wchar *) s2;
 
-#undef L_memmove
+	if (p >= s) {
+		while (n--) {
+			*s++ = *p++;
+		}
+	} else {
+		s += n;
+		p += n;
+		while (n--) {
+			*--s = *--p;
+		}
+	}
+
+	return s1;
+#else
+	register Wchar *s = (Wchar *) s1;
+	register const Wchar *p = (const Wchar *) s2;
+
+	if (p >= s) {
+		while (n) {
+			*s++ = *p++;
+			--n;
+		}
+	} else {
+		while (n) {
+			--n;
+			s[n] = p[n];
+		}
+	}
+
+	return s1;
+#endif
+}
+
+strong_alias(__Wmemmove,Wmemmove)

+ 28 - 5
libc/string/mempcpy.c

@@ -1,14 +1,37 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_mempcpy
-#define Wmempcpy __mempcpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmempcpy __wmempcpy
+# define Wmempcpy wmempcpy
+#else
+# define __Wmempcpy __mempcpy
+# define Wmempcpy mempcpy
+#endif
 
-strong_alias(__mempcpy,mempcpy)
+Wvoid attribute_hidden *__Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
+{
+	register Wchar *r1 = s1;
+	register const Wchar *r2 = s2;
 
-#undef L_mempcpy
+#ifdef __BCC__
+	while (n--) {
+		*r1++ = *r2++;
+	}
+#else
+	while (n) {
+		*r1++ = *r2++;
+		--n;
+	}
+#endif
+
+	return r1;
+}
+
+strong_alias(__Wmempcpy,Wmempcpy)

+ 33 - 0
libc/string/memrchr.c

@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+void attribute_hidden *__memrchr(const void *s, int c, size_t n)
+{
+	register const unsigned char *r;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+#define np n
+#endif
+	
+	r = ((unsigned char *)s) + ((size_t) np);
+
+	while (np) {
+		if (*--r == ((unsigned char)c)) {
+			return (void *) r;	/* silence the warning */
+		}
+		--np;
+	}
+
+	return NULL;
+}
+#undef np
+
+strong_alias(__memrchr,memrchr)

+ 28 - 5
libc/string/memset.c

@@ -1,14 +1,37 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memset
-#define Wmemset __memset
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wmemset __wmemset
+# define Wmemset wmemset
+#else
+# define __Wmemset __memset
+# define Wmemset memset
+#endif
 
-strong_alias(__memset, memset)
+Wvoid attribute_hidden *__Wmemset(Wvoid *s, Wint c, size_t n)
+{
+	register Wuchar *p = (Wuchar *) s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *np = (const char *) n;
+#else
+# define np n
+#endif
 
-#undef L_memset
+	while (np) {
+		*p++ = (Wuchar) c;
+		--np;
+	}
+
+	return s;
+}
+#undef np
+
+strong_alias(__Wmemset,Wmemset)

+ 30 - 0
libc/string/psignal.c

@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <stdio.h>
+#include <string.h>
+
+extern char *__strsignal (int __sig) __THROW attribute_hidden;
+
+/* TODO: make this threadsafe with a reentrant version of strsignal? */
+
+void psignal(int signum, register const char *message)
+{
+	/* If the program is calling psignal, it's a safe bet that printf and
+	 * friends are used as well.  It is also possible that the calling
+	 * program could buffer stderr, or reassign it. */
+
+	register const char *sep;
+
+	sep = ": ";
+	if (!(message && *message)) { /* Caller did not supply a prefix message */
+		message = (sep += 2);	/* or passed an empty string. */
+	}
+
+	fprintf(stderr, "%s%s%s\n", message, sep, __strsignal(signum));
+}

+ 19 - 0
libc/string/rawmemchr.c

@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+void attribute_hidden *__rawmemchr(const void *s, int c)
+{
+	register const unsigned char *r = s;
+
+	while (*r != ((unsigned char)c)) ++r;
+
+	return (void *) r;	/* silence the warning */
+}
+
+strong_alias(__rawmemchr,rawmemchr)

+ 22 - 5
libc/string/stpcpy.c

@@ -1,14 +1,31 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_stpcpy
-#define Wstpcpy __stpcpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstpcpy __wcpcpy
+# define Wstpcpy wcpcpy
+#else
+# define __Wstpcpy __stpcpy
+# define Wstpcpy stpcpy
+#endif
 
-strong_alias(__stpcpy, stpcpy)
+Wchar attribute_hidden *__Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2)
+{
+#ifdef __BCC__
+	do {
+		*s1 = *s2++;
+	} while (*s1++ != 0);
+#else
+	while ( (*s1++ = *s2++) != 0 );
+#endif
 
-#undef L_stpcpy
+	return s1 - 1;
+}
+
+strong_alias(__Wstpcpy,Wstpcpy)

+ 32 - 5
libc/string/stpncpy.c

@@ -1,14 +1,41 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_stpncpy
-#define Wstpncpy __stpncpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstpncpy __wcpncpy
+# define Wstpncpy wcpncpy
+#else
+# define __Wstpncpy __stpncpy
+# define Wstpncpy stpncpy
+#endif
 
-strong_alias(__stpncpy, stpncpy)
+Wchar attribute_hidden *__Wstpncpy(register Wchar * __restrict s1,
+				register const Wchar * __restrict s2,
+				size_t n)
+{
+	Wchar *s = s1;
+	const Wchar *p = s2;
 
-#undef L_stpncpy
+#ifdef __BCC__
+	while (n--) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+	}
+	return s1 + (s2 - p);
+#else
+	while (n) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+		--n;
+	}
+	return s1 + (s2 - p);
+#endif
+}
+
+strong_alias(__Wstpncpy,Wstpncpy)

+ 75 - 0
libc/string/strcasecmp.c

@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+#include <ctype.h>
+#include <locale.h>
+
+#ifdef __UCLIBC_HAS_XLOCALE__
+extern int __strcasecmp_l (__const char *__s1, __const char *__s2,
+			 __locale_t __loc)
+     __THROW __attribute_pure__ __nonnull ((1, 2, 3)) attribute_hidden;
+extern int __wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+			 __locale_t __loc) __THROW attribute_hidden;
+#endif
+
+#ifdef WANT_WIDE
+# define strcasecmp wcscasecmp
+# 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)
+extern wint_t __towlower_l (wint_t __wc, __locale_t __locale) __THROW attribute_hidden;
+# else
+#  define TOLOWER(C) __towlower((C))
+# endif
+#else
+# ifdef __UCLIBC_DO_XLOCALE
+#  define TOLOWER(C) __tolower_l((C), locale_arg)
+# else
+#  define TOLOWER(C) __tolower((C))
+# endif
+#endif
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+int attribute_hidden __strcasecmp(register const Wchar *s1, register const Wchar *s2)
+{
+	return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
+}
+strong_alias(__strcasecmp,strcasecmp)
+
+#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+int attribute_hidden __UCXL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
+					  __LOCALE_PARAM )
+{
+#ifdef WANT_WIDE
+	while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+	}
+
+	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))))
+			&& (++s2, *s1++));
+
+	return r;
+#endif
+}
+__UCXL_ALIAS(strcasecmp)
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */

+ 8 - 0
libc/string/strcasecmp_l.c

@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define __UCLIBC_DO_XLOCALE
+#include "strcasecmp.c"

+ 51 - 0
libc/string/strcasestr.c

@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+#include <ctype.h>
+
+char attribute_hidden *__strcasestr(const char *s1, const char *s2)
+{
+	register const char *s = s1;
+	register const char *p = s2;
+
+#if 1
+	do {
+		if (!*p) {
+			return (char *) s1;;
+		}
+		if ((*p == *s)
+			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
+			) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			if (!*s) {
+				return NULL;
+			}
+			s = ++s1;
+		}
+	} while (1);
+#else
+	while (*p && *s) {
+		if ((*p == *s)
+			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
+			) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			s = ++s1;
+		}
+	}
+
+	return (*p) ? NULL : (char *) s1;
+#endif
+}
+
+strong_alias(__strcasestr,strcasestr)

+ 20 - 5
libc/string/strcat.c

@@ -1,14 +1,29 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcat
-#define Wstrcat __strcat
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrcat __wcscat
+# define Wstrcat wcscat
+#else
+# define __Wstrcat __strcat
+# define Wstrcat strcat
+#endif
 
-strong_alias(__strcat, strcat)
+Wchar attribute_hidden *__Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2)
+{
+	register Wchar *s = s1;
 
-#undef L_strcat
+	while (*s++);
+	--s;
+	while ((*s++ = *s2++) != 0);
+
+	return s1;
+}
+
+strong_alias(__Wstrcat,Wstrcat)

+ 23 - 6
libc/string/strchr.c

@@ -1,16 +1,33 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strchr
-#define Wstrchr __strchr
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrchr __wcschr
+# define Wstrchr wcschr
+#else
+# define __Wstrchr __strchr
+# define Wstrchr strchr
+#endif
 
-strong_alias(__strchr, strchr)
+Wchar attribute_hidden *__Wstrchr(register const Wchar *s, Wint c)
+{
+	do {
+		if (*s == ((Wchar)c)) {
+			return (Wchar *) s;	/* silence the warning */
+		}
+	} while (*s++);
 
-weak_alias(strchr, index)
+	return NULL;
+}
 
-#undef L_strchr
+strong_alias(__strchr,strchr)
+
+#ifndef WANT_WIDE
+strong_alias(__strchr,index)
+#endif

+ 16 - 5
libc/string/strchrnul.c

@@ -1,14 +1,25 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strchrnul
-#define Wstrchrnul __strchrnul
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrchrnul __wcschrnul
+# define Wstrchrnul wcschrnul
+#else
+# define __Wstrchrnul __strchrnul
+# define Wstrchrnul strchrnul
+#endif
 
-strong_alias(__strchrnul, strchrnul)
+Wchar attribute_hidden *__Wstrchrnul(register const Wchar *s, Wint c)
+{
+	--s;
+	while (*++s && (*s != ((Wchar)c)));
+	return (Wchar *) s;
+}
 
-#undef L_strchrnul
+strong_alias(__Wstrchrnul,Wstrchrnul)

+ 38 - 8
libc/string/strcmp.c

@@ -1,19 +1,49 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcmp
-#define Wstrcmp __strcmp
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrcmp __wcscmp
+# define Wstrcmp wcscmp
+#else
+# define __Wstrcmp __strcmp
+# define Wstrcmp strcmp
+#endif
+
+int attribute_hidden __Wstrcmp(register const Wchar *s1, register const Wchar *s2)
+{
+#ifdef WANT_WIDE
+	while (*((Wuchar *)s1) == *((Wuchar *)s2)) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+	}
 
-strong_alias(__strcmp, strcmp)
+	return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1;
+#else
+	int r;
 
-#ifdef __LOCALE_C_ONLY
-hidden_strong_alias(__strcmp, __strcoll)
-strong_alias(__strcmp, strcoll)
+	while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++))
+			== 0) && *s1++);
+	
+	return r;
 #endif
+}
 
-#undef L_strcmp
+strong_alias(__Wstrcmp,Wstrcmp)
+
+#ifndef __UCLIBC_HAS_LOCALE__
+# ifdef WANT_WIDE
+hidden_strong_alias(__wcscmp,__wcscoll)
+strong_alias(__wcscmp,wcscoll)
+# else
+hidden_strong_alias(__strcmp,__strcoll)
+strong_alias(__strcmp,strcoll)
+# endif
+#endif

+ 24 - 5
libc/string/strcpy.c

@@ -1,14 +1,33 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcpy
-#define Wstrcpy __strcpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrcpy __wcscpy
+# define Wstrcpy wcscpy
+#else
+# define __Wstrcpy __strcpy
+# define Wstrcpy strcpy
+#endif
 
-strong_alias(__strcpy, strcpy)
+Wchar attribute_hidden *__Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2)
+{
+	register Wchar *s = s1;
 
-#undef L_strcpy
+#ifdef __BCC__
+	do {
+		*s = *s2++;
+	} while (*s++ != 0);
+#else
+	while ( (*s++ = *s2++) != 0 );
+#endif
+
+	return s1;
+}
+
+strong_alias(__Wstrcpy,Wstrcpy)

+ 23 - 5
libc/string/strcspn.c

@@ -1,14 +1,32 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcspn
-#define Wstrcspn __strcspn
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrcspn __wcscspn
+# define Wstrcspn wcscspn
+#else
+# define __Wstrcspn __strcspn
+# define Wstrcspn strcspn
+#endif
 
-strong_alias(__strcspn, strcspn)
+size_t attribute_hidden __Wstrcspn(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s;
+	register const Wchar *p;
 
-#undef L_strcspn
+	for ( s=s1 ; *s ; s++ ) {
+		for ( p=s2 ; *p ; p++ ) {
+			if (*p == *s) goto done;
+		}
+	}
+ done:
+	return s - s1;
+}
+
+strong_alias(__Wstrcspn,Wstrcspn)

+ 24 - 9
libc/string/strdup.c

@@ -1,19 +1,34 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strdup
-#define Wstrdup __strdup
+#include "_string.h"
+#include <stdlib.h>
 
-#undef Wstrlen
-#undef Wstrcpy
-#define Wstrlen __strlen
-#define Wstrcpy __strcpy
+#ifdef WANT_WIDE
+# define __Wstrdup __wcsdup
+# define Wstrdup wcsdup
+# define Wstrlen __wcslen
+# define Wstrcpy __wcscpy
+#else
+# define __Wstrdup __strdup
+# define Wstrdup strdup
+# define Wstrlen __strlen
+# define Wstrcpy __strcpy
+#endif
 
-#include "wstring.c"
+Wchar attribute_hidden *__Wstrdup(register const Wchar *s1)
+{
+	register Wchar *s;
 
-strong_alias(__strdup, strdup)
+    if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
+		Wstrcpy(s, s1);
+	}
 
-#undef L_strdup
+	return s;
+}
+
+strong_alias(__Wstrdup,Wstrdup)

+ 21 - 0
libc/string/strerror.c

@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <string.h>
+#include "_syserrmsg.h"
+
+char attribute_hidden *__strerror(int errnum)
+{
+    static char buf[_STRERROR_BUFSIZE];
+
+	__xpg_strerror_r_internal(errnum, buf, sizeof(buf));
+
+	return buf;
+}
+
+strong_alias(__strerror,strerror)

+ 46 - 0
libc/string/strlcat.c

@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* OpenBSD function:
+ * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
+ * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
+ * return val is >= n.
+ * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
+ *       taken as n. */
+
+#include "_string.h"
+
+size_t strlcat(register char *__restrict dst,
+			   register const char *__restrict src,
+			   size_t n)
+{
+	size_t len;
+	char dummy[1];
+
+	len = 0;
+
+	while (1) {
+		if (len >= n) {
+			dst = dummy;
+			break;
+		}
+		if (!*dst) {
+			break;
+		}
+		++dst;
+		++len;
+	}
+
+	while ((*dst = *src) != 0) {
+		if (++len < n) {
+			++dst;
+		}
+		++src;
+	}
+
+	return len;
+}

+ 46 - 9
libc/string/strlcpy.c

@@ -1,19 +1,56 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strlcpy
-#define Wstrlcpy __strlcpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrlcpy __wcslcpy
+# define Wstrlcpy wcslcpy
+#else
+# define __Wstrlcpy __strlcpy
+# define Wstrlcpy strlcpy
+#endif
 
-strong_alias(__strlcpy, strlcpy)
+/* 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. */
 
-#ifdef __LOCALE_C_ONLY
-hidden_strong_alias(__strlcpy, __strxfrm)
-strong_alias(__strlcpy, strxfrm)
-#endif
+size_t attribute_hidden __Wstrlcpy(register Wchar *__restrict dst,
+				  register const Wchar *__restrict src,
+				  size_t n)
+{
+	const Wchar *src0 = src;
+	Wchar dummy[1];
+
+	if (!n) {
+		dst = dummy;
+	} else {
+		--n;
+	}
+
+	while ((*dst = *src) != 0) {
+		if (n) {
+			--n;
+			++dst;
+		}
+		++src;
+	}
 
-#undef L_strlcpy
+	return src - src0;
+}
+
+strong_alias(__Wstrlcpy,Wstrlcpy)
+
+#ifndef __UCLIBC_HAS_LOCALE__
+# ifdef WANT_WIDE
+hidden_strong_alias(__wcslcpy,__wcsxfrm)
+strong_alias(__wcslcpy,wcsxfrm)
+# else
+hidden_strong_alias(__strlcpy,__strxfrm)
+strong_alias(__strlcpy,strxfrm)
+# endif
+#endif

+ 18 - 5
libc/string/strlen.c

@@ -1,14 +1,27 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strlen
-#define Wstrlen __strlen
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrlen __wcslen
+# define Wstrlen wcslen
+#else
+# define __Wstrlen __strlen
+# define Wstrlen strlen
+#endif
 
-strong_alias(__strlen, strlen)
+size_t attribute_hidden __Wstrlen(const Wchar *s)
+{
+	register const Wchar *p;
 
-#undef L_strlen
+	for (p=s ; *p ; p++);
+
+	return p - s;
+}
+
+strong_alias(__Wstrlen,Wstrlen)

+ 78 - 0
libc/string/strncasecmp.c

@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+#include <ctype.h>
+#include <locale.h>
+
+#ifdef __UCLIBC_HAS_XLOCALE__
+extern int __strncasecmp_l (__const char *__s1, __const char *__s2,
+			  size_t __n, __locale_t __loc)
+     __THROW __attribute_pure__ __nonnull ((1, 2, 4)) attribute_hidden;
+extern int __wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+			  size_t __n, __locale_t __loc) __THROW attribute_hidden;
+#endif
+
+#ifdef WANT_WIDE
+# define strncasecmp wcsncasecmp
+# 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)
+extern wint_t __towlower_l (wint_t __wc, __locale_t __locale) __THROW attribute_hidden;
+# else
+#  define TOLOWER(C) __towlower((C))
+# endif
+#else
+# ifdef __UCLIBC_DO_XLOCALE
+#  define TOLOWER(C) __tolower_l((C), locale_arg)
+# else
+#  define TOLOWER(C) __tolower((C))
+# endif
+#endif
+
+#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
+
+int attribute_hidden __strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+{
+	return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
+}
+strong_alias(__strncasecmp,strncasecmp)
+
+#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
+
+int attribute_hidden __UCXL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
+					  size_t n   __LOCALE_PARAM )
+{
+#ifdef WANT_WIDE
+	while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+		--n;
+	}
+
+	return (n == 0)
+		? 0
+		: ((((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))))
+			&& (--n, ++s2, *s1++));
+	return r;
+#endif
+}
+__UCXL_ALIAS(strncasecmp)
+
+#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */

+ 8 - 0
libc/string/strncasecmp_l.c

@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define __UCLIBC_DO_XLOCALE
+#include "strncasecmp.c"

+ 29 - 5
libc/string/strncat.c

@@ -1,14 +1,38 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncat
-#define Wstrncat __strncat
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrncat __wcsncat
+# define Wstrncat wcsncat
+#else
+# define __Wstrncat __strncat
+# define Wstrncat strncat
+#endif
 
-strong_alias(__strncat, strncat)
+Wchar attribute_hidden *__Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
+				size_t n)
+{
+	register Wchar *s = s1;
 
-#undef L_strncat
+	while (*s++);
+	--s;
+#if __BCC__
+	while (n-- && ((*s = *s2++) != 0)) ++s;
+#else
+	while (n && ((*s = *s2++) != 0)) {
+		--n;
+		++s;
+	}
+#endif
+	*s = 0;
+
+	return s1;
+}
+
+strong_alias(__Wstrncat,Wstrncat)

+ 33 - 5
libc/string/strncmp.c

@@ -1,14 +1,42 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncmp
-#define Wstrncmp __strncmp
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrncmp __wcsncmp
+# define Wstrncmp wcsncmp
+#else
+# define __Wstrncmp __strncmp
+# define Wstrncmp strncmp
+#endif
 
-strong_alias(__strncmp, strncmp)
+int attribute_hidden __Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n)
+{
+#ifdef WANT_WIDE
+	while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) {
+		if (!*s1++) {
+			return 0;
+		}
+		++s2;
+		--n;
+	}
 
-#undef L_strncmp
+	return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1);
+#else
+	int r = 0;
+
+	while (n--
+		   && ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++))
+			== 0)
+		   && *s1++);
+
+	return r;
+#endif
+}
+
+strong_alias(__Wstrncmp,Wstrncmp)

+ 30 - 5
libc/string/strncpy.c

@@ -1,14 +1,39 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncpy
-#define Wstrncpy __strncpy
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrncpy __wcsncpy
+# define Wstrncpy wcsncpy
+#else
+# define __Wstrncpy __strncpy
+# define Wstrncpy strncpy
+#endif
 
-strong_alias(__strncpy, strncpy)
+Wchar attribute_hidden *__Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2,
+				size_t n)
+{
+	register Wchar *s = s1;
 
-#undef L_strncpy
+#ifdef __BCC__
+	while (n--) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+	}
+#else
+	while (n) {
+		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
+		++s;
+		--n;
+	}
+#endif
+	
+	return s1;
+}
+
+strong_alias(__Wstrncpy,Wstrncpy)

+ 25 - 0
libc/string/strndup.c

@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+#include <stdlib.h>
+
+char attribute_hidden *__strndup(register const char *s1, size_t n)
+{
+	register char *s;
+
+	n = __strnlen(s1,n);			/* Avoid problems if s1 not nul-terminated. */
+
+    if ((s = malloc(n + 1)) != NULL) {
+		__memcpy(s, s1, n);
+		s[n] = 0;
+	}
+
+	return s;
+}
+
+strong_alias(__strndup,strndup)

+ 28 - 5
libc/string/strnlen.c

@@ -1,14 +1,37 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strnlen
-#define Wstrnlen __strnlen
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrnlen __wcsnlen
+# define Wstrnlen wcsnlen
+#else
+# define __Wstrnlen __strnlen
+# define Wstrnlen strnlen
+#endif
 
-strong_alias(__strnlen, strnlen)
+size_t attribute_hidden __Wstrnlen(const Wchar *s, size_t max)
+{
+	register const Wchar *p = s;
+#ifdef __BCC__
+	/* bcc can optimize the counter if it thinks it is a pointer... */
+	register const char *maxp = (const char *) max;
+#else
+# define maxp max
+#endif
 
-#undef L_strnlen
+	while (maxp && *p) {
+		++p;
+		--maxp;
+	}
+
+	return p - s;
+}
+#undef maxp
+
+strong_alias(__Wstrnlen,Wstrnlen)

+ 22 - 5
libc/string/strpbrk.c

@@ -1,14 +1,31 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strpbrk
-#define Wstrpbrk __strpbrk
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrpbrk __wcspbrk
+# define Wstrpbrk wcspbrk
+#else
+# define __Wstrpbrk __strpbrk
+# define Wstrpbrk strpbrk
+#endif
 
-strong_alias(__strpbrk, strpbrk)
+Wchar attribute_hidden *__Wstrpbrk(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s;
+	register const Wchar *p;
 
-#undef L_strpbrk
+	for ( s=s1 ; *s ; s++ ) {
+		for ( p=s2 ; *p ; p++ ) {
+			if (*p == *s) return (Wchar *) s; /* silence the warning */
+		}
+	}
+	return NULL;
+}
+
+strong_alias(__Wstrpbrk,Wstrpbrk)

+ 25 - 6
libc/string/strrchr.c

@@ -1,16 +1,35 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strrchr
-#define Wstrrchr __strrchr
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrrchr __wcsrchr
+# define Wstrrchr wcsrchr
+#else
+# define __Wstrrchr __strrchr
+# define Wstrrchr strrchr
+#endif
 
-strong_alias(__strrchr, strrchr)
+Wchar attribute_hidden *__Wstrrchr(register const  Wchar *s, Wint c)
+{
+	register const Wchar *p;
 
-weak_alias(strrchr, rindex)
+	p = NULL;
+	do {
+		if (*s == (Wchar) c) {
+			p = s;
+		}
+	} while (*s++);
 
-#undef L_strrchr
+	return (Wchar *) p;			/* silence the warning */
+}
+
+strong_alias(__Wstrrchr,Wstrrchr)
+#ifndef WANT_WIDE
+strong_alias(__strrchr,rindex)
+#endif

+ 31 - 0
libc/string/strsep.c

@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+char attribute_hidden *__strsep(char ** __restrict s1, const char * __restrict s2)
+{
+	register char *s = *s1;
+	register char *p;
+
+#if 1
+	p = NULL;
+	if (s && *s && (p = __strpbrk(s, s2))) {
+		*p++ = 0;
+	}
+#else
+	if (s && *s && *(p = s + __strcspn(s, s2))) {
+		*p++ = 0;
+	} else {
+		p = NULL;
+	}
+#endif
+	*s1 = p;
+	return s;
+}
+
+strong_alias(__strsep,strsep)

+ 144 - 0
libc/string/strsignal.c

@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/*
+ *  Sep 11, 2003
+ *  Patch by Atsushi Nemoto <anemo@mba.ocn.ne.jp> to do arch-required
+ *  mapping of signal strings (alpha, mips, hppa, sparc).
+ */
+
+/* TODO: make a threadsafe version? */
+
+#define _GNU_SOURCE
+#include <features.h>
+#include <string.h>
+#include <bits/uClibc_uintmaxtostr.h>
+
+#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__ */
+
+#if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15
+# define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15)
+#else
+# define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN
+#endif
+
+#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
+
+extern const char _string_syssigmsgs[];
+
+#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
+static const unsigned char sstridx[] = {
+	0,
+	SIGHUP,
+	SIGINT,
+	SIGQUIT,
+	SIGILL,
+	SIGTRAP,
+	SIGIOT,
+	SIGBUS,
+	SIGFPE,
+	SIGKILL,
+	SIGUSR1,
+	SIGSEGV,
+	SIGUSR2,
+	SIGPIPE,
+	SIGALRM,
+	SIGTERM,
+#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
+	0,
+#else
+	SIGSTKFLT,
+#endif
+	SIGCHLD,
+	SIGCONT,
+	SIGSTOP,
+	SIGTSTP,
+	SIGTTIN,
+	SIGTTOU,
+	SIGURG,
+	SIGXCPU,
+	SIGXFSZ,
+	SIGVTALRM,
+	SIGPROF,
+	SIGWINCH,
+	SIGIO,
+	SIGPWR,
+	SIGSYS,
+#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
+	SIGEMT,
+#endif
+};
+#endif
+
+char attribute_hidden *__strsignal(int signum)
+{
+    register char *s;
+    int i;
+    static char buf[_STRSIGNAL_BUFSIZE];
+    static const char unknown[] = {
+		'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
+    };
+
+#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
+	/* Need to translate signum to string index. */
+	for (i = 0 ; i < sizeof(sstridx)/sizeof(sstridx[0]) ; i++) {
+		if (sstridx[i] == signum) {
+			goto GOT_SSTRIDX;
+		}
+	}
+	i = INT_MAX;	/* Failed. */
+ GOT_SSTRIDX:
+#else
+	/* No signum to string index translation needed. */
+	i = signum;
+#endif
+
+    if (((unsigned int) signum) < _SYS_NSIG) {
+		/* Trade time for space.  This function should rarely be called
+		 * so rather than keeping an array of pointers for the different
+		 * messages, just run through the buffer until we find the
+		 * correct string. */
+		for (s = (char *) _string_syssigmsgs ; i ; ++s) {
+			if (!*s) {
+				--i;
+			}
+		}
+		if (*s) {		/* Make sure we have an actual message. */
+			goto DONE;
+		}
+    }
+
+    s = _int10tostr(buf+sizeof(buf)-1, signum) - sizeof(unknown);
+    __memcpy(s, unknown, sizeof(unknown));
+
+ DONE:
+	return s;
+}
+
+#else  /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
+
+char attribute_hidden *__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__ */
+
+strong_alias(__strsignal,strsignal)

+ 23 - 5
libc/string/strspn.c

@@ -1,14 +1,32 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strspn
-#define Wstrspn __strspn
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrspn __wcsspn
+# define Wstrspn wcsspn
+#else
+# define __Wstrspn __strspn
+# define Wstrspn strspn
+#endif
 
-strong_alias(__strspn, strspn)
+size_t attribute_hidden __Wstrspn(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s = s1;
+	register const Wchar *p = s2;
 
-#undef L_strspn
+	while (*p) {
+		if (*p++ == *s) {
+			++s;
+			p = s2;
+		}
+	}
+	return s - s1;
+}
+
+strong_alias(__Wstrspn,Wstrspn)

+ 36 - 5
libc/string/strstr.c

@@ -1,14 +1,45 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strstr
-#define Wstrstr __strstr
+#include "_string.h"
 
-#include "wstring.c"
+#ifdef WANT_WIDE
+# define __Wstrstr __wcsstr
+# define Wstrstr wcsstr
+#else
+# define __Wstrstr __strstr
+# define Wstrstr strstr
+#endif
 
-strong_alias(__strstr, strstr)
+/* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
 
-#undef L_strstr
+Wchar attribute_hidden *__Wstrstr(const Wchar *s1, const Wchar *s2)
+{
+	register const Wchar *s = s1;
+	register const Wchar *p = s2;
+
+	do {
+		if (!*p) {
+			return (Wchar *) s1;;
+		}
+		if (*p == *s) {
+			++p;
+			++s;
+		} else {
+			p = s2;
+			if (!*s) {
+				return NULL;
+			}
+			s = ++s1;
+		}
+	} while (1);
+}
+
+strong_alias(__Wstrstr,Wstrstr)
+#ifdef WANT_WIDE
+strong_alias(__wcsstr,wcswcs)
+#endif

+ 22 - 0
libc/string/strtok.c

@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "_string.h"
+
+#if 0 /*def WANT_WIDE*/
+# define Wstrtok wcstok
+# define Wstrtok_r __wcstok_r
+#else
+# define Wstrtok strtok
+# define Wstrtok_r __strtok_r
+#endif
+
+Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
+{
+	static Wchar *next_start;	/* Initialized to 0 since in bss. */
+	return Wstrtok_r(s1, s2, &next_start);
+}

+ 45 - 9
libc/string/strtok_r.c

@@ -1,19 +1,55 @@
 /*
+ * Copyright (C) 2002     Manuel Novoa III
  * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
  *
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strtok_r
-#define Wstrtok_r __strtok_r
+#include "_string.h"
 
-#undef Wstrspn
-#define Wstrspn __strspn
-#undef Wstrpbrk
-#define Wstrpbrk __strpbrk
+#ifdef WANT_WIDE
+# define __Wstrtok_r __wcstok
+# define Wstrtok_r wcstok
+# define Wstrspn __wcsspn
+# define Wstrpbrk __wcspbrk
+#else
+# define __Wstrtok_r __strtok_r
+# define Wstrtok_r strtok_r
+# define Wstrspn __strspn
+# define Wstrpbrk __strpbrk
+#endif
 
-#include "wstring.c"
+Wchar attribute_hidden *__Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
+				 Wchar ** __restrict next_start)
+{
+	register Wchar *s;
+	register Wchar *p;
 
-strong_alias(__strtok_r, strtok_r)
+#if 1
+	if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
+		if (*(s += Wstrspn(s, s2))) {
+			if ((p = Wstrpbrk(s, s2)) != NULL) {
+				*p++ = 0;
+			}
+		} else {
+			p = s = NULL;
+		}
+		*next_start = p;
+	}
+	return s;
+#else
+	if (!(s = s1)) {
+		s = *next_start;
+	}
+	if (s && *(s += Wstrspn(s, s2))) {
+		if (*(p = s + Wstrcspn(s, s2))) {
+			*p++ = 0;
+		}
+		*next_start = p;
+		return s;
+	}
+	return NULL;				/* TODO: set *next_start = NULL for safety? */
+#endif
+}
 
-#undef L_strtok_r
+strong_alias(__Wstrtok_r,Wstrtok_r)

+ 9 - 0
libc/string/strxfrm.c

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define L_strxfrm
+#include "_collate.c"

+ 10 - 0
libc/string/strxfrm_l.c

@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define __UCLIBC_DO_XLOCALE
+#define L_strxfrm_l
+#include "_collate.c"

+ 171 - 0
libc/string/sys_errlist.c

@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <errno.h>
+
+extern const char _string_syserrmsgs[];
+
+#ifdef __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

+ 57 - 0
libc/string/sys_siglist.c

@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2002     Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#define __need_NULL
+#include <stddef.h>
+#include <signal.h>
+
+extern const char _string_syssigmsgs[];
+
+#ifdef __UCLIBC_HAS_SYS_SIGLIST__
+
+const char *const sys_siglist[_NSIG] = {
+	[0] =				NULL,
+	[SIGHUP] =			_string_syssigmsgs + 1,
+	[SIGINT] =			_string_syssigmsgs + 8,
+	[SIGQUIT] =			_string_syssigmsgs + 18,
+	[SIGILL] =			_string_syssigmsgs + 23,
+	[SIGTRAP] =			_string_syssigmsgs + 43,
+	[SIGABRT] =			_string_syssigmsgs + 65,
+	[SIGBUS] =			_string_syssigmsgs + 73,
+	[SIGFPE] =			_string_syssigmsgs + 83,
+	[SIGKILL] =			_string_syssigmsgs + 108,
+	[SIGUSR1] =			_string_syssigmsgs + 115,
+	[SIGSEGV] =			_string_syssigmsgs + 137,
+	[SIGUSR2] =			_string_syssigmsgs + 156,
+	[SIGPIPE] =			_string_syssigmsgs + 178,
+	[SIGALRM] =			_string_syssigmsgs + 190,
+	[SIGTERM] =			_string_syssigmsgs + 202,
+#if !(defined(__alpha__) || defined(__mips__) || defined(__sparc__))
+	[SIGSTKFLT] =			_string_syssigmsgs + 213,
+#endif
+	[SIGCHLD] =			_string_syssigmsgs + 225,
+	[SIGCONT] =			_string_syssigmsgs + 238,
+	[SIGSTOP] =			_string_syssigmsgs + 248,
+	[SIGTSTP] =			_string_syssigmsgs + 265,
+	[SIGTTIN] =			_string_syssigmsgs + 273,
+	[SIGTTOU] =			_string_syssigmsgs + 293,
+	[SIGURG] =			_string_syssigmsgs + 314,
+	[SIGXCPU] =			_string_syssigmsgs + 335,
+	[SIGXFSZ] =			_string_syssigmsgs + 359,
+	[SIGVTALRM] =			_string_syssigmsgs + 384,
+	[SIGPROF] =			_string_syssigmsgs + 406,
+	[SIGWINCH] =			_string_syssigmsgs + 430,
+	[SIGIO] =			_string_syssigmsgs + 445,
+	[SIGPWR] =			_string_syssigmsgs + 458,
+	[SIGSYS] =			_string_syssigmsgs + 472,
+#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
+	[SIGEMT] =			_string_syssigmsgs + 488,
+#endif
+};
+
+#endif

+ 1 - 8
libc/string/wcpcpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_stpcpy
 #define WANT_WIDE
-#define Wstpcpy __wcpcpy
-
-#include "wstring.c"
-
-strong_alias(__wcpcpy, wcpcpy)
-
-#undef L_stpcpy
+#include "stpcpy.c"

+ 1 - 8
libc/string/wcpncpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_stpncpy
 #define WANT_WIDE
-#define Wstpncpy __wcpncpy
-
-#include "wstring.c"
-
-strong_alias(__wcpncpy, wcpncpy)
-
-#undef L_stpncpy
+#include "stpncpy.c"

+ 8 - 0
libc/string/wcscasecmp.c

@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#include "strcasecmp.c"

+ 9 - 0
libc/string/wcscasecmp_l.c

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define __UCLIBC_DO_XLOCALE
+#include "strcasecmp.c"

+ 1 - 8
libc/string/wcscat.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcat
 #define WANT_WIDE
-#define Wstrcat __wcscat
-
-#include "wstring.c"
-
-strong_alias(__wcscat, wcscat)
-
-#undef L_strcat
+#include "strcat.c"

+ 1 - 8
libc/string/wcschr.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strchr
 #define WANT_WIDE
-#define Wstrchr __wcschr
-
-#include "wstring.c"
-
-strong_alias(__wcschr, wcschr)
-
-#undef L_strchr
+#include "strchr.c"

+ 1 - 8
libc/string/wcschrnul.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strchrnul
 #define WANT_WIDE
-#define Wstrchrnul __wcschrnul
-
-#include "wstring.c"
-
-strong_alias(__wcschrnul, wcschrnul)
-
-#undef L_strchrnul
+#include "strchrnul.c"

+ 1 - 13
libc/string/wcscmp.c

@@ -4,17 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcmp
 #define WANT_WIDE
-#define Wstrcmp __wcscmp
-
-#include "wstring.c"
-
-strong_alias(__wcscmp, wcscmp)
-
-#ifdef __LOCALE_C_ONLY
-hidden_strong_alias(__wcscmp, __wcscoll)
-strong_alias(__wcscmp, wcscoll)
-#endif
-
-#undef L_strcmp
+#include "strcmp.c"

+ 1 - 8
libc/string/wcscpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcpy
 #define WANT_WIDE
-#define Wstrcpy __wcscpy
-
-#include "wstring.c"
-
-strong_alias(__wcscpy, wcscpy)
-
-#undef L_strcpy
+#include "strcpy.c"

+ 1 - 8
libc/string/wcscspn.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strcspn
 #define WANT_WIDE
-#define Wstrcspn __wcscspn
-
-#include "wstring.c"
-
-strong_alias(__wcscspn, wcscspn)
-
-#undef L_strcspn
+#include "strcspn.c"

+ 1 - 13
libc/string/wcsdup.c

@@ -4,17 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strdup
 #define WANT_WIDE
-#define Wstrdup __wcsdup
-
-#undef Wstrlen
-#undef Wstrcpy
-#define Wstrlen __wcslen
-#define Wstrcpy __wcscpy
-
-#include "wstring.c"
-
-strong_alias(__wcsdup, wcsdup)
-
-#undef L_strdup
+#include "strdup.c"

+ 1 - 10
libc/string/wcslcpy.c

@@ -4,14 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strlcpy
 #define WANT_WIDE
-#define Wstrlcpy __wcslcpy
-
-#include "wstring.c"
-
-#ifdef __LOCALE_C_ONLY
-weak_alias(__wcslcpy, wcsxfrm)
-#endif
-
-#undef L_strlcpy
+#include "strlcpy.c"

+ 1 - 8
libc/string/wcslen.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strlen
 #define WANT_WIDE
-#define Wstrlen __wcslen
-
-#include "wstring.c"
-
-strong_alias(__wcslen, wcslen)
-
-#undef L_strlen
+#include "strlen.c"

+ 8 - 0
libc/string/wcsncasecmp.c

@@ -0,0 +1,8 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#include "strncasecmp.c"

+ 9 - 0
libc/string/wcsncasecmp_l.c

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define __UCLIBC_DO_XLOCALE
+#include "strncasecmp.c"

+ 1 - 8
libc/string/wcsncat.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncat
 #define WANT_WIDE
-#define Wstrncat __wcsncat
-
-#include "wstring.c"
-
-strong_alias(__wcsncat, wcsncat)
-
-#undef L_strncat
+#include "strncat.c"

+ 1 - 8
libc/string/wcsncmp.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncmp
 #define WANT_WIDE
-#define Wstrncmp __wcsncmp
-
-#include "wstring.c"
-
-strong_alias(__wcsncmp, wcsncmp)
-
-#undef L_strncmp
+#include "strncmp.c"

+ 1 - 8
libc/string/wcsncpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strncpy
 #define WANT_WIDE
-#define Wstrncpy __wcsncpy
-
-#include "wstring.c"
-
-strong_alias(__wcsncpy, wcsncpy)
-
-#undef L_strncpy
+#include "strncpy.c"

+ 1 - 8
libc/string/wcsnlen.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strnlen
 #define WANT_WIDE
-#define Wstrnlen __wcsnlen
-
-#include "wstring.c"
-
-strong_alias(__wcsnlen, wcsnlen)
-
-#undef L_strnlen
+#include "strnlen.c"

+ 1 - 8
libc/string/wcspbrk.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strpbrk
 #define WANT_WIDE
-#define Wstrpbrk __wcspbrk
-
-#include "wstring.c"
-
-strong_alias(__wcspbrk, wcspbrk)
-
-#undef L_strpbrk
+#include "strpbrk.c"

+ 1 - 8
libc/string/wcsrchr.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strrchr
 #define WANT_WIDE
-#define Wstrrchr __wcsrchr
-
-#include "wstring.c"
-
-strong_alias(__wcsrchr, wcsrchr)
-
-#undef L_strrchr
+#include "strrchr.c"

+ 1 - 8
libc/string/wcsspn.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strspn
 #define WANT_WIDE
-#define Wstrspn __wcsspn
-
-#include "wstring.c"
-
-strong_alias(__wcsspn, wcsspn)
-
-#undef L_strspn
+#include "strspn.c"

+ 1 - 10
libc/string/wcsstr.c

@@ -4,14 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strstr
 #define WANT_WIDE
-#define Wstrstr __wcsstr
-
-#include "wstring.c"
-
-strong_alias(__wcsstr, wcsstr)
-
-weak_alias(wcsstr, wcswcs)
-
-#undef L_strstr
+#include "strstr.c"

+ 1 - 13
libc/string/wcstok.c

@@ -4,17 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_strtok_r
 #define WANT_WIDE
-#define Wstrtok_r __wcstok
-
-#undef Wstrspn
-#define Wstrspn __wcsspn
-#undef Wstrpbrk
-#define Wstrpbrk __wcspbrk
-
-#include "wstring.c"
-
-strong_alias(__wcstok, wcstok)
-
-#undef L_strtok_r
+#include "strtok_r.c"

+ 9 - 0
libc/string/wcsxfrm.c

@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define L_wcsxfrm
+#include "_collate.c"

+ 10 - 0
libc/string/wcsxfrm_l.c

@@ -0,0 +1,10 @@
+/*
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define WANT_WIDE
+#define __UCLIBC_DO_XLOCALE
+#define L_wcsxfrm_l
+#include "_collate.c"

+ 1 - 8
libc/string/wmemchr.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memchr
 #define WANT_WIDE
-#define Wmemchr __wmemchr
-
-#include "wstring.c"
-
-strong_alias(__wmemchr, wmemchr)
-
-#undef L_memchr
+#include "memchr.c"

+ 1 - 8
libc/string/wmemcmp.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memcmp
 #define WANT_WIDE
-#define Wmemcmp __wmemcmp
-
-#include "wstring.c"
-
-strong_alias(__wmemcmp, wmemcmp)
-
-#undef L_memcmp
+#include "memcmp.c"

+ 1 - 8
libc/string/wmemcpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memcpy
 #define WANT_WIDE
-#define Wmemcpy __wmemcpy
-
-#include "wstring.c"
-
-strong_alias(__wmemcpy, wmemcpy)
-
-#undef L_memcpy
+#include "memcpy.c"

+ 1 - 8
libc/string/wmemmove.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memmove
 #define WANT_WIDE
-#define Wmemmove __wmemmove
-
-#include "wstring.c"
-
-strong_alias(__wmemmove, wmemmove)
-
-#undef L_memmove
+#include "memmove.c"

+ 1 - 8
libc/string/wmempcpy.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_mempcpy
 #define WANT_WIDE
-#define Wmempcpy __wmempcpy
-
-#include "wstring.c"
-
-strong_alias(__wmempcpy, wmempcpy)
-
-#undef L_mempcpy
+#include "mempcpy.c"

+ 1 - 8
libc/string/wmemset.c

@@ -4,12 +4,5 @@
  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  */
 
-#define L_memset
 #define WANT_WIDE
-#define Wmemset __wmemset
-
-#include "wstring.c"
-
-strong_alias(__wmemset, wmemset)
-
-#undef L_memset
+#include "memset.c"

+ 0 - 3247
libc/string/wstring.c

@@ -1,3247 +0,0 @@
-/*
- * Copyright (C) 2002     Manuel Novoa III
- * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
-
-/*  ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!   ATTENTION!
- *
- *  Besides uClibc, I'm using this code in my libc for elks, which is
- *  a 16-bit environment with a fairly limited compiler.  It would make
- *  things much easier for me if this file isn't modified unnecessarily.
- *  In particular, please put any new or replacement functions somewhere
- *  else, and modify the makefile to use your version instead.
- *  Thanks.  Manuel
- *
- *  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.
- *
- *  Sep 11, 2003
- *  Patch by Atsushi Nemoto <anemo@mba.ocn.ne.jp> to do arch-required
- *  mapping of signal strings (alpha, mips, hppa, sparc).
- */
-
-#define _GNU_SOURCE
-#include <features.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include <limits.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <assert.h>
-#include <locale.h>
-#include <bits/uClibc_uintmaxtostr.h>
-
-#ifdef WANT_WIDE
-#include <wchar.h>
-#include <wctype.h>
-#include <bits/uClibc_uwchar.h>
-
-#define Wvoid			wchar_t
-#define Wchar			wchar_t
-#define Wuchar			__uwchar_t
-#define Wint			wchar_t
-
-#else
-
-#define Wvoid			void
-#define Wchar			char
-typedef unsigned char	__string_uchar_t;
-#define Wuchar			__string_uchar_t
-#define Wint			int
-
-#endif
-
-
-extern size_t __strnlen (__const char *__string, size_t __maxlen) attribute_hidden;
-extern char *__strpbrk (__const char *__s, __const char *__accept) attribute_hidden;
-extern size_t __strspn (__const char *__s, __const char *__accept) attribute_hidden;
-extern char *__strsignal (int __sig) attribute_hidden;
-extern char *__strtok_r (char *__restrict __s,
-			 __const char *__restrict __delim,
-			 char **__restrict __save_ptr) attribute_hidden;
-extern size_t __strlcpy(char *__restrict dst, const char *__restrict src,
-                      size_t n) attribute_hidden;
-
-#ifdef WANT_WIDE
-extern wchar_t *__wcsdup (__const wchar_t *__s) attribute_hidden;
-extern size_t __wcslen (__const wchar_t *__s) attribute_hidden;
-extern wchar_t *__wcscpy (wchar_t *__restrict __dest,
-			__const wchar_t *__restrict __src) attribute_hidden;
-extern size_t __wcsspn (__const wchar_t *__wcs, __const wchar_t *__accept) attribute_hidden;
-extern wchar_t *__wcspbrk (__const wchar_t *__wcs, __const wchar_t *__accept) attribute_hidden;
-extern int __wcscmp (__const wchar_t *__s1, __const wchar_t *__s2) attribute_hidden;
-extern size_t __wcsxfrm (wchar_t *__restrict __s1,
-		       __const wchar_t *__restrict __s2, size_t __n) attribute_hidden;
-extern wint_t __towlower (wint_t __wc) __THROW attribute_hidden;
-#endif
-#ifdef __UCLIBC_HAS_XLOCALE__
-extern int __strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l) attribute_hidden;
-extern size_t __strxfrm_l (char *__dest, __const char *__src, size_t __n, __locale_t __l) attribute_hidden;
-extern int __strcasecmp_l (__const char *__s1, __const char *__s2, __locale_t __loc) attribute_hidden;
-extern int __strncasecmp_l (__const char *__s1, __const char *__s2, size_t __n, __locale_t __loc) attribute_hidden;
-extern int __wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2, __locale_t __loc) attribute_hidden;
-extern int __wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2, size_t __n, __locale_t __loc) attribute_hidden;
-extern int __wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2, __locale_t __loc) attribute_hidden;
-extern size_t __wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2, size_t __n, __locale_t __loc) attribute_hidden;
-#ifdef __UCLIBC_DO_XLOCALE
-extern wint_t __towlower_l(wint_t __wc, __locale_t __locale) __THROW;
-#endif
-#endif
-
-/**********************************************************************/
-/* NOTE: If we ever do internationalized syserr messages, this will
- * have to be changed! */
-
-#define _SYS_NERR			125
-#if defined(__mips__) || defined(__sparc__)
-/* sparce and mips have an extra error entry, as EDEADLK and EDEADLOCK have
- * different meanings on those platforms. */
-#undef _SYS_NERR
-#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[];
-
-
-#if _SYS_ERRMSG_MAXLEN < __UIM_BUFLEN_INT + 14
-#define _STRERROR_BUFSIZE (__UIM_BUFLEN_INT + 14)
-#else
-#define _STRERROR_BUFSIZE _SYS_ERRMSG_MAXLEN
-#endif
-
-#if _SYS_SIGMSG_MAXLEN < __UIM_BUFLEN_INT + 15
-#define _STRSIGNAL_BUFSIZE (__UIM_BUFLEN_INT + 15)
-#else
-#define _STRSIGNAL_BUFSIZE _SYS_SIGMSG_MAXLEN
-#endif
-
-/**********************************************************************/
-#if defined(L__string_syserrmsgs) && defined(__UCLIBC_HAS_ERRNO_MESSAGES__)
-
-const char _string_syserrmsgs[] = {
-	/*   0:    0,  8 */ "Success\0"
-	/*   1:    8, 24 */ "Operation not permitted\0"
-	/*   2:   32, 26 */ "No such file or directory\0"
-	/*   3:   58, 16 */ "No such process\0"
-	/*   4:   74, 24 */ "Interrupted system call\0"
-	/*   5:   98, 19 */ "Input/output error\0"
-	/*   6:  117, 26 */ "No such device or address\0"
-	/*   7:  143, 23 */ "Argument list too long\0"
-	/*   8:  166, 18 */ "Exec format error\0"
-	/*   9:  184, 20 */ "Bad file descriptor\0"
-	/*  10:  204, 19 */ "No child processes\0"
-	/*  11:  223, 33 */ "Resource temporarily unavailable\0"
-	/*  12:  256, 23 */ "Cannot allocate memory\0"
-	/*  13:  279, 18 */ "Permission denied\0"
-	/*  14:  297, 12 */ "Bad address\0"
-	/*  15:  309, 22 */ "Block device required\0"
-	/*  16:  331, 24 */ "Device or resource busy\0"
-	/*  17:  355, 12 */ "File exists\0"
-	/*  18:  367, 26 */ "Invalid cross-device link\0"
-	/*  19:  393, 15 */ "No such device\0"
-	/*  20:  408, 16 */ "Not a directory\0"
-	/*  21:  424, 15 */ "Is a directory\0"
-	/*  22:  439, 17 */ "Invalid argument\0"
-	/*  23:  456, 30 */ "Too many open files in system\0"
-	/*  24:  486, 20 */ "Too many open files\0"
-	/*  25:  506, 31 */ "Inappropriate ioctl for device\0"
-	/*  26:  537, 15 */ "Text file busy\0"
-	/*  27:  552, 15 */ "File too large\0"
-	/*  28:  567, 24 */ "No space left on device\0"
-	/*  29:  591, 13 */ "Illegal seek\0"
-	/*  30:  604, 22 */ "Read-only file system\0"
-	/*  31:  626, 15 */ "Too many links\0"
-	/*  32:  641, 12 */ "Broken pipe\0"
-	/*  33:  653, 33 */ "Numerical argument out of domain\0"
-	/*  34:  686, 30 */ "Numerical result out of range\0"
-	/*  35:  716, 26 */ "Resource deadlock avoided\0"
-	/*  36:  742, 19 */ "File name too long\0"
-	/*  37:  761, 19 */ "No locks available\0"
-	/*  38:  780, 25 */ "Function not implemented\0"
-	/*  39:  805, 20 */ "Directory not empty\0"
-	/*  40:  825, 34 */ "Too many levels of symbolic links\0"
-	/*  41:  859,  1 */ "\0"
-	/*  42:  860, 27 */ "No message of desired type\0"
-	/*  43:  887, 19 */ "Identifier removed\0"
-	/*  44:  906, 28 */ "Channel number out of range\0"
-	/*  45:  934, 25 */ "Level 2 not synchronized\0"
-	/*  46:  959, 15 */ "Level 3 halted\0"
-	/*  47:  974, 14 */ "Level 3 reset\0"
-	/*  48:  988, 25 */ "Link number out of range\0"
-	/*  49: 1013, 29 */ "Protocol driver not attached\0"
-	/*  50: 1042, 27 */ "No CSI structure available\0"
-	/*  51: 1069, 15 */ "Level 2 halted\0"
-	/*  52: 1084, 17 */ "Invalid exchange\0"
-	/*  53: 1101, 27 */ "Invalid request descriptor\0"
-	/*  54: 1128, 14 */ "Exchange full\0"
-	/*  55: 1142,  9 */ "No anode\0"
-	/*  56: 1151, 21 */ "Invalid request code\0"
-	/*  57: 1172, 13 */ "Invalid slot\0"
-	/*  58: 1185,  1 */ "\0"
-	/*  59: 1186, 21 */ "Bad font file format\0"
-	/*  60: 1207, 20 */ "Device not a stream\0"
-	/*  61: 1227, 18 */ "No data available\0"
-	/*  62: 1245, 14 */ "Timer expired\0"
-	/*  63: 1259, 25 */ "Out of streams resources\0"
-	/*  64: 1284, 30 */ "Machine is not on the network\0"
-	/*  65: 1314, 22 */ "Package not installed\0"
-	/*  66: 1336, 17 */ "Object is remote\0"
-	/*  67: 1353, 22 */ "Link has been severed\0"
-	/*  68: 1375, 16 */ "Advertise error\0"
-	/*  69: 1391, 14 */ "Srmount error\0"
-	/*  70: 1405, 28 */ "Communication error on send\0"
-	/*  71: 1433, 15 */ "Protocol error\0"
-	/*  72: 1448, 19 */ "Multihop attempted\0"
-	/*  73: 1467, 19 */ "RFS specific error\0"
-	/*  74: 1486, 12 */ "Bad message\0"
-	/*  75: 1498, 38 */ "Value too large for defined data type\0"
-	/*  76: 1536, 27 */ "Name not unique on network\0"
-	/*  77: 1563, 29 */ "File descriptor in bad state\0"
-	/*  78: 1592, 23 */ "Remote address changed\0"
-	/*  79: 1615, 39 */ "Can not access a needed shared library\0"
-	/*  80: 1654, 37 */ "Accessing a corrupted shared library\0"
-	/*  81: 1691, 32 */ ".lib section in a.out corrupted\0"
-	/*  82: 1723, 48 */ "Attempting to link in too many shared libraries\0"
-	/*  83: 1771, 38 */ "Cannot exec a shared library directly\0"
-	/*  84: 1809, 50 */ "Invalid or incomplete multibyte or wide character\0"
-	/*  85: 1859, 44 */ "Interrupted system call should be restarted\0"
-	/*  86: 1903, 19 */ "Streams pipe error\0"
-	/*  87: 1922, 15 */ "Too many users\0"
-	/*  88: 1937, 31 */ "Socket operation on non-socket\0"
-	/*  89: 1968, 29 */ "Destination address required\0"
-	/*  90: 1997, 17 */ "Message too long\0"
-	/*  91: 2014, 31 */ "Protocol wrong type for socket\0"
-	/*  92: 2045, 23 */ "Protocol not available\0"
-	/*  93: 2068, 23 */ "Protocol not supported\0"
-	/*  94: 2091, 26 */ "Socket type not supported\0"
-	/*  95: 2117, 24 */ "Operation not supported\0"
-	/*  96: 2141, 30 */ "Protocol family not supported\0"
-	/*  97: 2171, 41 */ "Address family not supported by protocol\0"
-	/*  98: 2212, 23 */ "Address already in use\0"
-	/*  99: 2235, 32 */ "Cannot assign requested address\0"
-	/* 100: 2267, 16 */ "Network is down\0"
-	/* 101: 2283, 23 */ "Network is unreachable\0"
-	/* 102: 2306, 36 */ "Network dropped connection on reset\0"
-	/* 103: 2342, 33 */ "Software caused connection abort\0"
-	/* 104: 2375, 25 */ "Connection reset by peer\0"
-	/* 105: 2400, 26 */ "No buffer space available\0"
-	/* 106: 2426, 40 */ "Transport endpoint is already connected\0"
-	/* 107: 2466, 36 */ "Transport endpoint is not connected\0"
-	/* 108: 2502, 46 */ "Cannot send after transport endpoint shutdown\0"
-	/* 109: 2548, 35 */ "Too many references: cannot splice\0"
-	/* 110: 2583, 21 */ "Connection timed out\0"
-	/* 111: 2604, 19 */ "Connection refused\0"
-	/* 112: 2623, 13 */ "Host is down\0"
-	/* 113: 2636, 17 */ "No route to host\0"
-	/* 114: 2653, 30 */ "Operation already in progress\0"
-	/* 115: 2683, 26 */ "Operation now in progress\0"
-	/* 116: 2709, 22 */ "Stale NFS file handle\0"
-	/* 117: 2731, 25 */ "Structure needs cleaning\0"
-	/* 118: 2756, 28 */ "Not a XENIX named type file\0"
-	/* 119: 2784, 30 */ "No XENIX semaphores available\0"
-	/* 120: 2814, 21 */ "Is a named type file\0"
-	/* 121: 2835, 17 */ "Remote I/O error\0"
-	/* 122: 2852, 20 */ "Disk quota exceeded\0"
-	/* 123: 2872, 16 */ "No medium found\0"
-	/* 124: 2888, 18 */ "Wrong medium type"
-#if defined(__mips__) || defined(__sparc__)
-	"\0"
-	/* 125: 2906, 28 */ "File locking deadlock error"
-#endif
-	/* Note: for mips we are ignoring ECANCELED since glibc doesn't have a
-	 * corresponsding message.*/
-};
-
-#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
-/**********************************************************************/
-#if 0
-#ifdef L_wmemcpy
-#define L_memcpy
-#define Wmemcpy wmemcpy
-#else
-#define Wmemcpy memcpy
-#endif
-#endif
-
-#ifdef L_memcpy
-
-#ifndef WANT_WIDE
-#undef memcpy
-#else
-#undef wmemcpy
-#endif
-Wvoid attribute_hidden *Wmemcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
-{
-	register Wchar *r1 = s1;
-	register const Wchar *r2 = s2;
-
-#ifdef __BCC__
-	while (n--) {
-		*r1++ = *r2++;
-	}
-#else
-	while (n) {
-		*r1++ = *r2++;
-		--n;
-	}
-#endif
-
-	return s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wmemmove
-#define L_memmove
-#define Wmemmove wmemmove
-#else
-#define Wmemmove memmove
-#endif
-#endif
-
-#ifdef L_memmove
-
-#ifndef WANT_WIDE
-#undef memmove
-#else
-#undef wmemmove
-#endif
-Wvoid attribute_hidden *Wmemmove(Wvoid *s1, const Wvoid *s2, size_t n)
-{
-#ifdef __BCC__
-	register Wchar *s = (Wchar *) s1;
-	register const Wchar *p = (const Wchar *) s2;
-
-	if (p >= s) {
-		while (n--) {
-			*s++ = *p++;
-		}
-	} else {
-		s += n;
-		p += n;
-		while (n--) {
-			*--s = *--p;
-		}
-	}
-
-	return s1;
-#else
-	register Wchar *s = (Wchar *) s1;
-	register const Wchar *p = (const Wchar *) s2;
-
-	if (p >= s) {
-		while (n) {
-			*s++ = *p++;
-			--n;
-		}
-	} else {
-		while (n) {
-			--n;
-			s[n] = p[n];
-		}
-	}
-
-	return s1;
-#endif
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcscpy
-#define L_strcpy
-#define Wstrcpy wcscpy
-#else
-#define Wstrcpy strcpy
-#endif
-#endif
-
-#ifdef L_strcpy
-
-#ifndef WANT_WIDE
-#undef strcpy
-#else
-#undef wcscpy
-#endif
-Wchar attribute_hidden *Wstrcpy(Wchar * __restrict s1, const Wchar * __restrict s2)
-{
-	register Wchar *s = s1;
-
-#ifdef __BCC__
-	do {
-		*s = *s2++;
-	} while (*s++ != 0);
-#else
-	while ( (*s++ = *s2++) != 0 );
-#endif
-
-	return s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsncpy
-#define L_strncpy
-#define Wstrncpy wcsncpy
-#else
-#define Wstrncpy strncpy
-#endif
-#endif
-
-#ifdef L_strncpy
-
-#ifndef WANT_WIDE
-#undef strncpy
-#else
-#undef wcsncpy
-#endif
-Wchar attribute_hidden *Wstrncpy(Wchar * __restrict s1, register const Wchar * __restrict s2,
-				size_t n)
-{
-	register Wchar *s = s1;
-
-#ifdef __BCC__
-	while (n--) {
-		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
-		++s;
-	}
-#else
-	while (n) {
-		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
-		++s;
-		--n;
-	}
-#endif
-	
-	return s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcscat
-#define L_strcat
-#define Wstrcat wcscat
-#else
-#define Wstrcat strcat
-#endif
-#endif
-
-#ifdef L_strcat
-
-#ifndef WANT_WIDE
-#undef strcat
-#else
-#undef wcscat
-#endif
-Wchar attribute_hidden *Wstrcat(Wchar * __restrict s1, register const Wchar * __restrict s2)
-{
-	register Wchar *s = s1;
-
-	while (*s++);
-	--s;
-	while ((*s++ = *s2++) != 0);
-
-	return s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsncat
-#define L_strncat
-#define Wstrncat wcsncat
-#else
-#define Wstrncat strncat
-#endif
-#endif
-
-#ifdef L_strncat
-
-#ifndef WANT_WIDE
-#undef strncat
-#else
-#undef wcsncat
-#endif
-Wchar attribute_hidden *Wstrncat(Wchar * __restrict s1, register const Wchar * __restrict s2,
-				size_t n)
-{
-	register Wchar *s = s1;
-
-	while (*s++);
-	--s;
-#if __BCC__
-	while (n-- && ((*s = *s2++) != 0)) ++s;
-#else
-	while (n && ((*s = *s2++) != 0)) {
-		--n;
-		++s;
-	}
-#endif
-	*s = 0;
-
-	return s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wmemcmp
-#define L_memcmp
-#define Wmemcmp wmemcmp
-#else
-#define Wmemcmp memcmp
-#endif
-#endif
-
-#ifdef L_memcmp
-
-#ifndef WANT_WIDE
-#undef memcmp
-#else
-#undef wmemcmp
-#endif
-int attribute_hidden Wmemcmp(const Wvoid *s1, const Wvoid *s2, size_t n)
-{
-	register const Wuchar *r1 = (const Wuchar *) s1;
-	register const Wuchar *r2 = (const Wuchar *) s2;
-
-#ifdef WANT_WIDE
-	while (n && (*r1 == *r2)) {
-		++r1;
-		++r2;
-		--n;
-	}
-
-	return (n == 0) ? 0 : ((*r1 < *r2) ? -1 : 1);
-#else
-	int r = 0;
-
-	while (n-- && ((r = ((int)(*r1++)) - *r2++) == 0));
-
-	return r;
-#endif
-}
-
-#if 0 /* ndef L_wmemcmp */
-weak_alias(memcmp, bcmp)
-#endif
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcscmp
-#define L_strcmp
-#define Wstrcmp wcscmp
-#else
-#define Wstrcmp strcmp
-#endif
-#endif
-
-#ifdef L_strcmp
-
-#ifndef WANT_WIDE
-#undef strcmp
-#else
-#undef wcscmp
-#endif
-int attribute_hidden Wstrcmp(register const Wchar *s1, register const Wchar *s2)
-{
-#ifdef WANT_WIDE
-	while (*((Wuchar *)s1) == *((Wuchar *)s2)) {
-		if (!*s1++) {
-			return 0;
-		}
-		++s2;
-	}
-
-	return (*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1;
-#else
-	int r;
-
-	while (((r = ((int)(*((Wuchar *)s1))) - *((Wuchar *)s2++))
-			== 0) && *s1++);
-	
-	return r;
-#endif
-}
-
-#if 0 /* def __LOCALE_C_ONLY */
-#ifdef L_wcscmp
-weak_alias(wcscmp, wcscoll)
-#else  /* L_wcscmp */
-weak_alias(strcmp, strcoll)
-#endif /* L_wcscmp */
-#endif /* __LOCALE_C_ONLY */
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsncmp
-#define L_strncmp
-#define Wstrncmp wcsncmp
-#else
-#define Wstrncmp strncmp
-#endif
-#endif
-
-#ifdef L_strncmp
-
-#ifndef WANT_WIDE
-#undef strncmp
-#else
-#undef wcsncmp
-#endif
-int attribute_hidden Wstrncmp(register const Wchar *s1, register const Wchar *s2, size_t n)
-{
-#ifdef WANT_WIDE
-	while (n && (*((Wuchar *)s1) == *((Wuchar *)s2))) {
-		if (!*s1++) {
-			return 0;
-		}
-		++s2;
-		--n;
-	}
-
-	return (n == 0) ? 0 : ((*((Wuchar *)s1) < *((Wuchar *)s2)) ? -1 : 1);
-#else
-	int r = 0;
-
-	while (n--
-		   && ((r = ((int)(*((unsigned char *)s1))) - *((unsigned char *)s2++))
-			== 0)
-		   && *s1++);
-
-	return r;
-#endif
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wmemchr
-#define L_memchr
-#define Wmemchr wmemchr
-#else
-#define Wmemchr memchr
-#endif
-#endif
-
-#ifdef L_memchr
-
-#ifndef WANT_WIDE
-#undef memchr
-#else
-#undef wmemchr
-#endif
-Wvoid attribute_hidden *Wmemchr(const Wvoid *s, Wint c, size_t n)
-{
-	register const Wuchar *r = (const Wuchar *) s;
-#ifdef __BCC__
-	/* bcc can optimize the counter if it thinks it is a pointer... */
-	register const char *np = (const char *) n;
-#else
-#define np n
-#endif
-
-	while (np) {
-		if (*r == ((Wuchar)c)) {
-			return (Wvoid *) r;	/* silence the warning */
-		}
-		++r;
-		--np;
-	}
-
-	return NULL;
-}
-#undef np
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcschr
-#define L_strchr
-#define Wstrchr wcschr
-#else
-#define Wstrchr strchr
-#endif
-#endif
-
-#ifdef L_strchr
-
-#ifndef WANT_WIDE
-#undef strchr
-#else
-#undef wcschr
-#endif
-Wchar attribute_hidden *Wstrchr(register const Wchar *s, Wint c)
-{
-	do {
-		if (*s == ((Wchar)c)) {
-			return (Wchar *) s;	/* silence the warning */
-		}
-	} while (*s++);
-
-	return NULL;
-}
-
-#if 0 /* ndef L_wcschr */
-weak_alias(strchr, index)
-#endif
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcscspn
-#define L_strcspn
-#define Wstrcspn wcscspn
-#else
-#define Wstrcspn strcspn
-#endif
-#endif
-
-#ifdef L_strcspn
-
-#ifndef WANT_WIDE
-#undef strcspn
-#else
-#undef wcscspn
-#endif
-size_t attribute_hidden Wstrcspn(const Wchar *s1, const Wchar *s2)
-{
-	register const Wchar *s;
-	register const Wchar *p;
-
-	for ( s=s1 ; *s ; s++ ) {
-		for ( p=s2 ; *p ; p++ ) {
-			if (*p == *s) goto done;
-		}
-	}
- done:
-	return s - s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcspbrk
-#define L_strpbrk
-#define Wstrpbrk wcspbrk
-#else
-#define Wstrpbrk strpbrk
-#endif
-#endif
-
-#ifdef L_strpbrk
-
-#ifndef WANT_WIDE
-#undef strpbrk
-#else
-#undef wcspbrk
-#endif
-Wchar attribute_hidden *Wstrpbrk(const Wchar *s1, const Wchar *s2)
-{
-	register const Wchar *s;
-	register const Wchar *p;
-
-	for ( s=s1 ; *s ; s++ ) {
-		for ( p=s2 ; *p ; p++ ) {
-			if (*p == *s) return (Wchar *) s; /* silence the warning */
-		}
-	}
-	return NULL;
-}
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsrchr
-#define L_strrchr
-#define Wstrrchr wcsrchr
-#else
-#define Wstrrchr strrchr
-#endif
-#endif
-
-#ifdef L_strrchr
-
-#ifndef WANT_WIDE
-#undef strrchr
-#else
-#undef wcsrchr
-#endif
-Wchar attribute_hidden *Wstrrchr(register const  Wchar *s, Wint c)
-{
-	register const Wchar *p;
-
-	p = NULL;
-	do {
-		if (*s == (Wchar) c) {
-			p = s;
-		}
-	} while (*s++);
-
-	return (Wchar *) p;			/* silence the warning */
-}
-
-#if 0 /* ndef L_wcsrchr */
-weak_alias(strrchr, rindex)
-#endif
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsspn
-#define L_strspn
-#define Wstrspn wcsspn
-#else
-#define Wstrspn strspn
-#endif
-#endif
-
-#ifdef L_strspn
-
-#ifndef WANT_WIDE
-#undef strspn
-#else
-#undef wcsspn
-#endif
-size_t attribute_hidden Wstrspn(const Wchar *s1, const Wchar *s2)
-{
-	register const Wchar *s = s1;
-	register const Wchar *p = s2;
-
-	while (*p) {
-		if (*p++ == *s) {
-			++s;
-			p = s2;
-		}
-	}
-	return s - s1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsstr
-#define L_strstr
-#define Wstrstr wcsstr
-#else
-#define Wstrstr strstr
-#endif
-#endif
-
-#ifdef L_strstr
-
-/* NOTE: This is the simple-minded O(len(s1) * len(s2)) worst-case approach. */
-
-#ifndef WANT_WIDE
-#undef strstr
-#else
-#undef wcsstr
-#endif
-Wchar attribute_hidden *Wstrstr(const Wchar *s1, const Wchar *s2)
-{
-	register const Wchar *s = s1;
-	register const Wchar *p = s2;
-
-	do {
-		if (!*p) {
-			return (Wchar *) s1;;
-		}
-		if (*p == *s) {
-			++p;
-			++s;
-		} else {
-			p = s2;
-			if (!*s) {
-				return NULL;
-			}
-			s = ++s1;
-		}
-	} while (1);
-}
-
-#if 0 /* def L_wcsstr */
-weak_alias(wcsstr, wcswcs)
-#endif
-
-#endif
-/**********************************************************************/
-#if 0
-#undef Wstrspn
-#undef Wstrpbrk
-
-#ifdef L_wcstok
-#define L_strtok_r
-#define Wstrtok_r wcstok
-#define Wstrspn wcsspn
-#define Wstrpbrk wcspbrk
-#else
-#define Wstrtok_r __strtok_r
-#define Wstrspn strspn
-#define Wstrpbrk strpbrk
-#endif
-#endif
-
-#ifdef L_strtok_r
-
-#ifndef WANT_WIDE
-#undef strtok_r
-#else
-#undef wcstok
-#endif
-Wchar attribute_hidden *Wstrtok_r(Wchar * __restrict s1, const Wchar * __restrict s2,
-				 Wchar ** __restrict next_start)
-{
-	register Wchar *s;
-	register Wchar *p;
-
-#if 1
-	if (((s = s1) != NULL) || ((s = *next_start) != NULL)) {
-		if (*(s += Wstrspn(s, s2))) {
-			if ((p = Wstrpbrk(s, s2)) != NULL) {
-				*p++ = 0;
-			}
-		} else {
-			p = s = NULL;
-		}
-		*next_start = p;
-	}
-	return s;
-#else
-	if (!(s = s1)) {
-		s = *next_start;
-	}
-	if (s && *(s += Wstrspn(s, s2))) {
-		if (*(p = s + Wstrcspn(s, s2))) {
-			*p++ = 0;
-		}
-		*next_start = p;
-		return s;
-	}
-	return NULL;				/* TODO: set *next_start = NULL for safety? */
-#endif
-}
-
-#if 0 /* ndef L_wcstok */
-weak_alias(__strtok_r, strtok_r)
-#endif
-
-#endif
-/**********************************************************************/
-/*  #ifdef L_wcstok */
-/*  #define L_strtok */
-/*  #define Wstrtok wcstok */
-/*  #define Wstrtok_r wcstok_r */
-/*  #else */
-/*  #define Wstrtok strtok */
-/*  #define Wstrtok_r strtok_r */
-/*  #endif */
-
-#ifdef L_strtok
-#define Wstrtok strtok
-#define Wstrtok_r __strtok_r
-
-Wchar *Wstrtok(Wchar * __restrict s1, const Wchar * __restrict s2)
-{
-	static Wchar *next_start;	/* Initialized to 0 since in bss. */
-	return Wstrtok_r(s1, s2, &next_start);
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wmemset
-#define L_memset
-#define Wmemset wmemset
-#else
-#define Wmemset memset
-#endif
-#endif
-
-#ifdef L_memset
-
-#ifndef WANT_WIDE
-#undef memset
-#else
-#undef wmemset
-#endif
-Wvoid attribute_hidden *Wmemset(Wvoid *s, Wint c, size_t n)
-{
-	register Wuchar *p = (Wuchar *) s;
-#ifdef __BCC__
-	/* bcc can optimize the counter if it thinks it is a pointer... */
-	register const char *np = (const char *) n;
-#else
-#define np n
-#endif
-
-	while (np) {
-		*p++ = (Wuchar) c;
-		--np;
-	}
-
-	return s;
-}
-#undef np
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcslen
-#define L_strlen
-#define Wstrlen wcslen
-#else
-#define Wstrlen strlen
-#endif
-#endif
-
-#ifdef L_strlen
-
-#ifndef WANT_WIDE
-#undef strlen
-#else
-#undef wcslen
-#endif
-size_t attribute_hidden Wstrlen(const Wchar *s)
-{
-	register const Wchar *p;
-
-	for (p=s ; *p ; p++);
-
-	return p - s;
-}
-
-#endif
-/**********************************************************************/
-/* ANSI/ISO end here */
-/**********************************************************************/
-#ifdef L_ffs
-
-#undef ffs
-int attribute_hidden __ffs(int i)
-{
-#if 1
-	/* inlined binary search method */
-	char n = 1;
-#if UINT_MAX == 0xffffU
-	/* nothing to do here -- just trying to avoiding possible problems */
-#elif UINT_MAX == 0xffffffffU
-	if (!(i & 0xffff)) {
-		n += 16;
-		i >>= 16;
-	}
-#else
-#error ffs needs rewriting!
-#endif
-
-	if (!(i & 0xff)) {
-		n += 8;
-		i >>= 8;
-	}
-	if (!(i & 0x0f)) {
-		n += 4;
-		i >>= 4;
-	}
-	if (!(i & 0x03)) {
-		n += 2;
-		i >>= 2;
-	}
-	return (i) ? (n + ((i+1) & 0x01)) : 0;
-
-#else
-	/* linear search -- slow, but small */
-	int n;
-
-	for (n = 0 ; i ; ++n) {
-		i >>= 1;
-	}
-	
-	return n;
-#endif
-}
-
-strong_alias(__ffs, ffs)
-
-#endif
-/**********************************************************************/
-#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 __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 TOLOWER(C) tolower((C))
-#endif
-
-#endif /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
-
-
-#if defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE)
-
-int attribute_hidden __strcasecmp(register const Wchar *s1, register const Wchar *s2)
-{
-	return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
-}
-strong_alias(__strcasecmp,strcasecmp)
-
-#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-
-int attribute_hidden __UCXL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
-					  __LOCALE_PARAM )
-{
-#ifdef WANT_WIDE
-	while ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2))) {
-		if (!*s1++) {
-			return 0;
-		}
-		++s2;
-	}
-
-	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))))
-			&& (++s2, *s1++));
-
-	return r;
-#endif
-}
-__UCXL_ALIAS(strcasecmp)
-
-#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-
-#endif
-/**********************************************************************/
-#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 __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 TOLOWER(C) __towlower((C))
-#endif
-
-#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 attribute_hidden __strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
-{
-	return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
-}
-strong_alias(__strncasecmp,strncasecmp)
-
-#else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-
-int attribute_hidden __UCXL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
-					  size_t n   __LOCALE_PARAM )
-{
-#ifdef WANT_WIDE
-	while (n && ((*s1 == *s2) || (TOLOWER(*s1) == TOLOWER(*s2)))) {
-		if (!*s1++) {
-			return 0;
-		}
-		++s2;
-		--n;
-	}
-
-	return (n == 0)
-		? 0
-		: ((((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))))
-			&& (--n, ++s2, *s1++));
-	return r;
-#endif
-}
-__UCXL_ALIAS(strncasecmp)
-
-#endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcsnlen
-#define L_strnlen
-#define Wstrnlen wcsnlen
-#else
-#define Wstrnlen strnlen
-#endif
-#endif
-
-#ifdef L_strnlen
-
-#ifndef WANT_WIDE
-#undef strnlen
-#else
-#undef wcsnlen
-#endif
-size_t attribute_hidden Wstrnlen(const Wchar *s, size_t max)
-{
-	register const Wchar *p = s;
-#ifdef __BCC__
-	/* bcc can optimize the counter if it thinks it is a pointer... */
-	register const char *maxp = (const char *) max;
-#else
-#define maxp max
-#endif
-
-	while (maxp && *p) {
-		++p;
-		--maxp;
-	}
-
-	return p - s;
-}
-#undef maxp
-#endif
-/**********************************************************************/
-/* No wide analog. */
-
-#ifdef L_memccpy
-
-#undef memccpy
-void attribute_hidden *__memccpy(void * __restrict s1, const void * __restrict s2, int c, size_t n)
-{
-	register char *r1 = s1;
-	register const char *r2 = s2;
-
-	while (n-- && (((unsigned char)(*r1++ = *r2++)) != ((unsigned char) c)));
-
-	return (n == (size_t) -1) ? NULL : r1;
-}
-
-strong_alias(__memccpy, memccpy)
-
-#endif
-/**********************************************************************/
-#if 0
-#undef Wstrlen
-#undef Wstrcpy
-
-#ifdef L_wcsdup
-#define L_strdup
-#define Wstrdup wcsdup
-#define Wstrlen wcslen
-#define Wstrcpy wcscpy
-#else
-#define Wstrdup strdup
-#define Wstrlen strlen
-#define Wstrcpy strcpy
-#endif
-#endif
-
-#ifdef L_strdup
-
-#ifndef WANT_WIDE
-#undef strdup
-#else
-#undef wcsdup
-#endif
-Wchar attribute_hidden *Wstrdup(register const Wchar *s1)
-{
-	register Wchar *s;
-
-    if ((s = malloc((Wstrlen(s1) + 1) * sizeof(Wchar))) != NULL) {
-		Wstrcpy(s, s1);
-	}
-
-	return s;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_strerror
-
-#undef strerror
-char attribute_hidden *__strerror(int errnum)
-{
-    static char buf[_STRERROR_BUFSIZE];
-
-	__xpg_strerror_r_internal(errnum, buf, sizeof(buf));
-
-	return buf;
-}
-
-strong_alias(__strerror, strerror)
-
-#endif
-/**********************************************************************/
-/* SUSv3 functions. */
-/**********************************************************************/
-#ifdef L___xpg_strerror_r
-
-#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
-#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
-
-static const unsigned char estridx[] = {
-	0,							/* success is always 0 */
-	EPERM,
-	ENOENT,
-	ESRCH,
-	EINTR,
-	EIO,
-	ENXIO,
-	E2BIG,
-	ENOEXEC,
-	EBADF,
-	ECHILD,
-	EAGAIN,
-	ENOMEM,
-	EACCES,
-	EFAULT,
-	ENOTBLK,
-	EBUSY,
-	EEXIST,
-	EXDEV,
-	ENODEV,
-	ENOTDIR,
-	EISDIR,
-	EINVAL,
-	ENFILE,
-	EMFILE,
-	ENOTTY,
-	ETXTBSY,
-	EFBIG,
-	ENOSPC,
-	ESPIPE,
-	EROFS,
-	EMLINK,
-	EPIPE,
-	EDOM,
-	ERANGE,
-	EDEADLK,
-	ENAMETOOLONG,
-	ENOLCK,
-	ENOSYS,
-	ENOTEMPTY,
-	ELOOP,
-	0,
-	ENOMSG,
-	EIDRM,
-	ECHRNG,
-	EL2NSYNC,
-	EL3HLT,
-	EL3RST,
-	ELNRNG,
-	EUNATCH,
-	ENOCSI,
-	EL2HLT,
-	EBADE,
-	EBADR,
-	EXFULL,
-	ENOANO,
-	EBADRQC,
-	EBADSLT,
-	0,
-	EBFONT,
-	ENOSTR,
-	ENODATA,
-	ETIME,
-	ENOSR,
-	ENONET,
-	ENOPKG,
-	EREMOTE,
-	ENOLINK,
-	EADV,
-	ESRMNT,
-	ECOMM,
-	EPROTO,
-	EMULTIHOP,
-	EDOTDOT,
-	EBADMSG,
-	EOVERFLOW,
-	ENOTUNIQ,
-	EBADFD,
-	EREMCHG,
-	ELIBACC,
-	ELIBBAD,
-	ELIBSCN,
-	ELIBMAX,
-	ELIBEXEC,
-	EILSEQ,
-	ERESTART,
-	ESTRPIPE,
-	EUSERS,
-	ENOTSOCK,
-	EDESTADDRREQ,
-	EMSGSIZE,
-	EPROTOTYPE,
-	ENOPROTOOPT,
-	EPROTONOSUPPORT,
-	ESOCKTNOSUPPORT,
-	EOPNOTSUPP,
-	EPFNOSUPPORT,
-	EAFNOSUPPORT,
-	EADDRINUSE,
-	EADDRNOTAVAIL,
-	ENETDOWN,
-	ENETUNREACH,
-	ENETRESET,
-	ECONNABORTED,
-	ECONNRESET,
-	ENOBUFS,
-	EISCONN,
-	ENOTCONN,
-	ESHUTDOWN,
-	ETOOMANYREFS,
-	ETIMEDOUT,
-	ECONNREFUSED,
-	EHOSTDOWN,
-	EHOSTUNREACH,
-	EALREADY,
-	EINPROGRESS,
-	ESTALE,
-	EUCLEAN,
-	ENOTNAM,
-	ENAVAIL,
-	EISNAM,
-	EREMOTEIO,
-#ifdef __mips__
-	0,							/* mips has an outrageous value for this... */
-#else
-	EDQUOT,
-#endif
-	ENOMEDIUM,
-	EMEDIUMTYPE,
-#if defined(__mips__) || defined(__sparc__)
-	EDEADLOCK,
-#endif
-};
-
-#endif
-
-/* __xpg_strerror_r is used in header */
-int attribute_hidden __xpg_strerror_r_internal(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', ' '
-    };
-
-    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++) {
-		if (estridx[i] == errnum) {
-			goto GOT_ESTRIDX;
-		}
-	}
-	i = INT_MAX;	/* Failed, but may need to check mips special case. */
-#ifdef __mips__
-	if (errnum == EDQUOT) {	/* Deal with large EDQUOT value on mips */
-		i = 122;
-	}
-#endif /* __mips__ */
- GOT_ESTRIDX:
-#else
-	/* No errno to string index translation needed. */
-	i = errnum;
-#endif
-
-    if (((unsigned int) i) < _SYS_NERR) {
-		/* Trade time for space.  This function should rarely be called
-		 * so rather than keeping an array of pointers for the different
-		 * messages, just run through the buffer until we find the
-		 * correct string. */
-		for (s = (char *) _string_syserrmsgs ; i ; ++s) {
-			if (!*s) {
-				--i;
-			}
-		}
-		if (*s) {		/* Make sure we have an actual message. */
-			retval = 0;
-			goto GOT_MESG;
-		}
-    }
-
-#endif /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
-
-    s = _int10tostr(buf+sizeof(buf)-1, errnum) - sizeof(unknown);
-    __memcpy(s, unknown, sizeof(unknown));
-
- GOT_MESG:
-    if (!strerrbuf) {		/* SUSv3  */
-		buflen = 0;
-    }
-    i = __strlen(s) + 1;
-    if (i > buflen) {
-		i = buflen;
-		retval = ERANGE;
-    }
-
-    if (i) {
-		__memcpy(strerrbuf, s, i);
-		strerrbuf[i-1] = 0;	/* In case buf was too small. */
-    }
-
-    if (retval) {
-		__set_errno(retval);
-    }
-
-    return retval;
-}
-
-#else  /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
-
-int attribute_hidden __xpg_strerror_r_internal(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__ */
-strong_alias(__xpg_strerror_r_internal,__xpg_strerror_r)
-
-#endif
-/**********************************************************************/
-/* GNU extension functions. */
-/**********************************************************************/
-#ifdef L___glibc_strerror_r
-
-char attribute_hidden *__glibc_strerror_r_internal(int errnum, char *strerrbuf, size_t buflen)
-{
-    __xpg_strerror_r_internal(errnum, strerrbuf, buflen);
-
-    return strerrbuf;
-}
-
-strong_alias(__glibc_strerror_r_internal,__glibc_strerror_r)
-weak_alias(__glibc_strerror_r_internal, __strerror_r)
-#endif
-/**********************************************************************/
-#ifdef L_memmem
-
-#undef memmem
-void attribute_hidden *__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;
-}
-
-strong_alias(__memmem, memmem)
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wmempcpy
-#define L_mempcpy
-#define Wmempcpy wmempcpy
-#else
-#define Wmempcpy __mempcpy
-#endif
-#endif
-
-#ifdef L_mempcpy
-
-#ifndef WANT_WIDE
-#undef mempcpy
-#else
-#undef wmempcpy
-#endif
-Wvoid attribute_hidden *Wmempcpy(Wvoid * __restrict s1, const Wvoid * __restrict s2, size_t n)
-{
-	register Wchar *r1 = s1;
-	register const Wchar *r2 = s2;
-
-#ifdef __BCC__
-	while (n--) {
-		*r1++ = *r2++;
-	}
-#else
-	while (n) {
-		*r1++ = *r2++;
-		--n;
-	}
-#endif
-
-	return r1;
-}
-
-#if 0 /* ndef L_wmempcpy */
-weak_alias(__mempcpy, mempcpy)
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_memrchr
-
-#undef memrchr
-void attribute_hidden *__memrchr(const void *s, int c, size_t n)
-{
-	register const unsigned char *r;
-#ifdef __BCC__
-	/* bcc can optimize the counter if it thinks it is a pointer... */
-	register const char *np = (const char *) n;
-#else
-#define np n
-#endif
-	
-	r = ((unsigned char *)s) + ((size_t) np);
-
-	while (np) {
-		if (*--r == ((unsigned char)c)) {
-			return (void *) r;	/* silence the warning */
-		}
-		--np;
-	}
-
-	return NULL;
-}
-#undef np
-
-strong_alias(__memrchr, memrchr)
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcpcpy
-#define L_stpcpy
-#define Wstpcpy wcpcpy
-#else
-#define Wstpcpy stpcpy
-#endif
-#endif
-
-#ifdef L_stpcpy
-
-#ifndef WANT_WIDE
-#undef stpcpy
-#else
-#undef wcpcpy
-#endif
-Wchar attribute_hidden *Wstpcpy(register Wchar * __restrict s1, const Wchar * __restrict s2)
-{
-#ifdef __BCC__
-	do {
-		*s1 = *s2++;
-	} while (*s1++ != 0);
-#else
-	while ( (*s1++ = *s2++) != 0 );
-#endif
-
-	return s1 - 1;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcpncpy
-#define L_stpncpy
-#define Wstpncpy wcpncpy
-#else
-#define Wstpncpy stpncpy
-#endif
-#endif
-
-#ifdef L_stpncpy
-
-#ifndef WANT_WIDE
-#undef stpncpy
-#else
-#undef wcpncpy
-#endif
-Wchar attribute_hidden *Wstpncpy(register Wchar * __restrict s1,
-				register const Wchar * __restrict s2,
-				size_t n)
-{
-	Wchar *s = s1;
-	const Wchar *p = s2;
-
-#ifdef __BCC__
-	while (n--) {
-		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
-		++s;
-	}
-	return s1 + (s2 - p);
-#else
-	while (n) {
-		if ((*s = *s2) != 0) s2++; /* Need to fill tail with 0s. */
-		++s;
-		--n;
-	}
-	return s1 + (s2 - p);
-#endif
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_bzero
-
-#undef bzero
-void attribute_hidden __bzero(void *s, size_t n)
-{
-#if 1
-	(void)__memset(s, 0, n);
-#else
-	register unsigned char *p = s;
-#ifdef __BCC__
-	/* bcc can optimize the counter if it thinks it is a pointer... */
-	register const char *np = (const char *) n;
-#else
-#define np n
-#endif
-
-	while (np) {
-		*p++ = 0;
-		--np;
-	}
-#endif
-}
-#if 0
-weak_alias(__bzero, bzero)
-#else
-strong_alias(__bzero, bzero)
-#endif
-#undef np
-
-#endif
-/**********************************************************************/
-#ifdef L_bcopy
-
-#undef bcopy
-void attribute_hidden __bcopy(const void *s2, void *s1, size_t n)
-{
-#if 1
-	__memmove(s1, s2, n);
-#else
-#ifdef __BCC__
-	register char *s;
-	register const char *p;
-
-	s = s1;
-	p = s2;
-	if (p >= s) {
-		while (n--) {
-			*s++ = *p++;
-		}
-	} else {
-		s += n;
-		p += n;
-		while (n--) {
-			*--s = *--p;
-		}
-	}
-#else
-	register char *s;
-	register const char *p;
-
-	s = s1;
-	p = s2;
-	if (p >= s) {
-		while (n) {
-			*s++ = *p++;
-			--n;
-		}
-	} else {
-		while (n) {
-			--n;
-			s[n] = p[n];
-		}
-	}
-#endif
-#endif
-}
-
-strong_alias(__bcopy, bcopy)
-
-#endif
-/**********************************************************************/
-#ifdef L_strcasestr
-
-#undef strcasestr
-char attribute_hidden *__strcasestr(const char *s1, const char *s2)
-{
-	register const char *s = s1;
-	register const char *p = s2;
-
-#if 1
-	do {
-		if (!*p) {
-			return (char *) s1;;
-		}
-		if ((*p == *s)
-			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
-			) {
-			++p;
-			++s;
-		} else {
-			p = s2;
-			if (!*s) {
-				return NULL;
-			}
-			s = ++s1;
-		}
-	} while (1);
-#else
-	while (*p && *s) {
-		if ((*p == *s)
-			|| (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s)))
-			) {
-			++p;
-			++s;
-		} else {
-			p = s2;
-			s = ++s1;
-		}
-	}
-
-	return (*p) ? NULL : (char *) s1;
-#endif
-}
-
-strong_alias(__strcasestr, strcasestr)
-
-#endif
-/**********************************************************************/
-#ifdef L_strndup
-
-#undef strndup
-char attribute_hidden *__strndup(register const char *s1, size_t n)
-{
-	register char *s;
-
-	n = __strnlen(s1,n);			/* Avoid problems if s1 not nul-terminated. */
-
-    if ((s = malloc(n + 1)) != NULL) {
-		__memcpy(s, s1, n);
-		s[n] = 0;
-	}
-
-	return s;
-}
-
-strong_alias(__strndup, strndup)
-
-#endif
-/**********************************************************************/
-#ifdef L_strsep
-
-#undef strsep
-char attribute_hidden *__strsep(char ** __restrict s1, const char * __restrict s2)
-{
-	register char *s = *s1;
-	register char *p;
-
-#if 1
-	p = NULL;
-	if (s && *s && (p = __strpbrk(s, s2))) {
-		*p++ = 0;
-	}
-#else
-	if (s && *s && *(p = s + __strcspn(s, s2))) {
-		*p++ = 0;
-	} else {
-		p = NULL;
-	}
-#endif
-	*s1 = p;
-	return s;
-}
-
-strong_alias(__strsep, strsep)
-
-#endif
-/**********************************************************************/
-#if 0
-#ifdef L_wcschrnul
-#define L_strchrnul
-#define __Wstrchrnul __wcschrnul
-#define Wstrchrnul wcschrnul
-#else
-#define __Wstrchrnul __strchrnul
-#define Wstrchrnul strchrnul
-#endif
-#endif
-
-#ifdef L_strchrnul
-
-#ifndef WANT_WIDE
-#undef strchrnul
-#else
-#undef wcschrnul
-#endif
-Wchar attribute_hidden *Wstrchrnul(register const Wchar *s, Wint c)
-{
-	--s;
-	while (*++s && (*s != ((Wchar)c)));
-	return (Wchar *) s;
-}
-#if 0
-weak_alias(__Wstrchrnul, Wstrchrnul)
-#endif
-
-#endif
-/**********************************************************************/
-#ifdef L_rawmemchr
-
-#undef rawmemchr
-void attribute_hidden *__rawmemchr(const void *s, int c)
-{
-	register const unsigned char *r = s;
-
-	while (*r != ((unsigned char)c)) ++r;
-
-	return (void *) r;	/* silence the warning */
-}
-
-strong_alias(__rawmemchr, rawmemchr)
-
-#endif
-/**********************************************************************/
-#ifdef L_basename
-
-#undef basename
-char attribute_hidden *__basename(const char *path)
-{
-	register const char *s;
-	register const char *p;
-
-	p = s = path;
-
-	while (*s) {
-		if (*s++ == '/') {
-			p = s;
-		}
-	}
-
-	return (char *) p;
-}
-
-strong_alias(__basename, basename)
-
-#endif
-/**********************************************************************/
-#ifdef L___xpg_basename
-
-char *__xpg_basename(register char *path)
-{
-	static const char null_or_empty[] = ".";
-	char *first;
-	register char *last;
-
-	first = (char *) null_or_empty;
-
-	if (path && *path) {
-		first = path;
-		last = path - 1;
-
-		do {
-			if ((*path != '/') && (path > ++last)) {
-				last = first = path;
-			}
-		} while (*++path);
-
-		if (*first == '/') {
-			last = first;
-		}
-		last[1] = 0;
-	}
-
-	return first;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_dirname
-
-char *dirname(char *path)
-{
-	static const char null_or_empty_or_noslash[] = ".";
-	register char *s;
-	register char *last;
-	char *first;
-
-	last = s = path;
-
-	if (s != NULL) {
-
-	LOOP:
-		while (*s && (*s != '/')) ++s;
-		first = s;
-		while (*s == '/') ++s;
-		if (*s) {
-			last = first;
-			goto LOOP;
-		}
-
-		if (last == path) {
-			if (*last != '/') {
-				goto DOT;
-			}
-			if ((*++last == '/') && (last[1] == 0)) {
-				++last;
-			}
-		}
-		*last = 0;
-		return path;
-	}
- DOT:
-	return (char *) null_or_empty_or_noslash;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_strlcat
-
-/* OpenBSD function:
- * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
- * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
- * return val is >= n.
- * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
- *       taken as n. */
-
-size_t strlcat(register char *__restrict dst,
-			   register const char *__restrict src,
-			   size_t n)
-{
-	size_t len;
-	char dummy[1];
-
-	len = 0;
-
-	while (1) {
-		if (len >= n) {
-			dst = dummy;
-			break;
-		}
-		if (!*dst) {
-			break;
-		}
-		++dst;
-		++len;
-	}
-
-	while ((*dst = *src) != 0) {
-		if (++len < n) {
-			++dst;
-		}
-		++src;
-	}
-
-	return len;
-}
-
-#endif
-/**********************************************************************/
-#if 0
-#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
-#else
-#define Wstrlcpy strlcpy
-#endif
-#endif
-
-#ifdef L_strlcpy
-
-/* 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. */
-
-#ifndef WANT_WIDE
-#undef strlcpy
-#else
-#undef wcslcpy
-#endif
-size_t attribute_hidden Wstrlcpy(register Wchar *__restrict dst,
-				  register const Wchar *__restrict src,
-				  size_t n)
-{
-	const Wchar *src0 = src;
-	Wchar dummy[1];
-
-	if (!n) {
-		dst = dummy;
-	} else {
-		--n;
-	}
-
-	while ((*dst = *src) != 0) {
-		if (n) {
-			--n;
-			++dst;
-		}
-		++src;
-	}
-
-	return src - src0;
-}
-
-#if 0 /* def __LOCALE_C_ONLY */
-#ifdef L___wcslcpy
-weak_alias(__wcslcpy,wcsxfrm)
-#else
-weak_alias(strlcpy,strxfrm)
-#endif
-#endif
-
-#endif
-/**********************************************************************/
-#if defined(L__string_syssigmsgs) && defined(__UCLIBC_HAS_SIGNUM_MESSAGES__)
-
-const char _string_syssigmsgs[] = {
-	/*   0:    0,  1 */ "\0"
-	/*   1:    1,  7 */ "Hangup\0"
-	/*   2:    8, 10 */ "Interrupt\0"
-	/*   3:   18,  5 */ "Quit\0"
-	/*   4:   23, 20 */ "Illegal instruction\0"
-	/*   5:   43, 22 */ "Trace/breakpoint trap\0"
-	/*   6:   65,  8 */ "Aborted\0"
-	/*   7:   73, 10 */ "Bus error\0"
-	/*   8:   83, 25 */ "Floating point exception\0"
-	/*   9:  108,  7 */ "Killed\0"
-	/*  10:  115, 22 */ "User defined signal 1\0"
-	/*  11:  137, 19 */ "Segmentation fault\0"
-	/*  12:  156, 22 */ "User defined signal 2\0"
-	/*  13:  178, 12 */ "Broken pipe\0"
-	/*  14:  190, 12 */ "Alarm clock\0"
-	/*  15:  202, 11 */ "Terminated\0"
-	/*  16:  213, 12 */ "Stack fault\0"
-	/*  17:  225, 13 */ "Child exited\0"
-	/*  18:  238, 10 */ "Continued\0"
-	/*  19:  248, 17 */ "Stopped (signal)\0"
-	/*  20:  265,  8 */ "Stopped\0"
-	/*  21:  273, 20 */ "Stopped (tty input)\0"
-	/*  22:  293, 21 */ "Stopped (tty output)\0"
-	/*  23:  314, 21 */ "Urgent I/O condition\0"
-	/*  24:  335, 24 */ "CPU time limit exceeded\0"
-	/*  25:  359, 25 */ "File size limit exceeded\0"
-	/*  26:  384, 22 */ "Virtual timer expired\0"
-	/*  27:  406, 24 */ "Profiling timer expired\0"
-	/*  28:  430, 15 */ "Window changed\0"
-	/*  29:  445, 13 */ "I/O possible\0"
-	/*  30:  458, 14 */ "Power failure\0"
-	/*  31:  472, 16 */ "Bad system call"
-#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
-	/*  32:  488,  9 */ "\0EMT trap"
-#endif
-};
-
-#endif
-
-/**********************************************************************/
-#if defined(L_sys_siglist) && defined(__UCLIBC_HAS_SYS_SIGLIST__)
-
-const char *const sys_siglist[_NSIG] = {
-	[0] =				NULL,
-	[SIGHUP] =			_string_syssigmsgs + 1,
-	[SIGINT] =			_string_syssigmsgs + 8,
-	[SIGQUIT] =			_string_syssigmsgs + 18,
-	[SIGILL] =			_string_syssigmsgs + 23,
-	[SIGTRAP] =			_string_syssigmsgs + 43,
-	[SIGABRT] =			_string_syssigmsgs + 65,
-	[SIGBUS] =			_string_syssigmsgs + 73,
-	[SIGFPE] =			_string_syssigmsgs + 83,
-	[SIGKILL] =			_string_syssigmsgs + 108,
-	[SIGUSR1] =			_string_syssigmsgs + 115,
-	[SIGSEGV] =			_string_syssigmsgs + 137,
-	[SIGUSR2] =			_string_syssigmsgs + 156,
-	[SIGPIPE] =			_string_syssigmsgs + 178,
-	[SIGALRM] =			_string_syssigmsgs + 190,
-	[SIGTERM] =			_string_syssigmsgs + 202,
-#if !(defined(__alpha__) || defined(__mips__) || defined(__sparc__))
-	[SIGSTKFLT] =		_string_syssigmsgs + 213,
-#endif
-	[SIGCHLD] =			_string_syssigmsgs + 225,
-	[SIGCONT] =			_string_syssigmsgs + 238,
-	[SIGSTOP] =			_string_syssigmsgs + 248,
-	[SIGTSTP] =			_string_syssigmsgs + 265,
-	[SIGTTIN] =			_string_syssigmsgs + 273,
-	[SIGTTOU] =			_string_syssigmsgs + 293,
-	[SIGURG] =			_string_syssigmsgs + 314,
-	[SIGXCPU] =			_string_syssigmsgs + 335,
-	[SIGXFSZ] =			_string_syssigmsgs + 359,
-	[SIGVTALRM] =		_string_syssigmsgs + 384,
-	[SIGPROF] =			_string_syssigmsgs + 406,
-	[SIGWINCH] =		_string_syssigmsgs + 430,
-	[SIGIO] =			_string_syssigmsgs + 445,
-	[SIGPWR] =			_string_syssigmsgs + 458,
-	[SIGSYS] =			_string_syssigmsgs + 472,
-#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
-	[SIGEMT] =			_string_syssigmsgs + 488,
-#endif
-};
-
-#endif
-/**********************************************************************/
-#ifdef L_strsignal
-
-/* TODO: make a threadsafe version? */
-
-#undef strsignal
-#ifdef __UCLIBC_HAS_SIGNUM_MESSAGES__
-
-#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
-static const unsigned char sstridx[] = {
-	0,
-	SIGHUP,
-	SIGINT,
-	SIGQUIT,
-	SIGILL,
-	SIGTRAP,
-	SIGIOT,
-	SIGBUS,
-	SIGFPE,
-	SIGKILL,
-	SIGUSR1,
-	SIGSEGV,
-	SIGUSR2,
-	SIGPIPE,
-	SIGALRM,
-	SIGTERM,
-#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
-	0,
-#else
-	SIGSTKFLT,
-#endif
-	SIGCHLD,
-	SIGCONT,
-	SIGSTOP,
-	SIGTSTP,
-	SIGTTIN,
-	SIGTTOU,
-	SIGURG,
-	SIGXCPU,
-	SIGXFSZ,
-	SIGVTALRM,
-	SIGPROF,
-	SIGWINCH,
-	SIGIO,
-	SIGPWR,
-	SIGSYS,
-#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
-	SIGEMT,
-#endif
-};
-#endif
-
-char attribute_hidden *__strsignal(int signum)
-{
-    register char *s;
-    int i;
-    static char buf[_STRSIGNAL_BUFSIZE];
-    static const char unknown[] = {
-		'U', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 's', 'i', 'g', 'n', 'a', 'l', ' '
-    };
-
-#if defined(__alpha__) || defined(__mips__) || defined(__hppa__) || defined(__sparc__)
-	/* Need to translate signum to string index. */
-	for (i = 0 ; i < sizeof(sstridx)/sizeof(sstridx[0]) ; i++) {
-		if (sstridx[i] == signum) {
-			goto GOT_SSTRIDX;
-		}
-	}
-	i = INT_MAX;	/* Failed. */
- GOT_SSTRIDX:
-#else
-	/* No signum to string index translation needed. */
-	i = signum;
-#endif
-
-    if (((unsigned int) signum) < _SYS_NSIG) {
-		/* Trade time for space.  This function should rarely be called
-		 * so rather than keeping an array of pointers for the different
-		 * messages, just run through the buffer until we find the
-		 * correct string. */
-		for (s = (char *) _string_syssigmsgs ; i ; ++s) {
-			if (!*s) {
-				--i;
-			}
-		}
-		if (*s) {		/* Make sure we have an actual message. */
-			goto DONE;
-		}
-    }
-
-    s = _int10tostr(buf+sizeof(buf)-1, signum) - sizeof(unknown);
-    __memcpy(s, unknown, sizeof(unknown));
-
- DONE:
-	return s;
-}
-
-#else  /* __UCLIBC_HAS_SIGNUM_MESSAGES__ */
-
-char attribute_hidden *__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__ */
-
-strong_alias(__strsignal, strsignal)
-
-#endif
-/**********************************************************************/
-#ifdef L_psignal
-
-/* TODO: make this threadsafe with a reentrant version of strsignal? */
-
-void psignal(int signum, register const char *message)
-{
-	/* If the program is calling psignal, it's a safe bet that printf and
-	 * friends are used as well.  It is also possible that the calling
-	 * program could buffer stderr, or reassign it. */
-
-	register const char *sep;
-
-	sep = ": ";
-	if (!(message && *message)) { /* Caller did not supply a prefix message */
-		message = (sep += 2);	/* or passed an empty string. */
-	}
-
-	fprintf(stderr, "%s%s%s\n", message, sep, __strsignal(signum));
-}
-
-#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   __strcoll
-#define wcscoll_l strcoll_l
-#define __wcscoll_l __strcoll_l
-#define wcsxfrm   strxfrm
-#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 attribute_hidden __wcscoll (const Wchar *s0, const Wchar *s1)
-{
-	return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
-}
-strong_alias(__wcscoll,wcscoll)
-
-size_t attribute_hidden __wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
-{
-	return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
-}
-strong_alias(__wcsxfrm,wcsxfrm)
-
-#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 attribute_hidden __UCXL(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;
-}
-__UCXL_ALIAS(wcscoll)
-
-#ifdef WANT_WIDE
-
-size_t attribute_hidden __UCXL(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 __wcsxfrm(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;
-}
-
-__UCXL_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 attribute_hidden __UCXL(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;
-}
-
-__UCXL_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 */
-/**********************************************************************/