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 <zephyr/test_toolchain.h>
16 #include <stdio.h>
17 #include <stdarg.h>
18 
19 /**
20  *
21  * @brief Test implementation-defined constants library
22  * @ingroup libc_api
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 %zu\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 %zu\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 	/*
503 	 * GCC 7 and newer are smart enough to realize that in the statements
504 	 * below, the output will not fit in 0 or 4 bytes, but that it requires
505 	 * 9.
506 	 * So it throws a warning in compile time. But in this case we are
507 	 * actually testing that snprintf's return value is what it should be
508 	 * while truncating the output. So let's suppress this warning here.
509 	 */
510 	TOOLCHAIN_DISABLE_GCC_WARNING(TOOLCHAIN_WARNING_FORMAT_TRUNCATION);
511 
512 	int len;
513 	char buffer[100];
514 
515 	/*******************/
516 	buffer[0] = '\0';
517 	len = snprintf(buffer, 0, "%x", DEADBEEF);
518 	zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
519 		     "snprintf(%%x).  Expected return value %zu, not %d\n",
520 		     strlen(DEADBEEF_LHEX_STR), len);
521 
522 	zassert_true((strcmp(buffer, "") == 0),
523 		     "snprintf(%%x).  Expected '%s', got '%s'\n",
524 		     "", buffer);
525 	/*******************/
526 	len = snprintf(buffer, 4, "%x", DEADBEEF);
527 	zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
528 		     "snprintf(%%x).  Expected return value %zu, not %d\n",
529 		     strlen(DEADBEEF_LHEX_STR), len);
530 
531 	zassert_true((strcmp(buffer, "dea") == 0),
532 		     "snprintf(%%x).  Expected '%s', got '%s'\n",
533 		     "dea", buffer);
534 
535 	TOOLCHAIN_ENABLE_GCC_WARNING(TOOLCHAIN_WARNING_FORMAT_TRUNCATION);
536 }
537 
538 /**
539  *
540  * @brief Test the sprintf() routine with miscellaneous specifiers
541  *
542  */
543 
ZTEST(sprintf,test_sprintf_misc)544 ZTEST(sprintf, test_sprintf_misc)
545 {
546 	int count;
547 	char buffer[100];
548 
549 	/*******************/
550 	sprintf(buffer, "%p", (void *) DEADBEEF);
551 	zassert_false((strcmp(buffer, DEADBEEF_PTR_STR) != 0),
552 		      "sprintf(%%p).  Expected '%s', got '%s'", DEADBEEF_PTR_STR, buffer);
553 	/*******************/
554 	if (IS_MINIMAL_LIBC_NANO) {
555 		TC_PRINT(" MINIMAL_LIBC+CPBPRINTF skipped tests\n");
556 	} else {
557 #ifndef CONFIG_PICOLIBC
558 		sprintf(buffer, "test data %n test data", &count);
559 		zassert_false((count != 10),
560 			      "sprintf(%%n).  Expected count to be %d, not %d",
561 			      10, count);
562 
563 		zassert_false((strcmp(buffer, "test data  test data") != 0),
564 			      "sprintf(%%p).  Expected '%s', got '%s'",
565 			      "test data  test data", buffer);
566 #else
567 		/*
568 		 * Picolibc doesn't include %n support as it makes format string
569 		 * bugs a more serious security issue
570 		 */
571 		(void) count;
572 #endif
573 
574 
575 		/*******************/
576 		sprintf(buffer, "%*d", 10, 1234);
577 		zassert_true((strcmp(buffer, "      1234") == 0),
578 			     "sprintf(%%p).  Expected '%s', got '%s'",
579 			     "      1234", buffer);
580 
581 		/*******************/
582 		sprintf(buffer, "%*d", -10, 1234);
583 		zassert_true((strcmp(buffer, "1234      ") == 0),
584 			     "sprintf(%%p).  Expected '%s', got '%s'",
585 			     "1234      ", buffer);
586 
587 		/*******************/
588 		sprintf(buffer, "% d", 1234);
589 		zassert_true((strcmp(buffer, " 1234") == 0),
590 			     "sprintf(%% d). Expected '%s', got '%s'",
591 			     " 1234", buffer);
592 	}
593 
594 	/*******************/
595 	sprintf(buffer, "%hx", (unsigned short)1234);
596 	zassert_true((strcmp("4d2", buffer) == 0),
597 		     "sprintf(%%hx).  Expected '4d2', got '%s'", buffer);
598 
599 	/*******************/
600 	sprintf(buffer, "%lx", 1234ul);
601 	zassert_true((strcmp("4d2", buffer) == 0),
602 		     "sprintf(%%lx).  Expected '4d2', got '%s'", buffer);
603 
604 }
605 
606 /**
607  *
608  * @brief Test the sprintf() routine with integers
609  *
610  */
ZTEST(sprintf,test_sprintf_integer)611 ZTEST(sprintf, test_sprintf_integer)
612 {
613 	int len;
614 	char buffer[100];
615 
616 	/*******************/
617 
618 	/* Note: prints hex numbers in 8 characters */
619 	len = sprintf(buffer, "%x", 0x11);
620 	zassert_true((len == 2),
621 		     "sprintf(%%x). "
622 		     "Expected 2 bytes written, not %d", len);
623 
624 	zassert_true((strcmp(buffer, "11") == 0),
625 		     "sprintf(%%x). "
626 		     "Expected '%s', got '%s'", "11", buffer);
627 
628 	/*******************/
629 	len = sprintf(buffer, "%x", DEADBEEF);
630 	zassert_true((len == strlen(DEADBEEF_LHEX_STR)),
631 		     "sprintf(%%x).  Expected %zu bytes written, not %d\n",
632 		     strlen(DEADBEEF_LHEX_STR), len);
633 	/*******************/
634 	zassert_true((strcmp(buffer, DEADBEEF_LHEX_STR) == 0),
635 		     "sprintf(%%x).  Expected '%s', got '%s'\n",
636 		     DEADBEEF_LHEX_STR, buffer);
637 	/*******************/
638 	len = sprintf(buffer, "%X", DEADBEEF);
639 	zassert_true((len == strlen(DEADBEEF_UHEX_STR)),
640 		     "sprintf(%%X).  Expected %zu bytes written, not %d\n",
641 		     strlen(DEADBEEF_UHEX_STR), len);
642 
643 	/* no upper-case hex support */
644 	if (!IS_MINIMAL_LIBC_NANO) {
645 		zassert_true((strcmp(buffer, DEADBEEF_UHEX_STR) == 0),
646 			     "sprintf(%%X).  Expected '%s', got '%s'\n",
647 			     DEADBEEF_UHEX_STR, buffer);
648 	}
649 
650 	/*******************/
651 	len = sprintf(buffer, "%u", DEADBEEF);
652 	zassert_true((len == strlen(DEADBEEF_UNSIGNED_STR)),
653 		     "sprintf(%%u).  Expected %zu bytes written, not %d\n",
654 		     strlen(DEADBEEF_UNSIGNED_STR), len);
655 
656 	zassert_true((strcmp(buffer, DEADBEEF_UNSIGNED_STR) == 0),
657 		     "sprintf(%%u).  Expected '%s', got '%s'\n",
658 		     DEADBEEF_UNSIGNED_STR, buffer);
659 
660 	/*******************/
661 	len = sprintf(buffer, "%d", (int) DEADBEEF);
662 	zassert_true((len == strlen(DEADBEEF_SIGNED_STR)),
663 		     "sprintf(%%d).  Expected %zu bytes written, not %d\n",
664 		     strlen(DEADBEEF_SIGNED_STR), len);
665 
666 	zassert_true((strcmp(buffer, DEADBEEF_SIGNED_STR) == 0),
667 		     "sprintf(%%d).  Expected '%s', got '%s'\n",
668 		     DEADBEEF_SIGNED_STR, buffer);
669 
670 	/* MINIMAL_LIBC+NANO doesn't support the following tests */
671 	if (IS_MINIMAL_LIBC_NANO) {
672 		TC_PRINT(" MINIMAL_LIBC+CBPRINTF_NANO skipped tests\n");
673 		return;
674 	}
675 
676 	/*******************/
677 	len = sprintf(buffer, "%#o", DEADBEEF);
678 	zassert_true((len == strlen(DEADBEEF_OCTAL_ALT_STR)),
679 		     "sprintf(%%#o).  Expected %zu bytes written, not %d\n",
680 		     strlen(DEADBEEF_OCTAL_ALT_STR), len);
681 
682 	zassert_true((strcmp(buffer, DEADBEEF_OCTAL_ALT_STR) == 0),
683 		     "sprintf(%%#o).  Expected '%s', got '%s'\n",
684 		     DEADBEEF_OCTAL_ALT_STR, buffer);
685 
686 	/*******************/
687 	len = sprintf(buffer, "%o", DEADBEEF);
688 	zassert_true((len == strlen(DEADBEEF_OCTAL_STR)),
689 		     "sprintf(%%#o).  Expected %zu bytes written, not %d\n",
690 		     strlen(DEADBEEF_OCTAL_STR), len);
691 
692 	zassert_true((strcmp(buffer, DEADBEEF_OCTAL_STR) == 0),
693 		     "sprintf(%%o).  Expected '%s', got '%s'\n",
694 		     DEADBEEF_OCTAL_STR, buffer);
695 
696 	/*******************/
697 	len = sprintf(buffer, "%#x", DEADBEEF);
698 	zassert_true((len == strlen(DEADBEEF_LHEX_ALT_STR)),
699 		     "sprintf(%%#x).  Expected %zu bytes written, not %d\n",
700 		     strlen(DEADBEEF_LHEX_ALT_STR), len);
701 
702 	zassert_true((strcmp(buffer, DEADBEEF_LHEX_ALT_STR) == 0),
703 		     "sprintf(%%#x).  Expected '%s', got '%s'\n",
704 		     DEADBEEF_LHEX_ALT_STR, buffer);
705 
706 	/*******************/
707 	len = sprintf(buffer, "%#X", DEADBEEF);
708 	zassert_true((len == strlen(DEADBEEF_UHEX_ALT_STR)),
709 		     "sprintf(%%#X).  Expected %zu bytes written, not %d\n",
710 		     strlen(DEADBEEF_UHEX_ALT_STR), len);
711 
712 	zassert_true((strcmp(buffer, DEADBEEF_UHEX_ALT_STR) == 0),
713 		     "sprintf(%%#X).  Expected '%s', got '%s'\n",
714 		     DEADBEEF_UHEX_ALT_STR, buffer);
715 
716 	/*******************/
717 
718 	len = sprintf(buffer, "%+d", 1);
719 	zassert_true((len == 2),
720 		     "sprintf(%%+d).  Expected %d bytes written, not %d\n",
721 		     2, len);
722 
723 	zassert_true((strcmp(buffer, "+1") == 0),
724 		     "sprintf(%%+d). Expected '+1', got '%s'\n", buffer);
725 
726 }
727 
728 /**
729  *
730  * @brief Test sprintf with strings
731  *
732  */
733 
ZTEST(sprintf,test_sprintf_string)734 ZTEST(sprintf, test_sprintf_string)
735 {
736 	char buffer[400];
737 
738 	sprintf(buffer, "%%");
739 	zassert_true((strcmp(buffer, "%") == 0),
740 		     "sprintf(%%).  Expected '%%', got '%s'\n", buffer);
741 
742 	sprintf(buffer, "%c", 't');
743 	zassert_true((strcmp(buffer, "t") == 0),
744 		     "sprintf(%%c).  Expected 't', got '%s'\n", buffer);
745 
746 	sprintf(buffer, "%s", "short string");
747 	zassert_true((strcmp(buffer, "short string") == 0),
748 		     "sprintf(%%s). "
749 		     "Expected 'short string', got '%s'\n", buffer);
750 
751 	sprintf(buffer, "%s", REALLY_LONG_STRING);
752 	zassert_str_equal(buffer, REALLY_LONG_STRING,
753 			  "sprintf(%%s) of REALLY_LONG_STRING doesn't match!\n");
754 }
755 
756 
757 /**
758  *
759  * @brief Test print function
760  *
761  * @see printf().
762  *
763  */
ZTEST(sprintf,test_print)764 ZTEST(sprintf, test_print)
765 {
766 	int ret;
767 
768 	ret = printf("%d\n", 3);
769 	zassert_equal(ret, 2, "printf failed!");
770 
771 	ret = printf("");
772 	zassert_equal(ret, 0, "printf failed!");
773 }
774 
775 /**
776  *
777  * @brief Test fprintf function
778  *
779  * @see fprintf().
780  *
781  */
ZTEST(sprintf,test_fprintf)782 ZTEST(sprintf, test_fprintf)
783 {
784 	int ret, i = 3;
785 
786 	ret = fprintf(stdout, "%d\n", i);
787 	zassert_equal(ret, 2, "fprintf failed!");
788 
789 	ret = fprintf(stdout, "");
790 	zassert_equal(ret, 0, "fprintf failed!");
791 
792 }
793 
794 
795 /**
796  *
797  * @brief Test vfprintf function
798  *
799  */
800 
ZTEST(sprintf,test_vfprintf)801 ZTEST(sprintf, test_vfprintf)
802 {
803 	int ret;
804 
805 	ret = WriteFrmtd_vf(stdout, "This %0-d\n", 3);
806 	zassert_equal(ret, 7, "vfprintf \"This 3\" failed");
807 
808 	ret = WriteFrmtd_vf(stdout,  "%9d\n", 3);
809 	zassert_equal(ret, 10, "vfprintf \"3\" failed");
810 
811 	ret = WriteFrmtd_vf(stdout, "");
812 	zassert_equal(ret, 0, "vfprintf \"\" failed");
813 
814 	ret = WriteFrmtd_vf(stdout, "/%%/%c/\n", 'a');
815 	zassert_equal(ret, 6, "vfprintf \'a\' failed");
816 
817 	ret = WriteFrmtd_vf(stdout,  "11\n");
818 	zassert_equal(ret, 3, "vfprintf \"11\" failed");
819 
820 }
821 
822 /**
823  *
824  * @brief Test vprintf function
825  *
826  */
827 
WriteFrmtd_v(char * format,...)828 static int WriteFrmtd_v(char *format, ...)
829 {
830 	int ret;
831 	va_list args;
832 
833 	va_start(args, format);
834 	ret = vprintf(format, args);
835 	va_end(args);
836 
837 	return ret;
838 }
839 
ZTEST(sprintf,test_vprintf)840 ZTEST(sprintf, test_vprintf)
841 {
842 	int ret;
843 
844 	ret = WriteFrmtd_v("This %d\n", 3);
845 	zassert_equal(ret, 7, "vprintf \"This 3\" failed");
846 
847 	ret = WriteFrmtd_v("%9d\n", 3);
848 	zassert_equal(ret, 10, "vprintf \"3\" failed");
849 
850 	ret = WriteFrmtd_v("");
851 	zassert_equal(ret, 0, "vprintf \"3\" failed");
852 
853 	ret = WriteFrmtd_v("/%%/%c/\n", 'a');
854 	zassert_equal(ret, 6, "vprintf \'a\' failed");
855 
856 	ret = WriteFrmtd_v("11\n");
857 	zassert_equal(ret, 3, "vprintf \"11\" failed");
858 }
859 
860 /**
861  *
862  * @brief Test put function
863  *
864  * @see fputs(), puts(), fputc(), putc().
865  */
ZTEST(sprintf,test_put)866 ZTEST(sprintf, test_put)
867 {
868 	int ret;
869 
870 	ret = fputs("This 3\n", stdout);
871 	zassert_equal(ret, 0, "fputs \"This 3\" failed");
872 
873 	ret = fputs("This 3\n", stderr);
874 	zassert_equal(ret, 0, "fputs \"This 3\" failed");
875 
876 	ret = puts("This 3");
877 	zassert_equal(ret, 0, "puts \"This 3\" failed");
878 
879 	ret = fputc('T', stdout);
880 	zassert_equal(ret, 84, "fputc \'T\' failed");
881 
882 	ret = putc('T', stdout);
883 	zassert_equal(ret, 84, "putc \'T\' failed");
884 
885 	ret = fputc('T', stderr);
886 	zassert_equal(ret, 84, "fputc \'T\' failed");
887 
888 	ret = fputc('T', stdin);
889 	zassert_equal(ret, EOF, "fputc to stdin");
890 }
891 
892 /**
893  *
894  * @brief Test fwrite function
895  *
896  */
ZTEST(sprintf,test_fwrite)897 ZTEST(sprintf, test_fwrite)
898 {
899 	int ret;
900 
901 	ret = fwrite("This 3", 0, 0, stdout);
902 	zassert_equal(ret, 0, "fwrite failed!");
903 
904 	ret = fwrite("This 3", 0, 4, stdout);
905 	zassert_equal(ret, 0, "fwrite failed!");
906 
907 	ret = fwrite("This 3", 1, 4, stdout);
908 	zassert_equal(ret, 4, "fwrite failed!");
909 
910 	ret = fwrite("This 3", 1, 4, stdin);
911 	zassert_equal(ret, 0, "fwrite failed!");
912 }
913 
914 /**
915  *
916  * @brief Test stdout_hook_default() function
917  *
918  * @details When CONFIG_STDOUT_CONSOLE=n the default
919  * stdout hook function _stdout_hook_default() returns EOF.
920  */
921 
922 #else
ZTEST(sprintf,test_EOF)923 ZTEST(sprintf, test_EOF)
924 {
925 	int ret;
926 
927 	ret = fputc('T', stdout);
928 	zassert_equal(ret, EOF, "fputc \'T\' failed");
929 
930 	ret = fputs("This 3", stdout);
931 	zassert_equal(ret, EOF, "fputs \"This 3\" failed");
932 
933 	ret = puts("This 3");
934 	zassert_equal(ret, EOF, "puts \"This 3\" failed");
935 
936 	ret = WriteFrmtd_vf(stdout, "This %d", 3);
937 	zassert_equal(ret, EOF, "vfprintf \"3\" failed");
938 }
939 #endif
940 
941 /**
942  * @}
943  */
944 
945 /**
946  *
947  * @brief Test entry point
948  *
949  */
950 
951 ZTEST_SUITE(sprintf, NULL, NULL, NULL, NULL, NULL);
952