fix types for wctype_t and wctrans_t
authorRich Felker <dalias@aerifal.cx>
Tue, 5 Mar 2013 00:22:14 +0000 (19:22 -0500)
committerRich Felker <dalias@aerifal.cx>
Tue, 5 Mar 2013 00:22:14 +0000 (19:22 -0500)
wctype_t was incorrectly "int" rather than "long" on x86_64. not only
is this an ABI incompatibility; it's also a major design flaw if we
ever wanted wctype_t to be implemented as a pointer, which would be
necessary if locales support custom character classes, since int is
too small to store a converted pointer. this commit fixes wctype_t to
be unsigned long on all archs, matching the LSB ABI; this change does
not matter for C code, but for C++ it affects mangling.

the same issue applied to wctrans_t. glibc/LSB defines this type as
const __int32_t *, but since no such definition is visible, I've just
expanded the definition, int, everywhere.

it would be nice if these types (which don't vary by arch) could be in
wctype.h, but the OB XSI requirement in POSIX that wchar.h expose some
types and functions from wctype.h precludes doing so. glibc works
around this with some hideous hacks, but trying to duplicate that
would go against the intent of musl's headers.

arch/arm/bits/alltypes.h.sh
arch/i386/bits/alltypes.h.sh
arch/microblaze/bits/alltypes.h.sh
arch/mips/bits/alltypes.h.sh
arch/powerpc/bits/alltypes.h.sh
arch/x86_64/bits/alltypes.h.sh
src/ctype/wctrans.c

index 274de0df7d9dcece1ea2a192519f8dc59b3536b2..a531ee0f480be4bff07eeca4592d457a00b8beab 100755 (executable)
@@ -26,8 +26,8 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF unsigned wchar_t;
 #endif
 TYPEDEF int wint_t;
-TYPEDEF long wctrans_t;
-TYPEDEF long wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index 10fcf6a3c46a852d86e287e3ce7918fb2226737a..13def835b6c04ec45cc11e17899b9280276dc171 100755 (executable)
@@ -34,8 +34,8 @@ TYPEDEF long wchar_t;
 #endif
 #endif
 TYPEDEF long wint_t;
-TYPEDEF long wctrans_t;
-TYPEDEF long wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index c909bc37dfb31a8168aeff701ffa70e0a3aa7ef5..2397c6cdc95dc1c612b8b30b4181960aa5513e36 100755 (executable)
@@ -26,8 +26,8 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF int wchar_t;
 #endif
 TYPEDEF int wint_t;
-TYPEDEF long wctrans_t;
-TYPEDEF long wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index c909bc37dfb31a8168aeff701ffa70e0a3aa7ef5..2397c6cdc95dc1c612b8b30b4181960aa5513e36 100755 (executable)
@@ -26,8 +26,8 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF int wchar_t;
 #endif
 TYPEDEF int wint_t;
-TYPEDEF long wctrans_t;
-TYPEDEF long wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index befad081733bc4283aa3dfcf8742f043f38c2633..f3dac12a69574c36d601eebfb3dc7cad213abfd7 100755 (executable)
@@ -26,8 +26,8 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF long wchar_t;
 #endif
 TYPEDEF int wint_t;
-TYPEDEF long wctrans_t;
-TYPEDEF long wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index 083ea2300c033ac87b5ddc1f0cb66cc7f0b914d3..bc9a3cc0139c809f8e24165ffd846cbd436eaa03 100755 (executable)
@@ -25,8 +25,8 @@ TYPEDEF __builtin_va_list va_list;
 TYPEDEF int wchar_t;
 #endif
 TYPEDEF int wint_t;
-TYPEDEF int wctrans_t;
-TYPEDEF int wctype_t;
+TYPEDEF const int * wctrans_t;
+TYPEDEF unsigned long wctype_t;
 
 TYPEDEF signed char int8_t;
 TYPEDEF short       int16_t;
index 03e9fd6ab6b291b197ff0a2faaba5434007e7511..739869d059e4aec9b2f805cdc95d5c703dd711ca 100644 (file)
@@ -3,14 +3,14 @@
 
 wctrans_t wctrans(const char *class)
 {
-       if (!strcmp(class, "toupper")) return 1;
-       if (!strcmp(class, "tolower")) return 2;
+       if (!strcmp(class, "toupper")) return (wctrans_t)1;
+       if (!strcmp(class, "tolower")) return (wctrans_t)2;
        return 0;
 }
 
 wint_t towctrans(wint_t wc, wctrans_t trans)
 {
-       if (trans == 1) return towupper(wc);
-       if (trans == 2) return towlower(wc);
+       if (trans == (wctrans_t)1) return towupper(wc);
+       if (trans == (wctrans_t)2) return towlower(wc);
        return wc;
 }