1570af302Sopenharmony_ci#include <stdio.h>
2570af302Sopenharmony_ci#include <string.h>
3570af302Sopenharmony_ci#include <errno.h>
4570af302Sopenharmony_ci#include <limits.h>
5570af302Sopenharmony_ci#include <unistd.h>
6570af302Sopenharmony_ci#include <wchar.h>
7570af302Sopenharmony_ci#include "test.h"
8570af302Sopenharmony_ci
9570af302Sopenharmony_ci#define TEST(r, f, x, m) ( \
10570af302Sopenharmony_ci	errno=0, ((r) = (f)) == (x) || \
11570af302Sopenharmony_ci	(t_error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) )
12570af302Sopenharmony_ci
13570af302Sopenharmony_ci#define TEST_S(s, x, m) ( \
14570af302Sopenharmony_ci	!strcmp((s),(x)) || \
15570af302Sopenharmony_ci	(t_error("[%s] != [%s] (%s)\n", s, x, m), 0) )
16570af302Sopenharmony_ci
17570af302Sopenharmony_cistatic FILE *writetemp(const char *data)
18570af302Sopenharmony_ci{
19570af302Sopenharmony_ci	FILE *f = tmpfile();
20570af302Sopenharmony_ci	size_t n = strlen(data);
21570af302Sopenharmony_ci	if (!f) return 0;
22570af302Sopenharmony_ci	if (write(fileno(f), data, n) != n) {
23570af302Sopenharmony_ci		t_error("write: %s\n", strerror(errno));
24570af302Sopenharmony_ci		fclose(f);
25570af302Sopenharmony_ci		return 0;
26570af302Sopenharmony_ci	}
27570af302Sopenharmony_ci	if (lseek(fileno(f), 0, SEEK_SET) != 0) {
28570af302Sopenharmony_ci		t_error("lseek: %s\n", strerror(errno));
29570af302Sopenharmony_ci		fclose(f);
30570af302Sopenharmony_ci		return 0;
31570af302Sopenharmony_ci	}
32570af302Sopenharmony_ci	return f;
33570af302Sopenharmony_ci}
34570af302Sopenharmony_ci
35570af302Sopenharmony_ciint main(void)
36570af302Sopenharmony_ci{
37570af302Sopenharmony_ci	int i, x, y;
38570af302Sopenharmony_ci	double u;
39570af302Sopenharmony_ci	char a[100], b[100];
40570af302Sopenharmony_ci	FILE *f;
41570af302Sopenharmony_ci
42570af302Sopenharmony_ci	TEST(i, !!(f=writetemp("      42")), 1, "failed to make temp file");
43570af302Sopenharmony_ci	if (f) {
44570af302Sopenharmony_ci		x=y=-1;
45570af302Sopenharmony_ci		TEST(i, fwscanf(f, L" %n%*d%n", &x, &y), 0, "%d != %d");
46570af302Sopenharmony_ci		TEST(i, x, 6, "%d != %d");
47570af302Sopenharmony_ci		TEST(i, y, 8, "%d != %d");
48570af302Sopenharmony_ci		TEST(i, ftell(f), 8, "%d != %d");
49570af302Sopenharmony_ci		TEST(i, !!feof(f), 1, "%d != %d");
50570af302Sopenharmony_ci		fclose(f);
51570af302Sopenharmony_ci	}
52570af302Sopenharmony_ci
53570af302Sopenharmony_ci	TEST(i, !!(f=writetemp("[abc123]....x")), 1, "failed to make temp file");
54570af302Sopenharmony_ci	if (f) {
55570af302Sopenharmony_ci		x=y=-1;
56570af302Sopenharmony_ci		TEST(i, fwscanf(f, L"%10[^]]%n%10[].]%n", a, &x, b, &y), 2, "%d != %d");
57570af302Sopenharmony_ci		TEST_S(a, "[abc123", "wrong result for %[^]]");
58570af302Sopenharmony_ci		TEST_S(b, "]....", "wrong result for %[].]");
59570af302Sopenharmony_ci		TEST(i, x, 7, "%d != %d");
60570af302Sopenharmony_ci		TEST(i, y, 12, "%d != %d");
61570af302Sopenharmony_ci		TEST(i, ftell(f), 12, "%d != %d");
62570af302Sopenharmony_ci		TEST(i, feof(f), 0, "%d != %d");
63570af302Sopenharmony_ci		TEST(i, fgetwc(f), 'x', "%d != %d");
64570af302Sopenharmony_ci		fclose(f);
65570af302Sopenharmony_ci	}
66570af302Sopenharmony_ci
67570af302Sopenharmony_ci	/* Comment it because musl parse "0x1p" to "0x1" now rather than treat it as abnormal format.
68570af302Sopenharmony_ci	TEST(i, !!(f=writetemp("0x1p 12")), 1, "failed to make temp file");
69570af302Sopenharmony_ci	if (f) {
70570af302Sopenharmony_ci		x=y=-1;
71570af302Sopenharmony_ci		u=-1;
72570af302Sopenharmony_ci		TEST(i, fwscanf(f, L"%lf%n %d", &u, &x, &y), 0, "%d != %d");
73570af302Sopenharmony_ci		TEST(u, u, -1.0, "%g != %g");
74570af302Sopenharmony_ci		TEST(i, x, -1, "%d != %d");
75570af302Sopenharmony_ci		TEST(i, y, -1, "%d != %d");
76570af302Sopenharmony_ci		TEST(i, ftell(f), 4, "%d != %d");
77570af302Sopenharmony_ci		TEST(i, feof(f), 0, "%d != %d");
78570af302Sopenharmony_ci		TEST(i, fgetwc(f), ' ', "%d != %d");
79570af302Sopenharmony_ci		rewind(f);
80570af302Sopenharmony_ci		TEST(i, fgetwc(f), '0', "%d != %d");
81570af302Sopenharmony_ci		TEST(i, fgetwc(f), 'x', "%d != %d");
82570af302Sopenharmony_ci		TEST(i, fwscanf(f, L"%lf%n%c %d", &u, &x, a, &y), 3, "%d != %d");
83570af302Sopenharmony_ci		TEST(u, u, 1.0, "%g != %g");
84570af302Sopenharmony_ci		TEST(i, x, 1, "%d != %d");
85570af302Sopenharmony_ci		TEST(i, a[0], 'p', "%d != %d");
86570af302Sopenharmony_ci		TEST(i, y, 12, "%d != %d");
87570af302Sopenharmony_ci		TEST(i, ftell(f), 7, "%d != %d");
88570af302Sopenharmony_ci		TEST(i, !!feof(f), 1, "%d != %d");
89570af302Sopenharmony_ci		fclose(f);
90570af302Sopenharmony_ci	}
91570af302Sopenharmony_ci	*/
92570af302Sopenharmony_ci
93570af302Sopenharmony_ci	TEST(i, !!(f=writetemp("0x.1p4    012")), 1, "failed to make temp file");
94570af302Sopenharmony_ci	if (f) {
95570af302Sopenharmony_ci		x=y=-1;
96570af302Sopenharmony_ci		u=-1;
97570af302Sopenharmony_ci		TEST(i, fwscanf(f, L"%lf%n %i", &u, &x, &y), 2, "%d != %d");
98570af302Sopenharmony_ci		TEST(u, u, 1.0, "%g != %g");
99570af302Sopenharmony_ci		TEST(i, x, 6, "%d != %d");
100570af302Sopenharmony_ci		TEST(i, y, 10, "%d != %d");
101570af302Sopenharmony_ci		TEST(i, ftell(f), 13, "%d != %d");
102570af302Sopenharmony_ci		TEST(i, !!feof(f), 1, "%d != %d");
103570af302Sopenharmony_ci		fclose(f);
104570af302Sopenharmony_ci	}
105570af302Sopenharmony_ci
106570af302Sopenharmony_ci	TEST(i, !!(f=writetemp("0xx")), 1, "failed to make temp file");
107570af302Sopenharmony_ci	if (f) {
108570af302Sopenharmony_ci		x=y=-1;
109570af302Sopenharmony_ci		TEST(i, fwscanf(f, L"%x%n", &x, &y), 0, "%d != %d");
110570af302Sopenharmony_ci		TEST(i, x, -1, "%d != %d");
111570af302Sopenharmony_ci		TEST(i, y, -1, "%d != %d");
112570af302Sopenharmony_ci		TEST(i, ftell(f), 2, "%d != %d");
113570af302Sopenharmony_ci		TEST(i, feof(f), 0, "%d != %d");
114570af302Sopenharmony_ci		fclose(f);
115570af302Sopenharmony_ci	}
116570af302Sopenharmony_ci
117570af302Sopenharmony_ci	return t_status;
118570af302Sopenharmony_ci}
119