diff --git a/ndk/platforms/android-3/include/sys/cdefs.h b/ndk/platforms/android-3/include/sys/cdefs.h index 27c575c87..88ce720b2 100644 --- a/ndk/platforms/android-3/include/sys/cdefs.h +++ b/ndk/platforms/android-3/include/sys/cdefs.h @@ -37,11 +37,36 @@ #ifndef _SYS_CDEFS_H_ #define _SYS_CDEFS_H_ - -/* our implementation of wchar_t is only 8-bit - die die non-portable code */ +/* In previous NDK releases, wchar_t was defined as 'unsigned char' + * when targetting API level < 9 (i.e. Froyo or older). + * + * This is no longer the case, but you can define _WCHAR_IS_8BIT + * at compile time to restore the old behaviour. + * + * The reason for this redefine is purely historical. Until Android 2.3, + * i.e. API level 9, there was absolutely no official support for wchar_t + * in the C library, but compiling GCC and the GNU libstdc++ required a + * working . + * + * To allow this while keeping the C library small, wchar_t was redefined + * explicitely as an 8-bit unsigned integer (which is perfectly allowed + * by the standard) and a very small set of wcs-xxx functions provided + * as wrappers around the corresponding str-xxx ones. + * + * Starting with API level 9, wchar_t is properly defined as a 32-bit + * type (as mandated by the compiler itself), and the lines below + * were removed (see $NDK/platforms/android-9/include/sys/cdefs.h). + * + * Note that this only affects C source compilation. For C++, wchar_t + * is a compiler keyboard that cannot be redefined and is always 32-bit. + * + * On the other hand, _WCHAR_IS_8BIT also affects the definition of + * WCHAR_MIN, WCHAR_MAX and WEOF (see comments). + */ +#ifdef _WCHAR_IS_8BIT #undef __WCHAR_TYPE__ #define __WCHAR_TYPE__ unsigned char - +#endif /* * Macro to test if we're using a GNU C compiler of a specific vintage diff --git a/ndk/platforms/android-3/include/wchar.h b/ndk/platforms/android-3/include/wchar.h index ecbf921fd..836ad30e1 100644 --- a/ndk/platforms/android-3/include/wchar.h +++ b/ndk/platforms/android-3/include/wchar.h @@ -70,12 +70,41 @@ typedef enum { WC_TYPE_MAX } wctype_t; +/* TECHNICAL NOTE: This is tricky! + * + * Due to the following inclusion chain: + * -> -> -> + * + * WCHAR_MIN / WCHAR_MAX will already be defined to INT32_MIN / INT32_MAX + * when reaching this line in the following cases: + * - Compiling C source code. + * - Compiling C++ source code AND having __STDC_LIMIT_MACROS defined. + * + * When _WCHAR_IS_8BIT is defined, it should emulate the old behaviour. + * which was to (conditionally) set the values to 0 and 255, respectively. + */ #ifndef WCHAR_MAX -#define WCHAR_MAX 255 -#define WCHAR_MIN 0 +# ifdef _WCHAR_IS_8BIT +# define WCHAR_MAX 255 +# define WCHAR_MIN 0 +# else +/* Same values as INT32_MIN/INT32_MAX, without including */ +# define WCHAR_MAX (2147483647) +# define WCHAR_MIN (-1-2147483647) +# endif #endif +/* Similarly, WEOF used to be defined as simply -1, which is + * invalid (the standard mandates that the expression must have wint_t + * type). There is no difference in C, but there is one in C++!! + * + * Revert to the old broken behaviour is _WCHAR_IS_8BIT is defined. + */ +#ifdef _WCHAR_IS_8BIT #define WEOF (-1) +#else +#define WEOF ((wint_t)-1) +#endif extern wint_t btowc(int); extern int fwprintf(FILE *, const wchar_t *, ...); diff --git a/ndk/platforms/android-8/include/wchar.h b/ndk/platforms/android-8/include/wchar.h index efe60bb74..e67b0be73 100644 --- a/ndk/platforms/android-8/include/wchar.h +++ b/ndk/platforms/android-8/include/wchar.h @@ -70,12 +70,41 @@ typedef enum { WC_TYPE_MAX } wctype_t; +/* TECHNICAL NOTE: This is tricky! + * + * Due to the following inclusion chain: + * -> -> -> + * + * WCHAR_MIN / WCHAR_MAX will already be defined to INT32_MIN / INT32_MAX + * when reaching this line in the following cases: + * - Compiling C source code. + * - Compiling C++ source code AND having __STDC_LIMIT_MACROS defined. + * + * When _WCHAR_IS_8BIT is defined, it should emulate the old behaviour. + * which was to set the values to 0 and 255, respectively. + */ #ifndef WCHAR_MAX -#define WCHAR_MAX 255 -#define WCHAR_MIN 0 +# ifdef _WCHAR_IS_8BIT +# define WCHAR_MAX 255 +# define WCHAR_MIN 0 +# else +/* Same values as INT32_MIN/INT32_MAX, without including */ +# define WCHAR_MAX (2147483647) +# define WCHAR_MIN (-1-2147483647) +# endif #endif +/* Similarly, WEOF used to be defined as simply -1, which is + * invalid (the standard mandates that the expression must have wint_t + * type). There is no difference in C, but there is one in C++!! + * + * Revert to the old broken behaviour is _WCHAR_IS_8BIT is defined. + */ +#ifdef _WCHAR_IS_8BIT #define WEOF (-1) +#else +#define WEOF ((wint_t)-1) +#endif extern wint_t btowc(int); extern int fwprintf(FILE *, const wchar_t *, ...);