blob: e5fd5623056c26005f07bd1df7c37353182c734f [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//
37// These formats are in practise only used from vim script printf()
38// 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";
43char *fmt_212s = "%2$s %1$s %2$s";
44char *fmt_21s = "%2$s %1$s";
Bram Moolenaard2c946b2019-12-31 19:24:51 +010045
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020046/*
47 * Test trunc_string().
48 */
49 static void
50test_trunc_string(void)
51{
Bram Moolenaarb9644432016-07-19 12:33:44 +020052 char_u *buf; /*allocated every time to find uninit errors */
53 char_u *s;
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020054
Bram Moolenaar62818152021-02-14 15:37:30 +010055 // Should not write anything to destination if buflen is 0.
56 trunc_string((char_u *)"", NULL, 1, 0);
57
58 // Truncating an empty string does nothing.
59 buf = alloc(1);
60 trunc_string((char_u *)"", buf, 1, 1);
61 assert(buf[0] == NUL);
62 vim_free(buf);
63
Bram Moolenaar85a20022019-12-21 18:25:54 +010064 // in place
Bram Moolenaarb9644432016-07-19 12:33:44 +020065 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020066 STRCPY(buf, "text");
67 trunc_string(buf, buf, 20, 40);
68 assert(STRCMP(buf, "text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020069 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020070
Bram Moolenaarb9644432016-07-19 12:33:44 +020071 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020072 STRCPY(buf, "a short text");
73 trunc_string(buf, buf, 20, 40);
74 assert(STRCMP(buf, "a short text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020075 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020076
Bram Moolenaarb9644432016-07-19 12:33:44 +020077 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020078 STRCPY(buf, "a text tha just fits");
79 trunc_string(buf, buf, 20, 40);
80 assert(STRCMP(buf, "a text tha just fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020081 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020082
Bram Moolenaarb9644432016-07-19 12:33:44 +020083 buf = alloc(40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020084 STRCPY(buf, "a text that nott fits");
85 trunc_string(buf, buf, 20, 40);
86 assert(STRCMP(buf, "a text t...nott fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020087 vim_free(buf);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020088
Bram Moolenaar85a20022019-12-21 18:25:54 +010089 // copy from string to buf
Bram Moolenaarb9644432016-07-19 12:33:44 +020090 buf = alloc(40);
91 s = vim_strsave((char_u *)"text");
92 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020093 assert(STRCMP(buf, "text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +020094 vim_free(buf);
95 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +020096
Bram Moolenaarb9644432016-07-19 12:33:44 +020097 buf = alloc(40);
98 s = vim_strsave((char_u *)"a text that fits");
99 trunc_string(s, buf, 34, 40);
100 assert(STRCMP(buf, "a text that fits") == 0);
101 vim_free(buf);
102 vim_free(s);
103
104 buf = alloc(40);
105 s = vim_strsave((char_u *)"a short text");
106 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200107 assert(STRCMP(buf, "a short text") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200108 vim_free(buf);
109 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200110
Bram Moolenaarb9644432016-07-19 12:33:44 +0200111 buf = alloc(40);
112 s = vim_strsave((char_u *)"a text tha just fits");
113 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200114 assert(STRCMP(buf, "a text tha just fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200115 vim_free(buf);
116 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200117
Bram Moolenaarb9644432016-07-19 12:33:44 +0200118 buf = alloc(40);
119 s = vim_strsave((char_u *)"a text that nott fits");
120 trunc_string(s, buf, 20, 40);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200121 assert(STRCMP(buf, "a text t...nott fits") == 0);
Bram Moolenaarb9644432016-07-19 12:33:44 +0200122 vim_free(buf);
123 vim_free(s);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200124}
125
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100126/*
Ralf Schandlbc869872021-05-28 14:12:14 +0200127 * Test trunc_string() with mbyte chars.
128 */
129 static void
130test_trunc_string_mbyte(void)
131{
132 char_u *buf; // allocated every time to find uninit errors
133 char_u *s;
134
135 buf = alloc(40);
136 s = vim_strsave((char_u *)"Ä text tha just fits");
137 trunc_string(s, buf, 20, 40);
138 assert(STRCMP(buf, "Ä text tha just fits") == 0);
139 vim_free(buf);
140 vim_free(s);
141
142 buf = alloc(40);
143 s = vim_strsave((char_u *)"a text ÄÖÜä nott fits");
144 trunc_string(s, buf, 20, 40);
145 assert(STRCMP(buf, "a text Ä...nott fits") == 0);
146 vim_free(buf);
147 vim_free(s);
148
149 buf = alloc(40);
150 s = vim_strsave((char_u *)"a text that not fitsÄ");
151 trunc_string(s, buf, 20, 40);
152 assert(STRCMP(buf, "a text t...not fitsÄ") == 0);
153 vim_free(buf);
154 vim_free(s);
155}
156
157/*
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100158 * Test vim_snprintf() with a focus on checking that truncation is
159 * correct when buffer is small, since it cannot be tested from
dundargocc57b5bc2022-11-02 13:30:51 +0000160 * vim script tests. Check that:
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100161 * - no buffer overflows happens (with valgrind or asan)
162 * - output string is always NUL terminated.
163 *
164 * Not all formats of vim_snprintf() are checked here. They are
165 * checked more exhaustively in Test_printf*() vim script tests.
166 */
167 static void
168test_vim_snprintf(void)
169{
170 int n;
171 size_t bsize;
172 int bsize_int;
Bram Moolenaar4da6df42020-04-20 16:12:09 +0200173 void *ptr = (void *)0x87654321;
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100174
175 // Loop on various buffer sizes to make sure that truncation of
176 // vim_snprintf() is correct.
177 for (bsize = 0; bsize < 15; ++bsize)
178 {
179 bsize_int = (int)bsize - 1;
180
181 // buf is the heap rather than in the stack
182 // so valgrind can detect buffer overflows if any.
183 // Use malloc() rather than alloc() as test checks with 0-size
184 // buffer and its content should then never be used.
185 char *buf = malloc(bsize);
186
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200187 n = vim_snprintf(buf, bsize, "%.8g", 10000000.1);
188 assert(n == 12);
189 assert(bsize == 0 || STRNCMP(buf, "1.00000001e7", bsize_int) == 0);
190 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
191
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100192 n = vim_snprintf(buf, bsize, "%d", 1234567);
193 assert(n == 7);
194 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
195 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
196
197 n = vim_snprintf(buf, bsize, "%ld", 1234567L);
198 assert(n == 7);
199 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
200 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
201
202 n = vim_snprintf(buf, bsize, "%9ld", 1234567L);
203 assert(n == 9);
204 assert(bsize == 0 || STRNCMP(buf, " 1234567", bsize_int) == 0);
205 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
206
207 n = vim_snprintf(buf, bsize, "%-9ld", 1234567L);
208 assert(n == 9);
209 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
210 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
211
212 n = vim_snprintf(buf, bsize, "%x", 0xdeadbeef);
213 assert(n == 8);
214 assert(bsize == 0 || STRNCMP(buf, "deadbeef", bsize_int) == 0);
215 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
216
Bram Moolenaar1470dc32020-01-14 22:02:14 +0100217 n = vim_snprintf(buf, bsize, fmt_06b, (uvarnumber_T)12);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100218 assert(n == 6);
219 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
220 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
221
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200222 n = vim_snprintf(buf, bsize, "%s %s", "one", "two");
223 assert(n == 7);
224 assert(bsize == 0 || STRNCMP(buf, "one two", bsize_int) == 0);
225 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
226
227#ifdef FEAT_FLOAT
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');
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200257#endif
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100258
259 n = vim_snprintf(buf, bsize, "%s", "漢語");
260 assert(n == 6);
261 assert(bsize == 0 || STRNCMP(buf, "漢語", bsize_int) == 0);
262 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
263
264 n = vim_snprintf(buf, bsize, "%8s", "漢語");
265 assert(n == 8);
266 assert(bsize == 0 || STRNCMP(buf, " 漢語", bsize_int) == 0);
267 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
268
269 n = vim_snprintf(buf, bsize, "%-8s", "漢語");
270 assert(n == 8);
271 assert(bsize == 0 || STRNCMP(buf, "漢語 ", bsize_int) == 0);
272 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
273
274 n = vim_snprintf(buf, bsize, "%.3s", "漢語");
275 assert(n == 3);
276 assert(bsize == 0 || STRNCMP(buf, "漢", bsize_int) == 0);
277 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
278
279 n = vim_snprintf(buf, bsize, fmt_5S, "foo");
280 assert(n == 5);
281 assert(bsize == 0 || STRNCMP(buf, " foo", bsize_int) == 0);
282 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
283
284 n = vim_snprintf(buf, bsize, "%%%%%%");
285 assert(n == 3);
286 assert(bsize == 0 || STRNCMP(buf, "%%%", bsize_int) == 0);
287 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
288
289 n = vim_snprintf(buf, bsize, "%c%c", 1, 2);
290 assert(n == 2);
291 assert(bsize == 0 || STRNCMP(buf, "\x01\x02", bsize_int) == 0);
292 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
293
294 // %p format is not tested in vim script tests Test_printf*()
295 // as it only makes sense in C code.
Bram Moolenaard5b99142020-02-08 17:14:46 +0100296 // NOTE: SunOS libc doesn't use the prefix "0x" on %p.
297#ifdef SUN_SYSTEM
298# define PREFIX_LEN 0
299# define PREFIX_STR1 ""
300# define PREFIX_STR2 "00"
301#else
302# define PREFIX_LEN 2
303# define PREFIX_STR1 "0x"
304# define PREFIX_STR2 "0x"
305#endif
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100306 n = vim_snprintf(buf, bsize, "%p", ptr);
Bram Moolenaard5b99142020-02-08 17:14:46 +0100307 assert(n == 8 + PREFIX_LEN);
308 assert(bsize == 0
309 || STRNCMP(buf, PREFIX_STR1 "87654321", bsize_int) == 0);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100310 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
311
312 n = vim_snprintf(buf, bsize, fmt_012p, ptr);
313 assert(n == 12);
Bram Moolenaard5b99142020-02-08 17:14:46 +0100314 assert(bsize == 0
315 || STRNCMP(buf, PREFIX_STR2 "0087654321", bsize_int) == 0);
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100316 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
317
318 free(buf);
319 }
320}
321
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200322/*
323 * Test vim_snprintf() with a focus on checking that positional
324 * arguments are correctly applied and skipped
325 */
326 static void
327test_vim_snprintf_positional(void)
328{
329 int n;
330 size_t bsize;
331 int bsize_int;
332
333 // Loop on various buffer sizes to make sure that truncation of
334 // vim_snprintf() is correct.
335 for (bsize = 0; bsize < 25; ++bsize)
336 {
337 bsize_int = (int)bsize - 1;
338
339 // buf is the heap rather than in the stack
340 // so valgrind can detect buffer overflows if any.
341 // Use malloc() rather than alloc() as test checks with 0-size
342 // buffer and its content should then never be used.
343 char *buf = malloc(bsize);
344
345 n = vim_snprintf(buf, bsize, "%1$*2$ld", 1234567L, -9);
346 assert(n == 9);
347 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
348 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
349
350 n = vim_snprintf(buf, bsize, "%1$*2$.*3$ld", 1234567L, -9, 5);
351 assert(n == 9);
352 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
353 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
354
355 n = vim_snprintf(buf, bsize, "%1$*3$.*2$ld", 1234567L, 5, -9);
356 assert(n == 9);
357 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
358 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
359
360 n = vim_snprintf(buf, bsize, "%3$*1$.*2$ld", -9, 5, 1234567L);
361 assert(n == 9);
362 assert(bsize == 0 || STRNCMP(buf, "1234567 ", bsize_int) == 0);
363 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
364
365 n = vim_snprintf(buf, bsize, "%1$ld", 1234567L);
366 assert(n == 7);
367 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
368 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
369
370 n = vim_snprintf(buf, bsize, "%1$*2$ld", 1234567L, 9);
371 assert(n == 9);
372 assert(bsize == 0 || STRNCMP(buf, " 1234567", bsize_int) == 0);
373 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
374
375 n = vim_snprintf(buf, bsize, "%2$ld %1$d %3$lu", 12345, 9L, 7654321UL);
376 assert(n == 15);
377 assert(bsize == 0 || STRNCMP(buf, "9 12345 7654321", bsize_int) == 0);
378 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
379
380 n = vim_snprintf(buf, bsize, "%2$d %1$ld %3$lu", 1234567L, 9, 7654321UL);
381 assert(n == 17);
382 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
383 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
384
385 n = vim_snprintf(buf, bsize, "%2$d %1$lld %3$lu", 1234567LL, 9, 7654321UL);
386 assert(n == 17);
387 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
388 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
389
390 n = vim_snprintf(buf, bsize, "%2$ld %1$u %3$lu", 12345U, 9L, 7654321UL);
391 assert(n == 15);
392 assert(bsize == 0 || STRNCMP(buf, "9 12345 7654321", bsize_int) == 0);
393 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
394
395 n = vim_snprintf(buf, bsize, "%2$d %1$lu %3$lu", 1234567UL, 9, 7654321UL);
396 assert(n == 17);
397 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
398 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
399
400 n = vim_snprintf(buf, bsize, "%2$d %1$llu %3$lu", 1234567LLU, 9, 7654321UL);
401 assert(n == 17);
402 assert(bsize == 0 || STRNCMP(buf, "9 1234567 7654321", bsize_int) == 0);
403 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
404
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200405 n = vim_snprintf(buf, bsize, "%2$d %1$x %3$lu", 0xdeadbeef, 9, 7654321UL);
406 assert(n == 18);
407 assert(bsize == 0 || STRNCMP(buf, "9 deadbeef 7654321", bsize_int) == 0);
408 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
409
410 n = vim_snprintf(buf, bsize, "%2$ld %1$c %3$lu", 'c', 9L, 7654321UL);
411 assert(n == 11);
412 assert(bsize == 0 || STRNCMP(buf, "9 c 7654321", bsize_int) == 0);
413 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
414
415 n = vim_snprintf(buf, bsize, "%2$ld %1$s %3$lu", "hi", 9L, 7654321UL);
416 assert(n == 12);
417 assert(bsize == 0 || STRNCMP(buf, "9 hi 7654321", bsize_int) == 0);
418 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
419
420 n = vim_snprintf(buf, bsize, "%2$ld %1$e %3$lu", 0.0, 9L, 7654321UL);
421 assert(n == 22);
422 assert(bsize == 0 || STRNCMP(buf, "9 0.000000e+00 7654321", bsize_int) == 0);
423 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
424
425 n = vim_snprintf(buf, bsize, fmt_212s, "one", "two", "three");
426 assert(n == 11);
427 assert(bsize == 0 || STRNCMP(buf, "two one two", bsize_int) == 0);
428 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
429
430 n = vim_snprintf(buf, bsize, "%3$s %1$s %2$s", "one", "two", "three");
431 assert(n == 13);
432 assert(bsize == 0 || STRNCMP(buf, "three one two", bsize_int) == 0);
433 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
434
435 n = vim_snprintf(buf, bsize, "%1$d", 1234567);
436 assert(n == 7);
437 assert(bsize == 0 || STRNCMP(buf, "1234567", bsize_int) == 0);
438 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
439
440 n = vim_snprintf(buf, bsize, "%1$x", 0xdeadbeef);
441 assert(n == 8);
442 assert(bsize == 0 || STRNCMP(buf, "deadbeef", bsize_int) == 0);
443 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
444
445 n = vim_snprintf(buf, bsize, fmt_06pb, (uvarnumber_T)12, 6);
446 assert(n == 6);
447 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
448 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
449
450 n = vim_snprintf(buf, bsize, "%1$s %2$s", "one", "two");
451 assert(n == 7);
452 assert(bsize == 0 || STRNCMP(buf, "one two", bsize_int) == 0);
453 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
454
455 n = vim_snprintf(buf, bsize, fmt_06b, (uvarnumber_T)12);
456 assert(n == 6);
457 assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
458 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
459
460 n = vim_snprintf(buf, bsize, fmt_21s, "one", "two", "three");
461 assert(n == 7);
462 assert(bsize == 0 || STRNCMP(buf, "two one", bsize_int) == 0);
463 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
464
465#ifdef FEAT_FLOAT
466 n = vim_snprintf(buf, bsize, "%1$f", 1.234);
467 assert(n == 8);
468 assert(bsize == 0 || STRNCMP(buf, "1.234000", bsize_int) == 0);
469 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
470
471 n = vim_snprintf(buf, bsize, "%1$e", 1.234);
472 assert(n == 12);
473 assert(bsize == 0 || STRNCMP(buf, "1.234000e+00", bsize_int) == 0);
474 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
475
476 n = vim_snprintf(buf, bsize, "%1$f", 0.0/0.0);
477 assert(n == 3);
478 assert(bsize == 0 || STRNCMP(buf, "nan", bsize_int) == 0);
479 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
480
481 n = vim_snprintf(buf, bsize, "%1$f", 1.0/0.0);
482 assert(n == 3);
483 assert(bsize == 0 || STRNCMP(buf, "inf", bsize_int) == 0);
484 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
485
486 n = vim_snprintf(buf, bsize, "%1$f", -1.0/0.0);
487 assert(n == 4);
488 assert(bsize == 0 || STRNCMP(buf, "-inf", bsize_int) == 0);
489 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
490
491 n = vim_snprintf(buf, bsize, "%1$f", -0.0);
492 assert(n == 9);
493 assert(bsize == 0 || STRNCMP(buf, "-0.000000", bsize_int) == 0);
494 assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
495#endif
496
497 free(buf);
498 }
499}
500
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200501 int
502main(int argc, char **argv)
503{
Bram Moolenaara80faa82020-04-12 19:37:17 +0200504 CLEAR_FIELD(params);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200505 params.argc = argc;
506 params.argv = argv;
507 common_init(&params);
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200508
Bram Moolenaar31e5c602022-04-15 13:53:33 +0100509 set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"utf-8", 0);
Bram Moolenaard0337e32019-12-30 17:55:34 +0100510 init_chartab();
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200511 test_trunc_string();
Ralf Schandlbc869872021-05-28 14:12:14 +0200512 test_trunc_string_mbyte();
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100513 test_vim_snprintf();
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200514 test_vim_snprintf_positional();
Bram Moolenaard0337e32019-12-30 17:55:34 +0100515
Bram Moolenaar31e5c602022-04-15 13:53:33 +0100516 set_option_value_give_err((char_u *)"encoding", 0, (char_u *)"latin1", 0);
Bram Moolenaard0337e32019-12-30 17:55:34 +0100517 init_chartab();
518 test_trunc_string();
Bram Moolenaard2c946b2019-12-31 19:24:51 +0100519 test_vim_snprintf();
Christ van Willegen0c6181f2023-08-13 18:03:14 +0200520 test_vim_snprintf_positional();
Bram Moolenaard0337e32019-12-30 17:55:34 +0100521
Bram Moolenaar502ae4b2016-07-16 19:50:13 +0200522 return 0;
523}