From: Rich Felker Date: Tue, 5 Mar 2013 00:22:14 +0000 (-0500) Subject: fix types for wctype_t and wctrans_t X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=commitdiff_plain;h=da1442c9a8c58f8ad85a1bd96007f60bc372d157;hp=8c741783fc96d559cfe79301c924c217b2905c0c fix types for wctype_t and wctrans_t 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. --- diff --git a/arch/arm/bits/alltypes.h.sh b/arch/arm/bits/alltypes.h.sh index 274de0df..a531ee0f 100755 --- a/arch/arm/bits/alltypes.h.sh +++ b/arch/arm/bits/alltypes.h.sh @@ -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; diff --git a/arch/i386/bits/alltypes.h.sh b/arch/i386/bits/alltypes.h.sh index 10fcf6a3..13def835 100755 --- a/arch/i386/bits/alltypes.h.sh +++ b/arch/i386/bits/alltypes.h.sh @@ -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; diff --git a/arch/microblaze/bits/alltypes.h.sh b/arch/microblaze/bits/alltypes.h.sh index c909bc37..2397c6cd 100755 --- a/arch/microblaze/bits/alltypes.h.sh +++ b/arch/microblaze/bits/alltypes.h.sh @@ -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; diff --git a/arch/mips/bits/alltypes.h.sh b/arch/mips/bits/alltypes.h.sh index c909bc37..2397c6cd 100755 --- a/arch/mips/bits/alltypes.h.sh +++ b/arch/mips/bits/alltypes.h.sh @@ -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; diff --git a/arch/powerpc/bits/alltypes.h.sh b/arch/powerpc/bits/alltypes.h.sh index befad081..f3dac12a 100755 --- a/arch/powerpc/bits/alltypes.h.sh +++ b/arch/powerpc/bits/alltypes.h.sh @@ -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; diff --git a/arch/x86_64/bits/alltypes.h.sh b/arch/x86_64/bits/alltypes.h.sh index 083ea230..bc9a3cc0 100755 --- a/arch/x86_64/bits/alltypes.h.sh +++ b/arch/x86_64/bits/alltypes.h.sh @@ -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; diff --git a/src/ctype/wctrans.c b/src/ctype/wctrans.c index 03e9fd6a..739869d0 100644 --- a/src/ctype/wctrans.c +++ b/src/ctype/wctrans.c @@ -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; }