about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog58
-rw-r--r--config.make.in1
-rwxr-xr-xconfigure1
-rw-r--r--configure.in1
-rw-r--r--inet/Makefile4
-rw-r--r--inet/inet_net.c8
-rw-r--r--inet/tst-network.c73
-rw-r--r--intl/Makefile2
-rw-r--r--linuxthreads/condvar.c95
-rw-r--r--locale/C-monetary.c4
-rw-r--r--locale/C-numeric.c4
-rw-r--r--locale/indigitswc.h4
-rw-r--r--localedata/CHECKSUMS239
-rw-r--r--localedata/Makefile3
-rw-r--r--localedata/charmaps/IBM8642
-rw-r--r--localedata/charmaps/ISO-8859-84
-rw-r--r--localedata/charmaps/ISO-IR-902
-rw-r--r--localedata/charmaps/NEXTSTEP5
-rw-r--r--misc/syslog.c3
-rw-r--r--stdio-common/printf-parse.h1
-rw-r--r--stdio-common/printf_fp.c347
-rw-r--r--stdio-common/printf_size.c47
-rw-r--r--stdio-common/vfscanf.c150
-rw-r--r--stdlib/canonicalize.c8
-rw-r--r--sysdeps/arm/fpu/fpu_control.h2
-rw-r--r--sysdeps/generic/printf_fphex.c155
-rw-r--r--sysdeps/ieee754/ldbl-96/printf_fphex.c24
-rw-r--r--sysdeps/unix/sysv/linux/configure2
-rw-r--r--sysdeps/unix/sysv/linux/configure.in2
29 files changed, 849 insertions, 402 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ebb8ea183..13282cca2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,61 @@
+2000-02-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* stdio-common/printf-parse.h (parse_one_spec): Set wide elements.
+
+	* stdio-common/printf_fp.c: Truely support wide characater output.
+	Finally handle decimal points and thousands separator characters
+	correctly for multibyte output.
+	* stdio-common/printf_size.c: Likewise.
+	* sysdeps/generic/printf_fphex.c: Likewise.
+	* sysdeps/ieee754/ldbl-96/printf_fphex.c: Likewise.
+
+	* stdio-common/vfscanf.c: Implement I modifier for numbers to read
+	locale dependent digits.
+
+	* locale/C-monetary.c (_nl_C_LC_MONETARY): Change wide character
+	decimal point and thousands separator values to wide characters from
+	wide character strings.
+	* locale/C-numeric.c (_nl_C_LC_NUMERIC): Likewise.
+
+	* locale/indigitswc.h: Dereference wcdigits array elements.
+
+2000-02-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* stdlib/canonicalize.c (canonicalize): Zero terminate
+	path to copy on error.
+
+2000-02-01  Cristian Gafton  <gafton@redhat.com>
+
+	* misc/syslog.c (closelog): Reset LogType to SOCK_DGRAM.
+
+2000-01-31  Philip Blundell  <philb@gnu.org>
+
+	* sysdeps/arm/fpu/fpu_control.h (_FPU_DEFAULT): Set the AC bit.
+
+2000-01-31  Andreas Jaeger  <aj@suse.de>
+
+	* intl/Makefile (generated): msgs.h is generated.
+
+	* localedata/Makefile (generated-dirs): Add de_DE.437.
+
+2000-01-31  Jakub Jelinek  <jakub@redhat.com>
+
+	* config.make.in: Allow default localedir to come from configure.
+	* configure.in: Export libc_cv_localedir.
+	* sysdeps/unix/sysv/linux/configure.in: For sparc64, put locale
+	stuff into $exec_prefix/lib/locale because it can be shared between
+	32bit and 64bit libraries.
+	* configure: Rebuilt.
+	* sysdeps/unix/sysv/linux/configure: Rebuilt.
+
+2000-01-31  Andreas Jaeger  <aj@suse.de>
+
+	* inet/tst-network.c: New file.
+	* inet/Makefile (tests): Add tst-network.
+
+	* inet/inet_net.c (inet_network): Don't overwrite memory or allow
+	to great last digits.
+
 2000-02-10  Andreas Jaeger  <aj@suse.de>
 
 	* sysdeps/unix/sysv/linux/mips/clone.S: Rewritten.
diff --git a/config.make.in b/config.make.in
index 727ae3c430..9c58330aff 100644
--- a/config.make.in
+++ b/config.make.in
@@ -12,6 +12,7 @@ exec_prefix = @exec_prefix@
 datadir = @datadir@
 libdir = @libdir@
 slibdir = @libc_cv_slibdir@
+localedir = @libc_cv_localedir@
 sysconfdir = @libc_cv_sysconfdir@
 libexecdir = @libexecdir@
 rootsbindir = @libc_cv_rootsbindir@
diff --git a/configure b/configure
index d0b52adc65..0e17eb4cc4 100755
--- a/configure
+++ b/configure
@@ -3475,6 +3475,7 @@ s%@uname_version@%$uname_version%g
 s%@stdio@%$stdio%g
 s%@old_glibc_headers@%$old_glibc_headers%g
 s%@libc_cv_slibdir@%$libc_cv_slibdir%g
+s%@libc_cv_localedir@%$libc_cv_localedir%g
 s%@libc_cv_sysconfdir@%$libc_cv_sysconfdir%g
 s%@libc_cv_rootsbindir@%$libc_cv_rootsbindir%g
 s%@use_ldconfig@%$use_ldconfig%g
diff --git a/configure.in b/configure.in
index 4e44f1ed45..f2a0e1a3f9 100644
--- a/configure.in
+++ b/configure.in
@@ -1283,6 +1283,7 @@ fi
 AC_SUBST(old_glibc_headers)
 
 AC_SUBST(libc_cv_slibdir)
+AC_SUBST(libc_cv_localedir)
 AC_SUBST(libc_cv_sysconfdir)
 AC_SUBST(libc_cv_rootsbindir)
 
diff --git a/inet/Makefile b/inet/Makefile
index d28e226ef4..945f8e50a8 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+# Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -48,7 +48,7 @@ routines := htonl htons		\
 	    in6_addr getnameinfo if_index getipnodebyad freehostent \
 	    getipnodebynm
 
-tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-ipnode
+tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-ipnode tst-network
 
 # No warnings about losing BSD code.
 CFLAGS-rcmd.c = -w
diff --git a/inet/inet_net.c b/inet/inet_net.c
index cdc4d9dd96..78d22cda6b 100644
--- a/inet/inet_net.c
+++ b/inet/inet_net.c
@@ -66,7 +66,7 @@ again:
 			continue;
 		}
 		if (base == 16 && isxdigit(c)) {
-			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
+			val = (val << 4) + (tolower (c) + 10 - 'a');
 			cp++;
 			digit = 1;
 			continue;
@@ -75,9 +75,9 @@ again:
 	}
 	if (!digit)
 		return (INADDR_NONE);
+	if (pp >= parts + 4 || val > 0xff)
+		return (INADDR_NONE);
 	if (*cp == '.') {
-		if (pp >= parts + 4 || val > 0xff)
-			return (INADDR_NONE);
 		*pp++ = val, cp++;
 		goto again;
 	}
@@ -85,8 +85,6 @@ again:
 		return (INADDR_NONE);
 	*pp++ = val;
 	n = pp - parts;
-	if (n > 4)
-		return (INADDR_NONE);
 	for (val = 0, i = 0; i < n; i++) {
 		val <<= 8;
 		val |= parts[i] & 0xff;
diff --git a/inet/tst-network.c b/inet/tst-network.c
new file mode 100644
index 0000000000..09e102506d
--- /dev/null
+++ b/inet/tst-network.c
@@ -0,0 +1,73 @@
+/* Test for inet_network.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Andreas Jaeger <aj@suse.de>, 2000.
+
+   The GNU C 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.
+
+   The GNU C 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 the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+struct
+{
+  const char *network;
+  uint32_t number;
+} tests [] =
+{
+  {"1.0.0.0", 0x1000000},
+  {"1.0.0", 0x10000},
+  {"1.0", 0x100},
+  {"1", 0x1},
+  {"192.168.0.0", 0xC0A80000},
+  /* Now some invalid addresses.  */
+  {"141.30.225.2800", INADDR_NONE},
+  {"141.76.1.1.1", INADDR_NONE},
+  {"141.76.1.11.", INADDR_NONE},
+  {"1410", INADDR_NONE},
+  {"1.1410", INADDR_NONE},
+  {"1.1410.", INADDR_NONE},
+  {"1.1410", INADDR_NONE},
+  {"141.76.1111", INADDR_NONE},
+  {"141.76.1111.", INADDR_NONE}
+};
+
+
+int
+main (void)
+{
+  int errors = 0;
+  int i;
+  uint32_t res;
+
+  for (i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i)
+    {
+      printf ("Testing: %s\n", tests[i].network);
+      res = inet_network (tests[i].network);
+
+      if (res != tests[i].number)
+	{
+	  printf ("Test failed for inet_network (\"%s\"):\n",
+		  tests[i].network);
+	  printf ("Expected return value %u (0x%x) but got %u (0x%x).\n",
+		  tests[i].number, tests[i].number, res, res);
+	}
+
+    }
+
+  return errors != 0;
+}
diff --git a/intl/Makefile b/intl/Makefile
index ce7b15b8c7..7b40f2e432 100644
--- a/intl/Makefile
+++ b/intl/Makefile
@@ -33,6 +33,8 @@ before-compile = $(objpfx)msgs.h
 
 install-others = $(inst_msgcatdir)/locale.alias
 
+generated = msgs.h
+
 plural.c: plural.y
 	$(YACC) $(YFLAGS) $@ $^
 ifeq ($(with-cvs),yes)
diff --git a/linuxthreads/condvar.c b/linuxthreads/condvar.c
index 5f0e1939d3..c0c619992d 100644
--- a/linuxthreads/condvar.c
+++ b/linuxthreads/condvar.c
@@ -26,13 +26,13 @@
 #include "restart.h"
 
 static int pthread_cond_timedwait_relative_old(pthread_cond_t *,
-    pthread_mutex_t *, const struct timespec *);
+    pthread_mutex_t *, struct timespec *);
 
 static int pthread_cond_timedwait_relative_new(pthread_cond_t *,
-    pthread_mutex_t *, const struct timespec *);
+    pthread_mutex_t *, struct timespec *);
 
 static int (*pthread_cond_tw_rel)(pthread_cond_t *, pthread_mutex_t *,
-    const struct timespec *) = pthread_cond_timedwait_relative_old;
+    struct timespec *) = pthread_cond_timedwait_relative_old;
 
 /* initialize this module */
 void __pthread_init_condvar(int rt_sig_available)
@@ -130,32 +130,14 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
 static int
 pthread_cond_timedwait_relative_old(pthread_cond_t *cond,
 				pthread_mutex_t *mutex,
-				const struct timespec * abstime)
+				struct timespec * reltime)
 {
   volatile pthread_descr self = thread_self();
   sigset_t unblock, initial_mask;
-  int retsleep, already_canceled, was_signalled;
+  int already_canceled = 0;
+  int was_signalled = 0;
   sigjmp_buf jmpbuf;
   pthread_extricate_if extr;
-  struct timeval now;
-  struct timespec reltime;
-
-requeue_and_wait_again:
-
-  /* Compute a time offset relative to now.  */
-  __gettimeofday (&now, NULL);
-  reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
-  reltime.tv_sec = abstime->tv_sec - now.tv_sec;
-  if (reltime.tv_nsec < 0) {
-    reltime.tv_nsec += 1000000000;
-    reltime.tv_sec -= 1;
-  }
-  if (reltime.tv_sec < 0)
-    return ETIMEDOUT;
-
-  retsleep = 0;
-  already_canceled = 0;
-  was_signalled = 0;
 
   /* Set up extrication interface */
   extr.pu_object = cond;
@@ -191,13 +173,14 @@ requeue_and_wait_again:
       sigemptyset(&unblock);
       sigaddset(&unblock, __pthread_sig_restart);
       sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
-      /* Sleep for the required duration */
-      retsleep = __libc_nanosleep(&reltime, NULL);
+      /* Sleep for the required duration. If woken by a signal, resume waiting
+	 as required by Single Unix Specification.  */
+      while (__libc_nanosleep(reltime, reltime) != 0)
+	;
       /* Block the restart signal again */
       sigprocmask(SIG_SETMASK, &initial_mask, NULL);
       was_signalled = 0;
     } else {
-      retsleep = -1;
       was_signalled = 1;
     }
     THREAD_SETMEM(self, p_signal_jmp, NULL);
@@ -229,12 +212,7 @@ requeue_and_wait_again:
       if (was_on_queue) {
 	__pthread_set_own_extricate_if(self, 0);
 	pthread_mutex_lock(mutex);
-
-	if (retsleep == 0)
-	  return ETIMEDOUT;
-	/* Woken by a signal: resume waiting as required by Single Unix
-	   Specification.  */
-	goto requeue_and_wait_again;
+	return ETIMEDOUT;
       }
 
       suspend(self);
@@ -263,30 +241,15 @@ requeue_and_wait_again:
 static int
 pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
 				pthread_mutex_t *mutex,
-				const struct timespec * abstime)
+				struct timespec * reltime)
 {
   volatile pthread_descr self = thread_self();
   sigset_t unblock, initial_mask;
-  int retsleep, already_canceled, was_signalled;
+  int already_canceled = 0;
+  int was_signalled = 0;
   sigjmp_buf jmpbuf;
   pthread_extricate_if extr;
-  struct timeval now;
-  struct timespec reltime;
 
- requeue_and_wait_again:
-
-  /* Compute a time offset relative to now.  */
-  __gettimeofday (&now, NULL);
-  reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
-  reltime.tv_sec = abstime->tv_sec - now.tv_sec;
-  if (reltime.tv_nsec < 0) {
-    reltime.tv_nsec += 1000000000;
-    reltime.tv_sec -= 1;
-  }
-  if (reltime.tv_sec < 0)
-    return ETIMEDOUT;
-
-  retsleep = 0;
   already_canceled = 0;
   was_signalled = 0;
 
@@ -323,13 +286,14 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
     sigemptyset(&unblock);
     sigaddset(&unblock, __pthread_sig_restart);
     sigprocmask(SIG_UNBLOCK, &unblock, &initial_mask);
-    /* Sleep for the required duration */
-    retsleep = __libc_nanosleep(&reltime, NULL);
+    /* Sleep for the required duration. If woken by a signal, resume waiting
+       as required by Single Unix Specification.  */
+    while (__libc_nanosleep(reltime, reltime) != 0)
+      ;
     /* Block the restart signal again */
     sigprocmask(SIG_SETMASK, &initial_mask, NULL);
     was_signalled = 0;
   } else {
-    retsleep = -1;
     was_signalled = 1;
   }
   THREAD_SETMEM(self, p_signal_jmp, NULL);
@@ -358,12 +322,7 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
     if (was_on_queue) {
       __pthread_set_own_extricate_if(self, 0);
       pthread_mutex_lock(mutex);
-
-      if (retsleep == 0)
-	return ETIMEDOUT;
-      /* Woken by a signal: resume waiting as required by Single Unix
-	 Specification.  */
-      goto requeue_and_wait_again;
+      return ETIMEDOUT;
     }
 
     /* Eat the outstanding restart() from the signaller */
@@ -389,8 +348,22 @@ pthread_cond_timedwait_relative_new(pthread_cond_t *cond,
 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
                            const struct timespec * abstime)
 {
+  struct timeval now;
+  struct timespec reltime;
+
+  /* Compute a time offset relative to now.  */
+  __gettimeofday (&now, NULL);
+  reltime.tv_nsec = abstime->tv_nsec - now.tv_usec * 1000;
+  reltime.tv_sec = abstime->tv_sec - now.tv_sec;
+  if (reltime.tv_nsec < 0) {
+    reltime.tv_nsec += 1000000000;
+    reltime.tv_sec -= 1;
+  }
+  if (reltime.tv_sec < 0)
+    return ETIMEDOUT;
+
   /* Indirect call through pointer! */
-  return pthread_cond_tw_rel(cond, mutex, abstime);
+  return pthread_cond_tw_rel(cond, mutex, &reltime);
 }
 
 int pthread_cond_signal(pthread_cond_t *cond)
diff --git a/locale/C-monetary.c b/locale/C-monetary.c
index 6c7b4587f9..96a1e52f25 100644
--- a/locale/C-monetary.c
+++ b/locale/C-monetary.c
@@ -78,7 +78,7 @@ const struct locale_data _nl_C_LC_MONETARY =
     { word: 99991231 },
     { word: 1 },
     { word: 1 },
-    { wstr: (uint32_t *) L"." },
-    { wstr: (uint32_t *) L"" }
+    { word: (unsigned int) L'.' },
+    { word: (unsigned int) L'\0' }
   }
 };
diff --git a/locale/C-numeric.c b/locale/C-numeric.c
index 00c692799f..fc2e104304 100644
--- a/locale/C-numeric.c
+++ b/locale/C-numeric.c
@@ -37,7 +37,7 @@ const struct locale_data _nl_C_LC_NUMERIC =
     { string: "." },
     { string: "" },
     { string: not_available },
-    { wstr: (uint32_t *) L"." },
-    { wstr: (uint32_t *) L"" }
+    { word: (unsigned int) L'.' },
+    { word: (unsigned int) L'\0' }
   }
 };
diff --git a/locale/indigitswc.h b/locale/indigitswc.h
index 8afbb7ea17..7bd871527e 100644
--- a/locale/indigitswc.h
+++ b/locale/indigitswc.h
@@ -49,7 +49,7 @@ indigitwc_value (wchar_t wc, int *decided)
       /* Get the string for the digits with value N.  */
       wcdigits[n] = _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
 
-      if (wc == wcdigits[n])
+      if (wc == *wcdigits[n])
 	{
 	  /* Found it.  */
 	  if (*decided == -1)
@@ -67,7 +67,7 @@ indigitwc_value (wchar_t wc, int *decided)
       /* Search all ten digits of this level.  */
       for (n = 0; n < 10; ++n)
 	{
-	  if (wc == wcdigits[n])
+	  if (wc == *wcdigits[n])
 	    {
 	      /* Found it.  */
 	      if (*decided == -1)
diff --git a/localedata/CHECKSUMS b/localedata/CHECKSUMS
index c48253e4fe..2fcf41d4e3 100644
--- a/localedata/CHECKSUMS
+++ b/localedata/CHECKSUMS
@@ -1,17 +1,103 @@
+97ec3e0e5a02ba50bf034cfcdea6469d  locales/POSIX
+2ac9c8dab200035ab30329e025ae29be  locales/af_ZA
+dc560d0dd71ca1cf4b3a3f422fe03b14  locales/ca_ES
+e2b2c79ac083d3c7151e9ede9360f6c0  locales/cs_CZ
+6ed0464590918f9b59731ea8b762900d  locales/da_DK
+3c1e78eeb968fa5ef49b2672fe3da756  locales/de_AT
+6ee0be7a3b0033b35719419a9d84b27f  locales/de_BE
+89ff8fb9bb9d2ea2fbfd409baccd7f59  locales/de_CH
+693b60488445f63d15207cd407884345  locales/de_DE
+969062eb7dd2196ae96c26b837f77591  locales/de_LU
+9a10c3ac70ab2d0d26ea2e8921199665  locales/el_GR
+1df05f9450263138fd5d4ee513642310  locales/en_AU
+0271ab37e58ddb29733ab3f89789f10c  locales/en_BW
+bafe0469ff4621636a90e72acebb6f93  locales/en_CA
+688ec6a92b152ec3dfad2c52d7fd61ea  locales/en_CA,2.5
+172ca6f82d8dfb3edd86ddf51e157a1e  locales/en_DK
+94cd32fd51aa57d42255b9aa8ab7cee3  locales/en_DK.com
+8f322dd28903682c6a80a4a96861dc59  locales/en_GB
+aee81bf8761ef1e38f6adc39e5846b17  locales/en_IE
+e6accbc3458eba9e23156e99ce700439  locales/en_NZ
+e7e3223904043d185087bbb13bbc6e97  locales/en_US
+21fd1816ee6f32b6777d90222d660be3  locales/en_ZA
+d82de853fcd448dfd1a7e5d2bb114daf  locales/en_ZW
+b2f02bb97de06de5a14bb4cc11877ad7  locales/es_AR
+41630e6e8f5a164fa90e10b202cc3eaf  locales/es_BO
+b21ac1fea9726a62d7306d63e646c990  locales/es_CL
+8e3752256da403c9a9d66680deed45c8  locales/es_CO
+915aa3b6b7c73ffa00ceda87b8589495  locales/es_DO
+01175f59670c47e8bb62553c62d480ee  locales/es_EC
+c9df76a675c75ab0000057ffcf826aee  locales/es_ES
+0085a8fee4c77cfa02e5b2a700fa30d4  locales/es_GT
+de8e51deed4c7bf897cf886fea7772d6  locales/es_HN
+e07278e9fb181fd32e1a89f2025a43b7  locales/es_MX
+0f4c8e46eb4790f598137678ace1887c  locales/es_PA
+15decb57c2ce997e76e6c5c217c44d1d  locales/es_PE
+1e7d8a5c9f0abb506e3b7128a3f28980  locales/es_PY
+69dd105d588ef12726c51735d94e2d59  locales/es_SV
+97c3c0374bdd90fba624e0aa46bdb745  locales/es_US
+e24d7f66ec0f5fbbca742be937d680b5  locales/es_UY
+05d4a96a70ccaecd3472a1e9b40db513  locales/es_VE
+55b992cdb4b9adf72df968881a55045c  locales/et_EE
+4d85ff4728e48450e1ae4f371c1fd12e  locales/eu_ES
+b921bf84d560d5ab06111807981748e9  locales/fa_IR
+7fc821e07d7e228535dcc2b6c4fce8f1  locales/fi_FI
+35d631cc21c7cc9d1ce2933e1d94d81a  locales/fo_FO
+419d0507292b954a0cee5be020771b00  locales/fr_BE
+d9e85f9c1dc5d2d9396afac293f0553c  locales/fr_CA
+c1836dfa41f6eb43dc90900d2cd9b341  locales/fr_CA,2.13
+47b866d8e108070ebc393f18e5a11618  locales/fr_CH
+1d63fde6acfdc6c0dc03b36098a9f5ab  locales/fr_FR
+8c17257001e3d33e8ab8c5dc9fae87a7  locales/fr_LU
+fe6ba034da4ce416f480a11a0b1f7356  locales/ga_IE
+37dc43894af12d76a399af38ec3b848e  locales/gl_ES
+e5730342b747e9445b6448792d39d121  locales/he_IL
+8264c2cdffbead098d797ea1d861753f  locales/hr_HR
+70ea8a47c5e1ea1af40fe059795108f6  locales/hu_HU
+0d145a65dfa353f93f78090719cb086d  locales/id_ID
+d1089f83e82d9ea9256a82cd4b883a72  locales/in_ID
+c96cc2c4f753f6641d2744eb762dc4e3  locales/is_IS
+48252394b6e3f50cfcf00510eacd3683  locales/it_CH
+69b619bf7fad926c3c04349f1a316d0d  locales/it_IT
+e5730342b747e9445b6448792d39d121  locales/iw_IL
+934faede9009fc486fc7453c16084aba  locales/ja_JP
+2f97cb36f71528ce4dda636ddb96d0c5  locales/kl_GL
+880237172b8700c9645dd0cee6ad3a59  locales/ko_KR
+c7e3b3446446aa0e9fcc6dd1bdee6a5d  locales/lt_LT
+b93e2cb7a11c1fbd22d0427aab4922d0  locales/lv_LV
+5be9df64a7bf8669701f0f9983dc1004  locales/nl_BE
+4d58de18535a2e1f98e6985d4fa5b671  locales/nl_NL
+ed41a02e1c2aec4eddc42fe7b5702bf4  locales/no_NO
+83bf7b71dd5b09e267d9e69d37bc8883  locales/pl_PL
+7e40f55558927e1754744a5b705d5089  locales/pt_BR
+3ed6e5080462030ceb847ef241ee1352  locales/pt_PT
+33324d57567944135cadec56b4b1e77d  locales/ro_RO
+b4e8ac2dea2a3c736befb854c4edf45b  locales/ru_RU
+2be354a9d753a14159067f4e98437bb4  locales/ru_UA
+e138da41f8586445c277a761ca2fc7df  locales/sk_SK
+18408da663b6c4498c06d844ef14ae1b  locales/sl_SI
+d1aefa7d8bb6354743b0e386fcbb0652  locales/sr_YU
+2c1087e408f00e70320ca5e4efd80617  locales/sv_FI
+c4e59d821962d68097175242220427ea  locales/sv_SE
+669ade381cccccd0a3fac10bec9a2917  locales/th_TH
+f9ac3ea566e659cdcbc6dde43d7655fd  locales/tr_TR
+d10211b77b9c19fd04080e9df5b03bf5  locales/uk_UA
+d3d797491b67d7207ea1bf00204515d2  locales/zh_CN
 0e7fdb8285e9ca6113454ce247d3863c  charmaps/ANSI_X3.110-1983
 a586da90c49cd6875b8238a8878a7591  charmaps/ANSI_X3.4-1968
 5f18526bbba0326cf6af1861bcac141f  charmaps/ASMO_449
 a9f7051d90b3cd83bc0ad8bd7bae0b02  charmaps/BALTIC
 8e1e15a295bd169737f22dc53f08ab0b  charmaps/BS_4730
 93f30925bb39086d37e66e4d185ec84b  charmaps/BS_VIEWDATA
-41d1dc3ded4f1e379fa92bd3fcf5c35d  charmaps/CP1250
-de9e81aa6857f6904b8d8e48e199151b  charmaps/CP1251
-4295ced14d537e63d55c27a50f60fd65  charmaps/CP1252
-97bd97f3ca917489edfa63dbd3977255  charmaps/CP1253
-20cb2f279747e4f892f793b7ee0055c2  charmaps/CP1254
-a7a5467df241ffb55f8247bbf9f12ad5  charmaps/CP1255
-7d5cfac2ef35027f4c634cba8c43b4cc  charmaps/CP1256
-a8dc97d22ade3ee0a8cd8c7122bd4f18  charmaps/CP1257
+a907a00ba93ea9f46154cf3a80818e70  charmaps/CP1250
+2a92a00cd906127843d519aa937bf0c9  charmaps/CP1251
+10e2330202c5b24766d4d04ec46a56c1  charmaps/CP1252
+e26ab9843d95b3d200d94cf76981d09d  charmaps/CP1253
+c31e2cbcee34f148786ca38c0a5570d2  charmaps/CP1254
+0c8a06d02ed67967129d6f7496d24b15  charmaps/CP1255
+f861218a23625c411f6e736e9ae7a6fa  charmaps/CP1256
+bb9b52bfe2d51434c2d02755153ad215  charmaps/CP1257
+a6497ae372e62cc7b92c3cfd33efd5a0  charmaps/CP1258
 de28dafcea25942068f985ed626f2dc8  charmaps/CSA_Z243.4-1985-1
 052ef075f60624efa6e802e91410b47e  charmaps/CSA_Z243.4-1985-2
 06e1bab71c5bb639445d86075cf7cef4  charmaps/CSA_Z243.4-1985-GR
@@ -39,6 +125,9 @@ b2f02a121a48a3ac110bd6ee5263fd9b  charmaps/EBCDIC-US
 ac706419ebd1e3a649fb681312ac8ce5  charmaps/ECMA-CYRILLIC
 7dddc0b7992cd333434b8a02959c50a0  charmaps/ES
 4c0b61e790c2d2470516111e1d2aa319  charmaps/ES2
+d0eb42459f3bfa8a576579d74f10f3fd  charmaps/EUC-JP
+729b91a542fbf5f30a2e16258f21ceaf  charmaps/EUC-KR
+20bb289e25334344a0662470db3e9a8c  charmaps/GB2312
 a135f498373b1305167f1a6c699949a2  charmaps/GB_1988-80
 1e1e94ad8d1c12e9f10f7d6e1d870a68  charmaps/GOST_19768-74
 69a174dec8822dedba8b8aad36ba44df  charmaps/GREEK-CCITT
@@ -65,24 +154,25 @@ aa42a6d193da334341f83f5783e88346  charmaps/IBM285
 6f33fae170d1d8f2e8805598a5d9faec  charmaps/IBM420
 8b156f73e652c2d61b7ccd6a87f9a8ed  charmaps/IBM423
 66042b458fb9ab18f17b10c8f28f6e36  charmaps/IBM424
-b634bac1501c18318edd0f3933b384a2  charmaps/IBM437
+b7dbbe944c14f37b99c88589ce23f4f6  charmaps/IBM437
 fbfeade12b636f330ae301c8c4889066  charmaps/IBM500
 14624459eeab649848449d0e3f83acc1  charmaps/IBM850
 c758668ec74757819130a3fe0dc0c360  charmaps/IBM851
 c1788b0d0c362ad15d23ebe5aaeb035c  charmaps/IBM852
-2d3e765198279a53a3d9488b37facf2a  charmaps/IBM855
-cbb9a7e1fb92bc16aeef5d3f63027e2f  charmaps/IBM857
-5314bd045aea2814c576924e27013670  charmaps/IBM860
-cf51cf4947729270615891be457c327b  charmaps/IBM861
-c401a334989aad1355a558387ba834fd  charmaps/IBM862
-5755062fc1ca9f6a6a2b5ba7eadf72af  charmaps/IBM863
-1cbd4090174eb65cbf8b60d75286d0d2  charmaps/IBM864
-1bd1fd420dc3dea9a8ac7b1757916412  charmaps/IBM865
-54077be5b5a5ded48c5371fde65aacd3  charmaps/IBM866
+381e89c44f3563c165cad5649818f7e2  charmaps/IBM855
+9b8ee5f11d59b7ceb3714eb1448d9793  charmaps/IBM857
+32c16fd20b3fb11b92bb12e14de90825  charmaps/IBM860
+bc2e6b784e155a42c3329cb7b23cd653  charmaps/IBM861
+759ef63f459acb00c54fafed06b52fa3  charmaps/IBM862
+d663303a0f58dab4a6eb28a66a64b94e  charmaps/IBM863
+754b798ba5e75bc05fd2171f425261ed  charmaps/IBM864
+b6a61bfb10e0e97b6e6acfa85b974e54  charmaps/IBM865
+a97d1ae5b7e1042e9fd64b25ed471f40  charmaps/IBM866
 3c687466bbe8924d247de33aefc3b39c  charmaps/IBM868
-a4a9721bce720a8c24b3130dba84347d  charmaps/IBM869
+25a012edcc641079a92e48b7daaefb6c  charmaps/IBM869
 f06c133a6a95e36ed4bfd25def526769  charmaps/IBM870
 3484dd8f95b187e5875dc73278485dd5  charmaps/IBM871
+549df48822f4d8c00e36ecd8ac12dad2  charmaps/IBM874
 2ac060b9d24b0627a69edaf9c8f9b20f  charmaps/IBM875
 526e51ad0ce04ad9700b6444e83d4331  charmaps/IBM880
 d594cb73e9deddfbacf403223a39415e  charmaps/IBM891
@@ -95,22 +185,25 @@ b620d1383e848c22e993d83c929d4e2c  charmaps/IEC_P27-1
 698eb5f931a6378ec100988b2e7080f8  charmaps/INIS-8
 3355267d5b626e15335bc3d9e9ceecec  charmaps/INIS-CYRILLIC
 82997b03c60b1c75db7c684369afa784  charmaps/INVARIANT
-f6ec68e3fa6e6a32ce569a11b3053b6a  charmaps/ISO-8859-1
-a2dd10c556673a29a78ab36f03bf790b  charmaps/ISO-8859-10
-de357baff38cd0006a4b0b5a747de751  charmaps/ISO-8859-13
-3d44651d05855f6c2b14fc71e0c89a1c  charmaps/ISO-8859-14
-d3235d59344cfbbb418e11d0bcc4bb65  charmaps/ISO-8859-15
+f73101f88ab99ae54aab390a39e37bd2  charmaps/ISIRI-3342
+00278485a2b71756393bdaff1d475f09  charmaps/ISO-8859-1
+97daa5d07db924785235076958fd0cf4  charmaps/ISO-8859-10
+65b513f374f59ab6c3065f6cabac073a  charmaps/ISO-8859-13
+7a53d1853f07c116e8ceaac4b42c10f4  charmaps/ISO-8859-14
+291de15c8b16692c49cd7cbacf88c47a  charmaps/ISO-8859-15
+b5aeeb41514765d0c6d59e209e34b489  charmaps/ISO-8859-16
 eb0956b77262e50119b476b8a7266ee7  charmaps/ISO-8859-2
 5f4b7f0d6d3123a5928f83d13b15b8ef  charmaps/ISO-8859-3
 43a6fbbc2c730598a4c9924a4caf1a5a  charmaps/ISO-8859-4
 cf08296dd3226cb37c14faf45e7bf7e0  charmaps/ISO-8859-5
 2aa504f779ecaa9b1ed1bd2095f9b690  charmaps/ISO-8859-6
-ae6d8c251216bd6d062fa97738ec043e  charmaps/ISO-8859-7
-0fb1c5a4c1e86155ed868ef4365d5b31  charmaps/ISO-8859-8
+7aaf7cf69626b0db87314ec8b6f9a2c9  charmaps/ISO-8859-7
+e8820ebb915620714fe103155cd5429c  charmaps/ISO-8859-8
 172863abae066ff434fdde13bfcbdf74  charmaps/ISO-8859-9
-1b37bc4d952af81b97fdf412e0c09acc  charmaps/ISO-IR-90
+7f859ae24e0921d1ed24e9415865c20f  charmaps/ISO-IR-197
+35a007ff10462707262fddeaaed09a79  charmaps/ISO-IR-90
 29e4042157fbde4ecf3e36d82c976c62  charmaps/ISO_10367-BOX
-b71ed28fbb5d7d62d9f3a710a34a6df4  charmaps/ISO_10646
+a2fae2a1c29554eaa27fc44b6f2448b7  charmaps/ISO_10646
 2eb96001d9520c322ec37b9a9893431b  charmaps/ISO_2033-1983
 cdd74ad87b62bebded4d4f09e4b70d95  charmaps/ISO_5427
 9a0245eaeaa3542e4792462dc4167a3b  charmaps/ISO_5427-EXT
@@ -136,12 +229,14 @@ f6635f62933ca73d099f7f0deabf98e2  charmaps/JIS_C6229-1984-KANA
 0ef24ee22fe2db7c269f391fcf318a25  charmaps/JUS_I.B1.003-MAC
 d9f90201c1cf81ea3e1d168720bffc83  charmaps/JUS_I.B1.003-SERB
 67d61886ea42a4f7860ac7c4e02788d3  charmaps/KOI-8
-d59998eca2cfb8f43bf0720da364d74b  charmaps/KOI8-R
+7762b0e55445ff057d6d12b9d4b58858  charmaps/KOI8-R
+7e4c814f2e2237f50a8e9cb16cf972af  charmaps/KOI8-U
 740a29c47cc9a64027b11dfa25c40db0  charmaps/KSC5636
+58cd9bffdffb8acea02431bc05e1cffb  charmaps/KSX1001
 c4a4025dccd0b37119b9382d9f741736  charmaps/LATIN-GREEK
 5fb2c89721a7ac283154db22d6d2dce3  charmaps/LATIN-GREEK-1
 6680017c5cda54ba6b7191e9bbbbd521  charmaps/MAC-IS
-3b589dfa981564e6004cf62b137fa3fa  charmaps/MAC-UK
+b4dd3b580ed4c12a00db6a92bfe704a4  charmaps/MAC-UK
 4d605d9319f35bca76db2f3adc37b186  charmaps/MACINTOSH
 447109f8043eed245396b8dfb0c5b024  charmaps/MSZ_7795.3
 1d20c917abdd4beeeba248c57e315cfa  charmaps/NATS-DANO
@@ -149,91 +244,23 @@ b3bbdc3f120f8953a4f6aa642427fe15  charmaps/NATS-DANO-ADD
 6ecc9d568a7816ec1c36e671397bc62e  charmaps/NATS-SEFI
 10d8bd8b95e840b9158f429ad5b9365a  charmaps/NATS-SEFI-ADD
 0ecf1f5d1f3013682c36740c70a401b7  charmaps/NC_NC00-10
-2f4a07a32092af3ad9ba80327b2eee3d  charmaps/NEXTSTEP
+3d0fe48348b6bc87a8b51bc14e7095f1  charmaps/NEXTSTEP
 27d205fe2bdb212ff487149378a8fb13  charmaps/NF_Z_62-010
-d867bfe77c36b2d1aeecaa3f57d9d4e1  charmaps/NF_Z_62-010-1973
-3b41e78b72c9e6ae388372250a4c2aa1  charmaps/NF_Z_62-010_(1973)
+3b41e78b72c9e6ae388372250a4c2aa1  charmaps/NF_Z_62-010_1973
 f337a4af933e8cf76ce0cbe0c3220385  charmaps/NS_4551-1
 249ccbf125a7f3ba65f981c713315518  charmaps/NS_4551-2
 c31d1e195aa38a135db258ffe9819686  charmaps/PT
 15be55c497423c88f935bc5cb0b8a8a3  charmaps/PT2
 4350bd8c8fe1e5af0c7ce81ca1cede69  charmaps/SAMI
+a32a61d30e9a82987d46c6519ba4fa1b  charmaps/SAMI-WS2
 0749422e24fc635059683aab8e5cec7c  charmaps/SEN_850200_B
 ba143c0073ddafb215cb977c352c51a0  charmaps/SEN_850200_C
 9785b30026d616bbda77eaf8e6153787  charmaps/T.101-G2
 1f46111983da2e6089c96fe82dac584a  charmaps/T.61-7BIT
 c9cddee81fc56afc565103f0595512d8  charmaps/T.61-8BIT
-9fcdbcefc8f2945dcb3047496b6e4e1c  charmaps/UTF8
+f326985c547ec318a5f898b6515b575e  charmaps/TIS-620
+866ff501227eb0be777ab0311f9caadf  charmaps/UTF8
 ef3bf5ae895d02eaef728a6cad19f389  charmaps/VIDEOTEX-SUPPL
-b0fc83fb2cead90248f032e287299525  locales/POSIX
-5e9f804d3c68d2a8ceab10020b2d885c  locales/cs_CZ
-8084f6fe7165163028482a4f4ca52abe  locales/da_DK
-3c1e78eeb968fa5ef49b2672fe3da756  locales/de_AT
-6ee0be7a3b0033b35719419a9d84b27f  locales/de_BE
-89ff8fb9bb9d2ea2fbfd409baccd7f59  locales/de_CH
-1ad7034b9f3be247d0a169dff7d711bf  locales/de_DE
-969062eb7dd2196ae96c26b837f77591  locales/de_LU
-a8192252431fc5fcec56ed92068da88e  locales/el_GR
-1df05f9450263138fd5d4ee513642310  locales/en_AU
-bb28f2db6809e1e6064d447f509a2ede  locales/en_CA
-b7bd86ec5645f4731e78bfef70bec498  locales/en_CA,2.5
-a1b0fbbd332fcb1bf7376f240a96ad6d  locales/en_DK
-99a400d909a4db85570a9ab72a34c60b  locales/en_DK.com
-8f322dd28903682c6a80a4a96861dc59  locales/en_GB
-aee81bf8761ef1e38f6adc39e5846b17  locales/en_IE
-e6accbc3458eba9e23156e99ce700439  locales/en_NZ
-e7e3223904043d185087bbb13bbc6e97  locales/en_US
-c09fe242a78f095ba73a572cf1d3ae51  locales/es_AR
-f00557d5abe37ecb4c4a7a0f639d83bb  locales/es_BO
-dfa04a07e5020fcfbc185db523fc42f2  locales/es_CL
-02de1dc2939ca0d0e8ce22c2d4d49f88  locales/es_CO
-013a1ea40eb1a4d7313050642ed75b99  locales/es_DO
-fb3914b2ba26efc5723cd751e18fc92d  locales/es_EC
-d622778a3d44e49527e0885691c8bf9f  locales/es_ES
-d003b9b027005a95fd19ae213a3d47ea  locales/es_GT
-b7e903bbb4b5bd59050c1948f50b3a79  locales/es_HN
-254983b73ccc9855b03119403fdaef61  locales/es_MX
-2b61af6b007a1af4c31ea5ca8a9e3179  locales/es_PA
-95bc5dacc650bfa7b0d258ae749db9b5  locales/es_PE
-0f0db099f11bd5badd07af16c1a8ce65  locales/es_PY
-8fd678bf1f3fc81d8124d54b83604793  locales/es_SV
-ca950a3717ca14b9fd7b174cb3be0205  locales/es_US
-8bdf81518fb86575d754e46de5a5c0aa  locales/es_UY
-d2459a575f09c4ade4a50e4280356f89  locales/es_VE
-57fb2876beb2e100e09174f45918ac9b  locales/et_EE
-4d85ff4728e48450e1ae4f371c1fd12e  locales/eu_ES
-5c6df7ae14e499da97da67545d346a94  locales/fi_FI
-35d631cc21c7cc9d1ce2933e1d94d81a  locales/fo_FO
-419d0507292b954a0cee5be020771b00  locales/fr_BE
-d9e85f9c1dc5d2d9396afac293f0553c  locales/fr_CA
-50e86eff16c0c9eb52e00a936227966d  locales/fr_CA,2.13
-47b866d8e108070ebc393f18e5a11618  locales/fr_CH
-1d63fde6acfdc6c0dc03b36098a9f5ab  locales/fr_FR
-8c17257001e3d33e8ab8c5dc9fae87a7  locales/fr_LU
-fe6ba034da4ce416f480a11a0b1f7356  locales/ga_IE
-e5730342b747e9445b6448792d39d121  locales/he_IL
-1291e71feb2a02bf24717857c936ad16  locales/hr_HR
-0b21f01202e6ca3de0835191205c54ab  locales/hu_HU
-2325701702c17598f3a4e1321da6d84b  locales/is_IS
-69b619bf7fad926c3c04349f1a316d0d  locales/it_IT
-e5730342b747e9445b6448792d39d121  locales/iw_IL
-a0b6e1db02c80fe09efab5acadbeeb62  locales/ja_JP
-2f97cb36f71528ce4dda636ddb96d0c5  locales/kl_GL
-a91489780f5bbdb6b3e570804fb38df7  locales/lt_LT
-1be844bb3bc266422ee1c6352ac8c12e  locales/lv_LV
-5be9df64a7bf8669701f0f9983dc1004  locales/nl_BE
-4d58de18535a2e1f98e6985d4fa5b671  locales/nl_NL
-0159a137296be5f7e776feabec45b768  locales/no_NO
-6b255224747ac5d764fcf23f6cca86b4  locales/pl_PL
-7e40f55558927e1754744a5b705d5089  locales/pt_BR
-3ed6e5080462030ceb847ef241ee1352  locales/pt_PT
-92d78ef516c5e6c188acf575dc288a88  locales/ro_RO
-7d775a1146a075d0222e0fe0be7fbb3e  locales/ru_RU
-ac0344e42ac61764b7013244bc9c3532  locales/ru_SU
-e138da41f8586445c277a761ca2fc7df  locales/sk_SK
-c82e1d2468d3e268aa33606f75aa69b5  locales/sl_SI
-b1146c25b2827502bc08c5cdb05da5e3  locales/sr_YU
-2c1087e408f00e70320ca5e4efd80617  locales/sv_FI
-45c64c2c790971d5377890de2002f933  locales/sv_SE
-87c0290784eb817f78bfa38b6a390b3b  locales/tr_TR
-4b5befa44f25c973d70b1f49887ea169  locales/zh_CN
+d8b499f15cb60ae79eb30a5fddc46826  repertoiremaps/charids.894
+471cbc9b5fc329e2de0439c53bf15632  repertoiremaps/mnemonic.ds
+fb66d6b898b399e9a3ba9dc37d77e167  repertoiremaps/mnemonic.ja
diff --git a/localedata/Makefile b/localedata/Makefile
index f919a7ea4e..928d96a0bc 100644
--- a/localedata/Makefile
+++ b/localedata/Makefile
@@ -46,7 +46,8 @@ ld-test-srcs := $(addprefix tests/,$(addsuffix .cm,$(ld-test-names)) \
 				   $(addsuffix .def,$(ld-test-names)))
 
 generated := $(test-input) $(test-output)
-generated-dirs := $(basename $(test-input)) en_US $(ld-test-names) tt_TT
+generated-dirs := $(basename $(test-input)) en_US $(ld-test-names) tt_TT\
+		  de_DE.437
 
 distribute := CHECKSUMS README SUPPORTED ChangeLog			\
 	      $(charmaps) $(locales) $(repertoiremaps)			\
diff --git a/localedata/charmaps/IBM864 b/localedata/charmaps/IBM864
index fdef1cd4e1..3cefc87a34 100644
--- a/localedata/charmaps/IBM864
+++ b/localedata/charmaps/IBM864
@@ -298,7 +298,7 @@ CHARMAP
 <aH->                  /xC3     <UFE83> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
 <wH->                  /xC4     <UFE85> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
 <e+.>                  /xC5     <UFECA> ARABIC LETTER AIN FINAL FORM
-<yH,>                  /xC6     <UFE8D> ARABIC LETTER ALEF ISOLATED FORM
+<yH,>                  /xC6     <UFE8B> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
 <a+->                  /xC7     <UFE8D> ARABIC LETTER ALEF ISOLATED FORM
 <b+,>                  /xC8     <UFE91> ARABIC LETTER BEH INITIAL FORM
 <tm->                  /xC9     <UFE93> ARABIC LETTER TEH MARBUTA ISOLATED FORM
diff --git a/localedata/charmaps/ISO-8859-8 b/localedata/charmaps/ISO-8859-8
index be8beee5e5..89be4930a4 100644
--- a/localedata/charmaps/ISO-8859-8
+++ b/localedata/charmaps/ISO-8859-8
@@ -184,7 +184,7 @@ CHARMAP
 <NO>                   /xAC   <U00AC> NOT SIGN
 <-->                   /xAD   <U00AD> SOFT HYPHEN
 <Rg>                   /xAE   <U00AE> REGISTERED SIGN
-<'->                   /xAF   <U203E> OVERLINE
+<'m>                   /xAF   <U00AF> MACRON
 <DG>                   /xB0   <U00B0> DEGREE SIGN
 <+->                   /xB1   <U00B1> PLUS-MINUS SIGN
 <2S>                   /xB2   <U00B2> SUPERSCRIPT TWO
@@ -228,6 +228,8 @@ CHARMAP
 <R+>                   /xF8   <U05E8> HEBREW LETTER RESH
 <Sh>                   /xF9   <U05E9> HEBREW LETTER SHIN
 <T+>                   /xFA   <U05EA> HEBREW LETTER TAV
+<LR>                   /xFD   <U200E> LEFT-TO-RIGHT MARK
+<RL>                   /xFE   <U200F> RIGHT-TO-LEFT MARK
 <NUL>                  /x00   <U0000> NUL
 <SOH>                  /x01   <U0001> START OF HEADING (SOH)
 <STX>                  /x02   <U0002> START OF TEXT (STX)
diff --git a/localedata/charmaps/ISO-IR-90 b/localedata/charmaps/ISO-IR-90
index b839751b2e..ed03d2bb0d 100644
--- a/localedata/charmaps/ISO-IR-90
+++ b/localedata/charmaps/ISO-IR-90
@@ -497,5 +497,5 @@ CHARMAP
 <vertical-line>        /x7C   <U007C> VERTICAL LINE
 <right-brace>          /x7D   <U007D> RIGHT CURLY BRACKET
 <right-curly-bracket>  /x7D   <U007D> RIGHT CURLY BRACKET
-<tilde>                /x20   <U007E> TILDE
+<tilde>                /xC4/x20   <U007E> TILDE
 END CHARMAP
diff --git a/localedata/charmaps/NEXTSTEP b/localedata/charmaps/NEXTSTEP
index 3202e5355d..e3596d4668 100644
--- a/localedata/charmaps/NEXTSTEP
+++ b/localedata/charmaps/NEXTSTEP
@@ -176,8 +176,11 @@ CHARMAP
 <f2>                   /xA6   <U0192> LATIN SMALL LETTER F WITH HOOK
 <SE>                   /xA7   <U00A7> SECTION SIGN
 <Cu>                   /xA8   <U00A4> CURRENCY SIGN
+<'9>                   /xA9   <U2019> RIGHT SINGLE QUOTATION MARK
 <"6>                   /xAA   <U201C> LEFT DOUBLE QUOTATION MARK
 <<<>                   /xAB   <U00AB> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+<<1>                   /xAC   <U2039> SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+</>1>                  /xAD   <U203A> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
 <fi>                   /xAE   <UFB01> LATIN SMALL LIGATURE FI
 <fl>                   /xAF   <UFB02> LATIN SMALL LIGATURE FL
 <Rg>                   /xB0   <U00AE> REGISTERED SIGN
@@ -188,6 +191,8 @@ CHARMAP
 <BB>                   /xB5   <U00A6> BROKEN BAR
 <PI>                   /xB6   <U00B6> PILCROW SIGN
 <sb>                   /xB7   <U2022> BULLET
+<.9>                   /xB8   <U201A> SINGLE LOW-9 QUOTATION MARK
+<:9>                   /xB9   <U201E> DOUBLE LOW-9 QUOTATION MARK
 <"9>                   /xBA   <U201D> RIGHT DOUBLE QUOTATION MARK
 </>/>>                 /xBB   <U00BB> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
 <.3>                   /xBC   <U2026> HORIZONTAL ELLIPSIS
diff --git a/misc/syslog.c b/misc/syslog.c
index 9690bf1da6..29cd266f09 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -325,7 +325,8 @@ closelog ()
 
   closelog_internal ();
   LogTag = NULL;
-
+  LogType = SOCK_DGRAM; /* this is the default */
+  
   /* Free the lock.  */
   __libc_cleanup_region_end (1);
 }
diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
index 64ecbe023f..c79c67d058 100644
--- a/stdio-common/printf-parse.h
+++ b/stdio-common/printf-parse.h
@@ -149,6 +149,7 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
   spec->info.showsign = 0;
   spec->info.group = 0;
   spec->info.pad = ' ';
+  spec->info.wide = sizeof (UCHAR_T) > 1;
 
   /* Test for positional argument.  */
   if (ISDIGIT (*format))
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 13598e3030..1f0334f5e9 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -1,5 +1,5 @@
 /* Floating point output for `printf'.
-   Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
@@ -51,18 +51,18 @@
 /* This defines make it possible to use the same code for GNU C library and
    the GNU I/O library.	 */
 #ifdef USE_IN_LIBIO
-#  define PUT(f, s, n) _IO_sputn (f, s, n)
-#  define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
+# define PUT(f, s, n) _IO_sputn (f, s, n)
+# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
 /* We use this file GNU C library and GNU I/O library.	So make
    names equal.	 */
-#  undef putc
-#  define putc(c, f) (wide \
+# undef putc
+# define putc(c, f) (wide \
 		      ? _IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
-#  define size_t     _IO_size_t
-#  define FILE	     _IO_FILE
+# define size_t     _IO_size_t
+# define FILE	     _IO_FILE
 #else	/* ! USE_IN_LIBIO */
-#  define PUT(f, s, n) fwrite (s, 1, n, f)
-#  define PAD(f, c, n) __printf_pad (f, c, n)
+# define PUT(f, s, n) fwrite (s, 1, n, f)
+# define PAD(f, c, n) __printf_pad (f, c, n)
 ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
 #endif	/* USE_IN_LIBIO */
 
@@ -77,21 +77,25 @@ ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
       ++done;								      \
     } while (0)
 
-#define PRINT(ptr, len)							      \
+#define PRINT(ptr, wptr, len)						      \
   do									      \
     {									      \
       register size_t outlen = (len);					      \
       if (len > 20)							      \
 	{								      \
-	  if (PUT (fp, ptr, outlen) != outlen)				      \
+	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
 	    return -1;							      \
 	  ptr += outlen;						      \
 	  done += outlen;						      \
 	}								      \
       else								      \
 	{								      \
-	  while (outlen-- > 0)						      \
-	    outchar (*ptr++);						      \
+	  if (wide)							      \
+	    while (outlen-- > 0)					      \
+	      outchar (*wptr++);					      \
+	  else								      \
+	    while (outlen-- > 0)					      \
+	      outchar (*ptr++);						      \
 	}								      \
     } while (0)
 
@@ -125,11 +129,12 @@ extern mp_size_t __mpn_extract_long_double (mp_ptr res_ptr, mp_size_t size,
 					    int *expt, int *is_neg,
 					    long double value);
 extern unsigned int __guess_grouping (unsigned int intdig_max,
-				      const char *grouping, wchar_t sepchar);
+				      const char *grouping);
 
 
-static char *group_number (char *buf, char *bufend, unsigned int intdig_no,
-			   const char *grouping, wchar_t thousands_sep)
+static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
+			      unsigned int intdig_no, const char *grouping,
+			      wchar_t thousands_sep, int ngroups)
      internal_function;
 
 
@@ -147,14 +152,17 @@ __printf_fp (FILE *fp,
   fpnum;
 
   /* Locale-dependent representation of decimal point.	*/
-  wchar_t decimal;
+  const char *decimal;
+  wchar_t decimalwc;
 
   /* Locale-dependent thousands separator and grouping specification.  */
-  wchar_t thousands_sep;
+  const char *thousands_sep = NULL;
+  wchar_t thousands_sepwc = 0;
   const char *grouping;
 
   /* "NaN" or "Inf" for the special cases.  */
   const char *special = NULL;
+  const wchar_t *wspecial = NULL;
 
   /* We need just a few limbs for the input before shifting to the right
      position.	*/
@@ -178,7 +186,7 @@ __printf_fp (FILE *fp,
   MPN_VAR(tmp);
 
   /* Digit which is result of last hack_digit() call.  */
-  int digit;
+  wchar_t digit;
 
   /* The type of output format that will be used: 'e'/'E' or 'f'.  */
   int type;
@@ -192,7 +200,7 @@ __printf_fp (FILE *fp,
   /* Nonzero if this is output on a wide character stream.  */
   int wide = info->wide;
 
-  char hack_digit (void)
+  wchar_t hack_digit (void)
     {
       mp_limb_t hi;
 
@@ -222,7 +230,7 @@ __printf_fp (FILE *fp,
 		  /* We're not prepared for an mpn variable with zero
 		     limbs.  */
 		  fracsize = 1;
-		  return '0' + hi;
+		  return L'0' + hi;
 		}
 	    }
 
@@ -231,35 +239,24 @@ __printf_fp (FILE *fp,
 	    frac[fracsize++] = cy;
 	}
 
-      return '0' + hi;
+      return L'0' + hi;
     }
 
 
   /* Figure out the decimal point character.  */
   if (info->extra == 0)
     {
-      mbstate_t state;
-
-      memset (&state, '\0', sizeof (state));
-      if (__mbrtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
-		     strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT)),
-		     &state) <= 0)
-	decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+      decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
     }
   else
     {
-      mbstate_t state;
-
-      memset (&state, '\0', sizeof (state));
-      if (__mbrtowc (&decimal, _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT),
-		     strlen (_NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT)),
-		     &state) <= 0)
-	decimal = (wchar_t) *_NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+      decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
+				    _NL_MONETARY_DECIMAL_POINT_WC);
     }
-  /* Give default value.  */
-  if (decimal == L'\0')
-    decimal = L'.';
-
+  /* The decimal point character must not be zero.  */
+  assert (*decimal != L'\0');
 
   if (info->group)
     {
@@ -273,34 +270,33 @@ __printf_fp (FILE *fp,
       else
 	{
 	  /* Figure out the thousands separator character.  */
-	  if (info->extra == 0)
+	  if (wide)
 	    {
-	      mbstate_t state;
-
-	      memset (&state, '\0', sizeof (state));
-	      if (__mbrtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC,
-							  THOUSANDS_SEP),
-			     strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP)),
-			     &state) <= 0)
-		thousands_sep = (wchar_t) *_NL_CURRENT (LC_NUMERIC,
-							THOUSANDS_SEP);
+	      if (info->extra == 0)
+		thousands_sepwc =
+		  _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
+	      else
+		thousands_sepwc =
+		  _NL_CURRENT_WORD (LC_MONETARY,
+				    _NL_MONETARY_THOUSANDS_SEP_WC);
 	    }
 	  else
 	    {
-	      mbstate_t state;
-
-	      memset (&state, '\0', sizeof (state));
-	      if (__mbrtowc (&thousands_sep, _NL_CURRENT (LC_MONETARY,
-							  MON_THOUSANDS_SEP),
-			     strlen (_NL_CURRENT (LC_MONETARY,
-						  MON_THOUSANDS_SEP)),
-			     &state) <= 0)
-		thousands_sep = (wchar_t) *_NL_CURRENT (LC_MONETARY,
-							MON_THOUSANDS_SEP);
+	      if (info->extra == 0)
+		thousands_sep = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+	      else
+		thousands_sep = _NL_CURRENT (LC_MONETARY, MON_THOUSANDS_SEP);
 	    }
 
-	  if (thousands_sep == L'\0')
+	  if ((wide && thousands_sepwc == L'\0')
+	      || (! wide && *thousands_sep == '\0'))
 	    grouping = NULL;
+	  else if (thousands_sepwc == L'\0')
+	    /* If we are printing multibyte characters and there is a
+	       multibyte representation for the thousands separator,
+	       we must ensure the wide character thousands separator
+	       is available, even if it is fake.  */
+	    thousands_sepwc = 0xfffffffe;
 	}
     }
   else
@@ -315,12 +311,30 @@ __printf_fp (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnanl (fpnum.ldbl))
 	{
-	  special = isupper (info->spec) ? "NAN" : "nan";
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	    else
+	      {
+		special = "nan";
+		wspecial = L"nan";
+	      }
 	  is_neg = 0;
 	}
       else if (__isinfl (fpnum.ldbl))
 	{
-	  special = isupper (info->spec) ? "INF" : "inf";
+	  if (isupper (info->spec))
+	    {
+	      special = "INF";
+	      wspecial = L"INF";
+	    }
+	  else
+	    {
+	      special = "inf";
+	      wspecial = L"inf";
+	    }
 	  is_neg = fpnum.ldbl < 0;
 	}
       else
@@ -341,12 +355,30 @@ __printf_fp (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnan (fpnum.dbl))
 	{
-	  special = isupper (info->spec) ? "NAN" : "nan";
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	  else
+	    {
+	      special = "nan";
+	      wspecial = L"nan";
+	    }
 	  is_neg = 0;
 	}
       else if (__isinf (fpnum.dbl))
 	{
-	  special = isupper (info->spec) ? "INF" : "inf";
+	  if (isupper (info->spec))
+	    {
+	      special = "INF";
+	      wspecial = L"INF";
+	    }
+	  else
+	    {
+	      special = "inf";
+	      wspecial = L"inf";
+	    }
 	  is_neg = fpnum.dbl < 0;
 	}
       else
@@ -377,7 +409,7 @@ __printf_fp (FILE *fp,
       else if (info->space)
 	outchar (' ');
 
-      PRINT (special, 3);
+      PRINT (special, wspecial, 3);
 
       if (info->left && width > 0)
 	PADN (' ', width);
@@ -746,7 +778,7 @@ __printf_fp (FILE *fp,
 
   {
     int width = info->width;
-    char *buffer, *startp, *cp;
+    wchar_t *wbuffer, *wstartp, *wcp;
     int buffer_malloced;
     int chars_needed;
     int expscale;
@@ -754,6 +786,7 @@ __printf_fp (FILE *fp,
     int fracdig_min, fracdig_max, fracdig_no = 0;
     int dig_max;
     int significant;
+    int ngroups = 0;
 
     if (_tolower (info->spec) == 'e')
       {
@@ -811,25 +844,28 @@ __printf_fp (FILE *fp,
       }
 
     if (grouping)
-      /* Guess the number of groups we will make, and thus how
-	 many spaces we need for separator characters.  */
-      chars_needed += __guess_grouping (intdig_max, grouping, thousands_sep);
+      {
+	/* Guess the number of groups we will make, and thus how
+	   many spaces we need for separator characters.  */
+	ngroups = __guess_grouping (intdig_max, grouping);
+	chars_needed += ngroups;
+      }
 
     /* Allocate buffer for output.  We need two more because while rounding
        it is possible that we need two more characters in front of all the
        other output.  If the amount of memory we have to allocate is too
        large use `malloc' instead of `alloca'.  */
-    buffer_malloced = chars_needed > 20000;
+    buffer_malloced = chars_needed > 5000;
     if (buffer_malloced)
       {
-	buffer = (char *) malloc (2 + chars_needed);
-	if (buffer == NULL)
+	wbuffer = (wchar_t *) malloc ((2 + chars_needed) * sizeof (wchar_t));
+	if (wbuffer == NULL)
 	  /* Signal an error to the caller.  */
 	  return -1;
       }
     else
-      buffer = (char *) alloca (2 + chars_needed);
-    cp = startp = buffer + 2;	/* Let room for rounding.  */
+      wbuffer = (wchar_t *) alloca ((2 + chars_needed) * sizeof (wchar_t));
+    wcp = wstartp = wbuffer + 2;	/* Let room for rounding.  */
 
     /* Do the real work: put digits in allocated buffer.  */
     if (expsign == 0 || type != 'f')
@@ -838,21 +874,21 @@ __printf_fp (FILE *fp,
 	while (intdig_no < intdig_max)
 	  {
 	    ++intdig_no;
-	    *cp++ = hack_digit ();
+	    *wcp++ = hack_digit ();
 	  }
 	significant = 1;
 	if (info->alt
 	    || fracdig_min > 0
 	    || (fracdig_max > 0 && (fracsize > 1 || frac[0] != 0)))
-	  *cp++ = decimal;
+	  *wcp++ = decimalwc;
       }
     else
       {
 	/* |fp| < 1.0 and the selected type is 'f', so put "0."
 	   in the buffer.  */
-	*cp++ = '0';
+	*wcp++ = L'0';
 	--exponent;
-	*cp++ = decimal;
+	*wcp++ = decimalwc;
       }
 
     /* Generate the needed number of fractional digits.	 */
@@ -860,8 +896,8 @@ __printf_fp (FILE *fp,
 	   || (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
       {
 	++fracdig_no;
-	*cp = hack_digit ();
-	if (*cp != '0')
+	*wcp = hack_digit ();
+	if (*wcp != L'0')
 	  significant = 1;
 	else if (significant == 0)
 	  {
@@ -869,16 +905,16 @@ __printf_fp (FILE *fp,
 	    if (fracdig_min > 0)
 	      ++fracdig_min;
 	  }
-	++cp;
+	++wcp;
       }
 
     /* Do rounding.  */
     digit = hack_digit ();
-    if (digit > '4')
+    if (digit > L'4')
       {
-	char *tp = cp;
+	wchar_t *wtp = wcp;
 
-	if (digit == '5' && (*(cp - 1) & 1) == 0)
+	if (digit == L'5' && (*(wcp - 1) & 1) == 0)
 	  {
 	    /* This is the critical case.	 */
 	    if (fracsize == 1 && frac[0] == 0)
@@ -903,31 +939,31 @@ __printf_fp (FILE *fp,
 	  {
 	    /* Process fractional digits.  Terminate if not rounded or
 	       radix character is reached.  */
-	    while (*--tp != decimal && *tp == '9')
-	      *tp = '0';
-	    if (*tp != decimal)
+	    while (*--wtp != decimalwc && *wtp == L'9')
+	      *wtp = '0';
+	    if (*wtp != decimalwc)
 	      /* Round up.  */
-	      (*tp)++;
+	      (*wtp)++;
 	  }
 
-	if (fracdig_no == 0 || *tp == decimal)
+	if (fracdig_no == 0 || *wtp == decimalwc)
 	  {
 	    /* Round the integer digits.  */
-	    if (*(tp - 1) == decimal)
-	      --tp;
+	    if (*(wtp - 1) == decimalwc)
+	      --wtp;
 
-	    while (--tp >= startp && *tp == '9')
-	      *tp = '0';
+	    while (--wtp >= wstartp && *wtp == L'9')
+	      *wtp = L'0';
 
-	    if (tp >= startp)
+	    if (wtp >= wstartp)
 	      /* Round up.  */
-	      (*tp)++;
+	      (*wtp)++;
 	    else
 	      /* It is more critical.  All digits were 9's.  */
 	      {
 		if (type != 'f')
 		  {
-		    *startp = '1';
+		    *wstartp = '1';
 		    exponent += expsign == 0 ? 1 : -1;
 		  }
 		else if (intdig_no == dig_max)
@@ -935,13 +971,13 @@ __printf_fp (FILE *fp,
 		    /* This is the case where for type %g the number fits
 		       really in the range for %f output but after rounding
 		       the number of digits is too big.	 */
-		    *--startp = decimal;
-		    *--startp = '1';
+		    *--wstartp = decimalwc;
+		    *--wstartp = L'1';
 
 		    if (info->alt || fracdig_no > 0)
 		      {
 			/* Overwrite the old radix character.  */
-			startp[intdig_no + 2] = '0';
+			wstartp[intdig_no + 2] = L'0';
 			++fracdig_no;
 		      }
 
@@ -956,7 +992,7 @@ __printf_fp (FILE *fp,
 		  {
 		    /* We can simply add another another digit before the
 		       radix.  */
-		    *--startp = '1';
+		    *--wstartp = L'1';
 		    ++intdig_no;
 		  }
 
@@ -965,7 +1001,7 @@ __printf_fp (FILE *fp,
 		   fractional digits.  */
 		if (intdig_no + fracdig_no > dig_max)
 		  {
-		    cp -= intdig_no + fracdig_no - dig_max;
+		    wcp -= intdig_no + fracdig_no - dig_max;
 		    fracdig_no -= intdig_no + fracdig_no - dig_max;
 		  }
 	      }
@@ -974,25 +1010,26 @@ __printf_fp (FILE *fp,
 
   do_expo:
     /* Now remove unnecessary '0' at the end of the string.  */
-    while (fracdig_no > fracdig_min && *(cp - 1) == '0')
+    while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
       {
-	--cp;
+	--wcp;
 	--fracdig_no;
       }
     /* If we eliminate all fractional digits we perhaps also can remove
        the radix character.  */
-    if (fracdig_no == 0 && !info->alt && *(cp - 1) == decimal)
-      --cp;
+    if (fracdig_no == 0 && !info->alt && *(wcp - 1) == decimalwc)
+      --wcp;
 
     if (grouping)
       /* Add in separator characters, overwriting the same buffer.  */
-      cp = group_number (startp, cp, intdig_no, grouping, thousands_sep);
+      wcp = group_number (wstartp, wcp, intdig_no, grouping, thousands_sepwc,
+			  ngroups);
 
     /* Write the exponent if it is needed.  */
     if (type != 'f')
       {
-	*cp++ = type;
-	*cp++ = expsign ? '-' : '+';
+	*wcp++ = (wchar_t) type;
+	*wcp++ = expsign ? L'-' : L'+';
 
 	/* Find the magnitude of the exponent.	*/
 	expscale = 10;
@@ -1001,23 +1038,23 @@ __printf_fp (FILE *fp,
 
 	if (exponent < 10)
 	  /* Exponent always has at least two digits.  */
-	  *cp++ = '0';
+	  *wcp++ = L'0';
 	else
 	  do
 	    {
 	      expscale /= 10;
-	      *cp++ = '0' + (exponent / expscale);
+	      *wcp++ = L'0' + (exponent / expscale);
 	      exponent %= expscale;
 	    }
 	  while (expscale > 10);
-	*cp++ = '0' + exponent;
+	*wcp++ = L'0' + exponent;
       }
 
     /* Compute number of characters which must be filled with the padding
        character.  */
     if (is_neg || info->showsign || info->space)
       --width;
-    width -= cp - startp;
+    width -= wcp - wstartp;
 
     if (!info->left && info->pad != '0' && width > 0)
       PADN (info->pad, width);
@@ -1032,14 +1069,66 @@ __printf_fp (FILE *fp,
     if (!info->left && info->pad == '0' && width > 0)
       PADN ('0', width);
 
-    PRINT (startp, cp - startp);
+    {
+      char *buffer = NULL;
+      char *cp = NULL;
+
+      if (! wide)
+	{
+	  /* Create the single byte string.  */
+	  const char *decimal;
+	  size_t decimal_len;
+	  size_t thousands_sep_len;
+	  wchar_t *copywc;
+
+	  if (info->extra == 0)
+	    decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+	  else
+	    decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+	  decimal_len = strlen (decimal);
+
+	  if (thousands_sep == NULL)
+	    thousands_sep_len = 0;
+	  else
+	    thousands_sep_len = strlen (thousands_sep);
+
+	  if (buffer_malloced)
+	    {
+	      buffer = (char *) malloc (2 + chars_needed + decimal_len
+					+ ngroups * thousands_sep_len);
+	      if (buffer == NULL)
+		/* Signal an error to the caller.  */
+		return -1;
+	    }
+	  else
+	    buffer = (char *) alloca (2 + chars_needed + decimal_len
+				      + ngroups * thousands_sep_len);
+
+	  /* Now copy the wide character string.  Since the character
+	     (except for the decimal point and thousands separator) must
+	     be coming from the ASCII range we can esily convert the
+	     string without mapping tables.  */
+	  for (cp = buffer, copywc = wstartp; copywc < wcp; ++copywc)
+	    if (*copywc == decimalwc)
+	      cp = (char *) __mempcpy (cp, decimal, decimal_len);
+	    else if (*copywc == thousands_sepwc)
+	      cp = (char *) __mempcpy (cp, thousands_sep, thousands_sep_len);
+	    else
+	      *cp++ = (char) *copywc;
+	}
+
+      PRINT (buffer, wstartp, wide ? wcp - wstartp : cp - buffer);
+
+      /* Free the memory if necessary.  */
+      if (buffer_malloced)
+	{
+	  free (buffer);
+	  free (wbuffer);
+	}
+    }
 
     if (info->left && width > 0)
       PADN (info->pad, width);
-
-    /* Free the memory if necessary.  */
-    if (buffer_malloced)
-      free (buffer);
   }
   return done;
 }
@@ -1048,8 +1137,7 @@ __printf_fp (FILE *fp,
    into a number with INTDIG_MAX integer digits.  */
 
 unsigned int
-__guess_grouping (unsigned int intdig_max, const char *grouping,
-		  wchar_t sepchar)
+__guess_grouping (unsigned int intdig_max, const char *grouping)
 {
   unsigned int groups;
 
@@ -1087,22 +1175,21 @@ __guess_grouping (unsigned int intdig_max, const char *grouping,
    There is guaranteed enough space past BUFEND to extend it.
    Return the new end of buffer.  */
 
-static char *
+static wchar_t *
 internal_function
-group_number (char *buf, char *bufend, unsigned int intdig_no,
-	      const char *grouping, wchar_t thousands_sep)
+group_number (wchar_t *buf, wchar_t *bufend, unsigned int intdig_no,
+	      const char *grouping, wchar_t thousands_sep, int ngroups)
 {
-  unsigned int groups = __guess_grouping (intdig_no, grouping, thousands_sep);
-  char *p;
+  wchar_t *p;
 
-  if (groups == 0)
+  if (ngroups == 0)
     return bufend;
 
   /* Move the fractional part down.  */
-  memmove (buf + intdig_no + groups, buf + intdig_no,
-	   bufend - (buf + intdig_no));
+  wmemmove (buf + intdig_no + ngroups, buf + intdig_no,
+	    bufend - (buf + intdig_no));
 
-  p = buf + intdig_no + groups - 1;
+  p = buf + intdig_no + ngroups - 1;
   do
     {
       unsigned int len = *grouping++;
@@ -1128,5 +1215,5 @@ group_number (char *buf, char *bufend, unsigned int intdig_no,
     *p-- = buf[--intdig_no];
   while (p > buf);
 
-  return bufend + groups;
+  return bufend + ngroups;
 }
diff --git a/stdio-common/printf_size.c b/stdio-common/printf_size.c
index 654675a0d7..c3da4dcb17 100644
--- a/stdio-common/printf_size.c
+++ b/stdio-common/printf_size.c
@@ -1,5 +1,5 @@
 /* Print size value using units for orders of magnitude.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
    Based on a proposal by Larry McVoy <lm@sgi.com>.
@@ -24,26 +24,27 @@
 #include <math.h>
 #include <printf.h>
 #ifdef USE_IN_LIBIO
-#  include <libioP.h>
+# include <libioP.h>
 #else
-#  include <stdio.h>
+# include <stdio.h>
 #endif
 
 
 /* This defines make it possible to use the same code for GNU C library and
    the GNU I/O library.	 */
 #ifdef USE_IN_LIBIO
-#  define PUT(f, s, n) _IO_sputn (f, s, n)
-#  define PAD(f, c, n) _IO_padn (f, c, n)
+# define PUT(f, s, n) _IO_sputn (f, s, n)
+# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
 /* We use this file GNU C library and GNU I/O library.	So make
    names equal.	 */
-#  undef putc
-#  define putc(c, f) _IO_putc_unlocked (c, f)
-#  define size_t     _IO_size_t
-#  define FILE	     _IO_FILE
+# undef putc
+# define putc(c, f) (wide \
+		     ? _IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
+# define size_t	_IO_size_t
+# define FILE	_IO_FILE
 #else	/* ! USE_IN_LIBIO */
-#  define PUT(f, s, n) fwrite (s, 1, n, f)
-#  define PAD(f, c, n) __printf_pad (f, c, n)
+# define PUT(f, s, n) fwrite (s, 1, n, f)
+# define PAD(f, c, n) __printf_pad (f, c, n)
 ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
 #endif	/* USE_IN_LIBIO */
 
@@ -58,21 +59,25 @@ ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
       ++done;								      \
     } while (0)
 
-#define PRINT(ptr, len)							      \
+#define PRINT(ptr, wptr, len)						      \
   do									      \
     {									      \
       register size_t outlen = (len);					      \
       if (len > 20)							      \
 	{								      \
-	  if (PUT (fp, ptr, outlen) != outlen)				      \
+	  if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
 	    return -1;							      \
 	  ptr += outlen;						      \
 	  done += outlen;						      \
 	}								      \
       else								      \
 	{								      \
-	  while (outlen-- > 0)						      \
-	    outchar (*ptr++);						      \
+	  if (wide)							      \
+	    while (outlen-- > 0)					      \
+	      outchar (*wptr++);					      \
+	  else								      \
+	    while (outlen-- > 0)					      \
+	      outchar (*ptr++);						      \
 	}								      \
     } while (0)
 
@@ -117,9 +122,11 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
 
   /* "NaN" or "Inf" for the special cases.  */
   const char *special = NULL;
+  const wchar_t *wspecial = NULL;
 
   struct printf_info fp_info;
   int done = 0;
+  int wide = info->wide;
 
 
   /* Fetch the argument value.	*/
@@ -132,11 +139,13 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
       if (__isnanl (fpnum.ldbl.d))
 	{
 	  special = "nan";
+	  wspecial = L"nan";
 	  negative = 0;
 	}
       else if (__isinfl (fpnum.ldbl.d))
 	{
 	  special = "inf";
+	  wspecial = L"inf";
 
 	  negative = fpnum.ldbl.d < 0;
 	}
@@ -156,11 +165,13 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
       if (__isnan (fpnum.dbl.d))
 	{
 	  special = "nan";
+	  wspecial = L"nan";
 	  negative = 0;
 	}
       else if (__isinf (fpnum.dbl.d))
 	{
 	  special = "inf";
+	  wspecial = L"inf";
 
 	  negative = fpnum.dbl.d < 0;
 	}
@@ -174,7 +185,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
 
   if (special)
     {
-      int width = info->prec > info->width ? info->prec : info->width;
+      int width = info->prec > width ? info->prec : width;
 
       if (negative || info->showsign || info->space)
 	--width;
@@ -190,7 +201,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
       else if (info->space)
 	outchar (' ');
 
-      PRINT (special, 3);
+      PRINT (special, wspecial, 3);
 
       if (info->left && width > 0)
 	PADN (' ', width);
@@ -212,7 +223,7 @@ printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
   fp_info.group = info->group;
   fp_info.extra = info->extra;
   fp_info.pad = info->pad;
-  fp_info.wide = 0;
+  fp_info.wide = wide;
 
   if (fp_info.left && fp_info.pad == L' ')
     {
diff --git a/stdio-common/vfscanf.c b/stdio-common/vfscanf.c
index b50e7b8323..6b95352971 100644
--- a/stdio-common/vfscanf.c
+++ b/stdio-common/vfscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -62,6 +62,7 @@
 #define GROUP		0x080	/* ': group numbers */
 #define MALLOC		0x100	/* a: malloc strings */
 #define CHAR		0x200	/* hh: char */
+#define I18N		0x400	/* I: use locale's digits */
 
 
 #ifdef USE_IN_LIBIO
@@ -479,8 +480,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
 	    }
 	}
 
-      /* Check for the assignment-suppressing and the number grouping flag.  */
-      while (*f == L_('*') || *f == L_('\''))
+      /* Check for the assignment-suppressing, the number grouping flag,
+	 and the signal to use the locale's digit representation.  */
+      while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
 	switch (*f++)
 	  {
 	  case L_('*'):
@@ -489,6 +491,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
 	  case L_('\''):
 	    flags |= GROUP;
 	    break;
+	  case L_('I'):
+	    flags |= I18N;
+	    break;
 	  }
 
       /* We have seen width. */
@@ -1192,22 +1197,137 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
 	  if (base == 0)
 	    base = 10;
 
-	  /* Read the number into workspace.  */
-	  while (c != EOF && width != 0)
+	  if (base == 10 && (flags & I18N) != 0)
 	    {
-	      if (base == 16 ? !ISXDIGIT (c) :
-		  ((!ISDIGIT (c) || c - L_('0') >= base) &&
-		   !((flags & GROUP) && base == 10 && c == thousands)))
-		break;
-	      ADDW (c);
-	      if (width > 0)
-		--width;
+	      int from_level;
+	      int to_level;
+#ifdef COMPILE_WPRINTF
+	      const wchar_t *wcdigits;
+#else
+	      const char *mbdigits[10];
+#endif
+	      int n;
 
-	      c = inchar ();
+	      from_level = 0;
+#ifdef COMPILE_WPRINTF
+	      to_level = _NL_CURRENT_WORD (LC_CTYPE,
+					   _NL_CTYPE_INDIGITS_WC_LEN) - 1;
+#else
+	      to_level = _NL_CURRENT_WORD (LC_CTYPE,
+					   _NL_CTYPE_INDIGITS_MB_LEN) - 1;
+#endif
+
+	      /* In this round we get the pointer to the digit strings
+		 and also perform the first round of comparisons.  */
+	      for (n = 0; n < 10; ++n)
+		{
+		  size_t dlen;
+		  size_t dcnt;
+
+		  /* Get the string for the digits with value N.  */
+#ifdef COMPILE_WPRINTF
+		  wcdigits[n] = _NL_CURRENT (LC_CTYPE,
+					     _NL_CTYPE_INDIGITS0_WC + n);
+		  if (c == *wcdigit[n])
+		    break;
+
+		  /* Advance the pointer to the next string.  */
+		  ++wcdigits[n];
+#else
+		  mbdigits[n] = _NL_CURRENT (LC_CTYPE,
+					     _NL_CTYPE_INDIGITS0_MB + n);
+		  dlen = strlen (mbdigits[n]);
+
+		  dcnt = 0;
+		  do
+		    {
+		      if (c != mbdigits[n][dcnt])
+			break;
+		      c = inchar ();
+		    }
+		  while (--dcnt > 0);
+
+		  if (dcnt == 0)
+		    /* We found it.  */
+		    break;
+
+		  /* Advance the pointer to the next string.  */
+		  mbdigits[n] += dlen + 1;
+		}
+#endif
+
+	      if (n == 10)
+		{
+		  /*Have not yet found the digit.  */
+		  while (++from_level <= to_level)
+		    {
+		      /* Search all ten digits of this level.  */
+		      for (n = 0; n < 10; ++n)
+			{
+#ifdef COMPILE_WPRINTF
+			  if (c == *wcdigit[n])
+			    break;
+
+			  /* Advance the pointer to the next string.  */
+			  ++wcdigits[n];
+#else
+			  size_t dlen = strlen (mbdigits[n]);
+			  size_t dcnt;
+
+			  dcnt = 0;
+			  do
+			    {
+			      if (c != mbdigits[n][dcnt])
+				break;
+			      c = inchar ();
+			    }
+			  while (--dcnt > 0);
+
+			  if (dcnt == 0)
+			    /* We found it.  */
+			    break;
+
+			  /* Advance the pointer to the next string.  */
+			  mbdigits[n] += dlen + 1;
+#endif
+			}
+
+		      if (n < 10)
+			/* Found it.  */
+			break;
+
+		      /* Next level.  */
+		      ++from_level;
+		    }
+		}
+
+	      if (n == 10)
+		{
+		  /* Haven't found anything.  Push the last character back
+		     and return an error.  */
+		  ungetc (c, s);
+		  input_error ();
+		}
+
+	      ADDW (L_('0') + n);
 	    }
+	  else
+	    /* Read the number into workspace.  */
+	    while (c != EOF && width != 0)
+	      {
+		if (base == 16 ? !ISXDIGIT (c) :
+		    ((!ISDIGIT (c) || c - L_('0') >= base) &&
+		     !((flags & GROUP) && base == 10 && c == thousands)))
+		  break;
+		ADDW (c);
+		if (width > 0)
+		  --width;
+
+		c = inchar ();
+	      }
 
-	  if (wpsize == 0 ||
-	      (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
+	  if (wpsize == 0
+	      || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
 	    {
 	      /* There was no number.  If we are supposed to read a pointer
 		 we must recognize "(nil)" as well.  */
diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
index e4f7c9f628..c4edb48734 100644
--- a/stdlib/canonicalize.c
+++ b/stdlib/canonicalize.c
@@ -76,7 +76,10 @@ canonicalize (const char *name, char *resolved)
   if (name[0] != '/')
     {
       if (!__getcwd (rpath, path_max))
-	goto error;
+	{
+	  rpath[0] = '\0';
+	  goto error;
+	}
       dest = strchr (rpath, '\0');
     }
   else
@@ -122,6 +125,9 @@ canonicalize (const char *name, char *resolved)
 	      if (resolved)
 		{
 		  __set_errno (ENAMETOOLONG);
+		  if (dest > rpath + 1)
+		    dest--;
+		  *dest = '\0';
 		  goto error;
 		}
 	      new_size = rpath_limit - rpath;
diff --git a/sysdeps/arm/fpu/fpu_control.h b/sysdeps/arm/fpu/fpu_control.h
index 27b8dda972..b5338c5755 100644
--- a/sysdeps/arm/fpu/fpu_control.h
+++ b/sysdeps/arm/fpu/fpu_control.h
@@ -71,7 +71,7 @@
 
 /* The fdlibm code requires no interrupts for exceptions.  Don't
    change the rounding mode, it would break long double I/O!  */
-#define _FPU_DEFAULT  0x00000000 /* Default value.  */
+#define _FPU_DEFAULT  0x00001000 /* Default value.  */
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t;
diff --git a/sysdeps/generic/printf_fphex.c b/sysdeps/generic/printf_fphex.c
index 2042844f81..2b10fa62ac 100644
--- a/sysdeps/generic/printf_fphex.c
+++ b/sysdeps/generic/printf_fphex.c
@@ -1,6 +1,5 @@
-/* Print floating point number in hexadecimal notation according to
-   ISO C99.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Print floating point number in hexadecimal notation according to ISO C99.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -28,6 +27,7 @@
 #include <string.h>
 #include <wchar.h>
 #include "_itoa.h"
+#include "_itowa.h"
 #include <locale/localeinfo.h>
 
 /* #define NDEBUG 1*/		/* Undefine this for debugging assertions.  */
@@ -38,7 +38,7 @@
 #ifdef USE_IN_LIBIO
 # include <libioP.h>
 # define PUT(f, s, n) _IO_sputn (f, s, n)
-# define PAD(f, c, n) (wide  ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
+# define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
 /* We use this file GNU C library and GNU I/O library.	So make
    names equal.	 */
 # undef putc
@@ -63,13 +63,16 @@ ssize_t __printf_pad __P ((FILE *, char pad, int n)); /* In vfprintf.c.  */
       ++done;								      \
     } while (0)
 
-#define PRINT(ptr, len)							      \
+#define PRINT(ptr, wptr, len)						      \
   do									      \
     {									      \
-       int outlen = (len);						      \
-       const char *cp = (ptr);						      \
-       while (outlen-- > 0)						      \
-	 outchar (*cp++);						      \
+      register size_t outlen = (len);					      \
+      if (wide)								      \
+	while (outlen-- > 0)						      \
+	  outchar (*wptr++);						      \
+      else								      \
+	while (outlen-- > 0)						      \
+	  outchar (*ptr++);						      \
     } while (0)
 
 #define PADN(ch, len)							      \
@@ -100,21 +103,28 @@ __printf_fphex (FILE *fp,
   fpnum;
 
   /* Locale-dependent representation of decimal point.	*/
-  wchar_t decimal;
+  const char *decimal;
+  wchar_t decimalwc;
 
   /* "NaN" or "Inf" for the special cases.  */
   const char *special = NULL;
+  const wchar_t *wspecial = NULL;
 
   /* Buffer for the generated number string for the mantissa.  The
      maximal size for the mantissa is 128 bits.  */
   char numbuf[32];
   char *numstr;
   char *numend;
+  wchar_t wnumbuf[32];
+  wchar_t *wnumstr;
+  wchar_t *wnumend;
   int negative;
 
   /* The maximal exponent of two in decimal notation has 5 digits.  */
   char expbuf[5];
   char *expstr;
+  wchar_t wexpbuf[5];
+  wchar_t *wexpstr;
   int expnegative;
   int exponent;
 
@@ -140,27 +150,17 @@ __printf_fphex (FILE *fp,
   /* Figure out the decimal point character.  */
   if (info->extra == 0)
     {
-      mbstate_t state;
-
-      memset (&state, '\0', sizeof (state));
-      if (__mbrtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
-		     strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT)),
-		     &state) <= 0)
-	decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+      decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
     }
   else
     {
-      mbstate_t state;
-
-      memset (&state, '\0', sizeof (state));
-      if (__mbrtowc (&decimal, _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT),
-		     strlen (_NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT)),
-		     &state) <= 0)
-	decimal = (wchar_t) *_NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+      decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
+      decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
+				    _NL_MONETARY_DECIMAL_POINT_WC);
     }
-  /* Give default value.  */
-  if (decimal == L'\0')
-    decimal = L'.';
+  /* The decimal point character must never be zero.  */
+  assert (*decimal != '\0' && decimalwc != L'\0');
 
 
   /* Fetch the argument value.	*/
@@ -172,13 +172,33 @@ __printf_fphex (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnanl (fpnum.ldbl.d))
 	{
-	  special = isupper (info->spec) ? "NAN" : "nan";
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	  else
+	    {
+	      special = "nan";
+	      wspecial = L"nan";
+	    }
 	  negative = 0;
 	}
       else
 	{
 	  if (__isinfl (fpnum.ldbl.d))
-	    special = isupper (info->spec) ? "INF" : "inf";
+	    {
+	      if (isupper (info->spec))
+		{
+		  special = "INF";
+		  wspecial = L"INF";
+		}
+	      else
+		{
+		  special = "inf";
+		  wspecial = L"inf";
+		}
+	    }
 
 	  negative = signbit (fpnum.ldbl.d);
 	}
@@ -191,13 +211,33 @@ __printf_fphex (FILE *fp,
       /* Check for special values: not a number or infinity.  */
       if (__isnan (fpnum.dbl.d))
 	{
-	  special = isupper (info->spec) ? "NAN" : "nan";
+	  if (isupper (info->spec))
+	    {
+	      special = "NAN";
+	      wspecial = L"NAN";
+	    }
+	  else
+	    {
+	      special = "nan";
+	      wspecial = L"nan";
+	    }
 	  negative = 0;
 	}
       else
 	{
 	  if (__isinf (fpnum.dbl.d))
-	    special = isupper (info->spec) ? "INF" : "inf";
+	    {
+	      if (isupper (info->spec))
+		{
+		  special = "INF";
+		  wspecial = L"INF";
+		}
+	      else
+		{
+		  special = "inf";
+		  wspecial = L"inf";
+		}
+	    }
 
 	  negative = signbit (fpnum.dbl.d);
 	}
@@ -221,7 +261,7 @@ __printf_fphex (FILE *fp,
       else if (info->space)
 	outchar (' ');
 
-      PRINT (special, 3);
+      PRINT (special, wspecial, 3);
 
       if (info->left && width > 0)
 	PADN (' ', width);
@@ -243,15 +283,26 @@ __printf_fphex (FILE *fp,
       zero_mantissa = num == 0;
 
       if (sizeof (unsigned long int) > 6)
-	numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,
-			     info->spec == 'A');
+	{
+	  wnumstr = _itowa_word (num, wnumbuf + sizeof wnumbuf, 16,
+				 info->spec == 'A');
+	  numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,
+			       info->spec == 'A');
+	}
       else
-	numstr = _itoa (num, numbuf + sizeof numbuf, 16,
-			info->spec == 'A');
+	{
+	  wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf, 16,
+			    info->spec == 'A');
+	  numstr = _itoa (num, numbuf + sizeof numbuf, 16,
+			  info->spec == 'A');
+	}
 
       /* Fill with zeroes.  */
-      while (numstr > numbuf + (sizeof numbuf - 52 / 4))
-	*--numstr = '0';
+      while (wnumstr > wnumbuf + (sizeof wnumbuf - 52 / 4))
+	{
+	  *--wnumstr = L'0';
+	  *--numstr = '0';
+	}
 
       leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1';
 
@@ -287,9 +338,13 @@ __printf_fphex (FILE *fp,
   /* Look for trailing zeroes.  */
   if (! zero_mantissa)
     {
+      wnumend = wnumbuf + sizeof wnumbuf;
       numend = numbuf + sizeof numbuf;
-      while (numend[-1] == '0')
-	--numend;
+      while (wnumend[-1] == L'0')
+	{
+	  --wnumend;
+	  --numend;
+	}
 
       if (precision == -1)
 	precision = numend - numstr;
@@ -316,17 +371,22 @@ __printf_fphex (FILE *fp,
 		 like in ASCII.  This is true for the rest of GNU, too.  */
 	      if (ch == '9')
 		{
+		  wnumstr[cnt] = (wchar_t) info->spec;
 		  numstr[cnt] = info->spec;	/* This is tricky,
-						   think about it!  */
+		  				   think about it!  */
 		  break;
 		}
 	      else if (tolower (ch) < 'f')
 		{
 		  ++numstr[cnt];
+		  ++wnumstr[cnt];
 		  break;
 		}
 	      else
-		numstr[cnt] = '0';
+		{
+		  numstr[cnt] = '0';
+		  wnumstr[cnt] = L'0';
+		}
 	    }
 	  if (cnt < 0)
 	    {
@@ -357,10 +417,12 @@ __printf_fphex (FILE *fp,
       if (precision == -1)
 	precision = 0;
       numend = numstr;
+      wnumend = wnumstr;
     }
 
   /* Now we can compute the exponent string.  */
   expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
+  wexpstr = _itowa_word (exponent, wexpbuf + sizeof wexpbuf, 10, 0);
 
   /* Now we have all information to compute the size.  */
   width -= ((negative || info->showsign || info->space)
@@ -394,11 +456,14 @@ __printf_fphex (FILE *fp,
   outchar (leading);
 
   if (precision > 0 || info->alt)
-    outchar (decimal);
+    {
+      const wchar_t *wtmp = &decimalwc;
+      PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
+    }
 
   if (precision > 0)
     {
-      PRINT (numstr, MIN (numend - numstr, precision));
+      PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
       if (precision > numend - numstr)
 	PADN ('0', precision - (numend - numstr));
     }
@@ -413,7 +478,7 @@ __printf_fphex (FILE *fp,
 
   outchar (expnegative ? '-' : '+');
 
-  PRINT (expstr, (expbuf + sizeof expbuf) - expstr);
+  PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
 
   if (info->left && info->pad != '0' && width > 0)
     PADN (info->pad, width);
diff --git a/sysdeps/ieee754/ldbl-96/printf_fphex.c b/sysdeps/ieee754/ldbl-96/printf_fphex.c
index 1eec1a58a3..36d6014cea 100644
--- a/sysdeps/ieee754/ldbl-96/printf_fphex.c
+++ b/sysdeps/ieee754/ldbl-96/printf_fphex.c
@@ -1,6 +1,5 @@
-/* Print floating point number in hexadecimal notation according to
-   ISO C99.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Print floating point number in hexadecimal notation according to ISO C99.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -36,14 +35,25 @@ do {									      \
       zero_mantissa = num == 0;						      \
 									      \
       if (sizeof (unsigned long int) > 6)				      \
-	numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,		      \
-			     info->spec == 'A');			      \
+	{								      \
+	  numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,		      \
+			       info->spec == 'A');			      \
+	  wnumstr = _itowa_word (num, wnumbuf + sizeof wnumbuf, 16,	      \
+				 info->spec == 'A');			      \
+	}								      \
       else								      \
-	numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');  \
+	{								      \
+	  numstr = _itoa (num, numbuf + sizeof numbuf, 16, info->spec == 'A');\
+	  wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf, 16,		      \
+			    info->spec == 'A');				      \
+	}								      \
 									      \
       /* Fill with zeroes.  */						      \
       while (numstr > numbuf + (sizeof numbuf - 64 / 4))		      \
-	*--numstr = '0';						      \
+	{								      \
+	  *--numstr = '0';						      \
+	  *--wnumstr = L'0';						      \
+	}								      \
 									      \
       /* We use a full nibble for the leading digit.  */		      \
       leading = *numstr++;						      \
diff --git a/sysdeps/unix/sysv/linux/configure b/sysdeps/unix/sysv/linux/configure
index 5105eb694d..e505e876f2 100644
--- a/sysdeps/unix/sysv/linux/configure
+++ b/sysdeps/unix/sysv/linux/configure
@@ -97,6 +97,8 @@ if test "$prefix" = "/usr"; then
     libc_cv_slibdir="/lib64"
     if test "$libdir" = '${exec_prefix}/lib'; then
       libdir='${exec_prefix}/lib64';
+      # Locale data can be shared between 32bit and 64bit libraries
+      libc_cv_localedir='${exec_prefix}/lib/locale'
     fi
   else
     libc_cv_slibdir="/lib"
diff --git a/sysdeps/unix/sysv/linux/configure.in b/sysdeps/unix/sysv/linux/configure.in
index abdfd6fde6..5cb5462950 100644
--- a/sysdeps/unix/sysv/linux/configure.in
+++ b/sysdeps/unix/sysv/linux/configure.in
@@ -68,6 +68,8 @@ if test "$prefix" = "/usr"; then
     libc_cv_slibdir="/lib64"
     if test "$libdir" = '${exec_prefix}/lib'; then
       libdir='${exec_prefix}/lib64';
+      # Locale data can be shared between 32bit and 64bit libraries
+      libc_cv_localedir='${exec_prefix}/lib/locale'
     fi
   else
     libc_cv_slibdir="/lib"