#include <string.h>
#include <stdlib.h>
+// This probably isn't right, what should it be Vadim?
+// Otherwise we end up with no wxVsprintf defined.
+#ifdef __WXMOTIF__
+#define HAVE_VPRINTF
+#endif
+
#ifdef wxUSE_WCSRTOMBS
#include <wchar.h> // for wcsrtombs(), see comments where it's used
#endif // GNU
// empty C style string: points to 'string data' byte of g_strEmpty
extern const char *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)
+ #pragma message("Using sprintf() because no snprintf()-like function defined")
+#endif
+
// ----------------------------------------------------------------------------
// global functions
// ----------------------------------------------------------------------------
// iostream ones.
//
// ATTN: you can _not_ use both of these in the same program!
-#if 0 // def _MSC_VER
- #include <iostream>
- #define NAMESPACE std::
+#if wxUSE_IOSTREAMH
+#include <iostream.h>
+#define NAMESPACE
#else
- #include <iostream.h>
- #define NAMESPACE
-#endif //Visual C++
+#include <iostream>
+# ifdef _MSC_VER
+ using namespace std;
+# endif
+// for msvc (bcc50+ also) you don't need these NAMESPACE defines,
+// using namespace std; takes care of that.
+#define NAMESPACE std::
+#endif
+
+#ifdef __WXMSW__
+ #ifdef _MSC_VER
+ #define wxVsprintf _vsnprintf
+ #endif
+#else
+ #if defined ( HAVE_VSNPRINTF )
+ #define wxVsprintf vsnprintf
+ #endif
+#endif
+
+#ifndef wxVsprintf
+ // 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")
+#endif
NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str))
{
// 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;
}
return (psz == NULL) ? NOT_FOUND : psz - m_pchData;
}
+// ---------------------------------------------------------------------------
+// stream-like operators
+// ---------------------------------------------------------------------------
+wxString& wxString::operator<<(int i)
+{
+ wxString res;
+ res.Printf("%d", i);
+
+ return (*this) << res;
+}
+
+wxString& wxString::operator<<(float f)
+{
+ wxString res;
+ res.Printf("%f", f);
+
+ return (*this) << res;
+}
+
+wxString& wxString::operator<<(double d)
+{
+ wxString res;
+ res.Printf("%g", d);
+
+ return (*this) << res;
+}
+
// ---------------------------------------------------------------------------
// formatted output
// ---------------------------------------------------------------------------
int wxString::PrintfV(const char* pszFormat, va_list argptr)
{
+ // static buffer to avoid dynamic memory allocation each time
static char s_szScratch[1024];
- int iLen = vsprintf(s_szScratch, pszFormat, argptr);
+ // 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 ( iLen < (int)WXSIZEOF(s_szScratch) ) {
+ buffer = s_szScratch;
+ }
+ else {
+ int size = WXSIZEOF(s_szScratch) * 2;
+ buffer = (char *)malloc(size);
+ while ( buffer != NULL ) {
+ iLen = wxVsprintf(buffer, WXSIZEOF(s_szScratch), pszFormat, argptr);
+ if ( iLen < size ) {
+ // ok, there was enough space
+ break;
+ }
+
+ // still not enough, double it again
+ buffer = (char *)realloc(buffer, size *= 2);
+ }
+
+ if ( !buffer ) {
+ // out of memory
+ return -1;
+ }
+ }
+
AllocBeforeWrite(iLen);
- strcpy(m_pchData, s_szScratch);
+ strcpy(m_pchData, buffer);
+
+ if ( buffer != s_szScratch )
+ free(buffer);
return iLen;
}
}
#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
{