1 | #include <array_length.h> |
2 | #include <errno.h> |
3 | #include <stdio.h> |
4 | #include <support/check.h> |
5 | #include <sys/types.h> |
6 | #include <wchar.h> |
7 | |
8 | |
9 | static wchar_t buf[100]; |
10 | static const struct |
11 | { |
12 | size_t n; |
13 | const char *str; |
14 | ssize_t exp; |
15 | } tests[] = |
16 | { |
17 | { array_length (buf), "hello world" , 11 }, |
18 | { 0, "hello world" , -1 }, |
19 | { 1, "hello world" , -1 }, |
20 | { 2, "hello world" , -1 }, |
21 | { 11, "hello world" , -1 }, |
22 | { 12, "hello world" , 11 }, |
23 | { 0, "" , -1 }, |
24 | { array_length (buf), "" , 0 } |
25 | }; |
26 | |
27 | static int |
28 | do_test (void) |
29 | { |
30 | size_t n; |
31 | |
32 | TEST_COMPARE (swprintf (buf, array_length (buf), L"Hello %s" , "world" ), 11); |
33 | TEST_COMPARE_STRING_WIDE (buf, L"Hello world" ); |
34 | |
35 | TEST_COMPARE (swprintf (buf, array_length (buf), L"Is this >%g< 3.1?" , 3.1), |
36 | 18); |
37 | TEST_COMPARE_STRING_WIDE (buf, L"Is this >3.1< 3.1?" ); |
38 | |
39 | for (n = 0; n < array_length (tests); ++n) |
40 | { |
41 | wmemset (buf, 0xabcd, array_length (buf)); |
42 | errno = 0; |
43 | ssize_t res = swprintf (s: buf, n: tests[n].n, format: L"%s" , tests[n].str); |
44 | |
45 | if (tests[n].exp < 0 && res >= 0) |
46 | { |
47 | support_record_failure (); |
48 | printf (format: "swprintf (buf, %zu, L\"%%s\", \"%s\") expected to fail\n" , |
49 | tests[n].n, tests[n].str); |
50 | } |
51 | else if (tests[n].exp >= 0 && tests[n].exp != res) |
52 | { |
53 | support_record_failure (); |
54 | printf (format: "\ |
55 | swprintf (buf, %zu, L\"%%s\", \"%s\") expected to return %zd, but got %zd\n" , |
56 | tests[n].n, tests[n].str, tests[n].exp, res); |
57 | } |
58 | else if (res < 0 |
59 | && tests[n].n > 0 |
60 | && wcsnlen (s: buf, array_length (buf)) == array_length (buf)) |
61 | { |
62 | support_record_failure (); |
63 | printf (format: "\ |
64 | error: swprintf (buf, %zu, L\"%%s\", \"%s\") missing null terminator\n" , |
65 | tests[n].n, tests[n].str); |
66 | } |
67 | else if (res < 0 |
68 | && tests[n].n > 0 |
69 | && wcsnlen (s: buf, array_length (buf)) < array_length (buf) |
70 | && buf[wcsnlen (s: buf, array_length (buf)) + 1] != 0xabcd) |
71 | { |
72 | support_record_failure (); |
73 | printf (format: "\ |
74 | error: swprintf (buf, %zu, L\"%%s\", \"%s\") out of bounds write\n" , |
75 | tests[n].n, tests[n].str); |
76 | } |
77 | |
78 | if (res < 0 && tests[n].n < 0) |
79 | TEST_COMPARE (errno, E2BIG); |
80 | |
81 | printf (format: "swprintf (buf, %zu, L\"%%s\", \"%s\") OK\n" , |
82 | tests[n].n, tests[n].str); |
83 | } |
84 | |
85 | TEST_COMPARE (swprintf (buf, array_length (buf), L"%.0s" , "foo" ), 0); |
86 | TEST_COMPARE_STRING_WIDE (buf, L"" ); |
87 | |
88 | TEST_COMPARE (swprintf (buf, array_length (buf), L"%.0ls" , L"foo" ), 0); |
89 | TEST_COMPARE_STRING_WIDE (buf, L"" ); |
90 | |
91 | return 0; |
92 | } |
93 | |
94 | #include <support/test-driver.c> |
95 | |