summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--doc/functions/wcwidth.texi8
-rw-r--r--lib/wcwidth.c24
-rw-r--r--m4/wcwidth.m440
-rw-r--r--modules/wcwidth3
5 files changed, 80 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 35b4e12cfe..03b4ecf072 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2007-07-07 Bruno Haible <bruno@clisp.org>
+ Work around MacOS X wcwidth() bug.
+ * m4/wcwidth.m4 (gl_FUNC_WCWIDTH): Test against MacOS X 10.3 bug.
+ * lib/wcwidth.c: Include localcharset.h, streq.h, uniwidth.h.
+ (rpl_wcwidth): Special-case the UTF-8 locales. Fall back to the
+ original wcwidth in non-UTF-8 locales.
+ * modules/wcwidth (Depends-on): Add localcharset, streq,
+ uniwidth/width.
+ * doc/functions/wcwidth.texi: Update.
+
+2007-07-07 Bruno Haible <bruno@clisp.org>
+
* lib/wchar_.h: Include the GL_LINK_WARNING macro.
(wcwidth): New declaration.
* m4/wchar.m4 (gl_WCHAR_MODULE_INDICATOR, gl_WCHAR_H_DEFAULTS): New
diff --git a/doc/functions/wcwidth.texi b/doc/functions/wcwidth.texi
index 082821127d..b9653d13f7 100644
--- a/doc/functions/wcwidth.texi
+++ b/doc/functions/wcwidth.texi
@@ -11,14 +11,14 @@ Portability problems fixed by Gnulib:
@item
This function is missing on some platforms:
Solaris 2.5.1, mingw, BeOS.
-@end itemize
-
-Portability problems not fixed by Gnulib:
-@itemize
@item
This function handles combining characters in UTF-8 locales incorrectly on some
platforms:
MacOS X 10.3.
+@end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
@item
On Windows platforms, @code{wchar_t} is a 16-bit type and therefore cannot
accommodate all Unicode characters.
diff --git a/lib/wcwidth.c b/lib/wcwidth.c
index 57fb0a467b..77042c2ae3 100644
--- a/lib/wcwidth.c
+++ b/lib/wcwidth.c
@@ -23,8 +23,30 @@
/* Get iswprint. */
#include <wctype.h>
+#include "localcharset.h"
+#include "streq.h"
+#include "uniwidth.h"
+
+#undef wcwidth
+
int
rpl_wcwidth (wchar_t wc)
{
- return wc == 0 ? 0 : iswprint (wc) ? 1 : -1;
+ /* In UTF-8 locales, use a Unicode aware width function. */
+ const char *encoding = locale_charset ();
+ if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0))
+ {
+ /* We assume that in a UTF-8 locale, a wide character is the same as a
+ Unicode character. */
+ return uc_width (wc, encoding);
+ }
+ else
+ {
+ /* Otherwise, fall back to the system's wcwidth function. */
+#if HAVE_WCWIDTH
+ return wcwidth (wc);
+#else
+ return wc == 0 ? 0 : iswprint (wc) ? 1 : -1;
+#endif
+ }
}
diff --git a/m4/wcwidth.m4 b/m4/wcwidth.m4
index b6cedc2430..a260998a8b 100644
--- a/m4/wcwidth.m4
+++ b/m4/wcwidth.m4
@@ -1,4 +1,4 @@
-# wcwidth.m4 serial 10
+# wcwidth.m4 serial 11
dnl Copyright (C) 2006, 2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -35,6 +35,44 @@ AC_DEFUN([gl_FUNC_WCWIDTH],
if test $ac_cv_func_wcwidth = no; then
REPLACE_WCWIDTH=1
+ else
+ dnl On MacOS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1.
+ dnl This leads to bugs in 'ls' (coreutils).
+ AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales],
+ [gl_cv_func_wcwidth_works],
+ [
+ AC_TRY_RUN([
+#include <locale.h>
+/* AIX 3.2.5 declares wcwidth in <string.h>. */
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+ <wchar.h>.
+ BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
+ before <wchar.h>. */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+#if !HAVE_DECL_WCWIDTH
+extern
+# ifdef __cplusplus
+"C"
+# endif
+int wcwidth (int);
+#endif
+int main ()
+{
+ if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL)
+ if (wcwidth (0x0301) > 0)
+ return 1;
+ return 0;
+}], [gl_cv_func_wcwidth_works=yes], [gl_cv_func_wcwidth_works=no],
+ [gl_cv_func_wcwidth_works="guessing no"])
+ ])
+ case "$gl_cv_func_wcwidth_works" in
+ *yes) ;;
+ *no) REPLACE_WCWIDTH=1 ;;
+ esac
fi
if test $REPLACE_WCWIDTH = 1; then
AC_LIBOBJ([wcwidth])
diff --git a/modules/wcwidth b/modules/wcwidth
index 622fa228a8..74743947e1 100644
--- a/modules/wcwidth
+++ b/modules/wcwidth
@@ -10,6 +10,9 @@ m4/wint_t.m4
Depends-on:
wchar
wctype
+localcharset
+streq
+uniwidth/width
configure.ac:
gl_FUNC_WCWIDTH