+ break;
+
+ case wxT('$'): // a positional parameter (e.g. %2$s) ?
+ {
+ if (min_width <= 0)
+ break; // ignore this formatting flag as no
+ // numbers are preceding it
+
+ // remove from szFlags all digits previously added
+ do {
+ flagofs--;
+ } while (szFlags[flagofs] >= '1' &&
+ szFlags[flagofs] <= '9');
+
+ // re-adjust the offset making it point to the
+ // next free char of szFlags
+ flagofs++;
+
+ pos = min_width;
+ min_width = 0;
+ }
+ break;
+
+ case wxT('d'):
+ case wxT('i'):
+ case wxT('o'):
+ case wxT('u'):
+ case wxT('x'):
+ case wxT('X'):
+ CHECK_PREC
+ szFlags[flagofs++] = ch;
+ szFlags[flagofs] = '\0';
+ if (ilen == 0)
+ type = wxPAT_INT;
+ else if (ilen == -1)
+ // NB: 'short int' value passed through '...'
+ // is promoted to 'int', so we have to get
+ // an int from stack even if we need a short
+ type = wxPAT_INT;
+ else if (ilen == 1)
+ type = wxPAT_LONGINT;
+ else if (ilen == 2)
+#if SIZEOF_LONG_LONG
+ type = wxPAT_LONGLONGINT;
+#else // !long long
+ type = wxPAT_LONGINT;
+#endif // long long/!long long
+ else if (ilen == 3)
+ type = wxPAT_SIZET;
+ done = true;
+ break;
+
+ case wxT('e'):
+ case wxT('E'):
+ case wxT('f'):
+ case wxT('g'):
+ case wxT('G'):
+ CHECK_PREC
+ szFlags[flagofs++] = ch;
+ szFlags[flagofs] = '\0';
+ if (ilen == 2)
+ type = wxPAT_LONGDOUBLE;
+ else
+ type = wxPAT_DOUBLE;
+ done = true;
+ break;
+
+ case wxT('p'):
+ type = wxPAT_POINTER;
+ done = true;
+ break;
+
+ case wxT('c'):
+ if (ilen == -1)
+ {
+ // in Unicode mode %hc == ANSI character
+ // and in ANSI mode, %hc == %c == ANSI...
+ type = wxPAT_CHAR;
+ }
+ else if (ilen == 1)
+ {
+ // in ANSI mode %lc == Unicode character
+ // and in Unicode mode, %lc == %c == Unicode...
+ type = wxPAT_WCHAR;
+ }
+ else
+ {
+#if wxUSE_UNICODE
+ // in Unicode mode, %c == Unicode character
+ type = wxPAT_WCHAR;
+#else
+ // in ANSI mode, %c == ANSI character
+ type = wxPAT_CHAR;
+#endif
+ }
+ done = true;
+ break;
+
+ case wxT('s'):
+ if (ilen == -1)
+ {
+ // Unicode mode wx extension: we'll let %hs mean non-Unicode
+ // strings (when in ANSI mode, %s == %hs == ANSI string)
+ type = wxPAT_PCHAR;
+ }
+ else if (ilen == 1)
+ {
+ // in Unicode mode, %ls == %s == Unicode string
+ // in ANSI mode, %ls == Unicode string
+ type = wxPAT_PWCHAR;
+ }
+ else
+ {
+#if wxUSE_UNICODE
+ type = wxPAT_PWCHAR;
+#else
+ type = wxPAT_PCHAR;
+#endif
+ }
+ done = true;
+ break;
+
+ case wxT('n'):
+ if (ilen == 0)
+ type = wxPAT_NINT;
+ else if (ilen == -1)
+ type = wxPAT_NSHORTINT;
+ else if (ilen >= 1)
+ type = wxPAT_NLONGINT;
+ done = true;
+ break;
+
+ default:
+ // bad format, don't consider this an argument;
+ // leave it unchanged
+ return false;
+ }
+ }
+ while (!done);
+
+ return true; // parsing was successful
+}
+
+
+void wxPrintfConvSpec::ReplaceAsteriskWith(int w)
+{
+ char temp[wxMAX_SVNPRINTF_FLAGBUFFER_LEN];
+
+ // find the first * in our flag buffer
+ char *pwidth = strchr(szFlags, '*');
+ wxASSERT(pwidth);
+
+ // save what follows the * (the +1 is to skip it!)
+ strcpy(temp, pwidth+1);
+ if (w < 0) {
+ pwidth[0] = '-';
+ pwidth++;
+ }
+
+ // replace * with the actual integer given as width
+ int offset = ::sprintf(pwidth,"%d",abs(w));
+
+ // restore after the expanded * what was following it
+ strcpy(pwidth+offset, temp);
+}
+
+bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
+{
+ // did the '*' width/precision specifier was used ?
+ if (max_width == -1)
+ {
+ // take the maxwidth specifier from the stack
+ max_width = va_arg(argptr, int);
+ if (max_width < 0)
+ max_width = 0;
+ else
+ ReplaceAsteriskWith(max_width);
+ }
+
+ if (min_width == -1)
+ {
+ // take the minwidth specifier from the stack
+ min_width = va_arg(argptr, int);
+
+ ReplaceAsteriskWith(min_width);
+ if (min_width < 0)
+ {
+ adj_left = !adj_left;
+ min_width = -min_width;
+ }
+ }
+
+ switch (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 = 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
+ static char szScratch[1024];
+ size_t lenCur = 0;