// Name: wx/wxcrt.h
// Purpose: Type-safe ANSI and Unicode builds compatible wrappers for
// CRT functions
-// Author: Joel Farley, Ove K�ven
+// Author: Joel Farley, Ove Kaaven
// Modified by: Vadim Zeitlin, Robert Roebling, Ron Lee, Vaclav Slavik
// Created: 1998/06/12
// RCS-ID: $Id$
#include "wx/wxcrtbase.h"
#include "wx/string.h"
+#ifndef __WX_SETUP_H__
+// For non-configure builds assume vsscanf is available, if not Visual C or DMC
+#if !defined (__VISUALC__) && !defined (__DMC__)
+ #define HAVE_VSSCANF 1
+#endif
+#endif
+
// ============================================================================
// misc functions
// ============================================================================
inline bool wxIsEmpty(const wxCStrData& s) { return s.AsString().empty(); }
-// FIXME-UTF8: get rid of this, it's ANSI only anyway
-WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */
-
/* multibyte to wide char conversion functions and macros */
// (including even MSC) inline them just like we do right in their
// headers.
//
-#if wxUSE_UNICODE
- #include <string.h> //for mem funcs
+#include <string.h>
+#if wxUSE_UNICODE
//implement our own wmem variants
inline wxChar* wxTmemchr(const wxChar* s, wxChar c, size_t l)
{
return szRet;
}
-
- // and trivial wrappers for char* versions:
- inline char* wxTmemchr(const char* s, char c, size_t len)
- { return (char*)memchr(s, c, len); }
- inline int wxTmemcmp(const char* sz1, const char* sz2, size_t len)
- { return memcmp(sz1, sz2, len); }
- inline char* wxTmemcpy(char* szOut, const char* szIn, size_t len)
- { return (char*)memcpy(szOut, szIn, len); }
- inline char* wxTmemmove(char* szOut, const char* szIn, size_t len)
- { return (char*)memmove(szOut, szIn, len); }
- inline char* wxTmemset(char* szOut, const char cIn, size_t len)
- { return (char*)memset(szOut, cIn, len); }
-
-#else /* !wxUSE_UNICODE */
- #define wxTmemchr memchr
- #define wxTmemcmp memcmp
- #define wxTmemcpy memcpy
- #define wxTmemmove memmove
- #define wxTmemset memset
-#endif /* wxUSE_UNICODE/!wxUSE_UNICODE */
-
+#endif /* wxUSE_UNICODE */
+
+// provide trivial wrappers for char* versions for both ANSI and Unicode builds
+// (notice that these intentionally return "char *" and not "void *" unlike the
+// standard memxxx() for symmetry with the wide char versions):
+inline char* wxTmemchr(const char* s, char c, size_t len)
+ { return (char*)memchr(s, c, len); }
+inline int wxTmemcmp(const char* sz1, const char* sz2, size_t len)
+ { return memcmp(sz1, sz2, len); }
+inline char* wxTmemcpy(char* szOut, const char* szIn, size_t len)
+ { return (char*)memcpy(szOut, szIn, len); }
+inline char* wxTmemmove(char* szOut, const char* szIn, size_t len)
+ { return (char*)memmove(szOut, szIn, len); }
+inline char* wxTmemset(char* szOut, const char cIn, size_t len)
+ { return (char*)memset(szOut, cIn, len); }
// ============================================================================
// ----------------------------------------------------------------------------
// NB: we can't provide const wchar_t* (= wxChar*) overload, because calling
-// wxSetlocale(category, NULL) -- which is a common thing to do --would be
+// wxSetlocale(category, NULL) -- which is a common thing to do -- would be
// ambiguous
WXDLLIMPEXP_BASE char* wxSetlocale(int category, const char *locale);
inline char* wxSetlocale(int category, const wxCharBuffer& locale)
inline size_t wxStrlen(const wxString& s) { return s.length(); }
inline size_t wxStrlen(const wxCStrData& s) { return s.AsString().length(); }
+// this is a function new in 2.9 so we don't care about backwards compatibility and
+// so don't need to support wxCharBuffer/wxWCharBuffer overloads
+#if defined(wxCRT_StrnlenA)
+inline size_t wxStrnlen(const char *str, size_t maxlen) { return wxCRT_StrnlenA(str, maxlen); }
+#else
+inline size_t wxStrnlen(const char *str, size_t maxlen)
+{
+ size_t n;
+ for ( n = 0; n < maxlen; n++ )
+ if ( !str[n] )
+ break;
+
+ return n;
+}
+#endif
+
+#if defined(wxCRT_StrnlenW)
+inline size_t wxStrnlen(const wchar_t *str, size_t maxlen) { return wxCRT_StrnlenW(str, maxlen); }
+#else
+inline size_t wxStrnlen(const wchar_t *str, size_t maxlen)
+{
+ size_t n;
+ for ( n = 0; n < maxlen; n++ )
+ if ( !str[n] )
+ break;
+
+ return n;
+}
+#endif
+
// NB: these are defined in wxcrtbase.h, see the comment there
// inline char* wxStrdup(const char *s) { return wxStrdupA(s); }
// inline wchar_t* wxStrdup(const wchar_t *s) { return wxStrdupW(s); }
inline wchar_t *wxStrncpy(wchar_t *dest, const char *src, size_t n)
{ return wxCRT_StrncpyW(dest, wxConvLibc.cMB2WC(src), n); }
+// this is a function new in 2.9 so we don't care about backwards compatibility and
+// so don't need to support wchar_t/char overloads
+inline size_t wxStrlcpy(char *dest, const char *src, size_t n)
+{
+ const size_t len = wxCRT_StrlenA(src);
+
+ if ( n )
+ {
+ if ( n-- > len )
+ n = len;
+ wxCRT_StrncpyA(dest, src, n);
+ dest[n] = '\0';
+ }
+
+ return len;
+}
+inline size_t wxStrlcpy(wchar_t *dest, const wchar_t *src, size_t n)
+{
+ const size_t len = wxCRT_StrlenW(src);
+ if ( n )
+ {
+ if ( n-- > len )
+ n = len;
+ wxCRT_StrncpyW(dest, src, n);
+ dest[n] = L'\0';
+ }
+
+ return len;
+}
+
inline char *wxStrcat(char *dest, const char *src)
{ return wxCRT_StrcatA(dest, src); }
inline wchar_t *wxStrcat(wchar_t *dest, const wchar_t *src)
{ return WX_STR_CALL(forString, wxString(s1), wxString(s2)); } \
inline rettype WX_STR_DECL(name, const wxCharBuffer&, const wxCharBuffer&)\
{ return WX_STR_CALL(crtA, s1.data(), s2.data()); } \
- inline int WX_STR_DECL(name, const wxCharBuffer&, const wxWCharBuffer&) \
+ inline rettype WX_STR_DECL(name, const wxCharBuffer&, const wxWCharBuffer&) \
{ return WX_STR_CALL(forString, wxString(s1), wxString(s2)); } \
\
inline rettype WX_STR_DECL(name, const wxWCharBuffer&, const wchar_t *) \
{ return WX_STR_CALL(crtW, s1.data(), s2); } \
inline rettype WX_STR_DECL(name, const wxWCharBuffer&, const char *) \
{ return WX_STR_CALL(forString, wxString(s1), wxString(s2)); } \
- inline int WX_STR_DECL(name, const wxWCharBuffer&, const wxWCharBuffer&) \
+ inline rettype WX_STR_DECL(name, const wxWCharBuffer&, const wxWCharBuffer&) \
{ return WX_STR_CALL(crtW, s1.data(), s2.data()); } \
- inline int WX_STR_DECL(name, const wxWCharBuffer&, const wxCharBuffer&) \
+ inline rettype WX_STR_DECL(name, const wxWCharBuffer&, const wxCharBuffer&) \
{ return WX_STR_CALL(forString, wxString(s1), wxString(s2)); } \
\
inline rettype WX_STR_DECL(name, const wxString&, const char*) \
{ return s1.CmpNoCase(s2); }
WX_STRCMP_FUNC(wxStricmp, wxCRT_StricmpA, wxCRT_StricmpW, wxStricmp_String)
+#if defined(wxCRT_StrcollA) && defined(wxCRT_StrcollW)
// GCC 3.3 and other compilers have a bug that causes it to fail compilation if
// the template's implementation uses overloaded function declared later (see
// the wxStrcoll() call in wxStrcoll_String<T>()), so we have to
// forward-declare the template and implement it below WX_STRCMP_FUNC. OTOH,
-// this fails to compile with VC6, so don't do it for VC.
-#if !defined(__VISUALC__)
+// this fails to compile with VC6, so don't do it for VC. It also causes
+// problems with GCC visibility in newer GCC versions.
+#if !(defined(__VISUALC__) || wxCHECK_GCC_VERSION(3,4))
template<typename T>
inline int wxStrcoll_String(const wxString& s1, const T& s2);
WX_STRCMP_FUNC(wxStrcoll, wxCRT_StrcollA, wxCRT_StrcollW, wxStrcoll_String)
#endif
}
-#if defined(__VISUALC__)
+#if defined(__VISUALC__) || wxCHECK_GCC_VERSION(3,4)
// this is exactly the same WX_STRCMP_FUNC line as above wxStrcoll_String<>
WX_STRCMP_FUNC(wxStrcoll, wxCRT_StrcollA, wxCRT_StrcollW, wxStrcoll_String)
#endif
+#endif // defined(wxCRT_Strcoll[AW])
template<typename T>
-inline int wxStrspn_String(const wxString& s1, const T& s2)
+inline size_t wxStrspn_String(const wxString& s1, const T& s2)
{
size_t pos = s1.find_first_not_of(s2);
- return (pos == wxString::npos) ? s1.length() : pos;
+ return pos == wxString::npos ? s1.length() : pos;
}
WX_STR_FUNC(size_t, wxStrspn, wxCRT_StrspnA, wxCRT_StrspnW, wxStrspn_String)
template<typename T>
-inline int wxStrcspn_String(const wxString& s1, const T& s2)
+inline size_t wxStrcspn_String(const wxString& s1, const T& s2)
{
size_t pos = s1.find_first_of(s2);
- return (pos == wxString::npos) ? s1.length() : pos;
+ return pos == wxString::npos ? s1.length() : pos;
}
WX_STR_FUNC(size_t, wxStrcspn, wxCRT_StrcspnA, wxCRT_StrcspnW, wxStrcspn_String)
#undef WX_STR_FUNC
#undef WX_STR_FUNC_NO_INVERT
+#if defined(wxCRT_StrxfrmA) && defined(wxCRT_StrxfrmW)
+
inline size_t wxStrxfrm(char *dest, const char *src, size_t n)
{ return wxCRT_StrxfrmA(dest, src, n); }
inline size_t wxStrxfrm(wchar_t *dest, const wchar_t *src, size_t n)
inline size_t wxStrxfrm(wchar_t *dest, const wxCStrData& src, size_t n)
{ return wxCRT_StrxfrmW(dest, src.AsWCharBuf(), n); }
+#endif // defined(wxCRT_Strxfrm[AW])
+
inline char *wxStrtok(char *str, const char *delim, char **saveptr)
{ return wxCRT_StrtokA(str, delim, saveptr); }
inline wchar_t *wxStrtok(wchar_t *str, const wchar_t *delim, wchar_t **saveptr)
// to be ever used, but it still has to compile).
template<typename T> struct wxStrtoxCharType {};
template<> struct wxStrtoxCharType<char**>
- { typedef const char* Type; };
+{
+ typedef const char* Type;
+ static char** AsPointer(char **p) { return p; }
+};
template<> struct wxStrtoxCharType<wchar_t**>
- { typedef const wchar_t* Type; };
+{
+ typedef const wchar_t* Type;
+ static wchar_t** AsPointer(wchar_t **p) { return p; }
+};
template<> struct wxStrtoxCharType<int>
- { typedef const char* Type; /* this one is never used */ };
+{
+ typedef const char* Type; /* this one is never used */
+ static char** AsPointer(int WXUNUSED_UNLESS_DEBUG(p))
+ {
+ wxASSERT_MSG( p == 0, "passing non-NULL int is invalid" );
+ return NULL;
+ }
+};
template<typename T>
inline double wxStrtod(const wxString& nptr, T endptr)
// note that it is important to use c_str() here and not mb_str() or
// wc_str(), because we store the pointer into (possibly converted)
// buffer in endptr and so it must be valid even when wxStrtod() returns
- return wxStrtod((typename wxStrtoxCharType<T>::Type)nptr.c_str(), endptr);
+ typedef typename wxStrtoxCharType<T>::Type CharType;
+ return wxStrtod((CharType)nptr.c_str(),
+ wxStrtoxCharType<T>::AsPointer(endptr));
}
}
template<typename T>
if ( endptr == 0 ) \
return name(nptr.wx_str(), (wxStringCharType**)NULL, base); \
else \
- return name((typename wxStrtoxCharType<T>::Type)nptr.c_str(), \
- endptr, base); \
+ { \
+ typedef typename wxStrtoxCharType<T>::Type CharType; \
+ return name((CharType)nptr.c_str(), \
+ wxStrtoxCharType<T>::AsPointer(endptr), \
+ base); \
+ } \
} \
template<typename T> \
inline rettype name(const wxCStrData& nptr, T endptr, int base) \
#undef WX_STRTOX_FUNC
+// there is no command interpreter under CE, hence no system()
+#ifndef __WXWINCE__
+
// mingw32 doesn't provide _tsystem() even though it provides other stdlib.h
// functions in their wide versions
#ifdef wxCRT_SystemW
inline int wxSystem(const wxString& str) { return wxCRT_SystemA(str.mb_str()); }
#endif
+#endif // !__WXWINCE__/__WXWINCE__
+
inline char* wxGetenv(const char *name) { return wxCRT_GetenvA(name); }
inline wchar_t* wxGetenv(const wchar_t *name) { return wxCRT_GetenvW(name); }
inline char* wxGetenv(const wxString& name) { return wxCRT_GetenvA(name.mb_str()); }
inline char* wxGetenv(const wxCharBuffer& name) { return wxCRT_GetenvA(name.data()); }
inline wchar_t* wxGetenv(const wxWCharBuffer& name) { return wxCRT_GetenvW(name.data()); }
-
// ----------------------------------------------------------------------------
// time.h functions
// ----------------------------------------------------------------------------