]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wxchar.cpp
fix assert because of passing more than one border bit in style to the base class...
[wxWidgets.git] / src / common / wxchar.cpp
index 962a705dcda45b434e9bb74916a71b8416d1e039..9afb608e493a59fd47b9ef5abf74a7ea31abdb3d 100644 (file)
@@ -167,6 +167,10 @@ bool WXDLLEXPORT wxOKlibc()
 
 #if !defined(wxVsnprintf_)
 
+#if !wxUSE_WXVSNPRINTF
+    #error wxUSE_WXVSNPRINTF must be 1 if our wxVsnprintf_ is used
+#endif
+
 // wxUSE_STRUTILS says our wxVsnprintf_ implementation to use or not to
 // use wxStrlen and wxStrncpy functions over one-char processing loops.
 //
@@ -213,7 +217,7 @@ enum wxPrintfArgType {
 
     wxPAT_INT,          // %d, %i, %o, %u, %x, %X
     wxPAT_LONGINT,      // %ld, etc
-#if SIZEOF_LONG_LONG
+#ifdef wxLongLong_t
     wxPAT_LONGLONGINT,  // %Ld, etc
 #endif
     wxPAT_SIZET,        // %Zd, etc
@@ -238,8 +242,8 @@ enum wxPrintfArgType {
 typedef union {
     int pad_int;                        //  %d, %i, %o, %u, %x, %X
     long int pad_longint;               // %ld, etc
-#if SIZEOF_LONG_LONG
-    long long int pad_longlongint;      // %Ld, etc
+#ifdef wxLongLong_t
+    wxLongLong_t pad_longlongint;      // %Ld, etc
 #endif
     size_t pad_sizet;                   // %Zd, etc
 
@@ -347,7 +351,8 @@ bool wxPrintfConvSpec::Parse(const wxChar *format)
 
     // temporary parse data
     size_t flagofs = 1;
-    bool in_prec, prec_dot;
+    bool in_prec,       // true if we found the dot in some previous iteration
+         prec_dot;      // true if the dot has been already added to m_szFlags
     int ilen = 0;
 
     m_bAlignLeft = in_prec = prec_dot = false;
@@ -417,6 +422,25 @@ bool wxPrintfConvSpec::Parse(const wxChar *format)
                 CHECK_PREC
                 m_szFlags[flagofs++] = char(ch);
                 break;
+#ifdef __WXMSW__
+            // under Windows we support the special '%I64' notation as longlong
+            // integer conversion specifier for MSVC compatibility
+            // (it behaves exactly as '%lli' or '%Li' or '%qi')
+            case wxT('I'):
+                if (*(m_pArgEnd+1) != wxT('6') ||
+                    *(m_pArgEnd+2) != wxT('4'))
+                    return false;       // bad format
+
+                m_pArgEnd++;
+                m_pArgEnd++;
+
+                ilen = 2;
+                CHECK_PREC
+                m_szFlags[flagofs++] = char(ch);
+                m_szFlags[flagofs++] = '6';
+                m_szFlags[flagofs++] = '4';
+                break;
+#endif      // __WXMSW__
 
             case wxT('Z'):
                 ilen = 3;
@@ -508,11 +532,11 @@ bool wxPrintfConvSpec::Parse(const wxChar *format)
                 else if (ilen == 1)
                     m_type = wxPAT_LONGINT;
                 else if (ilen == 2)
-#if SIZEOF_LONG_LONG
+#ifdef wxLongLong_t
                     m_type = wxPAT_LONGLONGINT;
-#else // !long long
+#else // !wxLongLong_t
                     m_type = wxPAT_LONGINT;
-#endif // long long/!long long
+#endif // wxLongLong_t/!wxLongLong_t
                 else if (ilen == 3)
                     m_type = wxPAT_SIZET;
                 done = true;
@@ -678,11 +702,11 @@ bool wxPrintfConvSpec::LoadArg(wxPrintfArg *p, va_list &argptr)
         case wxPAT_LONGINT:
             p->pad_longint = va_arg(argptr, long int);
             break;
-#if SIZEOF_LONG_LONG
+#ifdef wxLongLong_t
         case wxPAT_LONGLONGINT:
-            p->pad_longlongint = va_arg(argptr, long long int);
+            p->pad_longlongint = va_arg(argptr, wxLongLong_t);
             break;
-#endif
+#endif // wxLongLong_t
         case wxPAT_SIZET:
             p->pad_sizet = va_arg(argptr, size_t);
             break;
@@ -762,7 +786,7 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
             lenScratch = system_sprintf(szScratch, wxMAX_SVNPRINTF_SCRATCHBUFFER_LEN, m_szFlags, p->pad_longint);
             break;
 
-#if SIZEOF_LONG_LONG
+#ifdef wxLongLong_t
         case wxPAT_LONGLONGINT:
             lenScratch = system_sprintf(szScratch, wxMAX_SVNPRINTF_SCRATCHBUFFER_LEN, m_szFlags, p->pad_longlongint);
             break;
@@ -928,7 +952,7 @@ int wxPrintfConvSpec::Process(wxChar *buf, size_t lenMax, wxPrintfArg *p, size_t
     {
         case wxPAT_INT:
         case wxPAT_LONGINT:
-#if SIZEOF_LONG_LONG
+#ifdef wxLongLong_t
         case wxPAT_LONGLONGINT:
 #endif
         case wxPAT_SIZET:
@@ -1124,6 +1148,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
     va_end(ap);
 
     // something failed while loading arguments from the variable list...
+    // (e.g. the user repeated twice the same positional argument)
     if (!ok)
     {
         buf[0] = 0;
@@ -1143,7 +1168,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
         if (lenCur == lenMax)
         {
             buf[lenMax - 1] = 0;
-            return -1;
+            return lenMax+1;      // not enough space in the output buffer !
         }
 
         // process this specifier directly in the output buffer
@@ -1151,7 +1176,7 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
         if (n == -1)
         {
             buf[lenMax-1] = wxT('\0');  // be sure to always NUL-terminate the string
-            return -1;      // not enough space in the output buffer !
+            return lenMax+1;      // not enough space in the output buffer !
         }
         lenCur += n;
 
@@ -1171,10 +1196,14 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
     if (buf[lenCur])
     {
         buf[lenCur] = 0;
-        return -1;
+        return lenMax+1;     // not enough space in the output buffer !
     }
 
-    wxASSERT(lenCur == wxStrlen(buf));
+    // Don't do:
+    //      wxASSERT(lenCur == wxStrlen(buf));
+    // in fact if we embedded NULLs in the output buffer (using %c with a '\0')
+    // such check would fail
+
     return lenCur;
 }
 
@@ -1182,10 +1211,16 @@ int WXDLLEXPORT wxVsnprintf_(wxChar *buf, size_t lenMax,
 #undef APPEND_STR
 #undef CHECK_PREC
 
-#endif // !wxVsnprintfA
+#else    // wxVsnprintf_ is defined
+
+#if wxUSE_WXVSNPRINTF
+    #error wxUSE_WXVSNPRINTF must be 0 if our wxVsnprintf_ is not used
+#endif
+
+#endif // !wxVsnprintf_
 
 #if !defined(wxSnprintf_)
-int WXDLLEXPORT wxSnprintf_(wxChar *buf, size_t len, const wxChar *format, ...)
+int WXDLLEXPORT wxDoSnprintf_(wxChar *buf, size_t len, const wxChar *format, ...)
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1201,7 +1236,7 @@ int WXDLLEXPORT wxSnprintf_(wxChar *buf, size_t len, const wxChar *format, ...)
 #if defined(__DMC__)
     /* Digital Mars adds count to _stprintf (C99) so convert */
     #if wxUSE_UNICODE
-        int wxSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... )
+        int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... )
         {
             va_list arglist;
 
@@ -1541,7 +1576,7 @@ wxString wxConvertFormat(const wxChar *format)
 
 #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF)
 
-int wxScanf( const wxChar *format, ... )
+int wxDoScanf( const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1553,7 +1588,7 @@ int wxScanf( const wxChar *format, ... )
     return ret;
 }
 
-int wxSscanf( const wxChar *str, const wxChar *format, ... )
+int wxDoSscanf( const wxChar *str, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1565,7 +1600,7 @@ int wxSscanf( const wxChar *str, const wxChar *format, ... )
     return ret;
 }
 
-int wxFscanf( FILE *stream, const wxChar *format, ... )
+int wxDoFscanf( FILE *stream, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1576,7 +1611,7 @@ int wxFscanf( FILE *stream, const wxChar *format, ... )
     return ret;
 }
 
-int wxPrintf( const wxChar *format, ... )
+int wxDoPrintf( const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1589,7 +1624,7 @@ int wxPrintf( const wxChar *format, ... )
 }
 
 #ifndef wxSnprintf
-int wxSnprintf( wxChar *str, size_t size, const wxChar *format, ... )
+int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1606,7 +1641,7 @@ int wxSnprintf( wxChar *str, size_t size, const wxChar *format, ... )
 }
 #endif // wxSnprintf
 
-int wxSprintf( wxChar *str, const wxChar *format, ... )
+int wxDoSprintf( wxChar *str, const wxChar *format, ... )
 {
     va_list argptr;
     va_start(argptr, format);
@@ -1621,7 +1656,7 @@ int wxSprintf( wxChar *str, const wxChar *format, ... )
     return s.length();
 }
 
-int wxFprintf( FILE *stream, const wxChar *format, ... )
+int wxDoFprintf( FILE *stream, const wxChar *format, ... )
 {
     va_list argptr;
     va_start( argptr, format );
@@ -2230,3 +2265,34 @@ int wxRemove(const wxChar *path)
 }
 
 #endif
+
+// ----------------------------------------------------------------------------
+// wxUniChar
+// ----------------------------------------------------------------------------
+
+/* static */
+wxUniChar::unicode_type wxUniChar::From8bit(char c)
+{
+    // all supported charsets have the first 128 characters same as ASCII:
+    if ( (unsigned char)c < 0x80 )
+        return c;
+
+    wchar_t buf[2];
+    if ( wxConvLibc.ToWChar(buf, 2, &c, 1) != 2 )
+        return wxT('?'); // FIXME-UTF8: what to use as failure character?
+    return buf[0];
+}
+
+/* static */
+char wxUniChar::To8bit(wxUniChar::unicode_type c)
+{
+    // all supported charsets have the first 128 characters same as ASCII:
+    if ( c < 0x80 )
+        return c;
+
+    wchar_t in = c;
+    char buf[2];
+    if ( wxConvLibc.FromWChar(buf, 2, &in, 1) != 2 )
+        return '?'; // FIXME-UTF8: what to use as failure character?
+    return buf[0];
+}