2 * NTDLL wide-char functions
4 * Copyright 2000 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
19 #include "wine/unicode.h"
21 #include "debugtools.h"
23 DEFAULT_DEBUG_CHANNEL(ntdll
);
26 /*********************************************************************
27 * NTDLL__wcsicmp (NTDLL)
29 INT __cdecl
NTDLL__wcsicmp( LPCWSTR str1
, LPCWSTR str2
)
31 return strcmpiW( str1
, str2
);
35 /*********************************************************************
36 * NTDLL__wcslwr (NTDLL)
38 LPWSTR __cdecl
NTDLL__wcslwr( LPWSTR str
)
40 return strlwrW( str
);
44 /*********************************************************************
45 * NTDLL__wcsnicmp (NTDLL)
47 INT __cdecl
NTDLL__wcsnicmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
49 return strncmpiW( str1
, str2
, n
);
53 /*********************************************************************
54 * NTDLL__wcsupr (NTDLL)
56 LPWSTR __cdecl
NTDLL__wcsupr( LPWSTR str
)
58 return struprW( str
);
62 /*********************************************************************
63 * NTDLL_towlower (NTDLL)
65 WCHAR __cdecl
NTDLL_towlower( WCHAR ch
)
71 /*********************************************************************
72 * NTDLL_towupper (NTDLL)
74 WCHAR __cdecl
NTDLL_towupper( WCHAR ch
)
80 /***********************************************************************
81 * NTDLL_wcscat (NTDLL)
83 LPWSTR __cdecl
NTDLL_wcscat( LPWSTR dst
, LPCWSTR src
)
85 return strcatW( dst
, src
);
89 /*********************************************************************
90 * NTDLL_wcschr (NTDLL)
92 LPWSTR __cdecl
NTDLL_wcschr( LPCWSTR str
, WCHAR ch
)
94 return strchrW( str
, ch
);
98 /*********************************************************************
99 * NTDLL_wcscmp (NTDLL)
101 INT __cdecl
NTDLL_wcscmp( LPCWSTR str1
, LPCWSTR str2
)
103 return strcmpW( str1
, str2
);
107 /***********************************************************************
108 * NTDLL_wcscpy (NTDLL)
110 LPWSTR __cdecl
NTDLL_wcscpy( LPWSTR dst
, LPCWSTR src
)
112 return strcpyW( dst
, src
);
116 /*********************************************************************
117 * NTDLL_wcscspn (NTDLL)
119 INT __cdecl
NTDLL_wcscspn( LPCWSTR str
, LPCWSTR reject
)
125 while (*p
&& (*p
!= *str
)) p
++;
133 /***********************************************************************
134 * NTDLL_wcslen (NTDLL)
136 INT __cdecl
NTDLL_wcslen( LPCWSTR str
)
138 return strlenW( str
);
142 /*********************************************************************
143 * NTDLL_wcsncat (NTDLL)
145 LPWSTR __cdecl
NTDLL_wcsncat( LPWSTR s1
, LPCWSTR s2
, INT n
)
149 while (n
-- > 0) if (!(*s1
++ = *s2
++)) return ret
;
155 /*********************************************************************
156 * NTDLL_wcsncmp (NTDLL)
158 INT __cdecl
NTDLL_wcsncmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
160 return strncmpW( str1
, str2
, n
);
164 /*********************************************************************
165 * NTDLL_wcsncpy (NTDLL)
167 LPWSTR __cdecl
NTDLL_wcsncpy( LPWSTR s1
, LPCWSTR s2
, INT n
)
169 return strncpyW( s1
, s2
, n
);
173 /*********************************************************************
174 * NTDLL_wcspbrk (NTDLL)
176 LPWSTR __cdecl
NTDLL_wcspbrk( LPCWSTR str
, LPCWSTR accept
)
181 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (LPWSTR
)str
;
188 /*********************************************************************
189 * NTDLL_wcsrchr (NTDLL)
191 LPWSTR __cdecl
NTDLL_wcsrchr( LPWSTR str
, WCHAR ch
)
196 if (*str
== ch
) last
= str
;
203 /*********************************************************************
204 * NTDLL_wcsspn (NTDLL)
206 INT __cdecl
NTDLL_wcsspn( LPCWSTR str
, LPCWSTR accept
)
212 while (*p
&& (*p
!= *str
)) p
++;
220 /*********************************************************************
221 * NTDLL_wcsstr (NTDLL)
223 LPWSTR __cdecl
NTDLL_wcsstr( LPCWSTR str
, LPCWSTR sub
)
225 return strstrW( str
, sub
);
229 /*********************************************************************
230 * NTDLL_wcstok (NTDLL)
232 LPWSTR __cdecl
NTDLL_wcstok( LPWSTR str
, LPCWSTR delim
)
234 static LPWSTR next
= NULL
;
238 if (!(str
= next
)) return NULL
;
240 while (*str
&& NTDLL_wcschr( delim
, *str
)) str
++;
241 if (!*str
) return NULL
;
243 while (*str
&& !NTDLL_wcschr( delim
, *str
)) str
++;
244 if (*str
) *str
++ = 0;
250 /*********************************************************************
251 * NTDLL_wcstombs (NTDLL)
253 INT __cdecl
NTDLL_wcstombs( LPSTR dst
, LPCWSTR src
, INT n
)
256 if (n
<= 0) return 0;
257 ret
= WideCharToMultiByte( CP_ACP
, 0, src
, -1, dst
, dst
? n
: 0, NULL
, NULL
);
258 if (!ret
) return n
; /* overflow */
259 return ret
- 1; /* do not count terminating NULL */
263 /*********************************************************************
264 * NTDLL_mbstowcs (NTDLL)
266 INT __cdecl
NTDLL_mbstowcs( LPWSTR dst
, LPCSTR src
, INT n
)
269 if (n
<= 0) return 0;
270 ret
= MultiByteToWideChar( CP_ACP
, 0, src
, -1, dst
, dst
? n
: 0 );
271 if (!ret
) return n
; /* overflow */
272 return ret
- 1; /* do not count terminating NULL */
276 /*********************************************************************
278 * Like strtol, but for wide character strings.
280 INT __cdecl
NTDLL_wcstol(LPWSTR s
,LPWSTR
*end
,INT base
)
282 LPSTR sA
= HEAP_strdupWtoA(GetProcessHeap(),0,s
),endA
;
283 INT ret
= strtol(sA
,&endA
,base
);
285 HeapFree(GetProcessHeap(),0,sA
);
286 if (end
) *end
= s
+(endA
-sA
); /* pointer magic checked. */
291 /*********************************************************************
292 * NTDLL_iswctype (NTDLL)
294 INT __cdecl
NTDLL_iswctype( WCHAR wc
, WCHAR wct
)
296 return (get_char_typeW(wc
) & 0xfff) & wct
;
300 /*********************************************************************
301 * NTDLL_iswalpha (NTDLL)
303 INT __cdecl
NTDLL_iswalpha( WCHAR wc
)
305 return get_char_typeW(wc
) & C1_ALPHA
;
309 /*********************************************************************
311 * Like _ultoa, but for wide character strings.
313 LPWSTR __cdecl
_ultow(ULONG value
, LPWSTR string
, INT radix
)
321 if (radix
> 36 || radix
<= 1)
324 while (v
|| tp
== tmp
)
331 *tp
++ = i
+ 'a' - 10;
341 /*********************************************************************
343 * Like atol, but for wide character strings.
345 LONG __cdecl
_wtol(LPWSTR string
)
348 NTDLL_wcstombs( buffer
, string
, sizeof(buffer
) );
349 return atol( buffer
);
352 /*********************************************************************
355 INT __cdecl
_wtoi(LPWSTR string
)
357 return _wtol(string
);
360 /* INTERNAL: Wide char snprintf
361 * If you fix a bug in this function, fix it in msvcrt/wcs.c also!
363 static int __cdecl
NTDLL_vsnwprintf(WCHAR
*str
, unsigned int len
,
364 const WCHAR
*format
, va_list valist
)
366 unsigned int written
= 0;
367 const WCHAR
*iter
= format
;
368 char bufa
[256], fmtbufa
[64], *fmta
;
370 TRACE("(%d,%s)\n",len
,debugstr_w(format
));
374 while (*iter
&& *iter
!= (WCHAR
)L
'%')
376 if (written
++ >= len
)
380 if (*iter
== (WCHAR
)L
'%')
384 while (*iter
== (WCHAR
)L
'0' ||
385 *iter
== (WCHAR
)L
'+' ||
386 *iter
== (WCHAR
)L
'-' ||
387 *iter
== (WCHAR
)L
' ' ||
388 *iter
== (WCHAR
)L
'0' ||
389 *iter
== (WCHAR
)L
'*' ||
390 *iter
== (WCHAR
)L
'#')
392 if (*iter
== (WCHAR
)L
'*')
394 char *buffiter
= bufa
;
395 int fieldlen
= va_arg(valist
, int);
396 sprintf(buffiter
, "%d", fieldlen
);
398 *fmta
++ = *buffiter
++;
405 while (isdigit(*iter
))
408 if (*iter
== (WCHAR
)L
'.')
411 if (*iter
== (WCHAR
)L
'*')
413 char *buffiter
= bufa
;
414 int fieldlen
= va_arg(valist
, int);
415 sprintf(buffiter
, "%d", fieldlen
);
417 *fmta
++ = *buffiter
++;
420 while (isdigit(*iter
))
423 if (*iter
== (WCHAR
)L
'h' ||
424 *iter
== (WCHAR
)L
'l')
434 static const WCHAR none
[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
435 const WCHAR
*wstr
= va_arg(valist
, const WCHAR
*);
436 const WCHAR
*striter
= wstr
? wstr
: none
;
439 if (written
++ >= len
)
448 if (written
++ >= len
)
450 *str
++ = (WCHAR
)va_arg(valist
, int);
456 /* For non wc types, use system sprintf and append to wide char output */
457 /* FIXME: for unrecognised types, should ignore % when printing */
458 char *bufaiter
= bufa
;
459 if (*iter
== (WCHAR
)L
'p')
460 sprintf(bufaiter
, "%08lX", va_arg(valist
, long));
465 if (*iter
== (WCHAR
)L
'f')
466 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, double));
468 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, void *));
472 if (written
++ >= len
)
474 *str
++ = *bufaiter
++;
484 *str
++ = (WCHAR
)L
'\0';
489 /***********************************************************************
492 int __cdecl
_snwprintf(WCHAR
*str
, unsigned int len
, const WCHAR
*format
, ...)
496 va_start(valist
, format
);
497 retval
= NTDLL_vsnwprintf(str
, len
, format
, valist
);
503 /***********************************************************************
504 * NTDLL_swprintf (NTDLL)
506 int __cdecl
NTDLL_swprintf(WCHAR
*str
, const WCHAR
*format
, ...)
510 va_start(valist
, format
);
511 retval
= NTDLL_vsnwprintf(str
, INT_MAX
, format
, valist
);