16
16
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17
17
│ PERFORMANCE OF THIS SOFTWARE. │
18
18
╚─────────────────────────────────────────────────────────────────────────────*/
19
+ #include "libc/runtime/fenv.h"
19
20
#include "libc/stdio/stdio.h"
20
21
#include "libc/str/str.h"
21
22
#include "libc/testlib/testlib.h"
@@ -24,64 +25,64 @@ TEST(snprintf, testVeryLargePrecision) {
24
25
char buf [512 ] = {};
25
26
int i = snprintf (buf , sizeof (buf ), "%.9999u" , 10 );
26
27
27
- ASSERT_EQ (i , 9999 );
28
- ASSERT_EQ (strlen (buf ), 511 );
28
+ ASSERT_EQ (9999 , i );
29
+ ASSERT_EQ (511 , strlen (buf ));
29
30
}
30
31
31
32
TEST (snprintf , testPlusFlagOnChar ) {
32
33
char buf [10 ] = {};
33
34
int i = snprintf (buf , sizeof (buf ), "%+c" , '=' );
34
35
35
- ASSERT_EQ (i , 1 );
36
- ASSERT_STREQ (buf , "=" );
36
+ ASSERT_EQ (1 , i );
37
+ ASSERT_STREQ ("=" , buf );
37
38
}
38
39
39
40
TEST (snprintf , testInf ) {
40
41
char buf [10 ] = {};
41
42
int i = snprintf (buf , sizeof (buf ), "%f" , 1.0 / 0.0 );
42
43
43
- ASSERT_EQ (i , 3 );
44
- ASSERT_STREQ (buf , "inf" );
44
+ ASSERT_EQ (3 , i );
45
+ ASSERT_STREQ ("inf" , buf );
45
46
46
47
memset (buf , '\0' , 4 );
47
48
i = snprintf (buf , sizeof (buf ), "%Lf" , 1.0L / 0.0L );
48
- ASSERT_EQ (i , 3 );
49
- ASSERT_STREQ (buf , "inf" );
49
+ ASSERT_EQ (3 , i );
50
+ ASSERT_STREQ ("inf" , buf );
50
51
51
52
memset (buf , '\0' , 4 );
52
53
i = snprintf (buf , sizeof (buf ), "%e" , 1.0 / 0.0 );
53
- ASSERT_EQ (i , 3 );
54
- ASSERT_STREQ (buf , "inf" );
54
+ ASSERT_EQ (3 , i );
55
+ ASSERT_STREQ ("inf" , buf );
55
56
56
57
memset (buf , '\0' , 4 );
57
58
i = snprintf (buf , sizeof (buf ), "%Le" , 1.0L / 0.0L );
58
- ASSERT_EQ (i , 3 );
59
- ASSERT_STREQ (buf , "inf" );
59
+ ASSERT_EQ (3 , i );
60
+ ASSERT_STREQ ("inf" , buf );
60
61
61
62
memset (buf , '\0' , 4 );
62
63
i = snprintf (buf , sizeof (buf ), "%g" , 1.0 / 0.0 );
63
- ASSERT_EQ (i , 3 );
64
- ASSERT_STREQ (buf , "inf" );
64
+ ASSERT_EQ (3 , i );
65
+ ASSERT_STREQ ("inf" , buf );
65
66
66
67
memset (buf , '\0' , 4 );
67
68
i = snprintf (buf , sizeof (buf ), "%Lg" , 1.0L / 0.0L );
68
- ASSERT_EQ (i , 3 );
69
- ASSERT_STREQ (buf , "inf" );
69
+ ASSERT_EQ (3 , i );
70
+ ASSERT_STREQ ("inf" , buf );
70
71
71
72
for (i = 4 ; i < 10 ; ++ i )
72
- ASSERT_EQ (buf [ i ], '\0' );
73
+ ASSERT_EQ ('\0' , buf [ i ] );
73
74
}
74
75
75
76
TEST (snprintf , testUppercaseCConversionSpecifier ) {
76
77
char buf [10 ] = {};
77
78
int i = snprintf (buf , sizeof (buf ), "%C" , L'a' );
78
79
79
- ASSERT_EQ (i , 1 );
80
- ASSERT_STREQ (buf , "a" );
80
+ ASSERT_EQ (1 , i );
81
+ ASSERT_STREQ ("a" , buf );
81
82
82
83
i = snprintf (buf , sizeof (buf ), "%C" , L'☺' );
83
- ASSERT_EQ (i , 3 );
84
- ASSERT_STREQ (buf , "☺" );
84
+ ASSERT_EQ (3 , i );
85
+ ASSERT_STREQ ("☺" , buf );
85
86
}
86
87
87
88
// Make sure we don't va_arg the wrong argument size on wide character
@@ -92,96 +93,126 @@ TEST(snprintf,
92
93
int i = snprintf (buf , sizeof (buf ), "%d%d%d%d%d%d%d%d%lc%d" , 0 , 0 , 0 , 0 , 0 , 0 ,
93
94
0 , 0 , L'x' , 1 );
94
95
95
- ASSERT_EQ (i , 10 );
96
- ASSERT_STREQ (buf , "00000000x1" );
96
+ ASSERT_EQ (10 , i );
97
+ ASSERT_STREQ ("00000000x1" , buf );
97
98
98
99
memset (buf , 0 , sizeof (buf ));
99
100
i = snprintf (buf , sizeof (buf ), "%d%d%d%d%d%d%d%d%C%d" , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
100
101
L'x' , 1 );
101
- ASSERT_EQ (i , 10 );
102
- ASSERT_STREQ (buf , "00000000x1" );
102
+ ASSERT_EQ (10 , i );
103
+ ASSERT_STREQ ("00000000x1" , buf );
103
104
}
104
105
105
106
static void check_n_buffer_contents (char buf [350 ]) {
106
107
for (int i = 0 ; i < 284 ; ++ i )
107
- ASSERT_EQ (buf [i ], ' ' );
108
- ASSERT_STREQ (& buf [284 ], "428463" );
108
+ ASSERT_EQ (' ' , buf [i ]);
109
+ ASSERT_STREQ ("428463" , & buf [284 ]);
109
110
for (int i = 290 ; i < 350 ; ++ i )
110
- ASSERT_EQ (buf [ i ], '\0' );
111
+ ASSERT_EQ ('\0' , buf [ i ] );
111
112
}
112
113
113
114
TEST (snprintf , testNConversionSpecifier ) {
114
115
char buf [350 ] = {};
115
116
116
117
int n_res_int = -1 ;
117
118
int i = snprintf (buf , sizeof (buf ), "%286d%d%n%d" , 42 , 84 , & n_res_int , 63 );
118
- ASSERT_EQ (i , 290 );
119
+ ASSERT_EQ (290 , i );
119
120
check_n_buffer_contents (buf );
120
- ASSERT_EQ (n_res_int , 288 );
121
+ ASSERT_EQ (288 , n_res_int );
121
122
122
123
memset (& buf , '\0' , sizeof (buf ));
123
124
long n_res_long = -1 ;
124
125
i = snprintf (buf , sizeof (buf ), "%286ld%ld%ln%ld" , 42L , 84L , & n_res_long , 63L );
125
- ASSERT_EQ (i , 290 );
126
+ ASSERT_EQ (290 , i );
126
127
check_n_buffer_contents (buf );
127
- ASSERT_EQ (n_res_long , 288 );
128
+ ASSERT_EQ (288 , n_res_long );
128
129
129
130
memset (& buf , '\0' , sizeof (buf ));
130
131
long long n_res_long_long = -1 ;
131
132
i = snprintf (buf , sizeof (buf ), "%286lld%lld%lln%lld" , 42LL , 84LL ,
132
133
& n_res_long_long , 63LL );
133
- ASSERT_EQ (i , 290 );
134
+ ASSERT_EQ (290 , i );
134
135
check_n_buffer_contents (buf );
135
- ASSERT_EQ (n_res_long_long , 288 );
136
+ ASSERT_EQ (288 , n_res_long_long );
136
137
137
138
ASSERT_EQ (sizeof (short ), 2 );
138
139
ASSERT_EQ (sizeof (int ), 4 );
139
140
memset (& buf , '\0' , sizeof (buf ));
140
141
short n_res_short = -1 ;
141
142
i = snprintf (buf , sizeof (buf ), "%286hd%hd%hn%hd" , (42 | 0xFFFF0000 ),
142
143
(84 | 0xFFFF0000 ), & n_res_short , (63 | 0xFFFF0000 ));
143
- ASSERT_EQ (i , 290 );
144
+ ASSERT_EQ (290 , i );
144
145
check_n_buffer_contents (buf );
145
- ASSERT_EQ (n_res_short , 288 );
146
+ ASSERT_EQ (288 , n_res_short );
146
147
147
148
ASSERT_EQ (sizeof (unsigned char ), 1 );
148
149
memset (& buf , '\0' , sizeof (buf ));
149
150
signed char n_res_char = -1 ;
150
151
i = snprintf (buf , sizeof (buf ), "%286hhd%hhd%hhn%hhd" , (42 | 0xFFFFFF00 ),
151
152
(84 | 0xFFFFFF00 ), & n_res_char , (63 | 0xFFFFFF00 ));
152
- ASSERT_EQ (i , 290 );
153
+ ASSERT_EQ (290 , i );
153
154
check_n_buffer_contents (buf );
154
- ASSERT_EQ (n_res_char , (signed char )288 );
155
+ ASSERT_EQ ((signed char )288 , n_res_char );
155
156
156
157
memset (& buf , '\0' , sizeof (buf ));
157
158
ssize_t n_res_size_t = -1 ;
158
159
i = snprintf (buf , sizeof (buf ), "%286zd%zd%zn%zd" , (ssize_t )42 , (ssize_t )84 ,
159
160
& n_res_size_t , (ssize_t )63 );
160
- ASSERT_EQ (i , 290 );
161
+ ASSERT_EQ (290 , i );
161
162
check_n_buffer_contents (buf );
162
- ASSERT_EQ (n_res_size_t , 288 );
163
+ ASSERT_EQ (288 , n_res_size_t );
163
164
164
165
memset (& buf , '\0' , sizeof (buf ));
165
166
intmax_t n_res_intmax_t = -1 ;
166
167
i = snprintf (buf , sizeof (buf ), "%286jd%jd%jn%jd" , (intmax_t )42 , (intmax_t )84 ,
167
168
& n_res_intmax_t , (intmax_t )63 );
168
- ASSERT_EQ (i , 290 );
169
+ ASSERT_EQ (290 , i );
169
170
check_n_buffer_contents (buf );
170
- ASSERT_EQ (n_res_intmax_t , 288 );
171
+ ASSERT_EQ (288 , n_res_intmax_t );
171
172
172
173
memset (& buf , '\0' , sizeof (buf ));
173
174
int128_t n_res_int128_t = -1 ;
174
175
i = snprintf (buf , sizeof (buf ), "%286jjd%jjd%jjn%jjd" , (int128_t )42 ,
175
176
(int128_t )84 , & n_res_int128_t , (int128_t )63 );
176
- ASSERT_EQ (i , 290 );
177
+ ASSERT_EQ (290 , i );
177
178
check_n_buffer_contents (buf );
178
- ASSERT_EQ (n_res_int128_t , 288 );
179
+ ASSERT_EQ (288 , n_res_int128_t );
179
180
180
181
memset (& buf , '\0' , sizeof (buf ));
181
182
ptrdiff_t n_res_ptrdiff_t = -1 ;
182
183
i = snprintf (buf , sizeof (buf ), "%286td%td%tn%td" , (ptrdiff_t )42 ,
183
184
(ptrdiff_t )84 , & n_res_ptrdiff_t , (ptrdiff_t )63 );
184
- ASSERT_EQ (i , 290 );
185
+ ASSERT_EQ (290 , i );
185
186
check_n_buffer_contents (buf );
186
- ASSERT_EQ (n_res_ptrdiff_t , 288 );
187
+ ASSERT_EQ (288 , n_res_ptrdiff_t );
188
+ }
189
+
190
+ TEST (snprintf , testLongDoubleEConversionSpecifier ) {
191
+ char buf [20 ] = {};
192
+ int i = snprintf (buf , sizeof (buf ), "%Le" , 1234567.8L );
193
+
194
+ ASSERT_EQ (12 , i );
195
+ ASSERT_STREQ ("1.234568e+06" , buf );
196
+ }
197
+
198
+ TEST (snprintf , testLongDoubleRounding ) {
199
+ int previous_rounding = fegetround ();
200
+ ASSERT_EQ (0 , fesetround (FE_DOWNWARD ));
201
+
202
+ char buf [20 ];
203
+ int i = snprintf (buf , sizeof (buf ), "%.3Lf" , 4.4375L );
204
+ ASSERT_EQ (5 , i );
205
+ ASSERT_STREQ ("4.437" , buf );
206
+
207
+ i = snprintf (buf , sizeof (buf ), "%.3Lf" , -4.4375L );
208
+ ASSERT_EQ (6 , i );
209
+ ASSERT_STREQ ("-4.438" , buf );
210
+
211
+ ASSERT_EQ (0 , fesetround (FE_TOWARDZERO ));
212
+
213
+ i = snprintf (buf , sizeof (buf ), "%.3Lf" , -4.4375L );
214
+ ASSERT_EQ (6 , i );
215
+ ASSERT_STREQ ("-4.437" , buf );
216
+
217
+ ASSERT_EQ (0 , fesetround (previous_rounding ));
187
218
}
0 commit comments