]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
Uses wxUSE_WCHAR_T for compilers that don't support wchar_t.
[wxWidgets.git] / src / common / string.cpp
index 4126813a500f35fcb0fd9e8ac92fd29ea6b28bde..2d371b9fa4893a67ab64d2d8f63d177a4dff5c16 100644 (file)
@@ -256,8 +256,7 @@ wxString::wxString(const void *pStart, const void *pEnd)
 wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 {
   // first get necessary size
 wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 {
   // first get necessary size
-
-  size_t nLen = conv.MB2WC((wchar_t *) NULL, psz, 0);
+  size_t nLen = psz ? conv.MB2WC((wchar_t *) NULL, psz, 0) : 0;
 
   // nLength is number of *Unicode* characters here!
   if (nLen > nLength)
 
   // nLength is number of *Unicode* characters here!
   if (nLen > nLength)
@@ -279,8 +278,7 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength)
 wxString::wxString(const wchar_t *pwz)
 {
   // first get necessary size
 wxString::wxString(const wchar_t *pwz)
 {
   // first get necessary size
-
-  size_t nLen = wxWC2MB((char *) NULL, pwz, 0);
+  size_t nLen = pwz ? wxWC2MB((char *) NULL, pwz, 0) : 0;
 
   // empty?
   if ( nLen != 0 ) {
 
   // empty?
   if ( nLen != 0 ) {
@@ -1187,8 +1185,8 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr)
            if (s.Len() < min_width)
              s.Pad(min_width - s.Len(), _T(' '), adj_left);
            *this += s;
            if (s.Len() < min_width)
              s.Pad(min_width - s.Len(), _T(' '), adj_left);
            *this += s;
-           done = TRUE;
          }
          }
+         done = TRUE;
          break;
        case _T('n'):
          if (ilen == 0) {
          break;
        case _T('n'):
          if (ilen == 0) {
@@ -1937,27 +1935,25 @@ static void wxLoadCharacterSets(void)
 
   if (already_loaded) return;
 
 
   if (already_loaded) return;
 
-#if defined(__UNIX__) && wxUSE_UNICODE
+#if defined(__UNIX__)
   // search through files in /usr/share/i18n/charmaps
   wxString fname;
   // search through files in /usr/share/i18n/charmaps
   wxString fname;
-  printf("Commencing load\n");
   for (fname = ::wxFindFirstFile(_T("/usr/share/i18n/charmaps/*"));
        !fname.IsEmpty();
        fname = ::wxFindNextFile()) {
   for (fname = ::wxFindFirstFile(_T("/usr/share/i18n/charmaps/*"));
        !fname.IsEmpty();
        fname = ::wxFindNextFile()) {
-    wxPrintf(_("Loading: %s\n"), fname.c_str());
     wxTextFile cmap(fname);
     if (cmap.Open()) {
       wxCharacterSet *cset = new wxCharacterSet;
       wxString comchar,escchar;
       bool in_charset = FALSE;
 
     wxTextFile cmap(fname);
     if (cmap.Open()) {
       wxCharacterSet *cset = new wxCharacterSet;
       wxString comchar,escchar;
       bool in_charset = FALSE;
 
-      wxPrintf(_T("yup, loaded %s\n"),fname.c_str());
+      // wxFprintf(stderr,_T("Loaded: %s\n"),fname.c_str());
 
       wxString line;
       for (line = cmap.GetFirstLine();
           !cmap.Eof();
           line = cmap.GetNextLine()) {
 
       wxString line;
       for (line = cmap.GetFirstLine();
           !cmap.Eof();
           line = cmap.GetNextLine()) {
-       wxPrintf(_T("line contents: %s\n"),line.c_str());
+       // wxFprintf(stderr,_T("line contents: %s\n"),line.c_str());
        wxStringTokenizer token(line);
        wxString cmd = token.GetNextToken();
        if (cmd == comchar) {
        wxStringTokenizer token(line);
        wxString cmd = token.GetNextToken();
        if (cmd == comchar) {
@@ -1974,12 +1970,13 @@ static void wxLoadCharacterSets(void)
          comchar = token.GetNextToken();
        else if (cmd == _T("<escape_char>"))
          escchar = token.GetNextToken();
          comchar = token.GetNextToken();
        else if (cmd == _T("<escape_char>"))
          escchar = token.GetNextToken();
-       else if (cmd == _T("<mb_cur_min")) {
+       else if (cmd == _T("<mb_cur_min>")) {
          delete cset;
          delete cset;
-         goto forget_it; // we don't support multibyte charsets ourselves (yet)
+         cset = (wxCharacterSet *) NULL;
+         break; // we don't support multibyte charsets ourselves (yet)
        }
        else if (cmd == _T("CHARMAP")) {
        }
        else if (cmd == _T("CHARMAP")) {
-         cset->data = (wchar_t *)calloc(256, sizeof(wxChar));
+         cset->data = (wchar_t *)calloc(256, sizeof(wchar_t));
          in_charset = TRUE;
        }
        else if (cmd == _T("END")) {
          in_charset = TRUE;
        }
        else if (cmd == _T("END")) {
@@ -1988,19 +1985,31 @@ static void wxLoadCharacterSets(void)
        }
        else if (in_charset) {
          // format: <NUL> /x00 <U0000> NULL (NUL)
        }
        else if (in_charset) {
          // format: <NUL> /x00 <U0000> NULL (NUL)
+         //         <A>   /x41 <U0041> LATIN CAPITAL LETTER A
          wxString hex = token.GetNextToken();
          wxString hex = token.GetNextToken();
+         // skip whitespace (why doesn't wxStringTokenizer do this?)
+         while (wxIsEmpty(hex) && token.HasMoreTokens()) hex = token.GetNextToken();
          wxString uni = token.GetNextToken();
          wxString uni = token.GetNextToken();
-         // just assume that we've got the right format
-         int pos = ::wxHexToDec(hex.Mid(2,2));
-         unsigned long uni1 = ::wxHexToDec(uni.Mid(2,2));
-         unsigned long uni2 = ::wxHexToDec(uni.Mid(4,2));
-         cset->data[pos] = (uni1 << 16) | uni2;
+         // skip whitespace again
+         while (wxIsEmpty(uni) && token.HasMoreTokens()) uni = token.GetNextToken();
+
+         if ((hex.GetChar(0) == escchar) && (hex.GetChar(1) == _T('x')) &&
+             (uni.Left(2) == _T("<U"))) {
+           hex.MakeUpper(); uni.MakeUpper();
+           int pos = ::wxHexToDec(hex.Mid(2,2));
+           if (pos>=0) {
+             unsigned long uni1 = ::wxHexToDec(uni.Mid(2,2));
+             unsigned long uni2 = ::wxHexToDec(uni.Mid(4,2));
+             cset->data[pos] = (uni1 << 16) | uni2;
+             // wxFprintf(stderr,_T("char %02x mapped to %04x (%c)\n"),pos,cset->data[pos],cset->data[pos]);
+           }
+         }
        }
       }
        }
       }
-      cset->names.Shrink();
-      wxCharsets.Add(cset);
-    forget_it:
-      continue;
+      if (cset) {
+       cset->names.Shrink();
+       wxCharsets.Add(cset);
+      }
     }
   }
 #endif
     }
   }
 #endif
@@ -2010,6 +2019,7 @@ static void wxLoadCharacterSets(void)
 
 static wxCharacterSet *wxFindCharacterSet(const wxChar *charset)
 {
 
 static wxCharacterSet *wxFindCharacterSet(const wxChar *charset)
 {
+  if (!charset) return (wxCharacterSet *)NULL;
   wxLoadCharacterSets();
   for (size_t n=0; n<wxCharsets.GetCount(); n++)
     if (wxCharsets[n].names.Index(charset) != wxNOT_FOUND)
   wxLoadCharacterSets();
   for (size_t n=0; n<wxCharsets.GetCount(); n++)
     if (wxCharsets[n].names.Index(charset) != wxNOT_FOUND)
@@ -2021,15 +2031,19 @@ WXDLLEXPORT_DATA(wxCSConv) wxConv_local((const wxChar *)NULL);
 
 wxCSConv::wxCSConv(const wxChar *charset)
 {
 
 wxCSConv::wxCSConv(const wxChar *charset)
 {
-  if (!charset) {
-#ifdef __UNIX__
-    wxChar *lang = wxGetenv(_T("LANG"));
-    wxChar *dot = lang ? wxStrchr(lang, _T('.')) : (wxChar *)NULL;
-    if (dot) charset = dot+1;
-#endif
-  }
+  m_name = (wxChar *) NULL;
   m_cset = (wxCharacterSet *) NULL;
   m_cset = (wxCharacterSet *) NULL;
-  m_deferred = FALSE;
+  m_deferred = TRUE;
+  SetName(charset);
+}
+
+wxCSConv::~wxCSConv()
+{
+  if (m_name) free(m_name);
+}
+
+void wxCSConv::SetName(const wxChar *charset)
+{
   if (charset) {
 #ifdef __UNIX__
     // first, convert the character set name to standard form
   if (charset) {
 #ifdef __UNIX__
     // first, convert the character set name to standard form
@@ -2054,15 +2068,17 @@ wxCSConv::wxCSConv(const wxChar *charset)
   }
 }
 
   }
 }
 
-wxCSConv::~wxCSConv()
-{
-  free(m_name);
-}
-
 void wxCSConv::LoadNow()
 {
 //  wxPrintf(_T("Conversion request\n"));
   if (m_deferred) {
 void wxCSConv::LoadNow()
 {
 //  wxPrintf(_T("Conversion request\n"));
   if (m_deferred) {
+    if (!m_name) {
+#ifdef __UNIX__
+      wxChar *lang = wxGetenv(_T("LANG"));
+      wxChar *dot = lang ? wxStrchr(lang, _T('.')) : (wxChar *)NULL;
+      if (dot) SetName(dot+1);
+#endif
+    }
     m_cset = wxFindCharacterSet(m_name);
     m_deferred = FALSE;
   }
     m_cset = wxFindCharacterSet(m_name);
     m_deferred = FALSE;
   }
@@ -2073,15 +2089,16 @@ size_t wxCSConv::MB2WC(wchar_t *buf, const char *psz, size_t n) const
   ((wxCSConv *)this)->LoadNow(); // discard constness
   if (buf) {
     if (m_cset) {
   ((wxCSConv *)this)->LoadNow(); // discard constness
   if (buf) {
     if (m_cset) {
-      for (size_t c=0; c<=n; c++)
+      for (size_t c=0; c<n; c++)
        buf[c] = m_cset->data[psz[c]];
     } else {
       // latin-1 (direct)
        buf[c] = m_cset->data[psz[c]];
     } else {
       // latin-1 (direct)
-      for (size_t c=0; c<=n; c++)
+      for (size_t c=0; c<n; c++)
        buf[c] = psz[c];
     }
        buf[c] = psz[c];
     }
+    return n;
   }
   }
-  return n;
+  return strlen(psz);
 }
 
 size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const
 }
 
 size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const
@@ -2089,17 +2106,17 @@ size_t wxCSConv::WC2MB(char *buf, const wchar_t *psz, size_t n) const
   ((wxCSConv *)this)->LoadNow(); // discard constness
   if (buf) {
     if (m_cset) {
   ((wxCSConv *)this)->LoadNow(); // discard constness
   if (buf) {
     if (m_cset) {
-      for (size_t c=0; c<=n; c++) {
+      for (size_t c=0; c<n; c++) {
        size_t n;
        for (n=0; (n<256) && (m_cset->data[n] != psz[c]); n++);
        buf[c] = (n>0xff) ? '?' : n;
       }
     } else {
       // latin-1 (direct)
        size_t n;
        for (n=0; (n<256) && (m_cset->data[n] != psz[c]); n++);
        buf[c] = (n>0xff) ? '?' : n;
       }
     } else {
       // latin-1 (direct)
-      for (size_t c=0; c<=n; c++)
+      for (size_t c=0; c<n; c++)
        buf[c] = (psz[c]>0xff) ? '?' : psz[c];
     }
        buf[c] = (psz[c]>0xff) ? '?' : psz[c];
     }
+    return n;
   }
   }
-  return n;
+  return wcslen(psz);
 }
 }
-