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