Reimplemented multi-byte and wide-chars functions to not depend on
[wine/multimedia.git] / dlls / crtdll / wcstring.c
bloba566b5fa261518497e25a9f1888a41aae5e46989
1 /*
2 * CRTDLL wide-char functions
4 * Copyright 1999 Alexandre Julliard
6 * TODO:
7 * These functions are really necessary only if sizeof(WCHAR) != sizeof(wchar_t),
8 * otherwise we could use the libc functions directly.
9 */
11 #include "config.h"
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #ifdef HAVE_WCTYPE_H
17 #include <wctype.h>
18 #endif
20 #include "windef.h"
21 #include "crtdll.h"
24 /*********************************************************************
25 * CRTDLL__wcsdup (CRTDLL.320)
27 LPWSTR __cdecl CRTDLL__wcsdup( LPCWSTR str )
29 LPWSTR ret = NULL;
30 if (str)
32 int size = (CRTDLL_wcslen(str) + 1) * sizeof(WCHAR);
33 ret = CRTDLL_malloc( size );
34 if (ret) memcpy( ret, str, size );
36 return ret;
40 /*********************************************************************
41 * CRTDLL__wcsicmp (CRTDLL.321)
43 INT __cdecl CRTDLL__wcsicmp( LPCWSTR str1, LPCWSTR str2 )
45 while (*str1 && (CRTDLL_towupper(*str1) == CRTDLL_towupper(*str2)))
47 str1++;
48 str2++;
50 return CRTDLL_towupper(*str1) - CRTDLL_towupper(*str2);
54 /*********************************************************************
55 * CRTDLL__wcsicoll (CRTDLL.322)
57 INT __cdecl CRTDLL__wcsicoll( LPCWSTR str1, LPCWSTR str2 )
59 /* FIXME: handle collates */
60 return CRTDLL__wcsicmp( str1, str2 );
64 /*********************************************************************
65 * CRTDLL__wcslwr (CRTDLL.323)
67 LPWSTR __cdecl CRTDLL__wcslwr( LPWSTR str )
69 LPWSTR ret = str;
70 for ( ; *str; str++) *str = CRTDLL_towlower(*str);
71 return ret;
75 /*********************************************************************
76 * CRTDLL__wcsnicmp (CRTDLL.324)
78 INT __cdecl CRTDLL__wcsnicmp( LPCWSTR str1, LPCWSTR str2, INT n )
80 if (!n) return 0;
81 while ((--n > 0) && *str1 && (CRTDLL_towupper(*str1) == CRTDLL_towupper(*str2)))
83 str1++;
84 str2++;
86 return CRTDLL_towupper(*str1) - CRTDLL_towupper(*str2);
90 /*********************************************************************
91 * CRTDLL__wcsnset (CRTDLL.325)
93 LPWSTR __cdecl CRTDLL__wcsnset( LPWSTR str, WCHAR c, INT n )
95 LPWSTR ret = str;
96 while ((n-- > 0) && *str) *str++ = c;
97 return ret;
101 /*********************************************************************
102 * CRTDLL__wcsrev (CRTDLL.326)
104 LPWSTR __cdecl CRTDLL__wcsrev( LPWSTR str )
106 LPWSTR ret = str;
107 LPWSTR end = str + CRTDLL_wcslen(str) - 1;
108 while (end > str)
110 WCHAR t = *end;
111 *end-- = *str;
112 *str++ = t;
114 return ret;
118 /*********************************************************************
119 * CRTDLL__wcsset (CRTDLL.327)
121 LPWSTR __cdecl CRTDLL__wcsset( LPWSTR str, WCHAR c )
123 LPWSTR ret = str;
124 while (*str) *str++ = c;
125 return ret;
129 /*********************************************************************
130 * CRTDLL__wcsupr (CRTDLL.328)
132 LPWSTR __cdecl CRTDLL__wcsupr( LPWSTR str )
134 LPWSTR ret = str;
135 for ( ; *str; str++) *str = CRTDLL_towupper(*str);
136 return ret;
140 /*********************************************************************
141 * CRTDLL_towlower (CRTDLL.493)
143 WCHAR __cdecl CRTDLL_towlower( WCHAR ch )
145 #ifdef HAVE_WCTYPE_H
146 ch = (WCHAR)towlower( (wchar_t)ch );
147 #else
148 if (!HIBYTE(ch)) ch = (WCHAR)tolower( LOBYTE(ch) ); /* FIXME */
149 #endif
150 return ch;
154 /*********************************************************************
155 * CRTDLL_towupper (CRTDLL.494)
157 WCHAR __cdecl CRTDLL_towupper( WCHAR ch )
159 #ifdef HAVE_WCTYPE_H
160 ch = (WCHAR)towupper( (wchar_t)ch );
161 #else
162 if (!HIBYTE(ch)) ch = (WCHAR)toupper( LOBYTE(ch) ); /* FIXME */
163 #endif
164 return ch;
168 /***********************************************************************
169 * CRTDLL_wcscat (CRTDLL.503)
171 LPWSTR __cdecl CRTDLL_wcscat( LPWSTR dst, LPCWSTR src )
173 LPWSTR p = dst;
174 while (*p) p++;
175 while ((*p++ = *src++));
176 return dst;
180 /*********************************************************************
181 * CRTDLL_wcschr (CRTDLL.504)
183 LPWSTR __cdecl CRTDLL_wcschr( LPCWSTR str, WCHAR ch )
185 while (*str)
187 if (*str == ch) return (LPWSTR)str;
188 str++;
190 return NULL;
194 /*********************************************************************
195 * CRTDLL_wcscmp (CRTDLL.505)
197 INT __cdecl CRTDLL_wcscmp( LPCWSTR str1, LPCWSTR str2 )
199 while (*str1 && (*str1 == *str2)) { str1++; str2++; }
200 return (INT)(*str1 - *str2);
204 /*********************************************************************
205 * CRTDLL_wcscoll (CRTDLL.506)
207 DWORD __cdecl CRTDLL_wcscoll( LPCWSTR str1, LPCWSTR str2 )
209 /* FIXME: handle collates */
210 return CRTDLL_wcscmp( str1, str2 );
214 /***********************************************************************
215 * CRTDLL_wcscpy (CRTDLL.507)
217 LPWSTR __cdecl CRTDLL_wcscpy( LPWSTR dst, LPCWSTR src )
219 LPWSTR p = dst;
220 while ((*p++ = *src++));
221 return dst;
225 /*********************************************************************
226 * CRTDLL_wcscspn (CRTDLL.508)
228 INT __cdecl CRTDLL_wcscspn( LPCWSTR str, LPCWSTR reject )
230 LPCWSTR start = str;
231 while (*str)
233 LPCWSTR p = reject;
234 while (*p && (*p != *str)) p++;
235 if (*p) break;
236 str++;
238 return str - start;
242 /***********************************************************************
243 * CRTDLL_wcslen (CRTDLL.510)
245 INT __cdecl CRTDLL_wcslen( LPCWSTR str )
247 LPCWSTR s = str;
248 while (*s) s++;
249 return s - str;
253 /*********************************************************************
254 * CRTDLL_wcsncat (CRTDLL.511)
256 LPWSTR __cdecl CRTDLL_wcsncat( LPWSTR s1, LPCWSTR s2, INT n )
258 LPWSTR ret = s1;
259 while (*s1) s1++;
260 while (n-- > 0) if (!(*s1++ = *s2++)) return ret;
261 *s1 = 0;
262 return ret;
266 /*********************************************************************
267 * CRTDLL_wcsncmp (CRTDLL.512)
269 INT __cdecl CRTDLL_wcsncmp( LPCWSTR str1, LPCWSTR str2, INT n )
271 if (!n) return 0;
272 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
273 return (INT)(*str1 - *str2);
277 /*********************************************************************
278 * CRTDLL_wcsncpy (CRTDLL.513)
280 LPWSTR __cdecl CRTDLL_wcsncpy( LPWSTR s1, LPCWSTR s2, INT n )
282 LPWSTR ret = s1;
283 while (n-- > 0) if (!(*s1++ = *s2++)) break;
284 while (n-- > 0) *s1++ = 0;
285 return ret;
289 /*********************************************************************
290 * CRTDLL_wcspbrk (CRTDLL.514)
292 LPWSTR __cdecl CRTDLL_wcspbrk( LPCWSTR str, LPCWSTR accept )
294 LPCWSTR p;
295 while (*str)
297 for (p = accept; *p; p++) if (*p == *str) return (LPWSTR)str;
298 str++;
300 return NULL;
304 /*********************************************************************
305 * CRTDLL_wcsrchr (CRTDLL.515)
307 LPWSTR __cdecl CRTDLL_wcsrchr( LPWSTR str, WCHAR ch )
309 LPWSTR last = NULL;
310 while (*str)
312 if (*str == ch) last = str;
313 str++;
315 return last;
319 /*********************************************************************
320 * CRTDLL_wcsspn (CRTDLL.516)
322 INT __cdecl CRTDLL_wcsspn( LPCWSTR str, LPCWSTR accept )
324 LPCWSTR start = str;
325 while (*str)
327 LPCWSTR p = accept;
328 while (*p && (*p != *str)) p++;
329 if (!*p) break;
330 str++;
332 return str - start;
336 /*********************************************************************
337 * CRTDLL_wcsstr (CRTDLL.517)
339 LPWSTR __cdecl CRTDLL_wcsstr( LPCWSTR str, LPCWSTR sub )
341 while (*str)
343 LPCWSTR p1 = str, p2 = sub;
344 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
345 if (!*p2) return (LPWSTR)str;
346 str++;
348 return NULL;
352 /*********************************************************************
353 * CRTDLL_wcstok (CRTDLL.519)
355 LPWSTR __cdecl CRTDLL_wcstok( LPWSTR str, LPCWSTR delim )
357 static LPWSTR next = NULL;
358 LPWSTR ret;
360 if (!str)
361 if (!(str = next)) return NULL;
363 while (*str && CRTDLL_wcschr( delim, *str )) str++;
364 if (!*str) return NULL;
365 ret = str++;
366 while (*str && !CRTDLL_wcschr( delim, *str )) str++;
367 if (*str) *str++ = 0;
368 next = str;
369 return ret;
373 /*********************************************************************
374 * CRTDLL_wcstombs (CRTDLL.521)
376 INT __cdecl CRTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT n )
378 wchar_t *buffer, *p;
379 int ret;
381 int size = (CRTDLL_wcslen(src) + 1) * sizeof(wchar_t);
382 if (!(buffer = CRTDLL_malloc( size ))) return -1;
383 p = buffer;
384 while ((*p++ = (wchar_t)*src++));
385 ret = wcstombs( dst, buffer, n );
386 CRTDLL_free( buffer );
387 return ret;
391 /*********************************************************************
392 * CRTDLL_wctomb (CRTDLL.524)
394 INT __cdecl CRTDLL_wctomb( LPSTR dst, WCHAR ch )
396 return wctomb( dst, (wchar_t)ch );