From 14b5b78e19a79f590233caee7848e7cb19084088 Mon Sep 17 00:00:00 2001 From: Owen Shepherd Date: Tue, 11 Sep 2012 22:48:43 +0100 Subject: [PATCH] PDCLIB-2: Pure wide character functions * functions/wchar/: functions which only involve wide characters & no locale dependent characters * opt/mincoll: new option providing bare minimum collation support (pure wchar_t binary comparison) * platform/win32: Use mincoll * testing/_PDCLIB_test.h: Provide wide character strings for testing the wide character functions --- functions/wchar/wcscat.c | 45 +++++++++++++++ functions/wchar/wcscmp.c | 39 +++++++++++++ functions/wchar/wcscspn.c | 48 ++++++++++++++++ functions/wchar/wcsncat.c | 60 ++++++++++++++++++++ functions/wchar/wcsncmp.c | 54 ++++++++++++++++++ functions/wchar/wcsncpy.c | 43 +++++++++++++++ functions/wchar/wcspbrk.c | 47 ++++++++++++++++ functions/wchar/wcsspn.c | 47 ++++++++++++++++ functions/wchar/wcsstr.c | 49 +++++++++++++++++ functions/wchar/wcstok.c | 109 +++++++++++++++++++++++++++++++++++++ functions/wchar/wmemchr.c | 39 +++++++++++++ functions/wchar/wmemcmp.c | 39 +++++++++++++ functions/wchar/wmemcpy.c | 39 +++++++++++++ functions/wchar/wmemmove.c | 49 +++++++++++++++++ opt/mincoll/wcscoll.c | 36 ++++++++++++ opt/mincoll/wcsxfrm.c | 28 ++++++++++ platform/win32/Config.jam | 2 +- testing/_PDCLIB_test.h | 5 ++ 18 files changed, 777 insertions(+), 1 deletion(-) create mode 100644 functions/wchar/wcscat.c create mode 100644 functions/wchar/wcscmp.c create mode 100644 functions/wchar/wcscspn.c create mode 100644 functions/wchar/wcsncat.c create mode 100644 functions/wchar/wcsncmp.c create mode 100644 functions/wchar/wcsncpy.c create mode 100644 functions/wchar/wcspbrk.c create mode 100644 functions/wchar/wcsspn.c create mode 100644 functions/wchar/wcsstr.c create mode 100644 functions/wchar/wcstok.c create mode 100644 functions/wchar/wmemchr.c create mode 100644 functions/wchar/wmemcmp.c create mode 100644 functions/wchar/wmemcpy.c create mode 100644 functions/wchar/wmemmove.c create mode 100644 opt/mincoll/wcscoll.c create mode 100644 opt/mincoll/wcsxfrm.c diff --git a/functions/wchar/wcscat.c b/functions/wchar/wcscat.c new file mode 100644 index 0000000..ad25291 --- /dev/null +++ b/functions/wchar/wcscat.c @@ -0,0 +1,45 @@ +/* wcscat( wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wcscat( wchar_t * _PDCLIB_restrict s1, + const wchar_t * _PDCLIB_restrict s2 ) +{ + wchar_t * rc = s1; + if ( *s1 ) + { + while ( *++s1 ); + } + while ( (*s1++ = *s2++) ); + return rc; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"xx\0xxxxxx"; + TESTCASE( wcscat( s, wabcde ) == s ); + TESTCASE( s[2] == L'a' ); + TESTCASE( s[6] == L'e' ); + TESTCASE( s[7] == L'\0' ); + TESTCASE( s[8] == L'x' ); + s[0] = L'\0'; + TESTCASE( wcscat( s, wabcdx ) == s ); + TESTCASE( s[4] == L'x' ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( wcscat( s, L"\0" ) == s ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( s[6] == L'e' ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcscmp.c b/functions/wchar/wcscmp.c new file mode 100644 index 0000000..810fac2 --- /dev/null +++ b/functions/wchar/wcscmp.c @@ -0,0 +1,39 @@ +/* wcscmp( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int wcscmp( const wchar_t * s1, const wchar_t * s2 ) +{ + while ( ( *s1 ) && ( *s1 == *s2 ) ) + { + ++s1; + ++s2; + } + return ( *(wchar_t *)s1 - *(wchar_t *)s2 ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t cmpabcde[] = L"abcde"; + wchar_t cmpabcd_[] = L"abcd\xfc"; + wchar_t empty[] = L""; + TESTCASE( wcscmp( wabcde, cmpabcde ) == 0 ); + TESTCASE( wcscmp( wabcde, wabcdx ) < 0 ); + TESTCASE( wcscmp( wabcdx, wabcde ) > 0 ); + TESTCASE( wcscmp( empty, wabcde ) < 0 ); + TESTCASE( wcscmp( wabcde, empty ) > 0 ); + TESTCASE( wcscmp( wabcde, cmpabcd_ ) < 0 ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcscspn.c b/functions/wchar/wcscspn.c new file mode 100644 index 0000000..1f311c6 --- /dev/null +++ b/functions/wchar/wcscspn.c @@ -0,0 +1,48 @@ +/* wcscspn( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +size_t wcscspn( const wchar_t * s1, const wchar_t * s2 ) +{ + size_t len = 0; + const wchar_t * p; + while ( s1[len] ) + { + p = s2; + while ( *p ) + { + if ( s1[len] == *p++ ) + { + return len; + } + } + ++len; + } + return len; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( wcscspn( wabcde, L"x" ) == 5 ); + TESTCASE( wcscspn( wabcde, L"xyz" ) == 5 ); + TESTCASE( wcscspn( wabcde, L"zyx" ) == 5 ); + TESTCASE( wcscspn( wabcdx, L"x" ) == 4 ); + TESTCASE( wcscspn( wabcdx, L"xyz" ) == 4 ); + TESTCASE( wcscspn( wabcdx, L"zyx" ) == 4 ); + TESTCASE( wcscspn( wabcde, L"a" ) == 0 ); + TESTCASE( wcscspn( wabcde, L"abc" ) == 0 ); + TESTCASE( wcscspn( wabcde, L"cba" ) == 0 ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcsncat.c b/functions/wchar/wcsncat.c new file mode 100644 index 0000000..b0c976c --- /dev/null +++ b/functions/wchar/wcsncat.c @@ -0,0 +1,60 @@ +/* wcsncat( wchar_t *, const wchar_t *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wcsncat( wchar_t * _PDCLIB_restrict s1, + const wchar_t * _PDCLIB_restrict s2, + size_t n ) +{ + wchar_t * rc = s1; + while ( *s1 ) + { + ++s1; + } + while ( n && ( *s1++ = *s2++ ) ) + { + --n; + } + if ( n == 0 ) + { + *s1 = '\0'; + } + return rc; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"xx\0xxxxxx"; + TESTCASE( wcsncat( s, wabcde, 10 ) == s ); + TESTCASE( s[2] == L'a' ); + TESTCASE( s[6] == L'e' ); + TESTCASE( s[7] == L'\0' ); + TESTCASE( s[8] == L'x' ); + s[0] = L'\0'; + TESTCASE( wcsncat( s, wabcdx, 10 ) == s ); + TESTCASE( s[4] == L'x' ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( wcsncat( s, "\0", 10 ) == s ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( s[6] == L'e' ); + TESTCASE( wcsncat( s, wabcde, 0 ) == s ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( s[6] == L'e' ); + TESTCASE( wcsncat( s, wabcde, 3 ) == s ); + TESTCASE( s[5] == L'a' ); + TESTCASE( s[7] == L'c' ); + TESTCASE( s[8] == L'\0' ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcsncmp.c b/functions/wchar/wcsncmp.c new file mode 100644 index 0000000..920d647 --- /dev/null +++ b/functions/wchar/wcsncmp.c @@ -0,0 +1,54 @@ +/* $Id$ */ + +/* wcsncmp( const wchar_t *, const wchar_t *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int wcsncmp( const wchar_t * s1, const wchar_t * s2, size_t n ) +{ + while ( *s1 && n && ( *s1 == *s2 ) ) + { + ++s1; + ++s2; + --n; + } + if ( ( n == 0 ) ) + { + return 0; + } + else + { + return ( *(wchar_t *)s1 - *(wchar_t *)s2 ); + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t cmpabcde[] = L"abcde\0f"; + wchar_t cmpabcd_[] = L"abcde\xfc"; + wchar_t empty[] = L""; + wchar_t x[] = L"x"; + TESTCASE( wcsncmp( wabcde, cmpabcde, 5 ) == 0 ); + TESTCASE( wcsncmp( wabcde, cmpabcde, 10 ) == 0 ); + TESTCASE( wcsncmp( wabcde, wabcdx, 5 ) < 0 ); + TESTCASE( wcsncmp( wabcdx, wabcde, 5 ) > 0 ); + TESTCASE( wcsncmp( empty, wabcde, 5 ) < 0 ); + TESTCASE( wcsncmp( wabcde, empty, 5 ) > 0 ); + TESTCASE( wcsncmp( wabcde, wabcdx, 4 ) == 0 ); + TESTCASE( wcsncmp( wabcde, x, 0 ) == 0 ); + TESTCASE( wcsncmp( wabcde, x, 1 ) < 0 ); + TESTCASE( wcsncmp( wabcde, cmpabcd_, 10 ) < 0 ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcsncpy.c b/functions/wchar/wcsncpy.c new file mode 100644 index 0000000..6d0e4d2 --- /dev/null +++ b/functions/wchar/wcsncpy.c @@ -0,0 +1,43 @@ +/* wchar_t * wcsncpy( wchar_t restrict *, const wchar_t restrict * , size_t ); + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t *wcsncpy( wchar_t * _PDCLIB_restrict s1, + const wchar_t * _PDCLIB_restrict s2, + size_t n ) +{ + wchar_t * rc = s1; + while ( ( n > 0 ) && ( *s1++ = *s2++ ) ) + { + /* Cannot do "n--" in the conditional as size_t is unsigned and we have + to check it again for >0 in the next loop below, so we must not risk + underflow. + */ + --n; + } + /* Checking against 1 as we missed the last --n in the loop above. */ + while ( n-- > 1 ) + { + *s1++ = '\0'; + } + return rc; +} + + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + return TEST_RESULTS; +} + +#endif diff --git a/functions/wchar/wcspbrk.c b/functions/wchar/wcspbrk.c new file mode 100644 index 0000000..73bf721 --- /dev/null +++ b/functions/wchar/wcspbrk.c @@ -0,0 +1,47 @@ +/* wcspbrk( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wcspbrk( const wchar_t * s1, const wchar_t * s2 ) +{ + const wchar_t * p1 = s1; + const wchar_t * p2; + while ( *p1 ) + { + p2 = s2; + while ( *p2 ) + { + if ( *p1 == *p2++ ) + { + return (wchar_t *) p1; + } + } + ++p1; + } + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( wcspbrk( wabcde, L"x" ) == NULL ); + TESTCASE( wcspbrk( wabcde, L"xyz" ) == NULL ); + TESTCASE( wcspbrk( wabcdx, L"x" ) == &wabcdx[4] ); + TESTCASE( wcspbrk( wabcdx, L"xyz" ) == &wabcdx[4] ); + TESTCASE( wcspbrk( wabcdx, L"zyx" ) == &wabcdx[4] ); + TESTCASE( wcspbrk( wabcde, L"a" ) == &wabcde[0] ); + TESTCASE( wcspbrk( wabcde, L"abc" ) == &wabcde[0] ); + TESTCASE( wcspbrk( wabcde, L"cba" ) == &wabcde[0] ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcsspn.c b/functions/wchar/wcsspn.c new file mode 100644 index 0000000..34446bd --- /dev/null +++ b/functions/wchar/wcsspn.c @@ -0,0 +1,47 @@ +/* wcsspn( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +size_t wcsspn( const wchar_t * s1, const wchar_t * s2 ) +{ + size_t len = 0; + const wchar_t * p; + while ( s1[ len ] ) + { + p = s2; + while ( *p ) + { + if ( s1[len] == *p ) + { + break; + } + ++p; + } + if ( ! *p ) + { + return len; + } + ++len; + } + return len; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( wcsspn( wabcde, L"abc" ) == 3 ); + TESTCASE( wcsspn( wabcde, L"b" ) == 0 ); + TESTCASE( wcsspn( wabcde, wabcde ) == 5 ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcsstr.c b/functions/wchar/wcsstr.c new file mode 100644 index 0000000..a2162f8 --- /dev/null +++ b/functions/wchar/wcsstr.c @@ -0,0 +1,49 @@ +/* wcsstr( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wcsstr( const wchar_t * s1, const wchar_t * s2 ) +{ + const wchar_t * p1 = s1; + const wchar_t * p2; + while ( *s1 ) + { + p2 = s2; + while ( *p2 && ( *p1 == *p2 ) ) + { + ++p1; + ++p2; + } + if ( ! *p2 ) + { + return (wchar_t *) s1; + } + ++s1; + p1 = s1; + } + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"abcabcabcdabcde"; + TESTCASE( wcsstr( s, L"x" ) == NULL ); + TESTCASE( wcsstr( s, L"xyz" ) == NULL ); + TESTCASE( wcsstr( s, L"a" ) == &s[0] ); + TESTCASE( wcsstr( s, L"abc" ) == &s[0] ); + TESTCASE( wcsstr( s, L"abcd" ) == &s[6] ); + TESTCASE( wcsstr( s, L"abcde" ) == &s[10] ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wcstok.c b/functions/wchar/wcstok.c new file mode 100644 index 0000000..62f8dd8 --- /dev/null +++ b/functions/wchar/wcstok.c @@ -0,0 +1,109 @@ +/* wcstok( wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wcstok( wchar_t * _PDCLIB_restrict s1, + const wchar_t * _PDCLIB_restrict s2, + wchar_t ** _PDCLIB_restrict ptr ) +{ + const wchar_t * p = s2; + + if ( s1 != NULL ) + { + /* new string */ + *ptr = s1; + } + else + { + /* old string continued */ + if ( *ptr == NULL ) + { + /* No old string, no new string, nothing to do */ + return NULL; + } + s1 = *ptr; + } + + /* skipping leading s2 characters */ + while ( *p && *s1 ) + { + if ( *s1 == *p ) + { + /* found seperator; skip and start over */ + ++s1; + p = s2; + continue; + } + ++p; + } + + if ( ! *s1 ) + { + /* no more to parse */ + return ( *ptr = NULL ); + } + + /* skipping non-s2 characters */ + *ptr = s1; + while ( **ptr ) + { + p = s2; + while ( *p ) + { + if ( **ptr == *p++ ) + { + /* found seperator; overwrite with '\0', position *ptr, return */ + *(*ptr)++ = L'\0'; + return s1; + } + } + ++(*ptr); + } + + /* parsed to end of string */ + *ptr = NULL; + return s1; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"_a_bc__d_"; + wchar_t* state = NULL; + wchar_t* tokres; + + TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[1] ); + TESTCASE( s[1] == L'a' ); + TESTCASE( s[2] == L'\0' ); + TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] ); + TESTCASE( s[3] == L'b' ); + TESTCASE( s[4] == L'c' ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[7] ); + TESTCASE( s[6] == L'_' ); + TESTCASE( s[7] == L'd' ); + TESTCASE( s[8] == L'\0' ); + TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL ); + wcscpy( s, L"ab_cd" ); + TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[0] ); + TESTCASE( s[0] == L'a' ); + TESTCASE( s[1] == L'b' ); + TESTCASE( s[2] == L'\0' ); + TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] ); + TESTCASE( s[3] == L'c' ); + TESTCASE( s[4] == L'd' ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wmemchr.c b/functions/wchar/wmemchr.c new file mode 100644 index 0000000..181da15 --- /dev/null +++ b/functions/wchar/wmemchr.c @@ -0,0 +1,39 @@ +/* wmemchr( const void *, int, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wmemchr( const wchar_t * p, wchar_t c, size_t n ) +{ + while ( n-- ) + { + if ( *p == c ) + { + return (wchar_t*) p; + } + ++p; + } + return NULL; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( wmemchr( wabcde, L'c', 5 ) == &wabcde[2] ); + TESTCASE( wmemchr( wabcde, L'a', 1 ) == &wabcde[0] ); + TESTCASE( wmemchr( wabcde, L'a', 0 ) == NULL ); + TESTCASE( wmemchr( wabcde, L'\0', 5 ) == NULL ); + TESTCASE( wmemchr( wabcde, L'\0', 6 ) == &wabcde[5] ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/wchar/wmemcmp.c b/functions/wchar/wmemcmp.c new file mode 100644 index 0000000..2d58914 --- /dev/null +++ b/functions/wchar/wmemcmp.c @@ -0,0 +1,39 @@ +/* wmemcmp( const wchar_t *, const wchar_t *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +int wmemcmp( const wchar_t * p1, const wchar_t * p2, size_t n ) +{ + while ( n-- ) + { + if ( *p1 != *p2 ) + { + return *p1 - *p2; + } + ++p1; + ++p2; + } + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t const xxxxx[] = L"xxxxx"; + TESTCASE( wmemcmp( wabcde, wabcdx, 5 ) < 0 ); + TESTCASE( wmemcmp( wabcde, wabcdx, 4 ) == 0 ); + TESTCASE( wmemcmp( wabcde, xxxxx, 0 ) == 0 ); + TESTCASE( wmemcmp( xxxxx, wabcde, 1 ) > 0 ); + return 0; +} +#endif diff --git a/functions/wchar/wmemcpy.c b/functions/wchar/wmemcpy.c new file mode 100644 index 0000000..e864dbc --- /dev/null +++ b/functions/wchar/wmemcpy.c @@ -0,0 +1,39 @@ +/* wmemcpy( wchar_t *, const wchar_t *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wmemcpy( wchar_t * _PDCLIB_restrict dest, + const wchar_t * _PDCLIB_restrict src, + size_t n ) +{ + wchar_t* rv = dest; + while ( n-- ) + { + *dest++ = *src++; + } + return rv; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"xxxxxxxxxxx"; + TESTCASE( wmemcpy( s, wabcde, 6 ) == s ); + TESTCASE( s[4] == L'e' ); + TESTCASE( s[5] == L'\0' ); + TESTCASE( wmemcpy( s + 5, wabcde, 5 ) == s + 5 ); + TESTCASE( s[9] == L'e' ); + TESTCASE( s[10] == L'x' ); + return TEST_RESULTS; +} +#endif diff --git a/functions/wchar/wmemmove.c b/functions/wchar/wmemmove.c new file mode 100644 index 0000000..e8d6075 --- /dev/null +++ b/functions/wchar/wmemmove.c @@ -0,0 +1,49 @@ +/* wmemmove( wchar_t *, const wchar_t *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +wchar_t * wmemmove( wchar_t * dest, const wchar_t * src, size_t n ) +{ + wchar_t* rv = dest; + if ( dest <= src ) + { + while ( n-- ) + { + *dest++ = *src++; + } + } + else + { + src += n; + dest += n; + while ( n-- ) + { + *--dest = *--src; + } + } + return rv; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + wchar_t s[] = L"xxxxabcde"; + TESTCASE( wmemmove( s, s + 4, 5 ) == s ); + TESTCASE( s[0] == L'a' ); + TESTCASE( s[4] == L'e' ); + TESTCASE( s[5] == L'b' ); + TESTCASE( wmemmove( s + 4, s, 5 ) == s + 4 ); + TESTCASE( s[4] == L'a' ); + return TEST_RESULTS; +} +#endif diff --git a/opt/mincoll/wcscoll.c b/opt/mincoll/wcscoll.c new file mode 100644 index 0000000..acdf640 --- /dev/null +++ b/opt/mincoll/wcscoll.c @@ -0,0 +1,36 @@ +/* wcscoll( const wchar_t *, const wchar_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +/* I did much searching as to how various people implement this. + * + * OpenBSD, NetBSD and Musl libc for Linux implement this as a call to wcscmp + * and have various "todo" notices on this function, and on the other hand + * glibc implements it as a 500 line function. FreeBSD has an implementation + * which kind of uses their single byte character strcoll data for the first + * 256 characters, but looks incredibly fragile and likely to break. + * + * TL;DR: Nobody uses this, and this will probably work perfectly fine for you. + */ + +int wcscoll( const wchar_t * s1, const wchar_t * s2 ) +{ + return wcscmp(s1, s2); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + return TEST_RESULTS; +} +#endif diff --git a/opt/mincoll/wcsxfrm.c b/opt/mincoll/wcsxfrm.c new file mode 100644 index 0000000..7430567 --- /dev/null +++ b/opt/mincoll/wcsxfrm.c @@ -0,0 +1,28 @@ +/* wcsxfrm( char *, const char *, size_t ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +/* See notes on wcscoll. */ +size_t wcsxfrm( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n ) +{ + wcsncpy(s1, s2, n); + return wcslen(s2); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + return TEST_RESULTS; +} +#endif + diff --git a/platform/win32/Config.jam b/platform/win32/Config.jam index 538f72b..a078d6f 100644 --- a/platform/win32/Config.jam +++ b/platform/win32/Config.jam @@ -23,6 +23,6 @@ if $(PDCLIB_TOOLCHAIN) = "gcc" { EXIT ; } -PDCLIB_OPTIONS = notime dlmalloc ; +PDCLIB_OPTIONS = notime dlmalloc mincoll ; CRT0 = [ FDirName platform win32 crt0$(SUFOBJ) ] ; \ No newline at end of file diff --git a/testing/_PDCLIB_test.h b/testing/_PDCLIB_test.h index e6d8c36..f380e61 100644 --- a/testing/_PDCLIB_test.h +++ b/testing/_PDCLIB_test.h @@ -14,12 +14,17 @@ #include #include #include +#include /* Some strings used for and testing. */ static char const abcde[] = "abcde"; static char const abcdx[] = "abcdx"; static char const teststring[] = "1234567890\nABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n"; +static wchar_t const wabcde[] = L"abcde"; +static wchar_t const wabcdx[] = L"abcdx"; +static wchar_t const wteststring[] = L"1234567890\nABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz\n"; + /* Temporary file names */ static char const testfile[]="testing/testfile"; static char const testfile1[]="testing/testfile1"; -- 2.40.0