diff --git a/libc/Android.mk b/libc/Android.mk index 84f42596659..79f2c9d8d76 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -178,14 +178,12 @@ libc_common_src_files := \ bionic/eventfd.c \ bionic/fcntl.c \ bionic/fdprintf.c \ - bionic/__fgets_chk.cpp \ bionic/flockfile.c \ bionic/fork.c \ bionic/fstatfs.c \ bionic/ftime.c \ bionic/ftok.c \ bionic/fts.c \ - bionic/getcwd.cpp \ bionic/getdtablesize.c \ bionic/gethostname.c \ bionic/getpgrp.c \ @@ -199,18 +197,14 @@ libc_common_src_files := \ bionic/issetugid.c \ bionic/ldexp.c \ bionic/libc_init_common.c \ - bionic/locale.c \ bionic/logd_write.c \ bionic/lseek64.c \ bionic/md5.c \ bionic/memccpy.c \ bionic/memchr.c \ - bionic/__memcpy_chk.cpp \ bionic/memmem.c \ - bionic/__memmove_chk.cpp \ bionic/memmove_words.c \ bionic/memrchr.c \ - bionic/__memset_chk.cpp \ bionic/memswap.c \ bionic/mmap.c \ bionic/openat.c \ @@ -253,40 +247,24 @@ libc_common_src_files := \ bionic/sigwait.c \ bionic/sleep.c \ bionic/statfs.c \ - bionic/__strcat_chk.cpp \ bionic/strcoll.c \ - bionic/__strcpy_chk.cpp \ - bionic/strerror.cpp \ - bionic/strerror_r.cpp \ - bionic/__strlcat_chk.cpp \ - bionic/__strlcpy_chk.cpp \ - bionic/__strlen_chk.cpp \ - bionic/__strncat_chk.cpp \ - bionic/__strncpy_chk.cpp \ bionic/strndup.c \ bionic/strnlen.c \ bionic/strntoimax.c \ bionic/strntoumax.c \ - bionic/strsignal.cpp \ bionic/strtotimeval.c \ - bionic/stubs.cpp \ bionic/system_properties.c \ bionic/tcgetpgrp.c \ bionic/tcsetpgrp.c \ bionic/tdestroy.c \ bionic/thread_atexit.c \ bionic/time64.c \ - bionic/tmpfile.cpp \ - bionic/__umask_chk.cpp \ bionic/umount.c \ bionic/unlockpt.c \ bionic/usleep.c \ bionic/utime.c \ bionic/utmp.c \ - bionic/__vsnprintf_chk.cpp \ - bionic/__vsprintf_chk.cpp \ bionic/wait.c \ - bionic/wchar.c \ bionic/wcscoll.c \ netbsd/gethnamaddr.c \ netbsd/isc/ev_timers.c \ @@ -319,6 +297,30 @@ libc_common_src_files := \ netbsd/nameser/ns_print.c \ netbsd/nameser/ns_samedomain.c \ +libc_bionic_src_files := \ + bionic/__fgets_chk.cpp \ + bionic/getcwd.cpp \ + bionic/__memcpy_chk.cpp \ + bionic/__memmove_chk.cpp \ + bionic/__memset_chk.cpp \ + bionic/setlocale.cpp \ + bionic/__strcat_chk.cpp \ + bionic/__strcpy_chk.cpp \ + bionic/strerror.cpp \ + bionic/strerror_r.cpp \ + bionic/__strlcat_chk.cpp \ + bionic/__strlcpy_chk.cpp \ + bionic/__strlen_chk.cpp \ + bionic/__strncat_chk.cpp \ + bionic/__strncpy_chk.cpp \ + bionic/strsignal.cpp \ + bionic/stubs.cpp \ + bionic/tmpfile.cpp \ + bionic/__umask_chk.cpp \ + bionic/__vsnprintf_chk.cpp \ + bionic/__vsprintf_chk.cpp \ + bionic/wchar.cpp \ + libc_upstream_netbsd_src_files := \ upstream-netbsd/libc/compat-43/creat.c \ upstream-netbsd/libc/gen/ftw.c \ @@ -509,7 +511,6 @@ libc_common_cflags := \ -I$(LOCAL_PATH)/private \ -DPOSIX_MISTAKE \ -DLOG_ON_HEAP_ERROR \ - -std=gnu99 \ -Wall -Wextra # these macro definitions are required to implement the @@ -772,6 +773,22 @@ LOCAL_SYSTEM_SHARED_LIBRARIES := include $(BUILD_STATIC_LIBRARY) +# ======================================================== +# libc_bionic.a - home-grown C library code +# ======================================================== +# +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(libc_bionic_src_files) +LOCAL_CFLAGS := $(libc_common_cflags) -Werror +LOCAL_C_INCLUDES := $(libc_common_c_includes) +LOCAL_MODULE := libc_bionic +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk +LOCAL_SYSTEM_SHARED_LIBRARIES := + +include $(BUILD_STATIC_LIBRARY) + + # ======================================================== # libc_common.a # ======================================================== @@ -779,11 +796,11 @@ include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := $(libc_common_src_files) -LOCAL_CFLAGS := $(libc_common_cflags) +LOCAL_CFLAGS := $(libc_common_cflags) -std=gnu99 LOCAL_C_INCLUDES := $(libc_common_c_includes) LOCAL_MODULE := libc_common LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk -LOCAL_WHOLE_STATIC_LIBRARIES := libbionic_ssp libc_netbsd +LOCAL_WHOLE_STATIC_LIBRARIES := libbionic_ssp libc_bionic libc_netbsd LOCAL_SYSTEM_SHARED_LIBRARIES := include $(BUILD_STATIC_LIBRARY) @@ -808,7 +825,8 @@ LOCAL_SRC_FILES := \ LOCAL_C_INCLUDES := $(libc_common_c_includes) LOCAL_CFLAGS := $(libc_common_cflags) \ - -DLIBC_STATIC + -DLIBC_STATIC \ + -std=gnu99 LOCAL_MODULE := libc_nomalloc LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk @@ -831,7 +849,8 @@ LOCAL_SRC_FILES := \ bionic/libc_init_static.c LOCAL_CFLAGS := $(libc_common_cflags) \ - -DLIBC_STATIC + -DLIBC_STATIC \ + -std=gnu99 LOCAL_C_INCLUDES := $(libc_common_c_includes) LOCAL_MODULE := libc LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk @@ -852,7 +871,7 @@ include $(CLEAR_VARS) # Since this code is experimental it is disabled by default. # see libc/bionic/pthread_debug.c for details -LOCAL_CFLAGS := $(libc_common_cflags) -DPTHREAD_DEBUG -DPTHREAD_DEBUG_ENABLED=0 +LOCAL_CFLAGS := $(libc_common_cflags) -std=gnu99 -DPTHREAD_DEBUG -DPTHREAD_DEBUG_ENABLED=0 LOCAL_C_INCLUDES := $(libc_common_c_includes) LOCAL_SRC_FILES := \ diff --git a/libc/bionic/locale.c b/libc/bionic/setlocale.cpp similarity index 91% rename from libc/bionic/locale.c rename to libc/bionic/setlocale.cpp index 9dabbe486c0..e8fdc9e89e4 100644 --- a/libc/bionic/locale.c +++ b/libc/bionic/setlocale.cpp @@ -25,10 +25,11 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #include +#include -char* setlocale (int category, char const *locale) -{ - /* INTENTIONAL: there is no locale support in Bionic */ - return 0; +// setlocale(3) always fails on bionic. +char* setlocale(int /*category*/, char const* /*locale*/) { + return NULL; } diff --git a/libc/bionic/wchar.c b/libc/bionic/wchar.c deleted file mode 100644 index d83613a6b2a..00000000000 --- a/libc/bionic/wchar.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2008 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 -#include -#include -#include -#include - -/* stubs for wide-char functions */ -wint_t btowc(int c) -{ - return (c == EOF) ? WEOF : c; -} - -int fwprintf(FILE *stream, const wchar_t *format, ...) -{ - va_list args; - int result; - - va_start(args, format); - result = vfwprintf(stream, format, args); - va_end(args); - return result; -} - -int wprintf(const wchar_t *format, ...) -{ - va_list args; - int result; - - va_start(args, format); - result = vwprintf(format, args); - va_end(args); - return result; -} - -int swprintf(wchar_t *s, size_t n, const wchar_t *format, ...) -{ - va_list args; - int result; - - va_start(args, format); - result = vswprintf(s, n, format, args); - va_end(args); - return result; -} - -int vwprintf(const wchar_t *format, va_list arg) -{ - return vfwprintf(stdout, format, arg); -} - -int vfwprintf(FILE *stream, const wchar_t *format, va_list arg) -{ - errno = ENOTSUP; - return -1; -} - -int vswprintf(wchar_t *s, size_t n, const wchar_t *format, va_list arg) -{ - errno = ENOTSUP; - return -1; -} - -int fwscanf(FILE *stream, const wchar_t *format, ... ) -{ - errno = ENOTSUP; - return -1; -} - -int wscanf(const wchar_t *format, ... ) -{ - va_list args; - int result; - - va_start (args, format); - result = fwscanf(stdout, format, args ); - va_end (args); - return result; -} - -int swscanf(const wchar_t *s, const wchar_t *format, ... ) -{ - errno = ENOTSUP; - return -1; -} - -int iswalnum(wint_t wc) { return isalnum(wc); } -int iswalpha(wint_t wc) { return isalpha(wc); } -int iswcntrl(wint_t wc) { return iscntrl(wc); } -int iswdigit(wint_t wc) { return isdigit(wc); } -int iswgraph(wint_t wc) { return isgraph(wc); } -int iswlower(wint_t wc) { return islower(wc); } -int iswprint(wint_t wc) { return isprint(wc); } -int iswpunct(wint_t wc) { return ispunct(wc); } -int iswspace(wint_t wc) { return isspace(wc); } -int iswupper(wint_t wc) { return isupper(wc); } -int iswxdigit(wint_t wc) { return isxdigit(wc); } - -int iswctype(wint_t wc, wctype_t charclass) -{ - switch (charclass) { - case WC_TYPE_ALNUM: return isalnum(wc); - case WC_TYPE_ALPHA: return isalpha(wc); - case WC_TYPE_BLANK: return isblank(wc); - case WC_TYPE_CNTRL: return iscntrl(wc); - case WC_TYPE_DIGIT: return isdigit(wc); - case WC_TYPE_GRAPH: return isgraph(wc); - case WC_TYPE_LOWER: return islower(wc); - case WC_TYPE_PRINT: return isprint(wc); - case WC_TYPE_PUNCT: return ispunct(wc); - case WC_TYPE_SPACE: return isspace(wc); - case WC_TYPE_UPPER: return isupper(wc); - case WC_TYPE_XDIGIT: return isxdigit(wc); - default: return 0; - }; -} - -wint_t fgetwc(FILE *stream) -{ - return (wint_t)fgetc(stream); -} - -wchar_t *fgetws(wchar_t *ws, int n, FILE *stream) -{ - return (wchar_t*) fgets((char*)ws, n, stream); -} - -wint_t fputwc(wchar_t wc, FILE *stream) -{ - return (wint_t)fputc((char)wc, stream); -} - -int fputws(const wchar_t *str, FILE *stream) -{ - return fputs( (const char*)str, stream ); -} - -int fwide(FILE *stream, int mode) -{ - stream=stream; - return (mode); -} - -wint_t getwc(FILE *stream) -{ - return getc(stream); -} - -wint_t getwchar(void) -{ - return getchar(); -} - -int mbsinit(const mbstate_t *ps) -{ - ps=ps; - return 1; -} - -size_t mbrlen(const char *s, size_t n, mbstate_t *ps) -{ - return (n != 0); -} - -size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps) -{ - if (s == NULL) { - s = ""; - pwc = NULL; - } - if (n == 0) { - if (pwc) - *pwc = 0; - return 0; - } - if (pwc) - *pwc = *s; - - return (*s != 0); -} - -size_t mbsrtowcs(wchar_t *dst, const char **src, size_t len, mbstate_t *ps) -{ - const char* s = *src; - const char* s2 = memchr( s, 0, len ); - - if (s2 != NULL) - len = (size_t)(s2 - s) + 1U; - - if (dst) - memcpy( (char*)dst, s, len ); - - *src = s + len; - return len; -} - -size_t mbstowcs(wchar_t *dst, const char *src, size_t len) -{ - return mbsrtowcs(dst, &src, len, NULL); -} - -wint_t putwc(wchar_t wc, FILE *stream) -{ - return fputc((char)wc, stream); -} - -wint_t putwchar(wchar_t wc) -{ - return putchar((char)wc); -} - -wint_t towlower(wint_t wc) -{ - return tolower(wc); -} - -wint_t towupper(wint_t wc) -{ - return toupper(wc); -} - -wint_t ungetwc(wint_t wc, FILE *stream) -{ - return ungetc((char)wc, stream); -} - -size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps) -{ - if (s != NULL) - *s = 1; - return 1; -} - -size_t wcsftime(wchar_t *wcs, size_t maxsize, const wchar_t *format, const struct tm *timptr) -{ - return strftime( (char*)wcs, maxsize, (const char*)format, timptr ); -} - -size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps) -{ - const char* s = (const char*)*src; - const char* s2 = memchr( s, 0, len ); - - if (s2 != NULL) - len = (s2 - s)+1; - - if (dst != NULL) - memcpy( dst, s, len ); - - *src = (wchar_t*)(s + len); - return len; -} - -size_t wcstombs(char *dst, const wchar_t *src, size_t len) -{ - return wcsrtombs(dst, &src, len, NULL); -} - -double wcstod(const wchar_t *nptr, wchar_t **endptr) -{ - return strtod( (const char*)nptr, (char**)endptr ); -} - -long int wcstol(const wchar_t *nptr, wchar_t **endptr, int base) -{ - return strtol( (const char*)nptr, (char**)endptr, base ); -} - -unsigned long int wcstoul(const wchar_t *nptr, wchar_t **endptr, int base) -{ - return strtoul( (const char*)nptr, (char**)endptr, base ); -} - -wchar_t *wcswcs(const wchar_t *ws1, const wchar_t *ws2) -{ - return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 ); -} - -int wctob(wint_t c) -{ - return c; -} - -wctype_t wctype(const char *property) -{ - static const char* const properties[WC_TYPE_MAX] = - { - "", - "alnum", "alpha", "blank", "cntrl", "digit", "graph", - "lower", "print", "punct", "space", "upper", "xdigit" - }; - int nn; - - for ( nn = 0; nn < WC_TYPE_MAX; nn++ ) - if ( !strcmp( properties[nn], property ) ) - return (wctype_t)(nn); - - return 0; -} - -int wcwidth(wchar_t wc) -{ - return (wc > 0); -} diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp new file mode 100644 index 00000000000..50a387535ae --- /dev/null +++ b/libc/bionic/wchar.cpp @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2008 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 +#include +#include +#include +#include + +/* stubs for wide-char functions */ + +wint_t btowc(int c) { + return (c == EOF) ? WEOF : c; +} + +int fwprintf(FILE* stream, const wchar_t* format, ...) { + va_list args; + va_start(args, format); + int result = vfwprintf(stream, format, args); + va_end(args); + return result; +} + +int wprintf(const wchar_t* format, ...) { + va_list args; + va_start(args, format); + int result = vwprintf(format, args); + va_end(args); + return result; +} + +int swprintf(wchar_t* s, size_t n, const wchar_t* format, ...) { + va_list args; + va_start(args, format); + int result = vswprintf(s, n, format, args); + va_end(args); + return result; +} + +int vwprintf(const wchar_t* format, va_list arg) { + return vfwprintf(stdout, format, arg); +} + +int vfwprintf(FILE* /*stream*/, const wchar_t* /*format*/, va_list /*arg*/) { + errno = ENOTSUP; + return -1; +} + +int vswprintf(wchar_t* /*s*/, size_t /*n*/, const wchar_t* /*format*/, va_list /*arg*/) { + errno = ENOTSUP; + return -1; +} + +int fwscanf(FILE* /*stream*/, const wchar_t* /*format*/, ... ) { + errno = ENOTSUP; + return -1; +} + +int wscanf(const wchar_t* format, ... ) { + va_list args; + va_start (args, format); + int result = fwscanf(stdout, format, args ); + va_end (args); + return result; +} + +int swscanf(const wchar_t* /*s*/, const wchar_t* /*format*/, ... ) { + errno = ENOTSUP; + return -1; +} + +int iswalnum(wint_t wc) { return isalnum(wc); } +int iswalpha(wint_t wc) { return isalpha(wc); } +int iswcntrl(wint_t wc) { return iscntrl(wc); } +int iswdigit(wint_t wc) { return isdigit(wc); } +int iswgraph(wint_t wc) { return isgraph(wc); } +int iswlower(wint_t wc) { return islower(wc); } +int iswprint(wint_t wc) { return isprint(wc); } +int iswpunct(wint_t wc) { return ispunct(wc); } +int iswspace(wint_t wc) { return isspace(wc); } +int iswupper(wint_t wc) { return isupper(wc); } +int iswxdigit(wint_t wc) { return isxdigit(wc); } + +int iswctype(wint_t wc, wctype_t char_class) { + switch (char_class) { + case WC_TYPE_ALNUM: return isalnum(wc); + case WC_TYPE_ALPHA: return isalpha(wc); + case WC_TYPE_BLANK: return isblank(wc); + case WC_TYPE_CNTRL: return iscntrl(wc); + case WC_TYPE_DIGIT: return isdigit(wc); + case WC_TYPE_GRAPH: return isgraph(wc); + case WC_TYPE_LOWER: return islower(wc); + case WC_TYPE_PRINT: return isprint(wc); + case WC_TYPE_PUNCT: return ispunct(wc); + case WC_TYPE_SPACE: return isspace(wc); + case WC_TYPE_UPPER: return isupper(wc); + case WC_TYPE_XDIGIT: return isxdigit(wc); + default: return 0; + } +} + +wint_t fgetwc(FILE* stream) { + return static_cast(fgetc(stream)); +} + +wchar_t* fgetws(wchar_t* ws, int n, FILE* stream) { + return reinterpret_cast(fgets(reinterpret_cast(ws), n, stream)); +} + +wint_t fputwc(wchar_t wc, FILE* stream) { + return static_cast(fputc(static_cast(wc), stream)); +} + +int fputws(const wchar_t* str, FILE* stream) { + return fputs(reinterpret_cast(str), stream ); +} + +int fwide(FILE* /*stream*/, int mode) { + return mode; +} + +wint_t getwc(FILE* stream) { + return getc(stream); +} + +wint_t getwchar() { + return getchar(); +} + +int mbsinit(const mbstate_t* /*ps*/) { + return 1; +} + +size_t mbrlen(const char* /*s*/, size_t n, mbstate_t* /*ps*/) { + return (n != 0); +} + +size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* /*ps*/) { + if (s == NULL) { + s = ""; + pwc = NULL; + } + if (n == 0) { + if (pwc) { + *pwc = 0; + return 0; + } + } + if (pwc) { + *pwc = *s; + } + return (*s != 0); +} + +size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* /*ps*/) { + const char* s = *src; + const char* s2 = reinterpret_cast(memchr(s, 0, len)); + + if (s2 != NULL) { + len = (size_t)(s2 - s) + 1U; + } + + if (dst) { + memcpy(reinterpret_cast(dst), s, len ); + } + + *src = s + len; + return len; +} + +size_t mbstowcs(wchar_t* dst, const char* src, size_t len) { + return mbsrtowcs(dst, &src, len, NULL); +} + +wint_t putwc(wchar_t wc, FILE* stream) { + return fputc(static_cast(wc), stream); +} + +wint_t putwchar(wchar_t wc) { + return putchar(static_cast(wc)); +} + +wint_t towlower(wint_t wc) { + return tolower(wc); +} + +wint_t towupper(wint_t wc) { + return toupper(wc); +} + +wint_t ungetwc(wint_t wc, FILE* stream) { + return ungetc(static_cast(wc), stream); +} + +size_t wcrtomb(char* s, wchar_t /*wc*/, mbstate_t* /*ps*/) { + if (s != NULL) { + *s = 1; + } + return 1; +} + +size_t wcsftime(wchar_t* wcs, size_t maxsize, const wchar_t* format, const struct tm* timptr) { + return strftime(reinterpret_cast(wcs), maxsize, reinterpret_cast(format), timptr); +} + +size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* /*ps*/) { + const char* s = reinterpret_cast(*src); + const char* s2 = reinterpret_cast(memchr(s, 0, len)); + if (s2 != NULL) { + len = (s2 - s)+1; + } + if (dst != NULL) { + memcpy( dst, s, len ); + } + *src = (wchar_t*)(s + len); + return len; +} + +size_t wcstombs(char* dst, const wchar_t* src, size_t len) { + return wcsrtombs(dst, &src, len, NULL); +} + +double wcstod(const wchar_t* nptr, wchar_t** endptr) { + return strtod(reinterpret_cast(nptr), reinterpret_cast(endptr)); +} + +long int wcstol(const wchar_t* nptr, wchar_t** endptr, int base) { + return strtol(reinterpret_cast(nptr), reinterpret_cast(endptr), base); +} + +unsigned long int wcstoul(const wchar_t* nptr, wchar_t** endptr, int base) { + return strtoul(reinterpret_cast(nptr), reinterpret_cast(endptr), base); +} + +wchar_t* wcswcs(const wchar_t* ws1, const wchar_t* ws2) { + const char* s1 = reinterpret_cast(ws1); + const char* s2 = reinterpret_cast(ws2); + return reinterpret_cast(strstr(s1, s2)); +} + +int wctob(wint_t c) { + return c; +} + +wctype_t wctype(const char* property) { + static const char* const properties[WC_TYPE_MAX] = { + "", + "alnum", "alpha", "blank", "cntrl", "digit", "graph", + "lower", "print", "punct", "space", "upper", "xdigit" + }; + for (size_t i = 0; i < WC_TYPE_MAX; ++i) { + if (!strcmp(properties[i], property)) { + return static_cast(i); + } + } + return static_cast(0); +} + +int wcwidth(wchar_t wc) { + return (wc > 0); +}