]> git.saurik.com Git - wxWidgets.git/blob - src/common/wxchar.cpp
Changed wxStat, wxAccess and wxOpen to no longer
[wxWidgets.git] / src / common / wxchar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wxchar.cpp
3 // Purpose: wxChar implementation
4 // Author: Ove Kåven
5 // Modified by:
6 // Created: 09/04/99
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows copyright
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "wxchar.h"
14 #endif
15
16 // ===========================================================================
17 // headers, declarations, constants
18 // ===========================================================================
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #define _ISOC9X_SOURCE 1 // to get vsscanf()
28 #define _BSD_SOURCE 1 // to still get strdup()
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <locale.h>
34 #include <time.h>
35
36 #ifndef WX_PRECOMP
37 #include "wx/defs.h"
38 #include "wx/wxchar.h"
39 #include "wx/string.h"
40 #include "wx/hash.h"
41 #endif
42
43 #include "wx/msgdlg.h"
44
45 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H)
46 #include <windef.h>
47 #include <winbase.h>
48 #include <winnls.h>
49 #include <winnt.h>
50 #endif
51
52 #if wxUSE_WCHAR_T
53 size_t WXDLLEXPORT wxMB2WC(wchar_t *buf, const char *psz, size_t n)
54 {
55 if (buf) {
56 if (!n || !*psz) {
57 if (n) *buf = wxT('\0');
58 return 0;
59 }
60 return mbstowcs(buf, psz, n);
61 }
62
63 // assume that we have mbsrtowcs() too if we have wcsrtombs()
64 #ifdef HAVE_WCSRTOMBS
65 mbstate_t mbstate;
66 return mbsrtowcs((wchar_t *) NULL, &psz, 0, &mbstate);
67 #else // !GNU libc
68 return mbstowcs((wchar_t *) NULL, psz, 0);
69 #endif // GNU
70 }
71
72 size_t WXDLLEXPORT wxWC2MB(char *buf, const wchar_t *pwz, size_t n)
73 {
74 if (buf) {
75 if (!n || !*pwz) {
76 // glibc2.1 chokes on null input
77 if (n) *buf = '\0';
78 return 0;
79 }
80 return wcstombs(buf, pwz, n);
81 }
82
83 #if HAVE_WCSRTOMBS
84 mbstate_t mbstate;
85 return wcsrtombs((char *) NULL, &pwz, 0, &mbstate);
86 #else // !GNU libc
87 return wcstombs((char *) NULL, pwz, 0);
88 #endif // GNU
89 }
90 #endif // wxUSE_WCHAR_T
91
92 bool WXDLLEXPORT wxOKlibc()
93 {
94 #if wxUSE_WCHAR_T && defined(__UNIX__) && defined(__GLIBC__)
95 // glibc 2.0 uses UTF-8 even when it shouldn't
96 wchar_t res = 0;
97 if ((MB_CUR_MAX == 2) &&
98 (wxMB2WC(&res, "\xdd\xa5", 1) == 1) &&
99 (res==0x765)) {
100 // this is UTF-8 allright, check whether that's what we want
101 char *cur_locale = setlocale(LC_CTYPE, NULL);
102 if ((strlen(cur_locale) < 4) ||
103 (strcasecmp(cur_locale + strlen(cur_locale) - 4, "utf8")) ||
104 (strcasecmp(cur_locale + strlen(cur_locale) - 5, "utf-8"))) {
105 // nope, don't use libc conversion
106 return FALSE;
107 }
108 }
109 #endif
110 return TRUE;
111 }
112
113 #ifndef HAVE_WCSLEN
114 size_t WXDLLEXPORT wcslen(const wchar_t *s)
115 {
116 size_t len = 0;
117 while (s[len]) len++;
118 return len;
119 }
120 #endif
121
122 #if defined(__WIN32__) && defined(wxNEED_WX_CTYPE_H)
123 inline WORD wxMSW_ctype(wxChar ch)
124 {
125 WORD ret;
126 GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, &ch, 1, &ret);
127 return ret;
128 }
129
130 WXDLLEXPORT int wxIsalnum(wxChar ch) { return IsCharAlphaNumeric(ch); }
131 WXDLLEXPORT int wxIsalpha(wxChar ch) { return IsCharAlpha(ch); }
132 WXDLLEXPORT int wxIsctrl(wxChar ch) { return wxMSW_ctype(ch) & C1_CNTRL; }
133 WXDLLEXPORT int wxIsdigit(wxChar ch) { return wxMSW_ctype(ch) & C1_DIGIT; }
134 WXDLLEXPORT int wxIsgraph(wxChar ch) { return wxMSW_ctype(ch) & (C1_DIGIT|C1_PUNCT|C1_ALPHA); }
135 WXDLLEXPORT int wxIslower(wxChar ch) { return IsCharLower(ch); }
136 WXDLLEXPORT int wxIsprint(wxChar ch) { return wxMSW_ctype(ch) & (C1_DIGIT|C1_SPACE|C1_PUNCT|C1_ALPHA); }
137 WXDLLEXPORT int wxIspunct(wxChar ch) { return wxMSW_ctype(ch) & C1_PUNCT; }
138 WXDLLEXPORT int wxIsspace(wxChar ch) { return wxMSW_ctype(ch) & C1_SPACE; }
139 WXDLLEXPORT int wxIsupper(wxChar ch) { return IsCharUpper(ch); }
140 WXDLLEXPORT int wxIsxdigit(wxChar ch) { return wxMSW_ctype(ch) & C1_XDIGIT; }
141 WXDLLEXPORT int wxTolower(wxChar ch) { return (wxChar)CharLower((LPTSTR)(ch)); }
142 WXDLLEXPORT int wxToupper(wxChar ch) { return (wxChar)CharUpper((LPTSTR)(ch)); }
143 #endif
144
145 #ifndef wxStrdup
146 WXDLLEXPORT wxChar * wxStrdup(const wxChar *psz)
147 {
148 size_t size = (wxStrlen(psz) + 1) * sizeof(wxChar);
149 wxChar *ret = (wxChar *) malloc(size);
150 memcpy(ret, psz, size);
151 return ret;
152 }
153 #endif
154
155 #ifndef wxStricmp
156 int WXDLLEXPORT wxStricmp(const wxChar *psz1, const wxChar *psz2)
157 {
158 register wxChar c1, c2;
159 do {
160 c1 = wxTolower(*psz1++);
161 c2 = wxTolower(*psz2++);
162 } while ( c1 && (c1 == c2) );
163 return c1 - c2;
164 }
165 #endif
166
167 #ifndef wxStricmp
168 int WXDLLEXPORT wxStrnicmp(const wxChar *s1, const wxChar *s2, size_t n)
169 {
170 register wxChar c1, c2;
171 while (n && ((c1 = wxTolower(*s1)) == (c2 = wxTolower(*s2)) ) && c1) n--, s1++, s2++;
172 if (n) {
173 if (c1 < c2) return -1;
174 if (c1 > c2) return 1;
175 }
176 return 0;
177 }
178 #endif
179
180 #ifndef wxStrtok
181 WXDLLEXPORT wxChar * wxStrtok(wxChar *psz, const wxChar *delim, wxChar **save_ptr)
182 {
183 if (!psz) psz = *save_ptr;
184 psz += wxStrspn(psz, delim);
185 if (!*psz) {
186 *save_ptr = (wxChar *)NULL;
187 return (wxChar *)NULL;
188 }
189 wxChar *ret = psz;
190 psz = wxStrpbrk(psz, delim);
191 if (!psz) *save_ptr = (wxChar*)NULL;
192 else {
193 *psz = wxT('\0');
194 *save_ptr = psz + 1;
195 }
196 return ret;
197 }
198 #endif
199
200 #ifndef wxSetlocale
201 WXDLLEXPORT wxWCharBuffer wxSetlocale(int category, const wxChar *locale)
202 {
203 char *localeOld = setlocale(category, wxConvLibc.cWX2MB(locale));
204
205 return wxWCharBuffer(wxConvLibc.cMB2WC(localeOld));
206 }
207 #endif
208
209 #ifdef wxNEED_WX_STRING_H
210 WXDLLEXPORT wxChar * wxStrcat(wxChar *dest, const wxChar *src)
211 {
212 wxChar *ret = dest;
213 while (*dest) dest++;
214 while ((*dest++ = *src++));
215 return ret;
216 }
217
218 WXDLLEXPORT const wxChar * wxStrchr(const wxChar *s, wxChar c)
219 {
220 // be careful here as the terminating NUL makes part of the string
221 while ( *s != c )
222 {
223 if ( !*s++ )
224 return NULL;
225 }
226
227 return s;
228 }
229
230 WXDLLEXPORT int wxStrcmp(const wxChar *s1, const wxChar *s2)
231 {
232 while ((*s1 == *s2) && *s1) s1++, s2++;
233 if ((wxUChar)*s1 < (wxUChar)*s2) return -1;
234 if ((wxUChar)*s1 > (wxUChar)*s2) return 1;
235 return 0;
236 }
237
238 WXDLLEXPORT wxChar * wxStrcpy(wxChar *dest, const wxChar *src)
239 {
240 wxChar *ret = dest;
241 while ((*dest++ = *src++));
242 return ret;
243 }
244
245 WXDLLEXPORT wxChar * wxStrncat(wxChar *dest, const wxChar *src, size_t n)
246 {
247 wxChar *ret = dest;
248 while (*dest) dest++;
249 while (n && (*dest++ = *src++)) n--;
250 return ret;
251 }
252
253 WXDLLEXPORT int wxStrncmp(const wxChar *s1, const wxChar *s2, size_t n)
254 {
255 while (n && (*s1 == *s2) && *s1) n--, s1++, s2++;
256 if (n) {
257 if ((wxUChar)*s1 < (wxUChar)*s2) return -1;
258 if ((wxUChar)*s1 > (wxUChar)*s2) return 1;
259 }
260 return 0;
261 }
262
263 WXDLLEXPORT wxChar * wxStrncpy(wxChar *dest, const wxChar *src, size_t n)
264 {
265 wxChar *ret = dest;
266 while (n && (*dest++ = *src++)) n--;
267 while (n) *dest++=0, n--; // the docs specify padding with zeroes
268 return ret;
269 }
270
271 WXDLLEXPORT const wxChar * wxStrpbrk(const wxChar *s, const wxChar *accept)
272 {
273 while (*s && !wxStrchr(accept, *s))
274 s++;
275
276 return *s ? s : NULL;
277 }
278
279 WXDLLEXPORT const wxChar * wxStrrchr(const wxChar *s, wxChar c)
280 {
281 const wxChar *ret = NULL;
282 do
283 {
284 if ( *s == c )
285 ret = s;
286 s++;
287 }
288 while ( *s );
289
290 return ret;
291 }
292
293 WXDLLEXPORT size_t wxStrspn(const wxChar *s, const wxChar *accept)
294 {
295 size_t len = 0;
296 while (wxStrchr(accept, *s++)) len++;
297 return len;
298 }
299
300 WXDLLEXPORT const wxChar *wxStrstr(const wxChar *haystack, const wxChar *needle)
301 {
302 wxCHECK_RET( needle, NULL, _T("NULL argument in wxStrstr") );
303
304 // VZ: this is not exactly the most efficient string search algorithm...
305
306 const size_t len = wxStrlen(needle);
307
308 while ( const wxChar *fnd = wxStrchr(haystack, *needle) )
309 {
310 if ( !wxStrncmp(fnd, needle, len) )
311 return fnd;
312
313 haystack = fnd + 1;
314 }
315
316 return NULL;
317 }
318
319 WXDLLEXPORT double wxStrtod(const wxChar *nptr, wxChar **endptr)
320 {
321 const wxChar *start = nptr;
322
323 // FIXME: only correct for C locale
324 while (wxIsspace(*nptr)) nptr++;
325 if (*nptr == wxT('+') || *nptr == wxT('-')) nptr++;
326 while (wxIsdigit(*nptr)) nptr++;
327 if (*nptr == wxT('.')) {
328 nptr++;
329 while (wxIsdigit(*nptr)) nptr++;
330 }
331 if (*nptr == wxT('E') || *nptr == wxT('e')) {
332 nptr++;
333 if (*nptr == wxT('+') || *nptr == wxT('-')) nptr++;
334 while (wxIsdigit(*nptr)) nptr++;
335 }
336
337 wxString data(nptr, nptr-start);
338 wxWX2MBbuf dat = data.mb_str(wxConvLibc);
339 char *rdat = wxMBSTRINGCAST dat;
340 double ret = strtod(dat, &rdat);
341
342 if (endptr) *endptr = (wxChar *)(start + (rdat - (const char *)dat));
343
344 return ret;
345 }
346
347 WXDLLEXPORT long int wxStrtol(const wxChar *nptr, wxChar **endptr, int base)
348 {
349 const wxChar *start = nptr;
350
351 // FIXME: only correct for C locale
352 while (wxIsspace(*nptr)) nptr++;
353 if (*nptr == wxT('+') || *nptr == wxT('-')) nptr++;
354 if (((base == 0) || (base == 16)) &&
355 (nptr[0] == wxT('0') && nptr[1] == wxT('x'))) {
356 nptr += 2;
357 base = 16;
358 }
359 else if ((base == 0) && (nptr[0] == wxT('0'))) base = 8;
360 else if (base == 0) base = 10;
361
362 while ((wxIsdigit(*nptr) && (*nptr - wxT('0') < base)) ||
363 (wxIsalpha(*nptr) && (wxToupper(*nptr) - wxT('A') + 10 < base))) nptr++;
364
365 wxString data(nptr, nptr-start);
366 wxWX2MBbuf dat = data.mb_str(wxConvLibc);
367 char *rdat = wxMBSTRINGCAST dat;
368 long int ret = strtol(dat, &rdat, base);
369
370 if (endptr) *endptr = (wxChar *)(start + (rdat - (const char *)dat));
371
372 return ret;
373 }
374 #endif
375
376 #ifdef wxNEED_WX_STDIO_H
377 WXDLLEXPORT FILE * wxFopen(const wxChar *path, const wxChar *mode)
378 {
379 return fopen( wxConvFile.cWX2MB(path), wxConvLibc.cWX2MB(mode) );
380 }
381
382 WXDLLEXPORT FILE * wxFreopen(const wxChar *path, const wxChar *mode, FILE *stream)
383 {
384 return freopen( wxConvFile.cWX2MB(path), wxConvLibc.cWX2MB(mode), stream );
385 }
386
387 WXDLLEXPORT int wxRemove(const wxChar *path)
388 {
389 return remove( wxConvFile.cWX2MB(path) );
390 }
391
392 WXDLLEXPORT int wxRename(const wxChar *oldpath, const wxChar *newpath)
393 {
394 return rename( wxConvFile.cWX2MB(oldpath), wxConvFile.cWX2MB(newpath) );
395 }
396
397 int WXDLLEXPORT wxPrintf(const wxChar *fmt, ...)
398 {
399 va_list argptr;
400 int ret;
401
402 va_start(argptr, fmt);
403 ret = wxVprintf(fmt, argptr);
404 va_end(argptr);
405 return ret;
406 }
407
408 int WXDLLEXPORT wxVprintf(const wxChar *fmt, va_list argptr)
409 {
410 wxString str;
411 str.PrintfV(fmt,argptr);
412 printf("%s", (const char*)str.mb_str());
413 return str.Len();
414 }
415
416 int WXDLLEXPORT wxFprintf(FILE *stream, const wxChar *fmt, ...)
417 {
418 va_list argptr;
419 int ret;
420
421 va_start(argptr, fmt);
422 ret = wxVfprintf(stream, fmt, argptr);
423 va_end(argptr);
424 return ret;
425 }
426
427 int WXDLLEXPORT wxVfprintf(FILE *stream, const wxChar *fmt, va_list argptr)
428 {
429 wxString str;
430 str.PrintfV(fmt,argptr);
431 fprintf(stream, "%s", (const char*)str.mb_str());
432 return str.Len();
433 }
434
435 int WXDLLEXPORT wxSprintf(wxChar *buf, const wxChar *fmt, ...)
436 {
437 va_list argptr;
438 int ret;
439
440 va_start(argptr, fmt);
441 ret = wxVsprintf(buf, fmt, argptr);
442 va_end(argptr);
443 return ret;
444 }
445
446 int WXDLLEXPORT wxVsprintf(wxChar *buf, const wxChar *fmt, va_list argptr)
447 {
448 // this might be sort of inefficient, but it doesn't matter since
449 // we'd prefer people to use wxString::Printf directly instead anyway
450 wxString str;
451 str.PrintfV(fmt,argptr);
452 wxStrcpy(buf,str.c_str());
453 return str.Len();
454 }
455
456 int WXDLLEXPORT wxSscanf(const wxChar *buf, const wxChar *fmt, ...)
457 {
458 va_list argptr;
459 int ret;
460
461 va_start(argptr, fmt);
462 ret = wxVsscanf(buf, fmt, argptr);
463 va_end(argptr);
464 return ret;
465 }
466
467 int WXDLLEXPORT wxVsscanf(const wxChar *buf, const wxChar *fmt, va_list argptr)
468 {
469 int ret;
470 // this will work only for numeric conversion! Strings will not be converted correctly
471 // hopefully this is all we'll need
472 ret = vsscanf(wxConvLibc.cWX2MB(buf), wxConvLibc.cWX2MB(fmt), argptr);
473 return ret;
474 }
475 #endif
476
477 #ifndef wxAtof
478 double WXDLLEXPORT wxAtof(const wxChar *psz)
479 {
480 return atof(wxConvLibc.cWX2MB(psz));
481 }
482 #endif
483
484 #ifdef wxNEED_WX_STDLIB_H
485 int WXDLLEXPORT wxAtoi(const wxChar *psz)
486 {
487 return atoi(wxConvLibc.cWX2MB(psz));
488 }
489
490 long WXDLLEXPORT wxAtol(const wxChar *psz)
491 {
492 return atol(wxConvLibc.cWX2MB(psz));
493 }
494
495 wxChar * WXDLLEXPORT wxGetenv(const wxChar *name)
496 {
497 static wxHashTable env;
498
499 // check if we already have stored the converted env var
500 wxObject *data = env.Get(name);
501 if (!data)
502 {
503 // nope, retrieve it,
504 #if wxUSE_UNICODE
505 wxCharBuffer buffer = wxConvLibc.cWX2MB(name);
506 // printf( "buffer %s\n", (const char*) buffer );
507 const char *val = getenv( (const char *)buffer );
508 #else
509 const char *val = getenv( name );
510 #endif
511
512 if (!val) return (wxChar *)NULL;
513 // printf( "home %s\n", val );
514
515 // convert it,
516 #ifdef wxUSE_UNICODE
517 data = (wxObject *)new wxString(val, wxConvLibc);
518 #else
519 data = (wxObject *)new wxString(val);
520 #endif
521
522 // and store it
523 env.Put(name, data);
524 }
525 // return converted env var
526 return (wxChar *)((wxString *)data)->c_str();
527 }
528
529 int WXDLLEXPORT wxSystem(const wxChar *psz)
530 {
531 return system(wxConvLibc.cWX2MB(psz));
532 }
533
534 #endif
535
536 #ifdef wxNEED_WX_TIME_H
537 WXDLLEXPORT size_t wxStrftime(wxChar *s, size_t max, const wxChar *fmt, const struct tm *tm)
538 {
539 if (!max) return 0;
540 char *buf = (char *)malloc(max);
541 size_t ret = strftime(buf, max, wxConvLibc.cWX2MB(fmt), tm);
542 if (ret) {
543 wxStrcpy(s, wxConvLibc.cMB2WX(buf));
544 free(buf);
545 return wxStrlen(s);
546 } else {
547 free(buf);
548 *s = 0;
549 return 0;
550 }
551 }
552 #endif