1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxChar implementation 
   8 // Copyright:   (c) wxWindows copyright 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13   #pragma implementation "wxchar.h" 
  16 // =========================================================================== 
  17 // headers, declarations, constants 
  18 // =========================================================================== 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  27 #define _ISOC9X_SOURCE 1 // to get vsscanf() 
  28 #define _BSD_SOURCE    1 // to still get strdup() 
  38   #include "wx/wxchar.h" 
  39   #include "wx/string.h" 
  43 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H) 
  51 size_t WXDLLEXPORT 
wxMB2WC(wchar_t *buf
, const char *psz
, size_t n
) 
  55       if (n
) *buf 
= wxT('\0'); 
  58     return mbstowcs(buf
, psz
, n
); 
  61   // assume that we have mbsrtowcs() too if we have wcsrtombs() 
  64   return mbsrtowcs((wchar_t *) NULL
, &psz
, 0, &mbstate
); 
  66   return mbstowcs((wchar_t *) NULL
, psz
, 0); 
  70 size_t WXDLLEXPORT 
wxWC2MB(char *buf
, const wchar_t *pwz
, size_t n
) 
  74       // glibc2.1 chokes on null input 
  78     return wcstombs(buf
, pwz
, n
); 
  83   return wcsrtombs((char *) NULL
, &pwz
, 0, &mbstate
); 
  85   return wcstombs((char *) NULL
, pwz
, 0); 
  88 #endif // wxUSE_WCHAR_T 
  90 bool WXDLLEXPORT 
wxOKlibc() 
  92 #if wxUSE_WCHAR_T && defined(__UNIX__) && defined(__GLIBC__) 
  93   // glibc 2.0 uses UTF-8 even when it shouldn't 
  95   if ((MB_CUR_MAX 
== 2) && 
  96       (wxMB2WC(&res
, "\xdd\xa5", 1) == 1) && 
  98     // this is UTF-8 allright, check whether that's what we want 
  99     char *cur_locale 
= setlocale(LC_CTYPE
, NULL
); 
 100     if ((strlen(cur_locale
) < 4) || 
 101             (strcasecmp(cur_locale 
+ strlen(cur_locale
) - 4, "utf8")) || 
 102             (strcasecmp(cur_locale 
+ strlen(cur_locale
) - 5, "utf-8"))) { 
 103       // nope, don't use libc conversion 
 112 size_t   WXDLLEXPORT 
wcslen(const wchar_t *s
) 
 115   while (s
[len
]) len
++; 
 120 // ============================================================================ 
 121 // printf() functions business 
 122 // ============================================================================ 
 124 // ---------------------------------------------------------------------------- 
 125 // implement [v]snprintf() if the system doesn't provide a safe one 
 126 // ---------------------------------------------------------------------------- 
 128 #if !defined(wxVsnprintf_) 
 129 int WXDLLEXPORT 
wxVsnprintf_(wxChar 
*buf
, size_t lenMax
, 
 130                              const wxChar 
*format
, va_list argptr
) 
 132     // buffer to avoid dynamic memory allocation each time for small strings 
 133     char szScratch
[1024]; 
 135     // number of characters in the buffer so far, must be less than lenMax 
 138     for (size_t n 
= 0; format
[n
]; n
++) 
 140         if (format
[n
] == wxT('%')) { 
 141             static char s_szFlags
[256] = "%"; 
 143             bool adj_left 
= FALSE
, 
 148             size_t min_width 
= 0, 
 149                    max_width 
= wxSTRING_MAXLEN
; 
 153                 if (in_prec && !prec_dot) \ 
 155                     s_szFlags[flagofs++] = '.'; \ 
 159 #define APPEND_CH(ch) \ 
 160                 if ( lenCur == lenMax ) \ 
 165 #define APPEND_STR(s) \ 
 167                     for ( const wxChar *p = s; *p; p++ ) \ 
 173                 switch (format
[++n
]) { 
 191                         s_szFlags
[flagofs
++] = format
[n
]; 
 197                         s_szFlags
[flagofs
++] = format
[n
]; 
 205                         // dot will be auto-added to s_szFlags if non-negative number follows 
 211                         s_szFlags
[flagofs
++] = format
[n
]; 
 217                         s_szFlags
[flagofs
++] = format
[n
]; 
 224                         s_szFlags
[flagofs
++] = format
[n
]; 
 230                         s_szFlags
[flagofs
++] = format
[n
]; 
 235                             int len 
= va_arg(argptr
, int); 
 242                                     adj_left 
= !adj_left
; 
 243                                     s_szFlags
[flagofs
++] = '-'; 
 248                             flagofs 
+= ::sprintf(s_szFlags
+flagofs
,"%d",len
); 
 252                     case wxT('1'): case wxT('2'): case wxT('3'): 
 253                     case wxT('4'): case wxT('5'): case wxT('6'): 
 254                     case wxT('7'): case wxT('8'): case wxT('9'): 
 258                                 while ((format
[n
]>=wxT('0')) && (format
[n
]<=wxT('9'))) { 
 259                                     s_szFlags
[flagofs
++] = format
[n
]; 
 260                                     len 
= len
*10 + (format
[n
] - wxT('0')); 
 263                             if (in_prec
) max_width 
= len
; 
 264                             else min_width 
= len
; 
 265                             n
--; // the main loop pre-increments n again 
 276                         s_szFlags
[flagofs
++] = format
[n
]; 
 277                         s_szFlags
[flagofs
] = '\0'; 
 279                             int val 
= va_arg(argptr
, int); 
 280                             ::sprintf(szScratch
, s_szFlags
, val
); 
 282                         else if (ilen 
== -1) { 
 283                             short int val 
= va_arg(argptr
, short int); 
 284                             ::sprintf(szScratch
, s_szFlags
, val
); 
 286                         else if (ilen 
== 1) { 
 287                             long int val 
= va_arg(argptr
, long int); 
 288                             ::sprintf(szScratch
, s_szFlags
, val
); 
 290                         else if (ilen 
== 2) { 
 292                             long long int val 
= va_arg(argptr
, long long int); 
 293                             ::sprintf(szScratch
, s_szFlags
, val
); 
 295                             long int val 
= va_arg(argptr
, long int); 
 296                             ::sprintf(szScratch
, s_szFlags
, val
); 
 299                         else if (ilen 
== 3) { 
 300                             size_t val 
= va_arg(argptr
, size_t); 
 301                             ::sprintf(szScratch
, s_szFlags
, val
); 
 304                         APPEND_STR(wxConvLibc
.cMB2WX(szScratch
)); 
 315                         s_szFlags
[flagofs
++] = format
[n
]; 
 316                         s_szFlags
[flagofs
] = '\0'; 
 318                             long double val 
= va_arg(argptr
, long double); 
 319                             ::sprintf(szScratch
, s_szFlags
, val
); 
 321                             double val 
= va_arg(argptr
, double); 
 322                             ::sprintf(szScratch
, s_szFlags
, val
); 
 325                         APPEND_STR(wxConvLibc
.cMB2WX(szScratch
)); 
 332                             void *val 
= va_arg(argptr
, void *); 
 334                                 s_szFlags
[flagofs
++] = format
[n
]; 
 335                             s_szFlags
[flagofs
] = '\0'; 
 336                             ::sprintf(szScratch
, s_szFlags
, val
); 
 338                             APPEND_STR(wxConvLibc
.cMB2WX(szScratch
)); 
 346                             wxChar val 
= va_arg(argptr
, int); 
 347                             // we don't need to honor padding here, do we? 
 356                             // wx extension: we'll let %hs mean non-Unicode strings 
 357                             char *val 
= va_arg(argptr
, char *); 
 359                             // ASCII->Unicode constructor handles max_width right 
 360                             wxString 
s(val
, wxConvLibc
, max_width
); 
 362                             size_t len 
= wxSTRING_MAXLEN
; 
 364                                 for (len 
= 0; val
[len
] && (len
<max_width
); len
++); 
 365                             } else val 
= wxT("(null)"); 
 366                             wxString 
s(val
, len
); 
 368                             if (s
.Len() < min_width
) 
 369                                 s
.Pad(min_width 
- s
.Len(), wxT(' '), adj_left
); 
 373                             wxChar 
*val 
= va_arg(argptr
, wxChar 
*); 
 374                             size_t len 
= wxSTRING_MAXLEN
; 
 376                                 for (len 
= 0; val
[len
] && (len
<max_width
); len
++); 
 377                             } else val 
= wxT("(null)"); 
 378                             wxString 
s(val
, len
); 
 379                             if (s
.Len() < min_width
) 
 380                                 s
.Pad(min_width 
- s
.Len(), wxT(' '), adj_left
); 
 389                             int *val 
= va_arg(argptr
, int *); 
 392                         else if (ilen 
== -1) { 
 393                             short int *val 
= va_arg(argptr
, short int *); 
 396                         else if (ilen 
>= 1) { 
 397                             long int *val 
= va_arg(argptr
, long int *); 
 404                         if (wxIsalpha(format
[n
])) 
 405                             // probably some flag not taken care of here yet 
 406                             s_szFlags
[flagofs
++] = format
[n
]; 
 409                             APPEND_CH(_T('%')); // just to pass the glibc tst-printf.c 
 419             APPEND_CH(format
[n
]); 
 430 #endif // !wxVsnprintfA 
 432 #if !defined(wxSnprintf_) 
 433 int WXDLLEXPORT 
wxSnprintf_(wxChar 
*buf
, size_t len
, const wxChar 
*format
, ...) 
 436     va_start(argptr
, format
); 
 438     int iLen 
= wxVsnprintf_(buf
, len
, format
, argptr
); 
 444 #endif // wxSnprintf_ 
 446 // ---------------------------------------------------------------------------- 
 447 // implement the standard IO functions for wide char if libc doesn't have them 
 448 // ---------------------------------------------------------------------------- 
 452 int wxFputs(const wchar_t *ws
, FILE *stream
) 
 454     // counting the number of wide characters written isn't worth the trouble, 
 455     // simply distinguish between ok and error 
 456     return fputs(wxConvLibc
.cWC2MB(ws
), stream
) == -1 ? -1 : 0; 
 459 int /* not wint_t */ wxPutc(wchar_t wc
, FILE *stream
) 
 461     wchar_t ws
[2] = { wc
, L
'\0' }; 
 463     return wxFputs(ws
, stream
); 
 466 #endif // wxNEED_FPUTWC 
 468 // NB: we only implement va_list functions here, the ones taking ... are 
 469 //     defined below for wxNEED_PRINTF_CONVERSION case anyhow and we reuse 
 470 //     the definitions there to avoid duplicating them here 
 471 #ifdef wxNEED_WPRINTF 
 473 // TODO: implement the scanf() functions 
 474 int vwscanf(const wchar_t *format
, va_list argptr
) 
 476     wxFAIL_MSG( _T("TODO") ); 
 481 int vswscanf(const wchar_t *ws
, const wchar_t *format
, va_list argptr
) 
 483     wxFAIL_MSG( _T("TODO") ); 
 488 int vfwscanf(FILE *stream
, const wchar_t *format
, va_list argptr
) 
 490     wxFAIL_MSG( _T("TODO") ); 
 495 #define vswprintf wxVsnprintf_ 
 497 int vfwprintf(FILE *stream
, const wchar_t *format
, va_list argptr
) 
 500     int rc 
= s
.PrintfV(format
, argptr
); 
 504         // we can't do much better without Unicode support in libc... 
 505         if ( fprintf(stream
, s
.mb_str()) == -1 ) 
 512 int vwprintf(const wchar_t *format
, va_list argptr
) 
 514     return wxVfprintf(stdout
, format
, argptr
); 
 517 #endif // wxNEED_WPRINTF 
 519 #ifdef wxNEED_PRINTF_CONVERSION 
 521 // ---------------------------------------------------------------------------- 
 522 // wxFormatConverter: class doing the "%s" -> "%ls" conversion 
 523 // ---------------------------------------------------------------------------- 
 526    Here are the gory details. We want to follow the Windows/MS conventions, 
 531    format specifier         results in 
 532    ----------------------------------- 
 538    format specifier         results in 
 539    ----------------------------------- 
 544    while on POSIX systems we have %C identical to %lc and %c always means char 
 545    (in any mode) while %lc always means wchar_t, 
 547    So to use native functions in order to get our semantics we must do the 
 548    following translations in Unicode mode (nothing to do in ANSI mode): 
 550    wxWindows specifier      POSIX specifier 
 551    ---------------------------------------- 
 557    And, of course, the same should be done for %s as well. 
 560 class wxFormatConverter
 
 563     wxFormatConverter(const wxChar 
*format
); 
 565     // notice that we only translated the string if m_fmtOrig == NULL (as set 
 566     // by CopyAllBefore()), otherwise we should simply use the original format 
 567     operator const wxChar 
*() const 
 568         { return m_fmtOrig 
? m_fmtOrig 
: m_fmt
.c_str(); } 
 571     // copy another character to the translated format: this function does the 
 572     // copy if we are translating but doesn't do anything at all if we don't, 
 573     // so we don't create the translated format string at all unless we really 
 574     // need to (i.e. InsertFmtChar() is called) 
 575     wxChar 
CopyFmtChar(wxChar ch
) 
 579             // we're translating, do copy 
 584             // simply increase the count which should be copied by 
 585             // CopyAllBefore() later if needed 
 592     // insert an extra character 
 593     void InsertFmtChar(wxChar ch
) 
 597             // so far we haven't translated anything yet 
 606         wxASSERT_MSG( m_fmtOrig 
&& m_fmt
.empty(), _T("logic error") ); 
 608         m_fmt 
= wxString(m_fmtOrig
, m_nCopied
); 
 610         // we won't need it any longer 
 614     static bool IsFlagChar(wxChar ch
) 
 616         return ch 
== _T('-') || ch 
== _T('+') || 
 617                ch 
== _T('0') || ch 
== _T(' ') || ch 
== _T('#'); 
 620     void SkipDigits(const wxChar 
**ppc
) 
 622         while ( **ppc 
>= _T('0') && **ppc 
<= _T('9') ) 
 623             CopyFmtChar(*(*ppc
)++); 
 626     // the translated format 
 629     // the original format 
 630     const wxChar 
*m_fmtOrig
; 
 632     // the number of characters already copied 
 636 wxFormatConverter::wxFormatConverter(const wxChar 
*format
) 
 643         if ( CopyFmtChar(*format
++) == _T('%') ) 
 646             while ( IsFlagChar(*format
) ) 
 647                 CopyFmtChar(*format
++); 
 649             // and possible width 
 650             if ( *format 
== _T('*') ) 
 651                 CopyFmtChar(*format
++); 
 656             if ( *format 
== _T('.') ) 
 661             // next we can have a size modifier 
 677                     // "ll" has a different meaning! 
 678                     if ( format
[1] != _T('l') ) 
 690             // and finally we should have the type 
 695                     // %C and %hC -> %c and %lC -> %lc 
 697                         CopyFmtChar(_T('l')); 
 699                     InsertFmtChar(*format
++ == _T('C') ? _T('c') : _T('s')); 
 704                     // %c -> %lc but %hc stays %hc and %lc is still %lc 
 708                             InsertFmtChar(_T('l')); 
 712                             CopyFmtChar(_T('h')); 
 721                     // nothing special to do 
 722                     CopyFmtChar(*format
++); 
 728 #else // !wxNEED_PRINTF_CONVERSION 
 729     // no conversion necessary 
 730     #define wxFormatConverter(x) (x) 
 731 #endif // wxNEED_PRINTF_CONVERSION/!wxNEED_PRINTF_CONVERSION 
 733 // ---------------------------------------------------------------------------- 
 734 // wxPrintf(), wxScanf() and relatives 
 735 // ---------------------------------------------------------------------------- 
 737 #if defined(wxNEED_PRINTF_CONVERSION) || defined(wxNEED_WPRINTF) 
 739 int wxScanf( const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_2
 
 742     va_start(argptr
, format
); 
 744     int ret 
= vwscanf(wxFormatConverter(format
), argptr 
); 
 751 int wxSscanf( const wxChar 
*str
, const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_3
 
 754     va_start(argptr
, format
); 
 756     int ret 
= vswscanf( str
, wxFormatConverter(format
), argptr 
); 
 763 int wxFscanf( FILE *stream
, const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_3
 
 766     va_start(argptr
, format
); 
 768     int ret 
= vfwscanf(stream
, wxFormatConverter(format
), argptr
); 
 775 int wxPrintf( const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_2
 
 778     va_start(argptr
, format
); 
 780     int ret 
= vwprintf( wxFormatConverter(format
), argptr 
); 
 788 int wxSnprintf( wxChar 
*str
, size_t size
, const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_4
 
 791     va_start(argptr
, format
); 
 793     int ret 
= vswprintf( str
, size
, wxFormatConverter(format
), argptr 
); 
 801 int wxSprintf( wxChar 
*str
, const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_3
 
 804     va_start(argptr
, format
); 
 806     // callers of wxSprintf() deserve what they get 
 807     int ret 
= vswprintf( str
, UINT_MAX
, wxFormatConverter(format
), argptr 
); 
 814 int wxFprintf( FILE *stream
, const wxChar 
*format
, ... ) ATTRIBUTE_PRINTF_3
 
 817     va_start( argptr
, format 
); 
 819     int ret 
= vfwprintf( stream
, wxFormatConverter(format
), argptr 
); 
 826 int wxVsscanf( const wxChar 
*str
, const wxChar 
*format
, va_list argptr 
) 
 828     return vswscanf( str
, wxFormatConverter(format
), argptr 
); 
 831 int wxVfprintf( FILE *stream
, const wxChar 
*format
, va_list argptr 
) 
 833     return vfwprintf( stream
, wxFormatConverter(format
), argptr 
); 
 836 int wxVprintf( const wxChar 
*format
, va_list argptr 
) 
 838     return vwprintf( wxFormatConverter(format
), argptr 
); 
 842 int wxVsnprintf( wxChar 
*str
, size_t size
, const wxChar 
*format
, va_list argptr 
) 
 844     return vswprintf( str
, size
, wxFormatConverter(format
), argptr 
); 
 846 #endif // wxVsnprintf 
 848 int wxVsprintf( wxChar 
*str
, const wxChar 
*format
, va_list argptr 
) 
 850     // same as for wxSprintf() 
 851     return vswprintf(str
, UINT_MAX
, wxFormatConverter(format
), argptr
); 
 854 #endif // wxNEED_PRINTF_CONVERSION 
 856 // ---------------------------------------------------------------------------- 
 857 // ctype.h stuff (currently unused) 
 858 // ---------------------------------------------------------------------------- 
 860 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H) 
 861 inline WORD 
wxMSW_ctype(wxChar ch
) 
 864   GetStringTypeEx(LOCALE_USER_DEFAULT
, CT_CTYPE1
, &ch
, 1, &ret
); 
 868 WXDLLEXPORT 
int wxIsalnum(wxChar ch
) { return IsCharAlphaNumeric(ch
); } 
 869 WXDLLEXPORT 
int wxIsalpha(wxChar ch
) { return IsCharAlpha(ch
); } 
 870 WXDLLEXPORT 
int wxIsctrl(wxChar ch
) { return wxMSW_ctype(ch
) & C1_CNTRL
; } 
 871 WXDLLEXPORT 
int wxIsdigit(wxChar ch
) { return wxMSW_ctype(ch
) & C1_DIGIT
; } 
 872 WXDLLEXPORT 
int wxIsgraph(wxChar ch
) { return wxMSW_ctype(ch
) & (C1_DIGIT
|C1_PUNCT
|C1_ALPHA
); } 
 873 WXDLLEXPORT 
int wxIslower(wxChar ch
) { return IsCharLower(ch
); } 
 874 WXDLLEXPORT 
int wxIsprint(wxChar ch
) { return wxMSW_ctype(ch
) & (C1_DIGIT
|C1_SPACE
|C1_PUNCT
|C1_ALPHA
); } 
 875 WXDLLEXPORT 
int wxIspunct(wxChar ch
) { return wxMSW_ctype(ch
) & C1_PUNCT
; } 
 876 WXDLLEXPORT 
int wxIsspace(wxChar ch
) { return wxMSW_ctype(ch
) & C1_SPACE
; } 
 877 WXDLLEXPORT 
int wxIsupper(wxChar ch
) { return IsCharUpper(ch
); } 
 878 WXDLLEXPORT 
int wxIsxdigit(wxChar ch
) { return wxMSW_ctype(ch
) & C1_XDIGIT
; } 
 879 WXDLLEXPORT 
int wxTolower(wxChar ch
) { return (wxChar
)CharLower((LPTSTR
)(ch
)); } 
 880 WXDLLEXPORT 
int wxToupper(wxChar ch
) { return (wxChar
)CharUpper((LPTSTR
)(ch
)); } 
 884 WXDLLEXPORT wxChar 
* wxStrdup(const wxChar 
*psz
) 
 886   size_t size 
= (wxStrlen(psz
) + 1) * sizeof(wxChar
); 
 887   wxChar 
*ret 
= (wxChar 
*) malloc(size
); 
 888   memcpy(ret
, psz
, size
); 
 894 int WXDLLEXPORT 
wxStricmp(const wxChar 
*psz1
, const wxChar 
*psz2
) 
 896   register wxChar c1
, c2
; 
 898     c1 
= wxTolower(*psz1
++); 
 899     c2 
= wxTolower(*psz2
++); 
 900   } while ( c1 
&& (c1 
== c2
) ); 
 906 int WXDLLEXPORT 
wxStrnicmp(const wxChar 
*s1
, const wxChar 
*s2
, size_t n
) 
 908   register wxChar c1
, c2
; 
 909   while (n 
&& ((c1 
= wxTolower(*s1
)) == (c2 
= wxTolower(*s2
)) ) && c1
) n
--, s1
++, s2
++; 
 911     if (c1 
< c2
) return -1; 
 912     if (c1 
> c2
) return 1; 
 919 WXDLLEXPORT wxChar 
* wxStrtok(wxChar 
*psz
, const wxChar 
*delim
, wxChar 
**save_ptr
) 
 921   if (!psz
) psz 
= *save_ptr
; 
 922   psz 
+= wxStrspn(psz
, delim
); 
 924     *save_ptr 
= (wxChar 
*)NULL
; 
 925     return (wxChar 
*)NULL
; 
 928   psz 
= wxStrpbrk(psz
, delim
); 
 929   if (!psz
) *save_ptr 
= (wxChar
*)NULL
; 
 939 WXDLLEXPORT wxWCharBuffer 
wxSetlocale(int category
, const wxChar 
*locale
) 
 941     char *localeOld 
= setlocale(category
, wxConvLocal
.cWX2MB(locale
)); 
 943     return wxWCharBuffer(wxConvLocal
.cMB2WC(localeOld
)); 
 947 // ---------------------------------------------------------------------------- 
 948 // string.h functions 
 949 // ---------------------------------------------------------------------------- 
 951 #ifdef wxNEED_WX_STRING_H 
 952 WXDLLEXPORT wxChar 
* wxStrcat(wxChar 
*dest
, const wxChar 
*src
) 
 955   while (*dest
) dest
++; 
 956   while ((*dest
++ = *src
++)); 
 960 WXDLLEXPORT 
const wxChar 
* wxStrchr(const wxChar 
*s
, wxChar c
) 
 962     // be careful here as the terminating NUL makes part of the string 
 972 WXDLLEXPORT 
int wxStrcmp(const wxChar 
*s1
, const wxChar 
*s2
) 
 974   while ((*s1 
== *s2
) && *s1
) s1
++, s2
++; 
 975   if ((wxUChar
)*s1 
< (wxUChar
)*s2
) return -1; 
 976   if ((wxUChar
)*s1 
> (wxUChar
)*s2
) return 1; 
 980 WXDLLEXPORT wxChar 
* wxStrcpy(wxChar 
*dest
, const wxChar 
*src
) 
 983   while ((*dest
++ = *src
++)); 
 987 WXDLLEXPORT wxChar 
* wxStrncat(wxChar 
*dest
, const wxChar 
*src
, size_t n
) 
 990   while (*dest
) dest
++; 
 991   while (n 
&& (*dest
++ = *src
++)) n
--; 
 995 WXDLLEXPORT 
int wxStrncmp(const wxChar 
*s1
, const wxChar 
*s2
, size_t n
) 
 997   while (n 
&& (*s1 
== *s2
) && *s1
) n
--, s1
++, s2
++; 
 999     if ((wxUChar
)*s1 
< (wxUChar
)*s2
) return -1; 
1000     if ((wxUChar
)*s1 
> (wxUChar
)*s2
) return 1; 
1005 WXDLLEXPORT wxChar 
* wxStrncpy(wxChar 
*dest
, const wxChar 
*src
, size_t n
) 
1008   while (n 
&& (*dest
++ = *src
++)) n
--; 
1009   while (n
) *dest
++=0, n
--; // the docs specify padding with zeroes 
1013 WXDLLEXPORT 
const wxChar 
* wxStrpbrk(const wxChar 
*s
, const wxChar 
*accept
) 
1015   while (*s 
&& !wxStrchr(accept
, *s
)) 
1018   return *s 
? s 
: NULL
; 
1021 WXDLLEXPORT 
const wxChar 
* wxStrrchr(const wxChar 
*s
, wxChar c
) 
1023     const wxChar 
*ret 
= NULL
; 
1035 WXDLLEXPORT 
size_t wxStrspn(const wxChar 
*s
, const wxChar 
*accept
) 
1038   while (wxStrchr(accept
, *s
++)) len
++; 
1042 WXDLLEXPORT 
const wxChar 
*wxStrstr(const wxChar 
*haystack
, const wxChar 
*needle
) 
1044     wxCHECK_RET( needle
, NULL
, _T("NULL argument in wxStrstr") ); 
1046     // VZ: this is not exactly the most efficient string search algorithm... 
1048     const size_t len 
= wxStrlen(needle
); 
1050     while ( const wxChar 
*fnd 
= wxStrchr(haystack
, *needle
) ) 
1052         if ( !wxStrncmp(fnd
, needle
, len
) ) 
1061 WXDLLEXPORT 
double wxStrtod(const wxChar 
*nptr
, wxChar 
**endptr
) 
1063   const wxChar 
*start 
= nptr
; 
1065   // FIXME: only correct for C locale 
1066   while (wxIsspace(*nptr
)) nptr
++; 
1067   if (*nptr 
== wxT('+') || *nptr 
== wxT('-')) nptr
++; 
1068   while (wxIsdigit(*nptr
)) nptr
++; 
1069   if (*nptr 
== wxT('.')) { 
1071     while (wxIsdigit(*nptr
)) nptr
++; 
1073   if (*nptr 
== wxT('E') || *nptr 
== wxT('e')) { 
1075     if (*nptr 
== wxT('+') || *nptr 
== wxT('-')) nptr
++; 
1076     while (wxIsdigit(*nptr
)) nptr
++; 
1079   wxString 
data(nptr
, nptr
-start
); 
1080   wxWX2MBbuf dat 
= data
.mb_str(wxConvLocal
); 
1081   char *rdat 
= wxMBSTRINGCAST dat
; 
1082   double ret 
= strtod(dat
, &rdat
); 
1084   if (endptr
) *endptr 
= (wxChar 
*)(start 
+ (rdat 
- (const char *)dat
)); 
1089 WXDLLEXPORT 
long int wxStrtol(const wxChar 
*nptr
, wxChar 
**endptr
, int base
) 
1091   const wxChar 
*start 
= nptr
; 
1093   // FIXME: only correct for C locale 
1094   while (wxIsspace(*nptr
)) nptr
++; 
1095   if (*nptr 
== wxT('+') || *nptr 
== wxT('-')) nptr
++; 
1096   if (((base 
== 0) || (base 
== 16)) && 
1097       (nptr
[0] == wxT('0') && nptr
[1] == wxT('x'))) { 
1101   else if ((base 
== 0) && (nptr
[0] == wxT('0'))) base 
= 8; 
1102   else if (base 
== 0) base 
= 10; 
1104   while ((wxIsdigit(*nptr
) && (*nptr 
- wxT('0') < base
)) || 
1105          (wxIsalpha(*nptr
) && (wxToupper(*nptr
) - wxT('A') + 10 < base
))) nptr
++; 
1107   wxString 
data(nptr
, nptr
-start
); 
1108   wxWX2MBbuf dat 
= data
.mb_str(wxConvLocal
); 
1109   char *rdat 
= wxMBSTRINGCAST dat
; 
1110   long int ret 
= strtol(dat
, &rdat
, base
); 
1112   if (endptr
) *endptr 
= (wxChar 
*)(start 
+ (rdat 
- (const char *)dat
)); 
1116 #endif // wxNEED_WX_STRING_H 
1118 #ifdef wxNEED_WX_STDIO_H 
1119 WXDLLEXPORT 
FILE * wxFopen(const wxChar 
*path
, const wxChar 
*mode
) 
1121     char mode_buffer
[10]; 
1122     for (size_t i 
= 0; i 
< wxStrlen(mode
)+1; i
++) 
1123        mode_buffer
[i
] = (char) mode
[i
]; 
1125     return fopen( wxConvFile
.cWX2MB(path
), mode_buffer 
); 
1128 WXDLLEXPORT 
FILE * wxFreopen(const wxChar 
*path
, const wxChar 
*mode
, FILE *stream
) 
1130     char mode_buffer
[10]; 
1131     for (size_t i 
= 0; i 
< wxStrlen(mode
)+1; i
++) 
1132        mode_buffer
[i
] = (char) mode
[i
]; 
1134     return freopen( wxConvFile
.cWX2MB(path
), mode_buffer
, stream 
); 
1137 WXDLLEXPORT 
int wxRemove(const wxChar 
*path
) 
1139     return remove( wxConvFile
.cWX2MB(path
) ); 
1142 WXDLLEXPORT 
int wxRename(const wxChar 
*oldpath
, const wxChar 
*newpath
) 
1144     return rename( wxConvFile
.cWX2MB(oldpath
), wxConvFile
.cWX2MB(newpath
) ); 
1149 double   WXDLLEXPORT 
wxAtof(const wxChar 
*psz
) 
1151   return atof(wxConvLocal
.cWX2MB(psz
)); 
1155 #ifdef wxNEED_WX_STDLIB_H 
1156 int      WXDLLEXPORT 
wxAtoi(const wxChar 
*psz
) 
1158   return atoi(wxConvLocal
.cWX2MB(psz
)); 
1161 long     WXDLLEXPORT 
wxAtol(const wxChar 
*psz
) 
1163   return atol(wxConvLocal
.cWX2MB(psz
)); 
1166 wxChar 
* WXDLLEXPORT 
wxGetenv(const wxChar 
*name
) 
1168   static wxHashTable env
; 
1170   // check if we already have stored the converted env var 
1171   wxObject 
*data 
= env
.Get(name
); 
1174     // nope, retrieve it, 
1176     wxCharBuffer buffer 
= wxConvLocal
.cWX2MB(name
); 
1177     // printf( "buffer %s\n", (const char*) buffer ); 
1178     const char *val 
= getenv( (const char *)buffer 
); 
1180     const char *val 
= getenv( name 
); 
1183     if (!val
) return (wxChar 
*)NULL
; 
1184     // printf( "home %s\n", val ); 
1187 #ifdef wxUSE_UNICODE 
1188     data 
= (wxObject 
*)new wxString(val
, wxConvLocal
); 
1190     data 
= (wxObject 
*)new wxString(val
); 
1194     env
.Put(name
, data
); 
1196   // return converted env var 
1197   return (wxChar 
*)((wxString 
*)data
)->c_str(); 
1200 int WXDLLEXPORT 
wxSystem(const wxChar 
*psz
) 
1202     return system(wxConvLocal
.cWX2MB(psz
)); 
1207 #ifdef wxNEED_WX_TIME_H 
1208 WXDLLEXPORT 
size_t   wxStrftime(wxChar 
*s
, size_t max
, const wxChar 
*fmt
, const struct tm 
*tm
) 
1212     char *buf 
= (char *)malloc(max
); 
1213     size_t ret 
= strftime(buf
, max
, wxConvLocal
.cWX2MB(fmt
), tm
); 
1216         wxStrcpy(s
, wxConvLocal
.cMB2WX(buf
));