]> pd.if.org Git - pdclib/commitdiff
PDCLIB-2: Pure wide character functions
authorOwen Shepherd <owen.shepherd@e43.eu>
Tue, 11 Sep 2012 21:48:43 +0000 (22:48 +0100)
committerOwen Shepherd <owen.shepherd@e43.eu>
Tue, 11 Sep 2012 21:48:43 +0000 (22:48 +0100)
 * 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

18 files changed:
functions/wchar/wcscat.c [new file with mode: 0644]
functions/wchar/wcscmp.c [new file with mode: 0644]
functions/wchar/wcscspn.c [new file with mode: 0644]
functions/wchar/wcsncat.c [new file with mode: 0644]
functions/wchar/wcsncmp.c [new file with mode: 0644]
functions/wchar/wcsncpy.c [new file with mode: 0644]
functions/wchar/wcspbrk.c [new file with mode: 0644]
functions/wchar/wcsspn.c [new file with mode: 0644]
functions/wchar/wcsstr.c [new file with mode: 0644]
functions/wchar/wcstok.c [new file with mode: 0644]
functions/wchar/wmemchr.c [new file with mode: 0644]
functions/wchar/wmemcmp.c [new file with mode: 0644]
functions/wchar/wmemcpy.c [new file with mode: 0644]
functions/wchar/wmemmove.c [new file with mode: 0644]
opt/mincoll/wcscoll.c [new file with mode: 0644]
opt/mincoll/wcsxfrm.c [new file with mode: 0644]
platform/win32/Config.jam
testing/_PDCLIB_test.h

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