Merge "Implement wctomb(3) for ltrace."

This commit is contained in:
Elliott Hughes 2014-04-07 21:39:37 +00:00 committed by Gerrit Code Review
commit 5f149f1bde
5 changed files with 80 additions and 18 deletions

View File

@ -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 @@ 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 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 @@ wint_t ungetwc(wint_t wc, FILE* stream) {
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);
}

View File

@ -151,7 +151,6 @@ extern lldiv_t lldiv(long long, long long);
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 @@ extern int mbtowc(wchar_t *, const char *, size_t);
/* 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

View File

@ -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 int wscanf(const wchar_t *, ...);
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

View File

@ -82,6 +82,7 @@ libBionicStandardTests_src_files := \
system_properties_test.cpp \
time_test.cpp \
unistd_test.cpp \
wchar_test.cpp \
libBionicStandardTests_cflags := \
$(test_cflags) \

57
tests/wchar_test.cpp Normal file
View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <limits.h>
#include <wchar.h>
TEST(wchar, sizeof_wchar_t) {
EXPECT_EQ(4U, sizeof(wchar_t));
EXPECT_EQ(4U, sizeof(wint_t));
}
TEST(wchar, mbrlen) {
char bytes[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
EXPECT_EQ(0U, mbrlen(&bytes[0], 0, NULL));
EXPECT_EQ(1U, mbrlen(&bytes[0], 1, NULL));
EXPECT_EQ(1U, mbrlen(&bytes[4], 1, NULL));
EXPECT_EQ(0U, mbrlen(&bytes[5], 1, NULL));
}
TEST(wchar, wctomb_wcrtomb) {
// wctomb and wcrtomb behave differently when s == NULL.
EXPECT_EQ(0, wctomb(NULL, L'h'));
EXPECT_EQ(0, wctomb(NULL, L'\0'));
EXPECT_EQ(1U, wcrtomb(NULL, L'\0', NULL));
EXPECT_EQ(1U, wcrtomb(NULL, L'h', NULL));
char bytes[MB_LEN_MAX];
// wctomb and wcrtomb behave similarly for the null wide character.
EXPECT_EQ(1, wctomb(bytes, L'\0'));
EXPECT_EQ(1U, wcrtomb(bytes, L'\0', NULL));
// ...and for regular characters.
bytes[0] = 'x';
EXPECT_EQ(1, wctomb(bytes, L'h'));
EXPECT_EQ('h', bytes[0]);
bytes[0] = 'x';
EXPECT_EQ(1U, wcrtomb(bytes, L'h', NULL));
EXPECT_EQ('h', bytes[0]);
}