]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wxchar.cpp
Fixed mismatch between wxOperatingSystemIdNames and wxOperatingSystemId (patch #1625019).
[wxWidgets.git] / src / common / wxchar.cpp
index e49acc8798eb2ec2e9516924720d8c49ee7fad57..962a705dcda45b434e9bb74916a71b8416d1e039 100644 (file)
@@ -317,7 +317,7 @@ public:
     // Process this conversion specifier and puts the result in the given
     // buffer. Returns the number of characters written in 'buf' or -1 if
     // there's not enough space.
-    int Process(wxChar *buf, size_t lenMax, wxPrintfArg *p);
+    int Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t written);
 
     // Loads the argument of this conversion specifier from given va_list.
     bool LoadArg(wxPrintfArg *p, va_list &argptr);
@@ -624,7 +624,7 @@ void wxPrintfConvSpec::ReplaceAsteriskWith(int width)
 
     // find the first * in our flag buffer
     char *pwidth = strchr(m_szFlags, '*');
-    wxASSERT(pwidth);
+    wxCHECK_RET(pwidth, _T("field width must be specified"));
 
     // save what follows the * (the +1 is to skip the asterisk itself!)
     strcpy(temp, pwidth+1);
@@ -728,7 +728,7 @@ bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
     return true;    // loading was successful
 }
 
-int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p)
+int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t written)
 {
     // buffer to avoid dynamic memory allocation each time for small strings;
     // note that this buffer is used only to hold results of number formatting,
@@ -906,15 +906,15 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p)
             break;
 
         case wxPAT_NINT:
-            *p->pad_nint = lenCur;
+            *p->pad_nint = written;
             break;
 
         case wxPAT_NSHORTINT:
-            *p->pad_nshortint = (short int)lenCur;
+            *p->pad_nshortint = (short int)written;
             break;
 
         case wxPAT_NLONGINT:
-            *p->pad_nlongint = lenCur;
+            *p->pad_nlongint = written;
             break;
 
         case wxPAT_INVALID:
@@ -993,19 +993,23 @@ 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)
+// 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
+// number of chars actually written. Does not treat null specially.
+//
+static int wxCopyStrWithPercents(
+        size_t maxOut,
+        wxChar *dest,
+        size_t maxIn,
+        const wxChar *source)
 {
     size_t written = 0;
 
-    if (n == 0)
+    if (maxIn == 0)
         return 0;
 
     size_t i;
-    for ( i = 0; i < n-1; source++, i++)
+    for ( i = 0; i < maxIn-1 && written < maxOut; source++, i++)
     {
         dest[written++] = *source;
         if (*(source+1) == wxT('%'))
@@ -1016,7 +1020,7 @@ static int wxCopyStrWithPercents(wxChar *dest, const wxChar *source, size_t n)
         }
     }
 
-    if (i < n)
+    if (i < maxIn && written < maxOut)
         // copy last character inconditionally
         dest[written++] = *source;
 
@@ -1097,8 +1101,10 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
     }
 
     if (posarg_present && nonposarg_present)
+    {
+        buf[0] = 0;
         return -1;      // format strings with both positional and
-                        // non-positional conversion specifier are unsupported !!
+    }                   // 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.
@@ -1119,7 +1125,10 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
 
     // something failed while loading arguments from the variable list...
     if (!ok)
+    {
+        buf[0] = 0;
         return -1;
+    }
 
     // finally, process each conversion specifier with its own argument
     toparse = format;
@@ -1128,19 +1137,17 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
         // copy in the output buffer the portion of the format string between
         // last specifier and the current one
         size_t tocopy = ( arg[i].m_pArgPos - toparse );
-        if (lenCur+tocopy >= lenMax)
+
+        lenCur += wxCopyStrWithPercents(lenMax - lenCur, buf + lenCur,
+                                        tocopy, toparse);
+        if (lenCur == lenMax)
         {
-            // not enough space in the output buffer !
-            // copy until the end of remaining space and then stop
-            wxCopyStrWithPercents(buf+lenCur, toparse, lenMax - lenCur - 1);
-            buf[lenMax-1] = wxT('\0');
+            buf[lenMax - 1] = 0;
             return -1;
         }
 
-        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].m_pos]);
+        int n = arg[i].Process(buf+lenCur, lenMax - lenCur, &argdata[arg[i].m_pos], lenCur);
         if (n == -1)
         {
             buf[lenMax-1] = wxT('\0');  // be sure to always NUL-terminate the string
@@ -1158,11 +1165,14 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
     //       conversion specifier
     // NOTE2: the +1 is because we want to copy also the '\0'
     size_t tocopy = wxStrlen(format) + 1  - ( toparse - format ) ;
-    if (lenCur+tocopy >= lenMax)
-        return -1;      // not enough space in the output buffer !
 
-    // the -1 is because of the '\0'
-    lenCur += wxCopyStrWithPercents(buf+lenCur, toparse, tocopy) - 1;
+    lenCur += wxCopyStrWithPercents(lenMax - lenCur, buf + lenCur, 
+                                    tocopy, toparse) - 1;
+    if (buf[lenCur])
+    {
+        buf[lenCur] = 0;
+        return -1;
+    }
 
     wxASSERT(lenCur == wxStrlen(buf));
     return lenCur;
@@ -1212,9 +1222,13 @@ int WXDLLEXPORT wxSnprintf_(wxChar *buf, size_t len, const wxChar *format, ...)
 #ifdef wxNEED_FPUTS
 int wxFputs(const wchar_t *ws, FILE *stream)
 {
+    wxCharBuffer buf(wxConvLibc.cWC2MB(ws));
+    if ( !buf )
+        return -1;
+
     // counting the number of wide characters written isn't worth the trouble,
     // simply distinguish between ok and error
-    return fputs(wxConvLibc.cWC2MB(ws), stream) == -1 ? -1 : 0;
+    return fputs(buf, stream) == -1 ? -1 : 0;
 }
 #endif // wxNEED_FPUTS