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 CRTDLL_iswalnum( WCHAR wc )
421 return isalnum( LOBYTE(wc) ); /* FIXME */
425 /*********************************************************************
426 * CRTDLL_iswalpha (CRTDLL.406)
428 int CRTDLL_iswalpha( WCHAR wc )
434 return isalpha( LOBYTE(wc) ); /* FIXME */
438 /*********************************************************************
439 * CRTDLL_iswcntrl (CRTDLL.408)
441 int CRTDLL_iswcntrl( WCHAR wc )
447 return iscntrl( LOBYTE(wc) ); /* FIXME */
451 /*********************************************************************
452 * CRTDLL_iswctype (CRTDLL.409)
454 int CRTDLL_iswctype( WCHAR wc, WCHAR wct )
459 if (wct & 0x0001) mask |= _ISwupper;
460 if (wct & 0x0002) mask |= _ISwlower;
461 if (wct & 0x0004) mask |= _ISwdigit;
462 if (wct & 0x0008) mask |= _ISwspace;
463 if (wct & 0x0010) mask |= _ISwpunct;
464 if (wct & 0x0020) mask |= _ISwcntrl;
465 if (wct & 0x0040) mask |= _ISwblank;
466 if (wct & 0x0080) mask |= _ISwxdigit;
467 if (wct & 0x0100) mask |= _ISwalpha;
469 FIXME(": iswctype(%04hx,_LEADBYTE|...) requested\n",wc);
472 return iswctype(wc,mask);
474 FIXME(":iswctype() not supported\n");
479 /*********************************************************************
480 * CRTDLL_iswdigit (CRTDLL.410)
482 int CRTDLL_iswdigit( WCHAR wc )
488 return isdigit( LOBYTE(wc) ); /* FIXME */
492 /*********************************************************************
493 * CRTDLL_iswgraph (CRTDLL.411)
495 int CRTDLL_iswgraph( WCHAR wc )
501 return isgraph( LOBYTE(wc) ); /* FIXME */
505 /*********************************************************************
506 * CRTDLL_iswlower (CRTDLL.412)
508 int CRTDLL_iswlower( WCHAR wc )
514 return islower( LOBYTE(wc) ); /* FIXME */
518 /*********************************************************************
519 * CRTDLL_iswprint (CRTDLL.413)
521 int CRTDLL_iswprint( WCHAR wc )
527 return isprint( LOBYTE(wc) ); /* FIXME */
531 /*********************************************************************
532 * CRTDLL_iswpunct (CRTDLL.414)
534 int CRTDLL_iswpunct( WCHAR wc )
540 return ispunct( LOBYTE(wc) ); /* FIXME */
544 /*********************************************************************
545 * CRTDLL_iswspace (CRTDLL.415)
547 int CRTDLL_iswspace( WCHAR wc )
553 return isspace( LOBYTE(wc) ); /* FIXME */
557 /*********************************************************************
558 * CRTDLL_iswupper (CRTDLL.416)
560 int CRTDLL_iswupper( WCHAR wc )
566 return isupper( LOBYTE(wc) ); /* FIXME */
570 /*********************************************************************
571 * CRTDLL_iswxdigit (CRTDLL.417)
573 int CRTDLL_iswxdigit( WCHAR wc )
577 return iswxdigit(wc);
579 return isxdigit( LOBYTE(wc) ); /* FIXME */