1570af302Sopenharmony_ci#include <stdio.h>
2570af302Sopenharmony_ci#include <string.h>
3570af302Sopenharmony_ci#include <wchar.h>
4570af302Sopenharmony_ci#include <wctype.h>
5570af302Sopenharmony_ci#include <stdlib.h>
6570af302Sopenharmony_ci#include <locale.h>
7570af302Sopenharmony_ci#include <langinfo.h>
8570af302Sopenharmony_ci#include <limits.h>
9570af302Sopenharmony_ci#include "test.h"
10570af302Sopenharmony_ci
11570af302Sopenharmony_ciint main(void)
12570af302Sopenharmony_ci{
13570af302Sopenharmony_ci	int i, j;
14570af302Sopenharmony_ci	mbstate_t st, st2;
15570af302Sopenharmony_ci	wchar_t wc, map[257], wtmp[257];
16570af302Sopenharmony_ci	char s[MB_LEN_MAX*256];
17570af302Sopenharmony_ci	size_t rv;
18570af302Sopenharmony_ci	int c;
19570af302Sopenharmony_ci	int ni_errors=0;
20570af302Sopenharmony_ci
21570af302Sopenharmony_ci	setlocale(LC_CTYPE, "C");
22570af302Sopenharmony_ci
23570af302Sopenharmony_ci	if (MB_CUR_MAX != 1) t_error("MB_CUR_MAX = %d, expected 1\n", (int)MB_CUR_MAX);
24570af302Sopenharmony_ci
25570af302Sopenharmony_ci	for (i=0; i<256; i++) {
26570af302Sopenharmony_ci		st = (mbstate_t){0};
27570af302Sopenharmony_ci		if (mbrtowc(&wc, &(char){i}, 1, &st) != !!i)
28570af302Sopenharmony_ci			t_error("mbrtowc failed to convert byte %.2x to wchar_t\n", i);
29570af302Sopenharmony_ci		if ((map[i]=btowc(i)) == WEOF) {
30570af302Sopenharmony_ci			t_error("btowc failed to convert byte %.2x to wchar_t\n", i);
31570af302Sopenharmony_ci			continue;
32570af302Sopenharmony_ci		}
33570af302Sopenharmony_ci		for (j=0; j<i; j++) {
34570af302Sopenharmony_ci			if (map[j]==map[i])
35570af302Sopenharmony_ci				t_error("bytes %.2x and %.2x map to same wchar_t %.4x\n", j, i, (unsigned)map[i]);
36570af302Sopenharmony_ci		}
37570af302Sopenharmony_ci	}
38570af302Sopenharmony_ci
39570af302Sopenharmony_ci	for (i=0; i<256; i++) {
40570af302Sopenharmony_ci		if (map[i]==WEOF) continue;
41570af302Sopenharmony_ci		if (wctob(map[i]) != i)
42570af302Sopenharmony_ci			t_error("wctob failed to convert wchar_t %.4x back to byte %.2x\n", (unsigned)map[i], i);
43570af302Sopenharmony_ci	}
44570af302Sopenharmony_ci
45570af302Sopenharmony_ci	/* covering whole 32-bit range would be too slow... maybe add random high tests? */
46570af302Sopenharmony_ci	for (i=0; i<0x110000; i++) {
47570af302Sopenharmony_ci		if (wcschr(map+1, i)) continue;
48570af302Sopenharmony_ci		if ((c=wctob(i)) != WEOF && ni_errors++ < 50)
49570af302Sopenharmony_ci			t_error("wctob accepted non-image wchar_t %.4x as byte %.2x\n", i, c);
50570af302Sopenharmony_ci		st = (mbstate_t){0};
51570af302Sopenharmony_ci		if (wcrtomb(s, i, &st) != -1  && ni_errors++ < 50)
52570af302Sopenharmony_ci			t_error("wcrtomb accepted non-image wchar_t %.4x\n", i);
53570af302Sopenharmony_ci	}
54570af302Sopenharmony_ci	if (ni_errors > 50)
55570af302Sopenharmony_ci		t_error("additional %d non-image errors (not printed)\n", ni_errors);
56570af302Sopenharmony_ci
57570af302Sopenharmony_ci	map[256] = 0;
58570af302Sopenharmony_ci	st = (mbstate_t){0};
59570af302Sopenharmony_ci	if ((rv=wcsrtombs(s, &(const wchar_t *){map+1}, sizeof s, &st)) != 255)
60570af302Sopenharmony_ci		t_error("wcsrtombs returned %zd, expected 255\n", rv);
61570af302Sopenharmony_ci	if ((rv=mbsrtowcs(wtmp, &(const char *){s}, 256, &st)) != 255)
62570af302Sopenharmony_ci		t_error("mbsrtowcs returned %zd, expected 255\n", rv);
63570af302Sopenharmony_ci	if (memcmp(map+1, wtmp, 256*sizeof(*map)))
64570af302Sopenharmony_ci		t_error("wcsrtombs/mbsrtowcs round trip failed\n");
65570af302Sopenharmony_ci
66570af302Sopenharmony_ci	for (i=128; i<256; i++) {
67570af302Sopenharmony_ci		if (iswalnum(map[i])) t_error("iswalnum returned true for %.4x (%.2x)\n", map[i], i);
68570af302Sopenharmony_ci		if (iswalpha(map[i])) t_error("iswalpha returned true for %.4x (%.2x)\n", map[i], i);
69570af302Sopenharmony_ci		if (iswblank(map[i])) t_error("iswblank returned true for %.4x (%.2x)\n", map[i], i);
70570af302Sopenharmony_ci		if (iswcntrl(map[i])) t_error("iswcntrl returned true for %.4x (%.2x)\n", map[i], i);
71570af302Sopenharmony_ci		if (iswdigit(map[i])) t_error("iswdigit returned true for %.4x (%.2x)\n", map[i], i);
72570af302Sopenharmony_ci		if (iswgraph(map[i])) t_error("iswgraph returned true for %.4x (%.2x)\n", map[i], i);
73570af302Sopenharmony_ci		if (iswlower(map[i])) t_error("iswlower returned true for %.4x (%.2x)\n", map[i], i);
74570af302Sopenharmony_ci		if (iswprint(map[i])) t_error("iswprint returned true for %.4x (%.2x)\n", map[i], i);
75570af302Sopenharmony_ci		if (iswpunct(map[i])) t_error("iswpunct returned true for %.4x (%.2x)\n", map[i], i);
76570af302Sopenharmony_ci		if (iswspace(map[i])) t_error("iswspace returned true for %.4x (%.2x)\n", map[i], i);
77570af302Sopenharmony_ci		if (iswupper(map[i])) t_error("iswupper returned true for %.4x (%.2x)\n", map[i], i);
78570af302Sopenharmony_ci		if (iswxdigit(map[i])) t_error("iswxdigit returned true for %.4x (%.2x)\n", map[i], i);
79570af302Sopenharmony_ci	}
80570af302Sopenharmony_ci
81570af302Sopenharmony_ci	return t_status;
82570af302Sopenharmony_ci}
83