X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a31746c7de9d15ae29bafcdf45f1ee23eca40de6..49b6ebb7e15f76f6a2076e43dfda10a13de3e605:/src/common/wxchar.cpp?ds=sidebyside diff --git a/src/common/wxchar.cpp b/src/common/wxchar.cpp index 3532e0533b..d6fd73b0a3 100644 --- a/src/common/wxchar.cpp +++ b/src/common/wxchar.cpp @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/common/wxchar.cpp // Purpose: wxChar implementation -// Author: Ove Kåven -// Modified by: Ron Lee +// Author: Ove Kaven +// Modified by: Ron Lee, Francesco Montorsi // Created: 09/04/99 // RCS-ID: $Id$ // Copyright: (c) wxWidgets copyright @@ -901,6 +901,36 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p) return lenCur; } +// differences from standard strncpy: +// 1) copies everything from 'source' except for '%%' sequence which is copied as '%' +// 2) returns the number of written characters in 'dest' as it could differ from given 'n' +// 3) much less optimized, unfortunately... +static int wxCopyStrWithPercents(wxChar *dest, const wxChar *source, size_t n) +{ + size_t written = 0; + + if (n == 0) + return 0; + + size_t i; + for ( i = 0; i < n-1; source++, i++) + { + dest[written++] = *source; + if (*(source+1) == wxT('%')) + { + // skip this additional '%' character + source++; + i++; + } + } + + if (i < n) + // copy last character inconditionally + dest[written++] = *source; + + return written; +} + int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax, const wxChar *format, va_list argptr) { @@ -958,15 +988,26 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax, return -1; // format strings with both positional and // non-positional conversion specifier are unsupported !! + // on platforms where va_list is an array type, it is necessary to make a + // copy to be able to pass it to LoadArg as a reference. + bool ok = true; + va_list ap; + wxVaCopy(ap, argptr); + // now load arguments from stack - for (i=0; i < nargs; i++) { - if (!pspec[i]) - return -1; // user forgot a positional parameter (e.g. %$1s %$3s) ? - if (!pspec[i]->LoadArg(&argdata[i], argptr)) - return -1; // this means that wxPrintfConvSpec::Parse failed - // to set its 'type' to a valid value... + for (i=0; i < nargs && ok; i++) { + // !pspec[i] if user forgot a positional parameter (e.g. %$1s %$3s) ? + // or LoadArg false if wxPrintfConvSpec::Parse failed to set its 'type' + // to a valid value... + ok = pspec[i] && pspec[i]->LoadArg(&argdata[i], ap); } + va_end(ap); + + // something failed while loading arguments from the variable list... + if (!ok) + return -1; + // finally, process each conversion specifier with its own argument toparse = format; for (i=0; i < nargs; i++) @@ -977,8 +1018,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax, if (lenCur+tocopy >= lenMax) return -1; // not enough space in the output buffer ! - wxStrncpy(buf+lenCur, toparse, tocopy); - lenCur += tocopy; + lenCur += wxCopyStrWithPercents(buf+lenCur, toparse, tocopy); // process this specifier directly in the output buffer int n = arg[i].Process(buf+lenCur, lenMax - lenCur, &argdata[arg[i].pos]); @@ -998,8 +1038,9 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax, size_t tocopy = wxStrlen(format) + 1 - ( toparse - format ) ; if (lenCur+tocopy >= lenMax) return -1; // not enough space in the output buffer ! - wxStrncpy(buf+lenCur, toparse, tocopy); - lenCur += tocopy - 1; // the -1 is because of the '\0' + + // the -1 is because of the '\0' + lenCur += wxCopyStrWithPercents(buf+lenCur, toparse, tocopy) - 1; // clean the static array portion used... // NOTE: other arrays do not need cleanup!