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:
parent
16c15822fe
commit
b113edcdd7
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user