1+ /*
2+ * Copyright 2026 Two Sigma Open Source, LLC
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
117/*
218 * sprintf_test.c
319 *
4- * Standalone test suite for sprintf / snprintf.
20+ * Bare-metal test suite for sprintf / snprintf.
521 *
622 * Rules:
7- * - NO calls to system printf/sprintf/snprintf/fprintf for validation.
23+ * - NO calls to system printf/sprintf/snprintf for validation.
824 * - Expected values are compile-time string/integer constants.
9- * - Only stdio used: puts() / fwrite() for test-result reporting .
10- * - All 129 original cases are covered; ~80 additional cases added .
25+ * - Output via uart_puts / uart_putchar only .
26+ * - Emits <<PASS>> / <<FAIL>> markers for cocotb test harness .
1127 */
1228
1329#include <sprintf.h>
30+ #include <uart.h>
1431
1532#include <stdbool.h>
1633#include <stdint.h>
17- #include <stdio.h> /* puts, fwrite, fputs – output only, no printf family */
18- #include <stdlib.h> /* EXIT_SUCCESS / EXIT_FAILURE */
1934#include <string.h> /* strcmp, strlen, memset, memcmp */
2035
2136/* ──────────────────────────────────────────────────────────────────────────
22- * Tiny report helpers – no printf, just puts / fwrite
37+ * Tiny report helpers – uses UART, avoids sprintf for reporting
2338 * ────────────────────────────────────────────────────────────────────────── */
2439
2540static int g_pass = 0 ;
2641static int g_fail = 0 ;
2742
28- /* Write a NUL-terminated string to stdout */
29- static void out (const char * s )
30- {
31- fputs (s , stdout );
32- }
33-
34- /* Correct decimal printer */
43+ /* Correct decimal printer (avoids using sprintf for test infrastructure) */
3544static void print_int (int n )
3645{
3746 char tmp [24 ];
@@ -49,23 +58,23 @@ static void print_int(int n)
4958 }
5059 if (neg )
5160 tmp [-- i ] = '-' ;
52- fputs (& tmp [i ], stdout );
61+ uart_puts (& tmp [i ]);
5362}
5463
5564static void print_str_escaped (const char * s )
5665{
57- putc ('[' , stdout );
66+ uart_putchar ('[' );
5867 for (; * s ; s ++ ) {
5968 if (* s == '\n' ) {
60- putc ('\\' , stdout );
61- putc ('n' , stdout );
69+ uart_putchar ('\\' );
70+ uart_putchar ('n' );
6271 } else if (* s == '\t' ) {
63- putc ('\\' , stdout );
64- putc ('t' , stdout );
72+ uart_putchar ('\\' );
73+ uart_putchar ('t' );
6574 } else
66- putc (* s , stdout );
75+ uart_putchar (* s );
6776 }
68- putc (']' , stdout );
77+ uart_putchar (']' );
6978}
7079
7180/* ──────────────────────────────────────────────────────────────────────────
@@ -83,30 +92,30 @@ static void check(
8392 return ;
8493 }
8594 g_fail ++ ;
86- out ("FAIL " );
87- out (name );
88- putc ('\n' , stdout );
95+ uart_puts ("FAIL " );
96+ uart_puts (name );
97+ uart_putchar ('\n' );
8998 if (!str_ok ) {
90- out (" expected : " );
99+ uart_puts (" expected : " );
91100 print_str_escaped (expected_str );
92- out (" (ret " );
101+ uart_puts (" (ret " );
93102 print_int (expected_ret );
94- out (")\n" );
95- out (" got : " );
103+ uart_puts (")\n" );
104+ uart_puts (" got : " );
96105 print_str_escaped (got_str );
97- out (" (ret " );
106+ uart_puts (" (ret " );
98107 print_int (got_ret );
99- out (")\n" );
108+ uart_puts (")\n" );
100109 } else {
101- out (" strings match but return values differ: expected=" );
110+ uart_puts (" strings match but return values differ: expected=" );
102111 print_int (expected_ret );
103- out (" got=" );
112+ uart_puts (" got=" );
104113 print_int (got_ret );
105- putc ('\n' , stdout );
114+ uart_putchar ('\n' );
106115 }
107116}
108117
109- /* Floating-point: accept ± 1 ULP in the last printed digit */
118+ /* Floating-point: accept +/- 1 ULP in the last printed digit */
110119static void check_fp (
111120 const char * name , const char * expected_str , int expected_ret , const char * got_str , int got_ret )
112121{
@@ -134,19 +143,19 @@ static void check_fp(
134143 }
135144 }
136145 g_fail ++ ;
137- out ("FAIL " );
138- out (name );
139- putc ('\n' , stdout );
140- out (" expected : " );
146+ uart_puts ("FAIL " );
147+ uart_puts (name );
148+ uart_putchar ('\n' );
149+ uart_puts (" expected : " );
141150 print_str_escaped (expected_str );
142- out (" (ret " );
151+ uart_puts (" (ret " );
143152 print_int (expected_ret );
144- out (")\n" );
145- out (" got : " );
153+ uart_puts (")\n" );
154+ uart_puts (" got : " );
146155 print_str_escaped (got_str );
147- out (" (ret " );
156+ uart_puts (" (ret " );
148157 print_int (got_ret );
149- out (")\n" );
158+ uart_puts (")\n" );
150159}
151160
152161/* Convenience macros */
@@ -169,9 +178,9 @@ static void check_fp(
169178/* section header */
170179static void section (const char * s )
171180{
172- out ("\n=== " );
173- out (s );
174- out (" ===\n" );
181+ uart_puts ("\n=== " );
182+ uart_puts (s );
183+ uart_puts (" ===\n" );
175184}
176185
177186/* ══════════════════════════════════════════════════════════════════════════
@@ -428,7 +437,7 @@ static void test_snprintf_trunc(void)
428437{
429438 section ("snprintf truncation / return value" );
430439
431- /* Truncation: "hello world" → buf size 5 → "hell\0", ret=11 */
440+ /* Truncation: "hello world" -> buf size 5 -> "hell\0", ret=11 */
432441 {
433442 char got [5 ];
434443 int r = snprintf (got , 5 , "%s" , "hello world" );
@@ -451,12 +460,12 @@ static void test_snprintf_trunc(void)
451460 g_pass ++ ;
452461 else {
453462 g_fail ++ ;
454- out ("FAIL size=0 no-write\n" );
455- out (" ret=" );
463+ uart_puts ("FAIL size=0 no-write\n" );
464+ uart_puts (" ret=" );
456465 print_int (r );
457- out (" got[0]='" );
458- putc (got [0 ], stdout );
459- out ("'\n" );
466+ uart_puts (" got[0]='" );
467+ uart_putchar (got [0 ]);
468+ uart_puts ("'\n" );
460469 }
461470 }
462471
@@ -535,7 +544,7 @@ static void test_length_mods(void)
535544 T ("ll signed min" , "-9223372036854775808" , 20 , "%lld" , -9223372036854775807LL - 1 );
536545 T ("ll unsigned max" , "18446744073709551615" , 20 , "%llu" , 18446744073709551615ULL );
537546 T ("z size_t" , "65536" , 5 , "%zu" , (size_t ) 65536 );
538- T ("z size_t large" , "1099511627776 " , 13 , "%zu" , (size_t ) 1099511627776ULL );
547+ T ("z size_t large" , "4294967295 " , 10 , "%zu" , (size_t ) 4294967295UL );
539548 T ("lx" , "ffffffffffffffff" , 16 , "%llx" , 18446744073709551615ULL );
540549 T ("lX" , "FFFFFFFFFFFFFFFF" , 16 , "%llX" , 18446744073709551615ULL );
541550}
@@ -554,7 +563,7 @@ static void test_pointer(void)
554563 g_pass ++ ;
555564 else {
556565 g_fail ++ ;
557- out ("FAIL p NULL has 0x prefix\n" );
566+ uart_puts ("FAIL p NULL has 0x prefix\n" );
558567 }
559568 }
560569 {
@@ -566,7 +575,7 @@ static void test_pointer(void)
566575 g_pass ++ ;
567576 else {
568577 g_fail ++ ;
569- out ("FAIL p 0xDEAD has 0x prefix\n" );
578+ uart_puts ("FAIL p 0xDEAD has 0x prefix\n" );
570579 }
571580 }
572581 {
@@ -579,11 +588,11 @@ static void test_pointer(void)
579588 g_pass ++ ;
580589 else {
581590 g_fail ++ ;
582- out ("FAIL p width=20: " );
591+ uart_puts ("FAIL p width=20: " );
583592 print_str_escaped (got );
584- out (" ret=" );
593+ uart_puts (" ret=" );
585594 print_int (r );
586- putc ('\n' , stdout );
595+ uart_putchar ('\n' );
587596 }
588597 }
589598}
@@ -629,9 +638,9 @@ static void test_n(void)
629638 g_pass ++ ;
630639 else {
631640 g_fail ++ ;
632- out ("FAIL %n pos: expected 5 got " );
641+ uart_puts ("FAIL %n pos: expected 5 got " );
633642 print_int (pos );
634- putc ('\n' , stdout );
643+ uart_putchar ('\n' );
635644 }
636645 }
637646 {
@@ -643,9 +652,9 @@ static void test_n(void)
643652 g_pass ++ ;
644653 else {
645654 g_fail ++ ;
646- out ("FAIL %n after %d: expected 5 got " );
655+ uart_puts ("FAIL %n after %d: expected 5 got " );
647656 print_int (pos );
648- putc ('\n' , stdout );
657+ uart_putchar ('\n' );
649658 }
650659 }
651660}
@@ -663,7 +672,7 @@ static void test_regression(void)
663672 g_pass ++ ;
664673 else {
665674 g_fail ++ ;
666- out ("FAIL NUL via %c\n" );
675+ uart_puts ("FAIL NUL via %c\n" );
667676 }
668677 }
669678 T ("d 10 digits" , "1000000000" , 10 , "%d" , 1000000000 );
@@ -697,9 +706,8 @@ static void test_regression(void)
697706
698707int main (void )
699708{
700- out ("╔══════════════════════════════════════════════════╗\n" );
701- out ("║ sprintf standalone static test suite ║\n" );
702- out ("╚══════════════════════════════════════════════════╝\n" );
709+ uart_puts ("sprintf/snprintf Test Suite\n" );
710+ uart_puts ("==========================\n" );
703711
704712 test_literal ();
705713 test_char ();
@@ -721,15 +729,24 @@ int main(void)
721729 test_n ();
722730 test_regression ();
723731
724- out ("\n══════════════════════════════════════════════════════ \n" );
725- out ("Results: " );
732+ uart_puts ("\n========================== \n" );
733+ uart_puts ("Results: " );
726734 print_int (g_pass );
727- out (" passed, " );
735+ uart_puts (" passed, " );
728736 print_int (g_fail );
729- out (" failed (total " );
737+ uart_puts (" failed (total " );
730738 print_int (g_pass + g_fail );
731- out (")\n" );
732- out ("══════════════════════════════════════════════════════\n" );
739+ uart_puts (")\n" );
740+
741+ if (g_fail == 0 ) {
742+ uart_puts ("ALL TESTS PASSED\n" );
743+ uart_puts ("<<PASS>>\n" );
744+ } else {
745+ uart_puts ("SOME TESTS FAILED\n" );
746+ uart_puts ("<<FAIL>>\n" );
747+ }
733748
734- return (g_fail == 0 ) ? 0 : -1 ;
749+ /* Halt */
750+ for (;;) {
751+ }
735752}
0 commit comments