diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index 78175e88ea43..97a8395f6956 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -3202,6 +3202,7 @@ ./usr/include/ttyent.h comp-c-include ./usr/include/tzfile.h comp-c-include ./usr/include/ucontext.h comp-c-include +./usr/include/uchar.h comp-c-include ./usr/include/ufs/ext2fs/ext2fs.h comp-c-include ./usr/include/ufs/ext2fs/ext2fs_dinode.h comp-c-include ./usr/include/ufs/ext2fs/ext2fs_dir.h comp-c-include diff --git a/include/Makefile b/include/Makefile index 184661ed9476..4c4c076b7f3f 100644 --- a/include/Makefile +++ b/include/Makefile @@ -20,7 +20,7 @@ INCS= a.out.h aio.h ar.h assert.h atomic.h \ resolv.h res_update.h rmt.h sched.h search.h semaphore.h setjmp.h \ string.h sgtty.h signal.h spawn.h stab.h stdalign.h stddef.h stdio.h \ stdlib.h stdnoreturn.h strings.h stringlist.h struct.h sysexits.h \ - tar.h time.h ttyent.h tzfile.h \ + tar.h time.h ttyent.h tzfile.h uchar.h \ ucontext.h ulimit.h unistd.h util.h utime.h utmp.h utmpx.h uuid.h \ vis.h wchar.h wctype.h wordexp.h INCS+= arpa/ftp.h arpa/inet.h arpa/nameser.h arpa/nameser_compat.h \ diff --git a/include/uchar.h b/include/uchar.h new file mode 100644 index 000000000000..5e00f6a56ba3 --- /dev/null +++ b/include/uchar.h @@ -0,0 +1,59 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _UCHAR_H +#define _UCHAR_H +#include +#include +#include + +#if (__cplusplus - 0) < 201103L +typedef uint16_t char16_t; +typedef uint32_t char32_t; +#endif + +#ifdef _BSD_SIZE_T_ +typedef _BSD_SIZE_T_ size_t; +#undef _BSD_SIZE_T_ +#endif + +typedef __mbstate_t mbstate_t; + +__BEGIN_DECLS +size_t c16rtomb(char *__restrict, char16_t, mbstate_t *__restrict); +size_t mbrtoc16(char16_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict); + +size_t c32rtomb(char *__restrict, char32_t, mbstate_t *__restrict); +size_t mbrtoc32(char32_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict); +__END_DECLS + +#endif diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 907f5acf10e0..8dd39454cfdf 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -90,6 +90,7 @@ CPPFLAGS+= -D__BUILD_LEGACY .include "${.CURDIR}/termios/Makefile.inc" .include "${.CURDIR}/thread-stub/Makefile.inc" .include "${.CURDIR}/time/Makefile.inc" +.include "${.CURDIR}/multibyte/Makefile.inc" .if ${RUMPRUN} != "yes" .include "${.CURDIR}/tls/Makefile.inc" .endif diff --git a/lib/libc/multibyte/Makefile.inc b/lib/libc/multibyte/Makefile.inc new file mode 100644 index 000000000000..858fd5e31456 --- /dev/null +++ b/lib/libc/multibyte/Makefile.inc @@ -0,0 +1,11 @@ +# $NetBSD$ + +.PATH: ${ARCHDIR}/multibyte ${.CURDIR}/multibyte + +COPTS.c16rtomb.c+= -g +COPTS.mbrtoc16.c+= -g + +SRCS+= c16rtomb.c +SRCS+= c32rtomb.c +SRCS+= mbrtoc16.c +SRCS+= mbrtoc32.c diff --git a/lib/libc/multibyte/c16rtomb.c b/lib/libc/multibyte/c16rtomb.c new file mode 100644 index 000000000000..54a0840521f5 --- /dev/null +++ b/lib/libc/multibyte/c16rtomb.c @@ -0,0 +1,63 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +size_t +c16rtomb(char * __restrict s, char16_t c16, mbstate_t * __restrict ps){ + char32_t c32; + + /* If s is a null pointer, the value of parameter c16 is ignored. */ + if (s == NULL) { + c32 = 0; + } else if (ps->__mbstateL >= 0xd800 && + ps->__mbstateL <= 0xdbff) { + /* We should see a trail surrogate now. */ + if (c16 < 0xdc00 || c16 > 0xdfff) { + errno = EILSEQ; + return ((size_t)-1); + } + c32 = 0x10000 + ((ps->__mbstateL & 0x3ff) << 10 | + (c16 & 0x3ff)); + } else if (c16 >= 0xd800 && c16 <= 0xdbff) { + /* Store lead surrogate for next invocation. */ + ps->__mbstateL = c16; + return (0); + } else { + /* Regular character. */ + c32 = c16; + } + + return (c32rtomb(s, c32, ps)); +} diff --git a/lib/libc/multibyte/c32rtomb.c b/lib/libc/multibyte/c32rtomb.c new file mode 100644 index 000000000000..55fb7ad837f8 --- /dev/null +++ b/lib/libc/multibyte/c32rtomb.c @@ -0,0 +1,46 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include + +size_t +c32rtomb(char * __restrict s, char32_t c32, mbstate_t * __restrict ps){ + + /* Unicode Standard 5.0, D90: ill-formed characters. */ + if ((c32 >= 0xd800 && c32 <= 0xdfff) || c32 > 0x10ffff) { + errno = EILSEQ; + return ((size_t)-1); + } + + /* Assume wchar_t uses UTF-32. */ + return (wcrtomb(s, c32, ps)); +} diff --git a/lib/libc/multibyte/mbrtoc16.c b/lib/libc/multibyte/mbrtoc16.c new file mode 100644 index 000000000000..2a8115a09c86 --- /dev/null +++ b/lib/libc/multibyte/mbrtoc16.c @@ -0,0 +1,74 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +#include +#include + +size_t +mbrtoc16(char16_t * __restrict pc16, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + char32_t c32; + size_t len; + /* + * Call straight into mbrtoc32() if we don't need to return a + * character value. According to the spec, if s is a null + * pointer, the value of parameter pc16 is also ignored. + */ + if (pc16 == NULL || s == NULL) { + memset(ps, 0, sizeof(*ps)); + return (mbrtoc32(NULL, s, n, ps)); + } + + /* Return the trail surrogate from the previous invocation. */ + if (ps->__mbstateL >= 0xdc00 && ps->__mbstateL <= 0xdfff) { + *pc16 = ps->__mbstateL; + memset(ps, 0, sizeof(*ps)); + + return ((size_t)-3); + } + + len = mbrtoc32(&c32, s, n, ps); + if(len > 0){ + if (c32 < 0x10000) { + /* Fits in one UTF-16 character. */ + *pc16 = c32; + } else { + /* Split up in a surrogate pair. */ + c32 -= 0x10000; + *pc16 = 0xd800 | (c32 >> 10); + ps->__mbstateL = 0xdc00 | (c32 & 0x3ff); + } + } + return (len); +} diff --git a/lib/libc/multibyte/mbrtoc32.c b/lib/libc/multibyte/mbrtoc32.c new file mode 100644 index 000000000000..2227fd956664 --- /dev/null +++ b/lib/libc/multibyte/mbrtoc32.c @@ -0,0 +1,43 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include + +size_t +mbrtoc32(char32_t * __restrict pc32, const char * __restrict s, size_t n, + mbstate_t * __restrict ps) +{ + + /* Assume wchar_t uses UTF-32. */ + /* XXX: is wchar_t really unsigned? */ + return (mbrtowc((wchar_t* __restrict)pc32, s, n, ps)); +} + diff --git a/tests/lib/libc/multibyte/Atffile b/tests/lib/libc/multibyte/Atffile new file mode 100644 index 000000000000..44b9bb01c831 --- /dev/null +++ b/tests/lib/libc/multibyte/Atffile @@ -0,0 +1,7 @@ +Content-Type: application/X-atf-atffile; version="1" + +# Automatically generated by bsd.test.mk. + +prop: test-suite = "NetBSD" + +tp: t_c16rtomb diff --git a/tests/lib/libc/multibyte/Makefile b/tests/lib/libc/multibyte/Makefile new file mode 100644 index 000000000000..f21a844b6909 --- /dev/null +++ b/tests/lib/libc/multibyte/Makefile @@ -0,0 +1,14 @@ +# $NetBSD $ + +.include + +TESTSDIR?= ${TESTSBASE}/lib/libc/multibyte + +COPTS.t_c16rtomb.c += -g +COPTS.t_mbrtoc16.c += -Wno-unused-variable -Wno-unused-but-set-variable -g + +TESTS_C+= t_c16rtomb +TESTS_C+= t_mbrtoc16 + +.include + diff --git a/tests/lib/libc/multibyte/t_c16rtomb.c b/tests/lib/libc/multibyte/t_c16rtomb.c new file mode 100644 index 000000000000..548f2570c950 --- /dev/null +++ b/tests/lib/libc/multibyte/t_c16rtomb.c @@ -0,0 +1,121 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(c16rtomb_single); +ATF_TC_HEAD(c16rtomb_single, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test c16rtomb on a single multibyte char"); +} +/* This test checks c16rtomb behavior in case of valid conversion. setlocale + is called to make sure we're operating in an UTF-8 environment */ +ATF_TC_BODY(c16rtomb_single, tc) +{ + int rc; + char target[MB_LEN_MAX] = {0x00}; + char expected[sizeof(target)] = {0xE2, 0x9A, 0xA0, 0x00}; + char16_t warning_char = u'\u26A0'; //U+26A0 Warning Sign + mbstate_t mbs; + + setlocale(LC_ALL, "en_US.UTF-8"); + + + memset(&mbs, 0, sizeof(mbs)); + rc = c16rtomb(target, warning_char, &mbs); + printf("rc=%d\terrno=%d %s\n", rc, errno, strerror(errno)); + ATF_REQUIRE(rc == 3); + ATF_REQUIRE(memcmp(target, expected, MB_LEN_MAX) == 0); +} + +ATF_TC(c16rtomb_snull); +ATF_TC_HEAD(c16rtomb_snull, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test c16rtomb when s == NULL"); +} +/* This test checks c16rtomb behavior when s is a null pointer */ +/* TODO: what else should we check here? Maybe a separate test case is + necesary */ +ATF_TC_BODY(c16rtomb_snull, tc) +{ + int rc; + mbstate_t sta; + char16_t warning_char = u'\u26A0'; //U+26A0 Warning Sign + + memset(&sta,0,sizeof(sta)); + setlocale(LC_ALL, "en_US.UTF-8"); + rc = c16rtomb(NULL, warning_char, &sta); + ATF_REQUIRE_EQ(rc, 1); +} + +ATF_TC(c16rtomb_notfinal); +ATF_TC_HEAD(c16rtomb_notfinal, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test c16rtomb when c16 is not a final code unit"); +} +ATF_TC_BODY(c16rtomb_notfinal, tc) +{ + mbstate_t sta; + char16_t warning_char = 0xD801; //high surogate of U+10437 + char s[MB_LEN_MAX] = {0x00}; + int i; + memset(&sta,0,sizeof(sta)); + + setlocale(LC_ALL, "en_US.UTF-8"); + c16rtomb(s, warning_char, &sta); + + for(i = 0; i < MB_LEN_MAX; i++){ + ATF_REQUIRE_EQ(s[i], 0); + } +} + +/* TODO: If c16 is the null wide character u'\0', a null byte is stored, + preceded by any shift sequence necessary to restore the initial shift state + and the conversion state parameter *ps is updated to represent the initial +shift state. */ + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, c16rtomb_single); + ATF_TP_ADD_TC(tp, c16rtomb_snull); + ATF_TP_ADD_TC(tp, c16rtomb_notfinal); + + return atf_no_error(); +} diff --git a/tests/lib/libc/multibyte/t_mbrtoc16.c b/tests/lib/libc/multibyte/t_mbrtoc16.c new file mode 100644 index 000000000000..2e3a7ee15d27 --- /dev/null +++ b/tests/lib/libc/multibyte/t_mbrtoc16.c @@ -0,0 +1,110 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2019 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Chris Lasocki + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +ATF_TC(mbrtoc16_single); +ATF_TC_HEAD(mbrtoc16_single, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mbrtoc16 .... todo "); +} +/* This test checks mbrtoc16 behavior in case of valid conversion. setlocale + is called to make sure we're operating in an UTF-8 environment */ +ATF_TC_BODY(mbrtoc16_single, tc) +{ + int rc; + char16_t target; + char warning_char[MB_LEN_MAX] = {0xE2, 0x9A, 0xA0, 0x00}; + char16_t expected = u'\u26A0'; //U+26A0 Warning Sign + mbstate_t mbs; + + + memset(&mbs, 0, sizeof(mbs)); + + setlocale(LC_ALL, "en_US.UTF-8"); + ATF_REQUIRE(mbrtoc16(&target, warning_char, + sizeof(warning_char), &mbs) == 3); + ATF_REQUIRE_EQ(expected,target); +} + +ATF_TC(mbrtoc16_null_char); +ATF_TC_HEAD(mbrtoc16_null_char, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mbrtoc16 behavior when target char16_t is NULL"); +} +ATF_TC_BODY(mbrtoc16_null_char, tc) +{ + int rc; + char warning_char[MB_LEN_MAX] = {0xE2, 0x9A, 0xA0, 0x00}; + mbstate_t sta; + + memset(&sta, 0, sizeof(sta)); + setlocale(LC_ALL, "en_US.UTF-8"); + rc = mbrtoc16(NULL, warning_char, 3, &sta); + ATF_REQUIRE_EQ(rc, 3); +} + +ATF_TC(mbrtoc16_surrogate_pair); +ATF_TC_HEAD(mbrtoc16_surrogate_pair, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test mbrtoc16 behavior on surrogate pairs"); +} +ATF_TC_BODY(mbrtoc16_surrogate_pair, tc) +{ + int rc; + char surrogate_pair[MB_LEN_MAX] = "\U0001F34C"; + char16_t target = 0; + mbstate_t sta; + + memset(&sta, 0, sizeof(sta)); + setlocale(LC_ALL, "en_US.UTF-8"); + rc = mbrtoc16(&target, surrogate_pair, 1, &sta); + ATF_REQUIRE_EQ(rc, -2); + ATF_REQUIRE_EQ(target, 0); + rc = mbrtoc16(&target, NULL, sizeof(surrogate_pair), &sta); + ATF_REQUIRE_EQ(rc, -3); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, mbrtoc16_single); + ATF_TP_ADD_TC(tp, mbrtoc16_null_char); + ATF_TP_ADD_TC(tp, mbrtoc16_surrogate_pair); + + return atf_no_error(); +}