+ int size = 1024;
+
+ for ( ;; )
+ {
+#if wxUSE_UNICODE_UTF8
+ BufferType tmp(str, size + 1);
+ typename BufferType::CharType *buf = tmp;
+#else
+ wxStringBuffer tmp(str, size + 1);
+ wxChar *buf = tmp;
+#endif
+
+ if ( !buf )
+ {
+ // out of memory
+
+ // in UTF-8 build, leaving uninitialized junk in the buffer
+ // could result in invalid non-empty UTF-8 string, so just
+ // reset the string to empty on failure:
+ buf[0] = '\0';
+ return -1;
+ }
+
+ // wxVsnprintf() may modify the original arg pointer, so pass it
+ // only a copy
+ va_list argptrcopy;
+ wxVaCopy(argptrcopy, argptr);
+ int len = wxVsnprintf(buf, size, format, argptrcopy);
+ va_end(argptrcopy);
+
+ // some implementations of vsnprintf() don't NUL terminate
+ // the string if there is not enough space for it so
+ // always do it manually
+ buf[size] = _T('\0');
+
+ // vsnprintf() may return either -1 (traditional Unix behaviour) or the
+ // total number of characters which would have been written if the
+ // buffer were large enough (newer standards such as Unix98)
+ if ( len < 0 )
+ {
+ // NB: wxVsnprintf() may call either wxCRT_VsnprintfW or
+ // wxCRT_VsnprintfA in UTF-8 build; wxUSE_WXVSNPRINTF
+ // is true if *both* of them use our own implementation,
+ // otherwise we can't be sure
+#if wxUSE_WXVSNPRINTF
+ // we know that our own implementation of wxVsnprintf() returns -1
+ // only for a format error - thus there's something wrong with
+ // the user's format string
+ buf[0] = '\0';
+ return -1;
+#else // possibly using system version
+ // assume it only returns error if there is not enough space, but
+ // as we don't know how much we need, double the current size of
+ // the buffer
+ size *= 2;
+#endif // wxUSE_WXVSNPRINTF/!wxUSE_WXVSNPRINTF
+ }
+ else if ( len >= size )
+ {
+#if wxUSE_WXVSNPRINTF
+ // we know that our own implementation of wxVsnprintf() returns
+ // size+1 when there's not enough space but that's not the size
+ // of the required buffer!
+ size *= 2; // so we just double the current size of the buffer
+#else
+ // some vsnprintf() implementations NUL-terminate the buffer and
+ // some don't in len == size case, to be safe always add 1
+ size = len + 1;
+#endif
+ }
+ else // ok, there was enough space
+ {
+ break;
+ }