Fix format strings parsing to understand C99 %zu etc.

The parser used to understand only 'Z' specifier for size_t/ptrdiff_t,
which is non-standard libc5 extension. C99 defines 'z' for this purpose,
so use that. Compatibility with 'Z' is preserved.

Also support Visual C++'s non-standard 'I' modifier with the same
meaning.

Fixes #12192.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64800 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík 2010-07-03 14:24:23 +00:00
parent 16c15822fe
commit b113edcdd7
2 changed files with 27 additions and 15 deletions

View File

@ -65,7 +65,7 @@ enum wxPrintfArgType
#ifdef wxLongLong_t
wxPAT_LONGLONGINT, // %Ld, etc
#endif
wxPAT_SIZET, // %Zd, etc
wxPAT_SIZET, // %zd, etc
wxPAT_DOUBLE, // %e, %E, %f, %g, %G
wxPAT_LONGDOUBLE, // %le, etc
@ -93,7 +93,7 @@ union wxPrintfArg
#ifdef wxLongLong_t
wxLongLong_t pad_longlongint; // %Ld, etc
#endif
size_t pad_sizet; // %Zd, etc
size_t pad_sizet; // %zd, etc
double pad_double; // %e, %E, %f, %g, %G
long double pad_longdouble; // %le, etc
@ -161,7 +161,7 @@ public:
// it's task of the caller ensure that memory is still valid !
const CharType *m_pArgEnd;
// a little buffer where formatting flags like #+\.hlqLZ are stored by Parse()
// a little buffer where formatting flags like #+\.hlqLz are stored by Parse()
// for use in Process()
char m_szFlags[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
@ -294,22 +294,26 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
// integer conversion specifier for MSVC compatibility
// (it behaves exactly as '%lli' or '%Li' or '%qi')
case wxT('I'):
if (*(m_pArgEnd+1) != wxT('6') ||
*(m_pArgEnd+2) != wxT('4'))
return false; // bad format
if (*(m_pArgEnd+1) == wxT('6') &&
*(m_pArgEnd+2) == wxT('4'))
{
m_pArgEnd++;
m_pArgEnd++;
m_pArgEnd++;
m_pArgEnd++;
ilen = 2;
CHECK_PREC
m_szFlags[flagofs++] = char(ch);
m_szFlags[flagofs++] = '6';
m_szFlags[flagofs++] = '4';
break;
ilen = 2;
CHECK_PREC
m_szFlags[flagofs++] = char(ch);
m_szFlags[flagofs++] = '6';
m_szFlags[flagofs++] = '4';
break;
}
// else: fall-through, 'I' is MSVC equivalent of C99 'z'
#endif // __WXMSW__
case wxT('z'):
case wxT('Z'):
// 'z' is C99 standard for size_t and ptrdiff_t, 'Z' was used
// for this purpose in libc5 and by wx <= 2.8
ilen = 3;
CHECK_PREC
m_szFlags[flagofs++] = char(ch);

View File

@ -219,4 +219,12 @@ void VarArgTestCase::ArgsValidation()
// %c should accept integers too
wxString::Format("%c", 80);
wxString::Format("%c", wxChar(80) + wxChar(1));
// check size_t handling
size_t len = sizeof(*this);
#ifdef __WXMSW__
wxString::Format("%Iu", len);
#else
wxString::Format("%zu", len);
#endif
}