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:
@@ -65,7 +65,7 @@ enum wxPrintfArgType
|
|||||||
#ifdef wxLongLong_t
|
#ifdef wxLongLong_t
|
||||||
wxPAT_LONGLONGINT, // %Ld, etc
|
wxPAT_LONGLONGINT, // %Ld, etc
|
||||||
#endif
|
#endif
|
||||||
wxPAT_SIZET, // %Zd, etc
|
wxPAT_SIZET, // %zd, etc
|
||||||
|
|
||||||
wxPAT_DOUBLE, // %e, %E, %f, %g, %G
|
wxPAT_DOUBLE, // %e, %E, %f, %g, %G
|
||||||
wxPAT_LONGDOUBLE, // %le, etc
|
wxPAT_LONGDOUBLE, // %le, etc
|
||||||
@@ -93,7 +93,7 @@ union wxPrintfArg
|
|||||||
#ifdef wxLongLong_t
|
#ifdef wxLongLong_t
|
||||||
wxLongLong_t pad_longlongint; // %Ld, etc
|
wxLongLong_t pad_longlongint; // %Ld, etc
|
||||||
#endif
|
#endif
|
||||||
size_t pad_sizet; // %Zd, etc
|
size_t pad_sizet; // %zd, etc
|
||||||
|
|
||||||
double pad_double; // %e, %E, %f, %g, %G
|
double pad_double; // %e, %E, %f, %g, %G
|
||||||
long double pad_longdouble; // %le, etc
|
long double pad_longdouble; // %le, etc
|
||||||
@@ -161,7 +161,7 @@ public:
|
|||||||
// it's task of the caller ensure that memory is still valid !
|
// it's task of the caller ensure that memory is still valid !
|
||||||
const CharType *m_pArgEnd;
|
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()
|
// for use in Process()
|
||||||
char m_szFlags[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
|
char m_szFlags[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
|
||||||
|
|
||||||
@@ -294,22 +294,26 @@ bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
|
|||||||
// integer conversion specifier for MSVC compatibility
|
// integer conversion specifier for MSVC compatibility
|
||||||
// (it behaves exactly as '%lli' or '%Li' or '%qi')
|
// (it behaves exactly as '%lli' or '%Li' or '%qi')
|
||||||
case wxT('I'):
|
case wxT('I'):
|
||||||
if (*(m_pArgEnd+1) != wxT('6') ||
|
if (*(m_pArgEnd+1) == wxT('6') &&
|
||||||
*(m_pArgEnd+2) != wxT('4'))
|
*(m_pArgEnd+2) == wxT('4'))
|
||||||
return false; // bad format
|
{
|
||||||
|
m_pArgEnd++;
|
||||||
|
m_pArgEnd++;
|
||||||
|
|
||||||
m_pArgEnd++;
|
ilen = 2;
|
||||||
m_pArgEnd++;
|
CHECK_PREC
|
||||||
|
m_szFlags[flagofs++] = char(ch);
|
||||||
ilen = 2;
|
m_szFlags[flagofs++] = '6';
|
||||||
CHECK_PREC
|
m_szFlags[flagofs++] = '4';
|
||||||
m_szFlags[flagofs++] = char(ch);
|
break;
|
||||||
m_szFlags[flagofs++] = '6';
|
}
|
||||||
m_szFlags[flagofs++] = '4';
|
// else: fall-through, 'I' is MSVC equivalent of C99 'z'
|
||||||
break;
|
|
||||||
#endif // __WXMSW__
|
#endif // __WXMSW__
|
||||||
|
|
||||||
|
case wxT('z'):
|
||||||
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;
|
ilen = 3;
|
||||||
CHECK_PREC
|
CHECK_PREC
|
||||||
m_szFlags[flagofs++] = char(ch);
|
m_szFlags[flagofs++] = char(ch);
|
||||||
|
@@ -219,4 +219,12 @@ void VarArgTestCase::ArgsValidation()
|
|||||||
// %c should accept integers too
|
// %c should accept integers too
|
||||||
wxString::Format("%c", 80);
|
wxString::Format("%c", 80);
|
||||||
wxString::Format("%c", wxChar(80) + wxChar(1));
|
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
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user