summaryrefslogtreecommitdiffstats
path: root/ndk
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@android.com>2013-07-03 15:54:16 +0200
committerDavid 'Digit' Turner <digit@android.com>2013-07-04 16:30:41 +0200
commitf85e243cdb008ae23b143407535dde73a9c259c0 (patch)
tree391c7f986e77a13952d90a033dbb748f236cd7aa /ndk
parentae9621de63000a4c54e95fc9424f7a02f2d9af9a (diff)
downloadandroid_development-f85e243cdb008ae23b143407535dde73a9c259c0.tar.gz
android_development-f85e243cdb008ae23b143407535dde73a9c259c0.tar.bz2
android_development-f85e243cdb008ae23b143407535dde73a9c259c0.zip
ndk: <sys/cdefs.h>: make wchar_t 32-bit for all API levels.
This patch ensures that wchar_t is a 32-bit number when targetting API level < 9 (i.e. Froyo or older). You can restore the previous (and broken) behaviour by defining _WCHAR_IS_8BIT at compile time. See http://b.android.com/57267 for more context. BUG=57267 Change-Id: Ib334e8fe95a3f592d5d4bb157b0f123984133597
Diffstat (limited to 'ndk')
-rw-r--r--ndk/platforms/android-3/include/sys/cdefs.h31
-rw-r--r--ndk/platforms/android-3/include/wchar.h33
-rw-r--r--ndk/platforms/android-8/include/wchar.h33
3 files changed, 90 insertions, 7 deletions
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 <wchar.h>.
+ *
+ * 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 <wchar.h> 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.h> -> <stdio.h> -> <sys/types.h> -> <stdint.h>
+ *
+ * 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 <stdint.h> */
+# 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.h> -> <stdio.h> -> <sys/types.h> -> <stdint.h>
+ *
+ * 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 <stdint.h> */
+# 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 *, ...);