+ done = true;
+ break;
+
+ case wxT('n'):
+ if (ilen == 0)
+ m_type = wxPAT_NINT;
+ else if (ilen == -1)
+ m_type = wxPAT_NSHORTINT;
+ else if (ilen >= 1)
+ m_type = wxPAT_NLONGINT;
+ done = true;
+ break;
+
+ default:
+ // bad format, don't consider this an argument;
+ // leave it unchanged
+ return false;
+ }
+
+ if (flagofs == wxMAX_SVNPRINTF_FLAGBUFFER_LEN)
+ {
+ wxLogDebug(wxT("Too many flags specified for a single conversion specifier!"));
+ return false;
+ }
+ }
+ while (!done);
+
+ return true; // parsing was successful
+}
+
+
+void wxPrintfConvSpec::ReplaceAsteriskWith(int width)
+{
+ wxChar temp[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
+
+ // find the first * in our flag buffer
+ wxChar *pwidth = wxStrchr(m_szFlags, wxT('*'));
+ wxASSERT(pwidth);
+
+ // save what follows the * (the +1 is to skip the asterisk itself!)
+ wxStrcpy(temp, pwidth+1);
+ if (width < 0)
+ {
+ pwidth[0] = wxT('-');
+ pwidth++;
+ }
+
+ // replace * with the actual integer given as width
+#if wxUSE_UNICODE
+ int maxlen = (m_szFlags + wxMAX_SVNPRINTF_FLAGBUFFER_LEN - pwidth) / sizeof(wxChar);
+ int offset = ::swprintf(pwidth, maxlen, L"%d", abs(width));
+#else
+ int offset = ::sprintf(pwidth, "%d", abs(width));
+#endif
+
+ // restore after the expanded * what was following it
+ wxStrcpy(pwidth+offset, temp);
+}
+
+bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
+{
+ // did the '*' width/precision specifier was used ?
+ if (m_nMaxWidth == -1)
+ {
+ // take the maxwidth specifier from the stack
+ m_nMaxWidth = va_arg(argptr, int);
+ if (m_nMaxWidth < 0)
+ m_nMaxWidth = 0;
+ else
+ ReplaceAsteriskWith(m_nMaxWidth);
+ }
+
+ if (m_nMinWidth == -1)
+ {
+ // take the minwidth specifier from the stack
+ m_nMinWidth = va_arg(argptr, int);
+
+ ReplaceAsteriskWith(m_nMinWidth);
+ if (m_nMinWidth < 0)
+ {
+ m_bAlignLeft = !m_bAlignLeft;
+ m_nMinWidth = -m_nMinWidth;
+ }
+ }
+
+ switch (m_type) {
+ case wxPAT_INT:
+ p->pad_int = va_arg(argptr, int);
+ break;
+ case wxPAT_LONGINT:
+ p->pad_longint = va_arg(argptr, long int);
+ break;
+#if SIZEOF_LONG_LONG
+ case wxPAT_LONGLONGINT:
+ p->pad_longlongint = va_arg(argptr, long long int);
+ break;
+#endif
+ case wxPAT_SIZET:
+ p->pad_sizet = va_arg(argptr, size_t);
+ break;
+ case wxPAT_DOUBLE:
+ p->pad_double = va_arg(argptr, double);
+ break;
+ case wxPAT_LONGDOUBLE:
+ p->pad_longdouble = va_arg(argptr, long double);
+ break;
+ case wxPAT_POINTER:
+ p->pad_pointer = va_arg(argptr, void *);
+ break;
+
+ case wxPAT_CHAR:
+ p->pad_char = va_arg(argptr, int); // char is promoted to int when passed through '...'
+ break;
+ case wxPAT_WCHAR:
+ p->pad_wchar = (wchar_t)va_arg(argptr, int); // char is promoted to int when passed through '...'
+ break;
+
+ case wxPAT_PCHAR:
+ p->pad_pchar = va_arg(argptr, char *);
+ break;
+ case wxPAT_PWCHAR:
+ p->pad_pwchar = va_arg(argptr, wchar_t *);
+ break;
+
+ case wxPAT_NINT:
+ p->pad_nint = va_arg(argptr, int *);
+ break;
+ case wxPAT_NSHORTINT:
+ p->pad_nshortint = va_arg(argptr, short int *);
+ break;
+ case wxPAT_NLONGINT:
+ p->pad_nlongint = va_arg(argptr, long int *);
+ break;
+
+ case wxPAT_INVALID:
+ default:
+ return false;
+ }
+
+ return true; // loading was successful
+}
+
+int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p)
+{
+ // buffer to avoid dynamic memory allocation each time for small strings;
+ // note that this buffer is used only to hold results of number formatting,
+ // %s directly writes user's string in buf, without using szScratch
+#define wxSCRATCH_BUFFER_SIZE 512
+
+ wxChar szScratch[wxSCRATCH_BUFFER_SIZE];
+ size_t lenScratch = 0, lenCur = 0;
+
+#if wxUSE_UNICODE
+#define system_sprintf(buff, flags, data) ::swprintf(buff, wxSCRATCH_BUFFER_SIZE, flags, data)
+#else
+#define system_sprintf ::sprintf
+#endif