Add our own implementations for all wchar.h functions.

* add implementation for wcpcpy(), wcpncpy(), wcscasecmp(), wcscat(),
  wcschr(), wcscmp(), wcscpy(), wcscspn(), wcsdup(), wcslcat(),
  wcslcpy(), wcslen(), wcsncasecmp(), wcsncat(), wcsncmp(), wcsncpy(),
  wcsnlen(), wcspbrk(), wcsrchr(), wcsspn(), wcsstr(), wcstok(),
  wmemchr(), wmemcmp(), wmemcpy(), wmemmove(), wmemset
* add implementations for GNU-extensions used by our glibc and some
  other programs/libs: wcschrnul(), wmempcpy()
* add stub for wcsftime()
This commit is contained in:
Oliver Tappe 2012-01-07 22:01:40 +01:00
parent d8ef8ef48b
commit 7efc2e3a0e
30 changed files with 750 additions and 0 deletions

View File

@ -0,0 +1,20 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcpcpy(wchar_t* dest, const wchar_t* src)
{
while (*src != L'\0')
*dest++ = *src++;
*dest = L'\0';
return dest;
}
B_DEFINE_WEAK_ALIAS(__wcpcpy, wcpcpy);

View File

@ -0,0 +1,27 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcpncpy(wchar_t* dest, const wchar_t* src, size_t n)
{
const wchar_t* srcEnd = src + n;
wchar_t* destEnd = dest + n;
while (src < srcEnd && *src != L'\0')
*dest++ = *src++;
if (dest < destEnd) {
while (--destEnd >= dest)
*destEnd = L'\0';
}
return dest;
}
B_DEFINE_WEAK_ALIAS(__wcpncpy, wcpncpy);

View File

@ -0,0 +1,29 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wctype.h>
#include <wchar_private.h>
int
__wcscasecmp(const wchar_t* wcs1, const wchar_t* wcs2)
{
int cmp;
for (;;) {
cmp = towlower(*wcs1) - towlower(*wcs2++);
/* note: won't overflow, since our wchar_t is guaranteed to never
have the highest bit set */
if (cmp != 0 || *wcs1++ == L'\0')
break;
}
return cmp;
}
B_DEFINE_WEAK_ALIAS(__wcscasecmp, wcscasecmp);

View File

@ -0,0 +1,23 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcscat(wchar_t* destIn, const wchar_t* src)
{
wchar_t* dest = destIn;
while (*dest != L'\0')
dest++;
while ((*dest++ = *src++) != L'\0')
;
return destIn;
}
B_DEFINE_WEAK_ALIAS(__wcscat, wcscat);

View File

@ -0,0 +1,23 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcschr(const wchar_t* wcs, wchar_t wc)
{
while (1) {
if (*wcs == wc)
return (wchar_t*)wcs;
if (*wcs++ == L'\0')
break;
}
return NULL;
}
B_DEFINE_WEAK_ALIAS(__wcschr, wcschr);

View File

@ -0,0 +1,19 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcschrnul(const wchar_t* wcs, wchar_t wc)
{
while (*wcs != L'\0' && *wcs != wc)
wcs++;
return (wchar_t*)wcs;
}
B_DEFINE_WEAK_ALIAS(__wcschrnul, wcschrnul);

View File

@ -0,0 +1,27 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__wcscmp(const wchar_t* wcs1, const wchar_t* wcs2)
{
int cmp;
for (;;) {
cmp = *wcs1 - *wcs2++;
/* note: won't overflow, since our wchar_t is guaranteed to never
have the highest bit set */
if (cmp != 0 || *wcs1++ == L'\0')
break;
}
return cmp;
}
B_DEFINE_WEAK_ALIAS(__wcscmp, wcscmp);

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>
wchar_t*
__wcscpy(wchar_t* destIn, const wchar_t* src)
{
wchar_t* dest = destIn;
while ((*dest++ = *src++) != L'\0')
;
return destIn;
}
B_DEFINE_WEAK_ALIAS(__wcscpy, wcscpy);

View File

@ -0,0 +1,25 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
size_t
__wcscspn(const wchar_t* wcs, const wchar_t* rejectIn)
{
const wchar_t* wcPointer = wcs;
wchar_t wc;
for (; (wc = *wcPointer) != L'\0'; ++wcPointer) {
const wchar_t* reject;
for (reject = rejectIn; *reject != L'\0'; ++reject) {
if (*reject == wc)
return wcPointer - wcs;
}
}
return wcPointer - wcs;
}
B_DEFINE_WEAK_ALIAS(__wcscspn, wcscspn);

View File

@ -0,0 +1,34 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <stdlib.h>
#include <string.h>
#include <errno_private.h>
#include <wchar_private.h>
wchar_t*
__wcsdup(const wchar_t* wcs)
{
if (wcs == NULL)
return NULL;
{
size_t bufferSize = (wcslen(wcs) + 1) * sizeof(wchar_t);
wchar_t* dest = malloc(bufferSize);
if (dest == NULL) {
__set_errno(ENOMEM);
return NULL;
}
memcpy(dest, wcs, bufferSize);
return dest;
}
}
B_DEFINE_WEAK_ALIAS(__wcsdup, wcsdup);

View File

@ -0,0 +1,20 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
extern "C" size_t
__wcsftime(wchar_t* wcs, size_t wcsSize, const wchar_t* format,
const struct tm* time)
{
#error "not implemented";
return cmp;
}
extern "C"
B_DEFINE_WEAK_ALIAS(__wcsftime, wcsftime);

View File

@ -0,0 +1,41 @@
/*
** Copyright 2002, Manuel J. Petit.
** Copyright 2011, Oliver Tappe <zooey@hirschkafer.de>.
** All rights reserved. Distributed under the terms of the NewOS License.
*/
#include <wchar_private.h>
/** Concatenates the source string to the destination, writes
* as much as "maxLength" bytes to the dest string.
* Always null terminates the string as long as maxLength is
* larger than the dest string.
* Returns the length of the string that it tried to create
* to be able to easily detect string truncation.
*/
size_t
__wcslcat(wchar_t* dest, const wchar_t* source, size_t maxLength)
{
size_t destLength = __wcsnlen(dest, maxLength);
size_t i;
if (destLength == maxLength) {
// the destination is already full
return destLength + __wcslen(source);
}
dest += destLength;
maxLength -= destLength;
for (i = 0; i < maxLength - 1 && *source != L'\0'; ++i)
*dest++ = *source++;
*dest = '\0';
return destLength + i + __wcslen(source);
}
B_DEFINE_WEAK_ALIAS(__wcslcat, wcslcat);

View File

@ -0,0 +1,27 @@
/*
** Copyright 2002, Manuel J. Petit.
** Copyright 2011, Oliver Tappe <zooey@hirschkafer.de>.
** All rights reserved. Distributed under the terms of the NewOS License.
*/
#include <wchar_private.h>
size_t
__wcslcpy(wchar_t* dest, const wchar_t* source, size_t maxLength)
{
size_t i;
if (maxLength == 0)
return __wcslen(source);
for (i = 0; i < maxLength - 1 && *source != L'\0'; ++i)
*dest++ = *source++;
*dest++ = 0;
return i + __wcslen(source);
}
B_DEFINE_WEAK_ALIAS(__wcslcpy, wcslcpy);

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
__wcslen(const wchar_t* wcs)
{
size_t length = 0;
while (*wcs++ != L'\0')
length++;
return length;
}
B_DEFINE_WEAK_ALIAS(__wcslen, wcslen);

View File

@ -0,0 +1,29 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wctype.h>
#include <wchar_private.h>
int
__wcsncasecmp(const wchar_t* wcs1, const wchar_t* wcs2, size_t count)
{
int cmp = 0;
while (count-- > 0) {
cmp = towlower(*wcs1) - towlower(*wcs2++);
/* note: won't overflow, since our wchar_t is guaranteed to never
have the highest bit set */
if (cmp != 0 || *wcs1++ == L'\0')
break;
}
return cmp;
}
B_DEFINE_WEAK_ALIAS(__wcsncasecmp, wcsncasecmp);

View File

@ -0,0 +1,25 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcsncat(wchar_t* destIn, const wchar_t* src, size_t n)
{
wchar_t* dest = destIn;
const wchar_t* srcEnd = src + n;
while (*dest != L'\0')
dest++;
while (src < srcEnd && *src != L'\0')
*dest++ = *src++;
*dest = L'\0';
return destIn;
}
B_DEFINE_WEAK_ALIAS(__wcsncat, wcsncat);

View File

@ -0,0 +1,27 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__wcsncmp(const wchar_t* wcs1, const wchar_t* wcs2, size_t count)
{
int cmp = 0;
while (count-- > 0) {
cmp = *wcs1 - *wcs2++;
/* note: won't overflow, since our wchar_t is guaranteed to never
have the highest bit set */
if (cmp != 0 || *wcs1++ == L'\0')
break;
}
return cmp;
}
B_DEFINE_WEAK_ALIAS(__wcsncmp, wcsncmp);

View File

@ -0,0 +1,25 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcsncpy(wchar_t* destIn, const wchar_t* src, size_t n)
{
wchar_t* dest = destIn;
const wchar_t* srcEnd = src + n;
const wchar_t* destEnd = dest + n;
while (src < srcEnd && *src != L'\0')
*dest++ = *src++;
while (dest < destEnd)
*dest++ = L'\0';
return destIn;
}
B_DEFINE_WEAK_ALIAS(__wcsncpy, wcsncpy);

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
__wcsnlen(const wchar_t* wcs, size_t maxLength)
{
size_t length = 0;
while (length < maxLength && *wcs++ != L'\0')
length++;
return length;
}
B_DEFINE_WEAK_ALIAS(__wcsnlen, wcsnlen);

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 <wchar_private.h>
wchar_t*
__wcspbrk(const wchar_t* wcs, const wchar_t* acceptIn)
{
for (; *wcs != L'\0'; ++wcs) {
const wchar_t* accept = acceptIn;
for (; *accept != L'\0'; ++accept) {
if (*accept == *wcs)
return (wchar_t*)wcs;
}
}
return NULL;
}
B_DEFINE_WEAK_ALIAS(__wcspbrk, wcspbrk);

View File

@ -0,0 +1,22 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcsrchr(const wchar_t* wcsIn, wchar_t wc)
{
const wchar_t* wcs = wcsIn + wcslen(wcsIn);
for (; wcs >= wcsIn; --wcs) {
if (*wcs == wc)
return (wchar_t*)wcs;
}
return NULL;
}
B_DEFINE_WEAK_ALIAS(__wcsrchr, wcsrchr);

View File

@ -0,0 +1,28 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
size_t
__wcsspn(const wchar_t* wcs, const wchar_t* acceptIn)
{
const wchar_t* wcPointer = wcs;
wchar_t wc;
for (; (wc = *wcPointer) != L'\0'; ++wcPointer) {
const wchar_t* accept;
for (accept = acceptIn; *accept != L'\0'; ++accept) {
if (*accept == wc)
break;
}
if (*accept == L'\0')
break;
}
return wcPointer - wcs;
}
B_DEFINE_WEAK_ALIAS(__wcsspn, wcsspn);

View File

@ -0,0 +1,29 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wcsstr(const wchar_t* haystack, const wchar_t* needleIn)
{
if (*needleIn == L'\0')
return (wchar_t*)haystack;
for (; *haystack != L'\0'; ++haystack) {
const wchar_t* needle = needleIn;
const wchar_t* haystackPointer = haystack;
while (*needle == *haystackPointer++ && *needle != 0)
++needle;
if (*needle == L'\0')
return (wchar_t*)haystack;
}
return NULL;
}
B_DEFINE_WEAK_ALIAS(__wcsstr, wcsstr);
B_DEFINE_WEAK_ALIAS(__wcsstr, wcswcs);

View File

@ -0,0 +1,40 @@
/*
** Copyright 2001, Travis Geiselbrecht.
** Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
** All rights reserved. Distributed under the terms of the NewOS License.
*/
#include <wchar_private.h>
wchar_t *
__wcstok(wchar_t* wcs, const wchar_t* delim, wchar_t** savePtr)
{
wchar_t *wcsBegin, *wcsEnd;
if (wcs == NULL && savePtr == NULL)
return NULL;
wcsBegin = wcs ? wcs : *savePtr;
if (wcsBegin == NULL)
return NULL;
wcsBegin += wcsspn(wcsBegin, delim);
if (*wcsBegin == '\0') {
if (savePtr)
*savePtr = NULL;
return NULL;
}
wcsEnd = wcspbrk(wcsBegin, delim);
if (wcsEnd && *wcsEnd != '\0')
*wcsEnd++ = '\0';
if (savePtr)
*savePtr = wcsEnd;
return wcsBegin;
}
B_DEFINE_WEAK_ALIAS(__wcstok, wcstok);

View File

@ -0,0 +1,22 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wmemchr(const wchar_t* dest, const wchar_t wc, size_t count)
{
while (count-- > 0) {
if (*dest == wc)
return (wchar_t*)dest;
++dest;
}
return NULL;
}
B_DEFINE_WEAK_ALIAS(__wmemchr, wmemchr);

View File

@ -0,0 +1,25 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
int
__wmemcmp(const wchar_t* wcs1, const wchar_t* wcs2, size_t count)
{
while (count-- > 0) {
const wchar_t wc1 = *wcs1++;
const wchar_t wc2 = *wcs2++;
if (wc1 > wc2)
return 1;
else if (wc2 > wc1)
return -1;
}
return 0;
}
B_DEFINE_WEAK_ALIAS(__wmemcmp, wmemcmp);

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 <string.h>
#include <wchar_private.h>
wchar_t*
__wmemcpy(wchar_t* dest, const wchar_t* src, size_t count)
{
return memcpy(dest, src, count * sizeof(wchar_t));
}
B_DEFINE_WEAK_ALIAS(__wmemcpy, wmemcpy);

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 <string.h>
#include <wchar_private.h>
wchar_t*
__wmemmove(wchar_t* dest, const wchar_t* src, size_t count)
{
return memmove(dest, src, count * sizeof(wchar_t));
}
B_DEFINE_WEAK_ALIAS(__wmemmove, wmemmove);

View File

@ -0,0 +1,20 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <string.h>
#include <wchar_private.h>
wchar_t*
__wmempcpy(wchar_t* dest, const wchar_t* src, size_t count)
{
memcpy(dest, src, count * sizeof(wchar_t));
return dest + count;
}
B_DEFINE_WEAK_ALIAS(__wmempcpy, wmempcpy);

View File

@ -0,0 +1,20 @@
/*
** Copyright 2011, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the Haiku License.
*/
#include <wchar_private.h>
wchar_t*
__wmemset(wchar_t* destIn, const wchar_t wc, size_t count)
{
wchar_t* dest = destIn;
while (count-- > 0)
*dest++ = wc;
return destIn;
}
B_DEFINE_WEAK_ALIAS(__wmemset, wmemset);