static wxChar buf[MAX_TEST_LEN];
int r;
-// these macros makes it possible to write all tests without repeating a lot
+// these macros makes it possible to write all tests without repeating a lot
// of times the wxT() macro
-// NOTE: you should use expected strings with these macros which do not exceed
+// NOTE: you should use expected strings with these macros which do not exceed
// MAX_TEST_LEN as these macro do check if the return value is == (int)wxStrlen(buf)
#define ASSERT_STR_EQUAL( a, b ) \
CPPUNIT_ASSERT_EQUAL( wxString(wxT(expected)).Left(size - 1), \
wxString(buffer) )
+// this is the same as wxSnprintf() but it passes the format string to
+// wxVsnprintf() without using ATTRIBUTE_PRINTF and thus suppresses the gcc
+// checks (and resulting warnings) for the format string
+//
+// use with extreme care and only when you're really sure the warnings must be
+// suppressed!
+template<typename T>
+static int
+wxUnsafeSnprintf(T *buf, size_t len, const wxChar *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+
+ int rc = wxVsnprintf(buf, len, fmt, args);
+
+ va_end(args);
+ return rc;
+}
// ----------------------------------------------------------------------------
// test class
#endif
CPPUNIT_TEST( BigToSmallBuffer );
+#if wxUSE_WXVSNPRINTF
CPPUNIT_TEST( WrongFormatStrings );
+#endif // wxUSE_WXVSNPRINTF
CPPUNIT_TEST( Miscellaneous );
CPPUNIT_TEST_SUITE_END();
void Unicode();
void BigToSmallBuffer();
+#if wxUSE_WXVSNPRINTF
void WrongFormatStrings();
+#endif // wxUSE_WXVSNPRINTF
void Miscellaneous();
- void Misc(wxChar *buffer, int size);
+ template<typename T> void Misc(T *buffer, int size);
// compares the expectedString and the result of wxVsnprintf() char by char
// for all its lenght (not only for first expectedLen chars) and also
#ifdef __WXMSW__
CMP3("123456789", "%I64d", (wxLongLong_t)123456789);
- CMP3("123456789abcdef", "%I64x", (wxLongLong_t)0x123456789abcdef);
+ CMP3("123456789abcdef", "%I64x", wxLL(0x123456789abcdef));
#endif
}
#endif
-void VsnprintfTestCase::Misc(wxChar *buffer, int size)
+template<typename T>
+void VsnprintfTestCase::Misc(T *buffer, int size)
{
// Remember that wx*printf could be mapped either to system
// implementation or to wx implementation.
//
// Note that in the second case (i.e. when we're using our own implementation),
// wxVsnprintf() will return the number of characters written in the standard
- // output or
+ // output or
// -1 if there was an error in the format string
// maxSize+1 if the output buffer is too small
#endif
// test unicode/ansi conversion specifiers
- // NB: this line will output two warnings like these, on GCC:
- // warning: use of 'h' length modifier with 's' type character (i.e.
- // GCC warns you that 'h' is not legal on 's' conv spec) but they must
- // be ignored as here we explicitely want to test the wxSnprintf()
- // behaviour in such case
-
- CMPTOSIZE(buffer, size,
- "unicode string: unicode!! W - ansi string: ansi!! w\n\n",
- "unicode string: %ls %lc - ansi string: %hs %hc\n\n",
- L"unicode!!", L'W', "ansi!!", 'w');
+ //
+ // NB: we use wxUnsafeSnprintf() as %hs and %hc are invalid in printf
+ // format and gcc would warn about this otherwise
+
+ r = wxUnsafeSnprintf(buffer, size,
+ _T("unicode string: %ls %lc - ansi string: %hs %hc\n\n"),
+ L"unicode!!", L'W', "ansi!!", 'w');
+ CPPUNIT_ASSERT( r != -1 );
+ CPPUNIT_ASSERT_EQUAL(
+ wxString(wxT("unicode string: unicode!! W - ansi string: ansi!! w\n\n")).Left(size - 1),
+ wxString(buffer)
+ );
}
+
+// this test is only for our own implementation, the system implementation
+// doesn't always give errors for invalid format strings (e.g. glibc doesn't)
+// and as it's not required too (the behaviour is "undefined" according to the
+// spec), there is really no sense in testing for it (and the first 2 formats
+// in this test are not invalid at all in fact)
+#if wxUSE_WXVSNPRINTF
+
void VsnprintfTestCase::WrongFormatStrings()
{
// test how wxVsnprintf() behaves with wrong format string:
-#if wxUSE_PRINTF_POS_PARAMS
+ // NB: the next 2 tests currently return an error but they shouldn't,
+ // according to POSIX reusing the parameters is allowed
// two positionals with the same index:
r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$s %1$s"), "hello");
- CPPUNIT_ASSERT(r == -1);
+ CPPUNIT_ASSERT(r != -1);
// three positionals with the same index mixed with other pos args:
r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%4$d %2$f %1$s %2$s %3$d"), "hello", "world", 3, 4);
- CPPUNIT_ASSERT(r == -1);
+ CPPUNIT_ASSERT(r != -1);
- // a missing positional arg:
+ // a missing positional arg: this should result in an error but not all
+ // implementations detect it (e.g. glibc doesn't)
r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %3$d"), 1, 2, 3);
- CPPUNIT_ASSERT(r == -1);
+ CPPUNIT_ASSERT_EQUAL(-1, r);
// positional and non-positionals in the same format string:
r = wxSnprintf(buf, MAX_TEST_LEN, wxT("%1$d %d %3$d"), 1, 2, 3);
- CPPUNIT_ASSERT(r == -1);
-
-#endif // wxUSE_PRINTF_POS_PARAMS
+ CPPUNIT_ASSERT_EQUAL(-1, r);
}
+#endif // wxUSE_WXVSNPRINTF
+
void VsnprintfTestCase::BigToSmallBuffer()
{
- wxChar buf[1024], buf2[16], buf3[4], buf4;
-
- Misc(buf, 1024);
- Misc(buf2, 16);
- Misc(buf3, 4);
- Misc(&buf4, 1);
+ // VC6 can't compile this code
+#if !defined(__VISUALC__) || (__VISUALC__ >= 1310)
+#if wxUSE_UNICODE
+ wchar_t bufw[1024], bufw2[16], bufw3[4], bufw4;
+ Misc(bufw, 1024);
+ Misc(bufw2, 16);
+ Misc(bufw3, 4);
+ Misc(&bufw4, 1);
+#endif // wxUSE_UNICODE
+
+ char bufa[1024], bufa2[16], bufa3[4], bufa4;
+ Misc(bufa, 1024);
+ Misc(bufa2, 16);
+ Misc(bufa3, 4);
+ Misc(&bufa4, 1);
+#endif // !VC6
}
void VsnprintfTestCase::DoMisc(
va_list ap;
va_start(ap, format);
-
+
int n = wxVsnprintf(buf, max, format, ap);
va_end(ap);