Browse Source

Fix a few bugs in the new extended locale functions.
Move stub gettext functions to a stub libintl to make switching in
gnu gettext easier. Also add a few gnu-isms.
Change to using hidden names with global weak aliases for the extended
locale functions, as expected by libstd++.
Slightly rework the locale data generation stuff to allow pregenerated
locale data to be used with buildroot.

Manuel Novoa III 20 years ago
parent
commit
50660812be

+ 2 - 1
Makefile

@@ -32,7 +32,7 @@ noconfig_targets := menuconfig config oldconfig randconfig \
 TOPDIR=./
 include Rules.mak
 
-DIRS = extra ldso libc libcrypt libresolv libnsl libutil libm libpthread
+DIRS = extra ldso libc libcrypt libresolv libnsl libutil libm libpthread libintl
 
 ifeq ($(strip $(HAVE_DOT_CONFIG)),y)
 
@@ -52,6 +52,7 @@ ifeq ($(strip $(HAVE_SHARED)),y)
 	@$(MAKE) -C libutil shared
 	@$(MAKE) -C libm shared
 	@$(MAKE) -C libpthread shared
+	@$(MAKE) -C libintl shared
 else
 ifeq ($(SHARED_TARGET),)
 	@echo

+ 3 - 39
extra/locale/Makefile

@@ -41,7 +41,6 @@ wctables.h: gen_wctype
 gen_locale: gen_locale.c c8tables.h
 	$(HOSTCC) $(HOSTCFLAGS) $(NATIVE_LDFLAGS) gen_locale.c -o $@
 
-# TODO: if no wide char support, we should auto-disable all UTF-8 locales
 locale_tables.h: gen_locale locales.txt
 	./gen_locale locales.txt
 
@@ -70,62 +69,27 @@ locales.txt:
 	    false; \
 	fi;
 
-# ifneq ($(TARGET_ARCH),$(HOST_ARCH))
-
-# locale.mmap: gen_mmap
-# 	echo Your locale.mmap file is either missing or out of date.
-# 	echo The developmental code can only generate one for the
-# 	echo target arch == native arch case.  Sorry.
-# else
-
-# gen_mmap: gen_mmap.c c8tables.h wctables.h locale_tables.h
-# 	gcc $(CFLAGS_mmap) -Os -Wall -static gen_mmap.c -o gen_mmap
-
-# locale.mmap: gen_mmap
-# 	./gen_mmap
-
-# endif
-
-# lmmtolso: lmmtolso.c
-# 	gcc -Os -Wall lmmtolso.c -o lmmtolso
-
-# locale_data.c: lmmtolso locale.mmap
-# 	./lmmtolso
-
 gen_ldc: gen_ldc.c c8tables.h wctables.h locale_tables.h locale_collate.h
 	$(HOSTCC) $(HOSTCFLAGS) $(NATIVE_LDFLAGS) $(CFLAGS_mmap) gen_ldc.c -o $@
-#gen_ldc.c -o gen_ldc
 
 locale_data.c: gen_ldc
 	./gen_ldc
 
-locale_data.o: locale_data.c lt_defines.h
-	$(CC) $(CFLAGS_mmap) -c locale_data.c
-	$(STRIPTOOL) -x -R .note -R .comment locale_data.o
-
 uClibc_locale_data.h: c8tables.h wctables.h lt_defines.h locale_mmap.h
 	grep -v "define __LC" lt_defines.h > uClibc_locale_data.h
 	cat c8tables.h wctables.h locale_mmap.h >> uClibc_locale_data.h
 
-links-target: locale_data.o uClibc_locale_data.h
-	ln -sf ../../../extra/locale/locale_data.o ../../libc/misc/locale
+links-target: locale_data.c uClibc_locale_data.h
 	cat uClibc_locale_data.h | awk 'BEGIN{i=1}{ if ( /WANT_/ ) i = /endif/ ; else if (i) print $0 }' > ../../include/bits/uClibc_locale_data.h
 
-#	cp uClibc_locale_data.h ../../libc/sysdeps/linux/common/bits/
-
 pregen:
-	$(CC) $(CFLAGS_mmap) -c locale_data.c
-	$(STRIPTOOL) -x -R .note -R .comment locale_data.o
-	ln -sf ../../../extra/locale/locale_data.o ../../libc/misc/locale
 	cat uClibc_locale_data.h | awk 'BEGIN{i=1}{ if ( /WANT_/ ) i = /endif/ ; else if (i) print $0 }' > ../../include/bits/uClibc_locale_data.h
 
-#	cp uClibc_locale_data.h ../../libc/sysdeps/linux/common/bits/
-
 clean:
 	rm -f *.[oa] *~ core
 	rm -f gen_wc8bit gen_wctype gen_locale gen_ldc gen_collate
 	rm -f c8tables.h wctables.h locale_tables.h lt_defines.h locale_collate.h
 	rm -f gen_mmap locale.mmap lmmtolso
-	rm -f locale_data.c locale_data.o  uClibc_locale_data.h
+	rm -f locale_data.c uClibc_locale_data.h
 
-.PHONY: pregen
+.PHONY: pregen links-target

+ 2 - 0
include/langinfo.h

@@ -615,6 +615,8 @@ extern char *nl_langinfo (nl_item __item) __THROW;
 
 /* Just like nl_langinfo but get the information from the locale object L.  */
 extern char *nl_langinfo_l (nl_item __item, __locale_t l);
+extern char *__nl_langinfo_l (nl_item __item, __locale_t l);
+
 #endif
 #endif
 

+ 6 - 0
include/locale.h

@@ -218,6 +218,12 @@ extern __locale_t uselocale (__locale_t __dataset) __THROW;
    Passing this value to any other function has undefined behavior.  */
 # define LC_GLOBAL_LOCALE	((__locale_t) -1L)
 
+extern __locale_t __newlocale (int __category_mask, __const char *__locale,
+			     __locale_t __base) __THROW;
+extern __locale_t __duplocale (__locale_t __dataset) __THROW;
+extern void __freelocale (__locale_t __dataset) __THROW;
+extern __locale_t __uselocale (__locale_t __dataset) __THROW;
+
 #endif
 
 __END_DECLS

+ 31 - 0
include/stdlib.h

@@ -267,6 +267,37 @@ extern float strtof_l (__const char *__restrict __nptr,
 extern long double strtold_l (__const char *__restrict __nptr,
 			      char **__restrict __endptr,
 			      __locale_t __loc) __THROW;
+
+/* Internal names to support libstd++. */
+extern long int __strtol_l (__const char *__restrict __nptr,
+			  char **__restrict __endptr, int __base,
+			  __locale_t __loc) __THROW;
+
+extern unsigned long int __strtoul_l (__const char *__restrict __nptr,
+				    char **__restrict __endptr,
+				    int __base, __locale_t __loc) __THROW;
+
+__extension__
+extern long long int __strtoll_l (__const char *__restrict __nptr,
+				char **__restrict __endptr, int __base,
+				__locale_t __loc) __THROW;
+
+__extension__
+extern unsigned long long int __strtoull_l (__const char *__restrict __nptr,
+					  char **__restrict __endptr,
+					  int __base, __locale_t __loc)
+     __THROW;
+
+extern double __strtod_l (__const char *__restrict __nptr,
+			char **__restrict __endptr, __locale_t __loc)
+     __THROW;
+
+extern float __strtof_l (__const char *__restrict __nptr,
+		       char **__restrict __endptr, __locale_t __loc) __THROW;
+
+extern long double __strtold_l (__const char *__restrict __nptr,
+			      char **__restrict __endptr,
+			      __locale_t __loc) __THROW;
 #endif /* GNU */
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 

+ 11 - 0
include/string.h

@@ -117,9 +117,15 @@ __END_NAMESPACE_STD
 /* Compare the collated forms of S1 and S2 using rules from L.  */
 extern int strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l)
      __THROW __attribute_pure__;
+extern int __strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l)
+     __THROW __attribute_pure__;
+
 /* Put a transformation of SRC into no more than N bytes of DEST.  */
 extern size_t strxfrm_l (char *__dest, __const char *__src, size_t __n,
 			 __locale_t __l) __THROW;
+extern size_t __strxfrm_l (char *__dest, __const char *__src, size_t __n,
+			 __locale_t __l) __THROW;
+
 #endif
 #endif
 
@@ -323,10 +329,15 @@ extern int strncasecmp (__const char *__s1, __const char *__s2, size_t __n)
    of the global one.  */
 extern int strcasecmp_l (__const char *__s1, __const char *__s2,
 			 __locale_t __loc) __THROW __attribute_pure__;
+extern int __strcasecmp_l (__const char *__s1, __const char *__s2,
+			 __locale_t __loc) __THROW __attribute_pure__;
 
 extern int strncasecmp_l (__const char *__s1, __const char *__s2,
 			  size_t __n, __locale_t __loc)
      __THROW __attribute_pure__;
+extern int __strncasecmp_l (__const char *__s1, __const char *__s2,
+			  size_t __n, __locale_t __loc)
+     __THROW __attribute_pure__;
 #endif
 #endif
 

+ 11 - 0
include/time.h

@@ -224,6 +224,17 @@ extern size_t strftime_l (char *__restrict __s, size_t __maxsize,
 extern char *strptime_l (__const char *__restrict __s,
 			 __const char *__restrict __fmt, struct tm *__tp,
 			 __locale_t __loc) __THROW;
+
+
+extern size_t __strftime_l (char *__restrict __s, size_t __maxsize,
+							__const char *__restrict __format,
+							__const struct tm *__restrict __tp,
+							__locale_t __loc) __THROW;
+
+extern char *__strptime_l (__const char *__restrict __s,
+						   __const char *__restrict __fmt, struct tm *__tp,
+						   __locale_t __loc) __THROW;
+
 # endif
 #endif
 

+ 39 - 0
include/wchar.h

@@ -180,9 +180,13 @@ extern int wcsncasecmp (__const wchar_t *__s1, __const wchar_t *__s2,
 
 extern int wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
 			 __locale_t __loc) __THROW;
+extern int __wcscasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+			 __locale_t __loc) __THROW;
 
 extern int wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
 			  size_t __n, __locale_t __loc) __THROW;
+extern int __wcsncasecmp_l (__const wchar_t *__s1, __const wchar_t *__s2,
+			  size_t __n, __locale_t __loc) __THROW;
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 #endif
 
@@ -206,12 +210,17 @@ __END_NAMESPACE_C99
    LC_COLLATE category of the given locale.  */
 extern int wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2,
 		      __locale_t __loc) __THROW;
+extern int __wcscoll_l (__const wchar_t *__s1, __const wchar_t *__s2,
+		      __locale_t __loc) __THROW;
 
 /* Transform S2 into array pointed to by S1 such that if wcscmp is
    applied to two transformed strings the result is the as applying
    `wcscoll' to the original strings.  */
 extern size_t wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2,
 			 size_t __n, __locale_t __loc) __THROW;
+extern size_t __wcsxfrm_l (wchar_t *__s1, __const wchar_t *__s2,
+			 size_t __n, __locale_t __loc) __THROW;
+
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 
 /* Duplicate S, returning an identical malloc'd string.  */
@@ -465,33 +474,57 @@ extern unsigned long long int wcstouq (__const wchar_t *__restrict __nptr,
 extern long int wcstol_l (__const wchar_t *__restrict __nptr,
 			  wchar_t **__restrict __endptr, int __base,
 			  __locale_t __loc) __THROW;
+extern long int __wcstol_l (__const wchar_t *__restrict __nptr,
+			  wchar_t **__restrict __endptr, int __base,
+			  __locale_t __loc) __THROW;
 
 extern unsigned long int wcstoul_l (__const wchar_t *__restrict __nptr,
 				    wchar_t **__restrict __endptr,
 				    int __base, __locale_t __loc) __THROW;
+extern unsigned long int __wcstoul_l (__const wchar_t *__restrict __nptr,
+				    wchar_t **__restrict __endptr,
+				    int __base, __locale_t __loc) __THROW;
 
 __extension__
 extern long long int wcstoll_l (__const wchar_t *__restrict __nptr,
 				wchar_t **__restrict __endptr,
 				int __base, __locale_t __loc) __THROW;
+__extension__
+extern long long int __wcstoll_l (__const wchar_t *__restrict __nptr,
+				wchar_t **__restrict __endptr,
+				int __base, __locale_t __loc) __THROW;
 
 __extension__
 extern unsigned long long int wcstoull_l (__const wchar_t *__restrict __nptr,
 					  wchar_t **__restrict __endptr,
 					  int __base, __locale_t __loc)
      __THROW;
+__extension__
+extern unsigned long long int __wcstoull_l (__const wchar_t *__restrict __nptr,
+					  wchar_t **__restrict __endptr,
+					  int __base, __locale_t __loc)
+     __THROW;
 
 extern double wcstod_l (__const wchar_t *__restrict __nptr,
 			wchar_t **__restrict __endptr, __locale_t __loc)
      __THROW;
+extern double __wcstod_l (__const wchar_t *__restrict __nptr,
+			wchar_t **__restrict __endptr, __locale_t __loc)
+     __THROW;
 
 extern float wcstof_l (__const wchar_t *__restrict __nptr,
 		       wchar_t **__restrict __endptr, __locale_t __loc)
      __THROW;
+extern float __wcstof_l (__const wchar_t *__restrict __nptr,
+		       wchar_t **__restrict __endptr, __locale_t __loc)
+     __THROW;
 
 extern long double wcstold_l (__const wchar_t *__restrict __nptr,
 			      wchar_t **__restrict __endptr,
 			      __locale_t __loc) __THROW;
+extern long double __wcstold_l (__const wchar_t *__restrict __nptr,
+			      wchar_t **__restrict __endptr,
+			      __locale_t __loc) __THROW;
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 #endif /* GNU */
 
@@ -803,6 +836,7 @@ extern int fputws_unlocked (__const wchar_t *__restrict __ws,
 #endif
 
 
+#if 0
 __BEGIN_NAMESPACE_C99
 /* Format TP into S according to FORMAT.
    Write no more than MAXSIZE wide characters and return the number
@@ -822,8 +856,13 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
 			  __const wchar_t *__restrict __format,
 			  __const struct tm *__restrict __tp,
 			  __locale_t __loc) __THROW;
+extern size_t __wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
+			  __const wchar_t *__restrict __format,
+			  __const struct tm *__restrict __tp,
+			  __locale_t __loc) __THROW;
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 # endif
+#endif /* 0 */
 
 /* The X/Open standard demands that most of the functions defined in
    the <wctype.h> header must also appear here.  This is probably

+ 17 - 0
include/wctype.h

@@ -322,6 +322,23 @@ extern wctrans_t wctrans_l (__const char *__property, __locale_t __locale)
 extern wint_t towctrans_l (wint_t __wc, wctrans_t __desc,
 			   __locale_t __locale) __THROW;
 
+extern int __iswalnum_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswalpha_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswblank_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswcntrl_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswdigit_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswgraph_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswlower_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswprint_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswpunct_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswspace_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswupper_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswxdigit_l(wint_t __wc, __locale_t __locale) __THROW;
+extern wint_t __towlower_l(wint_t __wc, __locale_t __locale) __THROW;
+extern wint_t __towupper_l(wint_t __wc, __locale_t __locale) __THROW;
+extern int __iswctype_l(wint_t __wc, wctype_t __desc, __locale_t __locale) __THROW;
+extern wctrans_t __wctrans_l(const char *__property, __locale_t __locale) __THROW;
+extern wint_t __towctrans_l(wint_t __wc, wctrans_t __desc, __locale_t __locale) __THROW;
 # endif /* Use GNU.  */
 
 __END_DECLS

+ 12 - 2
libc/misc/ctype/ctype.c

@@ -256,8 +256,9 @@ int tolower(int c)
 #ifdef L_tolower_l
 
 #undef tolower_l
+#undef __tolower_l
 
-int tolower_l(int c, __locale_t l)
+int __tolower_l(int c, __locale_t l)
 {
 #if defined(__UCLIBC_HAS_CTYPE_ENFORCED__)
 	assert(CTYPE_DOMAIN_CHECK(c));
@@ -265,6 +266,8 @@ int tolower_l(int c, __locale_t l)
 	return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_tolower[c] : c;
 }
 
+weak_alias(__tolower_l, tolower_l)
+
 #endif
 /**********************************************************************/
 #ifdef L_toupper
@@ -282,8 +285,9 @@ int toupper(int c)
 #ifdef L_toupper_l
 
 #undef toupper_l
+#undef __toupper_l
 
-int toupper_l(int c, __locale_t l)
+int __toupper_l(int c, __locale_t l)
 {
 #if defined(__UCLIBC_HAS_CTYPE_ENFORCED__)
 	assert(CTYPE_DOMAIN_CHECK(c));
@@ -291,6 +295,8 @@ int toupper_l(int c, __locale_t l)
 	return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_toupper[c] : c;
 }
 
+weak_alias(__toupper_l, toupper_l)
+
 #endif
 /**********************************************************************/
 #if defined(L_isascii) || defined(L_isascii_l)
@@ -300,6 +306,8 @@ int __XL(isascii)(int c)
 	return __isascii(c);		/* locale-independent */
 }
 
+__XL_ALIAS(isascii)
+
 #endif
 /**********************************************************************/
 #if defined(L_toascii) || defined(L_toascii_l)
@@ -309,6 +317,8 @@ int __XL(toascii)(int c)
 	return __toascii(c);		/* locale-independent */
 }
 
+__XL_ALIAS(toascii)
+
 #endif
 /**********************************************************************/
 /* old uClibc extensions */

+ 1 - 1
libc/misc/gnu/obstack.c

@@ -466,7 +466,7 @@ _obstack_memory_used (h)
 #  if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
 #   include <libintl.h>
 #   ifndef _
-#    define _(Str) gettext (Str)
+#    define _(Str) __dcgettext (NULL, Str, LC_MESSAGES)
 #   endif
 #  else
 #   define _(Str) (Str)

+ 1 - 2
libc/misc/intl/Makefile

@@ -25,8 +25,7 @@ TOPDIR=../../../
 include $(TOPDIR)Rules.mak
 
 MSRC= intl.c
-MOBJ= gettext.o ngettext.o  dgettext.o dcgettext.o dngettext.o dcngettext.o \
-	textdomain.o bindtextdomain.o bind_textdomain_codeset.o
+MOBJ= __uClibc_dgettext.o __uClibc_dcgettext.o
 
 OBJS=$(MOBJ)
 

+ 5 - 101
libc/misc/intl/intl.c

@@ -16,7 +16,7 @@
  */
 
 /*
- *  Supply some weaks for gettext and friends.  Used by strerror*().
+ *  Supply some weaks for use by strerror*(), etc.
  */
 
 #include <stdlib.h>
@@ -27,123 +27,27 @@
 #include <libintl.h>
 
 /**********************************************************************/
-#ifdef L_gettext
-
-char *weak_function gettext(const char *msgid)
-{
-	return (char *) msgid;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_dgettext
+#ifdef L___uClibc_dgettext
 
 char *__uClibc_dgettext(const char *domainname,
-									  const char *msgid)
+						const char *msgid)
 {
 	return (char *) msgid;
 }
 
 weak_alias (__uClibc_dgettext, __dgettext)
-weak_alias (__uClibc_dgettext, dgettext)
 
 #endif
 /**********************************************************************/
-#ifdef L_dcgettext
+#ifdef L___uClibc_dcgettext
 
 char * __uClibc_dcgettext(const char *domainname,
-									   const char *msgid, int category)
+						  const char *msgid, int category)
 {
 	return (char *) msgid;
 }
 
 weak_alias (__uClibc_dcgettext, __dcgettext)
-weak_alias (__uClibc_dcgettext, dcgettext)
-
-#endif
-/**********************************************************************/
-#ifdef L_ngettext
-
-char *weak_function ngettext(const char *msgid1, const char *msgid2,
-							 unsigned long int n)
-{
-	return (char *) ((n == 1) ? msgid1 : msgid2);
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_dngettext
-
-char *weak_function dngettext(const char *domainname, const char *msgid1,
-							  const char *msgid2, unsigned long int n)
-{
-	return (char *) ((n == 1) ? msgid1 : msgid2);
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_dcngettext
-
-char *weak_function dcngettext(const char *domainname, const char *msgid1,
-							   const char *msgid2, unsigned long int n,
-							   int category)
-{
-	return (char *) ((n == 1) ? msgid1 : msgid2);
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_textdomain
-
-char *weak_function textdomain(const char *domainname)
-{
-	static const char default_str[] = "messages";
-
-	if (domainname && *domainname && strcmp(domainname, default_str)) {
-		__set_errno(EINVAL);
-		return NULL;
-	}
-	return (char *) default_str;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_bindtextdomain
-
-char *weak_function bindtextdomain(const char *domainname, const char *dirname)
-{
-	static const char dir[] = "/";
-
-	if (!domainname || !*domainname
-		|| (dirname
-#if 1
-			&& ((dirname[0] != '/') || dirname[1])
-#else
-			&& strcmp(dirname, dir)
-#endif
-			)
-		) {
-		__set_errno(EINVAL);
-		return NULL;
-	}
-
-	return (char *) dir;
-}
-
-#endif
-/**********************************************************************/
-#ifdef L_bind_textdomain_codeset
-
-/* Specify the character encoding in which the messages from the
-   DOMAINNAME message catalog will be returned.  */
-char *weak_function bind_textdomain_codeset(const char *domainname,
-											const char *codeset)
-{
-	if (!domainname || !*domainname || codeset) {
-		__set_errno(EINVAL);
-	}
-	return NULL;
-}
 
 #endif
 /**********************************************************************/

+ 1 - 0
libc/misc/locale/.cvsignore

@@ -1 +1,2 @@
+locale_data.c
 locale_data.o

+ 10 - 12
libc/misc/locale/Makefile

@@ -36,18 +36,14 @@ ifeq ($(UCLIBC_HAS_XLOCALE),y)
 	MOBJx += nl_langinfo_l.o duplocale.o freelocale.o uselocale.o __curlocale.o
 endif
 
-OBJS= $(MOBJ) $(MOBJx)
-
-ifeq ($(UCLIBC_HAS_LOCALE),y)
-	OBJS += $(COBJS) locale_data.o
-endif
-
 DATA=
 ifeq ($(UCLIBC_HAS_LOCALE),y)
-	DATA += locale_data.o
+	DATA = locale_data.o
 endif
 
-all: $(DATA) $(OBJS) $(LIBC)
+OBJS= $(MOBJ) $(MOBJx) $(DATA)
+
+all: $(OBJS) $(LIBC)
 
 
 $(LIBC): ar-target
@@ -63,12 +59,14 @@ $(MOBJx): $(MSRC)
 	$(CC) $(CFLAGS) -DL_$* -D__UCLIBC_DO_XLOCALE $< -c -o $*.o
 	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
-$(OBJS): Makefile
+locale_data.o:
+	ln -sf ../../../extra/locale/locale_data.c
+	$(CC) $(CFLAGS) -c -D__WCHAR_ENABLED -I../../../extra/locale locale_data.c -o $@
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
 
-# locale_data.o:
-# 	make -C $(TOPDIR)/extra/locale
+$(OBJS): Makefile
 
 clean:
-	rm -f *.[oa] *~ core
+	rm -f *.[oa] *~ core locale_data.c
 
 .PHONY: data

+ 46 - 25
libc/misc/locale/locale.c

@@ -16,7 +16,6 @@
  */
 
 /* Nov. 1, 2002
- *
  * Reworked setlocale() return values and locale arg processing to
  *   be more like glibc.  Applications expecting to be able to
  *   query locale settings should now work... at the cost of almost
@@ -24,8 +23,15 @@
  * Fixed a bug in the internal fixed-size-string locale specifier code.
  *
  * Dec 20, 2002
- *
  * Added in collation support and updated stub nl_langinfo.
+ *
+ * Aug 1, 2003
+ * Added glibc-like extended locale stuff (newlocale, duplocale, etc).
+ *
+ * Aug 18, 2003
+ * Bug in duplocale... collation data wasn't copied.
+ * Bug in newlocale... translate 1<<LC_ALL to LC_ALL_MASK.
+ * Bug in _wchar_utf8sntowcs... fix cut-n-paste error.
  */
 
 
@@ -48,6 +54,8 @@
 #include <assert.h>
 #include <errno.h>
 #include <ctype.h>
+#warning devel code
+#include <stdio.h>
 
 #undef __LOCALE_C_ONLY
 #ifndef __UCLIBC_HAS_LOCALE__
@@ -249,10 +257,8 @@ char *setlocale(int category, const char *locale)
 	}
 
 	if (locale != NULL) {		/* Not just a query... */
-		if (!__newlocale((category == LC_ALL) ? LC_ALL_MASK : (1 << category),
-						 locale, __global_locale)
-			) { /* Failed! */
-			return NULL;
+		if (!__newlocale((1 << category), locale, __global_locale)) {
+			return NULL;		/* Failed! */
 		}
 		update_hr_locale(__global_locale->cur_locale);
 	}
@@ -436,35 +442,36 @@ static int init_cur_collate(int der_num, __collate_t *cur_collate)
 	cur_collate->ti_mask = (1 << cur_collate->ti_shift)-1;
 	cur_collate->ii_mask = (1 << cur_collate->ii_shift)-1;
 
-/*	 printf("base=%d  num_col_base: %d  %d\n", cdd->base_idx ,cur_collate->num_col_base, cdb->num_col_base); */
+/* 	fflush(stdout); */
+/* 	fprintf(stderr,"base=%d  num_col_base: %d  %d\n", cdd->base_idx ,cur_collate->num_col_base, cdb->num_col_base); */
 
 	n = (sizeof(coldata_header_t) + cdh->num_base * sizeof(coldata_base_t)
 		 + cdh->num_der * sizeof(coldata_der_t))/2;
 
-/*	 printf("n   = %d\n", n); */
+/* 	fprintf(stderr,"n   = %d\n", n); */
 	cur_collate->index2weight_tbl = __locale_collate_tbl + n + cdb->index2weight_offset;
-/*	 printf("i2w = %d\n", n + cdb->index2weight_offset); */
+/* 	fprintf(stderr,"i2w = %d\n", n + cdb->index2weight_offset); */
 	n += cdh->num_index2weight;
 	cur_collate->index2ruleidx_tbl = __locale_collate_tbl + n + cdb->index2ruleidx_offset;
-/*	 printf("i2r = %d\n", n + cdb->index2ruleidx_offset); */
+/* 	fprintf(stderr,"i2r = %d\n", n + cdb->index2ruleidx_offset); */
 	n += cdh->num_index2ruleidx;
 	cur_collate->multistart_tbl = __locale_collate_tbl + n + cdd->multistart_offset;
-/*	 printf("mts = %d\n", n + cdb->multistart_offset); */
+/* 	fprintf(stderr,"mts = %d\n", n + cdb->multistart_offset); */
 	n += cdh->num_multistart;
 	cur_collate->overrides_tbl = __locale_collate_tbl + n + cdd->overrides_offset;
-/*	 printf("ovr = %d\n", n + cdd->overrides_offset); */
+/* 	fprintf(stderr,"ovr = %d\n", n + cdd->overrides_offset); */
 	n += cdh->num_override;
 	cur_collate->ruletable = __locale_collate_tbl + n;
-/*	 printf("rtb = %d\n", n); */
+/* 	fprintf(stderr, "rtb = %d\n", n); */
 	n += cdh->num_ruletable;
 	cur_collate->weightstr = __locale_collate_tbl + n;
-/*	 printf("wts = %d\n", n); */
+/* 	fprintf(stderr,"wts = %d\n", n); */
 	n += cdh->num_weightstr;
 	cur_collate->wcs2colidt_tbl = __locale_collate_tbl + n
 		+ (((unsigned long)(cdb->wcs2colidt_offset_hi)) << 16)
 		+ cdb->wcs2colidt_offset_low;
-/*	 printf("wcs = %lu\n", n	+ (((unsigned long)(cdb->wcs2colidt_offset_hi)) << 16) */
-/* 		   + cdb->wcs2colidt_offset_low); */
+/* 	fprintf(stderr,"wcs = %lu\n", n	+ (((unsigned long)(cdb->wcs2colidt_offset_hi)) << 16) */
+/* 			+ cdb->wcs2colidt_offset_low); */
 
 	cur_collate->MAX_WEIGHTS = cdh->MAX_WEIGHTS;
 
@@ -494,13 +501,15 @@ static int init_cur_collate(int der_num, __collate_t *cur_collate)
 		w = *p++;
 		do {
 			i = *p++;
-/* 			fprintf(stderr, "	i=%d w=%d *p=%d\n", i, w, *p); */
+/* 			fprintf(stderr, "	i=%d (%#x) w=%d *p=%d\n", i, i, w, *p); */
 			cur_collate->index2weight[i-1] = w++;
 			cur_collate->index2ruleidx[i-1] = *p++;
 		} while (--n);
 	}
+	assert(*p == 1);
 	while (*++p) {
 		i = *p;
+/* 		fprintf(stderr, "	i=%d (%#x) w=%d *p=%d\n", i, i, p[1], p[2]); */
 		cur_collate->index2weight[i-1] = *++p;
 		cur_collate->index2ruleidx[i-1] = *++p;
 	}
@@ -869,7 +878,7 @@ char *nl_langinfo(nl_item item)
 
 char *nl_langinfo(nl_item item)
 {
-	return nl_langinfo_l(item, __UCLIBC_CURLOCALE);
+	return __nl_langinfo_l(item, __UCLIBC_CURLOCALE);
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1056,6 +1065,10 @@ __locale_t __newlocale(int category_mask, const char *locale, __locale_t base)
 	int i, j, k;
 	unsigned char new_selector[LOCALE_SELECTOR_SIZE];
 
+	if (category_mask == (1 << LC_ALL)) {
+		category_mask = LC_ALL_MASK;
+	}
+
 	if (!locale || (((unsigned int)(category_mask)) > LC_ALL_MASK)) {
 	INVALID:
 		__set_errno(EINVAL);
@@ -1141,20 +1154,22 @@ weak_alias(__newlocale, newlocale)
 #warning REMINDER: When we allocate ctype tables, remember to dup them.
 #endif
 
-__locale_t duplocale(__locale_t dataset)
+__locale_t __duplocale(__locale_t dataset)
 {
 	__locale_t r;
 	uint16_t * i2w;
+	size_t n;
 
 	assert(dataset != LC_GLOBAL_LOCALE);
 
 	if ((r = malloc(sizeof(__uclibc_locale_t))) != NULL) {
-		if ((i2w = calloc(2*dataset->collate.max_col_index+2,
-						  sizeof(uint16_t)))
+		n = 2*dataset->collate.max_col_index+2;
+		if ((i2w = calloc(n, sizeof(uint16_t)))
 			!= NULL
 			) {
 			memcpy(r, dataset, sizeof(__uclibc_locale_t));
 			r->collate.index2weight = i2w;
+			memcpy(i2w, dataset->collate.index2weight, n * sizeof(uint16_t));
 		} else {
 			free(r);
 			r = NULL;
@@ -1163,6 +1178,8 @@ __locale_t duplocale(__locale_t dataset)
 	return r;
 }
 
+weak_alias(__duplocale, duplocale)
+
 #endif
 /**********************************************************************/
 #ifdef L_freelocale
@@ -1171,7 +1188,7 @@ __locale_t duplocale(__locale_t dataset)
 #warning REMINDER: When we allocate ctype tables, remember to free them.
 #endif
 
-void freelocale(__locale_t dataset)
+void __freelocale(__locale_t dataset)
 {
 	assert(dataset != __global_locale);
 	assert(dataset != LC_GLOBAL_LOCALE);
@@ -1180,11 +1197,13 @@ void freelocale(__locale_t dataset)
 	free(dataset);				/* Free locale */
 }
 
+weak_alias(__freelocale, freelocale)
+
 #endif
 /**********************************************************************/
 #ifdef L_uselocale
 
-__locale_t uselocale(__locale_t dataset)
+__locale_t __uselocale(__locale_t dataset)
 {
 	__locale_t old;
 
@@ -1208,6 +1227,8 @@ __locale_t uselocale(__locale_t dataset)
 	return old;
 }
 
+weak_alias(__uselocale, uselocale)
+
 #endif
 /**********************************************************************/
 #ifdef L___curlocale
@@ -1283,8 +1304,8 @@ int __locale_mbrtowc_l(wchar_t *__restrict dst,
 #ifdef __CTYPE_HAS_8_BIT_LOCALES
 	if (loc->encoding == __ctype_encoding_8_bit) {
 		wchar_t wc = *dst - 0x80;
-		*dst = __LOCALE_PTR->tbl8c2wc[
-						(__LOCALE_PTR->idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
+		*dst = loc->tbl8c2wc[
+						(loc->idx8c2wc[wc >> Cc2wc_IDX_SHIFT]
 						 << Cc2wc_IDX_SHIFT) + (wc & (Cc2wc_ROW_LEN - 1))];
 		if (*dst) {
 			return 1;

+ 6 - 2
libc/misc/time/time.c

@@ -652,7 +652,7 @@ size_t strftime(char *__restrict s, size_t maxsize,
 				const char *__restrict format,
 				const struct tm *__restrict timeptr)
 {
-	return strftime_l(s, maxsize, format, timeptr, __UCLIBC_CURLOCALE);
+	return __strftime_l(s, maxsize, format, timeptr, __UCLIBC_CURLOCALE);
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1106,6 +1106,8 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize,
 	goto LOOP;
 }
 
+__XL_ALIAS(strftime)
+
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
 
 #endif
@@ -1127,7 +1129,7 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize,
 char *strptime(const char *__restrict buf, const char *__restrict format,
 			   struct tm *__restrict tm)
 {
-	return strptime_l(buf, format, tm, __UCLIBC_CURLOCALE);
+	return __strptime_l(buf, format, tm, __UCLIBC_CURLOCALE);
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1482,6 +1484,8 @@ char *__XL(strptime)(const char *__restrict buf, const char *__restrict format,
 	return NULL;
 }
 
+__XL_ALIAS(strptime)
+
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
 
 #endif

+ 0 - 9
libc/misc/wctype/wctype.c

@@ -44,15 +44,6 @@
 
 #ifdef __UCLIBC_HAS_XLOCALE__
 #include <xlocale.h>
-
-extern int __iswctype_l (wint_t __wc, wctype_t __desc, __locale_t __locale);
-     __THROW;
-extern wint_t __towlower_l (wint_t __wc, __locale_t __locale) __THROW;
-
-extern wint_t __towupper_l (wint_t __wc, __locale_t __locale) __THROW;
-extern wint_t __towctrans_l (wint_t __wc, wctrans_t __desc,
-			   __locale_t __locale) __THROW;
-
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 
 /* We know wide char support is enabled.  We wouldn't be here otherwise. */

+ 32 - 16
libc/stdlib/stdlib.c

@@ -299,9 +299,11 @@ strong_alias(__XL(strtol),__XL(strtoll))
 long __XL(strtol)(const char * __restrict str, char ** __restrict endptr,
 				  int base   __LOCALE_PARAM )
 {
-    return __XL(_stdlib_strto_l)(str, endptr, base, 1   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1   __LOCALE_ARG );
 }
 
+__XL_ALIAS(strtol)
+
 #endif
 /**********************************************************************/
 #if defined(L_strtoll) || defined(L_strtoll_l)
@@ -319,10 +321,12 @@ long long __XL(strtoll)(const char * __restrict str,
 						char ** __restrict endptr, int base
 						__LOCALE_PARAM )
 {
-    return (long long) __XL(_stdlib_strto_ll)(str, endptr, base, 1
-											  __LOCALE_ARG );
+    return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1
+												  __LOCALE_ARG );
 }
 
+__XL_ALIAS(strtoll)
+
 #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
 
 #endif
@@ -341,9 +345,11 @@ unsigned long __XL(strtoul)(const char * __restrict str,
 							char ** __restrict endptr, int base
 							__LOCALE_PARAM )
 {
-    return __XL(_stdlib_strto_l)(str, endptr, base, 0   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0   __LOCALE_ARG );
 }
 
+__XL_ALIAS(strtoul)
+
 #endif
 /**********************************************************************/
 #if defined(L_strtoull) || defined(L_strtoull_l)
@@ -361,9 +367,11 @@ unsigned long long __XL(strtoull)(const char * __restrict str,
 								  char ** __restrict endptr, int base
 								  __LOCALE_PARAM )
 {
-    return __XL(_stdlib_strto_ll)(str, endptr, base, 0   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0   __LOCALE_ARG );
 }
 
+__XL_ALIAS(strtoull)
+
 #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
 
 #endif
@@ -432,9 +440,9 @@ unsigned long _stdlib_strto_l(register const Wchar * __restrict str,
 /* This is the main work fuction which handles both strtol (sflag = 1) and
  * strtoul (sflag = 0). */
 
-unsigned long __XL(_stdlib_strto_l)(register const Wchar * __restrict str,
-									Wchar ** __restrict endptr, int base,
-									int sflag   __LOCALE_PARAM )
+unsigned long __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str,
+										Wchar ** __restrict endptr, int base,
+										int sflag   __LOCALE_PARAM )
 {
     unsigned long number, cutoff;
 #if _STRTO_ENDPTR
@@ -575,9 +583,9 @@ unsigned long long _stdlib_strto_ll(register const Wchar * __restrict str,
 /* This is the main work fuction which handles both strtoll (sflag = 1) and
  * strtoull (sflag = 0). */
 
-unsigned long long __XL(_stdlib_strto_ll)(register const Wchar * __restrict str,
-										  Wchar ** __restrict endptr, int base,
-										  int sflag   __LOCALE_PARAM )
+unsigned long long __XL_NPP(_stdlib_strto_ll)(register const Wchar * __restrict str,
+											  Wchar ** __restrict endptr, int base,
+											  int sflag   __LOCALE_PARAM )
 {
     unsigned long long number;
 #if _STRTO_ENDPTR
@@ -956,9 +964,11 @@ strong_alias(__XL(wcstol),__XL(wcstoll))
 long __XL(wcstol)(const wchar_t * __restrict str,
 				  wchar_t ** __restrict endptr, int base   __LOCALE_PARAM )
 {
-    return __XL(_stdlib_wcsto_l)(str, endptr, base, 1   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1   __LOCALE_ARG );
 }
 
+__XL_ALIAS(wcstol)
+
 #endif
 /**********************************************************************/
 #if defined(L_wcstoll) || defined(L_wcstoll_l)
@@ -976,10 +986,12 @@ long long __XL(wcstoll)(const wchar_t * __restrict str,
 						wchar_t ** __restrict endptr, int base
 						__LOCALE_PARAM )
 {
-    return (long long) __XL(_stdlib_wcsto_ll)(str, endptr, base, 1
-											  __LOCALE_ARG );
+    return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1
+												  __LOCALE_ARG );
 }
 
+__XL_ALIAS(wcstoll)
+
 #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
 
 #endif
@@ -998,9 +1010,11 @@ unsigned long __XL(wcstoul)(const wchar_t * __restrict str,
 							wchar_t ** __restrict endptr, int base
 							__LOCALE_PARAM )
 {
-    return __XL(_stdlib_wcsto_l)(str, endptr, base, 0   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0   __LOCALE_ARG );
 }
 
+__XL_ALIAS(wcstoul)
+
 #endif
 /**********************************************************************/
 #if defined(L_wcstoull) || defined(L_wcstoull_l)
@@ -1018,9 +1032,11 @@ unsigned long long __XL(wcstoull)(const wchar_t * __restrict str,
 								  wchar_t ** __restrict endptr, int base
 								  __LOCALE_PARAM )
 {
-    return __XL(_stdlib_wcsto_ll)(str, endptr, base, 0   __LOCALE_ARG );
+    return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0   __LOCALE_ARG );
 }
 
+__XL_ALIAS(wcstoull)
+
 #endif /* defined(ULLONG_MAX) && (LLONG_MAX > LONG_MAX) */
 
 #endif

+ 22 - 9
libc/stdlib/strtod.c

@@ -222,8 +222,8 @@ __fpmax_t __strtofpmax(const Wchar *str, Wchar **endptr, int exponent_power)
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
 
-__fpmax_t __XL(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power
-							 __LOCALE_PARAM )
+__fpmax_t __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power
+								 __LOCALE_PARAM )
 {
 	__fpmax_t number;
 	__fpmax_t p_base = 10;			/* Adjusted to 16 in the hex case. */
@@ -522,6 +522,8 @@ extern void __fp_range_check(__fpmax_t y, __fpmax_t x)
 #if defined(L_wcstof) || defined(L_wcstof_l)
 #define strtof           wcstof
 #define strtof_l         wcstof_l
+#define __strtof         __wcstof
+#define __strtof_l       __wcstof_l
 #define __strtofpmax     __wcstofpmax
 #define __strtofpmax_l   __wcstofpmax_l
 #define Wchar wchar_t
@@ -533,12 +535,12 @@ extern void __fp_range_check(__fpmax_t y, __fpmax_t x)
 float __XL(strtof)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 {
 #if FPMAX_TYPE == 1
-	return __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	return __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 #else
 	__fpmax_t x;
 	float y;
 
-	x = __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	x = __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 	y = (float) x;
 
 	__fp_range_check(y, x);
@@ -547,6 +549,8 @@ float __XL(strtof)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #endif
 }
 
+__XL_ALIAS(strtof)
+
 #endif
 #endif
 /**********************************************************************/
@@ -556,6 +560,8 @@ float __XL(strtof)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #if defined(L_wcstod) || defined(L_wcstod_l)
 #define strtod           wcstod
 #define strtod_l         wcstod_l
+#define __strtod         __wcstod
+#define __strtod_l       __wcstod_l
 #define __strtofpmax     __wcstofpmax
 #define __strtofpmax_l   __wcstofpmax_l
 #define Wchar wchar_t
@@ -563,15 +569,16 @@ float __XL(strtof)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #define Wchar char
 #endif
 
-double __XL(strtod)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
+double __XL(strtod)(const Wchar *__restrict str,
+					Wchar **__restrict endptr   __LOCALE_PARAM )
 {
 #if FPMAX_TYPE == 2
-	return __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	return __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 #else
 	__fpmax_t x;
 	double y;
 
-	x = __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	x = __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 	y = (double) x;
 
 	__fp_range_check(y, x);
@@ -580,6 +587,8 @@ double __XL(strtod)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #endif
 }
 
+__XL_ALIAS(strtod)
+
 #endif
 #endif
 /**********************************************************************/
@@ -589,6 +598,8 @@ double __XL(strtod)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #if defined(L_wcstold) || defined(L_wcstold_l)
 #define strtold           wcstold
 #define strtold_l         wcstold_l
+#define __strtold         __wcstold
+#define __strtold_l       __wcstold_l
 #define __strtofpmax     __wcstofpmax
 #define __strtofpmax_l   __wcstofpmax_l
 #define Wchar wchar_t
@@ -599,12 +610,12 @@ double __XL(strtod)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 long double __XL(strtold)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 {
 #if FPMAX_TYPE == 3
-	return __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	return __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 #else
 	__fpmax_t x;
 	long double y;
 
-	x = __XL(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
+	x = __XL_NPP(__strtofpmax)(str, endptr, 0   __LOCALE_ARG );
 	y = (long double) x;
 
 	__fp_range_check(y, x);
@@ -613,6 +624,8 @@ long double __XL(strtold)(const Wchar *str, Wchar **endptr   __LOCALE_PARAM )
 #endif
 }
 
+__XL_ALIAS(strtold)
+
 #endif
 #endif
 /**********************************************************************/

+ 23 - 9
libc/string/wstring.c

@@ -1087,8 +1087,9 @@ int ffs(int i)
 
 #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)
+#define TOLOWER(C) __towlower_l((C), locale_arg)
 #else
 #define TOLOWER(C) towlower((C))
 #endif
@@ -1096,7 +1097,7 @@ int ffs(int i)
 #else  /* defined(L_wcscasecmp) || defined(L_wcscasecmp_l) */
 
 #ifdef __UCLIBC_DO_XLOCALE
-#define TOLOWER(C) tolower_l((C), locale_arg)
+#define TOLOWER(C) __tolower_l((C), locale_arg)
 #else
 #define TOLOWER(C) tolower((C))
 #endif
@@ -1108,7 +1109,7 @@ int ffs(int i)
 
 int strcasecmp(register const Wchar *s1, register const Wchar *s2)
 {
-	return strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
+	return __strcasecmp_l(s1, s2, __UCLIBC_CURLOCALE);
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1138,6 +1139,8 @@ int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
 #endif
 }
 
+__XL_ALIAS(strcasecmp)
+
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
 
 #endif
@@ -1148,8 +1151,9 @@ int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
 
 #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)
+#define TOLOWER(C) __towlower_l((C), locale_arg)
 #else
 #define TOLOWER(C) towlower((C))
 #endif
@@ -1157,7 +1161,7 @@ int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
 #else  /* defined(L_wcsncasecmp) || defined(L_wcsncasecmp_l) */
 
 #ifdef __UCLIBC_DO_XLOCALE
-#define TOLOWER(C) tolower_l((C), locale_arg)
+#define TOLOWER(C) __tolower_l((C), locale_arg)
 #else
 #define TOLOWER(C) tolower((C))
 #endif
@@ -1169,7 +1173,7 @@ int __XL(strcasecmp)(register const Wchar *s1, register const Wchar *s2
 
 int strncasecmp(register const Wchar *s1, register const Wchar *s2, size_t n)
 {
-	return strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
+	return __strncasecmp_l(s1, s2, n, __UCLIBC_CURLOCALE);
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -1202,6 +1206,8 @@ int __XL(strncasecmp)(register const Wchar *s1, register const Wchar *s2,
 #endif
 }
 
+__XL_ALIAS(strncasecmp)
+
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
 
 #endif
@@ -2311,8 +2317,10 @@ void psignal(int signum, register const char *message)
 
 #define wcscoll   strcoll
 #define wcscoll_l strcoll_l
+#define __wcscoll_l __strcoll_l
 #define wcsxfrm   strxfrm
 #define wcsxfrm_l strxfrm_l
+#define __wcsxfrm_l __strxfrm_l
 
 #undef WANT_WIDE
 #undef Wvoid
@@ -2328,12 +2336,12 @@ void psignal(int signum, register const char *message)
 
 int wcscoll (const Wchar *s0, const Wchar *s1)
 {
-	return wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
+	return __wcscoll_l(s0, s1, __UCLIBC_CURLOCALE );
 }
 
 size_t wcsxfrm(Wchar *__restrict ws1, const Wchar *__restrict ws2, size_t n)
 {
-	return wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
+	return __wcsxfrm_l(ws1, ws2, n, __UCLIBC_CURLOCALE );
 }
 
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */
@@ -2387,7 +2395,7 @@ typedef struct {
 
 #undef TRACE
 #if 0
-#define TRACE(X)	printf##X
+#define TRACE(X)	printf X
 #else
 #define TRACE(X)	((void)0)
 #endif
@@ -2806,6 +2814,8 @@ int __XL(wcscoll) (const Wchar *s0, const Wchar *s1   __LOCALE_PARAM )
 	return 0;
 }
 
+__XL_ALIAS(wcscoll)
+
 #ifdef WANT_WIDE
 
 size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
@@ -2846,6 +2856,8 @@ size_t __XL(wcsxfrm)(wchar_t *__restrict ws1, const wchar_t *__restrict ws2,
 	return count-1;
 }
 
+__XL_ALIAS(wcsxfrm)
+
 #else  /* WANT_WIDE */
 
 static const unsigned long bound[] = {
@@ -2926,6 +2938,8 @@ size_t __XL(strxfrm)(char *__restrict ws1, const char *__restrict ws2, size_t n
 	return count-1;
 }
 
+__XL_ALIAS(strxfrm)
+
 #endif /* WANT_WIDE */
 
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */

+ 7 - 4
libc/sysdeps/linux/common/bits/uClibc_locale.h

@@ -41,6 +41,8 @@
 #define __LOCALE_C_ONLY 
 
 #define __XL(N) N
+#define __XL_NPP(N) N
+#define __XL_ALIAS(N)
 #define __LOCALE_PARAM
 #define __LOCALE_ARG
 
@@ -345,7 +347,9 @@ extern __locale_t __curlocale_set(__locale_t newloc);
 /**********************************************************************/
 #if defined(__UCLIBC_HAS_XLOCALE__) && defined(__UCLIBC_DO_XLOCALE)
 
-#define __XL(N) N ## _l
+#define __XL(N) __ ## N ## _l
+#define __XL_NPP(N) N ## _l
+#define __XL_ALIAS(N) weak_alias( __ ## N ## _l , N ## _l )
 #define __LOCALE_PARAM    , __locale_t locale_arg
 #define __LOCALE_ARG      , locale_arg
 #define __LOCALE_PTR      locale_arg
@@ -353,6 +357,8 @@ extern __locale_t __curlocale_set(__locale_t newloc);
 #else  /* defined(__UCLIBC_HAS_XLOCALE__) && defined(__STDLIB_DO_XLOCALE) */
 
 #define __XL(N) N
+#define __XL_NPP(N) N
+#define __XL_ALIAS(N)
 #define __LOCALE_PARAM
 #define __LOCALE_ARG
 #define __LOCALE_PTR      __UCLIBC_CURLOCALE
@@ -360,9 +366,6 @@ extern __locale_t __curlocale_set(__locale_t newloc);
 #endif /* defined(__UCLIBC_HAS_XLOCALE__) && defined(__STDLIB_DO_XLOCALE) */
 /**********************************************************************/
 
-extern __locale_t __newlocale(int category_mask, const char *locale, __locale_t base)
-	 __THROW;
-
 #endif /* defined(_LIBC) && !defined(__LOCALE_C_ONLY) */
 /**********************************************************************/
 

+ 1 - 0
libintl/.cvsignore

@@ -0,0 +1 @@
+libintl.so*

+ 66 - 0
libintl/Makefile

@@ -0,0 +1,66 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000 by Lineo, inc.
+# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Library General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Library General Public License
+# along with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# Derived in part from the Linux-8086 C library, the GNU C Library, and several
+# other sundry sources.  Files within this library are copyright by their
+# respective copyright holders.
+
+TOPDIR=../
+include $(TOPDIR)Rules.mak
+LIBC=$(TOPDIR)libc.a
+
+LIBINTL=libintl.a
+LIBINTL_SHARED=libintl.so
+LIBINTL_SHARED_FULLNAME=libintl-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
+
+MSRC= intl.c
+MOBJ= gettext.o ngettext.o  dgettext.o dcgettext.o dngettext.o dcngettext.o \
+	textdomain.o bindtextdomain.o bind_textdomain_codeset.o \
+	_nl_expand_alias.o _nl_msg_cat_cntr.o # glibc-isms
+
+OBJS=$(MOBJ)
+
+all: $(OBJS) $(LIBC)
+
+$(LIBC): ar-target
+
+ar-target: $(OBJS)
+	$(AR) $(ARFLAGS) $(LIBINTL) $(OBJS)
+	install -d $(TOPDIR)lib
+	rm -f $(TOPDIR)lib/$(LIBINTL)
+	install -m 644 $(LIBINTL) $(TOPDIR)lib/
+
+$(MOBJ): $(MSRC)
+	$(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+	$(STRIPTOOL) -x -R .note -R .comment $*.o
+
+shared: all
+	$(LD) $(LDFLAGS) -soname=$(LIBINTL_SHARED).$(MAJOR_VERSION) \
+		-o $(LIBINTL_SHARED_FULLNAME) --whole-archive $(LIBINTL) \
+		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
+		-L$(TOPDIR)/lib -lc;
+	install -d $(TOPDIR)lib
+	rm -f $(TOPDIR)lib/$(LIBINTL_SHARED_FULLNAME) $(TOPDIR)lib/$(LIBINTL_SHARED).$(MAJOR_VERSION)
+	install -m 644 $(LIBINTL_SHARED_FULLNAME) $(TOPDIR)lib/;
+	(cd $(TOPDIR)lib && ln -sf $(LIBINTL_SHARED_FULLNAME) $(LIBINTL_SHARED)); 
+	(cd $(TOPDIR)lib && ln -sf $(LIBINTL_SHARED_FULLNAME) $(LIBINTL_SHARED).$(MAJOR_VERSION)); 
+
+clean:
+	rm -f *.[oa] *~ core $(LIBINTL_SHARED)* $(LIBINTL_SHARED_FULLNAME)*
+

+ 166 - 0
libintl/intl.c

@@ -0,0 +1,166 @@
+/*  Copyright (C) 2003     Manuel Novoa III
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  Stub version of libintl.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#undef __OPTIMIZE__
+#include <libintl.h>
+
+/**********************************************************************/
+#ifdef L_gettext
+
+char *gettext(const char *msgid)
+{
+	return (char *) msgid;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_dgettext
+
+char *__dgettext(const char *domainname,
+				 const char *msgid)
+{
+	return (char *) msgid;
+}
+
+weak_alias (__dgettext, dgettext)
+
+#endif
+/**********************************************************************/
+#ifdef L_dcgettext
+
+char * __dcgettext(const char *domainname,
+				   const char *msgid, int category)
+{
+	return (char *) msgid;
+}
+
+weak_alias (__dcgettext, dcgettext)
+
+#endif
+/**********************************************************************/
+#ifdef L_ngettext
+
+char *ngettext(const char *msgid1, const char *msgid2,
+							 unsigned long int n)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_dngettext
+
+char *dngettext(const char *domainname, const char *msgid1,
+							  const char *msgid2, unsigned long int n)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_dcngettext
+
+char *dcngettext(const char *domainname, const char *msgid1,
+							   const char *msgid2, unsigned long int n,
+							   int category)
+{
+	return (char *) ((n == 1) ? msgid1 : msgid2);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_textdomain
+
+char *textdomain(const char *domainname)
+{
+	static const char default_str[] = "messages";
+
+	if (domainname && *domainname && strcmp(domainname, default_str)) {
+		__set_errno(EINVAL);
+		return NULL;
+	}
+	return (char *) default_str;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_bindtextdomain
+
+char *bindtextdomain(const char *domainname, const char *dirname)
+{
+	static const char dir[] = "/";
+
+	if (!domainname || !*domainname
+		|| (dirname
+#if 1
+			&& ((dirname[0] != '/') || dirname[1])
+#else
+			&& strcmp(dirname, dir)
+#endif
+			)
+		) {
+		__set_errno(EINVAL);
+		return NULL;
+	}
+
+	return (char *) dir;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_bind_textdomain_codeset
+
+/* Specify the character encoding in which the messages from the
+   DOMAINNAME message catalog will be returned.  */
+char *bind_textdomain_codeset(const char *domainname,
+											const char *codeset)
+{
+	if (!domainname || !*domainname || codeset) {
+		__set_errno(EINVAL);
+	}
+	return NULL;
+}
+
+#endif
+/**********************************************************************/
+#ifdef L__nl_expand_alias
+
+/* glibc-ism */
+
+const char *_nl_expand_alias(const char * name)
+{
+	return NULL;				/* uClibc does not support locale aliases. */
+}
+
+#endif
+/**********************************************************************/
+#ifdef L__nl_msg_cat_cntr
+
+/* glibc-ism */
+
+int _nl_msg_cat_cntr = 0;
+
+#endif
+/**********************************************************************/