#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2011\
The NetBSD Foundation, inc. All rights reserved.");
__RCSID("$NetBSD: t_io.c,v 1.5 2017/07/12 17:32:51 perseant Exp $");
#include <sys/param.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <atf-c.h>
ATF_TC(bad_big5_wprintf);
ATF_TC_HEAD(bad_big5_wprintf, tc)
{
atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf");
}
ATF_TC_BODY(bad_big5_wprintf, tc)
{
wchar_t ibuf[] = {
#ifdef __STDC_ISO_10646__
0x0978, 0
#else
0xcf10, 0
#endif
};
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0);
ATF_REQUIRE(ferror(stdout));
}
ATF_TC(bad_big5_swprintf);
ATF_TC_HEAD(bad_big5_swprintf, tc)
{
atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf");
}
ATF_TC_BODY(bad_big5_swprintf, tc)
{
wchar_t ibuf[] = {
#ifdef __STDC_ISO_10646__
0x0978, 0
#else
0xcf10, 0
#endif
};
wchar_t obuf[20];
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_ERRNO(EILSEQ,
swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0);
}
ATF_TC(good_big5_wprintf);
ATF_TC_HEAD(good_big5_wprintf, tc)
{
atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf");
}
ATF_TC_BODY(good_big5_wprintf, tc)
{
wchar_t ibuf[] = {
#ifdef __STDC_ISO_10646__
0x67DC, 0
#else
0xcf40, 0
#endif
};
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2);
}
ATF_TC(good_big5_swprintf);
ATF_TC_HEAD(good_big5_swprintf, tc)
{
atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf");
}
ATF_TC_BODY(good_big5_swprintf, tc)
{
wchar_t ibuf[] = {
#ifdef __STDC_ISO_10646__
0x67DC, 0
#else
0xcf40, 0
#endif
};
wchar_t obuf[20];
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2);
}
struct ibuf {
off_t off;
size_t buflen;
const char *buf;
};
static int
readfn(void *vp, char *buf, int len)
{
struct ibuf *ib = vp;
size_t todo = MIN((size_t)len, ib->buflen - ib->off);
memcpy(buf, ib->buf + ib->off, todo);
ib->off += todo;
return todo;
}
ATF_TC(good_big5_getwc);
ATF_TC_HEAD(good_big5_getwc, tc)
{
atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc");
}
ATF_TC_BODY(good_big5_getwc, tc)
{
const char buf[] = { 0xcf, 0x40 };
struct ibuf ib = {
.buf = buf,
.buflen = sizeof(buf),
};
FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
ATF_REQUIRE(fp != NULL);
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_EQ(getwc(fp),
#ifdef __STDC_ISO_10646__
0x67DC
#else
0xcf40
#endif
);
fclose(fp);
}
ATF_TC(bad_big5_getwc);
ATF_TC_HEAD(bad_big5_getwc, tc)
{
atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc");
}
ATF_TC_BODY(bad_big5_getwc, tc)
{
const char buf[] = { 0xcf, 0x20 };
struct ibuf ib = {
.buf = buf,
.buflen = sizeof(buf),
};
FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
ATF_REQUIRE(fp != NULL);
setlocale(LC_CTYPE, "zh_TW.Big5");
ATF_REQUIRE_EQ(getwc(fp), WEOF);
fclose(fp);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, bad_big5_wprintf);
ATF_TP_ADD_TC(tp, bad_big5_swprintf);
ATF_TP_ADD_TC(tp, good_big5_wprintf);
ATF_TP_ADD_TC(tp, good_big5_swprintf);
ATF_TP_ADD_TC(tp, good_big5_getwc);
ATF_TP_ADD_TC(tp, bad_big5_getwc);
return atf_no_error();
}