aboutsummaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2017-06-15 15:55:44 -0700
committerDan Albert <danalbert@google.com>2017-06-30 00:34:59 -0700
commit38a97131f3e63df180201af353db030b992ad493 (patch)
tree0cc6394221f3ea5917bc4cc6db5b608ef6491a13 /sources
parent355d3d664e11e2f65652e36934836a46efd29807 (diff)
downloadndk-38a97131f3e63df180201af353db030b992ad493.tar.gz
Remove musl stdio from libandroid_support.
Historically this is where the libandroid_support bugs are. The only things we lose by dropping this is support for %a in printf and functioning versions of *wprintf functions. Parts of libc++ that rely on the former are just being marked XFAIL for the moment (it's only needed for serialization of RNG state to stringstreams, something that doesn't seem all that important). We'll pick up Bionic's *sprintf family later to fix this. We've actually had definitions for the latter forever, but they just return -1 and set errno to ENOTSUP. The functions existing but not working actually causes std::to_wstring to OOM (it allocates an increasingly large wstring until it finds one that doesn't fail, and never does), which in turn causes OOM killer to kill the device. We can avoid this by implementing swprintf in terms of snprintf, using wcsrtombs and mbsrtowcs to translate. The only thing that doesn't work in this case is %ls. Since we're delegating to the device's snprintf, that will not work on old devices, but will work on new devices, so this only improves functionality. We need to pull in part of bionic's wide character implementation for this, because musl's isn't correct. Also disable a %a test for pre-L. We didn't have support for this until L, and it's temporarily being removed from libandroid_support. Test: ./checkbuild.py && ./run_tests.py Bug: https://github.com/android-ndk/ndk/issues/300 Bug: https://github.com/android-ndk/ndk/issues/437 Change-Id: Ic70c0d3f6f439de2e1c19027ec4fd3d37b766f77
Diffstat (limited to 'sources')
-rw-r--r--sources/android/support/Android.mk60
-rw-r--r--sources/android/support/include/langinfo.h93
-rw-r--r--sources/android/support/include/uchar.h19
-rw-r--r--sources/android/support/include/wchar.h210
-rw-r--r--sources/android/support/src/UniquePtr.h135
-rw-r--r--sources/android/support/src/musl-multibyte/btowc.c7
-rw-r--r--sources/android/support/src/musl-multibyte/internal.c36
-rw-r--r--sources/android/support/src/musl-multibyte/internal.h23
-rw-r--r--sources/android/support/src/musl-multibyte/libc.h8
-rw-r--r--sources/android/support/src/musl-multibyte/mbrlen.c13
-rw-r--r--sources/android/support/src/musl-multibyte/mbrtowc.c54
-rw-r--r--sources/android/support/src/musl-multibyte/mbsinit.c12
-rw-r--r--sources/android/support/src/musl-multibyte/mbsnrtowcs.c59
-rw-r--r--sources/android/support/src/musl-multibyte/mbsrtowcs.c101
-rw-r--r--sources/android/support/src/musl-multibyte/mbstowcs.c7
-rw-r--r--sources/android/support/src/musl-multibyte/mbtowc.c50
-rw-r--r--sources/android/support/src/musl-multibyte/wcrtomb.c34
-rw-r--r--sources/android/support/src/musl-multibyte/wcsnrtombs.c47
-rw-r--r--sources/android/support/src/musl-multibyte/wcsrtombs.c61
-rw-r--r--sources/android/support/src/musl-multibyte/wcstombs.c7
-rw-r--r--sources/android/support/src/musl-multibyte/wctob.c8
-rw-r--r--sources/android/support/src/musl-multibyte/wctomb.c14
-rw-r--r--sources/android/support/src/musl-stdio/printf.c12
-rw-r--r--sources/android/support/src/musl-stdio/snprintf.c13
-rw-r--r--sources/android/support/src/musl-stdio/sprintf.c12
-rw-r--r--sources/android/support/src/musl-stdio/swprintf.c13
-rw-r--r--sources/android/support/src/musl-stdio/vprintf.c6
-rw-r--r--sources/android/support/src/musl-stdio/vsprintf.c7
-rw-r--r--sources/android/support/src/musl-stdio/vwprintf.c7
-rw-r--r--sources/android/support/src/musl-stdio/vwscanf.c11
-rw-r--r--sources/android/support/src/musl-stdio/wprintf.c13
-rw-r--r--sources/android/support/src/musl-stdio/wscanf.c16
-rw-r--r--sources/android/support/src/stdio/vfprintf.c781
-rw-r--r--sources/android/support/src/stdio/vfwprintf.c431
-rw-r--r--sources/android/support/src/swprintf.cpp88
-rw-r--r--sources/android/support/tests/stdio_test.cpp13
36 files changed, 306 insertions, 2175 deletions
diff --git a/sources/android/support/Android.mk b/sources/android/support/Android.mk
index 7f594b0bf..a47875745 100644
--- a/sources/android/support/Android.mk
+++ b/sources/android/support/Android.mk
@@ -3,6 +3,12 @@ LOCAL_PATH := $(call my-dir)
android_support_c_includes := $(LOCAL_PATH)/include
ifneq ($(filter $(NDK_KNOWN_DEVICE_ABI64S),$(TARGET_ARCH_ABI)),)
+ is_lp64 := true
+else
+ is_lp64 :=
+endif
+
+ifeq ($(is_lp64),true)
# 64-bit ABIs
android_support_sources := \
src/locale_support.c \
@@ -42,36 +48,9 @@ android_support_sources := \
src/musl-math/frexp.c \
src/musl-math/frexpf.c \
src/musl-math/frexpl.c \
- src/musl-multibyte/btowc.c \
- src/musl-multibyte/internal.c \
- src/musl-multibyte/mblen.c \
- src/musl-multibyte/mbrlen.c \
- src/musl-multibyte/mbrtowc.c \
- src/musl-multibyte/mbsinit.c \
- src/musl-multibyte/mbsnrtowcs.c \
- src/musl-multibyte/mbsrtowcs.c \
- src/musl-multibyte/mbstowcs.c \
- src/musl-multibyte/mbtowc.c \
- src/musl-multibyte/wcrtomb.c \
- src/musl-multibyte/wcsnrtombs.c \
- src/musl-multibyte/wcsrtombs.c \
- src/musl-multibyte/wcstombs.c \
- src/musl-multibyte/wctob.c \
- src/musl-multibyte/wctomb.c \
- src/musl-stdio/printf.c \
- src/musl-stdio/snprintf.c \
- src/musl-stdio/sprintf.c \
- src/musl-stdio/swprintf.c \
- src/musl-stdio/vprintf.c \
- src/musl-stdio/vsprintf.c \
- src/musl-stdio/vwprintf.c \
- src/musl-stdio/wprintf.c \
src/posix_memalign.cpp \
- src/stdio/stdio_impl.c \
- src/stdio/strtod.c \
- src/stdio/vfprintf.c \
- src/stdio/vfwprintf.c \
src/stdlib_support.c \
+ src/swprintf.cpp \
src/wchar_support.c \
src/wcstox/floatscan.c \
src/wcstox/intscan.c \
@@ -103,13 +82,22 @@ include $(PREBUILT_STATIC_LIBRARY)
else # Building
+BIONIC_PATH := ../../../../bionic
+
# This is only available as a static library for now.
include $(CLEAR_VARS)
LOCAL_MODULE := android_support
LOCAL_SRC_FILES := $(android_support_sources)
LOCAL_C_INCLUDES := $(android_support_c_includes)
-LOCAL_CFLAGS += -Drestrict=__restrict__ -ffunction-sections -fdata-sections -fvisibility=hidden
-LOCAL_CPPFLAGS += -fvisibility-inlines-hidden
+LOCAL_CFLAGS := \
+ -Drestrict=__restrict__ \
+ -ffunction-sections \
+ -fdata-sections \
+ -fvisibility=hidden \
+
+LOCAL_CPPFLAGS := \
+ -fvisibility-inlines-hidden \
+ -std=c++11 \
# These Clang warnings are triggered by the Musl sources. The code is fine,
# but we don't want to modify it. TODO(digit): This is potentially dangerous,
@@ -125,6 +113,18 @@ LOCAL_CFLAGS += \
endif
LOCAL_EXPORT_C_INCLUDES := $(android_support_c_includes)
+
+ifneq ($(is_lp64),true)
+LOCAL_SRC_FILES += \
+ $(BIONIC_PATH)/libc/bionic/c32rtomb.cpp \
+ $(BIONIC_PATH)/libc/bionic/mbstate.cpp \
+ $(BIONIC_PATH)/libc/bionic/mbrtoc32.cpp \
+ $(BIONIC_PATH)/libc/bionic/wchar.cpp \
+ $(BIONIC_PATH)/libc/upstream-openbsd/lib/libc/locale/mbtowc.c \
+
+LOCAL_C_INCLUDES += $(BIONIC_PATH)/libc
+endif
+
include $(BUILD_STATIC_LIBRARY)
endif # Prebuilt/building
diff --git a/sources/android/support/include/langinfo.h b/sources/android/support/include/langinfo.h
index c3ae04da3..1a37ad508 100644
--- a/sources/android/support/include/langinfo.h
+++ b/sources/android/support/include/langinfo.h
@@ -28,97 +28,16 @@
#ifndef NDK_ANDROID_SUPPORT_LANGINFO_H
#define NDK_ANDROID_SUPPORT_LANGINFO_H
-// __LP64__
+#include_next <langinfo.h>
-#include <nl_types.h>
+__BEGIN_DECLS
-#define _NL_ITEM(category,index) (((category) << 10) | (index))
+#if __ANDROID_API__ < __ANDROID_API_O__
-#define _NL_ITEM_CATEGORY(nl) ((nl) >> 10)
-#define _NL_ITEM_INDEX(nl) ((nl) & 0x3ff)
+char* nl_langinfo(nl_item);
-#define CODESET _NL_ITEM(LC_CTYPE, 0)
-
-/* Abbreviated days of the week */
-#define ABDAY_1 _NL_ITEM(LC_TIME,1)
-#define ABDAY_2 _NL_ITEM(LC_TIME,2)
-#define ABDAY_3 _NL_ITEM(LC_TIME,3)
-#define ABDAY_4 _NL_ITEM(LC_TIME,4)
-#define ABDAY_5 _NL_ITEM(LC_TIME,5)
-#define ABDAY_6 _NL_ITEM(LC_TIME,6)
-#define ABDAY_7 _NL_ITEM(LC_TIME,7)
-
-/* Long names of the week */
-#define DAY_1 _NL_ITEM(LC_TIME,11)
-#define DAY_2 _NL_ITEM(LC_TIME,12)
-#define DAY_3 _NL_ITEM(LC_TIME,13)
-#define DAY_4 _NL_ITEM(LC_TIME,14)
-#define DAY_5 _NL_ITEM(LC_TIME,15)
-#define DAY_6 _NL_ITEM(LC_TIME,16)
-#define DAY_7 _NL_ITEM(LC_TIME,17)
-
-/* Abbreviated month names */
-#define ABMON_1 _NL_ITEM(LC_TIME,21)
-#define ABMON_2 _NL_ITEM(LC_TIME,22)
-#define ABMON_3 _NL_ITEM(LC_TIME,23)
-#define ABMON_4 _NL_ITEM(LC_TIME,24)
-#define ABMON_5 _NL_ITEM(LC_TIME,25)
-#define ABMON_6 _NL_ITEM(LC_TIME,26)
-#define ABMON_7 _NL_ITEM(LC_TIME,27)
-#define ABMON_8 _NL_ITEM(LC_TIME,28)
-#define ABMON_9 _NL_ITEM(LC_TIME,29)
-#define ABMON_10 _NL_ITEM(LC_TIME,30)
-#define ABMON_11 _NL_ITEM(LC_TIME,31)
-#define ABMON_12 _NL_ITEM(LC_TIME,32)
-
-/* Long month names */
-#define MON_1 _NL_ITEM(LC_TIME,41)
-#define MON_2 _NL_ITEM(LC_TIME,42)
-#define MON_3 _NL_ITEM(LC_TIME,43)
-#define MON_4 _NL_ITEM(LC_TIME,44)
-#define MON_5 _NL_ITEM(LC_TIME,45)
-#define MON_6 _NL_ITEM(LC_TIME,46)
-#define MON_7 _NL_ITEM(LC_TIME,47)
-#define MON_8 _NL_ITEM(LC_TIME,48)
-#define MON_9 _NL_ITEM(LC_TIME,49)
-#define MON_10 _NL_ITEM(LC_TIME,50)
-#define MON_11 _NL_ITEM(LC_TIME,51)
-#define MON_12 _NL_ITEM(LC_TIME,52)
-
-#define AM_STR _NL_ITEM(LC_TIME,53)
-#define PM_STR _NL_ITEM(LC_TIME,54)
-#define D_T_FMT _NL_ITEM(LC_TIME,55)
-#define D_FMT _NL_ITEM(LC_TIME,56)
-#define T_FMT _NL_ITEM(LC_TIME,57)
-#define T_FMT_AMPM _NL_ITEM(LC_TIME,58)
-#define ERA _NL_ITEM(LC_TIME,59)
-#define ERA_D_FMT _NL_ITEM(LC_TIME,60)
-#define ERA_D_T_FMT _NL_ITEM(LC_TIME,61)
-#define ERA_T_FMT _NL_ITEM(LC_TIME,62)
-#define ALT_DIGITS _NL_ITEM(LC_TIME,70)
-
-#define INT_CURRENCY_SYMBOL _NL_ITEM(LC_MONETARY,0)
-#define CURRENCY_SYMBOL _NL_ITEM(LC_MONETARY,1)
-#define MON_DECIMAL_POINT _NL_ITEM(LC_MONETARY,2)
-#define MON_THOUSANDS_SEP _NL_ITEM(LC_MONETARY,3)
-#define MON_GROUPING _NL_ITEM(LC_MONETARY,4)
-#define POSITIVE_SIGN _NL_ITEM(LC_MONETARY,5)
-#define NEGATIVE_SIGN _NL_ITEM(LC_MONETARY,6)
-#define INT_FRAC_DIGITS _NL_ITEM(LC_MONETARY,7)
-#define FRAC_DIGITS _NL_ITEM(LC_MONETARY,8)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(__LP64__)
-char *nl_langinfo(nl_item);
-char *nl_langinfo_l(nl_item, locale_t);
-#endif // !__LP64__
-
-#ifdef __cplusplus
-} // extern "C"
#endif
-#endif /* NDK_ANDROID_SUPPORT_LANGINFO_H */
+__END_DECLS
+#endif /* NDK_ANDROID_SUPPORT_LANGINFO_H */
diff --git a/sources/android/support/include/uchar.h b/sources/android/support/include/uchar.h
index a9de0718f..5028aa5dc 100644
--- a/sources/android/support/include/uchar.h
+++ b/sources/android/support/include/uchar.h
@@ -28,8 +28,23 @@
#ifndef NDK_ANDROID_SUPPORT_UCHAR_H
#define NDK_ANDROID_SUPPORT_UCHAR_H
-// __LP64__
+#include_next <uchar.h>
-#warning Not implemented
+__BEGIN_DECLS
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+size_t c16rtomb(char* __restrict, char16_t, mbstate_t* __restrict)
+ __INTRODUCED_IN(21);
+size_t c32rtomb(char* __restrict, char32_t, mbstate_t* __restrict)
+ __INTRODUCED_IN(21);
+size_t mbrtoc16(char16_t* __restrict, const char* __restrict, size_t,
+ mbstate_t* __restrict) __INTRODUCED_IN(21);
+size_t mbrtoc32(char32_t* __restrict, const char* __restrict, size_t,
+ mbstate_t* __restrict) __INTRODUCED_IN(21);
+
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
+
+__END_DECLS
#endif // NDK_ANDROID_SUPPORT_UCHAR_H
diff --git a/sources/android/support/include/wchar.h b/sources/android/support/include/wchar.h
index 8947bcf84..a1b7b37b7 100644
--- a/sources/android/support/include/wchar.h
+++ b/sources/android/support/include/wchar.h
@@ -25,207 +25,37 @@
#ifndef NDK_ANDROID_SUPPORT_WCHAR_H
#define NDK_ANDROID_SUPPORT_WCHAR_H
-/* IMPORTANT NOTE: Unlike other headers in the support library, this
- * one doesn't try to include the Bionic header through #include_next.
- *
- * This is intentional, and comes from the fact that before Gingerbread,
- * i.e. API level 9, the platform didn't really support wide chars, more
- * precisely:
- * - wchar_t is defined as an 8-bit unsigned integer.
- * - the few wchar-related functions available are just stubs
- * to their 8-bit counterparts (e.g. wcslen() -> strlen()).
- *
- * Starting from API level 9, wchar_t is a 32-bit unsigned integer,
- * and wchar-related functions implement support for it with several
- * gotchas:
- * - no proper Unicode support (e.g. towlower() only works on ASCII
- * codepoints, ignores all others).
- *
- * - no wprintf() and wscanf() functionality.
- *
- * - no multi-byte conversion routines.
- *
- * By completely overriding the C library functions, the support library
- * can be used to generate code that will run properly on _any_ version
- * of Android.
- *
- * This implementation supports the following:
- *
- * - Unicode code points in wchar_t, and working towlower() / towupper()
- * using the en_US.UTF-8 case mappings.
- *
- * - Multi-byte encoding/decoding to/from UTF-8 (no other multibyte
- * encoding are supported).
- *
- * - wprintf() / wfprintf() support.
- *
- * - wscanf() / wfscanf() coming soon :)
- */
-#if defined(__LP64__)
-
#include_next <wchar.h>
-#else
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdarg.h> // for va_list
-#include <stdio.h> // for FILE
-#include <stddef.h> // for size_t
-#include <wctype.h>
-#include <xlocale.h> // for locale_t
-
-#define __need___wchar_t
-#include <stddef.h>
-
-#ifndef WCHAR_MAX
-#define WCHAR_MAX __WCHAR_MAX__
-/* Clang does not define __WCHAR_MIN__ */
-#if defined(__WCHAR_UNSIGNED__)
-#define WCHAR_MIN L'\0'
-#else
-#define WCHAR_MIN (-(WCHAR_MAX) - 1)
-#endif
-#endif
-
-#define WEOF ((wint_t)(-1))
-
-typedef struct
-{
- unsigned __opaque1, __opaque2;
-} mbstate_t;
-
-wchar_t *wcscpy (wchar_t *__restrict__, const wchar_t *__restrict__);
-wchar_t *wcsncpy (wchar_t *__restrict__, const wchar_t *__restrict__, size_t);
-
-wchar_t *wcscat (wchar_t *__restrict__, const wchar_t *__restrict__);
-wchar_t *wcsncat (wchar_t *__restrict__, const wchar_t *__restrict__, size_t);
-
-int wcscmp (const wchar_t *, const wchar_t *);
-int wcsncmp (const wchar_t *, const wchar_t *, size_t);
-
-int wcscoll(const wchar_t *, const wchar_t *);
-size_t wcsxfrm (wchar_t *__restrict__, const wchar_t *__restrict__, size_t n);
-
-wchar_t *wcschr (const wchar_t *, wchar_t);
-wchar_t *wcsrchr (const wchar_t *, wchar_t);
-
-size_t wcscspn (const wchar_t *, const wchar_t *);
-size_t wcsspn (const wchar_t *, const wchar_t *);
-wchar_t *wcspbrk (const wchar_t *, const wchar_t *);
-
-wchar_t *wcstok (wchar_t *__restrict__, const wchar_t *__restrict__, wchar_t **__restrict__);
-
-size_t wcslen (const wchar_t *);
-
-wchar_t *wcsstr (const wchar_t *__restrict__, const wchar_t *__restrict__);
-wchar_t *wcswcs (const wchar_t *, const wchar_t *);
-
-wchar_t *wmemchr (const wchar_t *, wchar_t, size_t);
-int wmemcmp (const wchar_t *, const wchar_t *, size_t);
-wchar_t *wmemcpy (wchar_t *__restrict__, const wchar_t *__restrict__, size_t);
-wchar_t *wmemmove (wchar_t *, const wchar_t *, size_t);
-wchar_t *wmemset (wchar_t *, wchar_t, size_t);
-
-wint_t btowc (int);
-int wctob (wint_t);
-
-int mbsinit (const mbstate_t *);
-size_t mbrtowc (wchar_t *__restrict__, const char *__restrict__, size_t, mbstate_t *__restrict__);
-size_t wcrtomb (char *__restrict__, wchar_t, mbstate_t *__restrict__);
-
-size_t mbrlen (const char *__restrict__, size_t, mbstate_t *__restrict__);
-
-size_t mbsrtowcs (wchar_t *__restrict__, const char **__restrict__, size_t, mbstate_t *__restrict__);
-size_t wcsrtombs (char *__restrict__, const wchar_t **__restrict__, size_t, mbstate_t *__restrict__);
-
-float wcstof (const wchar_t *__restrict__, wchar_t **__restrict__);
-double wcstod (const wchar_t *__restrict__, wchar_t **__restrict__);
-long double wcstold (const wchar_t *__restrict__, wchar_t **__restrict__);
-
-long wcstol (const wchar_t *__restrict__, wchar_t **__restrict__, int);
-unsigned long wcstoul (const wchar_t *__restrict__, wchar_t **__restrict__, int);
+__BEGIN_DECLS
-long long wcstoll (const wchar_t *__restrict__, wchar_t **__restrict__, int);
-unsigned long long wcstoull (const wchar_t *__restrict__, wchar_t **__restrict__, int);
-intmax_t wcstoimax (const wchar_t * nptr, wchar_t** endptr , int base);
-uintmax_t wcstoumax (const wchar_t * nptr, wchar_t** endptr , int base);
+#if __ANDROID_API__ < __ANDROID_API_L__
+size_t mbsnrtowcs(wchar_t*, const char**, size_t, size_t, mbstate_t*);
+int vswprintf(wchar_t*, size_t, const wchar_t*, va_list);
+size_t wcsnrtombs(char*, const wchar_t**, size_t, size_t, mbstate_t*);
+float wcstof(const wchar_t*, wchar_t**);
+long long wcstoll(const wchar_t*, wchar_t**, int);
+long double wcstold(const wchar_t*, wchar_t**);
+unsigned long long wcstoull(const wchar_t*, wchar_t**, int);
-int fwide (FILE *, int);
+size_t wcslcat(wchar_t*, const wchar_t*, size_t);
+size_t wcslcpy(wchar_t*, const wchar_t*, size_t);
+intmax_t wcstoimax(const wchar_t* nptr, wchar_t** endptr, int base);
+uintmax_t wcstoumax(const wchar_t* nptr, wchar_t** endptr, int base);
-int wprintf (const wchar_t *__restrict__, ...);
-int fwprintf (FILE *__restrict__, const wchar_t *__restrict__, ...);
-int swprintf (wchar_t *__restrict__, size_t, const wchar_t *__restrict__, ...);
+size_t wcsnlen(const wchar_t*, size_t);
-int vwprintf (const wchar_t *__restrict__, va_list);
-int vfwprintf (FILE *__restrict__, const wchar_t *__restrict__, va_list);
-int vswprintf (wchar_t *__restrict__, size_t, const wchar_t *__restrict__, va_list);
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
-int wscanf (const wchar_t *__restrict__, ...);
-int fwscanf (FILE *__restrict__, const wchar_t *__restrict__, ...);
-int swscanf (const wchar_t *__restrict__, const wchar_t *__restrict__, ...);
-
-int vwscanf (const wchar_t *__restrict__, va_list);
-int vfwscanf (FILE *__restrict__, const wchar_t *__restrict__, va_list);
-int vswscanf (const wchar_t *__restrict__, const wchar_t *__restrict__, va_list);
-
-wint_t fgetwc (FILE *);
-wint_t getwc (FILE *);
-wint_t getwchar (void);
+#if __ANDROID_API__ < __ANDROID_API_M__
-wint_t fputwc (wchar_t, FILE *);
-wint_t putwc (wchar_t, FILE *);
-wint_t putwchar (wchar_t);
-
-wchar_t *fgetws (wchar_t *__restrict__, int, FILE *__restrict__);
-int fputws (const wchar_t *__restrict__, FILE *__restrict__);
-
-wint_t ungetwc (wint_t, FILE *);
+int wcscasecmp_l(const wchar_t*, const wchar_t*, locale_t);
+int wcsncasecmp_l(const wchar_t*, const wchar_t*, size_t, locale_t);
-struct tm;
-size_t wcsftime (wchar_t *__restrict__, size_t, const wchar_t *__restrict__, const struct tm *__restrict__);
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
-FILE *open_wmemstream(wchar_t **, size_t *);
-size_t mbsnrtowcs(wchar_t *__restrict__, const char **__restrict__, size_t, size_t, mbstate_t *__restrict__);
-size_t wcsnrtombs(char *__restrict__, const wchar_t **__restrict__, size_t, size_t, mbstate_t *__restrict__);
-wchar_t *wcsdup(const wchar_t *);
-size_t wcsnlen (const wchar_t *, size_t);
-wchar_t *wcpcpy (wchar_t *__restrict__, const wchar_t *__restrict__);
-wchar_t *wcpncpy (wchar_t *__restrict__, const wchar_t *__restrict__, size_t);
-int wcscasecmp(const wchar_t *, const wchar_t *);
-int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
-int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
-int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
-int wcwidth (wchar_t);
-int wcswidth (const wchar_t *, size_t);
-int iswalnum(wint_t);
-int iswalpha(wint_t);
-int iswblank(wint_t);
-int iswcntrl(wint_t);
-int iswdigit(wint_t);
-int iswgraph(wint_t);
-int iswlower(wint_t);
-int iswprint(wint_t);
-int iswpunct(wint_t);
-int iswspace(wint_t);
-int iswupper(wint_t);
-int iswxdigit(wint_t);
-int iswctype(wint_t, wctype_t);
-wint_t towlower(wint_t);
-wint_t towupper(wint_t);
-wctype_t wctype(const char *);
-
-int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
-size_t wcsxfrm_l(wchar_t *__restrict__, const wchar_t *__restrict__, size_t n, locale_t);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // !__LP64__
+__END_DECLS
#endif // NDK_ANDROID_SUPPORT_WCHAR_H
diff --git a/sources/android/support/src/UniquePtr.h b/sources/android/support/src/UniquePtr.h
new file mode 100644
index 000000000..2f5e39fa7
--- /dev/null
+++ b/sources/android/support/src/UniquePtr.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef ANDROID_SUPPORT_UNIQUE_PTR_H
+#define ANDROID_SUPPORT_UNIQUE_PTR_H
+
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
+ void operator=(const TypeName&) = delete
+
+template <typename T>
+struct DefaultDelete {
+ enum { type_must_be_complete = sizeof(T) };
+ DefaultDelete() {
+ }
+ void operator()(T* p) const {
+ delete p;
+ }
+};
+
+template <typename T>
+struct DefaultDelete<T[]> {
+ enum { type_must_be_complete = sizeof(T) };
+ void operator()(T* p) const {
+ delete[] p;
+ }
+};
+
+template <typename T, typename D = DefaultDelete<T> >
+class UniquePtr {
+ public:
+ explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
+ }
+
+ ~UniquePtr() {
+ reset();
+ }
+
+ T& operator*() const {
+ return *mPtr;
+ }
+ T* operator->() const {
+ return mPtr;
+ }
+ T* get() const {
+ return mPtr;
+ }
+
+ T* release() __attribute__((warn_unused_result)) {
+ T* result = mPtr;
+ mPtr = NULL;
+ return result;
+ }
+
+ void reset(T* ptr = NULL) {
+ if (ptr != mPtr) {
+ D()(mPtr);
+ mPtr = ptr;
+ }
+ }
+
+ private:
+ T* mPtr;
+
+ template <typename T2>
+ bool operator==(const UniquePtr<T2>& p) const;
+ template <typename T2>
+ bool operator!=(const UniquePtr<T2>& p) const;
+
+ DISALLOW_COPY_AND_ASSIGN(UniquePtr);
+};
+
+// Partial specialization for array types. Like std::unique_ptr, this removes
+// operator* and operator-> but adds operator[].
+template <typename T, typename D>
+class UniquePtr<T[], D> {
+ public:
+ explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) {
+ }
+
+ ~UniquePtr() {
+ reset();
+ }
+
+ T& operator[](size_t i) const {
+ return mPtr[i];
+ }
+ T* get() const {
+ return mPtr;
+ }
+
+ T* release() __attribute__((warn_unused_result)) {
+ T* result = mPtr;
+ mPtr = NULL;
+ return result;
+ }
+
+ void reset(T* ptr = NULL) {
+ if (ptr != mPtr) {
+ D()(mPtr);
+ mPtr = ptr;
+ }
+ }
+
+ private:
+ T* mPtr;
+
+ DISALLOW_COPY_AND_ASSIGN(UniquePtr);
+};
+
+#endif /* ANDROID_SUPPORT_UNIQUE_PTR_H */
diff --git a/sources/android/support/src/musl-multibyte/btowc.c b/sources/android/support/src/musl-multibyte/btowc.c
deleted file mode 100644
index 9d2c3b16e..000000000
--- a/sources/android/support/src/musl-multibyte/btowc.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-#include <wchar.h>
-
-wint_t btowc(int c)
-{
- return c<128U ? c : EOF;
-}
diff --git a/sources/android/support/src/musl-multibyte/internal.c b/sources/android/support/src/musl-multibyte/internal.c
deleted file mode 100644
index 1813b266c..000000000
--- a/sources/android/support/src/musl-multibyte/internal.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include "internal.h"
-
-#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
-#define D(x) C((x+16))
-#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
- x==0xd ? R(0x80,0xa0) : \
- R(0x80,0xc0) ) \
- | ( R(0x80,0xc0) >> 6 ) \
- | x )
-#define F(x) ( ( x>=5 ? 0 : \
- x==0 ? R(0x90,0xc0) : \
- x==4 ? R(0x80,0xa0) : \
- R(0x80,0xc0) ) \
- | ( R(0x80,0xc0) >> 6 ) \
- | ( R(0x80,0xc0) >> 12 ) \
- | x )
-
-const uint32_t bittab[] = {
- C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
- C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
- D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
- D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
- E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
- E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
- F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
-};
-
-#ifdef BROKEN_VISIBILITY
-__asm__(".hidden __fsmu8");
-#endif
diff --git a/sources/android/support/src/musl-multibyte/internal.h b/sources/android/support/src/musl-multibyte/internal.h
deleted file mode 100644
index 82f5a07e5..000000000
--- a/sources/android/support/src/musl-multibyte/internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#define bittab __fsmu8
-
-#include <stdint.h>
-#include "libc.h"
-
-extern const uint32_t bittab[] ATTR_LIBC_VISIBILITY;
-
-/* Upper 6 state bits are a negative integer offset to bound-check next byte */
-/* equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f */
-#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
-
-/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
-#define R(a,b) ((uint32_t)((a==0x80 ? 0x40-b : -a) << 23))
-#define FAILSTATE R(0x80,0x80)
-
-#define SA 0xc2u
-#define SB 0xf4u
diff --git a/sources/android/support/src/musl-multibyte/libc.h b/sources/android/support/src/musl-multibyte/libc.h
deleted file mode 100644
index c1e44c3e9..000000000
--- a/sources/android/support/src/musl-multibyte/libc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// Replacemenet for musl's libc
-
-#ifndef MUSL_LIBC_H
-#define MUSL_LIBC_H
-
-#define ATTR_LIBC_VISIBILITY __attribute__((visibility("hidden")))
-
-#endif // MUSL_LIBC_H
diff --git a/sources/android/support/src/musl-multibyte/mbrlen.c b/sources/android/support/src/musl-multibyte/mbrlen.c
deleted file mode 100644
index 3a5a74336..000000000
--- a/sources/android/support/src/musl-multibyte/mbrlen.c
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-
-size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
-{
- static unsigned internal;
- return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
-}
diff --git a/sources/android/support/src/musl-multibyte/mbrtowc.c b/sources/android/support/src/musl-multibyte/mbrtowc.c
deleted file mode 100644
index 35e834ee6..000000000
--- a/sources/android/support/src/musl-multibyte/mbrtowc.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-#include <errno.h>
-#include "internal.h"
-
-size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
-{
- static unsigned internal_state;
- unsigned c;
- const unsigned char *s = (const void *)src;
- const unsigned N = n;
-
- if (!st) st = (void *)&internal_state;
- c = *(unsigned *)st;
-
- if (!s) {
- if (c) goto ilseq;
- return 0;
- } else if (!wc) wc = (void *)&wc;
-
- if (!n) return -2;
- if (!c) {
- if (*s < 0x80) return !!(*wc = *s);
- if (*s-SA > SB-SA) goto ilseq;
- c = bittab[*s++-SA]; n--;
- }
-
- if (n) {
- if (OOB(c,*s)) goto ilseq;
-loop:
- c = c<<6 | *s++-0x80; n--;
- if (!(c&(1U<<31))) {
- *(unsigned *)st = 0;
- *wc = c;
- return N-n;
- }
- if (n) {
- if (*s-0x80u >= 0x40) goto ilseq;
- goto loop;
- }
- }
-
- *(unsigned *)st = c;
- return -2;
-ilseq:
- *(unsigned *)st = 0;
- errno = EILSEQ;
- return -1;
-}
diff --git a/sources/android/support/src/musl-multibyte/mbsinit.c b/sources/android/support/src/musl-multibyte/mbsinit.c
deleted file mode 100644
index e001d8444..000000000
--- a/sources/android/support/src/musl-multibyte/mbsinit.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-
-int mbsinit(const mbstate_t *st)
-{
- return !st || !*(unsigned *)st;
-}
diff --git a/sources/android/support/src/musl-multibyte/mbsnrtowcs.c b/sources/android/support/src/musl-multibyte/mbsnrtowcs.c
deleted file mode 100644
index 68b9960f3..000000000
--- a/sources/android/support/src/musl-multibyte/mbsnrtowcs.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-
-size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
-{
- size_t l, cnt=0, n2;
- wchar_t *ws, wbuf[256];
- const char *s = *src;
-
- if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
- else ws = wcs;
-
- /* making sure output buffer size is at most n/4 will ensure
- * that mbsrtowcs never reads more than n input bytes. thus
- * we can use mbsrtowcs as long as it's practical.. */
-
- while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
- if (n2>=wn) n2=wn;
- n -= n2;
- l = mbsrtowcs(ws, &s, n2, st);
- if (!(l+1)) {
- cnt = l;
- wn = 0;
- break;
- }
- if (ws != wbuf) {
- ws += l;
- wn -= l;
- }
- cnt += l;
- }
- if (s) while (wn && n) {
- l = mbrtowc(ws, s, n, st);
- if (l+2<=2) {
- if (!(l+1)) {
- cnt = l;
- break;
- }
- if (!l) {
- s = 0;
- break;
- }
- /* have to roll back partial character */
- *(unsigned *)st = 0;
- break;
- }
- s += l; n -= l;
- /* safe - this loop runs fewer than sizeof(wbuf)/8 times */
- ws++; wn--;
- cnt++;
- }
- if (wcs) *src = s;
- return cnt;
-}
diff --git a/sources/android/support/src/musl-multibyte/mbsrtowcs.c b/sources/android/support/src/musl-multibyte/mbsrtowcs.c
deleted file mode 100644
index 3c1343aea..000000000
--- a/sources/android/support/src/musl-multibyte/mbsrtowcs.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <stdint.h>
-#include <wchar.h>
-#include <errno.h>
-#include "internal.h"
-
-size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
-{
- const unsigned char *s = (const void *)*src;
- size_t wn0 = wn;
- unsigned c = 0;
-
- if (st && (c = *(unsigned *)st)) {
- if (ws) {
- *(unsigned *)st = 0;
- goto resume;
- } else {
- goto resume0;
- }
- }
-
- if (!ws) for (;;) {
- if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
- while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
- s += 4;
- wn -= 4;
- }
- }
- if (*s-1u < 0x7f) {
- s++;
- wn--;
- continue;
- }
- if (*s-SA > SB-SA) break;
- c = bittab[*s++-SA];
-resume0:
- if (OOB(c,*s)) { s--; break; }
- s++;
- if (c&(1U<<25)) {
- if (*s-0x80u >= 0x40) { s-=2; break; }
- s++;
- if (c&(1U<<19)) {
- if (*s-0x80u >= 0x40) { s-=3; break; }
- s++;
- }
- }
- wn--;
- c = 0;
- } else for (;;) {
- if (!wn) {
- *src = (const void *)s;
- return wn0;
- }
- if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
- while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
- *ws++ = *s++;
- *ws++ = *s++;
- *ws++ = *s++;
- *ws++ = *s++;
- wn -= 4;
- }
- }
- if (*s-1u < 0x7f) {
- *ws++ = *s++;
- wn--;
- continue;
- }
- if (*s-SA > SB-SA) break;
- c = bittab[*s++-SA];
-resume:
- if (OOB(c,*s)) { s--; break; }
- c = (c<<6) | *s++-0x80;
- if (c&(1U<<31)) {
- if (*s-0x80u >= 0x40) { s-=2; break; }
- c = (c<<6) | *s++-0x80;
- if (c&(1U<<31)) {
- if (*s-0x80u >= 0x40) { s-=3; break; }
- c = (c<<6) | *s++-0x80;
- }
- }
- *ws++ = c;
- wn--;
- c = 0;
- }
-
- if (!c && !*s) {
- if (ws) {
- *ws = 0;
- *src = 0;
- }
- return wn0-wn;
- }
- errno = EILSEQ;
- if (ws) *src = (const void *)s;
- return -1;
-}
diff --git a/sources/android/support/src/musl-multibyte/mbstowcs.c b/sources/android/support/src/musl-multibyte/mbstowcs.c
deleted file mode 100644
index dc0d45948..000000000
--- a/sources/android/support/src/musl-multibyte/mbstowcs.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdlib.h>
-#include <wchar.h>
-
-size_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)
-{
- return mbsrtowcs(ws, (void*)&s, wn, 0);
-}
diff --git a/sources/android/support/src/musl-multibyte/mbtowc.c b/sources/android/support/src/musl-multibyte/mbtowc.c
deleted file mode 100644
index 6710637ad..000000000
--- a/sources/android/support/src/musl-multibyte/mbtowc.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-#include <errno.h>
-#include "internal.h"
-
-int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)
-{
- unsigned c;
- const unsigned char *s = (const void *)src;
-
- if (!s) return 0;
- if (!n) goto ilseq;
- if (!wc) wc = (void *)&wc;
-
- if (*s < 0x80) return !!(*wc = *s);
- if (*s-SA > SB-SA) goto ilseq;
- c = bittab[*s++-SA];
-
- /* Avoid excessive checks against n: If shifting the state n-1
- * times does not clear the high bit, then the value of n is
- * insufficient to read a character */
- if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;
-
- if (OOB(c,*s)) goto ilseq;
- c = c<<6 | *s++-0x80;
- if (!(c&(1U<<31))) {
- *wc = c;
- return 2;
- }
-
- if (*s-0x80u >= 0x40) goto ilseq;
- c = c<<6 | *s++-0x80;
- if (!(c&(1U<<31))) {
- *wc = c;
- return 3;
- }
-
- if (*s-0x80u >= 0x40) goto ilseq;
- *wc = c<<6 | *s++-0x80;
- return 4;
-
-ilseq:
- errno = EILSEQ;
- return -1;
-}
diff --git a/sources/android/support/src/musl-multibyte/wcrtomb.c b/sources/android/support/src/musl-multibyte/wcrtomb.c
deleted file mode 100644
index 59f733db6..000000000
--- a/sources/android/support/src/musl-multibyte/wcrtomb.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-#include <errno.h>
-
-size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
-{
- if (!s) return 1;
- if ((unsigned)wc < 0x80) {
- *s = wc;
- return 1;
- } else if ((unsigned)wc < 0x800) {
- *s++ = 0xc0 | (wc>>6);
- *s = 0x80 | (wc&0x3f);
- return 2;
- } else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
- *s++ = 0xe0 | (wc>>12);
- *s++ = 0x80 | ((wc>>6)&0x3f);
- *s = 0x80 | (wc&0x3f);
- return 3;
- } else if ((unsigned)wc-0x10000 < 0x100000) {
- *s++ = 0xf0 | (wc>>18);
- *s++ = 0x80 | ((wc>>12)&0x3f);
- *s++ = 0x80 | ((wc>>6)&0x3f);
- *s = 0x80 | (wc&0x3f);
- return 4;
- }
- errno = EILSEQ;
- return -1;
-}
diff --git a/sources/android/support/src/musl-multibyte/wcsnrtombs.c b/sources/android/support/src/musl-multibyte/wcsnrtombs.c
deleted file mode 100644
index 7eb05d459..000000000
--- a/sources/android/support/src/musl-multibyte/wcsnrtombs.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-
-size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
-{
- size_t l, cnt=0, n2;
- char *s, buf[256];
- const wchar_t *ws = *wcs;
-
- if (!dst) s = buf, n = sizeof buf;
- else s = dst;
-
- while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
- if (n2>=n) n2=n;
- wn -= n2;
- l = wcsrtombs(s, &ws, n2, 0);
- if (!(l+1)) {
- cnt = l;
- n = 0;
- break;
- }
- if (s != buf) {
- s += l;
- n -= l;
- }
- cnt += l;
- }
- if (ws) while (n && wn) {
- l = wcrtomb(s, *ws, 0);
- if ((l+1)<=1) {
- if (!l) ws = 0;
- else cnt = l;
- break;
- }
- ws++; wn--;
- /* safe - this loop runs fewer than sizeof(buf) times */
- s+=l; n-=l;
- cnt++;
- }
- if (dst) *wcs = ws;
- return cnt;
-}
diff --git a/sources/android/support/src/musl-multibyte/wcsrtombs.c b/sources/android/support/src/musl-multibyte/wcsrtombs.c
deleted file mode 100644
index 30be415d0..000000000
--- a/sources/android/support/src/musl-multibyte/wcsrtombs.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <wchar.h>
-
-size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
-{
- const wchar_t *ws2;
- char buf[4];
- size_t N = n, l;
- if (!s) {
- for (n=0, ws2=*ws; *ws2; ws2++) {
- if (*ws2 >= 0x80u) {
- l = wcrtomb(buf, *ws2, 0);
- if (!(l+1)) return -1;
- n += l;
- } else n++;
- }
- return n;
- }
- while (n>=4) {
- if (**ws-1u >= 0x7fu) {
- if (!**ws) {
- *s = 0;
- *ws = 0;
- return N-n;
- }
- l = wcrtomb(s, **ws, 0);
- if (!(l+1)) return -1;
- s += l;
- n -= l;
- } else {
- *s++ = **ws;
- n--;
- }
- (*ws)++;
- }
- while (n) {
- if (**ws-1u >= 0x7fu) {
- if (!**ws) {
- *s = 0;
- *ws = 0;
- return N-n;
- }
- l = wcrtomb(buf, **ws, 0);
- if (!(l+1)) return -1;
- if (l>n) return N-n;
- wcrtomb(s, **ws, 0);
- s += l;
- n -= l;
- } else {
- *s++ = **ws;
- n--;
- }
- (*ws)++;
- }
- return N;
-}
diff --git a/sources/android/support/src/musl-multibyte/wcstombs.c b/sources/android/support/src/musl-multibyte/wcstombs.c
deleted file mode 100644
index ab152874d..000000000
--- a/sources/android/support/src/musl-multibyte/wcstombs.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdlib.h>
-#include <wchar.h>
-
-size_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)
-{
- return wcsrtombs(s, &(const wchar_t *){ws}, n, 0);
-}
diff --git a/sources/android/support/src/musl-multibyte/wctob.c b/sources/android/support/src/musl-multibyte/wctob.c
deleted file mode 100644
index d6353ee17..000000000
--- a/sources/android/support/src/musl-multibyte/wctob.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-#include <wchar.h>
-
-int wctob(wint_t c)
-{
- if (c < 128U) return c;
- return EOF;
-}
diff --git a/sources/android/support/src/musl-multibyte/wctomb.c b/sources/android/support/src/musl-multibyte/wctomb.c
deleted file mode 100644
index de7ed84d9..000000000
--- a/sources/android/support/src/musl-multibyte/wctomb.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * This code was written by Rich Felker in 2010; no copyright is claimed.
- * This code is in the public domain. Attribution is appreciated but
- * unnecessary.
- */
-
-#include <stdlib.h>
-#include <wchar.h>
-
-int wctomb(char *s, wchar_t wc)
-{
- if (!s) return 0;
- return wcrtomb(s, wc, 0);
-}
diff --git a/sources/android/support/src/musl-stdio/printf.c b/sources/android/support/src/musl-stdio/printf.c
deleted file mode 100644
index cebfe404f..000000000
--- a/sources/android/support/src/musl-stdio/printf.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-
-int printf(const char *restrict fmt, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vfprintf(stdout, fmt, ap);
- va_end(ap);
- return ret;
-}
diff --git a/sources/android/support/src/musl-stdio/snprintf.c b/sources/android/support/src/musl-stdio/snprintf.c
deleted file mode 100644
index 915e55ad9..000000000
--- a/sources/android/support/src/musl-stdio/snprintf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-
-int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...) __overloadable
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vsnprintf(s, n, fmt, ap);
- va_end(ap);
- return ret;
-}
-
diff --git a/sources/android/support/src/musl-stdio/sprintf.c b/sources/android/support/src/musl-stdio/sprintf.c
deleted file mode 100644
index 03b880bc5..000000000
--- a/sources/android/support/src/musl-stdio/sprintf.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-
-int sprintf(char *restrict s, const char *restrict fmt, ...) __overloadable
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vsprintf(s, fmt, ap);
- va_end(ap);
- return ret;
-}
diff --git a/sources/android/support/src/musl-stdio/swprintf.c b/sources/android/support/src/musl-stdio/swprintf.c
deleted file mode 100644
index f75eb112e..000000000
--- a/sources/android/support/src/musl-stdio/swprintf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdarg.h>
-#include <wchar.h>
-
-int swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vswprintf(s, n, fmt, ap);
- va_end(ap);
- return ret;
-}
-
diff --git a/sources/android/support/src/musl-stdio/vprintf.c b/sources/android/support/src/musl-stdio/vprintf.c
deleted file mode 100644
index 30d2bffa8..000000000
--- a/sources/android/support/src/musl-stdio/vprintf.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdio.h>
-
-int vprintf(const char *restrict fmt, va_list ap)
-{
- return vfprintf(stdout, fmt, ap);
-}
diff --git a/sources/android/support/src/musl-stdio/vsprintf.c b/sources/android/support/src/musl-stdio/vsprintf.c
deleted file mode 100644
index 352f8c25c..000000000
--- a/sources/android/support/src/musl-stdio/vsprintf.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-#include <limits.h>
-
-int vsprintf(char *restrict s, const char *restrict fmt, va_list ap) __overloadable
-{
- return vsnprintf(s, INT_MAX, fmt, ap);
-}
diff --git a/sources/android/support/src/musl-stdio/vwprintf.c b/sources/android/support/src/musl-stdio/vwprintf.c
deleted file mode 100644
index eeeecdc7c..000000000
--- a/sources/android/support/src/musl-stdio/vwprintf.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-#include <wchar.h>
-
-int vwprintf(const wchar_t *restrict fmt, va_list ap)
-{
- return vfwprintf(stdout, fmt, ap);
-}
diff --git a/sources/android/support/src/musl-stdio/vwscanf.c b/sources/android/support/src/musl-stdio/vwscanf.c
deleted file mode 100644
index 63c9cce10..000000000
--- a/sources/android/support/src/musl-stdio/vwscanf.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <wchar.h>
-#include "libc.h"
-
-int vwscanf(const wchar_t *restrict fmt, va_list ap)
-{
- return vfwscanf(stdin, fmt, ap);
-}
-
-weak_alias(vwscanf,__isoc99_vwscanf);
diff --git a/sources/android/support/src/musl-stdio/wprintf.c b/sources/android/support/src/musl-stdio/wprintf.c
deleted file mode 100644
index 342cd9791..000000000
--- a/sources/android/support/src/musl-stdio/wprintf.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <wchar.h>
-
-int wprintf(const wchar_t *restrict fmt, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vwprintf(fmt, ap);
- va_end(ap);
- return ret;
-}
diff --git a/sources/android/support/src/musl-stdio/wscanf.c b/sources/android/support/src/musl-stdio/wscanf.c
deleted file mode 100644
index 804122523..000000000
--- a/sources/android/support/src/musl-stdio/wscanf.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <wchar.h>
-#include "libc.h"
-
-int wscanf(const wchar_t *restrict fmt, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, fmt);
- ret = vwscanf(fmt, ap);
- va_end(ap);
- return ret;
-}
-
-weak_alias(wscanf,__isoc99_wscanf);
diff --git a/sources/android/support/src/stdio/vfprintf.c b/sources/android/support/src/stdio/vfprintf.c
deleted file mode 100644
index fe92e33b0..000000000
--- a/sources/android/support/src/stdio/vfprintf.c
+++ /dev/null
@@ -1,781 +0,0 @@
-/*
- Copyright (C) 2005-2012 Rich Felker
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Modified in 2013 for the Android Open Source Project.
- */
-#include <errno.h>
-#include <ctype.h>
-#include <limits.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <inttypes.h>
-#include <math.h>
-#include <float.h>
-
-#include "stdio_impl.h"
-
-/* Some useful macros */
-
-#define MAX(a,b) ((a)>(b) ? (a) : (b))
-#define MIN(a,b) ((a)<(b) ? (a) : (b))
-#define CONCAT2(x,y) x ## y
-#define CONCAT(x,y) CONCAT2(x,y)
-
-/* Convenient bit representation for modifier flags, which all fall
- * within 31 codepoints of the space character. */
-
-#define ALT_FORM (1U<<'#'-' ')
-#define ZERO_PAD (1U<<'0'-' ')
-#define LEFT_ADJ (1U<<'-'-' ')
-#define PAD_POS (1U<<' '-' ')
-#define MARK_POS (1U<<'+'-' ')
-#define GROUPED (1U<<'\''-' ')
-
-#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
-
-#if UINT_MAX == ULONG_MAX
-#define LONG_IS_INT
-#endif
-
-#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
-#define ODD_TYPES
-#endif
-
-/* State machine to accept length modifiers + conversion specifiers.
- * Result is 0 on failure, or an argument type to pop on success. */
-
-enum {
- BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
- ZTPRE, JPRE,
- STOP,
- PTR, INT, UINT, ULLONG,
-#ifndef LONG_IS_INT
- LONG, ULONG,
-#else
-#define LONG INT
-#define ULONG UINT
-#endif
- SHORT, USHORT, CHAR, UCHAR,
-#ifdef ODD_TYPES
- LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
-#else
-#define LLONG ULLONG
-#define SIZET ULONG
-#define IMAX LLONG
-#define UMAX ULLONG
-#define PDIFF LONG
-#define UIPTR ULONG
-#endif
- DBL, LDBL,
- NOARG,
- MAXSTATE
-};
-
-#define S(x) [(x)-'A']
-
-static const unsigned char states[]['z'-'A'+1] = {
- { /* 0: bare types */
- S('d') = INT, S('i') = INT,
- S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
- S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
- S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = CHAR, S('C') = INT,
- S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
- S('m') = NOARG,
- S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
- S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
- }, { /* 1: l-prefixed */
- S('d') = LONG, S('i') = LONG,
- S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
- S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
- S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = INT, S('s') = PTR, S('n') = PTR,
- S('l') = LLPRE,
- }, { /* 2: ll-prefixed */
- S('d') = LLONG, S('i') = LLONG,
- S('o') = ULLONG, S('u') = ULLONG,
- S('x') = ULLONG, S('X') = ULLONG,
- S('n') = PTR,
- }, { /* 3: h-prefixed */
- S('d') = SHORT, S('i') = SHORT,
- S('o') = USHORT, S('u') = USHORT,
- S('x') = USHORT, S('X') = USHORT,
- S('n') = PTR,
- S('h') = HHPRE,
- }, { /* 4: hh-prefixed */
- S('d') = CHAR, S('i') = CHAR,
- S('o') = UCHAR, S('u') = UCHAR,
- S('x') = UCHAR, S('X') = UCHAR,
- S('n') = PTR,
- }, { /* 5: L-prefixed */
- S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
- S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
- S('n') = PTR,
- }, { /* 6: z- or t-prefixed (assumed to be same size) */
- S('d') = PDIFF, S('i') = PDIFF,
- S('o') = SIZET, S('u') = SIZET,
- S('x') = SIZET, S('X') = SIZET,
- S('n') = PTR,
- }, { /* 7: j-prefixed */
- S('d') = IMAX, S('i') = IMAX,
- S('o') = UMAX, S('u') = UMAX,
- S('x') = UMAX, S('X') = UMAX,
- S('n') = PTR,
- }
-};
-
-#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
-
-union arg
-{
- uintmax_t i;
- long double f;
- void *p;
-};
-
-static void pop_arg(union arg *arg, int type, va_list *ap)
-{
- /* Give the compiler a hint for optimizing the switch. */
- if ((unsigned)type > MAXSTATE) return;
- switch (type) {
- case PTR: arg->p = va_arg(*ap, void *);
- break; case INT: arg->i = va_arg(*ap, int);
- break; case UINT: arg->i = va_arg(*ap, unsigned int);
-#ifndef LONG_IS_INT
- break; case LONG: arg->i = va_arg(*ap, long);
- break; case ULONG: arg->i = va_arg(*ap, unsigned long);
-#endif
- break; case ULLONG: arg->i = va_arg(*ap, unsigned long long);
- break; case SHORT: arg->i = (short)va_arg(*ap, int);
- break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int);
- break; case CHAR: arg->i = (signed char)va_arg(*ap, int);
- break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int);
-#ifdef ODD_TYPES
- break; case LLONG: arg->i = va_arg(*ap, long long);
- break; case SIZET: arg->i = va_arg(*ap, size_t);
- break; case IMAX: arg->i = va_arg(*ap, intmax_t);
- break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
- break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
- break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
-#endif
- break; case DBL: arg->f = va_arg(*ap, double);
- break; case LDBL: arg->f = va_arg(*ap, long double);
- }
-}
-
-static void out(FILE *f, const char *s, size_t l)
-{
-#if defined(__ANDROID__)
- fake_file_out(f, s, l);
-#else
- __fwritex((void *)s, l, f);
-#endif
-}
-
-static void pad(FILE *f, char c, int w, int l, int fl)
-{
- char pad[256];
- if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
- l = w - l;
- memset(pad, c, l>sizeof pad ? sizeof pad : l);
- for (; l >= sizeof pad; l -= sizeof pad)
- out(f, pad, sizeof pad);
- out(f, pad, l);
-}
-
-static const char xdigits[16] = {
- "0123456789ABCDEF"
-};
-
-static char *fmt_x(uintmax_t x, char *s, int lower)
-{
- for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
- return s;
-}
-
-static char *fmt_o(uintmax_t x, char *s)
-{
- for (; x; x>>=3) *--s = '0' + (x&7);
- return s;
-}
-
-static char *fmt_u(uintmax_t x, char *s)
-{
- unsigned long y;
- for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
- for (y=x; y; y/=10) *--s = '0' + y%10;
- return s;
-}
-
-static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
-{
- uint32_t big[(LDBL_MAX_EXP+LDBL_MANT_DIG)/9+1];
- uint32_t *a, *d, *r, *z;
- int e2=0, e, i, j, l;
- char buf[9+LDBL_MANT_DIG/4], *s;
- const char *prefix="-0X+0X 0X-0x+0x 0x";
- int pl;
- char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
-
- pl=1;
- if (signbit(y)) {
- y=-y;
- } else if (fl & MARK_POS) {
- prefix+=3;
- } else if (fl & PAD_POS) {
- prefix+=6;
- } else prefix++, pl=0;
-
- if (!isfinite(y)) {
- char *s = (t&32)?"inf":"INF";
- if (y!=y) s=(t&32)?"nan":"NAN", pl=0;
- pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
- out(f, prefix, pl);
- out(f, s, 3);
- pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
- return MAX(w, 3+pl);
- }
-
- y = frexpl(y, &e2) * 2;
- if (y) e2--;
-
- if ((t|32)=='a') {
- long double round = 8.0;
- int re;
-
- if (t&32) prefix += 9;
- pl += 2;
-
- if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
- else re=LDBL_MANT_DIG/4-1-p;
-
- if (re) {
- while (re--) round*=16;
- if (*prefix=='-') {
- y=-y;
- y-=round;
- y+=round;
- y=-y;
- } else {
- y+=round;
- y-=round;
- }
- }
-
- estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
- if (estr==ebuf) *--estr='0';
- *--estr = (e2<0 ? '-' : '+');
- *--estr = t+('p'-'a');
-
- s=buf;
- do {
- int x=y;
- *s++=xdigits[x]|(t&32);
- y=16*(y-x);
- if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
- } while (y);
-
- if (p && s-buf-2 < p)
- l = (p+2) + (ebuf-estr);
- else
- l = (s-buf) + (ebuf-estr);
-
- pad(f, ' ', w, pl+l, fl);
- out(f, prefix, pl);
- pad(f, '0', w, pl+l, fl^ZERO_PAD);
- out(f, buf, s-buf);
- pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
- out(f, estr, ebuf-estr);
- pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
- return MAX(w, pl+l);
- }
- if (p<0) p=6;
-
- if (y) y *= 0x1p28, e2-=28;
-
- if (e2<0) a=r=z=big;
- else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
-
- do {
- *z = y;
- y = 1000000000*(y-*z++);
- } while (y);
-
- while (e2>0) {
- uint32_t carry=0;
- int sh=MIN(29,e2);
- for (d=z-1; d>=a; d--) {
- uint64_t x = ((uint64_t)*d<<sh)+carry;
- *d = x % 1000000000;
- carry = x / 1000000000;
- }
- if (!z[-1] && z>a) z--;
- if (carry) *--a = carry;
- e2-=sh;
- }
- while (e2<0) {
- uint32_t carry=0, *b;
- int sh=MIN(9,-e2);
- for (d=a; d<z; d++) {
- uint32_t rm = *d & (1<<sh)-1;
- *d = (*d>>sh) + carry;
- carry = (1000000000>>sh) * rm;
- }
- if (!*a) a++;
- if (carry) *z++ = carry;
- /* Avoid (slow!) computation past requested precision */
- b = (t|32)=='f' ? r : a;
- if (z-b > 2+p/9) z = b+2+p/9;
- e2+=sh;
- }
-
- if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
- else e=0;
-
- /* Perform rounding: j is precision after the radix (possibly neg) */
- j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
- if (j < 9*(z-r-1)) {
- uint32_t x;
- /* We avoid C's broken division of negative numbers */
- d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
- j += 9*LDBL_MAX_EXP;
- j %= 9;
- for (i=10, j++; j<9; i*=10, j++);
- x = *d % i;
- /* Are there any significant digits past j? */
- if (x || d+1!=z) {
- long double round = CONCAT(0x1p,LDBL_MANT_DIG);
- long double small;
- if (*d/i & 1) round += 2;
- if (x<i/2) small=0x0.8p0;
- else if (x==i/2 && d+1==z) small=0x1.0p0;
- else small=0x1.8p0;
- if (pl && *prefix=='-') round*=-1, small*=-1;
- *d -= x;
- /* Decide whether to round by probing round+small */
- if (round+small != round) {
- *d = *d + i;
- while (*d > 999999999) {
- *d--=0;
- (*d)++;
- }
- if (d<a) a=d;
- for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
- }
- }
- if (z>d+1) z=d+1;
- for (; !z[-1] && z>a; z--);
- }
-
- if ((t|32)=='g') {
- if (!p) p++;
- if (p>e && e>=-4) {
- t--;
- p-=e+1;
- } else {
- t-=2;
- p--;
- }
- if (!(fl&ALT_FORM)) {
- /* Count trailing zeros in last place */
- if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
- else j=9;
- if ((t|32)=='f')
- p = MIN(p,MAX(0,9*(z-r-1)-j));
- else
- p = MIN(p,MAX(0,9*(z-r-1)+e-j));
- }
- }
- l = 1 + p + (p || (fl&ALT_FORM));
- if ((t|32)=='f') {
- if (e>0) l+=e;
- } else {
- estr=fmt_u(e<0 ? -e : e, ebuf);
- while(ebuf-estr<2) *--estr='0';
- *--estr = (e<0 ? '-' : '+');
- *--estr = t;
- l += ebuf-estr;
- }
-
- pad(f, ' ', w, pl+l, fl);
- out(f, prefix, pl);
- pad(f, '0', w, pl+l, fl^ZERO_PAD);
-
- if ((t|32)=='f') {
- if (a>r) a=r;
- for (d=a; d<=r; d++) {
- char *s = fmt_u(*d, buf+9);
- if (d!=a) while (s>buf) *--s='0';
- else if (s==buf+9) *--s='0';
- out(f, s, buf+9-s);
- }
- if (p || (fl&ALT_FORM)) out(f, ".", 1);
- for (; d<z && p>0; d++, p-=9) {
- char *s = fmt_u(*d, buf+9);
- while (s>buf) *--s='0';
- out(f, s, MIN(9,p));
- }
- pad(f, '0', p+9, 9, 0);
- } else {
- if (z<=a) z=a+1;
- for (d=a; d<z && p>=0; d++) {
- char *s = fmt_u(*d, buf+9);
- if (s==buf+9) *--s='0';
- if (d!=a) while (s>buf) *--s='0';
- else {
- out(f, s++, 1);
- if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
- }
- out(f, s, MIN(buf+9-s, p));
- p -= buf+9-s;
- }
- pad(f, '0', p+18, 18, 0);
- out(f, estr, ebuf-estr);
- }
-
- pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
-
- return MAX(w, pl+l);
-}
-
-static int getint(char **s) {
- int i;
- for (i=0; isdigit(**s); (*s)++)
- i = 10*i + (**s-'0');
- return i;
-}
-
-static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
-{
- char *a, *z, *s=(char *)fmt;
- unsigned l10n=0, fl;
- int w, p;
- union arg arg;
- int argpos;
- unsigned st, ps;
- int cnt=0, l=0;
- int i;
- char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
- const char *prefix;
- int t, pl;
- wchar_t wc[2], *ws;
- char mb[4];
-
- for (;;) {
- /* Update output count, end loop when fmt is exhausted */
- if (cnt >= 0) {
- if (l > INT_MAX - cnt) {
- errno = EOVERFLOW;
- cnt = -1;
- } else cnt += l;
- }
- if (!*s) break;
-
- /* Handle literal text and %% format specifiers */
- for (a=s; *s && *s!='%'; s++);
- for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
- l = z-a;
- if (f) out(f, a, l);
- if (l) continue;
-
- if (isdigit(s[1]) && s[2]=='$') {
- l10n=1;
- argpos = s[1]-'0';
- s+=3;
- } else {
- argpos = -1;
- s++;
- }
-
- /* Read modifier flags */
- for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
- fl |= 1U<<*s-' ';
-
- /* Read field width */
- if (*s=='*') {
- if (isdigit(s[1]) && s[2]=='$') {
- l10n=1;
- nl_type[s[1]-'0'] = INT;
- w = nl_arg[s[1]-'0'].i;
- s+=3;
- } else if (!l10n) {
- w = f ? va_arg(*ap, int) : 0;
- s++;
- } else return -1;
- if (w<0) fl|=LEFT_ADJ, w=-w;
- } else if ((w=getint(&s))<0) return -1;
-
- /* Read precision */
- if (*s=='.' && s[1]=='*') {
- if (isdigit(s[2]) && s[3]=='$') {
- nl_type[s[2]-'0'] = INT;
- p = nl_arg[s[2]-'0'].i;
- s+=4;
- } else if (!l10n) {
- p = f ? va_arg(*ap, int) : 0;
- s+=2;
- } else return -1;
- } else if (*s=='.') {
- s++;
- p = getint(&s);
- } else p = -1;
-
- /* Format specifier state machine */
- st=0;
- do {
- if (OOB(*s)) return -1;
- ps=st;
- st=states[st]S(*s++);
- } while (st-1<STOP);
- if (!st) return -1;
-
- /* Check validity of argument type (nl/normal) */
- if (st==NOARG) {
- if (argpos>=0) return -1;
- else if (!f) continue;
- } else {
- if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
- else if (f) pop_arg(&arg, st, ap);
- else return 0;
- }
-
- if (!f) continue;
-
- z = buf + sizeof(buf);
- prefix = "-+ 0X0x";
- pl = 0;
- t = s[-1];
-
- /* Transform ls,lc -> S,C */
- if (ps && (t&15)==3) t&=~32;
-
- /* - and 0 flags are mutually exclusive */
- if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
-
- switch(t) {
- case 'n':
-#ifndef __ANDROID__ /* Disabled on Android for security reasons. */
- switch(ps) {
- case BARE: *(int *)arg.p = cnt; break;
- case LPRE: *(long *)arg.p = cnt; break;
- case LLPRE: *(long long *)arg.p = cnt; break;
- case HPRE: *(unsigned short *)arg.p = cnt; break;
- case HHPRE: *(unsigned char *)arg.p = cnt; break;
- case ZTPRE: *(size_t *)arg.p = cnt; break;
- case JPRE: *(uintmax_t *)arg.p = cnt; break;
- }
-#endif /* !__ANDROID__ */
- continue;
- case 'p':
- p = MAX(p, 2*sizeof(void*));
- t = 'x';
- fl |= ALT_FORM;
- case 'x': case 'X':
- a = fmt_x(arg.i, z, t&32);
- if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
- if (0) {
- case 'o':
- a = fmt_o(arg.i, z);
- if ((fl&ALT_FORM) && arg.i) prefix+=5, pl=1;
- } if (0) {
- case 'd': case 'i':
- pl=1;
- if (arg.i>INTMAX_MAX) {
- arg.i=-arg.i;
- } else if (fl & MARK_POS) {
- prefix++;
- } else if (fl & PAD_POS) {
- prefix+=2;
- } else pl=0;
- case 'u':
- a = fmt_u(arg.i, z);
- }
- if (p>=0) fl &= ~ZERO_PAD;
- if (!arg.i && !p) {
- a=z;
- break;
- }
- p = MAX(p, z-a + !arg.i);
- break;
- case 'c':
- *(a=z-(p=1))=arg.i;
- fl &= ~ZERO_PAD;
- break;
- case 'm':
- if (1) a = strerror(errno); else
- case 's':
- a = arg.p ? arg.p : "(null)";
-#if defined(__ANDROID__)
- /* On Android, memchr() will return NULL for
- * out-of-bound requests, e.g. if |p == -1|. */
- if (p >= 0) {
- z = memchr(a, 0, p);
- if (!z) z=a+p;
- else p=z-a;
- } else {
- p=strlen(a);
- z=a+p;
- }
-#else /* !__ANDROID__ */
- if (!z) z=a+p;
- else p=z-a;
-#endif /* !__ANDROID__ */
- fl &= ~ZERO_PAD;
- break;
- case 'C':
- wc[0] = arg.i;
- wc[1] = 0;
- arg.p = wc;
- p = -1;
- case 'S':
- ws = arg.p;
- for (i=l=0; i<0U+p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=0U+p-i; i+=l);
- if (l<0) return -1;
- p = i;
- pad(f, ' ', w, p, fl);
- ws = arg.p;
- for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
- out(f, mb, l);
- pad(f, ' ', w, p, fl^LEFT_ADJ);
- l = w>p ? w : p;
- continue;
- case 'e': case 'f': case 'g': case 'a':
- case 'E': case 'F': case 'G': case 'A':
- l = fmt_fp(f, arg.f, w, p, fl, t);
- continue;
- }
-
- if (p < z-a) p = z-a;
- if (w < pl+p) w = pl+p;
-
- pad(f, ' ', w, pl+p, fl);
- out(f, prefix, pl);
- pad(f, '0', w, pl+p, fl^ZERO_PAD);
- pad(f, '0', p, z-a, 0);
- out(f, a, z-a);
- pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
-
- l = w;
- }
-
- if (f) return cnt;
- if (!l10n) return 0;
-
- for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
- pop_arg(nl_arg+i, nl_type[i], ap);
- for (; i<=NL_ARGMAX && !nl_type[i]; i++);
- if (i<=NL_ARGMAX) return -1;
- return 1;
-}
-
-#ifdef __ANDROID__
-#undef FILE /* no longer needed */
-
-int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
-{
- va_list ap2;
- int nl_type[NL_ARGMAX+1] = {0};
- union arg nl_arg[NL_ARGMAX+1];
- int ret;
- FakeFILE out[1];
- fake_file_init_file(out, f);
-
- va_copy(ap2, ap);
- ret = printf_core(0, fmt, &ap2, nl_arg, nl_type);
- va_end(ap2);
- if (ret < 0)
- return -1;
-
- va_copy(ap2, ap);
- ret = printf_core(out, fmt, &ap2, nl_arg, nl_type);
- va_end(ap2);
- return ret;
-}
-
-int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) __overloadable
-{
- va_list ap2;
- int nl_type[NL_ARGMAX+1] = {0};
- union arg nl_arg[NL_ARGMAX+1];
- int r;
- char b;
- FakeFILE out[1];
-
- if (n-1 > INT_MAX-1) {
- if (n) {
- errno = EOVERFLOW;
- return -1;
- }
- s = &b;
- n = 1;
- }
-
- /* Ensure pointers don't wrap if "infinite" n is passed in */
- if (n > (char *)0+SIZE_MAX-s-1) n = (char *)0+SIZE_MAX-s-1;
- fake_file_init_buffer(out, s, n);
-
- va_copy(ap2, ap);
- r = printf_core(out, fmt, &ap2, nl_arg, nl_type);
- va_end(ap2);
-
- if (r < n)
- s[r] = '\0';
- else
- s[n - 1] = '\0';
-
- return r;
-}
-
-#else /* !__ANDROID__ */
-int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
-{
- va_list ap2;
- int nl_type[NL_ARGMAX+1] = {0};
- union arg nl_arg[NL_ARGMAX+1];
- unsigned char internal_buf[80], *saved_buf = 0;
- int ret;
-
- va_copy(ap2, ap);
- if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
-
- FLOCK(f);
- if (!f->buf_size) {
- saved_buf = f->buf;
- f->wpos = f->wbase = f->buf = internal_buf;
- f->buf_size = sizeof internal_buf;
- f->wend = internal_buf + sizeof internal_buf;
- }
- ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
- if (saved_buf) {
- f->write(f, 0, 0);
- if (!f->wpos) ret = -1;
- f->buf = saved_buf;
- f->buf_size = 0;
- f->wpos = f->wbase = f->wend = 0;
- }
- FUNLOCK(f);
- va_end(ap2);
- return ret;
-}
-#endif /* !__ANDROID__ */
diff --git a/sources/android/support/src/stdio/vfwprintf.c b/sources/android/support/src/stdio/vfwprintf.c
deleted file mode 100644
index 241cf0cbb..000000000
--- a/sources/android/support/src/stdio/vfwprintf.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- Copyright (C) 2005-2012 Rich Felker
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- Modified in 2013 for the Android Open Source Project.
- */
-
-#include <errno.h>
-#include <ctype.h>
-#include <limits.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <wchar.h>
-#include <inttypes.h>
-
-#include "stdio_impl.h"
-
-/* Convenient bit representation for modifier flags, which all fall
- * within 31 codepoints of the space character. */
-
-#define ALT_FORM (1U<<'#'-' ')
-#define ZERO_PAD (1U<<'0'-' ')
-#define LEFT_ADJ (1U<<'-'-' ')
-#define PAD_POS (1U<<' '-' ')
-#define MARK_POS (1U<<'+'-' ')
-#define GROUPED (1U<<'\''-' ')
-
-#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
-
-#if UINT_MAX == ULONG_MAX
-#define LONG_IS_INT
-#endif
-
-#if SIZE_MAX != ULONG_MAX || UINTMAX_MAX != ULLONG_MAX
-#define ODD_TYPES
-#endif
-
-/* State machine to accept length modifiers + conversion specifiers.
- * Result is 0 on failure, or an argument type to pop on success. */
-
-enum {
- BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
- ZTPRE, JPRE,
- STOP,
- PTR, INT, UINT, ULLONG,
-#ifndef LONG_IS_INT
- LONG, ULONG,
-#else
-#define LONG INT
-#define ULONG UINT
-#endif
- SHORT, USHORT, CHAR, UCHAR,
-#ifdef ODD_TYPES
- LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
-#else
-#define LLONG ULLONG
-#define SIZET ULONG
-#define IMAX LLONG
-#define UMAX ULLONG
-#define PDIFF LONG
-#define UIPTR ULONG
-#endif
- DBL, LDBL,
- NOARG,
- MAXSTATE
-};
-
-#define S(x) [(x)-'A']
-
-static const unsigned char states[]['z'-'A'+1] = {
- { /* 0: bare types */
- S('d') = INT, S('i') = INT,
- S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
- S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
- S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
- S('c') = CHAR, S('C') = INT,
- S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
- S('m') = NOARG,
- S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
- S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
- }, { /* 1: l-prefixed */
- S('d') = LONG, S('i') = LONG,
- S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
- S('c') = INT, S('s') = PTR, S('n') = PTR,
- S('l') = LLPRE,
- }, { /* 2: ll-prefixed */
- S('d') = LLONG, S('i') = LLONG,
- S('o') = ULLONG, S('u') = ULLONG,
- S('x') = ULLONG, S('X') = ULLONG,
- S('n') = PTR,
- }, { /* 3: h-prefixed */
- S('d') = SHORT, S('i') = SHORT,
- S('o') = USHORT, S('u') = USHORT,
- S('x') = USHORT, S('X') = USHORT,
- S('n') = PTR,
- S('h') = HHPRE,
- }, { /* 4: hh-prefixed */
- S('d') = CHAR, S('i') = CHAR,
- S('o') = UCHAR, S('u') = UCHAR,
- S('x') = UCHAR, S('X') = UCHAR,
- S('n') = PTR,
- }, { /* 5: L-prefixed */
- S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
- S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
- S('n') = PTR,
- }, { /* 6: z- or t-prefixed (assumed to be same size) */
- S('d') = PDIFF, S('i') = PDIFF,
- S('o') = SIZET, S('u') = SIZET,
- S('x') = SIZET, S('X') = SIZET,
- S('n') = PTR,
- }, { /* 7: j-prefixed */
- S('d') = IMAX, S('i') = IMAX,
- S('o') = UMAX, S('u') = UMAX,
- S('x') = UMAX, S('X') = UMAX,
- S('n') = PTR,
- }
-};
-
-#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
-
-union arg
-{
- uintmax_t i;
- long double f;
- void *p;
-};
-
-static void pop_arg(union arg *arg, int type, va_list *ap)
-{
- /* Give the compiler a hint for optimizing the switch. */
- if ((unsigned)type > MAXSTATE) return;
- switch (type) {
- case PTR: arg->p = va_arg(*ap, void *);
- break; case INT: arg->i = va_arg(*ap, int);
- break; case UINT: arg->i = va_arg(*ap, unsigned int);
-#ifndef LONG_IS_INT
- break; case LONG: arg->i = va_arg(*ap, long);
- break; case ULONG: arg->i = va_arg(*ap, unsigned long);
-#endif
- break; case ULLONG: arg->i = va_arg(*ap, unsigned long long);
- break; case SHORT: arg->i = (short)va_arg(*ap, int);
- break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int);
- break; case CHAR: arg->i = (signed char)va_arg(*ap, int);
- break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int);
-#ifdef ODD_TYPES
- break; case LLONG: arg->i = va_arg(*ap, long long);
- break; case SIZET: arg->i = va_arg(*ap, size_t);
- break; case IMAX: arg->i = va_arg(*ap, intmax_t);
- break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
- break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
- break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
-#endif
- break; case DBL: arg->f = va_arg(*ap, double);
- break; case LDBL: arg->f = va_arg(*ap, long double);
- }
-}
-
-static void out(FILE *f, const wchar_t *s, size_t l)
-{
-#if defined(__ANDROID__)
- fake_file_outw(f, s, l);
-#else
- while (l--) fputwc(*s++, f);
-#endif
-}
-
-static int getint(wchar_t **s) {
- int i;
- for (i=0; iswdigit(**s); (*s)++)
- i = 10*i + (**s-'0');
- return i;
-}
-
-static const char sizeprefix['y'-'a'] = {
-['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
-['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
-['p'-'a']='j'
-};
-
-static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
-{
- wchar_t *a, *z, *s=(wchar_t *)fmt, *s0;
- unsigned l10n=0, litpct, fl;
- int w, p;
- union arg arg;
- int argpos;
- unsigned st, ps;
- int cnt=0, l=0;
- int i;
- int t;
- char *bs;
- char charfmt[16];
- wchar_t wc;
-
- for (;;) {
- /* Update output count, end loop when fmt is exhausted */
- if (cnt >= 0) {
- if (l > INT_MAX - cnt) {
- if (!ferror(f)) errno = EOVERFLOW;
- cnt = -1;
- } else cnt += l;
- }
- if (!*s) break;
-
- /* Handle literal text and %% format specifiers */
- for (a=s; *s && *s!='%'; s++);
- litpct = wcsspn(s, L"%")/2; /* Optimize %%%% runs */
- z = s+litpct;
- s += 2*litpct;
- l = z-a;
- if (f) out(f, a, l);
- if (l) continue;
-
- if (iswdigit(s[1]) && s[2]=='$') {
- l10n=1;
- argpos = s[1]-'0';
- s+=3;
- } else {
- argpos = -1;
- s++;
- }
-
- /* Read modifier flags */
- for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
- fl |= 1U<<*s-' ';
-
- /* Read field width */
- if (*s=='*') {
- if (iswdigit(s[1]) && s[2]=='$') {
- l10n=1;
- nl_type[s[1]-'0'] = INT;
- w = nl_arg[s[1]-'0'].i;
- s+=3;
- } else if (!l10n) {
- w = f ? va_arg(*ap, int) : 0;
- s++;
- } else return -1;
- if (w<0) fl|=LEFT_ADJ, w=-w;
- } else if ((w=getint(&s))<0) return -1;
-
- /* Read precision */
- if (*s=='.' && s[1]=='*') {
- if (isdigit(s[2]) && s[3]=='$') {
- nl_type[s[2]-'0'] = INT;
- p = nl_arg[s[2]-'0'].i;
- s+=4;
- } else if (!l10n) {
- p = f ? va_arg(*ap, int) : 0;
- s+=2;
- } else return -1;
- } else if (*s=='.') {
- s++;
- p = getint(&s);
- } else p = -1;
-
- /* Format specifier state machine */
- s0=s;
- st=0;
- do {
- if (OOB(*s)) return -1;
- ps=st;
- st=states[st]S(*s++);
- } while (st-1<STOP);
- if (!st) return -1;
-
- /* Check validity of argument type (nl/normal) */
- if (st==NOARG) {
- if (argpos>=0) return -1;
- else if (!f) continue;
- } else {
- if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
- else if (f) pop_arg(&arg, st, ap);
- else return 0;
- }
-
- if (!f) continue;
- t = s[-1];
- if (ps && (t&15)==3) t&=~32;
-
- switch (t) {
- case 'n':
-#ifndef __ANDROID__ /* Disabled on Android for security reasons. */
- switch(ps) {
- case BARE: *(int *)arg.p = cnt; break;
- case LPRE: *(long *)arg.p = cnt; break;
- case LLPRE: *(long long *)arg.p = cnt; break;
- case HPRE: *(unsigned short *)arg.p = cnt; break;
- case HHPRE: *(unsigned char *)arg.p = cnt; break;
- case ZTPRE: *(size_t *)arg.p = cnt; break;
- case JPRE: *(uintmax_t *)arg.p = cnt; break;
- }
-#endif /* !__ANDROID__ */
- continue;
- case 'c':
- fputwc(btowc(arg.i), f);
- l = 1;
- continue;
- case 'C':
- fputwc(arg.i, f);
- l = 1;
- continue;
- case 'S':
- a = arg.p;
- z = wmemchr(a, 0, p);
- if (!z) z=a+p;
- else p=z-a;
- if (w<p) w=p;
- if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
- out(f, a, p);
- if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
- l=w;
- continue;
- case 's':
- bs = arg.p;
- if (p<0) p = INT_MAX;
- for (i=l=0; l<p && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
- if (i<0) return -1;
- p=l;
- if (w<p) w=p;
- if (!(fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
- bs = arg.p;
- while (l--) {
- i=mbtowc(&wc, bs, MB_LEN_MAX);
- bs+=i;
- fputwc(wc, f);
- }
- if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
- l=w;
- continue;
- }
-
- snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c",
- "#"+!(fl & ALT_FORM),
- "+"+!(fl & MARK_POS),
- "-"+!(fl & LEFT_ADJ),
- " "+!(fl & PAD_POS),
- "0"+!(fl & ZERO_PAD),
- sizeprefix[(t|32)-'a'], t);
-
- switch (t|32) {
- case 'a': case 'e': case 'f': case 'g':
- l = fprintf(f, charfmt, w, p, arg.f);
- break;
- case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
- l = fprintf(f, charfmt, w, p, arg.i);
- break;
- }
- }
-
- if (f) return cnt;
- if (!l10n) return 0;
-
- for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
- pop_arg(nl_arg+i, nl_type[i], ap);
- for (; i<=NL_ARGMAX && !nl_type[i]; i++);
- if (i<=NL_ARGMAX) return -1;
- return 1;
-}
-
-#ifdef __ANDROID__
-#undef FILE /* no longer needed */
-int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
-{
- va_list ap2;
- int nl_type[NL_ARGMAX] = {0};
- union arg nl_arg[NL_ARGMAX];
- int ret;
- FakeFILE out[1];
- fake_file_init_file(out, f);
- va_copy(ap2, ap);
- // Check for error in format string before writing anything to file.
- if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
- va_end(ap2);
- return -1;
- }
- ret = wprintf_core(out, fmt, &ap2, nl_arg, nl_type);
- va_end(ap2);
- return ret;
-}
-
-int vswprintf(wchar_t *restrict s, size_t l, const wchar_t *restrict fmt, va_list ap)
-{
- va_list ap2;
- int nl_type[NL_ARGMAX] = {0};
- union arg nl_arg[NL_ARGMAX];
- int ret;
- FakeFILE out[1];
- fake_file_init_wbuffer(out, s, l);
- va_copy(ap2, ap);
- ret = wprintf_core(out, fmt, &ap2, nl_arg, nl_type);
- va_end(ap2);
- if (fake_feof(out)) return -1;
- return ret;
-}
-#else /* !__ANDROID__ */
-int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
-{
- va_list ap2;
- int nl_type[NL_ARGMAX] = {0};
- union arg nl_arg[NL_ARGMAX];
- int ret;
-
- va_copy(ap2, ap);
- if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
-
- FLOCK(f);
- ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
- FUNLOCK(f);
- va_end(ap2);
- return ret;
-}
-#endif /* !__ANDROID__ */
diff --git a/sources/android/support/src/swprintf.cpp b/sources/android/support/src/swprintf.cpp
new file mode 100644
index 000000000..01cfe5da2
--- /dev/null
+++ b/sources/android/support/src/swprintf.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <wchar.h>
+
+#include "UniquePtr.h"
+
+namespace {
+const size_t MBS_FAILURE = static_cast<size_t>(-1);
+}
+
+int swprintf(wchar_t* wcs, size_t maxlen, const wchar_t* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ int result = vswprintf(wcs, maxlen, format, ap);
+ va_end(ap);
+ return result;
+}
+
+int vswprintf(wchar_t* wcs, size_t maxlen, const wchar_t* fmt, va_list ap) {
+ mbstate_t mbstate;
+ memset(&mbstate, 0, sizeof(mbstate));
+
+ // At most, each wide character (UTF-32) can be expanded to four narrow
+ // characters (UTF-8).
+ const size_t max_mb_len = maxlen * 4;
+ const size_t mb_fmt_len = wcslen(fmt) * 4 + 1;
+ UniquePtr<char[]> mbfmt(new char[mb_fmt_len]);
+ if (wcsrtombs(mbfmt.get(), &fmt, mb_fmt_len, &mbstate) == MBS_FAILURE) {
+ return -1;
+ }
+
+ UniquePtr<char[]> mbs(new char[max_mb_len]);
+ int nprinted = vsnprintf(mbs.get(), max_mb_len, mbfmt.get(), ap);
+ if (nprinted == -1) {
+ return -1;
+ }
+
+ const char* mbsp = mbs.get();
+ if (mbsrtowcs(wcs, &mbsp, maxlen, &mbstate) == MBS_FAILURE) {
+ return -1;
+ }
+
+ // Can't use return value from vsnprintf because that number is in narrow
+ // characters, not wide characters.
+ int result = wcslen(wcs);
+
+ // swprintf differs from snprintf in that it returns -1 if the output was
+ // truncated.
+ //
+ // Truncation can occur in two places:
+ // 1) vsnprintf truncated, in which case the return value is greater than the
+ // length we passed.
+ // 2) Since the char buffer we pass to vsnprintf might be oversized, that
+ // might not truncate while mbsrtowcs will. In this case, mbsp will point
+ // to the next unconverted character instead of nullptr.
+ if (nprinted >= max_mb_len || mbsp != nullptr) {
+ return -1;
+ }
+
+ return result;
+}
diff --git a/sources/android/support/tests/stdio_test.cpp b/sources/android/support/tests/stdio_test.cpp
index 86b45a1d4..57378a8bb 100644
--- a/sources/android/support/tests/stdio_test.cpp
+++ b/sources/android/support/tests/stdio_test.cpp
@@ -18,8 +18,13 @@ TEST(stdio,snprintf) {
ASSERT_EQ(12, snprintf(char_buff, 1, "%s", kString));
ASSERT_EQ(L'\0', char_buff[0]);
+ // %a support wasn't available until L, and we're losing this temporarily
+ // since I haven't ported this part of bionic yet.
+ // https://github.com/android-ndk/ndk/issues/437
+#if __ANDROID_API__ >= __ANDROID_API_L__
ASSERT_EQ(20, snprintf(char_buff, char_buff_len, "%a", 3.1415926535));
ASSERT_STREQ("0x1.921fb54411744p+1", char_buff);
+#endif
}
TEST(stdio,swprintf) {
@@ -27,13 +32,15 @@ TEST(stdio,swprintf) {
size_t wide_buff_len = sizeof(wide_buff) / sizeof(wchar_t);
ASSERT_EQ(2, swprintf(wide_buff, wide_buff_len, L"ab"));
ASSERT_EQ(5, swprintf(wide_buff, wide_buff_len, L"%s", "abcde"));
+
+ // %ls didn't work until L.
+#if __ANDROID_API__ >= __ANDROID_API_L__
static const wchar_t kWideString[] = L"Hello\uff41 World";
ASSERT_EQ(12, swprintf(wide_buff, wide_buff_len, L"%ls", kWideString));
ASSERT_EQ(12, swprintf(wide_buff, 13, L"%ls", kWideString));
+#endif
// Unlike snprintf(), swprintf() returns -1 in case of truncation
// and doesn't necessarily zero-terminate the output!
- ASSERT_EQ(-1, swprintf(wide_buff, 12, L"%ls", kWideString));
- ASSERT_EQ(-1, swprintf(wide_buff, 1, L"%ls", kWideString));
+ ASSERT_EQ(-1, swprintf(wide_buff, 1, L"%s", "foo"));
}
-