aboutsummaryrefslogtreecommitdiff
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"