blob: 884a7a9cebca28e6360d24aead3fea2f7bb748a3 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar502ae4b2016-07-16 19:50:13 +02002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * message_test.c: Unittests for message.c
12 */
13
14#undef NDEBUG
15#include <assert.h>
16
Bram Moolenaar85a20022019-12-21 18:25:54 +010017// Must include main.c because it contains much more than just main()
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020018#define NO_VIM_MAIN
19#include "main.c"
20
Bram Moolenaar85a20022019-12-21 18:25:54 +010021// This file has to be included because some of the tested functions are
22// static.
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020023#include "message.c"
24
Bram Moolenaard2c946b2019-12-31 19:24:51 +010025#ifndef MIN
26# define MIN(x,y) ((x) < (y) ? (x) : (y))
27#endif
28
29// These formats are not standard in C printf() function.
30// Use a global variable rather than a literal format to disable
31// -Wformat compiler warnings:
32//
33// - warning: '0' flag used with ‘%p’ gnu_printf format
34// - warning: format ‘%S’ expects argument of type ‘wchar_t *’, but argument 4 has type ‘char *’
35// - warning: unknown conversion type character ‘b’ in format
36//
Hirohito Higashifbe4a8f2025-04-27 15:28:30 +020037// These formats are in practise only used from Vim script printf()
Bram Moolenaard2c946b2019-12-31 19:24:51 +010038// function and never as literals in C code.
39char *fmt_012p = "%012p";
40char *fmt_5S = "%5S";
41char *fmt_06b = "%06b";
Christ van Willegen0c6181f2023-08-13 18:03:14 +020042char *fmt_06pb = "%1$0.*2$b";
Christ van Willegenaa90d4f2023-09-03 17:22:37 +020043char *fmt_06pb2 = "%2$0*1$b";
Christ van Willegen0c6181f2023-08-13 18:03:14 +020044char *fmt_212s = "%2$s %1$s %2$s";
45char *fmt_21s = "%2$s %1$s";
Bram Moolenaard2c946b2019-12-31 19:24:51 +010046
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020047/*
48 * Test trunc_string().
49 */
50 static void
51test_trunc_string(void)
52{
Bram Moolenaarb9644432016-07-19 12:33:44 +020053 char_u *buf; /*allocated every time to find uninit errors */
54 char_u *s;
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020055
Bram Moolenaar62818152021-02-14 15:37:30 +010056 // Should not write anything to destination if buflen is 0.
57 trunc_string((char_u *)"", NULL, 1, 0);
58
59 // Truncating an empty string does nothing.
60 buf = alloc(1);
61 trunc_string((char_u *)"", buf, 1, 1);
62 assert(buf[0] == NUL);
63 vim_free(buf);
64
Bram Moolenaar85a20022019-12-21 18:25:54 +010065 // in place
Bram Moolenaarb9644432016-07-19 12:33:44 +020066 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020067 STRCPY(buf, "text");
68 trunc_string(buf, buf, 20, 40);
69 assert(STRCMP(buf, "text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020070 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020071
Bram Moolenaarb9644432016-07-19 12:33:44 +020072 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020073 STRCPY(buf, "a short text");
74 trunc_string(buf, buf, 20, 40);
75 assert(STRCMP(buf, "a short text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020076 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020077
Bram Moolenaarb9644432016-07-19 12:33:44 +020078 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020079 STRCPY(buf, "a text tha just fits");
80 trunc_string(buf, buf, 20, 40);
81 assert(STRCMP(buf, "a text tha just fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020082 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020083
Bram Moolenaarb9644432016-07-19 12:33:44 +020084 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020085 STRCPY(buf, "a text that nott fits");
86 trunc_string(buf, buf, 20, 40);
87 assert(STRCMP(buf, "a text t...nott fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020088 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020089
Bram Moolenaar85a20022019-12-21 18:25:54 +010090 // copy from string to buf
Bram Moolenaarb9644432016-07-19 12:33:44 +020091 buf = alloc(40);
92 s = vim_strsave((char_u *)"text");
93 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020094 assert(STRCMP(buf, "text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020095 vim_free(buf);
96 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020097
Bram Moolenaarb9644432016-07-19 12:33:44 +020098 buf = alloc(40);
99 s = vim_strsave((char_u *)"a text that fits");
100 trunc_string(s, buf, 34, 40);
101 assert(STRCMP(buf, "a text that fits") == 0);
102 vim_free(buf);
103 vim_free(s);
104
105 buf = alloc(40);
106 s = vim_strsave((char_u *)"a short text");
107 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200108 assert(STRCMP(buf, "a short text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200109 vim_free(buf);
110 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200111
Bram Moolenaarb9644432016-07-19 12:33:44 +0200112 buf = alloc(40);
113 s = vim_strsave((char_u *)"a text tha just fits");
114 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200115 assert(STRCMP(buf, "a text tha just fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200116 vim_free(buf);
117 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200118
Bram Moolenaarb9644432016-07-19 12:33:44 +0200119 buf = alloc(40);
120 s = vim_strsave((char_u *)"a text that nott fits");
121 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200122 assert(STRCMP(buf, "a text t...nott fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200123 vim_free(buf);
124 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200125}
126
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100127/*
Ralf Schandlbc869872021-05-28 14:12:14 +0200128 * Test trunc_string() with mbyte chars.
129 */
130 static void
131test_trunc_string_mbyte(void)
132{
133 char_u *buf; // allocated every time to find uninit errors
134 char_u *s;
135
136 buf = alloc(40);
137 s = vim_strsave((char_u *)"Ä text tha just fits");
138 trunc_string(s, buf, 20, 40);
139 assert(STRCMP(buf, "Ä text tha just fits") == 0);
140 vim_free(buf);
141 vim_free(s);
142
143 buf = alloc(40);
144 s = vim_strsave((char_u *)"a text ÄÖÜä nott fits");
145 trunc_string(s, buf, 20, 40);
146 assert(STRCMP(buf, "a text Ä...nott fits") == 0);
147 vim_free(buf);
148 vim_free(s);
149
150 buf = alloc(40);
151 s = vim_strsave((char_u *)"a text that not fitsÄ");
152 trunc_string(s, buf, 20, 40);
153 assert(STRCMP(buf, "a text t...not fitsÄ") == 0);
154 vim_free(buf);
155 vim_free(s);
156}
157
158/*
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100159 * Test vim_snprintf() with a focus on checking that truncation is
160 * correct when buffer is small, since it cannot be tested from
Hirohito Higashifbe4a8f2025-04-27 15:28:30 +0200161 * Vim script tests. Check that:
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100162 * - no buffer overflows happens (with valgrind or asan)
163 * - output string is always NUL terminated.
164 *
165 * Not all formats of vim_snprintf() are checked here. They are
Hirohito Higashifbe4a8f2025-04-27 15:28:30 +0200166 * checked more exhaustively in Test_printf*() Vim script tests.
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100167 */
168 static void
169test_vim_snprintf(void)
170{
171 int n;
172 size_t bsize;
173 int bsize_int;
Bram Moolenaar4da6df42020-04-20 16:12:09 +0200174 void *ptr = (void *)0x87654321;
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100175
176 // Loop on various buffer sizes to make sure that truncation of
177 // vim_snprintf() is correct.
178 for (bsize = 0; bsize < 15; ++bsize)
179 {
180 bsize_int = (int)bsize - 1;
181
182 // buf is the heap rather than in the stack
183 // so valgrind can detect buffer overflows if any.
184 // Use malloc() rather than alloc() as test checks with 0-size
185 // buffer and its content should then never be used.
186 char *buf = malloc(bsize);
187
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200188 n = vim_snprintf(buf, bsize, "%.8g", 10000000.1);
189 assert(n == 12);
190 assert(bsize == 0 || STRNCMP(buf, "1.00000001e7", bsize_int) == 0);
191 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
192
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100193 n = vim_snprintf(buf, bsize, "%d", 1234567);
194 assert(n == 7);
195 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
196 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
197
198 n = vim_snprintf(buf, bsize, "%ld", 1234567L);
199 assert(n == 7);
200 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
201 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
202
203 n = vim_snprintf(buf, bsize, "%9ld", 1234567L);
204 assert(n == 9);
205 assert(bsize == 0 || STRNCMP(buf, " 1234567", bsize_int) == 0);
206 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
207
208 n = vim_snprintf(buf, bsize, "%-9ld", 1234567L);
209 assert(n == 9);
210 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
211 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
212
213 n = vim_snprintf(buf, bsize, "%x", 0xdeadbeef);
214 assert(n == 8);
215 assert(bsize == 0 || STRNCMP(buf, "deadbeef", bsize_int) == 0);
216 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
217
Bram Moolenaar1470dc32020-01-14 22:02:14 +0100218 n = vim_snprintf(buf, bsize, fmt_06b, (uvarnumber_T)12);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100219 assert(n == 6);
220 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
221 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
222
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200223 n = vim_snprintf(buf, bsize, "%s %s", "one", "two");
224 assert(n == 7);
225 assert(bsize == 0 || STRNCMP(buf, "one two", bsize_int) == 0);
226 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
227
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100228 n = vim_snprintf(buf, bsize, "%f", 1.234);
229 assert(n == 8);
230 assert(bsize == 0 || STRNCMP(buf, "1.234000", bsize_int) == 0);
231 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
232
233 n = vim_snprintf(buf, bsize, "%e", 1.234);
234 assert(n == 12);
235 assert(bsize == 0 || STRNCMP(buf, "1.234000e+00", bsize_int) == 0);
236 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
237
238 n = vim_snprintf(buf, bsize, "%f", 0.0/0.0);
239 assert(n == 3);
240 assert(bsize == 0 || STRNCMP(buf, "nan", bsize_int) == 0);
241 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
242
243 n = vim_snprintf(buf, bsize, "%f", 1.0/0.0);
244 assert(n == 3);
245 assert(bsize == 0 || STRNCMP(buf, "inf", bsize_int) == 0);
246 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
247
248 n = vim_snprintf(buf, bsize, "%f", -1.0/0.0);
249 assert(n == 4);
250 assert(bsize == 0 || STRNCMP(buf, "-inf", bsize_int) == 0);
251 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
252
253 n = vim_snprintf(buf, bsize, "%f", -0.0);
254 assert(n == 9);
255 assert(bsize == 0 || STRNCMP(buf, "-0.000000", bsize_int) == 0);
256 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100257
258 n = vim_snprintf(buf, bsize, "%s", "漢語");
259 assert(n == 6);
260 assert(bsize == 0 || STRNCMP(buf, "漢語", bsize_int) == 0);
261 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
262
263 n = vim_snprintf(buf, bsize, "%8s", "漢語");
264 assert(n == 8);
265 assert(bsize == 0 || STRNCMP(buf, " 漢語", bsize_int) == 0);
266 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
267
268 n = vim_snprintf(buf, bsize, "%-8s", "漢語");
269 assert(n == 8);
270 assert(bsize == 0 || STRNCMP(buf, "漢語 ", bsize_int) == 0);
271 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
272
273 n = vim_snprintf(buf, bsize, "%.3s", "漢語");
274 assert(n == 3);
275 assert(bsize == 0 || STRNCMP(buf, "漢", bsize_int) == 0);
276 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
277
278 n = vim_snprintf(buf, bsize, fmt_5S, "foo");
279 assert(n == 5);
280 assert(bsize == 0 || STRNCMP(buf, " foo", bsize_int) == 0);
281 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
282
283 n = vim_snprintf(buf, bsize, "%%%%%%");
284 assert(n == 3);
285 assert(bsize == 0 || STRNCMP(buf, "%%%", bsize_int) == 0);
286 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
287
288 n = vim_snprintf(buf, bsize, "%c%c", 1, 2);
289 assert(n == 2);
290 assert(bsize == 0 || STRNCMP(buf, "\x01\x02", bsize_int) == 0);
291 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
292
Hirohito Higashifbe4a8f2025-04-27 15:28:30 +0200293 // %p format is not tested in Vim script tests Test_printf*()
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100294 // as it only makes sense in C code.
Bram Moolenaard5b99142020-02-08 17:14:46 +0100295 // NOTE: SunOS libc doesn't use the prefix "0x" on %p.
296#ifdef SUN_SYSTEM
297# define PREFIX_LEN 0
298# define PREFIX_STR1 ""
299# define PREFIX_STR2 "00"
300#else
301# define PREFIX_LEN 2
302# define PREFIX_STR1 "0x"
303# define PREFIX_STR2 "0x"
304#endif
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100305 n = vim_snprintf(buf, bsize, "%p", ptr);
Bram Moolenaard5b99142020-02-08 17:14:46 +0100306 assert(n == 8 + PREFIX_LEN);
307 assert(bsize == 0
308 || STRNCMP(buf, PREFIX_STR1 "87654321", bsize_int) == 0);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100309 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
310
311 n = vim_snprintf(buf, bsize, fmt_012p, ptr);
312 assert(n == 12);
Bram Moolenaard5b99142020-02-08 17:14:46 +0100313 assert(bsize == 0
314 || STRNCMP(buf, PREFIX_STR2 "0087654321", bsize_int) == 0);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100315 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
316
317 free(buf);
318 }
319}
320
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200321/*
322 * Test vim_snprintf() with a focus on checking that positional
323 * arguments are correctly applied and skipped
324 */
325 static void
326test_vim_snprintf_positional(void)
327{
328 int n;
329 size_t bsize;
330 int bsize_int;
331
332 // Loop on various buffer sizes to make sure that truncation of
333 // vim_snprintf() is correct.
334 for (bsize = 0; bsize < 25; ++bsize)
335 {
336 bsize_int = (int)bsize - 1;
337
338 // buf is the heap rather than in the stack
339 // so valgrind can detect buffer overflows if any.
340 // Use malloc() rather than alloc() as test checks with 0-size
341 // buffer and its content should then never be used.
342 char *buf = malloc(bsize);
343
344 n = vim_snprintf(buf, bsize, "%1$*2$ld", 1234567L, -9);
345 assert(n == 9);
346 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
347 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
348
349 n = vim_snprintf(buf, bsize, "%1$*2$.*3$ld", 1234567L, -9, 5);
350 assert(n == 9);
351 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
352 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
353
354 n = vim_snprintf(buf, bsize, "%1$*3$.*2$ld", 1234567L, 5, -9);
355 assert(n == 9);
356 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
357 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
358
359 n = vim_snprintf(buf, bsize, "%3$*1$.*2$ld", -9, 5, 1234567L);
360 assert(n == 9);
361 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
362 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
363
364 n = vim_snprintf(buf, bsize, "%1$ld", 1234567L);
365 assert(n == 7);
366 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
367 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
368
369 n = vim_snprintf(buf, bsize, "%1$*2$ld", 1234567L, 9);
370 assert(n == 9);
371 assert(bsize == 0 || STRNCMP(buf, " 1234567", bsize_int) == 0);
372 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
373
374 n = vim_snprintf(buf, bsize, "%2$ld %1$d %3$lu", 12345, 9L, 7654321UL);
375 assert(n == 15);
376 assert(bsize == 0 || STRNCMP(buf, "9 12345 7654321", bsize_int) == 0);
377 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
378
379 n = vim_snprintf(buf, bsize, "%2$d %1$ld %3$lu", 1234567L, 9, 7654321UL);
380 assert(n == 17);
381 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
382 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
383
384 n = vim_snprintf(buf, bsize, "%2$d %1$lld %3$lu", 1234567LL, 9, 7654321UL);
385 assert(n == 17);
386 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
387 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
388
389 n = vim_snprintf(buf, bsize, "%2$ld %1$u %3$lu", 12345U, 9L, 7654321UL);
390 assert(n == 15);
391 assert(bsize == 0 || STRNCMP(buf, "9 12345 7654321", bsize_int) == 0);
392 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
393
394 n = vim_snprintf(buf, bsize, "%2$d %1$lu %3$lu", 1234567UL, 9, 7654321UL);
395 assert(n == 17);
396 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
397 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
398
399 n = vim_snprintf(buf, bsize, "%2$d %1$llu %3$lu", 1234567LLU, 9, 7654321UL);
400 assert(n == 17);
401 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
402 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
403
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200404 n = vim_snprintf(buf, bsize, "%2$d %1$x %3$lu", 0xdeadbeef, 9, 7654321UL);
405 assert(n == 18);
406 assert(bsize == 0 || STRNCMP(buf, "9 deadbeef 7654321", bsize_int) == 0);
407 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
408
409 n = vim_snprintf(buf, bsize, "%2$ld %1$c %3$lu", 'c', 9L, 7654321UL);
410 assert(n == 11);
411 assert(bsize == 0 || STRNCMP(buf, "9 c 7654321", bsize_int) == 0);
412 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
413
414 n = vim_snprintf(buf, bsize, "%2$ld %1$s %3$lu", "hi", 9L, 7654321UL);
415 assert(n == 12);
416 assert(bsize == 0 || STRNCMP(buf, "9 hi 7654321", bsize_int) == 0);
417 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
418
419 n = vim_snprintf(buf, bsize, "%2$ld %1$e %3$lu", 0.0, 9L, 7654321UL);
420 assert(n == 22);
421 assert(bsize == 0 || STRNCMP(buf, "9 0.000000e+00 7654321", bsize_int) == 0);
422 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
423
424 n = vim_snprintf(buf, bsize, fmt_212s, "one", "two", "three");
425 assert(n == 11);
426 assert(bsize == 0 || STRNCMP(buf, "two one two", bsize_int) == 0);
427 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
428
429 n = vim_snprintf(buf, bsize, "%3$s %1$s %2$s", "one", "two", "three");
430 assert(n == 13);
431 assert(bsize == 0 || STRNCMP(buf, "three one two", bsize_int) == 0);
432 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
433
434 n = vim_snprintf(buf, bsize, "%1$d", 1234567);
435 assert(n == 7);
436 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
437 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
438
439 n = vim_snprintf(buf, bsize, "%1$x", 0xdeadbeef);
440 assert(n == 8);
441 assert(bsize == 0 || STRNCMP(buf, "deadbeef", bsize_int) == 0);
442 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
443
Christ van Willegenaa90d4f2023-09-03 17:22:37 +0200444 n = vim_snprintf(buf, bsize, fmt_06pb2, 6, (uvarnumber_T)12);
445 assert(n == 6);
446 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
447 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
448
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200449 n = vim_snprintf(buf, bsize, fmt_06pb, (uvarnumber_T)12, 6);
450 assert(n == 6);
451 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
452 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
453
454 n = vim_snprintf(buf, bsize, "%1$s %2$s", "one", "two");
455 assert(n == 7);
456 assert(bsize == 0 || STRNCMP(buf, "one two", bsize_int) == 0);
457 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
458
459 n = vim_snprintf(buf, bsize, fmt_06b, (uvarnumber_T)12);
460 assert(n == 6);
461 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
462 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
463
464 n = vim_snprintf(buf, bsize, fmt_21s, "one", "two", "three");
465 assert(n == 7);
466 assert(bsize == 0 || STRNCMP(buf, "two one", bsize_int) == 0);
467 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
468
469#ifdef FEAT_FLOAT
470 n = vim_snprintf(buf, bsize, "%1$f", 1.234);
471 assert(n == 8);
472 assert(bsize == 0 || STRNCMP(buf, "1.234000", bsize_int) == 0);
473 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
474
475 n = vim_snprintf(buf, bsize, "%1$e", 1.234);
476 assert(n == 12);
477 assert(bsize == 0 || STRNCMP(buf, "1.234000e+00", bsize_int) == 0);
478 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
479
480 n = vim_snprintf(buf, bsize, "%1$f", 0.0/0.0);
481 assert(n == 3);
482 assert(bsize == 0 || STRNCMP(buf, "nan", bsize_int) == 0);
483 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
484
485 n = vim_snprintf(buf, bsize, "%1$f", 1.0/0.0);
486 assert(n == 3);
487 assert(bsize == 0 || STRNCMP(buf, "inf", bsize_int) == 0);
488 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
489
490 n = vim_snprintf(buf, bsize, "%1$f", -1.0/0.0);
491 assert(n == 4);
492 assert(bsize == 0 || STRNCMP(buf, "-inf", bsize_int) == 0);
493 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
494
495 n = vim_snprintf(buf, bsize, "%1$f", -0.0);
496 assert(n == 9);
497 assert(bsize == 0 || STRNCMP(buf, "-0.000000", bsize_int) == 0);
498 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
499#endif
500
501 free(buf);
502 }
503}
504
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200505 int
506main(int argc, char **argv)
507{
Bram Moolenaara80faa82020-04-12 19:37:17 +0200508 CLEAR_FIELD(params);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200509 params.argc = argc;
510 params.argv = argv;
Hirohito Higashic5654b82025-02-10 20:55:17 +0100511 common_init_1();
512 common_init_2(&params);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200513
Bram Moolenaar31e5c602022-04-15 13:53:33 +0100514 set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"utf-8", 0);
Bram Moolenaard0337e32019-12-30 17:55:34 +0100515 init_chartab();
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200516 test_trunc_string();
Ralf Schandlbc869872021-05-28 14:12:14 +0200517 test_trunc_string_mbyte();
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100518 test_vim_snprintf();
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200519 test_vim_snprintf_positional();
Bram Moolenaard0337e32019-12-30 17:55:34 +0100520
Bram Moolenaar31e5c602022-04-15 13:53:33 +0100521 set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"latin1", 0);
Bram Moolenaard0337e32019-12-30 17:55:34 +0100522 init_chartab();
523 test_trunc_string();
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100524 test_vim_snprintf();
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200525 test_vim_snprintf_positional();
Bram Moolenaard0337e32019-12-30 17:55:34 +0100526
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200527 return 0;
528}