2 * msvcrt.dll wide-char functions
4 * Copyright 1999 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
37 enum { LEN_DEFAULT
, LEN_SHORT
, LEN_LONG
} IntegerLength
;
38 BOOLEAN IntegerDouble
, IntegerNative
, LeftAlign
, Alternate
, PadZero
;
39 BOOLEAN WideString
, NaturalString
;
40 int FieldLength
, Precision
;
44 static BOOL n_format_enabled
= TRUE
;
53 /*********************************************************************
54 * _get_printf_count_output (MSVCR80.@)
56 int CDECL
MSVCRT__get_printf_count_output( void )
58 return n_format_enabled
? 1 : 0;
61 /*********************************************************************
62 * _set_printf_count_output (MSVCR80.@)
64 int CDECL
MSVCRT__set_printf_count_output( int enable
)
66 BOOL old
= n_format_enabled
;
67 n_format_enabled
= enable
!= 0;
71 #endif /* _MSVCR_VER>=80 */
73 /*********************************************************************
76 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsdup( const MSVCRT_wchar_t
* str
)
78 MSVCRT_wchar_t
* ret
= NULL
;
81 int size
= (MSVCRT_wcslen(str
) + 1) * sizeof(MSVCRT_wchar_t
);
82 ret
= MSVCRT_malloc( size
);
83 if (ret
) memcpy( ret
, str
, size
);
88 /*********************************************************************
89 * _towlower_l (MSVCRT.@)
91 int CDECL
MSVCRT__towlower_l(MSVCRT_wint_t c
, MSVCRT__locale_t locale
)
93 MSVCRT_pthreadlocinfo locinfo
;
97 locinfo
= get_locinfo();
99 locinfo
= locale
->locinfo
;
101 if(!locinfo
->lc_handle
[MSVCRT_LC_CTYPE
]) {
102 if(c
>= 'A' && c
<= 'Z')
103 return c
+ 'a' - 'A';
107 if(!LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_CTYPE
], LCMAP_LOWERCASE
, &c
, 1, &ret
, 1))
112 /*********************************************************************
113 * towlower (MSVCRT.@)
115 int CDECL
MSVCRT_towlower(MSVCRT_wint_t c
)
117 return MSVCRT__towlower_l(c
, NULL
);
120 INT CDECL
MSVCRT__wcsicmp_l(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
, MSVCRT__locale_t locale
)
122 MSVCRT__locale_tstruct tmp
= {0};
123 MSVCRT_wchar_t c1
, c2
;
125 if(!MSVCRT_CHECK_PMT(str1
!= NULL
) || !MSVCRT_CHECK_PMT(str2
!= NULL
))
126 return MSVCRT__NLSCMPERROR
;
129 locale
= get_current_locale_noalloc(&tmp
);
133 c1
= MSVCRT__towlower_l(*str1
++, locale
);
134 c2
= MSVCRT__towlower_l(*str2
++, locale
);
135 } while(c1
&& (c1
== c2
));
137 free_locale_noalloc(&tmp
);
141 /*********************************************************************
142 * towctrans (MSVCR120.@)
144 wint_t CDECL
towctrans(wint_t c
, wctrans_t category
)
147 return MSVCRT__towupper_l(c
, NULL
);
148 return MSVCRT__towlower_l(c
, NULL
);
151 /*********************************************************************
152 * _wcsicmp (MSVCRT.@)
154 INT CDECL
MSVCRT__wcsicmp( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
156 return MSVCRT__wcsicmp_l(str1
, str2
, NULL
);
159 /*********************************************************************
160 * _wcsnicmp_l (MSVCRT.@)
162 INT CDECL
MSVCRT__wcsnicmp_l(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
,
163 MSVCRT_size_t n
, MSVCRT__locale_t locale
)
165 MSVCRT__locale_tstruct tmp
= {0};
166 MSVCRT_wchar_t c1
, c2
;
171 if(!MSVCRT_CHECK_PMT(str1
!= NULL
) || !MSVCRT_CHECK_PMT(str2
!= NULL
))
172 return MSVCRT__NLSCMPERROR
;
175 locale
= get_current_locale_noalloc(&tmp
);
179 c1
= MSVCRT__towlower_l(*str1
++, locale
);
180 c2
= MSVCRT__towlower_l(*str2
++, locale
);
181 } while(--n
&& c1
&& (c1
== c2
));
183 free_locale_noalloc(&tmp
);
187 /*********************************************************************
188 * _wcsnicmp (MSVCRT.@)
190 INT CDECL
MSVCRT__wcsnicmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
, MSVCRT_size_t n
)
192 return MSVCRT__wcsnicmp_l(str1
, str2
, n
, NULL
);
195 /*********************************************************************
196 * _wcsicoll_l (MSVCRT.@)
198 int CDECL
MSVCRT__wcsicoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT__locale_t locale
)
200 MSVCRT_pthreadlocinfo locinfo
;
203 locinfo
= get_locinfo();
205 locinfo
= locale
->locinfo
;
207 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
209 MSVCRT_wchar_t c1
, c2
;
214 if (c1
>= 'A' && c1
<= 'Z')
218 if (c2
>= 'A' && c2
<= 'Z')
220 } while(c1
&& (c1
== c2
));
224 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], NORM_IGNORECASE
,
225 str1
, -1, str2
, -1)-CSTR_EQUAL
;
228 /*********************************************************************
229 * _wcsicoll (MSVCRT.@)
231 INT CDECL
MSVCRT__wcsicoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
233 return MSVCRT__wcsicoll_l(str1
, str2
, NULL
);
236 /*********************************************************************
237 * _wcsnicoll_l (MSVCRT.@)
239 int CDECL
MSVCRT__wcsnicoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
,
240 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
242 MSVCRT_pthreadlocinfo locinfo
;
245 locinfo
= get_locinfo();
247 locinfo
= locale
->locinfo
;
249 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
251 MSVCRT_wchar_t c1
, c2
;
259 if (c1
>= 'A' && c1
<= 'Z')
263 if (c2
>= 'A' && c2
<= 'Z')
265 } while(--count
&& c1
&& (c1
== c2
));
269 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], NORM_IGNORECASE
,
270 str1
, MSVCRT_wcsnlen(str1
, count
),
271 str2
, MSVCRT_wcsnlen(str2
, count
))-CSTR_EQUAL
;
274 /*********************************************************************
275 * _wcsnicoll (MSVCRT.@)
277 INT CDECL
MSVCRT__wcsnicoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT_size_t count
)
279 return MSVCRT__wcsnicoll_l(str1
, str2
, count
, NULL
);
282 /*********************************************************************
283 * _wcsnset (MSVCRT.@)
285 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsnset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
, MSVCRT_size_t n
)
287 MSVCRT_wchar_t
* ret
= str
;
288 while ((n
-- > 0) && *str
) *str
++ = c
;
292 /*********************************************************************
293 * _wcsnset_s (MSVCRT.@)
295 int CDECL
MSVCRT__wcsnset_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t size
, MSVCRT_wchar_t c
, MSVCRT_size_t count
)
299 if(!str
&& !size
&& !count
) return 0;
300 if(!MSVCRT_CHECK_PMT(str
!= NULL
)) return MSVCRT_EINVAL
;
301 if(!MSVCRT_CHECK_PMT(size
> 0)) return MSVCRT_EINVAL
;
303 for(i
=0; i
<size
-1 && i
<count
; i
++) {
304 if(!str
[i
]) return 0;
308 if(!str
[i
]) return 0;
311 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
312 *MSVCRT__errno() = MSVCRT_EINVAL
;
313 return MSVCRT_EINVAL
;
316 /*********************************************************************
319 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsrev( MSVCRT_wchar_t
* str
)
321 MSVCRT_wchar_t
* ret
= str
;
322 MSVCRT_wchar_t
* end
= str
+ MSVCRT_wcslen(str
) - 1;
325 MSVCRT_wchar_t t
= *end
;
332 /*********************************************************************
333 * _wcsset_s (MSVCRT.@)
335 int CDECL
MSVCRT__wcsset_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t n
, MSVCRT_wchar_t c
)
337 MSVCRT_wchar_t
*p
= str
;
339 if(!MSVCRT_CHECK_PMT(str
!= NULL
)) return MSVCRT_EINVAL
;
340 if(!MSVCRT_CHECK_PMT(n
)) return MSVCRT_EINVAL
;
342 while(*p
&& --n
) *p
++ = c
;
345 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
346 *MSVCRT__errno() = MSVCRT_EINVAL
;
347 return MSVCRT_EINVAL
;
352 /*********************************************************************
355 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
)
357 MSVCRT_wchar_t
* ret
= str
;
358 while (*str
) *str
++ = c
;
362 /******************************************************************
363 * _wcsupr_s_l (MSVCRT.@)
365 int CDECL
MSVCRT__wcsupr_s_l( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
,
366 MSVCRT__locale_t locale
)
368 MSVCRT__locale_tstruct tmp
= {0};
369 MSVCRT_wchar_t
* ptr
= str
;
373 if (str
) *str
= '\0';
374 *MSVCRT__errno() = MSVCRT_EINVAL
;
375 return MSVCRT_EINVAL
;
379 locale
= get_current_locale_noalloc(&tmp
);
385 free_locale_noalloc(&tmp
);
388 *ptr
= MSVCRT__towupper_l(*ptr
, locale
);
392 free_locale_noalloc(&tmp
);
394 /* MSDN claims that the function should return and set errno to
395 * ERANGE, which doesn't seem to be true based on the tests. */
397 *MSVCRT__errno() = MSVCRT_EINVAL
;
398 return MSVCRT_EINVAL
;
401 /******************************************************************
402 * _wcsupr_s (MSVCRT.@)
405 INT CDECL
MSVCRT__wcsupr_s( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
)
407 return MSVCRT__wcsupr_s_l( str
, n
, NULL
);
410 /******************************************************************
411 * _wcsupr_l (MSVCRT.@)
413 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsupr_l( MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
415 MSVCRT__wcsupr_s_l( str
, -1, locale
);
419 /******************************************************************
422 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsupr( MSVCRT_wchar_t
*str
)
424 return MSVCRT__wcsupr_l(str
, NULL
);
427 /******************************************************************
428 * _wcslwr_s_l (MSVCRT.@)
430 int CDECL
MSVCRT__wcslwr_s_l( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
, MSVCRT__locale_t locale
)
432 MSVCRT__locale_tstruct tmp
= {0};
433 MSVCRT_wchar_t
* ptr
= str
;
437 if (str
) *str
= '\0';
438 *MSVCRT__errno() = MSVCRT_EINVAL
;
439 return MSVCRT_EINVAL
;
443 locale
= get_current_locale_noalloc(&tmp
);
449 free_locale_noalloc(&tmp
);
452 *ptr
= MSVCRT__towlower_l(*ptr
, locale
);
456 free_locale_noalloc(&tmp
);
458 /* MSDN claims that the function should return and set errno to
459 * ERANGE, which doesn't seem to be true based on the tests. */
461 *MSVCRT__errno() = MSVCRT_EINVAL
;
462 return MSVCRT_EINVAL
;
465 /******************************************************************
466 * _wcslwr_s (MSVCRT.@)
468 int CDECL
MSVCRT__wcslwr_s( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
)
470 return MSVCRT__wcslwr_s_l(str
, n
, NULL
);
473 /******************************************************************
474 * _wcslwr_l (MSVCRT.@)
476 MSVCRT_wchar_t
* CDECL
MSVCRT__wcslwr_l( MSVCRT_wchar_t
* str
, MSVCRT__locale_t locale
)
478 MSVCRT__wcslwr_s_l(str
, -1, locale
);
482 /******************************************************************
485 MSVCRT_wchar_t
* CDECL
MSVCRT__wcslwr( MSVCRT_wchar_t
* str
)
487 MSVCRT__wcslwr_s_l(str
, -1, NULL
);
491 /*********************************************************************
494 int CDECL
MSVCRT_wcsncmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
, MSVCRT_size_t n
)
498 while(--n
&& *str1
&& (*str1
== *str2
))
503 return *str1
- *str2
;
506 /*********************************************************************
507 * _wcsncoll_l (MSVCRT.@)
509 int CDECL
MSVCRT__wcsncoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
,
510 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
512 MSVCRT_pthreadlocinfo locinfo
;
515 locinfo
= get_locinfo();
517 locinfo
= locale
->locinfo
;
519 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
520 return MSVCRT_wcsncmp(str1
, str2
, count
);
521 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], 0,
522 str1
, MSVCRT_wcsnlen(str1
, count
),
523 str2
, MSVCRT_wcsnlen(str2
, count
))-CSTR_EQUAL
;
526 /*********************************************************************
527 * _wcsncoll (MSVCRT.@)
529 int CDECL
MSVCRT__wcsncoll(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT_size_t count
)
531 return MSVCRT__wcsncoll_l(str1
, str2
, count
, NULL
);
534 static MSVCRT_wchar_t
strtod_wstr_get(void *ctx
)
536 const MSVCRT_wchar_t
**p
= ctx
;
537 if (!**p
) return MSVCRT_WEOF
;
541 static void strtod_wstr_unget(void *ctx
)
543 const MSVCRT_wchar_t
**p
= ctx
;
547 /*********************************************************************
548 * _wcstod_l (MSVCRT.@)
550 double CDECL
MSVCRT__wcstod_l(const MSVCRT_wchar_t
* str
, MSVCRT_wchar_t
** end
,
551 MSVCRT__locale_t locale
)
553 MSVCRT_pthreadlocinfo locinfo
;
554 const MSVCRT_wchar_t
*beg
, *p
;
559 if (!MSVCRT_CHECK_PMT(str
!= NULL
)) {
560 if (end
) *end
= NULL
;
565 locinfo
= get_locinfo();
567 locinfo
= locale
->locinfo
;
570 while(MSVCRT__iswspace_l(*p
, locale
))
574 fp
= fpnum_parse(strtod_wstr_get
, strtod_wstr_unget
, &p
, locinfo
, FALSE
);
575 if (end
) *end
= (p
== beg
? (MSVCRT_wchar_t
*)str
: (MSVCRT_wchar_t
*)p
);
577 err
= fpnum_double(&fp
, &ret
);
578 if(err
) *MSVCRT__errno() = err
;
582 /*********************************************************************
583 * wcsrtombs_l (INTERNAL)
585 static MSVCRT_size_t
MSVCRT_wcsrtombs_l(char *mbstr
, const MSVCRT_wchar_t
**wcstr
,
586 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
588 MSVCRT_pthreadlocinfo locinfo
;
589 MSVCRT_size_t tmp
= 0;
590 BOOL used_default
= FALSE
;
594 locinfo
= get_locinfo();
596 locinfo
= locale
->locinfo
;
598 if(!locinfo
->lc_codepage
) {
602 return MSVCRT_wcslen(*wcstr
);
604 for(i
=0; i
<count
; i
++) {
605 if((*wcstr
)[i
] > 255) {
606 *MSVCRT__errno() = MSVCRT_EILSEQ
;
610 mbstr
[i
] = (*wcstr
)[i
];
611 if(!(*wcstr
)[i
]) break;
616 pused_default
= (locinfo
->lc_codepage
!= CP_UTF8
? &used_default
: NULL
);
619 tmp
= WideCharToMultiByte(locinfo
->lc_codepage
, WC_NO_BEST_FIT_CHARS
,
620 *wcstr
, -1, NULL
, 0, NULL
, pused_default
);
621 if(!tmp
|| used_default
) {
622 *MSVCRT__errno() = MSVCRT_EILSEQ
;
630 MSVCRT_size_t i
, size
;
632 size
= WideCharToMultiByte(locinfo
->lc_codepage
, WC_NO_BEST_FIT_CHARS
,
633 *wcstr
, 1, buf
, 3, NULL
, pused_default
);
634 if(!size
|| used_default
) {
635 *MSVCRT__errno() = MSVCRT_EILSEQ
;
641 for(i
=0; i
<size
; i
++)
642 mbstr
[tmp
++] = buf
[i
];
653 /*********************************************************************
654 * _wcstombs_l (MSVCRT.@)
656 MSVCRT_size_t CDECL
MSVCRT__wcstombs_l(char *mbstr
, const MSVCRT_wchar_t
*wcstr
,
657 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
659 return MSVCRT_wcsrtombs_l(mbstr
, &wcstr
, count
, locale
);
662 /*********************************************************************
663 * wcstombs (MSVCRT.@)
665 MSVCRT_size_t CDECL
MSVCRT_wcstombs(char *mbstr
, const MSVCRT_wchar_t
*wcstr
,
668 return MSVCRT_wcsrtombs_l(mbstr
, &wcstr
, count
, NULL
);
671 /*********************************************************************
672 * wcsrtombs (MSVCRT.@)
674 MSVCRT_size_t CDECL
MSVCRT_wcsrtombs(char *mbstr
, const MSVCRT_wchar_t
**wcstr
,
675 MSVCRT_size_t count
, MSVCRT_mbstate_t
*mbstate
)
680 return MSVCRT_wcsrtombs_l(mbstr
, wcstr
, count
, NULL
);
683 /*********************************************************************
684 * MSVCRT_wcsrtombs_s_l (INTERNAL)
686 static int MSVCRT_wcsrtombs_s_l(MSVCRT_size_t
*ret
, char *mbstr
,
687 MSVCRT_size_t size
, const MSVCRT_wchar_t
**wcstr
,
688 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
693 if(!mbstr
&& !size
&& wcstr
) {
694 conv
= MSVCRT_wcsrtombs_l(NULL
, wcstr
, 0, locale
);
698 return *MSVCRT__errno();
702 if (!MSVCRT_CHECK_PMT(mbstr
!= NULL
)) return MSVCRT_EINVAL
;
703 if (size
) mbstr
[0] = '\0';
704 if (!MSVCRT_CHECK_PMT(wcstr
!= NULL
)) return MSVCRT_EINVAL
;
705 if (!MSVCRT_CHECK_PMT(*wcstr
!= NULL
)) return MSVCRT_EINVAL
;
707 if(count
==MSVCRT__TRUNCATE
|| size
<count
)
713 conv
= MSVCRT_wcsrtombs_l(mbstr
, wcstr
, conv
, locale
);
718 err
= *MSVCRT__errno();
719 }else if(conv
< size
)
720 mbstr
[conv
++] = '\0';
721 else if(conv
==size
&& (count
==MSVCRT__TRUNCATE
|| mbstr
[conv
-1]=='\0')) {
722 mbstr
[conv
-1] = '\0';
723 if(count
==MSVCRT__TRUNCATE
)
724 err
= MSVCRT_STRUNCATE
;
726 MSVCRT_INVALID_PMT("mbstr[size] is too small", MSVCRT_ERANGE
);
738 /*********************************************************************
739 * _wcstombs_s_l (MSVCRT.@)
741 int CDECL
MSVCRT__wcstombs_s_l(MSVCRT_size_t
*ret
, char *mbstr
,
742 MSVCRT_size_t size
, const MSVCRT_wchar_t
*wcstr
,
743 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
745 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, &wcstr
,count
, locale
);
748 /*********************************************************************
749 * wcstombs_s (MSVCRT.@)
751 int CDECL
MSVCRT_wcstombs_s(MSVCRT_size_t
*ret
, char *mbstr
,
752 MSVCRT_size_t size
, const MSVCRT_wchar_t
*wcstr
, MSVCRT_size_t count
)
754 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, &wcstr
, count
, NULL
);
757 /*********************************************************************
758 * wcsrtombs_s (MSVCRT.@)
760 int CDECL
MSVCRT_wcsrtombs_s(MSVCRT_size_t
*ret
, char *mbstr
, MSVCRT_size_t size
,
761 const MSVCRT_wchar_t
**wcstr
, MSVCRT_size_t count
, MSVCRT_mbstate_t
*mbstate
)
766 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, wcstr
, count
, NULL
);
769 /*********************************************************************
772 double CDECL
MSVCRT_wcstod(const MSVCRT_wchar_t
* lpszStr
, MSVCRT_wchar_t
** end
)
774 return MSVCRT__wcstod_l(lpszStr
, end
, NULL
);
777 /*********************************************************************
780 double CDECL
MSVCRT__wtof(const MSVCRT_wchar_t
*str
)
782 return MSVCRT__wcstod_l(str
, NULL
, NULL
);
785 /*********************************************************************
788 double CDECL
MSVCRT__wtof_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
790 return MSVCRT__wcstod_l(str
, NULL
, locale
);
795 /*********************************************************************
796 * _wcstof_l (MSVCR120.@)
798 float CDECL
MSVCRT__wcstof_l( const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t
**end
, MSVCRT__locale_t locale
)
800 return MSVCRT__wcstod_l(str
, end
, locale
);
803 /*********************************************************************
804 * wcstof (MSVCR120.@)
806 float CDECL
MSVCRT_wcstof( const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t
**end
)
808 return MSVCRT__wcstof_l(str
, end
, NULL
);
811 #endif /* _MSVCR_VER>=120 */
813 /*********************************************************************
814 * arg_clbk_valist (INTERNAL)
816 printf_arg
arg_clbk_valist(void *ctx
, int arg_pos
, int type
, __ms_va_list
*valist
)
821 ret
.get_longlong
= va_arg(*valist
, LONGLONG
);
822 else if(type
== VT_INT
)
823 ret
.get_int
= va_arg(*valist
, int);
824 else if(type
== VT_R8
)
825 ret
.get_double
= va_arg(*valist
, double);
826 else if(type
== VT_PTR
)
827 ret
.get_ptr
= va_arg(*valist
, void*);
829 ERR("Incorrect type\n");
836 /*********************************************************************
837 * arg_clbk_positional (INTERNAL)
839 printf_arg
arg_clbk_positional(void *ctx
, int pos
, int type
, __ms_va_list
*valist
)
841 printf_arg
*args
= ctx
;
847 /*********************************************************************
848 * _vsnprintf (MSVCRT.@)
850 int CDECL
_vsnprintf( char *str
, size_t len
, const char *format
, __ms_va_list valist
)
852 static const char nullbyte
= '\0';
853 struct _str_ctx_a ctx
= {len
, str
};
856 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, NULL
, 0,
857 arg_clbk_valist
, NULL
, &valist
);
858 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
864 static int puts_clbk_str_c99_a(void *ctx
, int len
, const char *str
)
866 struct _str_ctx_a
*out
= ctx
;
872 memmove(out
->buf
, str
, out
->len
);
873 out
->buf
+= out
->len
;
878 memmove(out
->buf
, str
, len
);
884 /*********************************************************************
885 * __stdio_common_vsprintf (UCRTBASE.@)
887 int CDECL
__stdio_common_vsprintf( unsigned __int64 options
, char *str
, size_t len
, const char *format
,
888 _locale_t locale
, __ms_va_list valist
)
890 static const char nullbyte
= '\0';
891 struct _str_ctx_a ctx
= {len
, str
};
894 if (options
& ~UCRTBASE_PRINTF_MASK
)
895 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
896 ret
= pf_printf_a(puts_clbk_str_c99_a
,
897 &ctx
, format
, (MSVCRT__locale_t
)locale
, options
& UCRTBASE_PRINTF_MASK
, arg_clbk_valist
, NULL
, &valist
);
898 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
902 if(options
& UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION
)
903 return ret
>len
? -1 : ret
;
905 if(len
) str
[len
-1] = 0;
906 if(options
& UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR
)
908 return len
> 0 ? -2 : -1;
913 #endif /* _MSVCR_VER>=140 */
915 /*********************************************************************
916 * _vsnprintf_l (MSVCRT.@)
918 int CDECL
MSVCRT_vsnprintf_l( char *str
, MSVCRT_size_t len
, const char *format
,
919 MSVCRT__locale_t locale
, __ms_va_list valist
)
921 static const char nullbyte
= '\0';
922 struct _str_ctx_a ctx
= {len
, str
};
925 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, locale
, 0,
926 arg_clbk_valist
, NULL
, &valist
);
927 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
931 /*********************************************************************
932 * _vsprintf_l (MSVCRT.@)
934 int CDECL
MSVCRT_vsprintf_l( char *str
, const char *format
,
935 MSVCRT__locale_t locale
, __ms_va_list valist
)
937 return MSVCRT_vsnprintf_l(str
, INT_MAX
, format
, locale
, valist
);
940 /*********************************************************************
941 * _sprintf_l (MSVCRT.@)
943 int WINAPIV
MSVCRT_sprintf_l(char *str
, const char *format
,
944 MSVCRT__locale_t locale
, ...)
948 __ms_va_start(valist
, locale
);
949 retval
= MSVCRT_vsnprintf_l(str
, INT_MAX
, format
, locale
, valist
);
954 static int CDECL
MSVCRT_vsnprintf_s_l_opt( char *str
, MSVCRT_size_t sizeOfBuffer
,
955 MSVCRT_size_t count
, const char *format
, DWORD options
,
956 MSVCRT__locale_t locale
, __ms_va_list valist
)
958 static const char nullbyte
= '\0';
959 struct _str_ctx_a ctx
;
962 if(sizeOfBuffer
<count
+1 || count
==-1)
969 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
970 arg_clbk_valist
, NULL
, &valist
);
971 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
973 if(ret
<0 || ret
==len
) {
974 if(count
!=MSVCRT__TRUNCATE
&& count
>sizeOfBuffer
) {
975 MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE
);
976 memset(str
, 0, sizeOfBuffer
);
986 static int MSVCRT_vsnwprintf_s_l_opt( MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
987 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
, DWORD options
,
988 MSVCRT__locale_t locale
, __ms_va_list valist
)
990 static const MSVCRT_wchar_t nullbyte
= '\0';
991 struct _str_ctx_w ctx
;
995 if(count
!=-1 && len
>count
+1)
1000 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1001 arg_clbk_valist
, NULL
, &valist
);
1002 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1004 if(ret
<0 || ret
==len
) {
1005 if(count
!=MSVCRT__TRUNCATE
&& count
>sizeOfBuffer
) {
1006 MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE
);
1007 memset(str
, 0, sizeOfBuffer
*sizeof(MSVCRT_wchar_t
));
1017 /*********************************************************************
1018 * _vsnprintf_s_l (MSVCRT.@)
1020 int CDECL
MSVCRT_vsnprintf_s_l( char *str
, MSVCRT_size_t sizeOfBuffer
,
1021 MSVCRT_size_t count
, const char *format
,
1022 MSVCRT__locale_t locale
, __ms_va_list valist
)
1024 return MSVCRT_vsnprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, 0, locale
, valist
);
1027 /*********************************************************************
1028 * _vsprintf_s_l (MSVCRT.@)
1030 int CDECL
MSVCRT_vsprintf_s_l( char *str
, MSVCRT_size_t count
, const char *format
,
1031 MSVCRT__locale_t locale
, __ms_va_list valist
)
1033 return MSVCRT_vsnprintf_s_l(str
, INT_MAX
, count
, format
, locale
, valist
);
1036 /*********************************************************************
1037 * _sprintf_s_l (MSVCRT.@)
1039 int WINAPIV
MSVCRT_sprintf_s_l( char *str
, MSVCRT_size_t count
, const char *format
,
1040 MSVCRT__locale_t locale
, ...)
1043 __ms_va_list valist
;
1044 __ms_va_start(valist
, locale
);
1045 retval
= MSVCRT_vsnprintf_s_l(str
, INT_MAX
, count
, format
, locale
, valist
);
1046 __ms_va_end(valist
);
1050 /*********************************************************************
1051 * _vsnprintf_s (MSVCRT.@)
1053 int CDECL
MSVCRT_vsnprintf_s( char *str
, MSVCRT_size_t sizeOfBuffer
,
1054 MSVCRT_size_t count
, const char *format
, __ms_va_list valist
)
1056 return MSVCRT_vsnprintf_s_l(str
,sizeOfBuffer
, count
, format
, NULL
, valist
);
1059 /*********************************************************************
1060 * _vsnprintf_c_l (MSVCRT.@)
1062 int CDECL
MSVCRT_vsnprintf_c_l(char *str
, MSVCRT_size_t len
, const char *format
,
1063 MSVCRT__locale_t locale
, __ms_va_list valist
)
1065 return MSVCRT_vsnprintf_s_l_opt(str
, len
, len
, format
, 0, locale
, valist
);
1068 /*********************************************************************
1069 * _vsnprintf_c (MSVCRT.@)
1071 int CDECL
MSVCRT_vsnprintf_c(char *str
, MSVCRT_size_t len
,
1072 const char *format
, __ms_va_list valist
)
1074 return MSVCRT_vsnprintf_c_l(str
, len
, format
, NULL
, valist
);
1079 /*********************************************************************
1080 * __stdio_common_vsnprintf_s (UCRTBASE.@)
1082 int CDECL
MSVCRT__stdio_common_vsnprintf_s( unsigned __int64 options
,
1083 char *str
, MSVCRT_size_t sizeOfBuffer
, MSVCRT_size_t count
,
1084 const char *format
, MSVCRT__locale_t locale
, __ms_va_list valist
)
1086 if (options
& ~UCRTBASE_PRINTF_MASK
)
1087 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1088 return MSVCRT_vsnprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1091 /*********************************************************************
1092 * __stdio_common_vsnwprintf_s (UCRTBASE.@)
1094 int CDECL
MSVCRT__stdio_common_vsnwprintf_s( unsigned __int64 options
,
1095 MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
, MSVCRT_size_t count
,
1096 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list valist
)
1098 if (options
& ~UCRTBASE_PRINTF_MASK
)
1099 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1100 return MSVCRT_vsnwprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1103 /*********************************************************************
1104 * __stdio_common_vswprintf_s (UCRTBASE.@)
1106 int CDECL
MSVCRT__stdio_common_vswprintf_s( unsigned __int64 options
,
1107 MSVCRT_wchar_t
*str
, MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1108 MSVCRT__locale_t locale
, __ms_va_list valist
)
1110 return MSVCRT__stdio_common_vsnwprintf_s(options
, str
, INT_MAX
, count
, format
, locale
, valist
);
1113 /*********************************************************************
1114 * __stdio_common_vsprintf_s (UCRTBASE.@)
1116 int CDECL
MSVCRT__stdio_common_vsprintf_s( unsigned __int64 options
,
1117 char *str
, MSVCRT_size_t count
, const char *format
,
1118 MSVCRT__locale_t locale
, __ms_va_list valist
)
1120 if (options
& ~UCRTBASE_PRINTF_MASK
)
1121 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1122 return MSVCRT_vsnprintf_s_l_opt(str
, INT_MAX
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1125 #endif /* _MSVCR_VER>=140 */
1127 /*********************************************************************
1128 * vsprintf (MSVCRT.@)
1130 int CDECL
MSVCRT_vsprintf( char *str
, const char *format
, __ms_va_list valist
)
1132 return vsnprintf(str
, INT_MAX
, format
, valist
);
1135 /*********************************************************************
1136 * vsprintf_s (MSVCRT.@)
1138 int CDECL
MSVCRT_vsprintf_s( char *str
, MSVCRT_size_t num
, const char *format
, __ms_va_list valist
)
1140 return vsnprintf(str
, num
, format
, valist
);
1143 /*********************************************************************
1144 * _vscprintf (MSVCRT.@)
1146 int CDECL
MSVCRT__vscprintf( const char *format
, __ms_va_list valist
)
1148 return MSVCRT_vsnprintf_l( NULL
, INT_MAX
, format
, NULL
, valist
);
1151 /*********************************************************************
1152 * _vscprintf_l (MSVCRT.@)
1154 int CDECL
MSVCRT__vscprintf_l(const char *format
,
1155 MSVCRT__locale_t locale
, __ms_va_list valist
)
1157 return MSVCRT_vsnprintf_l(NULL
, INT_MAX
, format
, locale
, valist
);
1160 /*********************************************************************
1161 * _vscprintf_p_l (MSVCRT.@)
1163 int CDECL
MSVCRT__vscprintf_p_l(const char *format
,
1164 MSVCRT__locale_t locale
, __ms_va_list args
)
1166 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1167 struct _str_ctx_a puts_ctx
= {INT_MAX
, NULL
};
1170 memset(args_ctx
, 0, sizeof(args_ctx
));
1172 ret
= create_positional_ctx_a(args_ctx
, format
, args
);
1174 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1175 *MSVCRT__errno() = MSVCRT_EINVAL
;
1177 } else if(ret
== 0) {
1178 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1179 MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
,
1180 arg_clbk_valist
, NULL
, &args
);
1182 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1183 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
,
1184 arg_clbk_positional
, args_ctx
, NULL
);
1190 /*********************************************************************
1191 * _vscprintf_p (MSVCR80.@)
1193 int CDECL
MSVCRT__vscprintf_p(const char *format
, __ms_va_list argptr
)
1195 return MSVCRT__vscprintf_p_l(format
, NULL
, argptr
);
1198 /*********************************************************************
1199 * _snprintf (MSVCRT.@)
1201 int WINAPIV
MSVCRT__snprintf(char *str
, MSVCRT_size_t len
, const char *format
, ...)
1204 __ms_va_list valist
;
1205 __ms_va_start(valist
, format
);
1206 retval
= vsnprintf(str
, len
, format
, valist
);
1207 __ms_va_end(valist
);
1211 /*********************************************************************
1212 * _snprintf_l (MSVCRT.@)
1214 int WINAPIV
MSVCRT__snprintf_l(char *str
, MSVCRT_size_t count
, const char *format
,
1215 MSVCRT__locale_t locale
, ...)
1218 __ms_va_list valist
;
1219 __ms_va_start(valist
, locale
);
1220 retval
= MSVCRT_vsnprintf_l(str
, count
, format
, locale
, valist
);
1221 __ms_va_end(valist
);
1225 /*********************************************************************
1226 * _snprintf_c_l (MSVCRT.@)
1228 int WINAPIV
MSVCRT_snprintf_c_l(char *str
, MSVCRT_size_t count
, const char *format
,
1229 MSVCRT__locale_t locale
, ...)
1232 __ms_va_list valist
;
1233 __ms_va_start(valist
, locale
);
1234 retval
= MSVCRT_vsnprintf_c_l(str
, count
, format
, locale
, valist
);
1235 __ms_va_end(valist
);
1239 /*********************************************************************
1240 * _snprintf_c (MSVCRT.@)
1242 int WINAPIV
MSVCRT_snprintf_c(char *str
, MSVCRT_size_t count
, const char *format
, ...)
1245 __ms_va_list valist
;
1246 __ms_va_start(valist
, format
);
1247 retval
= MSVCRT_vsnprintf_c(str
, count
, format
, valist
);
1248 __ms_va_end(valist
);
1252 /*********************************************************************
1253 * _snprintf_s_l (MSVCRT.@)
1255 int WINAPIV
MSVCRT_snprintf_s_l(char *str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1256 const char *format
, MSVCRT__locale_t locale
, ...)
1259 __ms_va_list valist
;
1260 __ms_va_start(valist
, locale
);
1261 retval
= MSVCRT_vsnprintf_s_l(str
, len
, count
, format
, locale
, valist
);
1262 __ms_va_end(valist
);
1266 /*********************************************************************
1267 * _snprintf_s (MSVCRT.@)
1269 int WINAPIV
MSVCRT__snprintf_s(char *str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1270 const char *format
, ...)
1273 __ms_va_list valist
;
1274 __ms_va_start(valist
, format
);
1275 retval
= MSVCRT_vsnprintf_s_l(str
, len
, count
, format
, NULL
, valist
);
1276 __ms_va_end(valist
);
1280 /*********************************************************************
1281 * _scprintf (MSVCRT.@)
1283 int WINAPIV
MSVCRT__scprintf(const char *format
, ...)
1286 __ms_va_list valist
;
1287 __ms_va_start(valist
, format
);
1288 retval
= MSVCRT__vscprintf(format
, valist
);
1289 __ms_va_end(valist
);
1293 /*********************************************************************
1294 * _vsnwprintf (MSVCRT.@)
1296 int CDECL
MSVCRT_vsnwprintf(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1297 const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1299 static const MSVCRT_wchar_t nullbyte
= '\0';
1300 struct _str_ctx_w ctx
= {len
, str
};
1303 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, NULL
, 0,
1304 arg_clbk_valist
, NULL
, &valist
);
1305 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1309 /*********************************************************************
1310 * _vsnwprintf_l (MSVCRT.@)
1312 int CDECL
MSVCRT_vsnwprintf_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1313 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
,
1314 __ms_va_list valist
)
1316 static const MSVCRT_wchar_t nullbyte
= '\0';
1317 struct _str_ctx_w ctx
= {len
, str
};
1320 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, locale
, 0,
1321 arg_clbk_valist
, NULL
, &valist
);
1322 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1326 /*********************************************************************
1327 * _vswprintf_c_l (MSVCRT.@)
1329 int CDECL
MSVCRT_vswprintf_c_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1330 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
,
1331 __ms_va_list valist
)
1333 return MSVCRT_vsnwprintf_s_l_opt(str
, len
, len
, format
, 0, locale
, valist
);
1336 /*********************************************************************
1337 * _vswprintf_c (MSVCRT.@)
1339 int CDECL
MSVCRT_vswprintf_c(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1340 const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1342 return MSVCRT_vswprintf_c_l(str
, len
, format
, NULL
, valist
);
1345 static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1346 const MSVCRT_wchar_t
*format
, DWORD options
, MSVCRT__locale_t locale
, __ms_va_list args
)
1348 static const MSVCRT_wchar_t nullbyte
= '\0';
1349 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1350 struct _str_ctx_w puts_ctx
= {length
, buffer
};
1353 memset(args_ctx
, 0, sizeof(args_ctx
));
1355 ret
= create_positional_ctx_w(args_ctx
, format
, args
);
1357 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1358 *MSVCRT__errno() = MSVCRT_EINVAL
;
1361 ret
= pf_printf_w(puts_clbk_str_w
, &puts_ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1362 arg_clbk_valist
, NULL
, &args
);
1364 ret
= pf_printf_w(puts_clbk_str_w
, &puts_ctx
, format
, locale
,
1365 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1366 arg_clbk_positional
, args_ctx
, NULL
);
1368 puts_clbk_str_w(&puts_ctx
, 1, &nullbyte
);
1372 /*********************************************************************
1373 * _vswprintf_p_l (MSVCRT.@)
1375 int CDECL
MSVCRT_vswprintf_p_l(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1376 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1378 return MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, locale
, args
);
1382 /*********************************************************************
1383 * _vswprintf_p (MSVCR80.@)
1385 int CDECL
MSVCRT__vswprintf_p(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1386 const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1388 return MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, NULL
, args
);
1393 /*********************************************************************
1394 * __stdio_common_vswprintf_p (UCRTBASE.@)
1396 int CDECL
MSVCRT__stdio_common_vswprintf_p( unsigned __int64 options
,
1397 MSVCRT_wchar_t
*str
, MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1398 MSVCRT__locale_t locale
, __ms_va_list valist
)
1400 if (options
& ~UCRTBASE_PRINTF_MASK
)
1401 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1402 return MSVCRT_vswprintf_p_l_opt(str
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1406 /*********************************************************************
1407 * _vsnwprintf_s_l (MSVCRT.@)
1409 int CDECL
MSVCRT_vsnwprintf_s_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
1410 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1411 MSVCRT__locale_t locale
, __ms_va_list valist
)
1413 return MSVCRT_vsnwprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, 0, locale
, valist
);
1416 /*********************************************************************
1417 * _vsnwprintf_s (MSVCRT.@)
1419 int CDECL
MSVCRT_vsnwprintf_s(MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
1420 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1422 return MSVCRT_vsnwprintf_s_l(str
, sizeOfBuffer
, count
,
1423 format
, NULL
, valist
);
1426 /*********************************************************************
1427 * _snwprintf (MSVCRT.@)
1429 int WINAPIV
MSVCRT__snwprintf( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
, ...)
1432 __ms_va_list valist
;
1433 __ms_va_start(valist
, format
);
1434 retval
= MSVCRT_vsnwprintf(str
, len
, format
, valist
);
1435 __ms_va_end(valist
);
1439 /*********************************************************************
1440 * _snwprintf_l (MSVCRT.@)
1442 int WINAPIV
MSVCRT__snwprintf_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
,
1443 MSVCRT__locale_t locale
, ...)
1446 __ms_va_list valist
;
1447 __ms_va_start(valist
, locale
);
1448 retval
= MSVCRT_vsnwprintf_l(str
, len
, format
, locale
, valist
);
1449 __ms_va_end(valist
);
1453 /*********************************************************************
1454 * _snwprintf_s (MSVCRT.@)
1456 int WINAPIV
MSVCRT__snwprintf_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1457 const MSVCRT_wchar_t
*format
, ...)
1460 __ms_va_list valist
;
1461 __ms_va_start(valist
, format
);
1462 retval
= MSVCRT_vsnwprintf_s_l(str
, len
, count
, format
, NULL
, valist
);
1463 __ms_va_end(valist
);
1467 /*********************************************************************
1468 * _snwprintf_s_l (MSVCRT.@)
1470 int WINAPIV
MSVCRT__snwprintf_s_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1471 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1474 __ms_va_list valist
;
1475 __ms_va_start(valist
, locale
);
1476 retval
= MSVCRT_vsnwprintf_s_l(str
, len
, count
, format
, locale
, valist
);
1477 __ms_va_end(valist
);
1483 static int puts_clbk_str_c99_w(void *ctx
, int len
, const MSVCRT_wchar_t
*str
)
1485 struct _str_ctx_w
*out
= ctx
;
1490 if(out
->len
< len
) {
1491 memcpy(out
->buf
, str
, out
->len
*sizeof(MSVCRT_wchar_t
));
1492 out
->buf
+= out
->len
;
1497 memcpy(out
->buf
, str
, len
*sizeof(MSVCRT_wchar_t
));
1503 /*********************************************************************
1504 * __stdio_common_vswprintf (UCRTBASE.@)
1506 int CDECL
MSVCRT__stdio_common_vswprintf( unsigned __int64 options
,
1507 MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
,
1508 MSVCRT__locale_t locale
, __ms_va_list valist
)
1510 static const MSVCRT_wchar_t nullbyte
= '\0';
1511 struct _str_ctx_w ctx
= {len
, str
};
1514 if (options
& ~UCRTBASE_PRINTF_MASK
)
1515 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1516 ret
= pf_printf_w(puts_clbk_str_c99_w
,
1517 &ctx
, format
, locale
, options
& UCRTBASE_PRINTF_MASK
, arg_clbk_valist
, NULL
, &valist
);
1518 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1522 if(options
& UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION
)
1523 return ret
>len
? -1 : ret
;
1525 if(len
) str
[len
-1] = 0;
1526 if(options
& UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR
)
1528 return len
> 0 ? -2 : -1;
1533 #endif /* _MSVCR_VER>=140 */
1535 /*********************************************************************
1536 * sprintf (MSVCRT.@)
1538 int WINAPIV
MSVCRT_sprintf( char *str
, const char *format
, ... )
1543 __ms_va_start( ap
, format
);
1544 r
= vsnprintf( str
, INT_MAX
, format
, ap
);
1549 /*********************************************************************
1550 * sprintf_s (MSVCRT.@)
1552 int WINAPIV
MSVCRT_sprintf_s( char *str
, MSVCRT_size_t num
, const char *format
, ... )
1557 __ms_va_start( ap
, format
);
1558 r
= vsnprintf( str
, num
, format
, ap
);
1563 /*********************************************************************
1564 * _scwprintf (MSVCRT.@)
1566 int WINAPIV
MSVCRT__scwprintf( const MSVCRT_wchar_t
*format
, ... )
1571 __ms_va_start( ap
, format
);
1572 r
= MSVCRT_vsnwprintf( NULL
, INT_MAX
, format
, ap
);
1577 /*********************************************************************
1578 * swprintf (MSVCRT.@)
1580 int WINAPIV
MSVCRT_swprintf( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
, ... )
1585 __ms_va_start( ap
, format
);
1586 r
= MSVCRT_vsnwprintf( str
, INT_MAX
, format
, ap
);
1591 /*********************************************************************
1592 * swprintf_s (MSVCRT.@)
1594 int WINAPIV
MSVCRT_swprintf_s(MSVCRT_wchar_t
*str
, MSVCRT_size_t numberOfElements
,
1595 const MSVCRT_wchar_t
*format
, ... )
1600 __ms_va_start(ap
, format
);
1601 r
= MSVCRT_vsnwprintf_s(str
, numberOfElements
, INT_MAX
, format
, ap
);
1607 /*********************************************************************
1608 * _swprintf_s_l (MSVCRT.@)
1610 int WINAPIV
MSVCRT__swprintf_s_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t numberOfElements
,
1611 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1616 __ms_va_start(ap
, locale
);
1617 r
= MSVCRT_vsnwprintf_s_l(str
, numberOfElements
, INT_MAX
, format
, locale
, ap
);
1623 /*********************************************************************
1624 * _swprintf_c_l (MSVCRT.@)
1626 int WINAPIV
MSVCRT_swprintf_c_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1627 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1632 __ms_va_start(ap
, locale
);
1633 r
= MSVCRT_vswprintf_c_l(str
, len
, format
, locale
, ap
);
1639 /*********************************************************************
1640 * _swprintf_c (MSVCRT.@)
1642 int WINAPIV
MSVCRT_swprintf_c(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1643 const MSVCRT_wchar_t
*format
, ... )
1648 __ms_va_start(ap
, format
);
1649 r
= MSVCRT_vswprintf_c(str
, len
, format
, ap
);
1655 /*********************************************************************
1656 * _vswprintf (MSVCRT.@)
1658 int CDECL
MSVCRT_vswprintf( MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* format
, __ms_va_list args
)
1660 return MSVCRT_vsnwprintf( str
, INT_MAX
, format
, args
);
1663 /*********************************************************************
1664 * _vswprintf (MSVCRT.@)
1666 int CDECL
MSVCRT_vswprintf_l( MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* format
,
1667 MSVCRT__locale_t locale
, __ms_va_list args
)
1669 return MSVCRT_vsnwprintf_l( str
, INT_MAX
, format
, locale
, args
);
1672 /*********************************************************************
1673 * _vscwprintf (MSVCRT.@)
1675 int CDECL
MSVCRT__vscwprintf( const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1677 return MSVCRT_vsnwprintf( NULL
, INT_MAX
, format
, args
);
1680 /*********************************************************************
1681 * _vscwprintf_l (MSVCRT.@)
1683 int CDECL
MSVCRT__vscwprintf_l( const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1685 return MSVCRT_vsnwprintf_l( NULL
, INT_MAX
, format
, locale
, args
);
1688 /*********************************************************************
1689 * _vscwprintf_p_l (MSVCRT.@)
1691 int CDECL
MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1693 return MSVCRT_vswprintf_p_l_opt( NULL
, INT_MAX
, format
, 0, locale
, args
);
1697 /*********************************************************************
1698 * _vscwprintf_p (MSVCR80.@)
1700 int CDECL
MSVCRT__vscwprintf_p(const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1702 return MSVCRT_vswprintf_p_l_opt(NULL
, INT_MAX
, format
, 0, NULL
, args
);
1706 /*********************************************************************
1707 * vswprintf_s (MSVCRT.@)
1709 int CDECL
MSVCRT_vswprintf_s(MSVCRT_wchar_t
* str
, MSVCRT_size_t numberOfElements
,
1710 const MSVCRT_wchar_t
* format
, __ms_va_list args
)
1712 return MSVCRT_vsnwprintf_s(str
, numberOfElements
, INT_MAX
, format
, args
);
1715 /*********************************************************************
1716 * _vswprintf_s_l (MSVCRT.@)
1718 int CDECL
MSVCRT_vswprintf_s_l(MSVCRT_wchar_t
* str
, MSVCRT_size_t numberOfElements
,
1719 const MSVCRT_wchar_t
* format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1721 return MSVCRT_vsnwprintf_s_l(str
, numberOfElements
, INT_MAX
,
1722 format
, locale
, args
);
1725 static int MSVCRT_vsprintf_p_l_opt(char *buffer
, MSVCRT_size_t length
, const char *format
,
1726 DWORD options
, MSVCRT__locale_t locale
, __ms_va_list args
)
1728 static const char nullbyte
= '\0';
1729 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1730 struct _str_ctx_a puts_ctx
= {length
, buffer
};
1733 memset(args_ctx
, 0, sizeof(args_ctx
));
1735 ret
= create_positional_ctx_a(args_ctx
, format
, args
);
1737 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1738 *MSVCRT__errno() = MSVCRT_EINVAL
;
1741 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1742 MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
, arg_clbk_valist
, NULL
, &args
);
1744 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1745 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1746 arg_clbk_positional
, args_ctx
, NULL
);
1748 puts_clbk_str_a(&puts_ctx
, 1, &nullbyte
);
1752 /*********************************************************************
1753 * _vsprintf_p_l (MSVCRT.@)
1755 int CDECL
MSVCRT_vsprintf_p_l(char *buffer
, MSVCRT_size_t length
, const char *format
,
1756 MSVCRT__locale_t locale
, __ms_va_list args
)
1758 return MSVCRT_vsprintf_p_l_opt(buffer
, length
, format
, 0, locale
, args
);
1761 /*********************************************************************
1762 * _vsprintf_p (MSVCRT.@)
1764 int CDECL
MSVCRT_vsprintf_p(char *buffer
, MSVCRT_size_t length
,
1765 const char *format
, __ms_va_list args
)
1767 return MSVCRT_vsprintf_p_l(buffer
, length
, format
, NULL
, args
);
1771 /*********************************************************************
1772 * __stdio_common_vsprintf_p (UCRTBASE.@)
1774 int CDECL
MSVCRT__stdio_common_vsprintf_p(unsigned __int64 options
, char *buffer
, MSVCRT_size_t length
,
1775 const char *format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1777 if (options
& ~UCRTBASE_PRINTF_MASK
)
1778 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1779 return MSVCRT_vsprintf_p_l_opt(buffer
, length
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, args
);
1783 /*********************************************************************
1784 * _sprintf_p_l (MSVCRT.@)
1786 int WINAPIV
MSVCRT_sprintf_p_l(char *buffer
, MSVCRT_size_t length
,
1787 const char *format
, MSVCRT__locale_t locale
, ...)
1789 __ms_va_list valist
;
1792 __ms_va_start(valist
, locale
);
1793 r
= MSVCRT_vsprintf_p_l(buffer
, length
, format
, locale
, valist
);
1794 __ms_va_end(valist
);
1799 /*********************************************************************
1800 * __swprintf_l (MSVCRT.@)
1802 int WINAPIV
MSVCRT___swprintf_l( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
,
1803 MSVCRT__locale_t locale
, ...)
1806 __ms_va_list valist
;
1807 __ms_va_start(valist
, locale
);
1808 retval
= MSVCRT_vswprintf_l(str
, format
, locale
, valist
);
1809 __ms_va_end(valist
);
1814 /*********************************************************************
1815 * _sprintf_p (MSVCR80.@)
1817 int WINAPIV
MSVCRT__sprintf_p(char *buffer
, MSVCRT_size_t length
, const char *format
, ...)
1819 __ms_va_list valist
;
1822 __ms_va_start(valist
, format
);
1823 r
= MSVCRT_vsprintf_p_l(buffer
, length
, format
, NULL
, valist
);
1824 __ms_va_end(valist
);
1830 /*********************************************************************
1831 * _swprintf_p_l (MSVCRT.@)
1833 int WINAPIV
MSVCRT_swprintf_p_l(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1834 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
1836 __ms_va_list valist
;
1839 __ms_va_start(valist
, locale
);
1840 r
= MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, locale
, valist
);
1841 __ms_va_end(valist
);
1846 /*********************************************************************
1849 int CDECL
MSVCRT_wcscmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
)
1851 while (*str1
&& (*str1
== *str2
))
1864 /*********************************************************************
1865 * _wcscoll_l (MSVCRT.@)
1867 int CDECL
MSVCRT__wcscoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT__locale_t locale
)
1869 MSVCRT_pthreadlocinfo locinfo
;
1872 locinfo
= get_locinfo();
1874 locinfo
= locale
->locinfo
;
1876 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
1877 return MSVCRT_wcscmp(str1
, str2
);
1878 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], 0, str1
, -1, str2
, -1)-CSTR_EQUAL
;
1881 /*********************************************************************
1882 * wcscoll (MSVCRT.@)
1884 int CDECL
MSVCRT_wcscoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
1886 return MSVCRT__wcscoll_l(str1
, str2
, NULL
);
1889 /*********************************************************************
1890 * wcspbrk (MSVCRT.@)
1892 MSVCRT_wchar_t
* CDECL
MSVCRT_wcspbrk( const MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* accept
)
1894 const MSVCRT_wchar_t
* p
;
1898 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (MSVCRT_wchar_t
*)str
;
1904 /*********************************************************************
1905 * wcstok_s (MSVCRT.@)
1907 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok_s( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
,
1908 MSVCRT_wchar_t
**next_token
)
1910 MSVCRT_wchar_t
*ret
;
1912 if (!MSVCRT_CHECK_PMT(delim
!= NULL
)) return NULL
;
1913 if (!MSVCRT_CHECK_PMT(next_token
!= NULL
)) return NULL
;
1914 if (!MSVCRT_CHECK_PMT(str
!= NULL
|| *next_token
!= NULL
)) return NULL
;
1916 if (!str
) str
= *next_token
;
1918 while (*str
&& MSVCRT_wcschr( delim
, *str
)) str
++;
1919 if (!*str
) return NULL
;
1921 while (*str
&& !MSVCRT_wcschr( delim
, *str
)) str
++;
1922 if (*str
) *str
++ = 0;
1927 /*********************************************************************
1931 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
, MSVCRT_wchar_t
**ctx
)
1934 ctx
= &msvcrt_get_thread_data()->wcstok_next
;
1935 return MSVCRT_wcstok_s(str
, delim
, ctx
);
1938 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
)
1940 return MSVCRT_wcstok_s(str
, delim
, &msvcrt_get_thread_data()->wcstok_next
);
1944 /*********************************************************************
1945 * _wctomb_s_l (MSVCRT.@)
1947 int CDECL
MSVCRT__wctomb_s_l(int *len
, char *mbchar
, MSVCRT_size_t size
,
1948 MSVCRT_wchar_t wch
, MSVCRT__locale_t locale
)
1950 MSVCRT_pthreadlocinfo locinfo
;
1955 if(!mbchar
&& size
>0) {
1964 if(!MSVCRT_CHECK_PMT(size
<= INT_MAX
))
1965 return MSVCRT_EINVAL
;
1968 locinfo
= get_locinfo();
1970 locinfo
= locale
->locinfo
;
1972 if(!locinfo
->lc_codepage
) {
1974 if(mbchar
&& size
>0)
1975 memset(mbchar
, 0, size
);
1976 *MSVCRT__errno() = MSVCRT_EILSEQ
;
1977 return MSVCRT_EILSEQ
;
1980 if(!MSVCRT_CHECK_PMT_ERR(size
>= 1, MSVCRT_ERANGE
))
1981 return MSVCRT_ERANGE
;
1989 perror
= (locinfo
->lc_codepage
!= CP_UTF8
? &error
: NULL
);
1990 mblen
= WideCharToMultiByte(locinfo
->lc_codepage
, 0, &wch
, 1, mbchar
, size
, NULL
, perror
);
1991 if(!mblen
|| error
) {
1992 if(!mblen
&& GetLastError()==ERROR_INSUFFICIENT_BUFFER
) {
1993 if(mbchar
&& size
>0)
1994 memset(mbchar
, 0, size
);
1996 MSVCRT_INVALID_PMT("insufficient buffer size", MSVCRT_ERANGE
);
1997 return MSVCRT_ERANGE
;
2000 *MSVCRT__errno() = MSVCRT_EILSEQ
;
2001 return MSVCRT_EILSEQ
;
2009 /*********************************************************************
2010 * wctomb_s (MSVCRT.@)
2012 int CDECL
MSVCRT_wctomb_s(int *len
, char *mbchar
, MSVCRT_size_t size
, MSVCRT_wchar_t wch
)
2014 return MSVCRT__wctomb_s_l(len
, mbchar
, size
, wch
, NULL
);
2017 /*********************************************************************
2018 * _wctomb_l (MSVCRT.@)
2020 int CDECL
MSVCRT__wctomb_l(char *dst
, MSVCRT_wchar_t ch
, MSVCRT__locale_t locale
)
2024 MSVCRT__wctomb_s_l(&len
, dst
, dst
? MSVCRT_MB_LEN_MAX
: 0, ch
, locale
);
2028 /*********************************************************************
2031 INT CDECL
MSVCRT_wctomb( char *dst
, MSVCRT_wchar_t ch
)
2033 return MSVCRT__wctomb_l(dst
, ch
, NULL
);
2036 /*********************************************************************
2039 INT CDECL
MSVCRT_wctob( MSVCRT_wint_t wchar
)
2044 UINT codepage
= get_locinfo()->lc_codepage
;
2046 perror
= (codepage
!= CP_UTF8
? &error
: NULL
);
2050 return (signed char)wchar
;
2053 } else if(WideCharToMultiByte( codepage
, 0, &wchar
, 1, &out
, 1, NULL
, perror
) && !error
)
2058 /*********************************************************************
2059 * wcrtomb_s (MSVCRT.@)
2061 INT CDECL
MSVCRT_wcrtomb_s(MSVCRT_size_t
*len
, char *mbchar
,
2062 MSVCRT_size_t size
, MSVCRT_wchar_t wch
, MSVCRT_mbstate_t
*s
)
2067 ret
= MSVCRT_wctomb_s(&ilen
, mbchar
, size
, wch
);
2068 if (len
) *len
= ilen
;
2072 /*********************************************************************
2073 * wcrtomb (MSVCRT.@)
2075 MSVCRT_size_t CDECL
MSVCRT_wcrtomb( char *dst
, MSVCRT_wchar_t ch
, MSVCRT_mbstate_t
*s
)
2079 return MSVCRT_wctomb(dst
, ch
);
2082 /*********************************************************************
2083 * _iswctype_l (MSVCRT.@)
2085 INT CDECL
MSVCRT__iswctype_l( MSVCRT_wchar_t wc
, wctype_t type
, MSVCRT__locale_t locale
)
2089 if (wc
== MSVCRT_WEOF
) return 0;
2090 if (wc
< 256) return MSVCRT__pwctype
[wc
] & type
;
2092 if (!GetStringTypeW(CT_CTYPE1
, &wc
, 1, &ct
))
2094 ERR("GetStringTypeW failed for %x\n", wc
);
2100 /*********************************************************************
2101 * iswctype (MSVCRT.@)
2103 INT CDECL
MSVCRT_iswctype( MSVCRT_wchar_t wc
, wctype_t type
)
2105 return MSVCRT__iswctype_l( wc
, type
, NULL
);
2108 /*********************************************************************
2109 * _iswalnum_l (MSVCRT.@)
2111 int CDECL
MSVCRT__iswalnum_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2113 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__DIGIT
, locale
);
2116 /*********************************************************************
2117 * iswalnum (MSVCRT.@)
2119 INT CDECL
MSVCRT_iswalnum( MSVCRT_wchar_t wc
)
2121 return MSVCRT__iswalnum_l( wc
, NULL
);
2124 /*********************************************************************
2125 * iswalpha_l (MSVCRT.@)
2127 INT CDECL
MSVCRT__iswalpha_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2129 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
, locale
);
2132 /*********************************************************************
2133 * iswalpha (MSVCRT.@)
2135 INT CDECL
MSVCRT_iswalpha( MSVCRT_wchar_t wc
)
2137 return MSVCRT__iswalpha_l( wc
, NULL
);
2140 /*********************************************************************
2141 * _iswcntrl_l (MSVCRT.@)
2143 int CDECL
MSVCRT__iswcntrl_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2145 return MSVCRT__iswctype_l( wc
, MSVCRT__CONTROL
, locale
);
2148 /*********************************************************************
2149 * iswcntrl (MSVCRT.@)
2151 INT CDECL
MSVCRT_iswcntrl( MSVCRT_wchar_t wc
)
2153 return MSVCRT__iswcntrl_l( wc
, NULL
);
2156 /*********************************************************************
2157 * _iswdigit_l (MSVCRT.@)
2159 INT CDECL
MSVCRT__iswdigit_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2161 return MSVCRT__iswctype_l( wc
, MSVCRT__DIGIT
, locale
);
2164 /*********************************************************************
2165 * iswdigit (MSVCRT.@)
2167 INT CDECL
MSVCRT_iswdigit( MSVCRT_wchar_t wc
)
2169 return MSVCRT__iswdigit_l( wc
, NULL
);
2172 /*********************************************************************
2173 * _iswgraph_l (MSVCRT.@)
2175 int CDECL
MSVCRT__iswgraph_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2177 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__DIGIT
| MSVCRT__PUNCT
, locale
);
2180 /*********************************************************************
2181 * iswgraph (MSVCRT.@)
2183 INT CDECL
MSVCRT_iswgraph( MSVCRT_wchar_t wc
)
2185 return MSVCRT__iswgraph_l( wc
, NULL
);
2188 /*********************************************************************
2189 * _iswlower_l (MSVCRT.@)
2191 int CDECL
MSVCRT__iswlower_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2193 return MSVCRT__iswctype_l( wc
, MSVCRT__LOWER
, locale
);
2196 /*********************************************************************
2197 * iswlower (MSVCRT.@)
2199 INT CDECL
MSVCRT_iswlower( MSVCRT_wchar_t wc
)
2201 return MSVCRT__iswlower_l( wc
, NULL
);
2204 /*********************************************************************
2205 * _iswprint_l (MSVCRT.@)
2207 int CDECL
MSVCRT__iswprint_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2209 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__BLANK
|
2210 MSVCRT__DIGIT
| MSVCRT__PUNCT
, locale
);
2213 /*********************************************************************
2214 * iswprint (MSVCRT.@)
2216 INT CDECL
MSVCRT_iswprint( MSVCRT_wchar_t wc
)
2218 return MSVCRT__iswprint_l( wc
, NULL
);
2221 /*********************************************************************
2222 * _iswpunct_l (MSVCRT.@)
2224 INT CDECL
MSVCRT__iswpunct_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2226 return MSVCRT__iswctype_l( wc
, MSVCRT__PUNCT
, locale
);
2229 /*********************************************************************
2230 * iswpunct (MSVCRT.@)
2232 INT CDECL
MSVCRT_iswpunct( MSVCRT_wchar_t wc
)
2234 return MSVCRT__iswpunct_l( wc
, NULL
);
2237 /*********************************************************************
2238 * _iswspace_l (MSVCRT.@)
2240 INT CDECL
MSVCRT__iswspace_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2242 return MSVCRT__iswctype_l( wc
, MSVCRT__SPACE
, locale
);
2245 /*********************************************************************
2246 * iswspace (MSVCRT.@)
2248 INT CDECL
MSVCRT_iswspace( MSVCRT_wchar_t wc
)
2250 return MSVCRT__iswspace_l( wc
, NULL
);
2253 /*********************************************************************
2254 * _iswupper_l (MSVCRT.@)
2256 int CDECL
MSVCRT__iswupper_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2258 return MSVCRT__iswctype_l( wc
, MSVCRT__UPPER
, locale
);
2261 /*********************************************************************
2262 * iswupper (MSVCRT.@)
2264 INT CDECL
MSVCRT_iswupper( MSVCRT_wchar_t wc
)
2266 return MSVCRT__iswupper_l( wc
, NULL
);
2269 /*********************************************************************
2270 * _iswxdigit_l (MSVCRT.@)
2272 int CDECL
MSVCRT__iswxdigit_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2274 return MSVCRT__iswctype_l( wc
, MSVCRT__HEX
, locale
);
2277 /*********************************************************************
2278 * iswxdigit (MSVCRT.@)
2280 INT CDECL
MSVCRT_iswxdigit( MSVCRT_wchar_t wc
)
2282 return MSVCRT__iswxdigit_l( wc
, NULL
);
2285 /*********************************************************************
2286 * _iswblank_l (MSVCRT.@)
2288 INT CDECL
MSVCRT__iswblank_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2290 return wc
== '\t' || MSVCRT__iswctype_l( wc
, MSVCRT__BLANK
, locale
);
2293 /*********************************************************************
2294 * iswblank (MSVCRT.@)
2296 INT CDECL
MSVCRT_iswblank( MSVCRT_wchar_t wc
)
2298 return wc
== '\t' || MSVCRT__iswctype_l( wc
, MSVCRT__BLANK
, NULL
);
2301 /*********************************************************************
2302 * wcscpy_s (MSVCRT.@)
2304 INT CDECL
MSVCRT_wcscpy_s( MSVCRT_wchar_t
* wcDest
, MSVCRT_size_t numElement
, const MSVCRT_wchar_t
*wcSrc
)
2306 MSVCRT_size_t size
= 0;
2308 if(!MSVCRT_CHECK_PMT(wcDest
)) return MSVCRT_EINVAL
;
2309 if(!MSVCRT_CHECK_PMT(numElement
)) return MSVCRT_EINVAL
;
2311 if(!MSVCRT_CHECK_PMT(wcSrc
))
2314 return MSVCRT_EINVAL
;
2317 size
= MSVCRT_wcslen(wcSrc
) + 1;
2319 if(!MSVCRT_CHECK_PMT_ERR(size
<= numElement
, MSVCRT_ERANGE
))
2322 return MSVCRT_ERANGE
;
2325 memmove( wcDest
, wcSrc
, size
*sizeof(WCHAR
) );
2330 /***********************************************************************
2333 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcscpy( MSVCRT_wchar_t
*dst
, const MSVCRT_wchar_t
*src
)
2336 while ((*p
++ = *src
++));
2340 /******************************************************************
2341 * wcsncpy (MSVCRT.@)
2343 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcsncpy( MSVCRT_wchar_t
* s1
,
2344 const MSVCRT_wchar_t
*s2
, MSVCRT_size_t n
)
2349 if(!(s1
[i
] = s2
[i
])) break;
2355 /******************************************************************
2356 * wcsncpy_s (MSVCRT.@)
2358 INT CDECL
MSVCRT_wcsncpy_s( MSVCRT_wchar_t
* wcDest
, MSVCRT_size_t numElement
, const MSVCRT_wchar_t
*wcSrc
,
2359 MSVCRT_size_t count
)
2362 BOOL truncate
= (count
== MSVCRT__TRUNCATE
);
2364 if(!wcDest
&& !numElement
&& !count
)
2367 if (!wcDest
|| !numElement
)
2368 return MSVCRT_EINVAL
;
2373 return count
? MSVCRT_EINVAL
: 0;
2376 while (numElement
&& count
&& *wcSrc
)
2382 if (!numElement
&& truncate
)
2385 return MSVCRT_STRUNCATE
;
2387 else if (!numElement
)
2390 return MSVCRT_ERANGE
;
2397 /******************************************************************
2398 * wcscat_s (MSVCRT.@)
2401 INT CDECL
MSVCRT_wcscat_s(MSVCRT_wchar_t
* dst
, MSVCRT_size_t elem
, const MSVCRT_wchar_t
* src
)
2403 MSVCRT_wchar_t
* ptr
= dst
;
2405 if (!dst
|| elem
== 0) return MSVCRT_EINVAL
;
2409 return MSVCRT_EINVAL
;
2412 /* seek to end of dst string (or elem if no end of string is found */
2413 while (ptr
< dst
+ elem
&& *ptr
!= '\0') ptr
++;
2414 while (ptr
< dst
+ elem
)
2416 if ((*ptr
++ = *src
++) == '\0') return 0;
2418 /* not enough space */
2420 return MSVCRT_ERANGE
;
2423 /***********************************************************************
2426 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcscat( MSVCRT_wchar_t
*dst
, const MSVCRT_wchar_t
*src
)
2428 MSVCRT_wcscpy( dst
+ MSVCRT_wcslen(dst
), src
);
2432 /*********************************************************************
2433 * wcsncat_s (MSVCRT.@)
2436 INT CDECL
MSVCRT_wcsncat_s(MSVCRT_wchar_t
*dst
, MSVCRT_size_t elem
,
2437 const MSVCRT_wchar_t
*src
, MSVCRT_size_t count
)
2439 MSVCRT_size_t srclen
;
2440 MSVCRT_wchar_t dststart
;
2443 if (!MSVCRT_CHECK_PMT(dst
!= NULL
)) return MSVCRT_EINVAL
;
2444 if (!MSVCRT_CHECK_PMT(elem
> 0)) return MSVCRT_EINVAL
;
2445 if (!MSVCRT_CHECK_PMT(src
!= NULL
|| count
== 0)) return MSVCRT_EINVAL
;
2450 for (dststart
= 0; dststart
< elem
; dststart
++)
2452 if (dst
[dststart
] == '\0')
2455 if (dststart
== elem
)
2457 MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", MSVCRT_EINVAL
);
2458 return MSVCRT_EINVAL
;
2461 if (count
== MSVCRT__TRUNCATE
)
2463 srclen
= MSVCRT_wcslen(src
);
2464 if (srclen
>= (elem
- dststart
))
2466 srclen
= elem
- dststart
- 1;
2467 ret
= MSVCRT_STRUNCATE
;
2471 srclen
= min(MSVCRT_wcslen(src
), count
);
2472 if (srclen
< (elem
- dststart
))
2474 memcpy(&dst
[dststart
], src
, srclen
*sizeof(MSVCRT_wchar_t
));
2475 dst
[dststart
+srclen
] = '\0';
2478 MSVCRT_INVALID_PMT("dst[elem] is too small", MSVCRT_ERANGE
);
2480 return MSVCRT_ERANGE
;
2483 /*********************************************************************
2484 * wctoint (INTERNAL)
2486 static int wctoint(WCHAR c
, int base
)
2489 if ('0' <= c
&& c
<= '9')
2491 else if ('A' <= c
&& c
<= 'Z')
2493 else if ('a' <= c
&& c
<= 'z')
2496 /* NOTE: wine_fold_string(MAP_FOLDDIGITS) supports too many things. */
2497 /* Unicode points that contain digits 0-9; keep this sorted! */
2498 static const WCHAR zeros
[] = {
2499 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6,
2500 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10
2503 for (i
= 0; i
< ARRAY_SIZE(zeros
) && c
>= zeros
[i
]; ++i
) {
2504 if (zeros
[i
] <= c
&& c
<= zeros
[i
] + 9) {
2510 return v
< base
? v
: -1;
2513 /*********************************************************************
2514 * _wcstoi64_l (MSVCRT.@)
2516 * FIXME: locale parameter is ignored
2518 __int64 CDECL
MSVCRT__wcstoi64_l(const MSVCRT_wchar_t
*nptr
,
2519 MSVCRT_wchar_t
**endptr
, int base
, MSVCRT__locale_t locale
)
2521 BOOL negative
= FALSE
, empty
= TRUE
;
2524 TRACE("(%s %p %d %p)\n", debugstr_w(nptr
), endptr
, base
, locale
);
2526 if (!MSVCRT_CHECK_PMT(nptr
!= NULL
)) return 0;
2527 if (!MSVCRT_CHECK_PMT(base
== 0 || base
>= 2)) return 0;
2528 if (!MSVCRT_CHECK_PMT(base
<= 36)) return 0;
2531 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2533 while(MSVCRT__iswspace_l(*nptr
, locale
)) nptr
++;
2538 } else if(*nptr
== '+')
2541 if((base
==0 || base
==16) && wctoint(*nptr
, 1)==0 && (nptr
[1]=='x' || nptr
[1]=='X')) {
2547 if(wctoint(*nptr
, 1)==0)
2554 int v
= wctoint(*nptr
, base
);
2564 if(!negative
&& (ret
>MSVCRT_I64_MAX
/base
|| ret
*base
>MSVCRT_I64_MAX
-v
)) {
2565 ret
= MSVCRT_I64_MAX
;
2566 *MSVCRT__errno() = MSVCRT_ERANGE
;
2567 } else if(negative
&& (ret
<MSVCRT_I64_MIN
/base
|| ret
*base
<MSVCRT_I64_MIN
-v
)) {
2568 ret
= MSVCRT_I64_MIN
;
2569 *MSVCRT__errno() = MSVCRT_ERANGE
;
2574 if(endptr
&& !empty
)
2575 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2580 /*********************************************************************
2581 * _wcstoi64 (MSVCRT.@)
2583 __int64 CDECL
MSVCRT__wcstoi64(const MSVCRT_wchar_t
*nptr
,
2584 MSVCRT_wchar_t
**endptr
, int base
)
2586 return MSVCRT__wcstoi64_l(nptr
, endptr
, base
, NULL
);
2589 /*********************************************************************
2590 * _wcstol_l (MSVCRT.@)
2592 MSVCRT_long CDECL
MSVCRT__wcstol_l(const MSVCRT_wchar_t
*s
,
2593 MSVCRT_wchar_t
**end
, int base
, MSVCRT__locale_t locale
)
2595 __int64 ret
= MSVCRT__wcstoi64_l(s
, end
, base
, locale
);
2597 if(ret
> MSVCRT_LONG_MAX
) {
2598 ret
= MSVCRT_LONG_MAX
;
2599 *MSVCRT__errno() = MSVCRT_ERANGE
;
2600 }else if(ret
< MSVCRT_LONG_MIN
) {
2601 ret
= MSVCRT_LONG_MIN
;
2602 *MSVCRT__errno() = MSVCRT_ERANGE
;
2607 /*********************************************************************
2610 MSVCRT_long CDECL
MSVCRT_wcstol(const MSVCRT_wchar_t
*s
,
2611 MSVCRT_wchar_t
**end
, int base
)
2613 return MSVCRT__wcstol_l(s
, end
, base
, NULL
);
2616 /*********************************************************************
2617 * _wtoi_l (MSVCRT.@)
2619 int __cdecl
MSVCRT__wtoi_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2621 __int64 ret
= MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2625 *MSVCRT__errno() = MSVCRT_ERANGE
;
2626 } else if(ret
< INT_MIN
) {
2628 *MSVCRT__errno() = MSVCRT_ERANGE
;
2633 /*********************************************************************
2636 int __cdecl
MSVCRT__wtoi(const MSVCRT_wchar_t
*str
)
2638 return MSVCRT__wtoi_l(str
, NULL
);
2641 /*********************************************************************
2642 * _wtol_l (MSVCRT.@)
2644 MSVCRT_long __cdecl
MSVCRT__wtol_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2646 __int64 ret
= MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2648 if(ret
> MSVCRT_LONG_MAX
) {
2649 ret
= MSVCRT_LONG_MAX
;
2650 *MSVCRT__errno() = MSVCRT_ERANGE
;
2651 } else if(ret
< MSVCRT_LONG_MIN
) {
2652 ret
= MSVCRT_LONG_MIN
;
2653 *MSVCRT__errno() = MSVCRT_ERANGE
;
2658 /*********************************************************************
2661 MSVCRT_long __cdecl
MSVCRT__wtol(const MSVCRT_wchar_t
*str
)
2663 return MSVCRT__wtol_l(str
, NULL
);
2668 /*********************************************************************
2669 * _wtoll_l (MSVCR120.@)
2671 MSVCRT_longlong __cdecl
MSVCRT__wtoll_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2673 return MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2676 /*********************************************************************
2677 * _wtoll (MSVCR120.@)
2679 MSVCRT_longlong __cdecl
MSVCRT__wtoll(const MSVCRT_wchar_t
*str
)
2681 return MSVCRT__wtoll_l(str
, NULL
);
2684 #endif /* _MSVCR_VER>=120 */
2686 /*********************************************************************
2687 * _wcstoui64_l (MSVCRT.@)
2689 * FIXME: locale parameter is ignored
2691 unsigned __int64 CDECL
MSVCRT__wcstoui64_l(const MSVCRT_wchar_t
*nptr
,
2692 MSVCRT_wchar_t
**endptr
, int base
, MSVCRT__locale_t locale
)
2694 BOOL negative
= FALSE
, empty
= TRUE
;
2695 unsigned __int64 ret
= 0;
2697 TRACE("(%s %p %d %p)\n", debugstr_w(nptr
), endptr
, base
, locale
);
2699 if (!MSVCRT_CHECK_PMT(nptr
!= NULL
)) return 0;
2700 if (!MSVCRT_CHECK_PMT(base
== 0 || base
>= 2)) return 0;
2701 if (!MSVCRT_CHECK_PMT(base
<= 36)) return 0;
2704 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2706 while(MSVCRT__iswspace_l(*nptr
, locale
)) nptr
++;
2711 } else if(*nptr
== '+')
2714 if((base
==0 || base
==16) && wctoint(*nptr
, 1)==0 && (nptr
[1]=='x' || nptr
[1]=='X')) {
2720 if(wctoint(*nptr
, 1)==0)
2727 int v
= wctoint(*nptr
, base
);
2734 if(ret
>MSVCRT_UI64_MAX
/base
|| ret
*base
>MSVCRT_UI64_MAX
-v
) {
2735 ret
= MSVCRT_UI64_MAX
;
2736 *MSVCRT__errno() = MSVCRT_ERANGE
;
2741 if(endptr
&& !empty
)
2742 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2744 return negative
? -ret
: ret
;
2747 /*********************************************************************
2748 * _wcstoui64 (MSVCRT.@)
2750 unsigned __int64 CDECL
MSVCRT__wcstoui64(const MSVCRT_wchar_t
*nptr
,
2751 MSVCRT_wchar_t
**endptr
, int base
)
2753 return MSVCRT__wcstoui64_l(nptr
, endptr
, base
, NULL
);
2756 /*********************************************************************
2757 * _wcstoul_l (MSVCRT.@)
2759 MSVCRT_ulong __cdecl
MSVCRT__wcstoul_l(const MSVCRT_wchar_t
*s
,
2760 MSVCRT_wchar_t
**end
, int base
, MSVCRT__locale_t locale
)
2762 __int64 ret
= MSVCRT__wcstoi64_l(s
, end
, base
, locale
);
2764 if(ret
> MSVCRT_ULONG_MAX
) {
2765 ret
= MSVCRT_ULONG_MAX
;
2766 *MSVCRT__errno() = MSVCRT_ERANGE
;
2767 }else if(ret
< -(__int64
)MSVCRT_ULONG_MAX
) {
2769 *MSVCRT__errno() = MSVCRT_ERANGE
;
2774 /*********************************************************************
2775 * wcstoul (MSVCRT.@)
2777 MSVCRT_ulong __cdecl
MSVCRT_wcstoul(const MSVCRT_wchar_t
*s
, MSVCRT_wchar_t
**end
, int base
)
2779 return MSVCRT__wcstoul_l(s
, end
, base
, NULL
);
2782 /******************************************************************
2783 * wcsnlen (MSVCRT.@)
2785 MSVCRT_size_t CDECL
MSVCRT_wcsnlen(const MSVCRT_wchar_t
*s
, MSVCRT_size_t maxlen
)
2789 for (i
= 0; i
< maxlen
; i
++)
2794 /*********************************************************************
2795 * _towupper_l (MSVCRT.@)
2797 int CDECL
MSVCRT__towupper_l(MSVCRT_wint_t c
, MSVCRT__locale_t locale
)
2799 MSVCRT_pthreadlocinfo locinfo
;
2803 locinfo
= get_locinfo();
2805 locinfo
= locale
->locinfo
;
2807 if(!locinfo
->lc_handle
[MSVCRT_LC_CTYPE
]) {
2808 if(c
>= 'a' && c
<= 'z')
2809 return c
+ 'A' - 'a';
2813 if(!LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_CTYPE
], LCMAP_UPPERCASE
, &c
, 1, &ret
, 1))
2818 /*********************************************************************
2819 * towupper (MSVCRT.@)
2821 int CDECL
MSVCRT_towupper(MSVCRT_wint_t c
)
2823 return MSVCRT__towupper_l(c
, NULL
);
2826 /*********************************************************************
2829 MSVCRT_wchar_t
* CDECL
MSVCRT_wcschr(const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t ch
)
2831 do { if (*str
== ch
) return (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
2835 /*********************************************************************
2836 * wcsrchr (MSVCRT.@)
2838 MSVCRT_wchar_t
* CDECL
MSVCRT_wcsrchr(const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t ch
)
2841 do { if (*str
== ch
) ret
= (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
2845 /***********************************************************************
2848 MSVCRT_size_t CDECL
MSVCRT_wcslen(const MSVCRT_wchar_t
*str
)
2850 const MSVCRT_wchar_t
*s
= str
;
2855 /*********************************************************************
2858 MSVCRT_wchar_t
* CDECL
MSVCRT_wcsstr(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*sub
)
2862 const MSVCRT_wchar_t
*p1
= str
, *p2
= sub
;
2863 while(*p1
&& *p2
&& *p1
== *p2
)
2869 return (MSVCRT_wchar_t
*)str
;
2875 /*********************************************************************
2876 * _wtoi64_l (MSVCRT.@)
2878 __int64 CDECL
MSVCRT__wtoi64_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2880 ULONGLONG RunningTotal
= 0;
2881 BOOL bMinus
= FALSE
;
2883 while (MSVCRT__iswspace_l(*str
, locale
)) {
2889 } else if (*str
== '-') {
2894 while (*str
>= '0' && *str
<= '9') {
2895 RunningTotal
= RunningTotal
* 10 + *str
- '0';
2899 return bMinus
? -RunningTotal
: RunningTotal
;
2902 /*********************************************************************
2903 * _wtoi64 (MSVCRT.@)
2905 __int64 CDECL
MSVCRT__wtoi64(const MSVCRT_wchar_t
*str
)
2907 return MSVCRT__wtoi64_l(str
, NULL
);
2910 /*********************************************************************
2911 * _wcsxfrm_l (MSVCRT.@)
2913 MSVCRT_size_t CDECL
MSVCRT__wcsxfrm_l(MSVCRT_wchar_t
*dest
, const MSVCRT_wchar_t
*src
,
2914 MSVCRT_size_t len
, MSVCRT__locale_t locale
)
2916 MSVCRT_pthreadlocinfo locinfo
;
2919 if(!MSVCRT_CHECK_PMT(src
)) return INT_MAX
;
2920 if(!MSVCRT_CHECK_PMT(dest
|| !len
)) return INT_MAX
;
2923 FIXME("len > INT_MAX not supported\n");
2928 locinfo
= get_locinfo();
2930 locinfo
= locale
->locinfo
;
2932 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
]) {
2933 MSVCRT_wcsncpy(dest
, src
, len
);
2934 return MSVCRT_wcslen(src
);
2937 ret
= LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
],
2938 LCMAP_SORTKEY
, src
, -1, NULL
, 0);
2940 if(len
) dest
[0] = 0;
2941 *MSVCRT__errno() = MSVCRT_EILSEQ
;
2944 if(!len
) return ret
-1;
2948 *MSVCRT__errno() = MSVCRT_ERANGE
;
2952 ret
= LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
],
2953 LCMAP_SORTKEY
, src
, -1, dest
, len
) - 1;
2954 for(i
=ret
; i
>=0; i
--)
2955 dest
[i
] = ((unsigned char*)dest
)[i
];
2959 /*********************************************************************
2960 * wcsxfrm (MSVCRT.@)
2962 MSVCRT_size_t CDECL
MSVCRT_wcsxfrm(MSVCRT_wchar_t
*dest
,
2963 const MSVCRT_wchar_t
*src
, MSVCRT_size_t len
)
2965 return MSVCRT__wcsxfrm_l(dest
, src
, len
, NULL
);