3 * Purpose: Type-safe ANSI and Unicode builds compatible wrappers for
5 * Author: Joel Farley, Ove Kåven
6 * Modified by: Vadim Zeitlin, Robert Roebling, Ron Lee
9 * Copyright: (c) 1998-2006 wxWidgets dev team
10 * Licence: wxWindows licence
13 /* THIS IS A C FILE, DON'T USE C++ FEATURES (IN PARTICULAR COMMENTS) IN IT */
15 #ifndef _WX_WXCRTBASE_H_
16 #define _WX_WXCRTBASE_H_
18 /* -------------------------------------------------------------------------
19 headers and missing declarations
20 ------------------------------------------------------------------------- */
22 #include "wx/chartype.h"
25 Standard headers we need here.
27 NB: don't include any wxWidgets headers here because almost all of them
41 #if defined(HAVE_STRTOK_R) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
42 char *strtok_r(char *, const char *, char **);
46 a few compilers don't have the (non standard but common) isascii function,
47 define it ourselves for them
50 #if defined(__MWERKS__)
51 #define wxNEED_ISASCII
52 #elif defined(_WIN32_WCE)
54 #define wxNEED_ISASCII
60 inline int isascii(int c
) { return (unsigned)c
< 0x80; }
65 #define isspace(c) ((c) == _T(' ') || (c) == _T('\t'))
67 #endif /* _WIN32_WCE */
69 /* string.h functions */
71 #if defined(__MWERKS__) && !defined(__MACH__) && (__MSL__ < 0x00008000)
73 #elif defined(__WXWINCE__)
81 WXDLLIMPEXP_BASE
char *strdup(const char* s
);
84 /* missing functions in some WinCE versions */
86 #if (_WIN32_WCE < 300)
87 WXDLLIMPEXP_BASE
void *calloc( size_t num
, size_t size
);
89 #endif /* _WIN32_WCE */
92 #if defined(__MWERKS__)
93 /* Metrowerks only has wide char support for OS X >= 10.3 */
94 #if !defined(__DARWIN__) || \
95 (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
96 #define wxHAVE_MWERKS_UNICODE
99 #ifdef wxHAVE_MWERKS_UNICODE
100 #define HAVE_WPRINTF 1
101 #define HAVE_WCSRTOMBS 1
102 #define HAVE_VSWPRINTF 1
104 #endif /* __MWERKS__ */
107 /* -------------------------------------------------------------------------
108 UTF-8 locale handling
109 ------------------------------------------------------------------------- */
112 #if wxUSE_UNICODE_UTF8
113 /* flag indicating whether the current locale uses UTF-8 or not; must be
114 updated every time the locale is changed! */
115 #if wxUSE_UTF8_LOCALE_ONLY
116 #define wxLocaleIsUtf8 true
118 extern WXDLLIMPEXP_BASE
bool wxLocaleIsUtf8
;
120 /* function used to update the flag: */
121 extern WXDLLIMPEXP_BASE
void wxUpdateLocaleIsUtf8();
122 #else /* !wxUSE_UNICODE_UTF8 */
123 inline void wxUpdateLocaleIsUtf8() {}
124 #endif /* wxUSE_UNICODE_UTF8/!wxUSE_UNICODE_UTF8 */
125 #endif /* __cplusplus */
128 /* -------------------------------------------------------------------------
130 ------------------------------------------------------------------------- */
132 #define wxCRT_StrcatA strcat
133 #define wxCRT_StrchrA strchr
134 #define wxCRT_StrcmpA strcmp
135 #define wxCRT_StrcollA strcoll
136 #define wxCRT_StrcpyA strcpy
137 #define wxCRT_StrcspnA strcspn
138 #define wxCRT_StrlenA strlen
139 #define wxCRT_StrncatA strncat
140 #define wxCRT_StrncmpA strncmp
141 #define wxCRT_StrncpyA strncpy
142 #define wxCRT_StrpbrkA strpbrk
143 #define wxCRT_StrrchrA strrchr
144 #define wxCRT_StrspnA strspn
145 #define wxCRT_StrstrA strstr
146 #define wxCRT_StrxfrmA strxfrm
148 #define wxCRT_StrcatW wcscat
149 #define wxCRT_StrchrW wcschr
150 #define wxCRT_StrcmpW wcscmp
151 #define wxCRT_StrcollW wcscoll
152 #define wxCRT_StrcpyW wcscpy
153 #define wxCRT_StrcspnW wcscspn
154 #define wxCRT_StrncatW wcsncat
155 #define wxCRT_StrncmpW wcsncmp
156 #define wxCRT_StrncpyW wcsncpy
157 #define wxCRT_StrpbrkW wcspbrk
158 #define wxCRT_StrrchrW wcsrchr
159 #define wxCRT_StrspnW wcsspn
160 #define wxCRT_StrstrW wcsstr
161 #define wxCRT_StrxfrmW wcsxfrm
163 /* Almost all compiler have strdup(), but not quite all: CodeWarrior under
164 Mac and VC++ for Windows CE don't provide it; additionally, gcc under
165 Mac and OpenVMS do not have wcsdup: */
166 #if defined(__VISUALC__) && __VISUALC__ >= 1400
167 #define wxCRT_StrdupA _strdup
168 #elif !(defined(__MWERKS__) && defined(__WXMAC__)) && !defined(__WXWINCE__)
169 #define wxCRT_StrdupA strdup
171 #if defined(__WINDOWS__)
172 #define wxCRT_StrdupW _wcsdup
173 #elif defined(HAVE_WCSDUP)
174 #define wxCRT_StrdupW wcsdup
177 #ifdef wxHAVE_TCHAR_SUPPORT
178 /* we surely have wchar_t if we have TCHAR have wcslen() */
182 #endif /* wxHAVE_TCHAR_SUPPORT */
185 #define wxCRT_StrlenW wcslen
188 #define wxCRT_StrtodA strtod
189 #define wxCRT_StrtolA strtol
190 #define wxCRT_StrtoulA strtoul
191 #define wxCRT_StrtodW wcstod
192 #define wxCRT_StrtolW wcstol
193 #define wxCRT_StrtoulW wcstoul
196 #if __VISUALC__ >= 1300 && !defined(__WXWINCE__)
197 #define wxCRT_StrtollA _strtoi64
198 #define wxCRT_StrtoullA _strtoui64
199 #define wxCRT_StrtollW _wcstoi64
200 #define wxCRT_StrtoullW _wcstoui64
204 #define wxCRT_StrtollA strtoll
205 #define wxCRT_StrtoullA strtoull
206 #endif /* HAVE_STRTOULL */
208 /* assume that we have wcstoull(), which is also C99, too */
209 #define wxCRT_StrtollW wcstoll
210 #define wxCRT_StrtoullW wcstoull
211 #endif /* HAVE_WCSTOULL */
215 /* define wxCRT_StricmpA/W and wxCRT_StrnicmpA/W for various compilers */
217 /* note that we definitely are going to need our own version for widechar
219 #if !defined(wxCRT_StricmpA)
220 #if defined(__BORLANDC__) || defined(__WATCOMC__) || \
221 defined(__SALFORDC__) || defined(__VISAGECPP__) || \
222 defined(__EMX__) || defined(__DJGPP__)
223 #define wxCRT_StricmpA stricmp
224 #define wxCRT_StrnicmpA strnicmp
225 #elif defined(__WXPALMOS__)
226 /* FIXME: There is no equivalent to strnicmp in the Palm OS API. This
227 * quick hack should do until one can be written.
229 #define wxCRT_StricmpA StrCaselessCompare
230 #define wxCRT_StrnicmpA strnicmp
231 #elif defined(__SYMANTEC__) || defined(__VISUALC__) || \
232 (defined(__MWERKS__) && defined(__INTEL__))
233 #define wxCRT_StricmpA _stricmp
234 #define wxCRT_StrnicmpA _strnicmp
235 #elif defined(__UNIX__) || defined(__GNUWIN32__)
236 #define wxCRT_StricmpA strcasecmp
237 #define wxCRT_StrnicmpA strncasecmp
238 /* #else -- use wxWidgets implementation */
240 #endif /* !defined(wxCRT_StricmpA) */
241 /* FIXME-UTF8: use wcs(n)casecmp if available for *W versions */
244 #define wxCRT_StrtokA(str, sep, last) strtok_r(str, sep, last)
246 /* FIXME-UTF8: detect and use wcstok() if available for wxCRT_StrtokW */
248 /* these are extern "C" because they are used by regex lib: */
253 #ifndef wxCRT_StrlenW
254 WXDLLIMPEXP_BASE
size_t wxCRT_StrlenW(const wchar_t *s
);
257 #ifndef wxCRT_StrncmpW
258 WXDLLIMPEXP_BASE
int wxCRT_StrncmpW(const wchar_t *s1
, const wchar_t *s2
, size_t n
);
265 /* FIXME-UTF8: remove this once we are Unicode only */
267 #define wxCRT_StrlenNative wxCRT_StrlenW
268 #define wxCRT_StrncmpNative wxCRT_StrncmpW
269 #define wxCRT_ToupperNative wxCRT_ToupperW
270 #define wxCRT_TolowerNative wxCRT_TolowerW
272 #define wxCRT_StrlenNative wxCRT_StrlenA
273 #define wxCRT_StrncmpNative wxCRT_StrncmpA
274 #define wxCRT_ToupperNative toupper
275 #define wxCRT_TolowerNative tolower
278 #ifndef wxCRT_StrcatW
279 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrcatW(wchar_t *dest
, const wchar_t *src
);
282 #ifndef wxCRT_StrchrW
283 WXDLLIMPEXP_BASE
const wchar_t *wxCRT_StrchrW(const wchar_t *s
, wchar_t c
);
286 #ifndef wxCRT_StrcmpW
287 WXDLLIMPEXP_BASE
int wxCRT_StrcmpW(const wchar_t *s1
, const wchar_t *s2
);
290 #ifndef wxCRT_StrcollW
291 WXDLLIMPEXP_BASE
int wxCRT_StrcollW(const wchar_t *s1
, const wchar_t *s2
);
294 #ifndef wxCRT_StrcpyW
295 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrcpyW(wchar_t *dest
, const wchar_t *src
);
298 #ifndef wxCRT_StrcspnW
299 WXDLLIMPEXP_BASE
size_t wxCRT_StrcspnW(const wchar_t *s
, const wchar_t *reject
);
302 #ifndef wxCRT_StrncatW
303 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrncatW(wchar_t *dest
, const wchar_t *src
, size_t n
);
306 #ifndef wxCRT_StrncpyW
307 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrncpyW(wchar_t *dest
, const wchar_t *src
, size_t n
);
310 #ifndef wxCRT_StrpbrkW
311 WXDLLIMPEXP_BASE
const wchar_t *wxCRT_StrpbrkW(const wchar_t *s
, const wchar_t *accept
);
314 #ifndef wxCRT_StrrchrW
315 WXDLLIMPEXP_BASE
const wchar_t *wxCRT_StrrchrW(const wchar_t *s
, wchar_t c
);
318 #ifndef wxCRT_StrspnW
319 WXDLLIMPEXP_BASE
size_t wxCRT_StrspnW(const wchar_t *s
, const wchar_t *accept
);
322 #ifndef wxCRT_StrstrW
323 WXDLLIMPEXP_BASE
const wchar_t *wxCRT_StrstrW(const wchar_t *haystack
, const wchar_t *needle
);
326 #ifndef wxCRT_StrtodW
327 WXDLLIMPEXP_BASE
double wxCRT_StrtodW(const wchar_t *nptr
, wchar_t **endptr
);
330 #ifndef wxCRT_StrtolW
331 WXDLLIMPEXP_BASE
long int wxCRT_StrtolW(const wchar_t *nptr
, wchar_t **endptr
, int base
);
334 #ifndef wxCRT_StrtoulW
335 WXDLLIMPEXP_BASE
unsigned long int wxCRT_StrtoulW(const wchar_t *nptr
, wchar_t **endptr
, int base
);
338 #ifndef wxCRT_StrxfrmW
339 WXDLLIMPEXP_BASE
size_t wxCRT_StrxfrmW(wchar_t *dest
, const wchar_t *src
, size_t n
);
342 #ifndef wxCRT_StrdupA
343 WXDLLIMPEXP_BASE
char *wxCRT_StrdupA(const char *psz
);
346 #ifndef wxCRT_StrdupW
347 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrdupW(const wchar_t *pwz
);
350 #ifndef wxCRT_StricmpA
351 WXDLLIMPEXP_BASE
int wxCRT_StricmpA(const char *psz1
, const char *psz2
);
354 #ifndef wxCRT_StricmpW
355 WXDLLIMPEXP_BASE
int wxCRT_StricmpW(const wchar_t *psz1
, const wchar_t *psz2
);
358 #ifndef wxCRT_StrnicmpA
359 WXDLLIMPEXP_BASE
int wxCRT_StrnicmpA(const char *psz1
, const char *psz2
, size_t len
);
362 #ifndef wxCRT_StrnicmpW
363 WXDLLIMPEXP_BASE
int wxCRT_StrnicmpW(const wchar_t *psz1
, const wchar_t *psz2
, size_t len
);
366 #ifndef wxCRT_StrtokA
367 WXDLLIMPEXP_BASE
char *wxCRT_StrtokA(char *psz
, const char *delim
, char **save_ptr
);
370 #ifndef wxCRT_StrtokW
371 WXDLLIMPEXP_BASE
wchar_t *wxCRT_StrtokW(wchar_t *psz
, const wchar_t *delim
, wchar_t **save_ptr
);
374 /* supply strtoll and strtoull, if needed */
376 #ifndef wxCRT_StrtollA
377 WXDLLIMPEXP_BASE wxLongLong_t
wxCRT_StrtollA(const char* nptr
,
380 WXDLLIMPEXP_BASE wxULongLong_t
wxCRT_StrtoullA(const char* nptr
,
384 #ifndef wxCRT_StrtollW
385 WXDLLIMPEXP_BASE wxLongLong_t
wxCRT_StrtollW(const wchar_t* nptr
,
388 WXDLLIMPEXP_BASE wxULongLong_t
wxCRT_StrtoullW(const wchar_t* nptr
,
392 #endif // wxLongLong_t
395 /* -------------------------------------------------------------------------
397 ------------------------------------------------------------------------- */
399 #if defined(__UNIX__) || defined(__WXMAC__)
406 /* these functions are only needed in the form used for filenames (i.e. char*
407 on Unix, wchar_t* on Windows), so we don't need to use A/W suffix: */
408 #if wxMBFILES || !wxUSE_UNICODE /* ANSI filenames */
410 #define wxCRT_Fopen fopen
411 #define wxCRT_Freopen freopen
412 #define wxCRT_Remove remove
413 #define wxCRT_Rename rename
415 #else /* Unicode filenames */
417 /* special case: these functions are missing under Win9x with Unicows so we
418 have to implement them ourselves */
419 #if wxUSE_UNICODE_MSLU
420 WXDLLIMPEXP_BASE
FILE* wxMSLU__wfopen(const wchar_t *name
, const wchar_t *mode
);
421 WXDLLIMPEXP_BASE
FILE* wxMSLU__wfreopen(const wchar_t *name
, const wchar_t *mode
, FILE *stream
);
422 WXDLLIMPEXP_BASE
int wxMSLU__wrename(const wchar_t *oldname
, const wchar_t *newname
);
423 WXDLLIMPEXP_BASE
int wxMSLU__wremove(const wchar_t *name
);
424 #define wxCRT_Fopen wxMSLU__wfopen
425 #define wxCRT_Freopen wxMSLU__wfreopen
426 #define wxCRT_Remove wxMSLU__wremove
427 #define wxCRT_Rename wxMSLU__wrename
429 #define wxCRT_Rename _wrename
430 #define wxCRT_Fopen _wfopen
431 #define wxCRT_Freopen _wfreopen
433 /* carefully: wxCRT_Remove() must return 0 on success while
434 DeleteFile() returns 0 on error, so don't just define one as
436 int wxCRT_Remove(const wchar_t *path
);
438 #define wxCRT_Remove _wremove
442 #endif /* wxMBFILES/!wxMBFILES */
444 #define wxCRT_PutsA puts
445 #define wxCRT_FputsA fputs
446 #define wxCRT_FgetsA fgets
447 #define wxCRT_FputcA fputc
448 #define wxCRT_FgetcA fgetc
449 #define wxCRT_UngetcA ungetc
451 #ifdef wxHAVE_TCHAR_SUPPORT
452 #define wxCRT_PutsW _putws
453 #define wxCRT_FputsW fputws
454 #define wxCRT_FputcW fputwc
457 #define wxCRT_FputsW fputws
460 #define wxCRT_PutsW putws
463 #define wxCRT_FputcW fputwc
465 #define wxCRT_FgetsW fgetws
468 WXDLLIMPEXP_BASE
int wxCRT_PutsW(const wchar_t *ws
);
472 WXDLLIMPEXP_BASE
int wxCRT_FputsW(const wchar_t *ch
, FILE *stream
);
476 WXDLLIMPEXP_BASE
int wxCRT_FputcW(wchar_t wc
, FILE *stream
);
479 #define wxCRT_TmpnamA tmpnam
481 #define wxCRT_TmpnamW _wtmpnam
484 #ifndef wxCRT_TmpnamW
485 WXDLLIMPEXP_BASE
wchar_t *wxCRT_TmpnamW(wchar_t *s
);
488 #define wxCRT_PerrorA perror
489 #ifdef wxHAVE_TCHAR_SUPPORT
490 #define wxCRT_PerrorW _wperror
493 /* -------------------------------------------------------------------------
495 ------------------------------------------------------------------------- */
497 /* there are no env vars at all under CE, so no _tgetenv neither */
499 /* can't define as inline function as this is a C file... */
500 #define wxCRT_GetenvA(name) ((char*)NULL)
501 #define wxCRT_GetenvW(name) ((wchar_t*)NULL)
503 #define wxCRT_GetenvA getenv
505 #define wxCRT_GetenvW _wgetenv
509 #ifndef wxCRT_GetenvW
510 WXDLLIMPEXP_BASE
wchar_t * wxCRT_GetenvW(const wchar_t *name
);
514 #define wxCRT_SystemA system
515 /* mingw32 doesn't provide _tsystem() or _wsystem(): */
516 #if defined(_tsystem)
517 #define wxCRT_SystemW _wsystem
520 #define wxCRT_AtofA atof
521 #define wxCRT_AtoiA atoi
522 #define wxCRT_AtolA atol
524 #if defined(__MWERKS__)
526 #define wxCRT_AtofW watof
527 #define wxCRT_AtoiW watoi
528 #define wxCRT_AtolW watol
529 /* else: use ANSI versions */
531 #elif defined(wxHAVE_TCHAR_SUPPORT)
532 #define wxCRT_AtoiW _wtoi
533 #define wxCRT_AtolW _wtol
534 /* _wtof doesn't exist */
537 #define wxCRT_AtofW(s) wcstof(s, NULL)
539 #define wxCRT_AtolW(s) wcstol(s, NULL, 10)
540 /* wcstoi doesn't exist */
544 There are 2 unrelated problems with these functions under Mac:
545 a) Metrowerks MSL CRT implements them strictly in C99 sense and
546 doesn't support (very common) extension of allowing to call
547 mbstowcs(NULL, ...) which makes it pretty useless as you can't
548 know the size of the needed buffer
549 b) OS X <= 10.2 declares and even defined these functions but
550 doesn't really implement them -- they always return an error
552 So use our own replacements in both cases.
554 #if defined(__MWERKS__) && defined(__MSL__)
555 #define wxNEED_WX_MBSTOWCS
559 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_2
560 #define wxNEED_WX_MBSTOWCS
564 #ifdef wxNEED_WX_MBSTOWCS
565 /* even though they are defined and "implemented", they are bad and just
566 stubs so we need our own - we need these even in ANSI builds!! */
567 WXDLLIMPEXP_BASE
size_t wxMbstowcs(wchar_t *, const char *, size_t);
568 WXDLLIMPEXP_BASE
size_t wxWcstombs(char *, const wchar_t *, size_t);
570 #define wxMbstowcs mbstowcs
571 #define wxWcstombs wcstombs
576 /* -------------------------------------------------------------------------
578 ------------------------------------------------------------------------- */
580 #define wxCRT_StrftimeA strftime
581 /* FIXME-UTF8: when is this available? */
582 #define wxCRT_StrftimeW wcsftime
584 #ifndef wxCRT_StrftimeW
585 WXDLLIMPEXP_BASE
size_t wxCRT_StrftimeW(wchar_t *s
, size_t max
,
587 const struct tm
*tm
);
592 /* -------------------------------------------------------------------------
594 ------------------------------------------------------------------------- */
597 #define WXWCHAR_T_CAST(c) (wint_t)(c)
599 #define WXWCHAR_T_CAST(c) c
602 #define wxCRT_IsalnumW(c) iswalnum(WXWCHAR_T_CAST(c))
603 #define wxCRT_IsalphaW(c) iswalpha(WXWCHAR_T_CAST(c))
604 #define wxCRT_IscntrlW(c) iswcntrl(WXWCHAR_T_CAST(c))
605 #define wxCRT_IsdigitW(c) iswdigit(WXWCHAR_T_CAST(c))
606 #define wxCRT_IsgraphW(c) iswgraph(WXWCHAR_T_CAST(c))
607 #define wxCRT_IslowerW(c) iswlower(WXWCHAR_T_CAST(c))
608 #define wxCRT_IsprintW(c) iswprint(WXWCHAR_T_CAST(c))
609 #define wxCRT_IspunctW(c) iswpunct(WXWCHAR_T_CAST(c))
610 #define wxCRT_IsspaceW(c) iswspace(WXWCHAR_T_CAST(c))
611 #define wxCRT_IsupperW(c) iswupper(WXWCHAR_T_CAST(c))
612 #define wxCRT_IsxdigitW(c) iswxdigit(WXWCHAR_T_CAST(c))
615 #if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
616 /* /usr/include/wctype.h incorrectly declares translations */
617 /* tables which provokes tons of compile-time warnings -- try */
618 /* to correct this */
619 #define wxCRT_TolowerW(wc) towctrans((wc), (wctrans_t)__ctype_tolower)
620 #define wxCRT_ToupperW(wc) towctrans((wc), (wctrans_t)__ctype_toupper)
621 #else /* !glibc 2.0 */
622 #define wxCRT_TolowerW towlower
623 #define wxCRT_ToupperW towupper
625 #else /* !__GLIBC__ */
626 /* There is a bug in VC6 C RTL: toxxx() functions dosn't do anything
627 with signed chars < 0, so "fix" it here. */
628 #define wxCRT_TolowerW(c) towlower((wxUChar)(wxChar)(c))
629 #define wxCRT_ToupperW(c) towupper((wxUChar)(wxChar)(c))
630 #endif /* __GLIBC__/!__GLIBC__ */
636 /* -------------------------------------------------------------------------
637 wx wrappers for CRT functions in both char* and wchar_t* versions
638 ------------------------------------------------------------------------- */
642 /* NB: this belongs to wxcrt.h and not this header, but it makes life easier
643 * for buffer.h and stringimpl.h (both of which must be included before
644 * string.h, which is required by wxcrt.h) to have them here: */
646 /* safe version of strlen() (returns 0 if passed NULL pointer) */
647 inline size_t wxStrlen(const char *s
) { return s
? wxCRT_StrlenA(s
) : 0; }
648 inline size_t wxStrlen(const wchar_t *s
) { return s
? wxCRT_StrlenW(s
) : 0; }
649 #define wxWcslen wxCRT_StrlenW
651 #define wxStrdupA wxCRT_StrdupA
652 #define wxStrdupW wxCRT_StrdupW
653 inline char* wxStrdup(const char *s
) { return wxCRT_StrdupA(s
); }
654 inline wchar_t* wxStrdup(const wchar_t *s
) { return wxCRT_StrdupW(s
); }
656 #endif /* __cplusplus */
658 #endif /* _WX_WXCRTBASE_H_ */