summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMarko Kreen2013-01-06 10:48:38 +0000
committerMarko Kreen2013-01-06 10:48:38 +0000
commit8defa2ad87d9a58488a894f91fbddfebefe3cc5f (patch)
tree26cf45bcc47194319735a8f3bf16ffb4d7965943 /test
parentfa434093c39600a29bed2c37f94658bbeebf3d85 (diff)
wchar: compat mbsnrtowcs(), tests
Diffstat (limited to 'test')
-rw-r--r--test/Makefile1
-rw-r--r--test/force_compat.sed1
-rw-r--r--test/test_common.c1
-rw-r--r--test/test_common.h1
-rw-r--r--test/test_wchar.c139
5 files changed, 143 insertions, 0 deletions
diff --git a/test/Makefile b/test/Makefile
index dc8d339..af63339 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -14,6 +14,7 @@ regtest_system_SOURCES = \
test_cfparser.c test_endian.c test_hashtab.c test_mdict.c \
test_shlist.c test_time.c test_hashing.c test_fileutil.c \
test_socket.c test_getopt.c test_ctype.c test_fnmatch.c \
+ test_wchar.c \
test_common.h tinytest.h tinytest_macros.h
# build regtest_system against actual library
diff --git a/test/force_compat.sed b/test/force_compat.sed
index 33430da..dc3033e 100644
--- a/test/force_compat.sed
+++ b/test/force_compat.sed
@@ -11,3 +11,4 @@
/^#define.*GETOPT/s,.*,/* & */,
/^#define.*CTYPE_ON_CHAR/s,.*,/* & */,
/^#define.*FNMATCH/s,.*,/* & */,
+/^#define.*MBSNRTOWCS/s,.*,/* & */,
diff --git a/test/test_common.c b/test/test_common.c
index 5c407cc..dca1520 100644
--- a/test/test_common.c
+++ b/test/test_common.c
@@ -12,6 +12,7 @@ struct testgroup_t groups[] = {
{ "hashing/", hashing_tests },
{ "endian/", endian_tests },
{ "string/", string_tests },
+ { "wchar/", wchar_tests },
{ "fnmatch/", fnmatch_tests },
{ "ctype/", ctype_tests },
{ "heap/", heap_tests },
diff --git a/test/test_common.h b/test/test_common.h
index 375fa71..a9074b8 100644
--- a/test/test_common.h
+++ b/test/test_common.h
@@ -34,3 +34,4 @@ extern struct testcase_t socket_tests[];
extern struct testcase_t getopt_tests[];
extern struct testcase_t ctype_tests[];
extern struct testcase_t fnmatch_tests[];
+extern struct testcase_t wchar_tests[];
diff --git a/test/test_wchar.c b/test/test_wchar.c
new file mode 100644
index 0000000..df87b45
--- /dev/null
+++ b/test/test_wchar.c
@@ -0,0 +1,139 @@
+
+#include <usual/wchar.h>
+#include <string.h>
+
+#include "test_common.h"
+
+
+/*
+ * mbstr_decode()
+ */
+
+static const char *decode(const char *s, int inbuf)
+{
+ static char out[128];
+ wchar_t tmp[128];
+ wchar_t *res;
+ int reslen = 4;
+ unsigned i;
+
+ for (i = 0; i < 128; i++)
+ tmp[i] = '~';
+
+ res = mbstr_decode(s, inbuf, &reslen, tmp, sizeof(tmp), true);
+ if (res == NULL) {
+ if (errno == EILSEQ) return "EILSEQ";
+ if (errno == ENOMEM) return "ENOMEM";
+ return "NULL??";
+ }
+ if (res != tmp)
+ return "EBUF";
+ if (res[reslen] == 0)
+ res[reslen] = 'Z';
+ else
+ return "reslen fail?";
+
+ for (i = 0; i < 128; i++) {
+ out[i] = tmp[i];
+ if (out[i] == '~') {
+ out[i+1] = 0;
+ break;
+ } else if (out[i] == 0) {
+ out[i] = '#';
+ } else if (tmp[i] > 127) {
+ out[i] = 'A' + tmp[i] % 26;
+ }
+ }
+ return out;
+}
+
+static void test_mbstr_decode(void *p)
+{
+ str_check(decode("", 0), "Z~");
+ str_check(decode("", 1), "Z~");
+ str_check(decode("a", 0), "Z~");
+
+ str_check(decode("abc", 0), "Z~");
+ str_check(decode("abc", 1), "aZ~");
+ str_check(decode("abc", 2), "abZ~");
+ str_check(decode("abc", 3), "abcZ~");
+ str_check(decode("abc", 4), "abcZ~");
+ str_check(decode("abc", 5), "abcZ~");
+
+ if (MB_CUR_MAX > 1) {
+ str_check(decode("aa\200cc", 5), "aaYccZ~");
+ str_check(decode("a\200cc", 5), "aYccZ~");
+ str_check(decode("aa\200c", 5), "aaYcZ~");
+ }
+end:;
+}
+
+/*
+ * mbsnrtowcs()
+ */
+
+
+static const char *mbsnr(const char *str, int inbuf, int outbuf)
+{
+ static char out[128];
+ wchar_t tmp[128];
+ int res;
+ unsigned i;
+ const char *s = str;
+ mbstate_t ps;
+
+ for (i = 0; i < 128; i++)
+ tmp[i] = '~';
+
+ memset(&ps, 0, sizeof(ps));
+ res = mbsnrtowcs(tmp, &s, inbuf, outbuf, &ps);
+ if (res < 0) {
+ if (errno == EILSEQ) {
+ snprintf(out, sizeof(out), "EILSEQ(%d)", (int)(s - str));
+ return out;
+ }
+ return "unknown error";
+ }
+ if (tmp[res] == 0)
+ tmp[res] = s ? 'z' : 'Z';
+
+ for (i = 0; i < 128; i++) {
+ out[i] = tmp[i];
+ if (out[i] == '~') {
+ out[i+1] = 0;
+ break;
+ }
+ }
+ return out;
+}
+
+static void test_mbsnrtowcs(void *p)
+{
+ str_check(mbsnr("", 1, 1), "Z~");
+ str_check(mbsnr("", 0, 0), "~");
+ str_check(mbsnr("", 0, 1), "~"); /* XXX */
+ str_check(mbsnr("", 1, 0), "~");
+
+ str_check(mbsnr("x", 1, 1), "x~");
+ str_check(mbsnr("x", 0, 0), "~");
+ str_check(mbsnr("x", 0, 1), "~"); /* XXX */
+ str_check(mbsnr("x", 1, 0), "~");
+
+ str_check(mbsnr("abc", 3, 3), "abc~");
+ str_check(mbsnr("abc", 3, 4), "abc~"); /* XXX */
+
+ str_check(mbsnr("abc", 4, 3), "abc~");
+ str_check(mbsnr("abc", 4, 4), "abcZ~");
+end:;
+}
+
+/*
+ * Describe
+ */
+
+struct testcase_t wchar_tests[] = {
+ { "mbsnrtowcs", test_mbsnrtowcs },
+ { "mbstr_decode", test_mbstr_decode },
+ END_OF_TESTCASES
+};
+