X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/70e51d69185a2018d31193958c3660c0699cd988..c1df0a3b587f9b830783aeeaca514b3c0dff50e6:/include/wx/wxchar.h diff --git a/include/wx/wxchar.h b/include/wx/wxchar.h index 93d8a76918..cf866aee5f 100644 --- a/include/wx/wxchar.h +++ b/include/wx/wxchar.h @@ -5,7 +5,7 @@ * Modified by: Vadim Zeitlin, Robert Roebling, Ron Lee * Created: 1998/06/12 * RCS-ID: $Id$ - * Copyright: (c) 1998-2002 Joel Farley, Ove Kåven, Robert Roebling, Ron Lee + * Copyright: (c) 1998-2006 wxWidgets dev team * Licence: wxWindows licence */ @@ -14,7 +14,18 @@ #ifndef _WX_WXCHAR_H_ #define _WX_WXCHAR_H_ -#include "wx/defs.h" /* for wxUSE_UNICODE */ +/* defs.h indirectly includes this file, so don't include it here */ +#include "wx/platform.h" +#include "wx/dlimpexp.h" + +#ifdef __cplusplus + #include "wx/strvararg.h" +#else + /* make the file compile without doing anything in C code: */ + #define WX_DEFINE_VARARG_FUNC(rettype, name, impl) +#endif + +#include /* we use FILE below */ #if defined(HAVE_STRTOK_R) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS char *strtok_r(char *, const char *, char **); @@ -48,7 +59,7 @@ /* Standard headers we need here. - NB: don't include any wxWidgets headers here because almost of them include + NB: don't include any wxWidgets headers here because almost all of them include this one! */ @@ -57,7 +68,9 @@ /* Almost all compiler have strdup(), but not quite all: CodeWarrior under Mac */ /* and VC++ for Windows CE don't provide it */ -#if !(defined(__MWERKS__) && defined(__WXMAC__)) && !defined(__WXWINCE__) +#if defined(__VISUALC__) && __VISUALC__ >= 1400 + #define wxStrdupA _strdup +#elif !(defined(__MWERKS__) && defined(__WXMAC__)) && !defined(__WXWINCE__) /* use #define, not inline wrapper, as it is tested with #ifndef below */ #define wxStrdupA strdup #endif @@ -105,6 +118,14 @@ /* include stdlib.h for wchar_t */ #include #endif /* HAVE_WCHAR_H */ + + #ifdef HAVE_WIDEC_H + #include + #endif + + #if !defined(__GNUC__) || defined(__DARWIN__) + #define wxWINT_T_IS_TYPEDEF + #endif #endif /* wxUSE_WCHAR_T */ /* ---------------------------------------------------------------------------- */ @@ -141,9 +162,19 @@ #define wxHAVE_TCHAR_SUPPORT #endif /* compilers with (good) TCHAR support */ -#ifdef __MWERKS__ - #define HAVE_WPRINTF -#endif +#if defined(__MWERKS__) + /* Metrowerks only has wide char support for OS X >= 10.3 */ + #if !defined(__DARWIN__) || \ + (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3) + #define wxHAVE_MWERKS_UNICODE + #endif + + #ifdef wxHAVE_MWERKS_UNICODE + #define HAVE_WPRINTF 1 + #define HAVE_WCSRTOMBS 1 + #define HAVE_VSWPRINTF 1 + #endif +#endif /* __MWERKS__ */ #ifdef wxHAVE_TCHAR_SUPPORT /* get TCHAR definition if we've got it */ @@ -176,6 +207,13 @@ /* char wchar_t is always unsigned) and (b) was how the previous */ /* definitions worked so keep it like this */ + /* Sun's SunPro compiler supports the wchar_t type and wide character */ + /* functions, but does not define __WCHAR_TYPE__. Define it here to */ + /* allow unicode enabled builds. */ + #if defined(__SUNPRO_CC) || defined(__SUNPRO_C) + #define __WCHAR_TYPE__ wxchar_t + #endif + /* GNU libc has __WCHAR_TYPE__ which requires special treatment, see */ /* comment below */ #if !defined(__WCHAR_TYPE__) || \ @@ -185,13 +223,16 @@ typedef wchar_t wxSChar; typedef wchar_t wxUChar; #else /* __WCHAR_TYPE__ and gcc < 2.96 */ - /* VS: wxWidgets used to define wxChar as __WCHAR_TYPE__ here. However, */ - /* this doesn't work with new GCC 3.x compilers because wchar_t is */ - /* C++'s builtin type in the new standard. OTOH, old compilers (GCC */ - /* 2.x) won't accept new definition of wx{S,U}Char, therefore we */ - /* have to define wxChar conditionally depending on detected */ - /* compiler & compiler version. */ + /* VS: wxWidgets used to define wxChar as __WCHAR_TYPE__ here. */ + /* However, this doesn't work with new GCC 3.x compilers because */ + /* wchar_t is C++'s builtin type in the new standard. OTOH, old */ + /* compilers (GCC 2.x) won't accept new definition of */ + /* wx{S,U}CharType, so we have to define wxChar */ + /* conditionally depending on detected compiler & compiler */ + /* version. */ + /* with old definition of wxChar. */ + #define wchar_t __WCHAR_TYPE__ typedef __WCHAR_TYPE__ wxChar; typedef __WCHAR_TYPE__ wxSChar; typedef __WCHAR_TYPE__ wxUChar; @@ -213,7 +254,8 @@ #if !wxUSE_UNICODE #define _T(x) x #else /* Unicode */ - #define _T(x) L ## x + /* use wxCONCAT_HELPER so that x could be expanded if it's a macro */ + #define _T(x) wxCONCAT_HELPER(L, x) #endif /* ASCII/Unicode */ #endif /* !defined(_T) */ @@ -222,28 +264,28 @@ /* and _() in wxWidgets sources */ #define wxT(x) _T(x) +/* a helper macro allowing to make another macro Unicode-friendly, see below */ +#define wxAPPLY_T(x) _T(x) + /* Unicode-friendly __FILE__, __DATE__ and __TIME__ analogs */ #ifndef __TFILE__ - #define __XFILE__(x) wxT(x) - #define __TFILE__ __XFILE__(__FILE__) + #define __TFILE__ wxAPPLY_T(__FILE__) #endif #ifndef __TDATE__ - #define __XDATE__(x) wxT(x) - #define __TDATE__ __XDATE__(__DATE__) + #define __TDATE__ wxAPPLY_T(__DATE__) #endif #ifndef __TTIME__ - #define __XTIME__(x) wxT(x) - #define __TTIME__ __XTIME__(__TIME__) + #define __TTIME__ wxAPPLY_T(__TIME__) #endif /* define wxFoo() function for each standard foo() function whose signature (exceptionally including the return type) includes any mention of char: wxFoo() is going to be a Unicode-friendly version of foo(), i.e. will have - the same signature but with char replaced by wxChar which allows us to use - it in Unicode build as well + the same signature but with char replaced by wxChar which allows us to + use it in Unicode build as well */ #ifdef wxHAVE_TCHAR_SUPPORT @@ -272,8 +314,8 @@ There is a bug in VC6 C RTL: toxxx() functions dosn't do anything with signed chars < 0, so "fix" it here. */ - #define wxTolower(c) _totlower((wxUChar)(c)) - #define wxToupper(c) _totupper((wxUChar)(c)) + #define wxTolower(c) _totlower((wxUChar)(wxChar)(c)) + #define wxToupper(c) _totupper((wxUChar)(wxChar)(c)) /* locale.h functons */ #define wxSetlocale _tsetlocale @@ -300,6 +342,12 @@ #define wxStrtod _tcstod #define wxStrtol _tcstol #define wxStrtoul _tcstoul + #ifdef __VISUALC__ + #if __VISUALC__ >= 1300 && !defined(__WXWINCE__) + #define wxStrtoll _tcstoi64 + #define wxStrtoull _tcstoui64 + #endif /* VC++ 7+ */ + #endif #define wxStrxfrm _tcsxfrm /* stdio.h functions */ @@ -307,13 +355,15 @@ #define wxFgetchar _fgettchar #define wxFgets _fgetts #if wxUSE_UNICODE_MSLU + WXDLLIMPEXP_BASE FILE * wxMSLU__tfopen(const wxChar *name, const wxChar *mode); + #define wxFopen wxMSLU__tfopen #else #define wxFopen _tfopen #endif #define wxFputc _fputtc #define wxFputchar _fputtchar - #define wxFprintf _ftprintf + WX_DEFINE_VARARG_FUNC(int, wxFprintf, _ftprintf) #define wxFputs _fputts #define wxFreopen _tfreopen #define wxFscanf _ftscanf @@ -321,7 +371,7 @@ #define wxGetchar _gettchar #define wxGets _getts #define wxPerror _tperror - #define wxPrintf _tprintf + WX_DEFINE_VARARG_FUNC(int, wxPrintf, _tprintf) #define wxPutc(c,f) _puttc(WXWCHAR_T_CAST(c),f) #define wxPutchar _puttchar #define wxPuts _putts @@ -329,13 +379,14 @@ #if defined(__DMC__) #if wxUSE_UNICODE /* Digital Mars adds count to _stprintf (C99) so prototype conversion see wxchar.cpp */ - int wxSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) ; + int wxDoSprintf (wchar_t * __RESTRICT s, const wchar_t * __RESTRICT format, ... ) ; + WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf) #else /* and there is a bug in D Mars tchar.h prior to 8.39.4n, so define as sprintf */ - #define wxSprintf sprintf + WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf) #endif #else - #define wxSprintf _stprintf + WX_DEFINE_VARARG_FUNC(int, wxSprintf, _stprintf) #endif #define wxSscanf _stscanf @@ -346,16 +397,12 @@ #define wxVsscanf _vstscanf #define wxVsprintf _vstprintf - /* special case: not all TCHAR-aware compilers have those */ - #if defined(__VISUALC__) || \ - (defined(__BORLANDC__) && __BORLANDC__ >= 0x540) - #define wxVsnprintf_ _vsntprintf - #define wxSnprintf_ _sntprintf - #endif - /* special case: these functions are missing under Win9x with Unicows so we */ /* have to implement them ourselves */ #if wxUSE_UNICODE_MSLU + WXDLLIMPEXP_BASE int wxMSLU__trename(const wxChar *oldname, const wxChar *newname); + WXDLLIMPEXP_BASE int wxMSLU__tremove(const wxChar *name); + #define wxRemove wxMSLU__tremove #define wxRename wxMSLU__trename #else @@ -420,9 +467,19 @@ #define wxWcstombs wcstombs #endif - /* No UNICODE in the c library except wchar_t typedef on mac OSX 10.2 and less - roll our own */ - #if !defined(__MWERKS__) && wxUSE_UNICODE && defined(__DARWIN__) && ( MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_2 ) - + /* + The system C library on Mac OS X 10.2 and below does not support + unicode: in other words all wide-character functions such as towupper et + al. do simply not exist so we need to provide our own in that context, + except for the wchar_t definition/typedef itself. + + We need to do this for both project builder and CodeWarrior as + the latter uses the system C library in Mach builds for wide character + support, which as mentioned does not exist on 10.2 and below. + */ + #if wxUSE_UNICODE && \ + defined(__DARWIN__) && \ + ( MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_2 ) /* we need everything! */ #define wxNEED_WX_STRING_H #define wxNEED_WX_CTYPE_H @@ -510,6 +567,11 @@ #define wxStrtod wcstod #define wxStrtol wcstol #define wxStrtoul wcstoul + #ifdef HAVE_WCSTOULL + /* assume that we have wcstoull(), which is also C99, too */ + #define wxStrtoll wcstoll + #define wxStrtoull wcstoull + #endif /* HAVE_WCSTOULL */ #define wxStrxfrm wcsxfrm #define wxFgetc fgetwc @@ -679,6 +741,11 @@ #endif #define wxStrtol strtol #define wxStrtoul strtoul + #ifdef HAVE_STRTOULL + /* assume that we have wcstoull(), which is also C99, too */ + #define wxStrtoll strtoll + #define wxStrtoull strtoull + #endif /* HAVE_WCSTOULL */ #define wxStrxfrm strxfrm /* stdio.h functions */ @@ -696,17 +763,17 @@ #define wxFputc fputc #define wxFputs fputs #define wxFputchar fputchar - #define wxFprintf fprintf + WX_DEFINE_VARARG_FUNC(int, wxFprintf, fprintf) #define wxFscanf fscanf #define wxGetc getc #define wxGetchar getchar #define wxGets gets - #define wxPrintf printf + WX_DEFINE_VARARG_FUNC(int, wxPrintf, printf) #define wxPutc putc #define wxPutchar putchar #define wxPuts puts #define wxScanf scanf - #define wxSprintf sprintf + WX_DEFINE_VARARG_FUNC(int, wxSprintf, sprintf) #define wxSscanf sscanf #define wxUngetc ungetc #define wxVfprintf vfprintf @@ -728,6 +795,10 @@ #endif /* Unicode/ASCII */ #endif /* TCHAR-aware compilers/the others */ +#ifdef wxStrtoll + #define wxHAS_STRTOLL +#endif + /* various special cases */ @@ -815,7 +886,7 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ #else extern #endif - int snprintf(char *str, size_t size, const char *format, ...); + WXDLLIMPEXP_BASE int snprintf(char *str, size_t size, const char *format, ...); #endif /* !HAVE_SNPRINTF_DECL */ /* Wrapper for vsnprintf if it's 3rd parameter is non-const. Note: the @@ -829,56 +900,118 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ #endif /* - First of all, we always want to define safe snprintf() function to be used - instead of sprintf(). Some compilers already have it (or rather vsnprintf() - which we really need...), otherwise we implement it using our own printf() - code. - - We define function with a trailing underscore here because the real one is a - wrapper around it as explained below + MinGW MSVCRT has non-standard vswprintf() (for MSVC compatibility + presumably) and normally _vsnwprintf() is used instead */ -#ifndef wxVsnprintf_ - #if wxUSE_UNICODE - #if defined(__MWERKS__) - #define HAVE_WCSRTOMBS 1 - #define HAVE_VSWPRINTF 1 - #endif - #if defined(__WATCOMC__) - #define wxVsnprintf_ _vsnwprintf - #define wxSnprintf_ _snwprintf - #endif - #if defined(HAVE__VSNWPRINTF) - #define wxVsnprintf_ _vsnwprintf - /* MinGW?MSVCRT has the wrong vswprintf */ - #elif defined(HAVE_VSWPRINTF) && !defined(__MINGW32__) - #define wxVsnprintf_ vswprintf - #endif - #else /* ASCII */ - /* all versions of CodeWarrior supported by wxWidgets apparently have */ - /* both snprintf() and vsnprintf() */ - #if defined(HAVE_SNPRINTF) || defined(__MWERKS__) || defined(__WATCOMC__) - #ifndef HAVE_BROKEN_SNPRINTF_DECL - #define wxSnprintf_ snprintf +#if defined(HAVE_VSWPRINTF) && defined(__MINGW32__) + #undef HAVE_VSWPRINTF +#endif + +#if wxUSE_PRINTF_POS_PARAMS + /* + The systems where vsnprintf() supports positional parameters should + define the HAVE_UNIX98_PRINTF symbol. + + On systems which don't (e.g. Windows) we are forced to use + our wxVsnprintf() implementation. + */ + #if defined(HAVE_UNIX98_PRINTF) + #if wxUSE_UNICODE + #ifdef HAVE_VSWPRINTF + #define wxVsnprintf_ vswprintf #endif - #endif - #if defined(HAVE_VSNPRINTF) || defined(__MWERKS__) || defined(__WATCOMC__) - #if defined __cplusplus && defined HAVE_BROKEN_VSNPRINTF_DECL + #else /* ASCII */ + #ifdef HAVE_BROKEN_VSNPRINTF_DECL #define wxVsnprintf_ wx_fixed_vsnprintf #else #define wxVsnprintf_ vsnprintf #endif #endif + #else /* !HAVE_UNIX98_PRINTF */ + /* + The only compiler with positional parameters support under Windows + is VC++ 8.0 which provides a new xxprintf_p() functions family. + The 2003 PSDK includes a slightly earlier version of VC8 than the + main release and does not have the printf_p functions. + */ + #if defined _MSC_FULL_VER && _MSC_FULL_VER >= 140050727 && !defined __WXWINCE__ + #if wxUSE_UNICODE + #define wxVsnprintf_ _vswprintf_p + #else + #define wxVsnprintf_ _vsprintf_p + #endif + #endif + #endif /* HAVE_UNIX98_PRINTF/!HAVE_UNIX98_PRINTF */ +#else /* !wxUSE_PRINTF_POS_PARAMS */ + /* + We always want to define safe snprintf() function to be used instead of + sprintf(). Some compilers already have it (or rather vsnprintf() which + we really need...), otherwise we implement it using our own printf() + code. + + We define function with a trailing underscore here because the real one + is a wrapper around it as explained below + */ + + /* first deal with TCHAR-aware compilers which have _vsntprintf */ + #ifndef wxVsnprintf_ + #if defined(__VISUALC__) || \ + (defined(__BORLANDC__) && __BORLANDC__ >= 0x540) + #define wxVsnprintf_ _vsntprintf + WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _sntprintf) + #endif #endif -#endif /* wxVsnprintf_ not defined yet */ + + /* if this didn't work, define it separately for Unicode and ANSI builds */ + #ifndef wxVsnprintf_ + #if wxUSE_UNICODE + #if defined(HAVE__VSNWPRINTF) + #define wxVsnprintf_ _vsnwprintf + #elif defined(HAVE_VSWPRINTF) + #define wxVsnprintf_ vswprintf + #elif defined(__WATCOMC__) + #define wxVsnprintf_ _vsnwprintf + WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, _snwprintf) + #endif + #else /* ASCII */ + /* + All versions of CodeWarrior supported by wxWidgets apparently + have both snprintf() and vsnprintf() + */ + #if defined(HAVE_SNPRINTF) \ + || defined(__MWERKS__) || defined(__WATCOMC__) + #ifndef HAVE_BROKEN_SNPRINTF_DECL + WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, snprintf) + #endif + #endif + #if defined(HAVE_VSNPRINTF) \ + || defined(__MWERKS__) || defined(__WATCOMC__) + #ifdef HAVE_BROKEN_VSNPRINTF_DECL + #define wxVsnprintf_ wx_fixed_vsnprintf + #else + #define wxVsnprintf_ vsnprintf + #endif + #endif + #endif /* Unicode/ASCII */ + #endif /* wxVsnprintf_ */ +#endif /* wxUSE_PRINTF_POS_PARAMS/!wxUSE_PRINTF_POS_PARAMS */ #ifndef wxSnprintf_ - /* no [v]snprintf(), cook our own */ - WXDLLIMPEXP_BASE int wxSnprintf_(wxChar *buf, size_t len, const wxChar *format, - ...) ATTRIBUTE_PRINTF_3; + /* no snprintf(), cook our own */ + WXDLLIMPEXP_BASE int + wxDoSnprintf_(wxChar *buf, size_t len, + const wxChar *format, ...) ATTRIBUTE_PRINTF_3; + WX_DEFINE_VARARG_FUNC(int, wxSnprintf_, wxDoSnprintf_) #endif #ifndef wxVsnprintf_ - WXDLLIMPEXP_BASE int wxVsnprintf_(wxChar *buf, size_t len, const wxChar *format, - va_list argptr); + /* no (suitable) vsnprintf(), cook our own */ + WXDLLIMPEXP_BASE int + wxVsnprintf_(wxChar *buf, size_t len, + const wxChar *format, va_list argptr); + + #define wxUSE_WXVSNPRINTF 1 +#else + #define wxUSE_WXVSNPRINTF 0 #endif /* @@ -909,16 +1042,25 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ either because we don't have them at all or because they don't have the semantics we need */ + WX_DEFINE_VARARG_FUNC(int, wxScanf, wxDoScanf) + int wxDoScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1; + + WX_DEFINE_VARARG_FUNC(int, wxSscanf, wxDoSscanf) + int wxDoSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; - #include /* for FILE */ + WX_DEFINE_VARARG_FUNC(int, wxFscanf, wxDoFscanf) + int wxDoFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; + + WX_DEFINE_VARARG_FUNC(int, wxPrintf, wxDoPrintf) + int wxDoPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1; + + WX_DEFINE_VARARG_FUNC(int, wxSprintf, wxDoSprintf) + int wxDoSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; + + WX_DEFINE_VARARG_FUNC(int, wxFprintf, wxDoFprintf) + int wxDoFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; - int wxScanf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1; - int wxSscanf( const wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; - int wxFscanf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; int wxVsscanf( const wxChar *str, const wxChar *format, va_list ap ); - int wxPrintf( const wxChar *format, ... ) ATTRIBUTE_PRINTF_1; - int wxSprintf( wxChar *str, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; - int wxFprintf( FILE *stream, const wxChar *format, ... ) ATTRIBUTE_PRINTF_2; int wxVfprintf( FILE *stream, const wxChar *format, va_list ap ); int wxVprintf( const wxChar *format, va_list ap ); int wxVsprintf( wxChar *str, const wxChar *format, va_list ap ); @@ -931,7 +1073,8 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ anything as our own wxVsnprintf_() already behaves as needed. */ #if defined(wxNEED_PRINTF_CONVERSION) && defined(wxVsnprintf_) - int wxSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3; + WX_DEFINE_VARARG_FUNC(int, wxSnprintf, wxDoSnprintf) + int wxDoSnprintf( wxChar *str, size_t size, const wxChar *format, ... ) ATTRIBUTE_PRINTF_3; int wxVsnprintf( wxChar *str, size_t size, const wxChar *format, va_list ap ); #else #define wxSnprintf wxSnprintf_ @@ -966,7 +1109,7 @@ WXDLLIMPEXP_BASE bool wxOKlibc(); /* for internal use */ /* the file parsing -- this may be true for 5.0 as well, update #ifdef then */ #if defined(__VISUALC__) && (__VISUALC__ >= 1200) && !wxUSE_UNICODE #undef wxIsspace - #define wxIsspace(c) ((((unsigned)c) < 128) && isspace(c)) + #define wxIsspace(c) ((((unsigned)(wxChar)c) < 128) && isspace(c)) #endif /* VC++ */ /* @@ -1121,7 +1264,8 @@ WXDLLIMPEXP_BASE int wxSystem(const wxChar *psz); /*silent gabby compilers*/ struct tm; WXDLLIMPEXP_BASE size_t wxStrftime(wxChar *s, size_t max, - const wxChar *fmt, const struct tm *tm); + const wxChar *fmt, + const struct tm *tm); #endif /* wxNEED_WX_TIME_H */ #ifndef wxCtime @@ -1236,6 +1380,352 @@ WXDLLIMPEXP_BASE void *calloc( size_t num, size_t size ); #endif /*__cplusplus*/ +/* + FIXME-UTF8: split this header into more: + wxchartype.h for wxChar definition (only this one will have to + remain C header, the rest can be C++) + wxcrt.h for CRT wrappers + wxchar.h for wxChar+wxCharRef classes + */ +#ifdef __cplusplus +class WXDLLIMPEXP_BASE wxString; +class WXDLLIMPEXP_BASE wxUniCharRef; + +// This class represents single Unicode character. It can be converted to +// and from char or wchar_t and implements commonly used character operations. +class WXDLLIMPEXP_BASE wxUniChar +{ +public: + // NB: this is not wchar_t on purpose, it needs to represent the entire + // Unicode code points range and wchar_t may be too small for that + // (e.g. on Win32 where wchar_t* is encoded in UTF-16) + typedef unsigned int unicode_type; + + wxUniChar() : m_value(0) {} + + // Create the character from 8bit character value encoded in the current + // locale's charset. + wxUniChar(char c) { m_value = From8bit(c); } + + // Create the character from a wchar_t character value. + wxUniChar(wchar_t c) { m_value = c; } + +#ifndef wxWINT_T_IS_TYPEDEF + // Create the character from a wint_t character value. + wxUniChar(wint_t c) { m_value = c; } +#endif + + wxUniChar(int c) { m_value = c; } + + wxUniChar(const wxUniCharRef& c); + + // Returns Unicode code point value of the character + unicode_type GetValue() const { return m_value; } + + // Casts to char and wchar_t types: + operator char() const { return To8bit(m_value); } + operator wchar_t() const { return m_value; } +#ifndef wxWINT_T_IS_TYPEDEF + operator wint_t() const { return m_value; } +#endif + operator int() const { return m_value; } + + // We need this operator for the "*p" part of expressions like "for ( + // const_iterator p = begin() + nStart; *p; ++p )". In this case, + // compilation would fail without it because the conversion to bool would + // be ambiguous (there are all these int types conversions...). (And adding + // operator unspecified_bool_type() would only makes the ambiguity worse.) + operator bool() const { return m_value != 0; } + bool operator!() const { return !((bool)*this); } +#if (defined(__VISUALC__) && __VISUALC__ < 1400) || \ + defined(__DIGITALMARS__) || defined(__BORLANDC__) + // We need this for VC++ < 8 or DigitalMars and expressions like + // "str[0] && *p": + bool operator&&(bool v) const { return (bool)*this && v; } +#endif + + // Assignment operators: + wxUniChar& operator=(const wxUniChar& c) { m_value = c.m_value; return *this; } + wxUniChar& operator=(char c) { m_value = From8bit(c); return *this; } + wxUniChar& operator=(wchar_t c) { m_value = c; return *this; } +#ifndef wxWINT_T_IS_TYPEDEF + wxUniChar& operator=(wint_t c) { m_value = c; return *this; } +#endif + + // Comparision operators: + bool operator==(const wxUniChar& c) const { return m_value == c.m_value; } + bool operator==(char c) const { return m_value == From8bit(c); } + bool operator==(wchar_t c) const { return m_value == (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator==(wint_t c) const { return m_value == (unicode_type)c; } +#endif + + bool operator!=(const wxUniChar& c) const { return m_value != c.m_value; } + bool operator!=(char c) const { return m_value != From8bit(c); } + bool operator!=(wchar_t c) const { return m_value != (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator!=(wint_t c) const { return m_value != (unicode_type)c; } +#endif + + bool operator>(const wxUniChar& c) const { return m_value > c.m_value; } + bool operator>(char c) const { return m_value > (unicode_type)c; } + bool operator>(wchar_t c) const { return m_value > (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator>(wint_t c) const { return m_value > (unicode_type)c; } +#endif + + bool operator<(const wxUniChar& c) const { return m_value < c.m_value; } + bool operator<(char c) const { return m_value < From8bit(c); } + bool operator<(wchar_t c) const { return m_value < (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator<(wint_t c) const { return m_value < (unicode_type)c; } +#endif + + bool operator>=(const wxUniChar& c) const { return m_value >= c.m_value; } + bool operator>=(char c) const { return m_value >= From8bit(c); } + bool operator>=(wchar_t c) const { return m_value >= (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator>=(wint_t c) const { return m_value >= (unicode_type)c; } +#endif + + bool operator<=(const wxUniChar& c) const { return m_value <= c.m_value; } + bool operator<=(char c) const { return m_value <= From8bit(c); } + bool operator<=(wchar_t c) const { return m_value <= (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator<=(wint_t c) const { return m_value <= (unicode_type)c; } +#endif + + int operator-(const wxUniChar& c) const { return m_value - c.m_value; } + int operator-(char c) const { return m_value - From8bit(c); } + int operator-(wchar_t c) const { return m_value - (unicode_type)c; } +#ifndef wxWINT_T_IS_TYPEDEF + int operator-(wint_t c) const { return m_value - (unicode_type)c; } +#endif + +private: + static unicode_type From8bit(char c); + static char To8bit(unicode_type c); + +private: + unicode_type m_value; +}; + + +// Writeable reference to a character in wxString. +// +// This class can be used in the same way wxChar is used, except that changing +// its value updates the underlying string object. +class WXDLLIMPEXP_BASE wxUniCharRef +{ +private: + // create the reference + // FIXME: the interface will need changes for UTF-8 build + wxUniCharRef(wxChar *pos) : m_pos(pos) {} + +public: + // NB: we have to make this public, because we don't have wxString + // declaration available here and so can't declare wxString::iterator + // as friend; so at least don't use a ctor but a static function + // that must be used explicitly (this is more than using 'explicit' + // keyword on ctor!): + // + // FIXME: the interface will need changes for UTF-8 build + static wxUniCharRef CreateForString(wxChar *pos) + { return wxUniCharRef(pos); } + + wxUniChar::unicode_type GetValue() const { return UniChar().GetValue(); } + + // Assignment operators: + wxUniCharRef& operator=(const wxUniCharRef& c) + { + *m_pos = *c.m_pos; + return *this; + }; + + wxUniCharRef& operator=(const wxUniChar& c) + { + *m_pos = c; + return *this; + }; + + wxUniCharRef& operator=(char c) { return *this = wxUniChar(c); } + wxUniCharRef& operator=(wchar_t c) { return *this = wxUniChar(c); } + + // Casts to wxUniChar type: + operator char() const { return UniChar(); } + operator wchar_t() const { return UniChar(); } +#ifndef wxWINT_T_IS_TYPEDEF + operator wint_t() const { return UniChar(); } +#endif + operator int() const { return UniChar(); } + + // see wxUniChar::operator bool etc. for explanation + operator bool() const { return (bool)UniChar(); } + bool operator!() const { return !UniChar(); } +#if (defined(__VISUALC__) && __VISUALC__ < 1400) || \ + defined(__DIGITALMARS__) || defined(__BORLANDC__) + bool operator&&(bool v) const { return UniChar() && v; } +#endif + + // Comparision operators: + bool operator==(const wxUniCharRef& c) const { return m_pos == c.m_pos; } + bool operator==(const wxUniChar& c) const { return UniChar() == c; } + bool operator==(char c) const { return UniChar() == c; } + bool operator==(wchar_t c) const { return UniChar() == c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator==(wint_t c) const { return UniChar() == c; } +#endif + + bool operator!=(const wxUniCharRef& c) const { return m_pos != c.m_pos; } + bool operator!=(const wxUniChar& c) const { return UniChar() != c; } + bool operator!=(char c) const { return UniChar() != c; } + bool operator!=(wchar_t c) const { return UniChar() != c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator!=(wint_t c) const { return UniChar() != c; } +#endif + + bool operator>(const wxUniCharRef& c) const { return UniChar() > c.UniChar(); } + bool operator>(const wxUniChar& c) const { return UniChar() > c; } + bool operator>(char c) const { return UniChar() > c; } + bool operator>(wchar_t c) const { return UniChar() > c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator>(wint_t c) const { return UniChar() > c; } +#endif + + bool operator<(const wxUniCharRef& c) const { return UniChar() < c.UniChar(); } + bool operator<(const wxUniChar& c) const { return UniChar() < c; } + bool operator<(char c) const { return UniChar() < c; } + bool operator<(wchar_t c) const { return UniChar() < c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator<(wint_t c) const { return UniChar() < c; } +#endif + + bool operator>=(const wxUniCharRef& c) const { return UniChar() >= c.UniChar(); } + bool operator>=(const wxUniChar& c) const { return UniChar() >= c; } + bool operator>=(char c) const { return UniChar() >= c; } + bool operator>=(wchar_t c) const { return UniChar() >= c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator>=(wint_t c) const { return UniChar() >= c; } +#endif + + bool operator<=(const wxUniCharRef& c) const { return UniChar() <= c.UniChar(); } + bool operator<=(const wxUniChar& c) const { return UniChar() <= c; } + bool operator<=(char c) const { return UniChar() <= c; } + bool operator<=(wchar_t c) const { return UniChar() <= c; } +#ifndef wxWINT_T_IS_TYPEDEF + bool operator<=(wint_t c) const { return UniChar() <= c; } +#endif + + int operator-(const wxUniCharRef& c) const { return UniChar() - c.UniChar(); } + int operator-(const wxUniChar& c) const { return UniChar() - c; } + int operator-(char c) const { return UniChar() - c; } + int operator-(wchar_t c) const { return UniChar() - c; } +#ifndef wxWINT_T_IS_TYPEDEF + int operator-(wint_t c) const { return UniChar() - c; } +#endif + +private: + wxUniChar UniChar() const { return *m_pos; } + friend class WXDLLIMPEXP_BASE wxUniChar; + +private: + // pointer to the character in string + wxChar *m_pos; +}; + +inline wxUniChar::wxUniChar(const wxUniCharRef& c) +{ + m_value = c.UniChar().m_value; +} + +// Comparision operators for the case when wxUniChar(Ref) is the second operand: +inline bool operator==(char c1, const wxUniChar& c2) { return c2 == c1; } +inline bool operator==(wchar_t c1, const wxUniChar& c2) { return c2 == c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator==(wint_t c1, const wxUniChar& c2) { return c2 == c1; } +#endif + +inline bool operator!=(char c1, const wxUniChar& c2) { return c2 != c1; } +inline bool operator!=(wchar_t c1, const wxUniChar& c2) { return c2 != c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator!=(wint_t c1, const wxUniChar& c2) { return c2 != c1; } +#endif + +inline bool operator>(char c1, const wxUniChar& c2) { return c2 < c1; } +inline bool operator>(wchar_t c1, const wxUniChar& c2) { return c2 < c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator>(wint_t c1, const wxUniChar& c2) { return c2 < c1; } +#endif + +inline bool operator<(char c1, const wxUniChar& c2) { return c2 > c1; } +inline bool operator<(wchar_t c1, const wxUniChar& c2) { return c2 > c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator<(wint_t c1, const wxUniChar& c2) { return c2 > c1; } +#endif + +inline bool operator>=(char c1, const wxUniChar& c2) { return c2 <= c1; } +inline bool operator>=(wchar_t c1, const wxUniChar& c2) { return c2 <= c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator>=(wint_t c1, const wxUniChar& c2) { return c2 <= c1; } +#endif + +inline bool operator<=(char c1, const wxUniChar& c2) { return c2 >= c1; } +inline bool operator<=(wchar_t c1, const wxUniChar& c2) { return c2 >= c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator<=(wint_t c1, const wxUniChar& c2) { return c2 >= c1; } +#endif + + +inline bool operator==(char c1, const wxUniCharRef& c2) { return c2 == c1; } +inline bool operator==(wchar_t c1, const wxUniCharRef& c2) { return c2 == c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator==(wint_t c1, const wxUniCharRef& c2) { return c2 == c1; } +#endif +inline bool operator==(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 == c1; } + +inline bool operator!=(char c1, const wxUniCharRef& c2) { return c2 != c1; } +inline bool operator!=(wchar_t c1, const wxUniCharRef& c2) { return c2 != c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator!=(wint_t c1, const wxUniCharRef& c2) { return c2 != c1; } +#endif +inline bool operator!=(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 != c1; } + +inline bool operator>(char c1, const wxUniCharRef& c2) { return c2 < c1; } +inline bool operator>(wchar_t c1, const wxUniCharRef& c2) { return c2 < c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator>(wint_t c1, const wxUniCharRef& c2) { return c2 < c1; } +#endif +inline bool operator>(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 < c1; } + +inline bool operator<(char c1, const wxUniCharRef& c2) { return c2 > c1; } +inline bool operator<(wchar_t c1, const wxUniCharRef& c2) { return c2 > c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator<(wint_t c1, const wxUniCharRef& c2) { return c2 > c1; } +#endif +inline bool operator<(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 > c1; } + +inline bool operator>=(char c1, const wxUniCharRef& c2) { return c2 <= c1; } +inline bool operator>=(wchar_t c1, const wxUniCharRef& c2) { return c2 <= c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator>=(wint_t c1, const wxUniCharRef& c2) { return c2 <= c1; } +#endif +inline bool operator>=(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 <= c1; } + +inline bool operator<=(char c1, const wxUniCharRef& c2) { return c2 >= c1; } +inline bool operator<=(wchar_t c1, const wxUniCharRef& c2) { return c2 >= c1; } +#ifndef wxWINT_T_IS_TYPEDEF +inline bool operator<=(wint_t c1, const wxUniCharRef& c2) { return c2 >= c1; } +#endif +inline bool operator<=(const wxUniChar& c1, const wxUniCharRef& c2) { return c2 >= c1; } + +inline int operator-(char c1, const wxUniCharRef& c2) { return -(c2 - c1); } +inline int operator-(wchar_t c1, const wxUniCharRef& c2) { return -(c2 - c1); } +#ifndef wxWINT_T_IS_TYPEDEF +inline int operator-(wint_t c1, const wxUniCharRef& c2) { return -(c2 - c1); } +#endif +inline int operator-(const wxUniChar& c1, const wxUniCharRef& c2) { return -(c2 - c1); } + +#endif // __cplusplus #endif /* _WX_WXCHAR_H_ */