]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/string.cpp
toplevel code transferred to wxTopLevelWindow
[wxWidgets.git] / src / common / string.cpp
index 902b9a5af744f21f6dc53b9310b4c108f203ed42..b45a1482a020d4bf564b139456d0f1bda485f849 100644 (file)
   #include <clib.h>
 #endif
 
-#if wxUSE_WCSRTOMBS
-  #include <wchar.h>    // for wcsrtombs(), see comments where it's used
-#endif // GNU
-
 #ifdef  WXSTRING_IS_WXOBJECT
   IMPLEMENT_DYNAMIC_CLASS(wxString, wxObject)
 #endif  //WXSTRING_IS_WXOBJECT
 // static class variables definition
 // ---------------------------------------------------------------------------
 
+#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
+// must define this static for VA or else you get multiply defined symbols
+// everywhere
+const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
+#endif // Visual Age
+
 #ifdef  wxSTD_STRING_COMPATIBILITY
   const size_t wxString::npos = wxSTRING_MAXLEN;
 #endif // wxSTD_STRING_COMPATIBILITY
@@ -85,12 +87,6 @@ static const struct
   wxChar dummy;
 } g_strEmpty = { {-1, 0, 0}, wxT('\0') };
 
-#if defined(__VISAGECPP__) && __IBMCPP__ >= 400
-// must define this static for VA or else you get multiply defined symbols
-// everywhere
-const unsigned int wxSTRING_MAXLEN = UINT_MAX - 100;
-#endif // Visual Age
-
 // empty C style string: points to 'string data' byte of g_strEmpty
 extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy;
 
@@ -137,7 +133,7 @@ extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy;
     #endif //compiler
 #endif // no vsnprintf
 
-#ifdef _AIX
+#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
@@ -499,18 +495,21 @@ void wxString::Shrink()
 {
   wxStringData *pData = GetStringData();
 
-  // this variable is unused in release build, so avoid the compiler warning
-  // by just not declaring it
-#ifdef __WXDEBUG__
-  void *p =
-#endif
-  realloc(pData, sizeof(wxStringData) + (pData->nDataLength + 1)*sizeof(wxChar));
+  size_t nLen = pData->nDataLength;
+  void *p = realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(wxChar));
 
-  // we rely on a reasonable realloc() implementation here - so far I haven't
-  // seen any which wouldn't behave like this
+  wxASSERT_MSG( p != NULL, _T("can't free memory?") );
+
+  if ( p != pData )
+  {
+      // contrary to what one might believe, some realloc() implementation do
+      // move the memory block even when its size is reduced
+      pData = (wxStringData *)p;
 
-  wxASSERT( p != NULL );  // can't free memory?
-  wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
+      m_pchData = pData->data();
+  }
+
+  pData->nAllocLength = nLen;
 }
 
 // get the pointer to writable buffer of (at least) nLen bytes
@@ -589,6 +588,7 @@ wxString& wxString::operator=(wxChar ch)
   return *this;
 }
 
+
 // assigns C string
 wxString& wxString::operator=(const wxChar *psz)
 {
@@ -1091,26 +1091,26 @@ int wxString::Find(const wxChar *pszSub) const
 // conversion to numbers
 // ----------------------------------------------------------------------------
 
-bool wxString::ToLong(long *val) const
+bool wxString::ToLong(long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToLong") );
 
     const wxChar *start = c_str();
     wxChar *end;
-    *val = wxStrtol(start, &end, 10);
+    *val = wxStrtol(start, &end, base);
 
     // return TRUE only if scan was stopped by the terminating NUL and if the
     // string was not empty to start with
     return !*end && (end != start);
 }
 
-bool wxString::ToULong(unsigned long *val) const
+bool wxString::ToULong(unsigned long *val, int base) const
 {
     wxCHECK_MSG( val, FALSE, _T("NULL pointer in wxString::ToULong") );
 
     const wxChar *start = c_str();
     wxChar *end;
-    *val = wxStrtoul(start, &end, 10);
+    *val = wxStrtoul(start, &end, base);
 
     // return TRUE only if scan was stopped by the terminating NUL and if the
     // string was not empty to start with
@@ -1456,6 +1456,53 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr)
 // of them)
 bool wxString::Matches(const wxChar *pszMask) const
 {
+    // I disable this code as it doesn't seem to be faster (in fact, it seems
+    // to be much slower) than the old, hand-written code below and using it
+    // here requires always linking with libregex even if the user code doesn't
+    // use it
+#if 0 // wxUSE_REGEX
+    // first translate the shell-like mask into a regex
+    wxString pattern;
+    pattern.reserve(wxStrlen(pszMask));
+
+    pattern += _T('^');
+    while ( *pszMask )
+    {
+        switch ( *pszMask )
+        {
+            case _T('?'):
+                pattern += _T('.');
+                break;
+
+            case _T('*'):
+                pattern += _T(".*");
+                break;
+
+            case _T('^'):
+            case _T('.'):
+            case _T('$'):
+            case _T('('):
+            case _T(')'):
+            case _T('|'):
+            case _T('+'):
+            case _T('\\'):
+                // these characters are special in a RE, quote them
+                // (however note that we don't quote '[' and ']' to allow
+                // using them for Unix shell like matching)
+                pattern += _T('\\');
+                // fall through
+
+            default:
+                pattern += *pszMask;
+        }
+
+        pszMask++;
+    }
+    pattern += _T('$');
+
+    // and now use it
+    return wxRegEx(pattern, wxRE_NOSUB | wxRE_EXTENDED).Matches(c_str());
+#else // !wxUSE_REGEX
   // TODO: this is, of course, awfully inefficient...
 
   // the char currently being checked
@@ -1539,6 +1586,7 @@ match:
   }
 
   return FALSE;
+#endif // wxUSE_REGEX/!wxUSE_REGEX
 }
 
 // Count the number of chars
@@ -1586,7 +1634,7 @@ void wxString::resize(size_t nSize, wxChar ch)
     }
     else if ( nSize > len )
     {
-        *this += wxString(ch, len - nSize);
+        *this += wxString(ch, nSize - len);
     }
     //else: we have exactly the specified length, nothing to do
 }
@@ -1652,7 +1700,7 @@ size_t wxString::find(wxChar ch, size_t nStart) const
 size_t wxString::rfind(const wxString& str, size_t nStart) const
 {
   wxASSERT( str.GetStringData()->IsValid() );
-  wxASSERT( nStart <= Len() );
+  wxASSERT( nStart == npos || nStart <= Len() );
 
   // TODO could be made much quicker than that
   const wxChar *p = c_str() + (nStart == npos ? Len() : nStart);
@@ -1669,7 +1717,7 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const
 #if !defined(__VISUALC__) || defined(__WIN32__)
 size_t wxString::rfind(const wxChar* sz, size_t nStart, size_t n) const
 {
-    return rfind(wxString(sz, n == npos ? 0 : n), nStart);
+    return rfind(wxString(sz, n == npos ? wxSTRING_MAXLEN : n), nStart);
 }
 
 size_t wxString::rfind(wxChar ch, size_t nStart) const
@@ -2110,6 +2158,16 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex)
   m_nCount++;
 }
 
+// expand the array
+void wxArrayString::SetCount(size_t count)
+{
+    Alloc(count);
+
+    wxString s;
+    while ( m_nCount < count )
+        m_pItems[m_nCount++] = (wxChar *)s.c_str();
+}
+
 // removes item from array (by index)
 void wxArrayString::Remove(size_t nIndex)
 {