Implement wctomb(3) for ltrace.
This is an implementation in the style of the rest: char == byte.
We might want to come back and implement UTF-8, but this is enough for ltrace.
Bug: 13747066
Change-Id: Ib2b63609c9014fdef9a8491e067467c4fc5ae3cc
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index 50a3875..8d56458 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -28,6 +28,7 @@
#include <ctype.h>
#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
@@ -156,8 +157,8 @@
return 1;
}
-size_t mbrlen(const char* /*s*/, size_t n, mbstate_t* /*ps*/) {
- return (n != 0);
+size_t mbrlen(const char* s, size_t n, mbstate_t* /*ps*/) {
+ return (n == 0 || s[0] == 0) ? 0 : 1;
}
size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* /*ps*/) {
@@ -217,13 +218,26 @@
return ungetc(static_cast<char>(wc), stream);
}
-size_t wcrtomb(char* s, wchar_t /*wc*/, mbstate_t* /*ps*/) {
- if (s != NULL) {
- *s = 1;
+int wctomb(char* s, wchar_t wc) {
+ if (s == NULL) {
+ return 0;
+ }
+ if (wc <= 0xff) {
+ *s = static_cast<char>(wc);
+ } else {
+ *s = '?';
}
return 1;
}
+size_t wcrtomb(char* s, wchar_t wc, mbstate_t* /*ps*/) {
+ if (s == NULL) {
+ char buf[MB_LEN_MAX];
+ return wctomb(buf, L'\0');
+ }
+ return wctomb(s, wc);
+}
+
size_t wcsftime(wchar_t* wcs, size_t maxsize, const wchar_t* format, const struct tm* timptr) {
return strftime(reinterpret_cast<char*>(wcs), maxsize, reinterpret_cast<const char*>(format), timptr);
}
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 9b7e6d1..5dbcb3d 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -151,7 +151,6 @@
extern const char* getprogname(void);
extern void setprogname(const char*);
-#if 1 /* MISSING FROM BIONIC - ENABLED FOR STLPort and libstdc++-v3 */
/* make STLPort happy */
extern int mblen(const char *, size_t);
extern size_t mbstowcs(wchar_t *, const char *, size_t);
@@ -160,7 +159,6 @@
/* Likewise, make libstdc++-v3 happy. */
extern int wctomb(char *, wchar_t);
extern size_t wcstombs(char *, const wchar_t *, size_t);
-#endif /* MISSING */
#define MB_CUR_MAX 1
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index 32cf127..89c6fb6 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -36,13 +36,6 @@
#include <time.h>
#include <malloc.h>
-/* IMPORTANT: Any code that relies on wide character support is essentially
- * non-portable and/or broken. the only reason this header exist
- * is because I'm really a nice guy. However, I'm not nice enough
- * to provide you with a real implementation. instead wchar_t == char
- * and all wc functions are stubs to their "normal" equivalent...
- */
-
__BEGIN_DECLS
typedef __WINT_TYPE__ wint_t;
@@ -150,12 +143,11 @@
extern size_t wcslcat(wchar_t*, const wchar_t*, size_t);
extern size_t wcslcpy(wchar_t*, const wchar_t*, size_t);
-/* No really supported. These are just for making libstdc++-v3 happy. */
typedef void *wctrans_t;
-extern wint_t towctrans(wint_t, wctrans_t);
-extern wctrans_t wctrans (const char *);
+extern wint_t towctrans(wint_t, wctrans_t);
+extern wctrans_t wctrans(const char*);
-#if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
+#if __POSIX_VISIBLE >= 200809
wchar_t* wcsdup(const wchar_t*);
size_t wcsnlen(const wchar_t*, size_t);
#endif