1 /* $OpenBSD: test_wcrtomb.c,v 1.2 2017/07/27 15:08:37 bluhm Exp $ */ 2 /* 3 * Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/types.h> 19 #include <err.h> 20 #include <errno.h> 21 #include <limits.h> 22 #include <locale.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <wchar.h> 26 27 static mbstate_t mbs; 28 29 void 30 onetest(const char *name, const wchar_t wcin, int outerr, const char *out) 31 { 32 char buf[MB_LEN_MAX]; 33 size_t sz, outsz; 34 35 memset(buf, 0, MB_LEN_MAX); 36 outsz = out == NULL ? (size_t)-1 : *out == '\0' ? 1 : strlen(out); 37 sz = wcrtomb(buf, wcin, &mbs); 38 if (errno != outerr) 39 err(1, "%zu %s U+%04X", MB_CUR_MAX, name, wcin); 40 if (sz != outsz || (out != NULL && strncmp(buf, out, sz))) 41 errx(1, "%zu %s U+%04X: %4.4s(%zd) != %4.4s(%zd)", 42 MB_CUR_MAX, name, wcin, buf, sz, 43 out == NULL ? "(NULL)" : out, outsz); 44 if (mbsinit(&mbs) == 0) 45 errx(1, "%zu %s U+%04X mbsinit", MB_CUR_MAX, name, wcin); 46 if (errno == 0 && outerr == 0) 47 return; 48 errno = 0; 49 memset(&mbs, 0, sizeof(mbs)); 50 } 51 52 int 53 main(void) 54 { 55 onetest("NUL", L'\0', 0, ""); 56 onetest("BEL", L'\a', 0, "\a"); 57 onetest("A", L'A', 0, "A"); 58 onetest("DEL", L'\177', 0, "\177"); 59 onetest("CSI", L'\233', 0, "\233"); 60 onetest("0x100", 0x100, EILSEQ, NULL); 61 62 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) 63 errx(1, "setlocale(UTF-8) failed"), 64 65 onetest("NUL", L'\0', 0, ""); 66 onetest("BEL", L'\a', 0, "\a"); 67 onetest("A", L'A', 0, "A"); 68 onetest("DEL", L'\177', 0, "\177"); 69 onetest("CSI", L'\233', 0, "\302\233"); 70 onetest("0xe9", 0xe9, 0, "\303\251"); 71 onetest("0xcfff", 0xcfff, 0, "\354\277\277"); 72 onetest("0xd800", 0xd800, EILSEQ, NULL); 73 74 if (setlocale(LC_CTYPE, "POSIX") == NULL) 75 errx(1, "setlocale(POSIX) failed"), 76 77 onetest("0xff", L'\377', 0, "\377"); 78 79 if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL) 80 errx(1, "second setlocale(UTF-8) failed"), 81 82 onetest("U+13000", 0x13000, 0, "\360\223\200\200"); 83 84 return 0; 85 } 86