make our vsnprintf() implementation work for ANSI version too
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@46518 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -560,25 +560,6 @@ int wxCRT_VsnprintfW(wchar_t *str, size_t size, const wchar_t *format, va_list a
|
|||||||
}
|
}
|
||||||
#endif // !wxCRT_VsnprintfW
|
#endif // !wxCRT_VsnprintfW
|
||||||
|
|
||||||
// FIXME-UTF8: we only implement widechar version of vsnprintf() in wxprint.cpp,
|
|
||||||
// so this one has to convert the data for now
|
|
||||||
#ifndef wxCRT_VsnprintfA
|
|
||||||
int wxCRT_VsnprintfA(char *buf, size_t len, const char *format, va_list argptr)
|
|
||||||
{
|
|
||||||
wxWCharBuffer wbuf(len);
|
|
||||||
int rt = wxCRT_VsnprintfW(wbuf.data(), len,
|
|
||||||
(const wchar_t*)wxConvLibc.cMB2WC(format),
|
|
||||||
argptr);
|
|
||||||
if ( rt < 0 || rt >= (int)len )
|
|
||||||
return rt;
|
|
||||||
|
|
||||||
if ( wxConvLibc.FromWChar(buf, len, wbuf) == wxCONV_FAILED )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
#endif // !wxCRT_VsnprintfA
|
|
||||||
|
|
||||||
#ifndef wxCRT_VsprintfW
|
#ifndef wxCRT_VsprintfW
|
||||||
int wxCRT_VsprintfW( wchar_t *str, const wchar_t *format, va_list argptr )
|
int wxCRT_VsprintfW( wchar_t *str, const wchar_t *format, va_list argptr )
|
||||||
{
|
{
|
||||||
|
@@ -45,6 +45,7 @@ using namespace std ;
|
|||||||
// them to be able to test them
|
// them to be able to test them
|
||||||
#ifdef wxTEST_PRINTF
|
#ifdef wxTEST_PRINTF
|
||||||
#undef wxCRT_VsnprintfW_
|
#undef wxCRT_VsnprintfW_
|
||||||
|
#undef wxCRT_VsnprintfA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -53,11 +54,11 @@ using namespace std ;
|
|||||||
// (very useful for i18n purposes)
|
// (very useful for i18n purposes)
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !defined(wxCRT_VsnprintfW_)
|
// ----------------------------------------------------------------------------
|
||||||
|
// common code for both ANSI and Unicode versions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !wxUSE_WXVSNPRINTFW
|
#if !defined(wxCRT_VsnprintfW_) || !defined(wxCRT_VsnprintfA)
|
||||||
#error "wxUSE_WXVSNPRINTFW must be 1 if our wxCRT_VsnprintfW_ is used"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// wxUSE_STRUTILS says our wxCRT_VsnprintfW_ implementation to use or not to
|
// wxUSE_STRUTILS says our wxCRT_VsnprintfW_ implementation to use or not to
|
||||||
// use wxStrlen and wxStrncpy functions over one-char processing loops.
|
// use wxStrlen and wxStrncpy functions over one-char processing loops.
|
||||||
@@ -99,6 +100,9 @@ using namespace std ;
|
|||||||
#define SYSTEM_SPRINTF_IS_UNSAFE
|
#define SYSTEM_SPRINTF_IS_UNSAFE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
// the conversion specifiers accepted by wxCRT_VsnprintfW_
|
// the conversion specifiers accepted by wxCRT_VsnprintfW_
|
||||||
enum wxPrintfArgType {
|
enum wxPrintfArgType {
|
||||||
wxPAT_INVALID = -1,
|
wxPAT_INVALID = -1,
|
||||||
@@ -150,11 +154,28 @@ typedef union {
|
|||||||
long int *pad_nlongint; // %ln
|
long int *pad_nlongint; // %ln
|
||||||
} wxPrintfArg;
|
} wxPrintfArg;
|
||||||
|
|
||||||
|
// helper for converting string into either char* or wchar_t* dependening
|
||||||
|
// on the type of wxPrintfConvSpec<T> instantiation:
|
||||||
|
template<typename CharType> struct wxPrintfStringHelper {};
|
||||||
|
|
||||||
|
template<> struct wxPrintfStringHelper<char>
|
||||||
|
{
|
||||||
|
typedef const wxWX2MBbuf ConvertedType;
|
||||||
|
static ConvertedType Convert(const wxString& s) { return s.mb_str(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> struct wxPrintfStringHelper<wchar_t>
|
||||||
|
{
|
||||||
|
typedef const wxWX2WCbuf ConvertedType;
|
||||||
|
static ConvertedType Convert(const wxString& s) { return s.wc_str(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Contains parsed data relative to a conversion specifier given to
|
// Contains parsed data relative to a conversion specifier given to
|
||||||
// wxCRT_VsnprintfW_ and parsed from the format string
|
// wxCRT_VsnprintfW_ and parsed from the format string
|
||||||
// NOTE: in C++ there is almost no difference between struct & classes thus
|
// NOTE: in C++ there is almost no difference between struct & classes thus
|
||||||
// there is no performance gain by using a struct here...
|
// there is no performance gain by using a struct here...
|
||||||
|
template<typename CharType>
|
||||||
class wxPrintfConvSpec
|
class wxPrintfConvSpec
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -176,13 +197,13 @@ public:
|
|||||||
// pointer to the '%' of this conversion specifier in the format string
|
// pointer to the '%' of this conversion specifier in the format string
|
||||||
// NOTE: this points somewhere in the string given to the Parse() function -
|
// NOTE: this points somewhere in the string given to the Parse() function -
|
||||||
// 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 wchar_t *m_pArgPos;
|
const CharType *m_pArgPos;
|
||||||
|
|
||||||
// pointer to the last character of this conversion specifier in the
|
// pointer to the last character of this conversion specifier in the
|
||||||
// format string
|
// format string
|
||||||
// NOTE: this points somewhere in the string given to the Parse() function -
|
// NOTE: this points somewhere in the string given to the Parse() function -
|
||||||
// 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 wchar_t *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()
|
||||||
@@ -203,12 +224,12 @@ public:
|
|||||||
// Parses the first conversion specifier in the given string, which must
|
// Parses the first conversion specifier in the given string, which must
|
||||||
// begin with a '%'. Returns false if the first '%' does not introduce a
|
// begin with a '%'. Returns false if the first '%' does not introduce a
|
||||||
// (valid) conversion specifier and thus should be ignored.
|
// (valid) conversion specifier and thus should be ignored.
|
||||||
bool Parse(const wchar_t *format);
|
bool Parse(const CharType *format);
|
||||||
|
|
||||||
// Process this conversion specifier and puts the result in the given
|
// Process this conversion specifier and puts the result in the given
|
||||||
// buffer. Returns the number of characters written in 'buf' or -1 if
|
// buffer. Returns the number of characters written in 'buf' or -1 if
|
||||||
// there's not enough space.
|
// there's not enough space.
|
||||||
int Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_t written);
|
int Process(CharType *buf, size_t lenMax, wxPrintfArg *p, size_t written);
|
||||||
|
|
||||||
// Loads the argument of this conversion specifier from given va_list.
|
// Loads the argument of this conversion specifier from given va_list.
|
||||||
bool LoadArg(wxPrintfArg *p, va_list &argptr);
|
bool LoadArg(wxPrintfArg *p, va_list &argptr);
|
||||||
@@ -218,7 +239,8 @@ private:
|
|||||||
void ReplaceAsteriskWith(int w);
|
void ReplaceAsteriskWith(int w);
|
||||||
};
|
};
|
||||||
|
|
||||||
void wxPrintfConvSpec::Init()
|
template<typename CharType>
|
||||||
|
void wxPrintfConvSpec<CharType>::Init()
|
||||||
{
|
{
|
||||||
m_nMinWidth = 0;
|
m_nMinWidth = 0;
|
||||||
m_nMaxWidth = 0xFFFF;
|
m_nMaxWidth = 0xFFFF;
|
||||||
@@ -232,7 +254,8 @@ void wxPrintfConvSpec::Init()
|
|||||||
m_szFlags[0] = '%';
|
m_szFlags[0] = '%';
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxPrintfConvSpec::Parse(const wchar_t *format)
|
template<typename CharType>
|
||||||
|
bool wxPrintfConvSpec<CharType>::Parse(const CharType *format)
|
||||||
{
|
{
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
@@ -254,7 +277,7 @@ bool wxPrintfConvSpec::Parse(const wchar_t *format)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// what follows '%'?
|
// what follows '%'?
|
||||||
const wchar_t ch = *(++m_pArgEnd);
|
const CharType ch = *(++m_pArgEnd);
|
||||||
switch ( ch )
|
switch ( ch )
|
||||||
{
|
{
|
||||||
case wxT('\0'):
|
case wxT('\0'):
|
||||||
@@ -362,8 +385,8 @@ bool wxPrintfConvSpec::Parse(const wchar_t *format)
|
|||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
CHECK_PREC
|
CHECK_PREC
|
||||||
while ( (*m_pArgEnd >= wxT('0')) &&
|
while ( (*m_pArgEnd >= CharType('0')) &&
|
||||||
(*m_pArgEnd <= wxT('9')) )
|
(*m_pArgEnd <= CharType('9')) )
|
||||||
{
|
{
|
||||||
m_szFlags[flagofs++] = char(*m_pArgEnd);
|
m_szFlags[flagofs++] = char(*m_pArgEnd);
|
||||||
len = len*10 + (*m_pArgEnd - wxT('0'));
|
len = len*10 + (*m_pArgEnd - wxT('0'));
|
||||||
@@ -528,8 +551,8 @@ bool wxPrintfConvSpec::Parse(const wchar_t *format)
|
|||||||
return true; // parsing was successful
|
return true; // parsing was successful
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename CharType>
|
||||||
void wxPrintfConvSpec::ReplaceAsteriskWith(int width)
|
void wxPrintfConvSpec<CharType>::ReplaceAsteriskWith(int width)
|
||||||
{
|
{
|
||||||
char temp[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
|
char temp[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
|
||||||
|
|
||||||
@@ -556,7 +579,8 @@ void wxPrintfConvSpec::ReplaceAsteriskWith(int width)
|
|||||||
strcpy(pwidth+offset, temp);
|
strcpy(pwidth+offset, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
|
template<typename CharType>
|
||||||
|
bool wxPrintfConvSpec<CharType>::LoadArg(wxPrintfArg *p, va_list &argptr)
|
||||||
{
|
{
|
||||||
// did the '*' width/precision specifier was used ?
|
// did the '*' width/precision specifier was used ?
|
||||||
if (m_nMaxWidth == -1)
|
if (m_nMaxWidth == -1)
|
||||||
@@ -637,7 +661,8 @@ bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
|
|||||||
return true; // loading was successful
|
return true; // loading was successful
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_t written)
|
template<typename CharType>
|
||||||
|
int wxPrintfConvSpec<CharType>::Process(CharType *buf, size_t lenMax, wxPrintfArg *p, size_t written)
|
||||||
{
|
{
|
||||||
// buffer to avoid dynamic memory allocation each time for small strings;
|
// buffer to avoid dynamic memory allocation each time for small strings;
|
||||||
// note that this buffer is used only to hold results of number formatting,
|
// note that this buffer is used only to hold results of number formatting,
|
||||||
@@ -688,32 +713,13 @@ int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_
|
|||||||
case wxPAT_CHAR:
|
case wxPAT_CHAR:
|
||||||
case wxPAT_WCHAR:
|
case wxPAT_WCHAR:
|
||||||
{
|
{
|
||||||
wchar_t val =
|
wxUniChar ch;
|
||||||
#if wxUSE_UNICODE
|
|
||||||
p->pad_wchar;
|
|
||||||
|
|
||||||
if (m_type == wxPAT_CHAR)
|
if (m_type == wxPAT_CHAR)
|
||||||
{
|
ch = p->pad_char;
|
||||||
// user passed a character explicitely indicated as ANSI...
|
else // m_type == wxPAT_WCHAR
|
||||||
const char buf[2] = { p->pad_char, 0 };
|
ch = p->pad_wchar;
|
||||||
val = wxString(buf, wxConvLibc)[0u];
|
|
||||||
|
|
||||||
//wprintf(L"converting ANSI=>Unicode"); // for debug
|
CharType val = ch;
|
||||||
}
|
|
||||||
#else
|
|
||||||
p->pad_char;
|
|
||||||
|
|
||||||
#if wxUSE_WCHAR_T
|
|
||||||
if (m_type == wxPAT_WCHAR)
|
|
||||||
{
|
|
||||||
// user passed a character explicitely indicated as Unicode...
|
|
||||||
const wchar_t buf[2] = { p->pad_wchar, 0 };
|
|
||||||
val = wxString(buf, wxConvLibc)[0u];
|
|
||||||
|
|
||||||
//printf("converting Unicode=>ANSI"); // for debug
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@@ -738,9 +744,12 @@ int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_
|
|||||||
if ( !arg.IsValid() && m_nMaxWidth >= 6 )
|
if ( !arg.IsValid() && m_nMaxWidth >= 6 )
|
||||||
s = wxT("(null)");
|
s = wxT("(null)");
|
||||||
|
|
||||||
|
typename wxPrintfStringHelper<CharType>::ConvertedType strbuf(
|
||||||
|
wxPrintfStringHelper<CharType>::Convert(s));
|
||||||
|
|
||||||
// at this point we are sure that m_nMaxWidth is positive or
|
// at this point we are sure that m_nMaxWidth is positive or
|
||||||
// null (see top of wxPrintfConvSpec::LoadArg)
|
// null (see top of wxPrintfConvSpec::LoadArg)
|
||||||
int len = wxMin((unsigned int)m_nMaxWidth, s.length());
|
int len = wxMin((unsigned int)m_nMaxWidth, wxStrlen(strbuf));
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -750,19 +759,9 @@ int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_
|
|||||||
APPEND_CH(_T(' '));
|
APPEND_CH(_T(' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxUSE_STRUTILS
|
|
||||||
len = wxMin((unsigned int)len, lenMax-lenCur);
|
len = wxMin((unsigned int)len, lenMax-lenCur);
|
||||||
#if wxUSE_UNICODE // FIXME-UTF8
|
wxStrncpy(buf+lenCur, strbuf, len);
|
||||||
wxStrncpy(buf+lenCur, s.wc_str(), len);
|
|
||||||
#else
|
|
||||||
wxStrncpy(buf+lenCur, s.mb_str(), len);
|
|
||||||
#endif
|
|
||||||
lenCur += len;
|
lenCur += len;
|
||||||
#else
|
|
||||||
wxString::const_iterator end = s.begin() + len;
|
|
||||||
for (wxString::const_iterator j = s.begin(); j != end; ++j)
|
|
||||||
APPEND_CH(*j);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_bAlignLeft)
|
if (m_bAlignLeft)
|
||||||
{
|
{
|
||||||
@@ -803,54 +802,22 @@ int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_
|
|||||||
case wxPAT_DOUBLE:
|
case wxPAT_DOUBLE:
|
||||||
case wxPAT_POINTER:
|
case wxPAT_POINTER:
|
||||||
wxASSERT(lenScratch < wxMAX_SVNPRINTF_SCRATCHBUFFER_LEN);
|
wxASSERT(lenScratch < wxMAX_SVNPRINTF_SCRATCHBUFFER_LEN);
|
||||||
#if !wxUSE_UNICODE
|
// NB: 1) we can compare lenMax (for CharType*, i.e. possibly
|
||||||
|
// wchar_t*) with lenScratch (char*) because this code is
|
||||||
|
// formatting integers and that will have the same length
|
||||||
|
// even in UTF-8 (the only case when char* length may be
|
||||||
|
// more than wchar_t* length of the same string)
|
||||||
|
// 2) wxStrncpy converts the 2nd argument to 1st argument's
|
||||||
|
// type transparently if their types differ, so this code
|
||||||
|
// works for both instantiations
|
||||||
|
if (lenMax < lenScratch)
|
||||||
{
|
{
|
||||||
if (lenMax < lenScratch)
|
// fill output buffer and then return -1
|
||||||
{
|
wxStrncpy(buf, szScratch, lenMax);
|
||||||
// fill output buffer and then return -1
|
return -1;
|
||||||
wxStrncpy(buf, szScratch, lenMax);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
wxStrncpy(buf, szScratch, lenScratch);
|
|
||||||
lenCur += lenScratch;
|
|
||||||
}
|
}
|
||||||
#else
|
wxStrncpy(buf, szScratch, lenScratch);
|
||||||
{
|
lenCur += lenScratch;
|
||||||
// Copy the char scratch to the wide output. This requires
|
|
||||||
// conversion, but we can optimise by making use of the fact
|
|
||||||
// that we are formatting numbers, this should mean only 7-bit
|
|
||||||
// ascii characters are involved.
|
|
||||||
wchar_t *bufptr = buf;
|
|
||||||
const wchar_t *bufend = buf + lenMax;
|
|
||||||
const char *scratchptr = szScratch;
|
|
||||||
|
|
||||||
// Simply copy each char to a wchar_t, stopping on the first
|
|
||||||
// null or non-ascii byte. Checking '(signed char)*scratchptr
|
|
||||||
// > 0' is an extra optimisation over '*scratchptr != 0 &&
|
|
||||||
// isascii(*scratchptr)', though it assumes signed char is
|
|
||||||
// 8-bit 2 complement.
|
|
||||||
while ((signed char)*scratchptr > 0 && bufptr != bufend)
|
|
||||||
*bufptr++ = *scratchptr++;
|
|
||||||
|
|
||||||
if (bufptr == bufend)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
lenCur += bufptr - buf;
|
|
||||||
|
|
||||||
// check if the loop stopped on a non-ascii char, if yes then
|
|
||||||
// fall back to wxMB2WX
|
|
||||||
if (*scratchptr)
|
|
||||||
{
|
|
||||||
size_t len = wxMB2WX(bufptr, scratchptr, bufend - bufptr);
|
|
||||||
|
|
||||||
if (len && len != (size_t)(-1))
|
|
||||||
if (bufptr[len - 1])
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
lenCur += len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -863,12 +830,12 @@ int wxPrintfConvSpec::Process(wchar_t *buf, size_t lenMax, wxPrintfArg *p, size_
|
|||||||
// Copy chars from source to dest converting '%%' to '%'. Takes at most maxIn
|
// Copy chars from source to dest converting '%%' to '%'. Takes at most maxIn
|
||||||
// chars from source and write at most outMax chars to dest, returns the
|
// chars from source and write at most outMax chars to dest, returns the
|
||||||
// number of chars actually written. Does not treat null specially.
|
// number of chars actually written. Does not treat null specially.
|
||||||
//
|
template<typename CharType>
|
||||||
static int wxCopyStrWithPercents(
|
static int wxCopyStrWithPercents(
|
||||||
size_t maxOut,
|
size_t maxOut,
|
||||||
wchar_t *dest,
|
CharType *dest,
|
||||||
size_t maxIn,
|
size_t maxIn,
|
||||||
const wchar_t *source)
|
const CharType *source)
|
||||||
{
|
{
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
|
|
||||||
@@ -894,8 +861,9 @@ static int wxCopyStrWithPercents(
|
|||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
template<typename CharType>
|
||||||
const wchar_t *format, va_list argptr)
|
static int wxDoVsnprintf(CharType *buf, size_t lenMax,
|
||||||
|
const CharType *format, va_list argptr)
|
||||||
{
|
{
|
||||||
// useful for debugging, to understand if we are really using this function
|
// useful for debugging, to understand if we are really using this function
|
||||||
// rather than the system implementation
|
// rather than the system implementation
|
||||||
@@ -904,9 +872,9 @@ int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// required memory:
|
// required memory:
|
||||||
wxPrintfConvSpec arg[wxMAX_SVNPRINTF_ARGUMENTS];
|
wxPrintfConvSpec<CharType> arg[wxMAX_SVNPRINTF_ARGUMENTS];
|
||||||
wxPrintfArg argdata[wxMAX_SVNPRINTF_ARGUMENTS];
|
wxPrintfArg argdata[wxMAX_SVNPRINTF_ARGUMENTS];
|
||||||
wxPrintfConvSpec *pspec[wxMAX_SVNPRINTF_ARGUMENTS] = { NULL };
|
wxPrintfConvSpec<CharType> *pspec[wxMAX_SVNPRINTF_ARGUMENTS] = { NULL };
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@@ -914,7 +882,7 @@ int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
|||||||
size_t lenCur = 0;
|
size_t lenCur = 0;
|
||||||
|
|
||||||
size_t nargs = 0;
|
size_t nargs = 0;
|
||||||
const wchar_t *toparse = format;
|
const CharType *toparse = format;
|
||||||
|
|
||||||
// parse the format string
|
// parse the format string
|
||||||
bool posarg_present = false, nonposarg_present = false;
|
bool posarg_present = false, nonposarg_present = false;
|
||||||
@@ -928,7 +896,7 @@ int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
|||||||
if (arg[nargs].Parse(toparse))
|
if (arg[nargs].Parse(toparse))
|
||||||
{
|
{
|
||||||
// ...yes it is
|
// ...yes it is
|
||||||
wxPrintfConvSpec *current = &arg[nargs];
|
wxPrintfConvSpec<CharType> *current = &arg[nargs];
|
||||||
|
|
||||||
// make toparse point to the end of this specifier
|
// make toparse point to the end of this specifier
|
||||||
toparse = current->m_pArgEnd;
|
toparse = current->m_pArgEnd;
|
||||||
@@ -1053,6 +1021,26 @@ int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
|||||||
#undef APPEND_CH
|
#undef APPEND_CH
|
||||||
#undef CHECK_PREC
|
#undef CHECK_PREC
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
#endif // !defined(wxCRT_VsnprintfW_) || !defined(wxCRT_VsnprintfA)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxCRT_VsnprintfW_
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if !defined(wxCRT_VsnprintfW_)
|
||||||
|
|
||||||
|
#if !wxUSE_WXVSNPRINTFW
|
||||||
|
#error "wxUSE_WXVSNPRINTFW must be 1 if our wxCRT_VsnprintfW_ is used"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int wxCRT_VsnprintfW_(wchar_t *buf, size_t len,
|
||||||
|
const wchar_t *format, va_list argptr)
|
||||||
|
{
|
||||||
|
return wxDoVsnprintf(buf, len, format, argptr);
|
||||||
|
}
|
||||||
|
|
||||||
#else // wxCRT_VsnprintfW_ is defined
|
#else // wxCRT_VsnprintfW_ is defined
|
||||||
|
|
||||||
#if wxUSE_WXVSNPRINTFW
|
#if wxUSE_WXVSNPRINTFW
|
||||||
@@ -1060,3 +1048,27 @@ int WXDLLEXPORT wxCRT_VsnprintfW_(wchar_t *buf, size_t lenMax,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !wxCRT_VsnprintfW_
|
#endif // !wxCRT_VsnprintfW_
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxCRT_VsnprintfA
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef wxCRT_VsnprintfA
|
||||||
|
|
||||||
|
#if !wxUSE_WXVSNPRINTFA
|
||||||
|
#error "wxUSE_WXVSNPRINTFA must be 1 if our wxCRT_VsnprintfA is used"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int wxCRT_VsnprintfA(char *buf, size_t len,
|
||||||
|
const char *format, va_list argptr)
|
||||||
|
{
|
||||||
|
return wxDoVsnprintf(buf, len, format, argptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // wxCRT_VsnprintfA is defined
|
||||||
|
|
||||||
|
#if wxUSE_WXVSNPRINTFA
|
||||||
|
#error "wxUSE_WXVSNPRINTFA must be 0 if our wxCRT_VsnprintfA is not used"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !wxCRT_VsnprintfA
|
||||||
|
Reference in New Issue
Block a user