@@ -75,6 +75,8 @@ const char *context = "";
7575 } \
7676 } while (0)
7777
78+ #define TEST_WSTR (x , expect ) TEST_XSTR(wcscmp, wchar_t, x, expect, "%ls")
79+
7880#define TEST_FLT (x , expect ) do { \
7981 tests++; \
8082 if ((x) != (expect)) { \
@@ -209,6 +211,58 @@ int vsscanf_wrap(const char *str, const char *fmt, ...) {
209211 return ret ;
210212}
211213
214+ int vswprintf_wrap (wchar_t * buf , size_t n , const wchar_t * fmt , ...) {
215+ va_list ap ;
216+ va_start (ap , fmt );
217+ int ret = vswprintf (buf , n , fmt , ap );
218+ va_end (ap );
219+ return ret ;
220+ }
221+
222+ #ifdef _WIN32
223+ int _vscprintf_wrap (const char * fmt , ...) {
224+ va_list ap ;
225+ va_start (ap , fmt );
226+ int ret = _vscprintf (fmt , ap );
227+ va_end (ap );
228+ return ret ;
229+ }
230+
231+ int _vswprintf_wrap (wchar_t * buf , const wchar_t * fmt , ...) {
232+ va_list ap ;
233+ va_start (ap , fmt );
234+ int ret = _vswprintf (buf , fmt , ap );
235+ va_end (ap );
236+ return ret ;
237+ }
238+
239+ int _vsnwprintf_wrap (wchar_t * buf , size_t n , const wchar_t * fmt , ...) {
240+ va_list ap ;
241+ va_start (ap , fmt );
242+ int ret = _vsnwprintf (buf , n , fmt , ap );
243+ va_end (ap );
244+ return ret ;
245+ }
246+
247+ #ifdef __MINGW32__
248+ int vsnwprintf_wrap (wchar_t * buf , size_t n , const wchar_t * fmt , ...) {
249+ va_list ap ;
250+ va_start (ap , fmt );
251+ int ret = vsnwprintf (buf , n , fmt , ap );
252+ va_end (ap );
253+ return ret ;
254+ }
255+ #endif
256+
257+ int _vscwprintf_wrap (const wchar_t * fmt , ...) {
258+ va_list ap ;
259+ va_start (ap , fmt );
260+ int ret = _vscwprintf (fmt , ap );
261+ va_end (ap );
262+ return ret ;
263+ }
264+ #endif
265+
212266double int_to_double (uint64_t i ) {
213267 union {
214268 uint64_t i ;
@@ -218,6 +272,12 @@ double int_to_double(uint64_t i) {
218272 return u .d ;
219273}
220274
275+ void fill_wchar (wchar_t * buf , wchar_t c , size_t n ) {
276+ for (size_t i = 0 ; i < n ; i ++ )
277+ buf [i ] = c ;
278+ }
279+
280+ #define ARRAYLEN (x ) (sizeof(x)/sizeof(*x))
221281
222282void test_strings () {
223283 char buf [200 ];
@@ -394,6 +454,100 @@ void test_strings() {
394454 snprintf (buf , sizeof (buf ), fmt , 42 );
395455 TEST_STR (buf , "0002a" );
396456
457+ #ifdef _WIN32
458+ TEST_INT (_scprintf ("%d" , 12345 ), 5 );
459+ TEST_INT (_vscprintf_wrap ("%d" , 12345 ), 5 );
460+ #endif
461+
462+ wchar_t wbuf [200 ], wbuf2 [5 ];
463+ int ret ;
464+ fill_wchar (wbuf , '#' , ARRAYLEN (wbuf ));
465+ ret = swprintf (wbuf , ARRAYLEN (wbuf ), L"%d" , 42 );
466+ TEST_INT (ret , 2 );
467+ TEST_WSTR (wbuf , L"42" );
468+ TEST_INT (wbuf [ARRAYLEN (wbuf )- 1 ], '#' );
469+
470+ fill_wchar (wbuf , '#' , ARRAYLEN (wbuf ));
471+ ret = vswprintf_wrap (wbuf , ARRAYLEN (wbuf ), L"%d" , 42 );
472+ TEST_INT (ret , 2 );
473+ TEST_WSTR (wbuf , L"42" );
474+ TEST_INT (wbuf [ARRAYLEN (wbuf )- 1 ], '#' );
475+
476+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
477+ ret = swprintf (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 12345 );
478+ TEST_INT (ret , -1 );
479+ #ifndef __GLIBC__
480+ // On overflow, glibc doesn't seem to null terminate the array.
481+ // https://sourceware.org/bugzilla/show_bug.cgi?id=27857, fixed in
482+ // glibc 2.37.
483+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '\0' );
484+ #endif
485+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
486+ TEST_WSTR (wbuf2 , L"1234" );
487+
488+ #ifdef _WIN32
489+ fill_wchar (wbuf , '#' , ARRAYLEN (wbuf ));
490+ ret = _swprintf (wbuf , L"%d" , 42 );
491+ TEST_WSTR (wbuf , L"42" );
492+ TEST_INT (ret , 2 );
493+ TEST_INT (wbuf [ARRAYLEN (wbuf )- 1 ], '#' );
494+
495+ fill_wchar (wbuf , '#' , ARRAYLEN (wbuf ));
496+ ret = _vswprintf_wrap (wbuf , L"%d" , 42 );
497+ TEST_WSTR (wbuf , L"42" );
498+ TEST_INT (ret , 2 );
499+ TEST_INT (wbuf [ARRAYLEN (wbuf )- 1 ], '#' );
500+
501+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
502+ ret = _snwprintf (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 12345 );
503+ TEST_INT (ret , 5 );
504+ // On overflow, _snwprintf doesn't null terminate.
505+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '5' );
506+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
507+ TEST_WSTR (wbuf2 , L"1234" );
508+
509+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
510+ ret = _snwprintf (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 123456 );
511+ TEST_INT (ret , -1 );
512+ // On overflow, _snwprintf doesn't null terminate.
513+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '5' );
514+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
515+ TEST_WSTR (wbuf2 , L"1234" );
516+
517+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
518+ ret = _vsnwprintf_wrap (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 12345 );
519+ TEST_INT (ret , 5 );
520+ // On overflow, _vsnwprintf doesn't null terminate.
521+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '5' );
522+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
523+ TEST_WSTR (wbuf2 , L"1234" );
524+
525+ #ifdef __MINGW32__
526+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
527+ ret = snwprintf (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 123456 );
528+ TEST_INT (ret , 6 );
529+ // On overflow, snwprintf null terminates.
530+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '\0' );
531+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
532+ TEST_WSTR (wbuf2 , L"1234" );
533+
534+ TEST_INT (snwprintf (NULL , 0 , L"%d" , 123456 ), 6 );
535+
536+ fill_wchar (wbuf2 , '#' , ARRAYLEN (wbuf2 ));
537+ ret = vsnwprintf_wrap (wbuf2 , ARRAYLEN (wbuf2 ), L"%d" , 123456 );
538+ TEST_INT (ret , 6 );
539+ // On overflow, vsnwprintf null terminates.
540+ TEST_INT (wbuf2 [ARRAYLEN (wbuf2 )- 1 ], '\0' );
541+ wbuf2 [ARRAYLEN (wbuf2 )- 1 ] = '\0' ;
542+ TEST_WSTR (wbuf2 , L"1234" );
543+
544+ TEST_INT (vsnwprintf_wrap (NULL , 0 , L"%d" , 123456 ), 6 );
545+ #endif
546+
547+ TEST_INT (_scwprintf (L"%d" , 123456 ), 6 );
548+ TEST_INT (_vscwprintf_wrap (L"%d" , 123456 ), 6 );
549+ #endif
550+
397551 uint64_t val0 , val1 , val2 , val3 , val4 , val5 , val6 , val7 , val8 , val9 ;
398552 if (sscanf ("baadf00dcafe baadf00dcaff baadf00dcb00 baadf00dcb01 baadf00dcb02 baadf00dcb03 baadf00dcb04 baadf00dcb05 baadf00dcb06 baadf00dcb07" , "%" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 " %" SCNx64 , & val0 , & val1 , & val2 , & val3 , & val4 , & val5 , & val6 , & val7 , & val8 , & val9 ) != 10 ) {
399553 fails ++ ;
0 commit comments