summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2009-09-08 23:27:09 +0200
committerBruno Haible <bruno@clisp.org>2009-09-08 23:27:09 +0200
commit28db629d4f20b514087389b0339b5ba8c83a707b (patch)
tree2d3cae6d8a7f2a8e94f1427feec3bc2e7e39c0a6
parent6588bee3103aceaf840cb073ef5717d85d3e412a (diff)
downloadgnulib-28db629d4f20b514087389b0339b5ba8c83a707b.tar.gz
Work around towlower, towupper bug on mingw.
-rw-r--r--ChangeLog9
-rw-r--r--doc/posix-functions/towlower.texi4
-rw-r--r--doc/posix-functions/towupper.texi4
-rw-r--r--lib/wctype.in.h31
-rw-r--r--m4/wctype.m413
5 files changed, 59 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 5391614538..f055a3cf5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-08 Bruno Haible <bruno@clisp.org>
+
+ Work around towlower, towupper bug on mingw.
+ * lib/wctype.in.h (towlower, towupper) [__MINGW32__]: New replacements.
+ * m4/wctype.m4 (gl_WCTYPE_H): Replace <wctype.h> also on mingw.
+ * doc/posix-functions/towlower.texi: Mention the mingw bug.
+ * doc/posix-functions/towupper.texi: Likewise.
+ Reported by Eric Blake.
+
2009-09-08 Jim Meyering <meyering@redhat.com>
build: don't try to run autoheader if we don't use it
diff --git a/doc/posix-functions/towlower.texi b/doc/posix-functions/towlower.texi
index 9857c56a74..18b6eda067 100644
--- a/doc/posix-functions/towlower.texi
+++ b/doc/posix-functions/towlower.texi
@@ -11,6 +11,10 @@ Portability problems fixed by Gnulib:
@item
This function is missing on some platforms:
IRIX 5.3, Solaris 2.5.1.
+@item
+This function returns values of which the upper 16 bits are incorrect
+on some platforms:
+mingw.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/doc/posix-functions/towupper.texi b/doc/posix-functions/towupper.texi
index 2fd8aea20c..d63469b137 100644
--- a/doc/posix-functions/towupper.texi
+++ b/doc/posix-functions/towupper.texi
@@ -11,6 +11,10 @@ Portability problems fixed by Gnulib:
@item
This function is missing on some platforms:
IRIX 5.3, Solaris 2.5.1.
+@item
+This function returns values of which the upper 16 bits are incorrect
+on some platforms:
+mingw.
@end itemize
Portability problems not fixed by Gnulib:
diff --git a/lib/wctype.in.h b/lib/wctype.in.h
index 66e095a374..835185f46f 100644
--- a/lib/wctype.in.h
+++ b/lib/wctype.in.h
@@ -196,5 +196,36 @@ towupper (wint_t wc)
# endif /* ! HAVE_ISWCNTRL */
+# if defined __MINGW32__
+
+/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
+ The functions towlower and towupper are implemented in the MSVCRT library
+ to take a wchar_t argument and return a wchar_t result. mingw declares
+ these functions to take a wint_t argument and return a wint_t result.
+ This means that:
+ 1. When the user passes an argument outside the range 0x0000..0xFFFF, the
+ function will look only at the lower 16 bits. This is allowed according
+ to POSIX.
+ 2. The return value is returned in the lower 16 bits of the result register.
+ The upper 16 bits are random: whatever happened to be in that part of the
+ result register. We need to fix this by adding a zero-extend from
+ wchar_t to wint_t after the call. */
+
+static inline wint_t
+rpl_towlower (wint_t wc)
+{
+ return (wint_t) (wchar_t) towlower (wc);
+}
+# define towlower rpl_towlower
+
+static inline wint_t
+rpl_towupper (wint_t wc)
+{
+ return (wint_t) (wchar_t) towupper (wc);
+}
+# define towupper rpl_towupper
+
+# endif
+
#endif /* _GL_WCTYPE_H */
#endif /* _GL_WCTYPE_H */
diff --git a/m4/wctype.m4 b/m4/wctype.m4
index 6a1b6f07f4..1eb55a412f 100644
--- a/m4/wctype.m4
+++ b/m4/wctype.m4
@@ -1,4 +1,4 @@
-# wctype.m4 serial 2
+# wctype.m4 serial 3
dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
@@ -12,6 +12,7 @@ dnl Written by Paul Eggert.
AC_DEFUN([gl_WCTYPE_H],
[
AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS_ONCE([iswcntrl])
if test $ac_cv_func_iswcntrl = yes; then
HAVE_ISWCNTRL=1
@@ -52,7 +53,15 @@ AC_DEFUN([gl_WCTYPE_H],
])
])
if test $gl_cv_func_iswcntrl_works = yes; then
- WCTYPE_H=
+ case "$host_os" in
+ mingw*)
+ dnl On mingw, towlower and towupper return random high 16 bits.
+ ;;
+ *)
+ dnl iswcntrl works. towlower and towupper work as well.
+ WCTYPE_H=
+ ;;
+ esac
fi
fi
dnl Compute NEXT_WCTYPE_H even if WCTYPE_H is empty,