// Author: Ove Kaven
// Modified by: Ron Lee, Francesco Montorsi
// Created: 09/04/99
-// RCS-ID: $Id$
// Copyright: (c) wxWidgets copyright
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include <string.h>
-#if defined(__MWERKS__) && __MSL__ >= 0x6000
-namespace std {}
-using namespace std ;
-#endif
-
// prefer snprintf over sprintf
#if defined(__VISUALC__) || \
(defined(__BORLANDC__) && __BORLANDC__ >= 0x540)
#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
#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
// 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];
m_pArgPos = m_pArgEnd = NULL;
m_type = wxPAT_INVALID;
+ memset(m_szFlags, 0, sizeof(m_szFlags));
// this character will never be removed from m_szFlags array and
// is important when calling sprintf() in wxPrintfConvSpec::Process() !
m_szFlags[0] = '%';
CHECK_PREC
m_szFlags[flagofs++] = char(ch);
break;
-#ifdef __WXMSW__
+#ifdef __WINDOWS__
// under Windows we support the special '%I64' notation as longlong
// 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
-
- m_pArgEnd++;
- m_pArgEnd++;
+ if (*(m_pArgEnd+1) == wxT('6') &&
+ *(m_pArgEnd+2) == wxT('4'))
+ {
+ m_pArgEnd++;
+ m_pArgEnd++;
- ilen = 2;
- CHECK_PREC
- m_szFlags[flagofs++] = char(ch);
- m_szFlags[flagofs++] = '6';
- m_szFlags[flagofs++] = '4';
- break;
-#endif // __WXMSW__
+ 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 // __WINDOWS__
+ 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);
case wxT('X'):
CHECK_PREC
m_szFlags[flagofs++] = char(ch);
- m_szFlags[flagofs] = '\0';
if (ilen == 0)
m_type = wxPAT_INT;
else if (ilen == -1)
case wxT('G'):
CHECK_PREC
m_szFlags[flagofs++] = char(ch);
- m_szFlags[flagofs] = '\0';
if (ilen == 2)
m_type = wxPAT_LONGDOUBLE;
else
case wxT('p'):
m_type = wxPAT_POINTER;
m_szFlags[flagofs++] = char(ch);
- m_szFlags[flagofs] = '\0';
done = true;
break;
case wxPAT_PCHAR:
case wxPAT_PWCHAR:
{
- wxArgNormalizedString arg(p->pad_str);
- wxString s = arg;
-
- if ( !arg.IsValid() && m_nMaxWidth >= 6 )
- s = wxT("(null)");
+ wxString s;
+ if ( !p->pad_str )
+ {
+ if ( m_nMaxWidth >= 6 )
+ s = wxT("(null)");
+ }
+ else if (m_type == wxPAT_PCHAR)
+ s.assign(static_cast<const char *>(p->pad_str));
+ else // m_type == wxPAT_PWCHAR
+ s.assign(static_cast<const wchar_t *>(p->pad_str));
typename wxPrintfStringHelper<CharType>::ConvertedType strbuf(
wxPrintfStringHelper<CharType>::Convert(s));
// special handling for specifications including asterisks: we need
// to reserve an extra slot (or two if asterisks were used for both
// width and precision) in specs array in this case
- for ( const char *f = strchr(spec->m_szFlags, '*');
- f;
- f = strchr(f + 1, '*') )
+ if ( const char *f = strchr(spec->m_szFlags, '*') )
{
- if ( nargs++ == wxMAX_SVNPRINTF_ARGUMENTS )
- break;
+ unsigned numAsterisks = 1;
+ if ( strchr(++f, '*') )
+ numAsterisks++;
- // TODO: we need to support specifiers of the form "%2$*1$s"
- // (this is the same as "%*s") as if any positional arguments
- // are used all asterisks must be positional as well but this
- // requires a lot of changes in this code (basically we'd need
- // to rewrite Parse() to return "*" and conversion itself as
- // separate entries)
- if ( posarg_present )
+ for ( unsigned n = 0; n < numAsterisks; n++ )
{
- wxFAIL_MSG
- (
- wxString::Format
+ if ( nargs++ == wxMAX_SVNPRINTF_ARGUMENTS )
+ break;
+
+ // TODO: we need to support specifiers of the form "%2$*1$s"
+ // (this is the same as "%*s") as if any positional arguments
+ // are used all asterisks must be positional as well but this
+ // requires a lot of changes in this code (basically we'd need
+ // to rewrite Parse() to return "*" and conversion itself as
+ // separate entries)
+ if ( posarg_present )
+ {
+ wxFAIL_MSG
(
- "Format string \"%s\" uses both positional "
- "parameters and '*' but this is not currently "
- "supported by this implementation, sorry.",
- fmt
- )
- );
- }
+ wxString::Format
+ (
+ "Format string \"%s\" uses both positional "
+ "parameters and '*' but this is not currently "
+ "supported by this implementation, sorry.",
+ fmt
+ )
+ );
+ }
- specs[nargs] = *spec;
+ specs[nargs] = *spec;
- // make an entry for '*' and point to it from pspec
- spec->Init();
- spec->m_type = wxPAT_STAR;
- pspec[nargs - 1] = spec;
+ // make an entry for '*' and point to it from pspec
+ spec->Init();
+ spec->m_type = wxPAT_STAR;
+ pspec[nargs - 1] = spec;
- spec = &specs[nargs];
+ spec = &specs[nargs];
+ }
}
+
// check if this is a positional or normal argument
if ( spec->m_pos > 0 )
{