2 * CRTDLL wide-char functions
4 * Copyright 1999 Alexandre Julliard
7 * These functions are really necessary only if sizeof(WCHAR) != sizeof(wchar_t),
8 * otherwise we could use the libc functions directly.
22 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(crtdll
);
26 /*********************************************************************
27 * CRTDLL__wcsdup (CRTDLL.320)
29 LPWSTR __cdecl
CRTDLL__wcsdup( LPCWSTR str
)
34 int size
= (CRTDLL_wcslen(str
) + 1) * sizeof(WCHAR
);
35 ret
= CRTDLL_malloc( size
);
36 if (ret
) memcpy( ret
, str
, size
);
42 /*********************************************************************
43 * CRTDLL__wcsicmp (CRTDLL.321)
45 INT __cdecl
CRTDLL__wcsicmp( LPCWSTR str1
, LPCWSTR str2
)
47 while (*str1
&& (CRTDLL_towupper(*str1
) == CRTDLL_towupper(*str2
)))
52 return CRTDLL_towupper(*str1
) - CRTDLL_towupper(*str2
);
56 /*********************************************************************
57 * CRTDLL__wcsicoll (CRTDLL.322)
59 INT __cdecl
CRTDLL__wcsicoll( LPCWSTR str1
, LPCWSTR str2
)
61 /* FIXME: handle collates */
62 return CRTDLL__wcsicmp( str1
, str2
);
66 /*********************************************************************
67 * CRTDLL__wcslwr (CRTDLL.323)
69 LPWSTR __cdecl
CRTDLL__wcslwr( LPWSTR str
)
72 for ( ; *str
; str
++) *str
= CRTDLL_towlower(*str
);
77 /*********************************************************************
78 * CRTDLL__wcsnicmp (CRTDLL.324)
80 INT __cdecl
CRTDLL__wcsnicmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
83 while ((--n
> 0) && *str1
&& (CRTDLL_towupper(*str1
) == CRTDLL_towupper(*str2
)))
88 return CRTDLL_towupper(*str1
) - CRTDLL_towupper(*str2
);
92 /*********************************************************************
93 * CRTDLL__wcsnset (CRTDLL.325)
95 LPWSTR __cdecl
CRTDLL__wcsnset( LPWSTR str
, WCHAR c
, INT n
)
98 while ((n
-- > 0) && *str
) *str
++ = c
;
103 /*********************************************************************
104 * CRTDLL__wcsrev (CRTDLL.326)
106 LPWSTR __cdecl
CRTDLL__wcsrev( LPWSTR str
)
109 LPWSTR end
= str
+ CRTDLL_wcslen(str
) - 1;
120 /*********************************************************************
121 * CRTDLL__wcsset (CRTDLL.327)
123 LPWSTR __cdecl
CRTDLL__wcsset( LPWSTR str
, WCHAR c
)
126 while (*str
) *str
++ = c
;
131 /*********************************************************************
132 * CRTDLL__wcsupr (CRTDLL.328)
134 LPWSTR __cdecl
CRTDLL__wcsupr( LPWSTR str
)
137 for ( ; *str
; str
++) *str
= CRTDLL_towupper(*str
);
142 /*********************************************************************
143 * CRTDLL_towlower (CRTDLL.493)
145 WCHAR __cdecl
CRTDLL_towlower( WCHAR ch
)
148 ch
= (WCHAR
)towlower( (wchar_t)ch
);
150 if (!HIBYTE(ch
)) ch
= (WCHAR
)tolower( LOBYTE(ch
) ); /* FIXME */
156 /*********************************************************************
157 * CRTDLL_towupper (CRTDLL.494)
159 WCHAR __cdecl
CRTDLL_towupper( WCHAR ch
)
162 ch
= (WCHAR
)towupper( (wchar_t)ch
);
164 if (!HIBYTE(ch
)) ch
= (WCHAR
)toupper( LOBYTE(ch
) ); /* FIXME */
170 /***********************************************************************
171 * CRTDLL_wcscat (CRTDLL.503)
173 LPWSTR __cdecl
CRTDLL_wcscat( LPWSTR dst
, LPCWSTR src
)
177 while ((*p
++ = *src
++));
182 /*********************************************************************
183 * CRTDLL_wcschr (CRTDLL.504)
185 LPWSTR __cdecl
CRTDLL_wcschr( LPCWSTR str
, WCHAR ch
)
189 if (*str
== ch
) return (LPWSTR
)str
;
196 /*********************************************************************
197 * CRTDLL_wcscmp (CRTDLL.505)
199 INT __cdecl
CRTDLL_wcscmp( LPCWSTR str1
, LPCWSTR str2
)
201 while (*str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
202 return (INT
)(*str1
- *str2
);
206 /*********************************************************************
207 * CRTDLL_wcscoll (CRTDLL.506)
209 DWORD __cdecl
CRTDLL_wcscoll( LPCWSTR str1
, LPCWSTR str2
)
211 /* FIXME: handle collates */
212 return CRTDLL_wcscmp( str1
, str2
);
216 /***********************************************************************
217 * CRTDLL_wcscpy (CRTDLL.507)
219 LPWSTR __cdecl
CRTDLL_wcscpy( LPWSTR dst
, LPCWSTR src
)
222 while ((*p
++ = *src
++));
227 /*********************************************************************
228 * CRTDLL_wcscspn (CRTDLL.508)
230 INT __cdecl
CRTDLL_wcscspn( LPCWSTR str
, LPCWSTR reject
)
236 while (*p
&& (*p
!= *str
)) p
++;
244 /***********************************************************************
245 * CRTDLL_wcslen (CRTDLL.510)
247 INT __cdecl
CRTDLL_wcslen( LPCWSTR str
)
255 /*********************************************************************
256 * CRTDLL_wcsncat (CRTDLL.511)
258 LPWSTR __cdecl
CRTDLL_wcsncat( LPWSTR s1
, LPCWSTR s2
, INT n
)
262 while (n
-- > 0) if (!(*s1
++ = *s2
++)) return ret
;
268 /*********************************************************************
269 * CRTDLL_wcsncmp (CRTDLL.512)
271 INT __cdecl
CRTDLL_wcsncmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
274 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
275 return (INT
)(*str1
- *str2
);
279 /*********************************************************************
280 * CRTDLL_wcsncpy (CRTDLL.513)
282 LPWSTR __cdecl
CRTDLL_wcsncpy( LPWSTR s1
, LPCWSTR s2
, INT n
)
285 while (n
-- > 0) if (!(*s1
++ = *s2
++)) break;
286 while (n
-- > 0) *s1
++ = 0;
291 /*********************************************************************
292 * CRTDLL_wcspbrk (CRTDLL.514)
294 LPWSTR __cdecl
CRTDLL_wcspbrk( LPCWSTR str
, LPCWSTR accept
)
299 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (LPWSTR
)str
;
306 /*********************************************************************
307 * CRTDLL_wcsrchr (CRTDLL.515)
309 LPWSTR __cdecl
CRTDLL_wcsrchr( LPWSTR str
, WCHAR ch
)
314 if (*str
== ch
) last
= str
;
321 /*********************************************************************
322 * CRTDLL_wcsspn (CRTDLL.516)
324 INT __cdecl
CRTDLL_wcsspn( LPCWSTR str
, LPCWSTR accept
)
330 while (*p
&& (*p
!= *str
)) p
++;
338 /*********************************************************************
339 * CRTDLL_wcsstr (CRTDLL.517)
341 LPWSTR __cdecl
CRTDLL_wcsstr( LPCWSTR str
, LPCWSTR sub
)
345 LPCWSTR p1
= str
, p2
= sub
;
346 while (*p1
&& *p2
&& *p1
== *p2
) { p1
++; p2
++; }
347 if (!*p2
) return (LPWSTR
)str
;
354 /*********************************************************************
355 * CRTDLL_wcstok (CRTDLL.519)
357 LPWSTR __cdecl
CRTDLL_wcstok( LPWSTR str
, LPCWSTR delim
)
359 static LPWSTR next
= NULL
;
363 if (!(str
= next
)) return NULL
;
365 while (*str
&& CRTDLL_wcschr( delim
, *str
)) str
++;
366 if (!*str
) return NULL
;
368 while (*str
&& !CRTDLL_wcschr( delim
, *str
)) str
++;
369 if (*str
) *str
++ = 0;
375 /*********************************************************************
376 * CRTDLL_wcstombs (CRTDLL.521)
378 * FIXME: the reason I do not use wcstombs is that it seems to fail
379 * for any latin-1 valid character. Not good.
381 INT __cdecl
CRTDLL_wcstombs( LPSTR dst
, LPCWSTR src
, INT n
)
384 while ((n
>0) && *src
) {
386 /* FIXME: could potentially overflow if we ever have MB of 2 bytes*/
387 ret
= wctomb(dst
,(wchar_t)*src
);
389 /* FIXME: sadly, some versions of glibc do not like latin characters
390 * as UNICODE chars for some reason (like german umlauts). Just
391 * copy those anyway. MM 991106
404 /*********************************************************************
405 * CRTDLL_wctomb (CRTDLL.524)
407 INT __cdecl
CRTDLL_wctomb( LPSTR dst
, WCHAR ch
)
409 return wctomb( dst
, (wchar_t)ch
);
412 /*********************************************************************
413 * CRTDLL_iswalnum (CRTDLL.405)
415 INT __cdecl
CRTDLL_iswalnum( WCHAR wc
)
421 return isalnum( LOBYTE(wc
) ); /* FIXME */
425 /*********************************************************************
426 * CRTDLL_iswalpha (CRTDLL.406)
428 INT __cdecl
CRTDLL_iswalpha( WCHAR wc
)
434 return isalpha( LOBYTE(wc
) ); /* FIXME */
438 /*********************************************************************
439 * CRTDLL_iswcntrl (CRTDLL.408)
441 INT __cdecl
CRTDLL_iswcntrl( WCHAR wc
)
447 return iscntrl( LOBYTE(wc
) ); /* FIXME */
451 /*********************************************************************
452 * CRTDLL_iswdigit (CRTDLL.410)
454 INT __cdecl
CRTDLL_iswdigit( WCHAR wc
)
460 return isdigit( LOBYTE(wc
) ); /* FIXME */
464 /*********************************************************************
465 * CRTDLL_iswgraph (CRTDLL.411)
467 INT __cdecl
CRTDLL_iswgraph( WCHAR wc
)
473 return isgraph( LOBYTE(wc
) ); /* FIXME */
477 /*********************************************************************
478 * CRTDLL_iswlower (CRTDLL.412)
480 INT __cdecl
CRTDLL_iswlower( WCHAR wc
)
486 return islower( LOBYTE(wc
) ); /* FIXME */
490 /*********************************************************************
491 * CRTDLL_iswprint (CRTDLL.413)
493 INT __cdecl
CRTDLL_iswprint( WCHAR wc
)
499 return isprint( LOBYTE(wc
) ); /* FIXME */
503 /*********************************************************************
504 * CRTDLL_iswpunct (CRTDLL.414)
506 INT __cdecl
CRTDLL_iswpunct( WCHAR wc
)
512 return ispunct( LOBYTE(wc
) ); /* FIXME */
516 /*********************************************************************
517 * CRTDLL_iswspace (CRTDLL.415)
519 INT __cdecl
CRTDLL_iswspace( WCHAR wc
)
525 return isspace( LOBYTE(wc
) ); /* FIXME */
529 /*********************************************************************
530 * CRTDLL_iswupper (CRTDLL.416)
532 INT __cdecl
CRTDLL_iswupper( WCHAR wc
)
538 return isupper( LOBYTE(wc
) ); /* FIXME */
542 /*********************************************************************
543 * CRTDLL_iswxdigit (CRTDLL.417)
545 INT __cdecl
CRTDLL_iswxdigit( WCHAR wc
)
549 return iswxdigit(wc
);
551 return isxdigit( LOBYTE(wc
) ); /* FIXME */
555 /*********************************************************************
556 * CRTDLL_iswctype (CRTDLL.409)
558 INT __cdecl
CRTDLL_iswctype( WCHAR wc
, WCHAR wct
)
562 if (wct
& 0x0001) res
|= CRTDLL_iswupper(wc
);
563 if (wct
& 0x0002) res
|= CRTDLL_iswlower(wc
);
564 if (wct
& 0x0004) res
|= CRTDLL_iswdigit(wc
);
565 if (wct
& 0x0008) res
|= CRTDLL_iswspace(wc
);
566 if (wct
& 0x0010) res
|= CRTDLL_iswpunct(wc
);
567 if (wct
& 0x0020) res
|= CRTDLL_iswcntrl(wc
);
568 if (wct
& 0x0080) res
|= CRTDLL_iswxdigit(wc
);
569 if (wct
& 0x0100) res
|= CRTDLL_iswalpha(wc
);
571 FIXME(": iswctype(%04hx,_BLANK|...) requested\n",wc
);
573 FIXME(": iswctype(%04hx,_LEADBYTE|...) requested\n",wc
);