2 * NTDLL wide-char functions
4 * Copyright 2000 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
17 #include "wine/unicode.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(ntdll
);
23 /*********************************************************************
26 INT __cdecl
NTDLL__wcsicmp( LPCWSTR str1
, LPCWSTR str2
)
28 return strcmpiW( str1
, str2
);
32 /*********************************************************************
35 LPWSTR __cdecl
NTDLL__wcslwr( LPWSTR str
)
37 return strlwrW( str
);
41 /*********************************************************************
44 INT __cdecl
NTDLL__wcsnicmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
46 return strncmpiW( str1
, str2
, n
);
50 /*********************************************************************
53 LPWSTR __cdecl
NTDLL__wcsupr( LPWSTR str
)
55 return struprW( str
);
59 /*********************************************************************
62 WCHAR __cdecl
NTDLL_towlower( WCHAR ch
)
68 /*********************************************************************
71 WCHAR __cdecl
NTDLL_towupper( WCHAR ch
)
77 /***********************************************************************
80 LPWSTR __cdecl
NTDLL_wcscat( LPWSTR dst
, LPCWSTR src
)
82 return strcatW( dst
, src
);
86 /*********************************************************************
89 LPWSTR __cdecl
NTDLL_wcschr( LPCWSTR str
, WCHAR ch
)
91 return strchrW( str
, ch
);
95 /*********************************************************************
98 INT __cdecl
NTDLL_wcscmp( LPCWSTR str1
, LPCWSTR str2
)
100 return strcmpW( str1
, str2
);
104 /***********************************************************************
107 LPWSTR __cdecl
NTDLL_wcscpy( LPWSTR dst
, LPCWSTR src
)
109 return strcpyW( dst
, src
);
113 /*********************************************************************
116 INT __cdecl
NTDLL_wcscspn( LPCWSTR str
, LPCWSTR reject
)
122 while (*p
&& (*p
!= *str
)) p
++;
130 /***********************************************************************
133 INT __cdecl
NTDLL_wcslen( LPCWSTR str
)
135 return strlenW( str
);
139 /*********************************************************************
142 LPWSTR __cdecl
NTDLL_wcsncat( LPWSTR s1
, LPCWSTR s2
, INT n
)
146 while (n
-- > 0) if (!(*s1
++ = *s2
++)) return ret
;
152 /*********************************************************************
155 INT __cdecl
NTDLL_wcsncmp( LPCWSTR str1
, LPCWSTR str2
, INT n
)
157 return strncmpW( str1
, str2
, n
);
161 /*********************************************************************
164 LPWSTR __cdecl
NTDLL_wcsncpy( LPWSTR s1
, LPCWSTR s2
, INT n
)
166 return strncpyW( s1
, s2
, n
);
170 /*********************************************************************
173 LPWSTR __cdecl
NTDLL_wcspbrk( LPCWSTR str
, LPCWSTR accept
)
178 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (LPWSTR
)str
;
185 /*********************************************************************
188 LPWSTR __cdecl
NTDLL_wcsrchr( LPWSTR str
, WCHAR ch
)
193 if (*str
== ch
) last
= str
;
200 /*********************************************************************
203 INT __cdecl
NTDLL_wcsspn( LPCWSTR str
, LPCWSTR accept
)
209 while (*p
&& (*p
!= *str
)) p
++;
217 /*********************************************************************
220 LPWSTR __cdecl
NTDLL_wcsstr( LPCWSTR str
, LPCWSTR sub
)
222 return strstrW( str
, sub
);
226 /*********************************************************************
229 LPWSTR __cdecl
NTDLL_wcstok( LPWSTR str
, LPCWSTR delim
)
231 static LPWSTR next
= NULL
;
235 if (!(str
= next
)) return NULL
;
237 while (*str
&& NTDLL_wcschr( delim
, *str
)) str
++;
238 if (!*str
) return NULL
;
240 while (*str
&& !NTDLL_wcschr( delim
, *str
)) str
++;
241 if (*str
) *str
++ = 0;
247 /*********************************************************************
250 INT __cdecl
NTDLL_wcstombs( LPSTR dst
, LPCWSTR src
, INT n
)
256 RtlUnicodeToMultiByteSize( &len
, src
, strlenW(src
)*sizeof(WCHAR
) );
261 if (n
<= 0) return 0;
262 RtlUnicodeToMultiByteN( dst
, n
, &len
, src
, strlenW(src
)*sizeof(WCHAR
) );
263 if (len
< n
) dst
[len
] = 0;
269 /*********************************************************************
272 INT __cdecl
NTDLL_mbstowcs( LPWSTR dst
, LPCSTR src
, INT n
)
278 RtlMultiByteToUnicodeSize( &len
, src
, strlen(src
) );
282 if (n
<= 0) return 0;
283 RtlMultiByteToUnicodeN( dst
, n
*sizeof(WCHAR
), &len
, src
, strlen(src
) );
284 if (len
/ sizeof(WCHAR
) < n
) dst
[len
/ sizeof(WCHAR
)] = 0;
286 return len
/ sizeof(WCHAR
);
290 /*********************************************************************
292 * Like strtol, but for wide character strings.
294 INT __cdecl
NTDLL_wcstol(LPCWSTR s
,LPWSTR
*end
,INT base
)
301 RtlInitUnicodeString( &uni
, s
);
302 RtlUnicodeStringToAnsiString( &ansi
, &uni
, TRUE
);
303 ret
= strtol( ansi
.Buffer
, &endA
, base
);
307 RtlMultiByteToUnicodeSize( &len
, ansi
.Buffer
, endA
- ansi
.Buffer
);
308 *end
= (LPWSTR
)s
+ len
/sizeof(WCHAR
);
310 RtlFreeAnsiString( &ansi
);
315 /*********************************************************************
317 * Like strtoul, but for wide character strings.
319 INT __cdecl
NTDLL_wcstoul(LPCWSTR s
,LPWSTR
*end
,INT base
)
326 RtlInitUnicodeString( &uni
, s
);
327 RtlUnicodeStringToAnsiString( &ansi
, &uni
, TRUE
);
328 ret
= strtoul( ansi
.Buffer
, &endA
, base
);
332 RtlMultiByteToUnicodeSize( &len
, ansi
.Buffer
, endA
- ansi
.Buffer
);
333 *end
= (LPWSTR
)s
+ len
/sizeof(WCHAR
);
335 RtlFreeAnsiString( &ansi
);
340 /*********************************************************************
343 INT __cdecl
NTDLL_iswctype( WCHAR wc
, WCHAR wct
)
345 return (get_char_typeW(wc
) & 0xfff) & wct
;
349 /*********************************************************************
352 INT __cdecl
NTDLL_iswalpha( WCHAR wc
)
354 return get_char_typeW(wc
) & C1_ALPHA
;
358 /*********************************************************************
360 * Like _ultoa, but for wide character strings.
362 LPWSTR __cdecl
_ultow(ULONG value
, LPWSTR string
, INT radix
)
370 if (radix
> 36 || radix
<= 1)
373 while (v
|| tp
== tmp
)
380 *tp
++ = i
+ 'a' - 10;
390 /*********************************************************************
392 * Like atol, but for wide character strings.
394 LONG __cdecl
_wtol(LPWSTR string
)
397 NTDLL_wcstombs( buffer
, string
, sizeof(buffer
) );
398 return atol( buffer
);
401 /*********************************************************************
404 INT __cdecl
_wtoi(LPWSTR string
)
406 return _wtol(string
);
409 /* INTERNAL: Wide char snprintf
410 * If you fix a bug in this function, fix it in msvcrt/wcs.c also!
412 static int __cdecl
NTDLL_vsnwprintf(WCHAR
*str
, unsigned int len
,
413 const WCHAR
*format
, va_list valist
)
415 unsigned int written
= 0;
416 const WCHAR
*iter
= format
;
417 char bufa
[256], fmtbufa
[64], *fmta
;
419 TRACE("(%d,%s)\n",len
,debugstr_w(format
));
423 while (*iter
&& *iter
!= (WCHAR
)L
'%')
425 if (written
++ >= len
)
429 if (*iter
== (WCHAR
)L
'%')
433 while (*iter
== (WCHAR
)L
'0' ||
434 *iter
== (WCHAR
)L
'+' ||
435 *iter
== (WCHAR
)L
'-' ||
436 *iter
== (WCHAR
)L
' ' ||
437 *iter
== (WCHAR
)L
'0' ||
438 *iter
== (WCHAR
)L
'*' ||
439 *iter
== (WCHAR
)L
'#')
441 if (*iter
== (WCHAR
)L
'*')
443 char *buffiter
= bufa
;
444 int fieldlen
= va_arg(valist
, int);
445 sprintf(buffiter
, "%d", fieldlen
);
447 *fmta
++ = *buffiter
++;
454 while (isdigit(*iter
))
457 if (*iter
== (WCHAR
)L
'.')
460 if (*iter
== (WCHAR
)L
'*')
462 char *buffiter
= bufa
;
463 int fieldlen
= va_arg(valist
, int);
464 sprintf(buffiter
, "%d", fieldlen
);
466 *fmta
++ = *buffiter
++;
469 while (isdigit(*iter
))
472 if (*iter
== (WCHAR
)L
'h' ||
473 *iter
== (WCHAR
)L
'l')
483 static const WCHAR none
[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
484 const WCHAR
*wstr
= va_arg(valist
, const WCHAR
*);
485 const WCHAR
*striter
= wstr
? wstr
: none
;
488 if (written
++ >= len
)
497 if (written
++ >= len
)
499 *str
++ = (WCHAR
)va_arg(valist
, int);
505 /* For non wc types, use system sprintf and append to wide char output */
506 /* FIXME: for unrecognised types, should ignore % when printing */
507 char *bufaiter
= bufa
;
508 if (*iter
== (WCHAR
)L
'p')
509 sprintf(bufaiter
, "%08lX", va_arg(valist
, long));
514 if (*iter
== (WCHAR
)L
'f')
515 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, double));
517 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, void *));
521 if (written
++ >= len
)
523 *str
++ = *bufaiter
++;
533 *str
++ = (WCHAR
)L
'\0';
538 /***********************************************************************
539 * _snwprintf (NTDLL.@)
541 int __cdecl
_snwprintf(WCHAR
*str
, unsigned int len
, const WCHAR
*format
, ...)
545 va_start(valist
, format
);
546 retval
= NTDLL_vsnwprintf(str
, len
, format
, valist
);
552 /***********************************************************************
555 int __cdecl
NTDLL_swprintf(WCHAR
*str
, const WCHAR
*format
, ...)
559 va_start(valist
, format
);
560 retval
= NTDLL_vsnwprintf(str
, INT_MAX
, format
, valist
);