1 /* test_sprintf.c - test various sprintf functionality */
2
3 /*
4 * Copyright (c) 2013-2014 Wind River Systems, Inc.
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 /*
10 * DESCRIPTION
11 * This module contains the code for testing sprintf() functionality.
12 */
13
14 #include <zephyr/ztest.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17
18 /**
19 *
20 * @brief Test implementation-defined constants library
21 * @defgroup libc_api
22 * @ingroup all_tests
23 * @{
24 *
25 */
26
27 #define DEADBEEF 0xdeadbeef
28
29 #define DEADBEEF_LHEX_ALT_STR "0xdeadbeef"
30 #define DEADBEEF_UHEX_ALT_STR "0XDEADBEEF"
31 #define DEADBEEF_LHEX_STR "deadbeef"
32 #define DEADBEEF_UHEX_STR "DEADBEEF"
33 #define DEADBEEF_UNSIGNED_STR "3735928559"
34 #define DEADBEEF_SIGNED_STR "-559038737"
35 #define DEADBEEF_OCTAL_STR "33653337357"
36 #define DEADBEEF_OCTAL_ALT_STR "033653337357"
37 #define DEADBEEF_PTR_STR "0xdeadbeef"
38
39 #define IS_MINIMAL_LIBC_NANO (IS_ENABLED(CONFIG_MINIMAL_LIBC) \
40 && IS_ENABLED(CONFIG_CBPRINTF_NANO))
41
42 #define IS_MINIMAL_LIBC_NOFP (IS_ENABLED(CONFIG_MINIMAL_LIBC) \
43 && !IS_ENABLED(CONFIG_CBPRINTF_FP_SUPPORT))
44
45 #define IS_PICOLIBC_NOFP (IS_ENABLED(CONFIG_PICOLIBC) \
46 && !IS_ENABLED(CONFIG_PICOLIBC_IO_FLOAT))
47
48 /*
49 * A really long string (330 characters + NULL).
50 * The underlying sprintf() architecture will truncate it.
51 */
52 #define REALLY_LONG_STRING \
53 "1111111111111111111111111111111111" \
54 "1111111111111111111111111111111" \
55 "22222222222222222222222222222222" \
56 "222222222222222222222222222222222" \
57 "333333333333333333333333333333333" \
58 "33333333333333333333333333333333" \
59 "44444444444444444444444444444444" \
60 "444444444444444444444444444444444" \
61 "555555555555555555555555555555555" \
62 "55555555555555555555555555555555" \
63 "66666666666666666666666666666666" \
64 "666666666666666666666666666666666"
65
66 #ifdef CONFIG_BIG_ENDIAN
67 union raw_double_u {
68 double d;
69 struct {
70 uint32_t fraction;
71 uint32_t exponent;
72 };
73 };
74 #else
75 union raw_double_u {
76 double d;
77 struct {
78 uint32_t exponent;
79 uint32_t fraction;
80 };
81 };
82 #endif
83
WriteFrmtd_vf(FILE * stream,char * format,...)84 static int WriteFrmtd_vf(FILE *stream, char *format, ...)
85 {
86 int ret;
87 va_list args;
88
89 va_start(args, format);
90 ret = vfprintf(stream, format, args);
91 va_end(args);
92
93 return ret;
94 }
95
96 /**
97 *
98 * @brief Test sprintf with doubles
99 *
100 */
101
102 #ifdef CONFIG_STDOUT_CONSOLE
ZTEST(sprintf,test_sprintf_double)103 ZTEST(sprintf, test_sprintf_double)
104 {
105 char buffer[400];
106 union raw_double_u var;
107
108
109 /* Conversion not supported with minimal_libc without
110 * CBPRINTF_FP_SUPPORT.
111 *
112 * Conversion not supported with picolibc without
113 * PICOLIBC_IO_FLOAT
114 *
115 */
116 if (IS_MINIMAL_LIBC_NOFP || IS_PICOLIBC_NOFP) {
117 ztest_test_skip();
118 return;
119 }
120
121 var.exponent = 0x00000000;
122 var.fraction = 0x7ff00000; /* Bit pattern for +INF (double) */
123 sprintf(buffer, "%e", var.d);
124 zassert_true((strcmp(buffer, "inf") == 0),
125 "sprintf(inf) - incorrect output '%s'\n", buffer);
126
127 sprintf(buffer, "%E", var.d);
128 zassert_true((strcmp(buffer, "INF") == 0),
129 "sprintf(INF) - incorrect output '%s'\n", buffer);
130
131 sprintf(buffer, "%f", var.d);
132 zassert_true((strcmp(buffer, "inf") == 0),
133 "sprintf(inf) - incorrect output '%s'\n", buffer);
134
135 sprintf(buffer, "%F", var.d);
136 zassert_true((strcmp(buffer, "INF") == 0),
137 "sprintf(INF) - incorrect output '%s'\n", buffer);
138
139 sprintf(buffer, "%g", var.d);
140 zassert_true((strcmp(buffer, "inf") == 0),
141 "sprintf(inf) - incorrect output '%s'\n", buffer);
142
143 sprintf(buffer, "%G", var.d);
144 zassert_true((strcmp(buffer, "INF") == 0),
145 "sprintf(INF) - incorrect output '%s'\n", buffer);
146
147 var.exponent = 0x00000000;
148 var.fraction = 0xfff00000; /* Bit pattern for -INF (double) */
149 sprintf(buffer, "%e", var.d);
150 zassert_true((strcmp(buffer, "-inf") == 0),
151 "sprintf(-INF) - incorrect output '%s'\n", buffer);
152
153 sprintf(buffer, "%E", var.d);
154 zassert_true((strcmp(buffer, "-INF") == 0),
155 "sprintf(-INF) - incorrect output '%s'\n", buffer);
156
157 sprintf(buffer, "%f", var.d);
158 zassert_true((strcmp(buffer, "-inf") == 0),
159 "sprintf(-INF) - incorrect output '%s'\n", buffer);
160
161 sprintf(buffer, "%F", var.d);
162 zassert_true((strcmp(buffer, "-INF") == 0),
163 "sprintf(-INF) - incorrect output '%s'\n", buffer);
164
165 sprintf(buffer, "%g", var.d);
166 zassert_true((strcmp(buffer, "-inf") == 0),
167 "sprintf(-INF) - incorrect output '%s'\n", buffer);
168
169 sprintf(buffer, "%G", var.d);
170 zassert_true((strcmp(buffer, "-INF") == 0),
171 "sprintf(-INF) - incorrect output '%s'\n", buffer);
172
173 sprintf(buffer, "%010f", var.d);
174 zassert_true((strcmp(buffer, " -inf") == 0),
175 "sprintf( +inf) - incorrect output '%s'\n", buffer);
176
177 var.exponent = 0x00000000;
178 var.fraction = 0x7ff80000; /* Bit pattern for NaN (double) */
179 sprintf(buffer, "%e", var.d);
180 zassert_true((strcmp(buffer, "nan") == 0),
181 "sprintf(nan) - incorrect output '%s'\n", buffer);
182
183 sprintf(buffer, "%E", var.d);
184 zassert_true((strcmp(buffer, "NAN") == 0),
185 "sprintf(NAN) - incorrect output '%s'\n", buffer);
186
187 sprintf(buffer, "%f", var.d);
188 zassert_true((strcmp(buffer, "nan") == 0),
189 "sprintf(nan) - incorrect output '%s'\n", buffer);
190
191 sprintf(buffer, "%F", var.d);
192 zassert_true((strcmp(buffer, "NAN") == 0),
193 "sprintf(NAN) - incorrect output '%s'\n", buffer);
194
195 sprintf(buffer, "%g", var.d);
196 zassert_true((strcmp(buffer, "nan") == 0),
197 "sprintf(nan) - incorrect output '%s'\n", buffer);
198
199 sprintf(buffer, "%G", var.d);
200 zassert_true((strcmp(buffer, "NAN") == 0),
201 "sprintf(NAN) - incorrect output '%s'\n", buffer);
202
203 sprintf(buffer, "%+8.5e", var.d);
204 zassert_true((strcmp(buffer, " +nan") == 0),
205 "sprintf( +nan) - incorrect output '%s'\n", buffer);
206
207 var.exponent = 0x00000000;
208 var.fraction = 0xfff80000; /* Bit pattern for -NaN (double) */
209 sprintf(buffer, "%e", var.d);
210 zassert_true((strcmp(buffer, "-nan") == 0),
211 "sprintf(-nan) - incorrect output '%s'\n", buffer);
212
213 sprintf(buffer, "%E", var.d);
214 zassert_true((strcmp(buffer, "-NAN") == 0),
215 "sprintf(-NAN) - incorrect output '%s'\n", buffer);
216
217 sprintf(buffer, "%f", var.d);
218 zassert_true((strcmp(buffer, "-nan") == 0),
219 "sprintf(-nan) - incorrect output '%s'\n", buffer);
220
221 sprintf(buffer, "%F", var.d);
222 zassert_true((strcmp(buffer, "-NAN") == 0),
223 "sprintf(-NAN) - incorrect output '%s'\n", buffer);
224
225 sprintf(buffer, "%g", var.d);
226 zassert_true((strcmp(buffer, "-nan") == 0),
227 "sprintf(-nan) - incorrect output '%s'\n", buffer);
228
229 sprintf(buffer, "%G", var.d);
230 zassert_true((strcmp(buffer, "-NAN") == 0),
231 "sprintf(-NAN) - incorrect output '%s'\n", buffer);
232
233 var.d = 1.0;
234 sprintf(buffer, "%f", var.d);
235 zassert_true((strcmp(buffer, "1.000000") == 0),
236 "sprintf(1.0) - incorrect output '%s'\n", buffer);
237
238 sprintf(buffer, "%+f", var.d);
239 zassert_true((strcmp(buffer, "+1.000000") == 0),
240 "sprintf(+1.0) - incorrect output '%s'\n", buffer);
241
242 sprintf(buffer, "%.2f", var.d);
243 zassert_true((strcmp(buffer, "1.00") == 0),
244 "sprintf(1.00) - incorrect output '%s'\n", buffer);
245
246 sprintf(buffer, "%.*f", 11, var.d);
247 zassert_true((strcmp(buffer, "1.00000000000") == 0),
248 "sprintf(1.00000000000) - incorrect "
249 "output '%s'\n", buffer);
250
251 sprintf(buffer, "%12f", var.d);
252 zassert_true((strcmp(buffer, " 1.000000") == 0),
253 "sprintf( 1.000000) - incorrect "
254 "output '%s'\n", buffer);
255
256 sprintf(buffer, "%-12f", var.d);
257 zassert_true((strcmp(buffer, "1.000000 ") == 0),
258 "sprintf(1.000000 ) - incorrect "
259 "output '%s'\n", buffer);
260
261 sprintf(buffer, "%012f", var.d);
262 zassert_true((strcmp(buffer, "00001.000000") == 0),
263 "sprintf(00001.000000) - incorrect "
264 "output '%s'\n", buffer);
265
266 var.d = -1.0;
267 sprintf(buffer, "%f", var.d);
268 zassert_true((strcmp(buffer, "-1.000000") == 0),
269 "sprintf(-1.0) - incorrect output '%s'\n", buffer);
270
271 var.d = 1234.56789;
272 sprintf(buffer, "%f", var.d);
273 zassert_true((strcmp(buffer, "1234.567890") == 0),
274 "sprintf(1234.56789) - incorrect output '%s'\n", buffer);
275
276 /*
277 * With very large precision, the output differs significantly in
278 * terms of string even if not in terms of actual value depending
279 * on the library used and FPU implementation. However the length
280 * and decimal position should remain identical.
281 */
282 var.d = 0x1p800;
283 sprintf(buffer, "%.140f", var.d);
284 zassert_true((strlen(buffer) == 382),
285 "sprintf(<large output>) - incorrect length %d\n",
286 strlen(buffer));
287 buffer[10] = 0; /* log facility doesn't support %.10s */
288 zassert_true((strcmp(buffer, "6668014432") == 0),
289 "sprintf(<large output>) - starts with \"%s\" "
290 "expected \"6668014432\"\n", buffer);
291 zassert_true((buffer[241] == '.'),
292 "sprintf(<large output>) - expected '.' got '%c'\n",
293 buffer[241]);
294
295 var.d = 0x1p-400;
296
297 /* 3.872E-121 expressed as " 0.0...387" */
298 sprintf(buffer, "% .380f", var.d);
299 zassert_true((strlen(buffer) == 383),
300 "sprintf(<large output>) - incorrect length %d\n",
301 strlen(buffer));
302 zassert_equal(strncmp(&buffer[119], "00003872", 8), 0,
303 "sprintf(<large output>) - misplaced value\n");
304 buffer[10] = 0; /* log facility doesn't support %.10s */
305 zassert_true((strcmp(buffer, " 0.0000000") == 0),
306 "sprintf(<large output>) - starts with \"%s\" "
307 "expected \" 0.0000000\"\n", buffer);
308 buffer[119 + 10] = 0; /* log facility doesn't support %.10s */
309 zassert_true((strcmp(buffer + 119, "0000387259") == 0),
310 "sprintf(<large output>) - got \"%s\" "
311 "while expecting \"0000387259\"\n", buffer + 119);
312
313 /*******************/
314 var.d = 1234.0;
315 sprintf(buffer, "%e", var.d);
316 zassert_true((strcmp(buffer, "1.234000e+03") == 0),
317 "sprintf(1.234000e+03) - incorrect "
318 "output '%s'\n", buffer);
319
320 sprintf(buffer, "%E", var.d);
321 zassert_true((strcmp(buffer, "1.234000E+03") == 0),
322 "sprintf(1.234000E+03) - incorrect "
323 "output '%s'\n", buffer);
324
325 /*******************/
326 var.d = 0.1234;
327 sprintf(buffer, "%e", var.d);
328 zassert_true((strcmp(buffer, "1.234000e-01") == 0),
329 "sprintf(1.234000e-01) - incorrect "
330 "output '%s'\n", buffer);
331
332 sprintf(buffer, "%E", var.d);
333 zassert_true((strcmp(buffer, "1.234000E-01") == 0),
334 "sprintf(1.234000E-01) - incorrect "
335 "output '%s'\n", buffer);
336
337 /*******************/
338 var.d = 1234000000.0;
339 sprintf(buffer, "%g", var.d);
340 zassert_true((strcmp(buffer, "1.234e+09") == 0),
341 "sprintf(1.234e+09) - incorrect "
342 "output '%s'\n", buffer);
343
344 sprintf(buffer, "%G", var.d);
345 zassert_true((strcmp(buffer, "1.234E+09") == 0),
346 "sprintf(1.234E+09) - incorrect "
347 "output '%s'\n", buffer);
348
349 var.d = 150.0;
350 sprintf(buffer, "%#.3g", var.d);
351 zassert_true((strcmp(buffer, "150.") == 0),
352 "sprintf(150.) - incorrect "
353 "output '%s'\n", buffer);
354
355 var.d = 150.1;
356 sprintf(buffer, "%.2g", var.d);
357 zassert_true((strcmp(buffer, "1.5e+02") == 0),
358 "sprintf(1.5e+02) - incorrect "
359 "output '%s'\n", buffer);
360
361 var.d = 150.567;
362 sprintf(buffer, "%.3g", var.d);
363 zassert_true((strcmp(buffer, "151") == 0),
364 "sprintf(151) - incorrect "
365 "output '%s'\n", buffer);
366
367 var.d = 15e-5;
368 sprintf(buffer, "%#.3g", var.d);
369 zassert_true((strcmp(buffer, "0.000150") == 0),
370 "sprintf(0.000150) - incorrect "
371 "output '%s'\n", buffer);
372
373 var.d = 1505e-7;
374 sprintf(buffer, "%.4g", var.d);
375 zassert_true((strcmp(buffer, "0.0001505") == 0),
376 "sprintf(0.0001505) - incorrect "
377 "output '%s'\n", buffer);
378
379 var.exponent = 0x00000001;
380 var.fraction = 0x00000000; /* smallest denormal value */
381 sprintf(buffer, "%g", var.d);
382 #ifdef CONFIG_PICOLIBC
383 zassert_true((strcmp(buffer, "5e-324") == 0),
384 "sprintf(5e-324) - incorrect "
385 "output '%s'\n", buffer);
386 #else
387 zassert_true((strcmp(buffer, "4.94066e-324") == 0),
388 "sprintf(4.94066e-324) - incorrect "
389 "output '%s'\n", buffer);
390 #endif
391 }
392
393 /**
394 * @brief A test wrapper for vsnprintf()
395 */
tvsnprintf(char * s,size_t len,const char * format,...)396 int tvsnprintf(char *s, size_t len, const char *format, ...)
397 {
398 va_list vargs;
399 int r;
400
401 va_start(vargs, format);
402 r = vsnprintf(s, len, format, vargs);
403 va_end(vargs);
404
405 return r;
406 }
407
408 /**
409 *
410 * @brief Test the vsprintf() routine
411 *
412 * This routine does not aim to test the same underlying functionality as
413 * sprintfTest(). Instead it tries to limit it to functionality specific to
414 * vsnprintf(). Instead of calling vsnprintf() directly, it invokes the wrapper
415 * routine tvsnprintf().
416 *
417 */
418
ZTEST(sprintf,test_vsnprintf)419 ZTEST(sprintf, test_vsnprintf)
420 {
421 int len;
422 char buffer[100];
423
424 /*******************/
425 buffer[0] = '\0';
426 len = tvsnprintf(buffer, 0, "%x", DEADBEEF);
427 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
428 "vsnprintf(%%x). Expected return value %zu, not %d\n",
429 strlen(DEADBEEF_LHEX_STR), len);
430
431 zassert_true((strcmp(buffer, "") == 0),
432 "vsnprintf(%%x). Expected '%s', got '%s'\n",
433 "", buffer);
434
435 /*******************/
436 len = tvsnprintf(buffer, 4, "%x", DEADBEEF);
437 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
438 "vsnprintf(%%x). Expected return value %zu, not %d\n",
439 strlen(DEADBEEF_LHEX_STR), len);
440
441 zassert_true((strcmp(buffer, "dea") == 0),
442 "vsnprintf(%%x). Expected '%s', got '%s'\n",
443 "dea", buffer);
444
445 }
446
447 /**
448 *
449 * @brief A test wrapper for vsprintf()
450 */
451
tvsprintf(char * s,const char * format,...)452 int tvsprintf(char *s, const char *format, ...)
453 {
454 va_list vargs;
455 int r;
456
457 va_start(vargs, format);
458 r = vsprintf(s, format, vargs);
459 va_end(vargs);
460
461 return r;
462 }
463
464 /**
465 *
466 * @brief Test the vsprintf() routine
467 *
468 * This routine does not aim to test the same underlying functionality as
469 * sprintfTest(). Instead it tries to limit it to functionality specific to
470 * vsprintf().
471 *
472 */
473
ZTEST(sprintf,test_vsprintf)474 ZTEST(sprintf, test_vsprintf)
475 {
476 int len;
477 char buffer[100];
478
479 /*******************/
480 len = tvsprintf(buffer, "%x", DEADBEEF);
481 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
482 "sprintf(%%x). Expected %zu bytes written, not %d\n",
483 strlen(DEADBEEF_LHEX_STR), len);
484
485 zassert_true((strcmp(buffer, DEADBEEF_LHEX_STR) == 0),
486 "sprintf(%%x). Expected '%s', got '%s'\n",
487 DEADBEEF_LHEX_STR, buffer);
488 }
489
490 /**
491 *
492 * @brief Test the snprintf() routine
493 *
494 * This routine does not aim to test the same underlying functionality as
495 * sprintfTest(). Instead it tries to limit it to functionality specific to
496 * snprintf().
497 *
498 */
499
ZTEST(sprintf,test_snprintf)500 ZTEST(sprintf, test_snprintf)
501 {
502 #if defined(__GNUC__) && __GNUC__ >= 7
503 /*
504 * GCC 7 and newer are smart enough to realize that in the statements
505 * below, the output will not fit in 0 or 4 bytes, but that it requires
506 * 9.
507 * So it throws a warning in compile time. But in this case we are
508 * actually testing that snprintf's return value is what it should be
509 * while truncating the output. So let's suppress this warning here.
510 */
511 #pragma GCC diagnostic push
512 #pragma GCC diagnostic ignored "-Wformat-truncation"
513 #endif
514
515 int len;
516 char buffer[100];
517
518 /*******************/
519 buffer[0] = '\0';
520 len = snprintf(buffer, 0, "%x", DEADBEEF);
521 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
522 "snprintf(%%x). Expected return value %zu, not %d\n",
523 strlen(DEADBEEF_LHEX_STR), len);
524
525 zassert_true((strcmp(buffer, "") == 0),
526 "snprintf(%%x). Expected '%s', got '%s'\n",
527 "", buffer);
528 /*******************/
529 len = snprintf(buffer, 4, "%x", DEADBEEF);
530 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
531 "snprintf(%%x). Expected return value %zu, not %d\n",
532 strlen(DEADBEEF_LHEX_STR), len);
533
534 zassert_true((strcmp(buffer, "dea") == 0),
535 "snprintf(%%x). Expected '%s', got '%s'\n",
536 "dea", buffer);
537
538 #if defined(__GNUC__) && __GNUC__ >= 7
539 #pragma GCC diagnostic pop
540 #endif
541 }
542
543 /**
544 *
545 * @brief Test the sprintf() routine with miscellaneous specifiers
546 *
547 */
548
ZTEST(sprintf,test_sprintf_misc)549 ZTEST(sprintf, test_sprintf_misc)
550 {
551 int count;
552 char buffer[100];
553
554 /*******************/
555 sprintf(buffer, "%p", (void *) DEADBEEF);
556 zassert_false((strcmp(buffer, DEADBEEF_PTR_STR) != 0),
557 "sprintf(%%p). Expected '%s', got '%s'", DEADBEEF_PTR_STR, buffer);
558 /*******************/
559 if (IS_MINIMAL_LIBC_NANO) {
560 TC_PRINT(" MINIMAL_LIBC+CPBPRINTF skipped tests\n");
561 } else {
562 #ifndef CONFIG_PICOLIBC
563 sprintf(buffer, "test data %n test data", &count);
564 zassert_false((count != 10),
565 "sprintf(%%n). Expected count to be %d, not %d",
566 10, count);
567
568 zassert_false((strcmp(buffer, "test data test data") != 0),
569 "sprintf(%%p). Expected '%s', got '%s'",
570 "test data test data", buffer);
571 #else
572 /*
573 * Picolibc doesn't include %n support as it makes format string
574 * bugs a more serious security issue
575 */
576 (void) count;
577 #endif
578
579
580 /*******************/
581 sprintf(buffer, "%*d", 10, 1234);
582 zassert_true((strcmp(buffer, " 1234") == 0),
583 "sprintf(%%p). Expected '%s', got '%s'",
584 " 1234", buffer);
585
586 /*******************/
587 sprintf(buffer, "%*d", -10, 1234);
588 zassert_true((strcmp(buffer, "1234 ") == 0),
589 "sprintf(%%p). Expected '%s', got '%s'",
590 "1234 ", buffer);
591
592 /*******************/
593 sprintf(buffer, "% d", 1234);
594 zassert_true((strcmp(buffer, " 1234") == 0),
595 "sprintf(%% d). Expected '%s', got '%s'",
596 " 1234", buffer);
597 }
598
599 /*******************/
600 sprintf(buffer, "%hx", (unsigned short)1234);
601 zassert_true((strcmp("4d2", buffer) == 0),
602 "sprintf(%%hx). Expected '4d2', got '%s'", buffer);
603
604 /*******************/
605 sprintf(buffer, "%lx", 1234ul);
606 zassert_true((strcmp("4d2", buffer) == 0),
607 "sprintf(%%lx). Expected '4d2', got '%s'", buffer);
608
609 }
610
611 /**
612 *
613 * @brief Test the sprintf() routine with integers
614 *
615 */
ZTEST(sprintf,test_sprintf_integer)616 ZTEST(sprintf, test_sprintf_integer)
617 {
618 int len;
619 char buffer[100];
620
621 /*******************/
622
623 /* Note: prints hex numbers in 8 characters */
624 len = sprintf(buffer, "%x", 0x11);
625 zassert_true((len == 2),
626 "sprintf(%%x). "
627 "Expected 2 bytes written, not %d", len);
628
629 zassert_true((strcmp(buffer, "11") == 0),
630 "sprintf(%%x). "
631 "Expected '%s', got '%s'", "11", buffer);
632
633 /*******************/
634 len = sprintf(buffer, "%x", DEADBEEF);
635 zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
636 "sprintf(%%x). Expected %zu bytes written, not %d\n",
637 strlen(DEADBEEF_LHEX_STR), len);
638 /*******************/
639 zassert_true((strcmp(buffer, DEADBEEF_LHEX_STR) == 0),
640 "sprintf(%%x). Expected '%s', got '%s'\n",
641 DEADBEEF_LHEX_STR, buffer);
642 /*******************/
643 len = sprintf(buffer, "%X", DEADBEEF);
644 zassert_true((len == strlen(DEADBEEF_UHEX_STR)),
645 "sprintf(%%X). Expected %zu bytes written, not %d\n",
646 strlen(DEADBEEF_UHEX_STR), len);
647
648 /* no upper-case hex support */
649 if (!IS_MINIMAL_LIBC_NANO) {
650 zassert_true((strcmp(buffer, DEADBEEF_UHEX_STR) == 0),
651 "sprintf(%%X). Expected '%s', got '%s'\n",
652 DEADBEEF_UHEX_STR, buffer);
653 }
654
655 /*******************/
656 len = sprintf(buffer, "%u", DEADBEEF);
657 zassert_true((len == strlen(DEADBEEF_UNSIGNED_STR)),
658 "sprintf(%%u). Expected %zu bytes written, not %d\n",
659 strlen(DEADBEEF_UNSIGNED_STR), len);
660
661 zassert_true((strcmp(buffer, DEADBEEF_UNSIGNED_STR) == 0),
662 "sprintf(%%u). Expected '%s', got '%s'\n",
663 DEADBEEF_UNSIGNED_STR, buffer);
664
665 /*******************/
666 len = sprintf(buffer, "%d", (int) DEADBEEF);
667 zassert_true((len == strlen(DEADBEEF_SIGNED_STR)),
668 "sprintf(%%d). Expected %zu bytes written, not %d\n",
669 strlen(DEADBEEF_SIGNED_STR), len);
670
671 zassert_true((strcmp(buffer, DEADBEEF_SIGNED_STR) == 0),
672 "sprintf(%%d). Expected '%s', got '%s'\n",
673 DEADBEEF_SIGNED_STR, buffer);
674
675 /* MINIMAL_LIBC+NANO doesn't support the following tests */
676 if (IS_MINIMAL_LIBC_NANO) {
677 TC_PRINT(" MINIMAL_LIBC+CBPRINTF_NANO skipped tests\n");
678 return;
679 }
680
681 /*******************/
682 len = sprintf(buffer, "%#o", DEADBEEF);
683 zassert_true((len == strlen(DEADBEEF_OCTAL_ALT_STR)),
684 "sprintf(%%#o). Expected %zu bytes written, not %d\n",
685 strlen(DEADBEEF_OCTAL_ALT_STR), len);
686
687 zassert_true((strcmp(buffer, DEADBEEF_OCTAL_ALT_STR) == 0),
688 "sprintf(%%#o). Expected '%s', got '%s'\n",
689 DEADBEEF_OCTAL_ALT_STR, buffer);
690
691 /*******************/
692 len = sprintf(buffer, "%o", DEADBEEF);
693 zassert_true((len == strlen(DEADBEEF_OCTAL_STR)),
694 "sprintf(%%#o). Expected %zu bytes written, not %d\n",
695 strlen(DEADBEEF_OCTAL_STR), len);
696
697 zassert_true((strcmp(buffer, DEADBEEF_OCTAL_STR) == 0),
698 "sprintf(%%o). Expected '%s', got '%s'\n",
699 DEADBEEF_OCTAL_STR, buffer);
700
701 /*******************/
702 len = sprintf(buffer, "%#x", DEADBEEF);
703 zassert_true((len == strlen(DEADBEEF_LHEX_ALT_STR)),
704 "sprintf(%%#x). Expected %zu bytes written, not %d\n",
705 strlen(DEADBEEF_LHEX_ALT_STR), len);
706
707 zassert_true((strcmp(buffer, DEADBEEF_LHEX_ALT_STR) == 0),
708 "sprintf(%%#x). Expected '%s', got '%s'\n",
709 DEADBEEF_LHEX_ALT_STR, buffer);
710
711 /*******************/
712 len = sprintf(buffer, "%#X", DEADBEEF);
713 zassert_true((len == strlen(DEADBEEF_UHEX_ALT_STR)),
714 "sprintf(%%#X). Expected %zu bytes written, not %d\n",
715 strlen(DEADBEEF_UHEX_ALT_STR), len);
716
717 zassert_true((strcmp(buffer, DEADBEEF_UHEX_ALT_STR) == 0),
718 "sprintf(%%#X). Expected '%s', got '%s'\n",
719 DEADBEEF_UHEX_ALT_STR, buffer);
720
721 /*******************/
722
723 len = sprintf(buffer, "%+d", 1);
724 zassert_true((len == 2),
725 "sprintf(%%+d). Expected %d bytes written, not %d\n",
726 2, len);
727
728 zassert_true((strcmp(buffer, "+1") == 0),
729 "sprintf(%%+d). Expected '+1', got '%s'\n", buffer);
730
731 }
732
733 /**
734 *
735 * @brief Test sprintf with strings
736 *
737 */
738
ZTEST(sprintf,test_sprintf_string)739 ZTEST(sprintf, test_sprintf_string)
740 {
741 char buffer[400];
742
743 sprintf(buffer, "%%");
744 zassert_true((strcmp(buffer, "%") == 0),
745 "sprintf(%%). Expected '%%', got '%s'\n", buffer);
746
747 sprintf(buffer, "%c", 't');
748 zassert_true((strcmp(buffer, "t") == 0),
749 "sprintf(%%c). Expected 't', got '%s'\n", buffer);
750
751 sprintf(buffer, "%s", "short string");
752 zassert_true((strcmp(buffer, "short string") == 0),
753 "sprintf(%%s). "
754 "Expected 'short string', got '%s'\n", buffer);
755
756 sprintf(buffer, "%s", REALLY_LONG_STRING);
757 zassert_str_equal(buffer, REALLY_LONG_STRING,
758 "sprintf(%%s) of REALLY_LONG_STRING doesn't match!\n");
759 }
760
761
762 /**
763 *
764 * @brief Test print function
765 *
766 * @see printf().
767 *
768 */
ZTEST(sprintf,test_print)769 ZTEST(sprintf, test_print)
770 {
771 int ret;
772
773 ret = printf("%d\n", 3);
774 zassert_equal(ret, 2, "printf failed!");
775
776 ret = printf("");
777 zassert_equal(ret, 0, "printf failed!");
778 }
779
780 /**
781 *
782 * @brief Test fprintf function
783 *
784 * @see fprintf().
785 *
786 */
ZTEST(sprintf,test_fprintf)787 ZTEST(sprintf, test_fprintf)
788 {
789 int ret, i = 3;
790
791 ret = fprintf(stdout, "%d\n", i);
792 zassert_equal(ret, 2, "fprintf failed!");
793
794 ret = fprintf(stdout, "");
795 zassert_equal(ret, 0, "fprintf failed!");
796
797 }
798
799
800 /**
801 *
802 * @brief Test vfprintf function
803 *
804 */
805
ZTEST(sprintf,test_vfprintf)806 ZTEST(sprintf, test_vfprintf)
807 {
808 int ret;
809
810 ret = WriteFrmtd_vf(stdout, "This %0-d\n", 3);
811 zassert_equal(ret, 7, "vfprintf \"This 3\" failed");
812
813 ret = WriteFrmtd_vf(stdout, "%9d\n", 3);
814 zassert_equal(ret, 10, "vfprintf \"3\" failed");
815
816 ret = WriteFrmtd_vf(stdout, "");
817 zassert_equal(ret, 0, "vfprintf \"\" failed");
818
819 ret = WriteFrmtd_vf(stdout, "/%%/%c/\n", 'a');
820 zassert_equal(ret, 6, "vfprintf \'a\' failed");
821
822 ret = WriteFrmtd_vf(stdout, "11\n");
823 zassert_equal(ret, 3, "vfprintf \"11\" failed");
824
825 }
826
827 /**
828 *
829 * @brief Test vprintf function
830 *
831 */
832
WriteFrmtd_v(char * format,...)833 static int WriteFrmtd_v(char *format, ...)
834 {
835 int ret;
836 va_list args;
837
838 va_start(args, format);
839 ret = vprintf(format, args);
840 va_end(args);
841
842 return ret;
843 }
844
ZTEST(sprintf,test_vprintf)845 ZTEST(sprintf, test_vprintf)
846 {
847 int ret;
848
849 ret = WriteFrmtd_v("This %d\n", 3);
850 zassert_equal(ret, 7, "vprintf \"This 3\" failed");
851
852 ret = WriteFrmtd_v("%9d\n", 3);
853 zassert_equal(ret, 10, "vprintf \"3\" failed");
854
855 ret = WriteFrmtd_v("");
856 zassert_equal(ret, 0, "vprintf \"3\" failed");
857
858 ret = WriteFrmtd_v("/%%/%c/\n", 'a');
859 zassert_equal(ret, 6, "vprintf \'a\' failed");
860
861 ret = WriteFrmtd_v("11\n");
862 zassert_equal(ret, 3, "vprintf \"11\" failed");
863 }
864
865 /**
866 *
867 * @brief Test put function
868 *
869 * @see fputs(), puts(), fputc(), putc().
870 */
ZTEST(sprintf,test_put)871 ZTEST(sprintf, test_put)
872 {
873 int ret;
874
875 ret = fputs("This 3\n", stdout);
876 zassert_equal(ret, 0, "fputs \"This 3\" failed");
877
878 ret = fputs("This 3\n", stderr);
879 zassert_equal(ret, 0, "fputs \"This 3\" failed");
880
881 ret = puts("This 3");
882 zassert_equal(ret, 0, "puts \"This 3\" failed");
883
884 ret = fputc('T', stdout);
885 zassert_equal(ret, 84, "fputc \'T\' failed");
886
887 ret = putc('T', stdout);
888 zassert_equal(ret, 84, "putc \'T\' failed");
889
890 ret = fputc('T', stderr);
891 zassert_equal(ret, 84, "fputc \'T\' failed");
892
893 ret = fputc('T', stdin);
894 zassert_equal(ret, EOF, "fputc to stdin");
895 }
896
897 /**
898 *
899 * @brief Test fwrite function
900 *
901 */
ZTEST(sprintf,test_fwrite)902 ZTEST(sprintf, test_fwrite)
903 {
904 int ret;
905
906 ret = fwrite("This 3", 0, 0, stdout);
907 zassert_equal(ret, 0, "fwrite failed!");
908
909 ret = fwrite("This 3", 0, 4, stdout);
910 zassert_equal(ret, 0, "fwrite failed!");
911
912 ret = fwrite("This 3", 1, 4, stdout);
913 zassert_equal(ret, 4, "fwrite failed!");
914
915 ret = fwrite("This 3", 1, 4, stdin);
916 zassert_equal(ret, 0, "fwrite failed!");
917 }
918
919 /**
920 *
921 * @brief Test stdout_hook_default() function
922 *
923 * @details When CONFIG_STDOUT_CONSOLE=n the default
924 * stdout hook function _stdout_hook_default() returns EOF.
925 */
926
927 #else
ZTEST(sprintf,test_EOF)928 ZTEST(sprintf, test_EOF)
929 {
930 int ret;
931
932 ret = fputc('T', stdout);
933 zassert_equal(ret, EOF, "fputc \'T\' failed");
934
935 ret = fputs("This 3", stdout);
936 zassert_equal(ret, EOF, "fputs \"This 3\" failed");
937
938 ret = puts("This 3");
939 zassert_equal(ret, EOF, "puts \"This 3\" failed");
940
941 ret = WriteFrmtd_vf(stdout, "This %d", 3);
942 zassert_equal(ret, EOF, "vfprintf \"3\" failed");
943 }
944 #endif
945
946 /**
947 * @}
948 */
949
950 /**
951 *
952 * @brief Test entry point
953 *
954 */
955
956 ZTEST_SUITE(sprintf, NULL, NULL, NULL, NULL, NULL);
957