Activate our new multibyte implementation.

* add implementations for the following multibyte-related
  functions:
    btwoc()
    mblen()
    mbrlen()
    mbrtowc()
    mbsinit()
    mbtowc()
    wcrtomb()
    wcswidth()
    wctob()
    wctomb()
* the implementation of the above function live in a symbol
  named __<name>, the above symbol names are defined as a weak
  alias to the internal ones - TODO: we need to make sure to
  only invoked the internal functions (i.e. prepended with __)
  in order to avoid problems with symbol preemption.
* deactivate the limited mb implementation we provided before,
  as well as respective stuff from glibc
This commit is contained in:
Oliver Tappe 2011-11-22 18:31:27 +01:00
parent 32a04e8721
commit cc5eca7554
15 changed files with 342 additions and 22 deletions

View File

@ -17,11 +17,14 @@ __BEGIN_DECLS
extern wint_t __btowc(int);
extern int __mblen(const char *string, size_t maxSize);
extern size_t __mbrlen(const char *s, size_t n, mbstate_t *ps);
extern size_t __mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
extern int __mbsinit(const mbstate_t *);
extern size_t __mbsrtowcs(wchar_t *dst, const char **src, size_t len,
mbstate_t *ps);
extern size_t __mbstowcs(wchar_t *pwcs, const char *string, size_t maxSize);
extern int __mbtowc(wchar_t *pwc, const char *string, size_t maxSize);
extern size_t __wcrtomb(char *, wchar_t, mbstate_t *);
extern wchar_t *__wcscat(wchar_t *, const wchar_t *);
@ -51,6 +54,8 @@ extern long double __wcstold(const wchar_t *, wchar_t **);
extern long long __wcstoll(const wchar_t *, wchar_t **, int);
extern unsigned long __wcstoul(const wchar_t *, wchar_t **, int);
extern unsigned long long __wcstoull(const wchar_t *, wchar_t **, int);
extern size_t __wcstombs(char *string, const wchar_t *pwcs, size_t maxSize);
extern int __wctomb(char *string, wchar_t wchar);
extern wchar_t *__wcswcs(const wchar_t *, const wchar_t *);
extern int __wcswidth(const wchar_t *, size_t);
extern size_t __wcsxfrm(wchar_t *, const wchar_t *, size_t);

View File

@ -23,9 +23,7 @@ MergeObject posix_gnu_stdlib.o :
lcong48_r.c
lrand48.c
lrand48_r.c
mblen.c
mbstowcs.c
mbtowc.c
mrand48.c
mrand48_r.c
nrand48.c
@ -39,5 +37,4 @@ MergeObject posix_gnu_stdlib.o :
strtold.c
strtof.c
wcstombs.c
wctomb.c
;

View File

@ -15,16 +15,11 @@ SubDirSysHdrs $(HAIKU_TOP) src system libroot posix glibc ;
SubDirCcFlags -D_GNU_SOURCE -DUSE_IN_LIBIO ;
MergeObject posix_gnu_wcsmbs.o :
btowc.c
mbrlen.c
mbrtowc.c
mbsinit.c
mbsnrtowcs.c
mbsrtowcs.c
# mbsrtowcs_l.c
wcpcpy.c
wcpncpy.c
wcrtomb.c
wcscasecmp.c
# wcscasecmp_l.c
wcscat.c
@ -55,10 +50,7 @@ MergeObject posix_gnu_wcsmbs.o :
wcstold.c
wcstoul.c
wcstoull.c
# wcswidth.c
wcsxfrm.c
wctob.c
# wcwidth.c
wmemchr.c
wmemcmp.c
wmemcpy.c

View File

@ -13,10 +13,5 @@ MergeObject posix_locale.o :
localeconv.cpp
nl_langinfo.cpp
setlocale.cpp
#mb_none.c
#mblen.c
#mbrtowc.c
#mbsinit.c
#wcrtomb.c
wctype.cpp
;

View File

@ -1,6 +1,20 @@
SubDir HAIKU_TOP src system libroot posix wchar ;
MergeObject posix_wchar.o :
wcwidth.c
wcswidth.c
UsePrivateHeaders
[ FDirName libroot ]
[ FDirName libroot locale ]
;
MergeObject posix_wchar.o :
btowc.c
mblen.c
mbrlen.c
mbrtowc.cpp
mbsinit.c
mbtowc.c
wcrtomb.cpp
wcswidth.c
wctob.c
wctomb.c
wcwidth.c
;

View File

@ -0,0 +1,33 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wint_t
__btowc(int c)
{
static mbstate_t internalMbState;
char character = (char)c;
wchar_t wc;
if (c == EOF)
return WEOF;
if (c == '\0')
return L'\0';
{
int byteCount = mbrtowc(&wc, &character, 1, &internalMbState);
if (byteCount != 1)
return WEOF;
}
return wc;
}
B_DEFINE_WEAK_ALIAS(__btowc, btowc);

View File

@ -0,0 +1,32 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__mblen(const char* s, size_t n)
{
static mbstate_t internalMbState;
int rval;
if (s == NULL) {
static const mbstate_t initial;
internalMbState = initial;
return 0; // we do not support stateful converters
}
rval = __mbrtowc(NULL, s, n, &internalMbState);
if (rval == -1 || rval == -2)
return -1;
return rval;
}
B_DEFINE_WEAK_ALIAS(__mblen, mblen);

View File

@ -0,0 +1,21 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
size_t
__mbrlen(const char* s, size_t n, mbstate_t* ps)
{
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
}
return __mbrtowc(NULL, s, n, ps);
}
B_DEFINE_WEAK_ALIAS(__mbrlen, mbrlen);

View File

@ -0,0 +1,77 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <errno.h>
#include <string.h>
#include <wchar.h>
#include "LocaleBackend.h"
using BPrivate::Libroot::gLocaleBackend;
extern "C" size_t
__mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* ps)
{
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
}
if (s == NULL)
return __mbrtowc(NULL, "", 1, ps);
if (gLocaleBackend == NULL) {
if (*s == '\0') {
memset(ps, 0, sizeof(mbstate_t));
if (pwc != NULL)
*pwc = 0;
return 0;
}
/*
* The POSIX locale is active. Since the POSIX locale only contains
* chars 0-127 and those ASCII chars are compatible with the UTF32
* values used in wint_t, we can just return the byte.
*/
if (*s < 0) {
// char is non-ASCII
errno = EILSEQ;
return (size_t)-1;
}
if (pwc != NULL)
*pwc = *s;
return 1;
}
size_t lengthUsed;
status_t status
= gLocaleBackend->MultibyteToWchar(pwc, s, n, ps, lengthUsed);
if (status == B_BAD_INDEX)
return (size_t)-2;
if (status == B_BAD_DATA) {
errno = EILSEQ;
return (size_t)-1;
}
if (status != B_OK) {
errno = EINVAL;
return (size_t)-1;
}
return lengthUsed;
}
extern "C"
B_DEFINE_WEAK_ALIAS(__mbrtowc, mbrtowc);

View File

@ -0,0 +1,16 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__mbsinit(const mbstate_t* ps)
{
return ps == NULL || ps->count == 0;
}
B_DEFINE_WEAK_ALIAS(__mbsinit, mbsinit);

View File

@ -0,0 +1,26 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <errno.h>
#include <wchar_private.h>
int
__mbtowc(wchar_t* pwc, const char* s, size_t n)
{
static mbstate_t internalMbState;
int result = mbrtowc(pwc, s, n, &internalMbState);
if (result == -2) {
errno = EILSEQ;
result = -1;
}
return result;
}
B_DEFINE_WEAK_ALIAS(__mbtowc, mbtowc);

View File

@ -0,0 +1,67 @@
/*
** Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <errno.h>
#include <string.h>
#include <wchar.h>
#include "LocaleBackend.h"
using BPrivate::Libroot::gLocaleBackend;
extern "C" size_t
__wcrtomb(char* s, wchar_t wc, mbstate_t* ps)
{
if (ps == NULL) {
static mbstate_t internalMbState;
ps = &internalMbState;
}
if (s == NULL) {
char internalBuffer[MB_LEN_MAX];
return __wcrtomb(internalBuffer, L'\0', ps);
}
if (gLocaleBackend == NULL) {
/*
* The POSIX locale is active. Since the POSIX locale only contains
* chars 0-127 and those ASCII chars are compatible with the UTF32
* values used in wint_t, we can just return the byte.
*/
if (wc > 127) {
// char is non-ASCII
errno = EILSEQ;
return (size_t)-1;
}
*s = char(wc);
return 1;
}
size_t lengthUsed;
status_t status = gLocaleBackend->WcharToMultibyte(s, wc, ps, lengthUsed);
if (status == B_BAD_INDEX)
return (size_t)-2;
if (status == B_BAD_DATA) {
errno = EILSEQ;
return (size_t)-1;
}
if (status != B_OK) {
errno = EINVAL;
return (size_t)-1;
}
return lengthUsed;
}
extern "C"
B_DEFINE_WEAK_ALIAS(__wcrtomb, wcrtomb);

View File

@ -1,13 +1,13 @@
/*
* Copyright 2010, Oliver Tappe, zooey@hirschkaefer.de
* Copyright 2010-2011, Oliver Tappe, zooey@hirschkaefer.de
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <wchar.h>
#include <wchar_private.h>
int
wcswidth(const wchar_t* wcstring, size_t n)
__wcswidth(const wchar_t* wcstring, size_t n)
{
int width = 0;
@ -21,3 +21,6 @@ wcswidth(const wchar_t* wcstring, size_t n)
return width;
}
B_DEFINE_WEAK_ALIAS(__wcswidth, wcswidth);

View File

@ -0,0 +1,24 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <stdint.h>
#include <wchar_private.h>
int
__wctob(wint_t c)
{
char internalBuffer[MB_LEN_MAX];
int32_t byteCount = wcrtomb(internalBuffer, c, NULL);
if (byteCount != 1)
return EOF;
return (int)(unsigned char)internalBuffer[0];
}
B_DEFINE_WEAK_ALIAS(__wctob, wctob);

View File

@ -0,0 +1,18 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__wctomb(char* s, wchar_t wc)
{
static mbstate_t internalMbState;
return wcrtomb(s, wc, &internalMbState);
}
B_DEFINE_WEAK_ALIAS(__wctomb, wctomb);