]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wxchar.cpp
All editors that derive from wxGridCellTextEditor will now select the
[wxWidgets.git] / src / common / wxchar.cpp
index 657a0554c2eac439d7e3d3ed1be5f2ff9d2df37c..2f030b8ed9152c38e54c50eff5761184cf01cf83 100644 (file)
@@ -40,8 +40,6 @@
   #include "wx/hash.h"
 #endif
 
-#include "wx/msgdlg.h"
-
 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H)
   #include <windef.h>
   #include <winbase.h>
@@ -119,6 +117,302 @@ size_t   WXDLLEXPORT wcslen(const wchar_t *s)
 }
 #endif
 
+#ifdef wxNEED_PRINTF_CONVERSION
+
+#define CONVERT_FORMAT_1  \
+    wxChar *new_format = (wxChar*) format; \
+    size_t old_len = wxStrlen( format ); \
+    int n = 0; \
+    size_t i; \
+    for (i = 0; i < old_len; i++) \
+    { \
+        if ( (format[i] == L'%') && \
+             ((i < old_len) && ((format[i+1] == L's') || (format[i+1] == L'c'))) && \
+             ((i == 0) || (format[i-1] != L'%')) ) \
+        { \
+            n++; \
+        } \
+    } \
+ \
+    if (n > 0) \
+    { \
+        new_format = new wxChar[old_len+n+1]; \
+        wxChar *s = new_format; \
+ \
+        for (i = 0; i < old_len+1; i++) \
+        { \
+            if ( (format[i] == L'%') && \
+                 ((i < old_len) && ((format[i+1] == L's') || (format[i+1] == L'c'))) && \
+                 ((i == 0) || (format[i-1] != L'%')) ) \
+            { \
+                *s = L'%'; \
+                s++; \
+                *s = L'l'; \
+                s++; \
+            } \
+            else \
+            { \
+                *s = format[i]; \
+                s++; \
+            } \
+        } \
+    }
+
+#define CONVERT_FORMAT_2 \
+    if (n > 0) \
+        delete [] new_format;
+    
+
+int wxScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_2
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+
+    int ret = vwscanf( new_format, argptr );
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+    
+    return ret;
+}
+
+int wxSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+
+    int ret = vswscanf( str, new_format, argptr );
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+    
+    return ret;
+}
+
+int wxFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+
+    int ret = vfwscanf(stream, new_format, argptr);
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+    
+    return ret;
+}
+
+int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap )
+{
+    CONVERT_FORMAT_1
+
+    int ret = vswscanf( str, new_format, ap );
+    
+    CONVERT_FORMAT_2
+
+    return ret;
+}
+
+int wxPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_2
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+    
+    int ret = vwprintf( new_format, argptr );
+    
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+
+    return ret;
+}
+
+int wxSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_4
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+
+    int ret = vswprintf( str, size, new_format, argptr );
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+
+    return ret;
+}
+
+int wxSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start(argptr, format);
+
+    // Ugly
+    int ret = vswprintf( str, 10000, new_format, argptr );
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+
+    return ret;
+}
+
+int wxFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3
+{
+    CONVERT_FORMAT_1
+
+    va_list argptr;
+    va_start( argptr, format );
+
+    int ret = vfwprintf( stream, new_format, argptr );
+
+    CONVERT_FORMAT_2
+
+    va_end(argptr);
+
+    return ret;
+}
+
+int wxVfprint( FILE *stream, const wxChar *format, va_list ap )
+{
+    CONVERT_FORMAT_1
+
+    int ret = vfwprintf( stream, new_format, ap );
+
+    CONVERT_FORMAT_2
+
+    return ret;
+}
+
+int wxVprintf( const wxChar *format, va_list ap )
+{
+    CONVERT_FORMAT_1
+
+    int ret = vwprintf( new_format, ap );
+
+    CONVERT_FORMAT_2
+
+    return ret;
+}
+
+int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap )
+{
+    CONVERT_FORMAT_1
+
+    int ret = vswprintf( str, size, new_format, ap );
+
+    CONVERT_FORMAT_2
+
+    return ret;
+}
+
+int wxVsprintf( wxChar *str, const wxChar *format, va_list ap )
+{
+    CONVERT_FORMAT_1
+
+    // This is so ugly
+    int ret = vswprintf(str, 10000, new_format, ap);
+
+    CONVERT_FORMAT_2
+
+    return ret;
+}
+#endif
+
+// we want to find out if the current platform supports vsnprintf()-like
+// function: for Unix this is done with configure, for Windows we test the
+// compiler explicitly.
+//
+// FIXME currently, this is only for ANSI (!Unicode) strings, so we call this
+//       function wxVsnprintfA (A for ANSI), should also find one for Unicode
+//       strings in Unicode build
+#ifdef __WXMSW__
+    #if defined(__VISUALC__) || (defined(__MINGW32__) && wxUSE_NORLANDER_HEADERS)
+        #define wxVsnprintfA     _vsnprintf
+    #endif
+#elif defined(__WXMAC__)
+    #define wxVsnprintfA       vsnprintf
+#else   // !Windows
+    #ifdef HAVE_VSNPRINTF
+        #define wxVsnprintfA       vsnprintf
+    #endif
+#endif  // Windows/!Windows
+
+#ifndef wxVsnprintfA
+    // in this case we'll use vsprintf() (which is ANSI and thus should be
+    // always available), but it's unsafe because it doesn't check for buffer
+    // size - so give a warning
+    #define wxVsnprintfA(buf, len, format, arg) vsprintf(buf, format, arg)
+
+    #if defined(__VISUALC__)
+        #pragma message("Using sprintf() because no snprintf()-like function defined")
+    #elif defined(__GNUG__)
+        #warning "Using sprintf() because no snprintf()-like function defined"
+    #endif //compiler
+#endif // no vsnprintf
+
+#if defined(_AIX)
+  // AIX has vsnprintf, but there's no prototype in the system headers.
+  extern "C" int vsnprintf(char* str, size_t n, const char* format, va_list ap);
+#endif
+
+#if !defined(wxVsnprintf) && !defined(wxHAS_VSNPRINTF)
+int WXDLLEXPORT wxVsnprintf(wxChar *buf, size_t len,
+                            const wxChar *format, va_list argptr)
+{
+#if wxUSE_UNICODE
+    wxString s;
+    int iLen = s.PrintfV(format, argptr);
+    if ( iLen != -1 )
+    {
+        wxStrncpy(buf, s.c_str(), len);
+        buf[len-1] = wxT('\0');
+    }
+
+    return iLen;
+#else // ANSI
+    // vsnprintf() will not terminate the string with '\0' if there is not
+    // enough place, but we want the string to always be NUL terminated
+    int rc = wxVsnprintfA(buf, len - 1, format, argptr);
+    if ( rc == -1 )
+    {
+        buf[len] = 0;
+    }
+
+    return rc;
+#endif // Unicode/ANSI
+}
+#endif
+
+#if !defined(wxSnprintf) && !defined(wxHAS_SNPRINTF)
+int WXDLLEXPORT wxSnprintf(wxChar *buf, size_t len,
+                           const wxChar *format, ...)
+{
+    va_list argptr;
+    va_start(argptr, format);
+
+    int iLen = wxVsnprintf(buf, len, format, argptr);
+
+    va_end(argptr);
+
+    return iLen;
+}
+#endif
+
 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H)
 inline WORD wxMSW_ctype(wxChar ch)
 {
@@ -200,9 +494,9 @@ WXDLLEXPORT wxChar * wxStrtok(wxChar *psz, const wxChar *delim, wxChar **save_pt
 #ifndef wxSetlocale
 WXDLLEXPORT wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
 {
-    char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
+    char *localeOld = setlocale(category, wxConvLocal.cWX2MB(locale));
 
-    return wxWCharBuffer(wxConvLibc.cMB2WC(localeOld));
+    return wxWCharBuffer(wxConvLocal.cMB2WC(localeOld));
 }
 #endif
 
@@ -335,7 +629,7 @@ WXDLLEXPORT double wxStrtod(const wxChar *nptr, wxChar **endptr)
   }
 
   wxString data(nptr, nptr-start);
-  wxWX2MBbuf dat = data.mb_str(wxConvLibc);
+  wxWX2MBbuf dat = data.mb_str(wxConvLocal);
   char *rdat = wxMBSTRINGCAST dat;
   double ret = strtod(dat, &rdat);
 
@@ -363,7 +657,7 @@ WXDLLEXPORT long int wxStrtol(const wxChar *nptr, wxChar **endptr, int base)
          (wxIsalpha(*nptr) && (wxToupper(*nptr) - wxT('A') + 10 < base))) nptr++;
 
   wxString data(nptr, nptr-start);
-  wxWX2MBbuf dat = data.mb_str(wxConvLibc);
+  wxWX2MBbuf dat = data.mb_str(wxConvLocal);
   char *rdat = wxMBSTRINGCAST dat;
   long int ret = strtol(dat, &rdat, base);
 
@@ -376,12 +670,20 @@ WXDLLEXPORT long int wxStrtol(const wxChar *nptr, wxChar **endptr, int base)
 #ifdef wxNEED_WX_STDIO_H
 WXDLLEXPORT FILE * wxFopen(const wxChar *path, const wxChar *mode)
 {
-    return fopen( wxConvFile.cWX2MB(path), wxConvLibc.cWX2MB(mode) );
+    char mode_buffer[10];
+    for (size_t i = 0; i < wxStrlen(mode)+1; i++)
+       mode_buffer[i] = (char) mode[i];
+    
+    return fopen( wxConvFile.cWX2MB(path), mode_buffer );
 }
 
 WXDLLEXPORT FILE * wxFreopen(const wxChar *path, const wxChar *mode, FILE *stream)
 {
-    return freopen( wxConvFile.cWX2MB(path), wxConvLibc.cWX2MB(mode), stream );
+    char mode_buffer[10];
+    for (size_t i = 0; i < wxStrlen(mode)+1; i++)
+       mode_buffer[i] = (char) mode[i];
+    
+    return freopen( wxConvFile.cWX2MB(path), mode_buffer, stream );
 }
 
 WXDLLEXPORT int wxRemove(const wxChar *path)
@@ -393,103 +695,24 @@ WXDLLEXPORT int wxRename(const wxChar *oldpath, const wxChar *newpath)
 {
     return rename( wxConvFile.cWX2MB(oldpath), wxConvFile.cWX2MB(newpath) );
 }
-
-int WXDLLEXPORT wxPrintf(const wxChar *fmt, ...)
-{
-  va_list argptr;
-  int ret;
-
-  va_start(argptr, fmt);
-  ret = wxVprintf(fmt, argptr);
-  va_end(argptr);
-  return ret;
-}
-
-int WXDLLEXPORT wxVprintf(const wxChar *fmt, va_list argptr)
-{
-  wxString str;
-  str.PrintfV(fmt,argptr);
-  printf("%s", (const char*)str.mb_str());
-  return str.Len();
-}
-
-int WXDLLEXPORT wxFprintf(FILE *stream, const wxChar *fmt, ...)
-{
-  va_list argptr;
-  int ret;
-
-  va_start(argptr, fmt);
-  ret = wxVfprintf(stream, fmt, argptr);
-  va_end(argptr);
-  return ret;
-}
-
-int WXDLLEXPORT wxVfprintf(FILE *stream, const wxChar *fmt, va_list argptr)
-{
-  wxString str;
-  str.PrintfV(fmt,argptr);
-  fprintf(stream, "%s", (const char*)str.mb_str());
-  return str.Len();
-}
-
-int WXDLLEXPORT wxSprintf(wxChar *buf, const wxChar *fmt, ...)
-{
-  va_list argptr;
-  int ret;
-
-  va_start(argptr, fmt);
-  ret = wxVsprintf(buf, fmt, argptr);
-  va_end(argptr);
-  return ret;
-}
-
-int WXDLLEXPORT wxVsprintf(wxChar *buf, const wxChar *fmt, va_list argptr)
-{
-  // this might be sort of inefficient, but it doesn't matter since
-  // we'd prefer people to use wxString::Printf directly instead anyway
-  wxString str;
-  str.PrintfV(fmt,argptr);
-  wxStrcpy(buf,str.c_str());
-  return str.Len();
-}
-
-int WXDLLEXPORT wxSscanf(const wxChar *buf, const wxChar *fmt, ...)
-{
-  va_list argptr;
-  int ret;
-
-  va_start(argptr, fmt);
-  ret = wxVsscanf(buf, fmt, argptr);
-  va_end(argptr);
-  return ret;
-}
-
-int WXDLLEXPORT wxVsscanf(const wxChar *buf, const wxChar *fmt, va_list argptr)
-{
-  int ret;
-  // this will work only for numeric conversion! Strings will not be converted correctly
-  // hopefully this is all we'll need
-  ret = vsscanf(wxConvLibc.cWX2MB(buf), wxConvLibc.cWX2MB(fmt), argptr);
-  return ret;
-}
 #endif
 
 #ifndef wxAtof
 double   WXDLLEXPORT wxAtof(const wxChar *psz)
 {
-  return atof(wxConvLibc.cWX2MB(psz));
+  return atof(wxConvLocal.cWX2MB(psz));
 }
 #endif
 
 #ifdef wxNEED_WX_STDLIB_H
 int      WXDLLEXPORT wxAtoi(const wxChar *psz)
 {
-  return atoi(wxConvLibc.cWX2MB(psz));
+  return atoi(wxConvLocal.cWX2MB(psz));
 }
 
 long     WXDLLEXPORT wxAtol(const wxChar *psz)
 {
-  return atol(wxConvLibc.cWX2MB(psz));
+  return atol(wxConvLocal.cWX2MB(psz));
 }
 
 wxChar * WXDLLEXPORT wxGetenv(const wxChar *name)
@@ -502,7 +725,7 @@ wxChar * WXDLLEXPORT wxGetenv(const wxChar *name)
   {
     // nope, retrieve it,
 #if wxUSE_UNICODE
-    wxCharBuffer buffer = wxConvLibc.cWX2MB(name);
+    wxCharBuffer buffer = wxConvLocal.cWX2MB(name);
     // printf( "buffer %s\n", (const char*) buffer );
     const char *val = getenv( (const char *)buffer );
 #else
@@ -514,7 +737,7 @@ wxChar * WXDLLEXPORT wxGetenv(const wxChar *name)
     
     // convert it,
 #ifdef wxUSE_UNICODE
-    data = (wxObject *)new wxString(val, wxConvLibc);
+    data = (wxObject *)new wxString(val, wxConvLocal);
 #else
     data = (wxObject *)new wxString(val);
 #endif
@@ -526,9 +749,9 @@ wxChar * WXDLLEXPORT wxGetenv(const wxChar *name)
   return (wxChar *)((wxString *)data)->c_str();
 }
 
-int      WXDLLEXPORT wxSystem(const wxChar *psz)
+int WXDLLEXPORT wxSystem(const wxChar *psz)
 {
-  return system(wxConvLibc.cWX2MB(psz));
+    return system(wxConvLocal.cWX2MB(psz));
 }
 
 #endif
@@ -536,17 +759,21 @@ int      WXDLLEXPORT wxSystem(const wxChar *psz)
 #ifdef wxNEED_WX_TIME_H
 WXDLLEXPORT size_t   wxStrftime(wxChar *s, size_t max, const wxChar *fmt, const struct tm *tm)
 {
-  if (!max) return 0;
-  char *buf = (char *)malloc(max);
-  size_t ret = strftime(buf, max, wxConvLibc.cWX2MB(fmt), tm);
-  if (ret) {
-    wxStrcpy(s, wxConvLibc.cMB2WX(buf));
-    free(buf);
-    return wxStrlen(s);
-  } else {
-    free(buf);
-    *s = 0;
-    return 0;
+    if (!max) return 0;
+    
+    char *buf = (char *)malloc(max);
+    size_t ret = strftime(buf, max, wxConvLocal.cWX2MB(fmt), tm);
+    if (ret)
+    {
+        wxStrcpy(s, wxConvLocal.cMB2WX(buf));
+        free(buf);
+        return wxStrlen(s);
+    } 
+    else
+    {
+        free(buf);
+        *s = 0;
+        return 0;
   }
 }
 #endif