#include <string.h>
#include <stdlib.h>
-#ifdef wxUSE_WCSRTOMBS
+#ifdef __SALFORDC__
+#include <clib.h>
+#endif
+
+#if wxUSE_WCSRTOMBS
#include <wchar.h> // for wcsrtombs(), see comments where it's used
#endif // GNU
// static class variables definition
// ---------------------------------------------------------------------------
-#ifdef STD_STRING_COMPATIBILITY
+#ifdef wxSTD_STRING_COMPATIBILITY
const size_t wxString::npos = STRING_MAXLEN;
-#endif
+#endif // wxSTD_STRING_COMPATIBILITY
// ----------------------------------------------------------------------------
// static data
} g_strEmpty = { {-1, 0, 0}, '\0' };
// empty C style string: points to 'string data' byte of g_strEmpty
-extern const char *g_szNul = &g_strEmpty.dummy;
+extern const char WXDLLEXPORT *g_szNul = &g_strEmpty.dummy;
+
+// ----------------------------------------------------------------------------
+// conditional compilation
+// ----------------------------------------------------------------------------
+
+// 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.
+#ifdef __WXMSW__
+ #ifdef _MSC_VER
+ #define wxVsprintf _vsnprintf
+ #endif
+#else // !Windows
+ #ifdef HAVE_VSNPRINTF
+ #define wxVsprintf vsnprintf
+ #endif
+#endif // Windows/!Windows
+
+#ifndef wxVsprintf
+ // 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 wxVsprintf(buffer,len,format,argptr) vsprintf(buffer,format, argptr)
+#ifndef __SC__
+ #pragma message("Using sprintf() because no snprintf()-like function defined")
+#endif
+#endif
// ----------------------------------------------------------------------------
// global functions
// ----------------------------------------------------------------------------
-#ifdef STD_STRING_COMPATIBILITY
+#ifdef wxSTD_STRING_COMPATIBILITY
// MS Visual C++ version 5.0 provides the new STL headers as well as the old
// iostream ones.
#endif
#ifdef __WXMSW__
- #ifdef _MSC_VER
- #define wxVsprintf _vsnprintf
- #endif
+ #ifdef _MSC_VER
+ #define wxVsprintf _vsnprintf
+ #endif
#else
- #if defined ( HAVE_VSNPRINTF )
- #define wxVsprintf vsnprintf
- #endif
+ #if defined ( HAVE_VSNPRINTF )
+ #define wxVsprintf vsnprintf
+ #endif
#endif
#ifndef wxVsprintf
- #ifdef HAVE_VPRINTF
+ // vsprintf() is ANSI so we can always use it, but it's unsafe!
#define wxVsprintf(buffer,len,format,argptr) vsprintf(buffer,format, argptr)
#pragma message("Using sprintf() because no snprintf()-like function defined")
- #else
- #pragma error("No vsnprintf() or vsprintf() function available.")
- #endif
#endif
NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str))
InitWith((const char *)psz, 0, nLength);
}
-#ifdef STD_STRING_COMPATIBILITY
+#ifdef wxSTD_STRING_COMPATIBILITY
// poor man's iterators are "void *" pointers
wxString::wxString(const void *pStart, const void *pEnd)
// NB: GNU libc5 wcstombs() is completely broken, don't use it (it doesn't
// honor the 3rd parameter, thus it will happily crash here).
-#ifdef wxUSE_WCSRTOMBS
+#if wxUSE_WCSRTOMBS
// don't know if it's really needed (or if we can pass NULL), but better safe
// than quick
mbstate_t mbstate;
pData->Unlock();
AllocBuffer(nLen);
}
+ else {
+ // update the string length
+ pData->nDataLength = nLen;
+ }
wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner
}
// get all characters after the last occurence of ch
// (returns the whole string if ch not found)
-wxString wxString::Right(char ch) const
+wxString wxString::AfterLast(char ch) const
{
wxString str;
int iPos = Find(ch, TRUE);
- if ( iPos == NOT_FOUND )
+ if ( iPos == wxNOT_FOUND )
str = *this;
else
str = c_str() + iPos + 1;
// get all characters before the first occurence of ch
// (returns the whole string if ch not found)
-wxString wxString::Left(char ch) const
+wxString wxString::BeforeFirst(char ch) const
{
wxString str;
for ( const char *pc = m_pchData; *pc != '\0' && *pc != ch; pc++ )
/// get all characters before the last occurence of ch
/// (returns empty string if ch not found)
-wxString wxString::Before(char ch) const
+wxString wxString::BeforeLast(char ch) const
{
wxString str;
int iPos = Find(ch, TRUE);
- if ( iPos != NOT_FOUND && iPos != 0 )
+ if ( iPos != wxNOT_FOUND && iPos != 0 )
str = wxString(c_str(), iPos);
return str;
/// get all characters after the first occurence of ch
/// (returns empty string if ch not found)
-wxString wxString::After(char ch) const
+wxString wxString::AfterFirst(char ch) const
{
wxString str;
int iPos = Find(ch);
- if ( iPos != NOT_FOUND )
+ if ( iPos != wxNOT_FOUND )
str = c_str() + iPos + 1;
return str;
psz++;
// fix up data and length
- int nDataLength = GetStringData()->nDataLength - (psz - m_pchData);
+ int nDataLength = GetStringData()->nDataLength - (psz - (const char*) m_pchData);
memmove(m_pchData, psz, (nDataLength + 1)*sizeof(char));
GetStringData()->nDataLength = nDataLength;
}
// truncate the string
wxString& wxString::Truncate(size_t uiLen)
{
- *(m_pchData + uiLen) = '\0';
- GetStringData()->nDataLength = uiLen;
+ if ( uiLen < Len() ) {
+ CopyBeforeWrite();
+
+ *(m_pchData + uiLen) = '\0';
+ GetStringData()->nDataLength = uiLen;
+ }
+ //else: nothing to do, string is already short enough
return *this;
}
// ---------------------------------------------------------------------------
-// finding (return NOT_FOUND if not found and index otherwise)
+// finding (return wxNOT_FOUND if not found and index otherwise)
// ---------------------------------------------------------------------------
// find a character
{
const char *psz = bFromEnd ? strrchr(m_pchData, ch) : strchr(m_pchData, ch);
- return (psz == NULL) ? NOT_FOUND : psz - m_pchData;
+ return (psz == NULL) ? wxNOT_FOUND : psz - (const char*) m_pchData;
}
// find a sub-string (like strstr)
{
const char *psz = strstr(m_pchData, pszSub);
- return (psz == NULL) ? NOT_FOUND : psz - m_pchData;
+ return (psz == NULL) ? wxNOT_FOUND : psz - (const char*) m_pchData;
}
// ---------------------------------------------------------------------------
int wxString::PrintfV(const char* pszFormat, va_list argptr)
{
-#if defined(__BORLANDC__) || defined(__GNUWIN32__)
- static char s_szScratch[1024];
-
- int iLen = vsprintf(s_szScratch, pszFormat, argptr);
- AllocBeforeWrite(iLen);
- strcpy(m_pchData, s_szScratch);
-
- return iLen;
-#else
-
// static buffer to avoid dynamic memory allocation each time
static char s_szScratch[1024];
+ // NB: wxVsprintf() may return either less than the buffer size or -1 if there
+ // is not enough place depending on implementation
int iLen = wxVsprintf(s_szScratch, WXSIZEOF(s_szScratch), pszFormat, argptr);
char *buffer;
- if ( (size_t)iLen < WXSIZEOF(s_szScratch) ) {
+ if ( iLen < (int)WXSIZEOF(s_szScratch) ) {
buffer = s_szScratch;
}
else {
free(buffer);
return iLen;
-#endif
}
// ----------------------------------------------------------------------------
return *pszTxt == '\0';
}
+// Count the number of chars
+int wxString::Freq(char ch) const
+{
+ int count = 0;
+ int len = Len();
+ for (int i = 0; i < len; i++)
+ {
+ if (GetChar(i) == ch)
+ count ++;
+ }
+ return count;
+}
+
// ---------------------------------------------------------------------------
// standard C++ library string functions
// ---------------------------------------------------------------------------
-#ifdef STD_STRING_COMPATIBILITY
+#ifdef wxSTD_STRING_COMPATIBILITY
wxString& wxString::insert(size_t nPos, const wxString& str)
{
}
#endif
+// Gives a duplicate symbol (presumably a case-insensitivity problem)
+#if !defined(__BORLANDC__)
size_t wxString::find(char ch, size_t nStart) const
{
wxASSERT( nStart <= Len() );
return p == NULL ? npos : p - c_str();
}
+#endif
size_t wxString::rfind(const wxString& str, size_t nStart) const
{
}
}
- return NOT_FOUND;
+ return wxNOT_FOUND;
}
// add item at the end
{
int iIndex = Index(sz);
- wxCHECK_RET( iIndex != NOT_FOUND,
+ wxCHECK_RET( iIndex != wxNOT_FOUND,
_("removing inexistent element in wxArrayString::Remove") );
Remove(iIndex);