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
22 #include "wine/port.h"
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 * _wcsicmp (MSVCRT.@)
144 INT CDECL
MSVCRT__wcsicmp( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
146 return MSVCRT__wcsicmp_l(str1
, str2
, NULL
);
149 /*********************************************************************
150 * _wcsnicmp_l (MSVCRT.@)
152 INT CDECL
MSVCRT__wcsnicmp_l(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
,
153 MSVCRT_size_t n
, MSVCRT__locale_t locale
)
155 MSVCRT__locale_tstruct tmp
= {0};
156 MSVCRT_wchar_t c1
, c2
;
161 if(!MSVCRT_CHECK_PMT(str1
!= NULL
) || !MSVCRT_CHECK_PMT(str2
!= NULL
))
162 return MSVCRT__NLSCMPERROR
;
165 locale
= get_current_locale_noalloc(&tmp
);
169 c1
= MSVCRT__towlower_l(*str1
++, locale
);
170 c2
= MSVCRT__towlower_l(*str2
++, locale
);
171 } while(--n
&& c1
&& (c1
== c2
));
173 free_locale_noalloc(&tmp
);
177 /*********************************************************************
178 * _wcsnicmp (MSVCRT.@)
180 INT CDECL
MSVCRT__wcsnicmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
, MSVCRT_size_t n
)
182 return MSVCRT__wcsnicmp_l(str1
, str2
, n
, NULL
);
185 /*********************************************************************
186 * _wcsicoll_l (MSVCRT.@)
188 int CDECL
MSVCRT__wcsicoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT__locale_t locale
)
190 MSVCRT_pthreadlocinfo locinfo
;
193 locinfo
= get_locinfo();
195 locinfo
= locale
->locinfo
;
197 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
199 MSVCRT_wchar_t c1
, c2
;
204 if (c1
>= 'A' && c1
<= 'Z')
208 if (c2
>= 'A' && c2
<= 'Z')
210 } while(c1
&& (c1
== c2
));
214 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], NORM_IGNORECASE
,
215 str1
, -1, str2
, -1)-CSTR_EQUAL
;
218 /*********************************************************************
219 * _wcsicoll (MSVCRT.@)
221 INT CDECL
MSVCRT__wcsicoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
223 return MSVCRT__wcsicoll_l(str1
, str2
, NULL
);
226 /*********************************************************************
227 * _wcsnicoll_l (MSVCRT.@)
229 int CDECL
MSVCRT__wcsnicoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
,
230 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
232 MSVCRT_pthreadlocinfo locinfo
;
235 locinfo
= get_locinfo();
237 locinfo
= locale
->locinfo
;
239 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
241 MSVCRT_wchar_t c1
, c2
;
249 if (c1
>= 'A' && c1
<= 'Z')
253 if (c2
>= 'A' && c2
<= 'Z')
255 } while(--count
&& c1
&& (c1
== c2
));
259 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], NORM_IGNORECASE
,
260 str1
, MSVCRT_wcsnlen(str1
, count
),
261 str2
, MSVCRT_wcsnlen(str2
, count
))-CSTR_EQUAL
;
264 /*********************************************************************
265 * _wcsnicoll (MSVCRT.@)
267 INT CDECL
MSVCRT__wcsnicoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT_size_t count
)
269 return MSVCRT__wcsnicoll_l(str1
, str2
, count
, NULL
);
272 /*********************************************************************
273 * _wcsnset (MSVCRT.@)
275 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsnset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
, MSVCRT_size_t n
)
277 MSVCRT_wchar_t
* ret
= str
;
278 while ((n
-- > 0) && *str
) *str
++ = c
;
282 /*********************************************************************
283 * _wcsnset_s (MSVCRT.@)
285 int CDECL
MSVCRT__wcsnset_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t size
, MSVCRT_wchar_t c
, MSVCRT_size_t count
)
289 if(!str
&& !size
&& !count
) return 0;
290 if(!MSVCRT_CHECK_PMT(str
!= NULL
)) return MSVCRT_EINVAL
;
291 if(!MSVCRT_CHECK_PMT(size
> 0)) return MSVCRT_EINVAL
;
293 for(i
=0; i
<size
-1 && i
<count
; i
++) {
294 if(!str
[i
]) return 0;
298 if(!str
[i
]) return 0;
301 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
302 *MSVCRT__errno() = MSVCRT_EINVAL
;
303 return MSVCRT_EINVAL
;
306 /*********************************************************************
309 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsrev( MSVCRT_wchar_t
* str
)
311 MSVCRT_wchar_t
* ret
= str
;
312 MSVCRT_wchar_t
* end
= str
+ MSVCRT_wcslen(str
) - 1;
315 MSVCRT_wchar_t t
= *end
;
322 /*********************************************************************
323 * _wcsset_s (MSVCRT.@)
325 int CDECL
MSVCRT__wcsset_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t n
, MSVCRT_wchar_t c
)
327 MSVCRT_wchar_t
*p
= str
;
329 if(!MSVCRT_CHECK_PMT(str
!= NULL
)) return MSVCRT_EINVAL
;
330 if(!MSVCRT_CHECK_PMT(n
)) return MSVCRT_EINVAL
;
332 while(*p
&& --n
) *p
++ = c
;
335 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
336 *MSVCRT__errno() = MSVCRT_EINVAL
;
337 return MSVCRT_EINVAL
;
342 /*********************************************************************
345 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
)
347 MSVCRT_wchar_t
* ret
= str
;
348 while (*str
) *str
++ = c
;
352 /******************************************************************
353 * _wcsupr_s_l (MSVCRT.@)
355 int CDECL
MSVCRT__wcsupr_s_l( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
,
356 MSVCRT__locale_t locale
)
358 MSVCRT__locale_tstruct tmp
= {0};
359 MSVCRT_wchar_t
* ptr
= str
;
363 if (str
) *str
= '\0';
364 *MSVCRT__errno() = MSVCRT_EINVAL
;
365 return MSVCRT_EINVAL
;
369 locale
= get_current_locale_noalloc(&tmp
);
375 free_locale_noalloc(&tmp
);
378 *ptr
= MSVCRT__towupper_l(*ptr
, locale
);
382 free_locale_noalloc(&tmp
);
384 /* MSDN claims that the function should return and set errno to
385 * ERANGE, which doesn't seem to be true based on the tests. */
387 *MSVCRT__errno() = MSVCRT_EINVAL
;
388 return MSVCRT_EINVAL
;
391 /******************************************************************
392 * _wcsupr_s (MSVCRT.@)
395 INT CDECL
MSVCRT__wcsupr_s( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
)
397 return MSVCRT__wcsupr_s_l( str
, n
, NULL
);
400 /******************************************************************
401 * _wcsupr_l (MSVCRT.@)
403 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsupr_l( MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
405 MSVCRT__wcsupr_s_l( str
, -1, locale
);
409 /******************************************************************
412 MSVCRT_wchar_t
* CDECL
MSVCRT__wcsupr( MSVCRT_wchar_t
*str
)
414 return MSVCRT__wcsupr_l(str
, NULL
);
417 /******************************************************************
418 * _wcslwr_s_l (MSVCRT.@)
420 int CDECL
MSVCRT__wcslwr_s_l( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
, MSVCRT__locale_t locale
)
422 MSVCRT__locale_tstruct tmp
= {0};
423 MSVCRT_wchar_t
* ptr
= str
;
427 if (str
) *str
= '\0';
428 *MSVCRT__errno() = MSVCRT_EINVAL
;
429 return MSVCRT_EINVAL
;
433 locale
= get_current_locale_noalloc(&tmp
);
439 free_locale_noalloc(&tmp
);
442 *ptr
= MSVCRT__towlower_l(*ptr
, locale
);
446 free_locale_noalloc(&tmp
);
448 /* MSDN claims that the function should return and set errno to
449 * ERANGE, which doesn't seem to be true based on the tests. */
451 *MSVCRT__errno() = MSVCRT_EINVAL
;
452 return MSVCRT_EINVAL
;
455 /******************************************************************
456 * _wcslwr_s (MSVCRT.@)
458 int CDECL
MSVCRT__wcslwr_s( MSVCRT_wchar_t
* str
, MSVCRT_size_t n
)
460 return MSVCRT__wcslwr_s_l(str
, n
, NULL
);
463 /******************************************************************
464 * _wcslwr_l (MSVCRT.@)
466 MSVCRT_wchar_t
* CDECL
MSVCRT__wcslwr_l( MSVCRT_wchar_t
* str
, MSVCRT__locale_t locale
)
468 MSVCRT__wcslwr_s_l(str
, -1, locale
);
472 /******************************************************************
475 MSVCRT_wchar_t
* CDECL
MSVCRT__wcslwr( MSVCRT_wchar_t
* str
)
477 MSVCRT__wcslwr_s_l(str
, -1, NULL
);
481 /*********************************************************************
484 int CDECL
MSVCRT_wcsncmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
, MSVCRT_size_t n
)
488 while(--n
&& *str1
&& (*str1
== *str2
))
493 return *str1
- *str2
;
496 /*********************************************************************
497 * _wcsncoll_l (MSVCRT.@)
499 int CDECL
MSVCRT__wcsncoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
,
500 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
502 MSVCRT_pthreadlocinfo locinfo
;
505 locinfo
= get_locinfo();
507 locinfo
= locale
->locinfo
;
509 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
510 return MSVCRT_wcsncmp(str1
, str2
, count
);
511 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], 0,
512 str1
, MSVCRT_wcsnlen(str1
, count
),
513 str2
, MSVCRT_wcsnlen(str2
, count
))-CSTR_EQUAL
;
516 /*********************************************************************
517 * _wcsncoll (MSVCRT.@)
519 int CDECL
MSVCRT__wcsncoll(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT_size_t count
)
521 return MSVCRT__wcsncoll_l(str1
, str2
, count
, NULL
);
524 static MSVCRT_wchar_t
strtod_wstr_get(void *ctx
)
526 const MSVCRT_wchar_t
**p
= ctx
;
527 if (!**p
) return MSVCRT_WEOF
;
531 static void strtod_wstr_unget(void *ctx
)
533 const MSVCRT_wchar_t
**p
= ctx
;
537 /*********************************************************************
538 * _wcstod_l (MSVCRT.@)
540 double CDECL
MSVCRT__wcstod_l(const MSVCRT_wchar_t
* str
, MSVCRT_wchar_t
** end
,
541 MSVCRT__locale_t locale
)
543 MSVCRT_pthreadlocinfo locinfo
;
544 const MSVCRT_wchar_t
*beg
, *p
;
549 if (!MSVCRT_CHECK_PMT(str
!= NULL
)) {
550 if (end
) *end
= NULL
;
555 locinfo
= get_locinfo();
557 locinfo
= locale
->locinfo
;
560 while(MSVCRT__iswspace_l(*p
, locale
))
564 fp
= fpnum_parse(strtod_wstr_get
, strtod_wstr_unget
, &p
, locinfo
, FALSE
);
565 if (end
) *end
= (p
== beg
? (MSVCRT_wchar_t
*)str
: (MSVCRT_wchar_t
*)p
);
567 err
= fpnum_double(&fp
, &ret
);
568 if(err
) *MSVCRT__errno() = err
;
572 /*********************************************************************
573 * wcsrtombs_l (INTERNAL)
575 static MSVCRT_size_t
MSVCRT_wcsrtombs_l(char *mbstr
, const MSVCRT_wchar_t
**wcstr
,
576 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
578 MSVCRT_pthreadlocinfo locinfo
;
579 MSVCRT_size_t tmp
= 0;
580 BOOL used_default
= FALSE
;
584 locinfo
= get_locinfo();
586 locinfo
= locale
->locinfo
;
588 if(!locinfo
->lc_codepage
) {
592 return MSVCRT_wcslen(*wcstr
);
594 for(i
=0; i
<count
; i
++) {
595 if((*wcstr
)[i
] > 255) {
596 *MSVCRT__errno() = MSVCRT_EILSEQ
;
600 mbstr
[i
] = (*wcstr
)[i
];
601 if(!(*wcstr
)[i
]) break;
606 pused_default
= (locinfo
->lc_codepage
!= CP_UTF8
? &used_default
: NULL
);
609 tmp
= WideCharToMultiByte(locinfo
->lc_codepage
, WC_NO_BEST_FIT_CHARS
,
610 *wcstr
, -1, NULL
, 0, NULL
, pused_default
);
611 if(!tmp
|| used_default
) {
612 *MSVCRT__errno() = MSVCRT_EILSEQ
;
620 MSVCRT_size_t i
, size
;
622 size
= WideCharToMultiByte(locinfo
->lc_codepage
, WC_NO_BEST_FIT_CHARS
,
623 *wcstr
, 1, buf
, 3, NULL
, pused_default
);
624 if(!size
|| used_default
) {
625 *MSVCRT__errno() = MSVCRT_EILSEQ
;
631 for(i
=0; i
<size
; i
++)
632 mbstr
[tmp
++] = buf
[i
];
643 /*********************************************************************
644 * _wcstombs_l (MSVCRT.@)
646 MSVCRT_size_t CDECL
MSVCRT__wcstombs_l(char *mbstr
, const MSVCRT_wchar_t
*wcstr
,
647 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
649 return MSVCRT_wcsrtombs_l(mbstr
, &wcstr
, count
, locale
);
652 /*********************************************************************
653 * wcstombs (MSVCRT.@)
655 MSVCRT_size_t CDECL
MSVCRT_wcstombs(char *mbstr
, const MSVCRT_wchar_t
*wcstr
,
658 return MSVCRT_wcsrtombs_l(mbstr
, &wcstr
, count
, NULL
);
661 /*********************************************************************
662 * wcsrtombs (MSVCRT.@)
664 MSVCRT_size_t CDECL
MSVCRT_wcsrtombs(char *mbstr
, const MSVCRT_wchar_t
**wcstr
,
665 MSVCRT_size_t count
, MSVCRT_mbstate_t
*mbstate
)
670 return MSVCRT_wcsrtombs_l(mbstr
, wcstr
, count
, NULL
);
673 /*********************************************************************
674 * MSVCRT_wcsrtombs_s_l (INTERNAL)
676 static int MSVCRT_wcsrtombs_s_l(MSVCRT_size_t
*ret
, char *mbstr
,
677 MSVCRT_size_t size
, const MSVCRT_wchar_t
**wcstr
,
678 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
683 if(!mbstr
&& !size
&& wcstr
) {
684 conv
= MSVCRT_wcsrtombs_l(NULL
, wcstr
, 0, locale
);
688 return *MSVCRT__errno();
692 if (!MSVCRT_CHECK_PMT(mbstr
!= NULL
)) return MSVCRT_EINVAL
;
693 if (size
) mbstr
[0] = '\0';
694 if (!MSVCRT_CHECK_PMT(wcstr
!= NULL
)) return MSVCRT_EINVAL
;
695 if (!MSVCRT_CHECK_PMT(*wcstr
!= NULL
)) return MSVCRT_EINVAL
;
697 if(count
==MSVCRT__TRUNCATE
|| size
<count
)
703 conv
= MSVCRT_wcsrtombs_l(mbstr
, wcstr
, conv
, locale
);
708 err
= *MSVCRT__errno();
709 }else if(conv
< size
)
710 mbstr
[conv
++] = '\0';
711 else if(conv
==size
&& (count
==MSVCRT__TRUNCATE
|| mbstr
[conv
-1]=='\0')) {
712 mbstr
[conv
-1] = '\0';
713 if(count
==MSVCRT__TRUNCATE
)
714 err
= MSVCRT_STRUNCATE
;
716 MSVCRT_INVALID_PMT("mbstr[size] is too small", MSVCRT_ERANGE
);
728 /*********************************************************************
729 * _wcstombs_s_l (MSVCRT.@)
731 int CDECL
MSVCRT__wcstombs_s_l(MSVCRT_size_t
*ret
, char *mbstr
,
732 MSVCRT_size_t size
, const MSVCRT_wchar_t
*wcstr
,
733 MSVCRT_size_t count
, MSVCRT__locale_t locale
)
735 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, &wcstr
,count
, locale
);
738 /*********************************************************************
739 * wcstombs_s (MSVCRT.@)
741 int CDECL
MSVCRT_wcstombs_s(MSVCRT_size_t
*ret
, char *mbstr
,
742 MSVCRT_size_t size
, const MSVCRT_wchar_t
*wcstr
, MSVCRT_size_t count
)
744 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, &wcstr
, count
, NULL
);
747 /*********************************************************************
748 * wcsrtombs_s (MSVCRT.@)
750 int CDECL
MSVCRT_wcsrtombs_s(MSVCRT_size_t
*ret
, char *mbstr
, MSVCRT_size_t size
,
751 const MSVCRT_wchar_t
**wcstr
, MSVCRT_size_t count
, MSVCRT_mbstate_t
*mbstate
)
756 return MSVCRT_wcsrtombs_s_l(ret
, mbstr
, size
, wcstr
, count
, NULL
);
759 /*********************************************************************
762 double CDECL
MSVCRT_wcstod(const MSVCRT_wchar_t
* lpszStr
, MSVCRT_wchar_t
** end
)
764 return MSVCRT__wcstod_l(lpszStr
, end
, NULL
);
767 /*********************************************************************
770 double CDECL
MSVCRT__wtof(const MSVCRT_wchar_t
*str
)
772 return MSVCRT__wcstod_l(str
, NULL
, NULL
);
775 /*********************************************************************
778 double CDECL
MSVCRT__wtof_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
780 return MSVCRT__wcstod_l(str
, NULL
, locale
);
785 /*********************************************************************
786 * _wcstof_l (MSVCR120.@)
788 float CDECL
MSVCRT__wcstof_l( const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t
**end
, MSVCRT__locale_t locale
)
790 return MSVCRT__wcstod_l(str
, end
, locale
);
793 /*********************************************************************
794 * wcstof (MSVCR120.@)
796 float CDECL
MSVCRT_wcstof( const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t
**end
)
798 return MSVCRT__wcstof_l(str
, end
, NULL
);
801 #endif /* _MSVCR_VER>=120 */
803 /*********************************************************************
804 * arg_clbk_valist (INTERNAL)
806 printf_arg
arg_clbk_valist(void *ctx
, int arg_pos
, int type
, __ms_va_list
*valist
)
811 ret
.get_longlong
= va_arg(*valist
, LONGLONG
);
812 else if(type
== VT_INT
)
813 ret
.get_int
= va_arg(*valist
, int);
814 else if(type
== VT_R8
)
815 ret
.get_double
= va_arg(*valist
, double);
816 else if(type
== VT_PTR
)
817 ret
.get_ptr
= va_arg(*valist
, void*);
819 ERR("Incorrect type\n");
826 /*********************************************************************
827 * arg_clbk_positional (INTERNAL)
829 printf_arg
arg_clbk_positional(void *ctx
, int pos
, int type
, __ms_va_list
*valist
)
831 printf_arg
*args
= ctx
;
835 /*********************************************************************
836 * _vsnprintf (MSVCRT.@)
838 int CDECL
MSVCRT_vsnprintf( char *str
, MSVCRT_size_t len
,
839 const char *format
, __ms_va_list valist
)
841 static const char nullbyte
= '\0';
842 struct _str_ctx_a ctx
= {len
, str
};
845 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, NULL
, 0,
846 arg_clbk_valist
, NULL
, &valist
);
847 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
853 static int puts_clbk_str_c99_a(void *ctx
, int len
, const char *str
)
855 struct _str_ctx_a
*out
= ctx
;
861 memmove(out
->buf
, str
, out
->len
);
862 out
->buf
+= out
->len
;
867 memmove(out
->buf
, str
, len
);
873 /*********************************************************************
874 * __stdio_common_vsprintf (UCRTBASE.@)
876 int CDECL
MSVCRT__stdio_common_vsprintf( unsigned __int64 options
, char *str
, MSVCRT_size_t len
, const char *format
,
877 MSVCRT__locale_t locale
, __ms_va_list valist
)
879 static const char nullbyte
= '\0';
880 struct _str_ctx_a ctx
= {len
, str
};
883 if (options
& ~UCRTBASE_PRINTF_MASK
)
884 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
885 ret
= pf_printf_a(puts_clbk_str_c99_a
,
886 &ctx
, format
, locale
, options
& UCRTBASE_PRINTF_MASK
, arg_clbk_valist
, NULL
, &valist
);
887 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
891 if(options
& UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION
)
892 return ret
>len
? -1 : ret
;
894 if(len
) str
[len
-1] = 0;
895 if(options
& UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR
)
897 return len
> 0 ? -2 : -1;
902 #endif /* _MSVCR_VER>=140 */
904 /*********************************************************************
905 * _vsnprintf_l (MSVCRT.@)
907 int CDECL
MSVCRT_vsnprintf_l( char *str
, MSVCRT_size_t len
, const char *format
,
908 MSVCRT__locale_t locale
, __ms_va_list valist
)
910 static const char nullbyte
= '\0';
911 struct _str_ctx_a ctx
= {len
, str
};
914 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, locale
, 0,
915 arg_clbk_valist
, NULL
, &valist
);
916 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
920 /*********************************************************************
921 * _vsprintf_l (MSVCRT.@)
923 int CDECL
MSVCRT_vsprintf_l( char *str
, const char *format
,
924 MSVCRT__locale_t locale
, __ms_va_list valist
)
926 return MSVCRT_vsnprintf_l(str
, INT_MAX
, format
, locale
, valist
);
929 /*********************************************************************
930 * _sprintf_l (MSVCRT.@)
932 int WINAPIV
MSVCRT_sprintf_l(char *str
, const char *format
,
933 MSVCRT__locale_t locale
, ...)
937 __ms_va_start(valist
, locale
);
938 retval
= MSVCRT_vsnprintf_l(str
, INT_MAX
, format
, locale
, valist
);
943 static int CDECL
MSVCRT_vsnprintf_s_l_opt( char *str
, MSVCRT_size_t sizeOfBuffer
,
944 MSVCRT_size_t count
, const char *format
, DWORD options
,
945 MSVCRT__locale_t locale
, __ms_va_list valist
)
947 static const char nullbyte
= '\0';
948 struct _str_ctx_a ctx
;
951 if(sizeOfBuffer
<count
+1 || count
==-1)
958 ret
= pf_printf_a(puts_clbk_str_a
, &ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
959 arg_clbk_valist
, NULL
, &valist
);
960 puts_clbk_str_a(&ctx
, 1, &nullbyte
);
962 if(ret
<0 || ret
==len
) {
963 if(count
!=MSVCRT__TRUNCATE
&& count
>sizeOfBuffer
) {
964 MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE
);
965 memset(str
, 0, sizeOfBuffer
);
975 static int MSVCRT_vsnwprintf_s_l_opt( MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
976 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
, DWORD options
,
977 MSVCRT__locale_t locale
, __ms_va_list valist
)
979 static const MSVCRT_wchar_t nullbyte
= '\0';
980 struct _str_ctx_w ctx
;
984 if(count
!=-1 && len
>count
+1)
989 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
990 arg_clbk_valist
, NULL
, &valist
);
991 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
993 if(ret
<0 || ret
==len
) {
994 if(count
!=MSVCRT__TRUNCATE
&& count
>sizeOfBuffer
) {
995 MSVCRT_INVALID_PMT("str[sizeOfBuffer] is too small", MSVCRT_ERANGE
);
996 memset(str
, 0, sizeOfBuffer
*sizeof(MSVCRT_wchar_t
));
1006 /*********************************************************************
1007 * _vsnprintf_s_l (MSVCRT.@)
1009 int CDECL
MSVCRT_vsnprintf_s_l( char *str
, MSVCRT_size_t sizeOfBuffer
,
1010 MSVCRT_size_t count
, const char *format
,
1011 MSVCRT__locale_t locale
, __ms_va_list valist
)
1013 return MSVCRT_vsnprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, 0, locale
, valist
);
1016 /*********************************************************************
1017 * _vsprintf_s_l (MSVCRT.@)
1019 int CDECL
MSVCRT_vsprintf_s_l( char *str
, MSVCRT_size_t count
, const char *format
,
1020 MSVCRT__locale_t locale
, __ms_va_list valist
)
1022 return MSVCRT_vsnprintf_s_l(str
, INT_MAX
, count
, format
, locale
, valist
);
1025 /*********************************************************************
1026 * _sprintf_s_l (MSVCRT.@)
1028 int WINAPIV
MSVCRT_sprintf_s_l( char *str
, MSVCRT_size_t count
, const char *format
,
1029 MSVCRT__locale_t locale
, ...)
1032 __ms_va_list valist
;
1033 __ms_va_start(valist
, locale
);
1034 retval
= MSVCRT_vsnprintf_s_l(str
, INT_MAX
, count
, format
, locale
, valist
);
1035 __ms_va_end(valist
);
1039 /*********************************************************************
1040 * _vsnprintf_s (MSVCRT.@)
1042 int CDECL
MSVCRT_vsnprintf_s( char *str
, MSVCRT_size_t sizeOfBuffer
,
1043 MSVCRT_size_t count
, const char *format
, __ms_va_list valist
)
1045 return MSVCRT_vsnprintf_s_l(str
,sizeOfBuffer
, count
, format
, NULL
, valist
);
1048 /*********************************************************************
1049 * _vsnprintf_c_l (MSVCRT.@)
1051 int CDECL
MSVCRT_vsnprintf_c_l(char *str
, MSVCRT_size_t len
, const char *format
,
1052 MSVCRT__locale_t locale
, __ms_va_list valist
)
1054 return MSVCRT_vsnprintf_s_l_opt(str
, len
, len
, format
, 0, locale
, valist
);
1057 /*********************************************************************
1058 * _vsnprintf_c (MSVCRT.@)
1060 int CDECL
MSVCRT_vsnprintf_c(char *str
, MSVCRT_size_t len
,
1061 const char *format
, __ms_va_list valist
)
1063 return MSVCRT_vsnprintf_c_l(str
, len
, format
, NULL
, valist
);
1068 /*********************************************************************
1069 * __stdio_common_vsnprintf_s (UCRTBASE.@)
1071 int CDECL
MSVCRT__stdio_common_vsnprintf_s( unsigned __int64 options
,
1072 char *str
, MSVCRT_size_t sizeOfBuffer
, MSVCRT_size_t count
,
1073 const char *format
, MSVCRT__locale_t locale
, __ms_va_list valist
)
1075 if (options
& ~UCRTBASE_PRINTF_MASK
)
1076 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1077 return MSVCRT_vsnprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1080 /*********************************************************************
1081 * __stdio_common_vsnwprintf_s (UCRTBASE.@)
1083 int CDECL
MSVCRT__stdio_common_vsnwprintf_s( unsigned __int64 options
,
1084 MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
, MSVCRT_size_t count
,
1085 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list valist
)
1087 if (options
& ~UCRTBASE_PRINTF_MASK
)
1088 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1089 return MSVCRT_vsnwprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1092 /*********************************************************************
1093 * __stdio_common_vswprintf_s (UCRTBASE.@)
1095 int CDECL
MSVCRT__stdio_common_vswprintf_s( unsigned __int64 options
,
1096 MSVCRT_wchar_t
*str
, MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1097 MSVCRT__locale_t locale
, __ms_va_list valist
)
1099 return MSVCRT__stdio_common_vsnwprintf_s(options
, str
, INT_MAX
, count
, format
, locale
, valist
);
1102 /*********************************************************************
1103 * __stdio_common_vsprintf_s (UCRTBASE.@)
1105 int CDECL
MSVCRT__stdio_common_vsprintf_s( unsigned __int64 options
,
1106 char *str
, MSVCRT_size_t count
, const char *format
,
1107 MSVCRT__locale_t locale
, __ms_va_list valist
)
1109 if (options
& ~UCRTBASE_PRINTF_MASK
)
1110 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1111 return MSVCRT_vsnprintf_s_l_opt(str
, INT_MAX
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1114 #endif /* _MSVCR_VER>=140 */
1116 /*********************************************************************
1117 * vsprintf (MSVCRT.@)
1119 int CDECL
MSVCRT_vsprintf( char *str
, const char *format
, __ms_va_list valist
)
1121 return MSVCRT_vsnprintf(str
, INT_MAX
, format
, valist
);
1124 /*********************************************************************
1125 * vsprintf_s (MSVCRT.@)
1127 int CDECL
MSVCRT_vsprintf_s( char *str
, MSVCRT_size_t num
, const char *format
, __ms_va_list valist
)
1129 return MSVCRT_vsnprintf(str
, num
, format
, valist
);
1132 /*********************************************************************
1133 * _vscprintf (MSVCRT.@)
1135 int CDECL
MSVCRT__vscprintf( const char *format
, __ms_va_list valist
)
1137 return MSVCRT_vsnprintf( NULL
, INT_MAX
, format
, valist
);
1140 /*********************************************************************
1141 * _vscprintf_l (MSVCRT.@)
1143 int CDECL
MSVCRT__vscprintf_l(const char *format
,
1144 MSVCRT__locale_t locale
, __ms_va_list valist
)
1146 return MSVCRT_vsnprintf_l(NULL
, INT_MAX
, format
, locale
, valist
);
1149 /*********************************************************************
1150 * _vscprintf_p_l (MSVCRT.@)
1152 int CDECL
MSVCRT__vscprintf_p_l(const char *format
,
1153 MSVCRT__locale_t locale
, __ms_va_list args
)
1155 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1156 struct _str_ctx_a puts_ctx
= {INT_MAX
, NULL
};
1159 memset(args_ctx
, 0, sizeof(args_ctx
));
1161 ret
= create_positional_ctx_a(args_ctx
, format
, args
);
1163 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1164 *MSVCRT__errno() = MSVCRT_EINVAL
;
1166 } else if(ret
== 0) {
1167 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1168 MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
,
1169 arg_clbk_valist
, NULL
, &args
);
1171 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1172 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
,
1173 arg_clbk_positional
, args_ctx
, NULL
);
1179 /*********************************************************************
1180 * _vscprintf_p (MSVCR80.@)
1182 int CDECL
MSVCRT__vscprintf_p(const char *format
, __ms_va_list argptr
)
1184 return MSVCRT__vscprintf_p_l(format
, NULL
, argptr
);
1187 /*********************************************************************
1188 * _snprintf (MSVCRT.@)
1190 int WINAPIV
MSVCRT__snprintf(char *str
, MSVCRT_size_t len
, const char *format
, ...)
1193 __ms_va_list valist
;
1194 __ms_va_start(valist
, format
);
1195 retval
= MSVCRT_vsnprintf(str
, len
, format
, valist
);
1196 __ms_va_end(valist
);
1200 /*********************************************************************
1201 * _snprintf_l (MSVCRT.@)
1203 int WINAPIV
MSVCRT__snprintf_l(char *str
, MSVCRT_size_t count
, const char *format
,
1204 MSVCRT__locale_t locale
, ...)
1207 __ms_va_list valist
;
1208 __ms_va_start(valist
, locale
);
1209 retval
= MSVCRT_vsnprintf_l(str
, count
, format
, locale
, valist
);
1210 __ms_va_end(valist
);
1214 /*********************************************************************
1215 * _snprintf_c_l (MSVCRT.@)
1217 int WINAPIV
MSVCRT_snprintf_c_l(char *str
, MSVCRT_size_t count
, const char *format
,
1218 MSVCRT__locale_t locale
, ...)
1221 __ms_va_list valist
;
1222 __ms_va_start(valist
, locale
);
1223 retval
= MSVCRT_vsnprintf_c_l(str
, count
, format
, locale
, valist
);
1224 __ms_va_end(valist
);
1228 /*********************************************************************
1229 * _snprintf_c (MSVCRT.@)
1231 int WINAPIV
MSVCRT_snprintf_c(char *str
, MSVCRT_size_t count
, const char *format
, ...)
1234 __ms_va_list valist
;
1235 __ms_va_start(valist
, format
);
1236 retval
= MSVCRT_vsnprintf_c(str
, count
, format
, valist
);
1237 __ms_va_end(valist
);
1241 /*********************************************************************
1242 * _snprintf_s_l (MSVCRT.@)
1244 int WINAPIV
MSVCRT_snprintf_s_l(char *str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1245 const char *format
, MSVCRT__locale_t locale
, ...)
1248 __ms_va_list valist
;
1249 __ms_va_start(valist
, locale
);
1250 retval
= MSVCRT_vsnprintf_s_l(str
, len
, count
, format
, locale
, valist
);
1251 __ms_va_end(valist
);
1255 /*********************************************************************
1256 * _snprintf_s (MSVCRT.@)
1258 int WINAPIV
MSVCRT__snprintf_s(char *str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1259 const char *format
, ...)
1262 __ms_va_list valist
;
1263 __ms_va_start(valist
, format
);
1264 retval
= MSVCRT_vsnprintf_s_l(str
, len
, count
, format
, NULL
, valist
);
1265 __ms_va_end(valist
);
1269 /*********************************************************************
1270 * _scprintf (MSVCRT.@)
1272 int WINAPIV
MSVCRT__scprintf(const char *format
, ...)
1275 __ms_va_list valist
;
1276 __ms_va_start(valist
, format
);
1277 retval
= MSVCRT__vscprintf(format
, valist
);
1278 __ms_va_end(valist
);
1282 /*********************************************************************
1283 * _vsnwprintf (MSVCRT.@)
1285 int CDECL
MSVCRT_vsnwprintf(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1286 const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1288 static const MSVCRT_wchar_t nullbyte
= '\0';
1289 struct _str_ctx_w ctx
= {len
, str
};
1292 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, NULL
, 0,
1293 arg_clbk_valist
, NULL
, &valist
);
1294 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1298 /*********************************************************************
1299 * _vsnwprintf_l (MSVCRT.@)
1301 int CDECL
MSVCRT_vsnwprintf_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1302 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
,
1303 __ms_va_list valist
)
1305 static const MSVCRT_wchar_t nullbyte
= '\0';
1306 struct _str_ctx_w ctx
= {len
, str
};
1309 ret
= pf_printf_w(puts_clbk_str_w
, &ctx
, format
, locale
, 0,
1310 arg_clbk_valist
, NULL
, &valist
);
1311 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1315 /*********************************************************************
1316 * _vswprintf_c_l (MSVCRT.@)
1318 int CDECL
MSVCRT_vswprintf_c_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1319 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
,
1320 __ms_va_list valist
)
1322 return MSVCRT_vsnwprintf_s_l_opt(str
, len
, len
, format
, 0, locale
, valist
);
1325 /*********************************************************************
1326 * _vswprintf_c (MSVCRT.@)
1328 int CDECL
MSVCRT_vswprintf_c(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1329 const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1331 return MSVCRT_vswprintf_c_l(str
, len
, format
, NULL
, valist
);
1334 static int MSVCRT_vswprintf_p_l_opt(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1335 const MSVCRT_wchar_t
*format
, DWORD options
, MSVCRT__locale_t locale
, __ms_va_list args
)
1337 static const MSVCRT_wchar_t nullbyte
= '\0';
1338 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1339 struct _str_ctx_w puts_ctx
= {length
, buffer
};
1342 memset(args_ctx
, 0, sizeof(args_ctx
));
1344 ret
= create_positional_ctx_w(args_ctx
, format
, args
);
1346 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1347 *MSVCRT__errno() = MSVCRT_EINVAL
;
1350 ret
= pf_printf_w(puts_clbk_str_w
, &puts_ctx
, format
, locale
, MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1351 arg_clbk_valist
, NULL
, &args
);
1353 ret
= pf_printf_w(puts_clbk_str_w
, &puts_ctx
, format
, locale
,
1354 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1355 arg_clbk_positional
, args_ctx
, NULL
);
1357 puts_clbk_str_w(&puts_ctx
, 1, &nullbyte
);
1361 /*********************************************************************
1362 * _vswprintf_p_l (MSVCRT.@)
1364 int CDECL
MSVCRT_vswprintf_p_l(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1365 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1367 return MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, locale
, args
);
1371 /*********************************************************************
1372 * _vswprintf_p (MSVCR80.@)
1374 int CDECL
MSVCRT__vswprintf_p(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1375 const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1377 return MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, NULL
, args
);
1382 /*********************************************************************
1383 * __stdio_common_vswprintf_p (UCRTBASE.@)
1385 int CDECL
MSVCRT__stdio_common_vswprintf_p( unsigned __int64 options
,
1386 MSVCRT_wchar_t
*str
, MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1387 MSVCRT__locale_t locale
, __ms_va_list valist
)
1389 if (options
& ~UCRTBASE_PRINTF_MASK
)
1390 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1391 return MSVCRT_vswprintf_p_l_opt(str
, count
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, valist
);
1395 /*********************************************************************
1396 * _vsnwprintf_s_l (MSVCRT.@)
1398 int CDECL
MSVCRT_vsnwprintf_s_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
1399 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
,
1400 MSVCRT__locale_t locale
, __ms_va_list valist
)
1402 return MSVCRT_vsnwprintf_s_l_opt(str
, sizeOfBuffer
, count
, format
, 0, locale
, valist
);
1405 /*********************************************************************
1406 * _vsnwprintf_s (MSVCRT.@)
1408 int CDECL
MSVCRT_vsnwprintf_s(MSVCRT_wchar_t
*str
, MSVCRT_size_t sizeOfBuffer
,
1409 MSVCRT_size_t count
, const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
1411 return MSVCRT_vsnwprintf_s_l(str
, sizeOfBuffer
, count
,
1412 format
, NULL
, valist
);
1415 /*********************************************************************
1416 * _snwprintf (MSVCRT.@)
1418 int WINAPIV
MSVCRT__snwprintf( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
, ...)
1421 __ms_va_list valist
;
1422 __ms_va_start(valist
, format
);
1423 retval
= MSVCRT_vsnwprintf(str
, len
, format
, valist
);
1424 __ms_va_end(valist
);
1428 /*********************************************************************
1429 * _snwprintf_l (MSVCRT.@)
1431 int WINAPIV
MSVCRT__snwprintf_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
,
1432 MSVCRT__locale_t locale
, ...)
1435 __ms_va_list valist
;
1436 __ms_va_start(valist
, locale
);
1437 retval
= MSVCRT_vsnwprintf_l(str
, len
, format
, locale
, valist
);
1438 __ms_va_end(valist
);
1442 /*********************************************************************
1443 * _snwprintf_s (MSVCRT.@)
1445 int WINAPIV
MSVCRT__snwprintf_s( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1446 const MSVCRT_wchar_t
*format
, ...)
1449 __ms_va_list valist
;
1450 __ms_va_start(valist
, format
);
1451 retval
= MSVCRT_vsnwprintf_s_l(str
, len
, count
, format
, NULL
, valist
);
1452 __ms_va_end(valist
);
1456 /*********************************************************************
1457 * _snwprintf_s_l (MSVCRT.@)
1459 int WINAPIV
MSVCRT__snwprintf_s_l( MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, MSVCRT_size_t count
,
1460 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1463 __ms_va_list valist
;
1464 __ms_va_start(valist
, locale
);
1465 retval
= MSVCRT_vsnwprintf_s_l(str
, len
, count
, format
, locale
, valist
);
1466 __ms_va_end(valist
);
1472 static int puts_clbk_str_c99_w(void *ctx
, int len
, const MSVCRT_wchar_t
*str
)
1474 struct _str_ctx_w
*out
= ctx
;
1479 if(out
->len
< len
) {
1480 memcpy(out
->buf
, str
, out
->len
*sizeof(MSVCRT_wchar_t
));
1481 out
->buf
+= out
->len
;
1486 memcpy(out
->buf
, str
, len
*sizeof(MSVCRT_wchar_t
));
1492 /*********************************************************************
1493 * __stdio_common_vswprintf (UCRTBASE.@)
1495 int CDECL
MSVCRT__stdio_common_vswprintf( unsigned __int64 options
,
1496 MSVCRT_wchar_t
*str
, MSVCRT_size_t len
, const MSVCRT_wchar_t
*format
,
1497 MSVCRT__locale_t locale
, __ms_va_list valist
)
1499 static const MSVCRT_wchar_t nullbyte
= '\0';
1500 struct _str_ctx_w ctx
= {len
, str
};
1503 if (options
& ~UCRTBASE_PRINTF_MASK
)
1504 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1505 ret
= pf_printf_w(puts_clbk_str_c99_w
,
1506 &ctx
, format
, locale
, options
& UCRTBASE_PRINTF_MASK
, arg_clbk_valist
, NULL
, &valist
);
1507 puts_clbk_str_w(&ctx
, 1, &nullbyte
);
1511 if(options
& UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION
)
1512 return ret
>len
? -1 : ret
;
1514 if(len
) str
[len
-1] = 0;
1515 if(options
& UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR
)
1517 return len
> 0 ? -2 : -1;
1522 #endif /* _MSVCR_VER>=140 */
1524 /*********************************************************************
1525 * sprintf (MSVCRT.@)
1527 int WINAPIV
MSVCRT_sprintf( char *str
, const char *format
, ... )
1532 __ms_va_start( ap
, format
);
1533 r
= MSVCRT_vsnprintf( str
, INT_MAX
, format
, ap
);
1538 /*********************************************************************
1539 * sprintf_s (MSVCRT.@)
1541 int WINAPIV
MSVCRT_sprintf_s( char *str
, MSVCRT_size_t num
, const char *format
, ... )
1546 __ms_va_start( ap
, format
);
1547 r
= MSVCRT_vsnprintf( str
, num
, format
, ap
);
1552 /*********************************************************************
1553 * _scwprintf (MSVCRT.@)
1555 int WINAPIV
MSVCRT__scwprintf( const MSVCRT_wchar_t
*format
, ... )
1560 __ms_va_start( ap
, format
);
1561 r
= MSVCRT_vsnwprintf( NULL
, INT_MAX
, format
, ap
);
1566 /*********************************************************************
1567 * swprintf (MSVCRT.@)
1569 int WINAPIV
MSVCRT_swprintf( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
, ... )
1574 __ms_va_start( ap
, format
);
1575 r
= MSVCRT_vsnwprintf( str
, INT_MAX
, format
, ap
);
1580 /*********************************************************************
1581 * swprintf_s (MSVCRT.@)
1583 int WINAPIV
MSVCRT_swprintf_s(MSVCRT_wchar_t
*str
, MSVCRT_size_t numberOfElements
,
1584 const MSVCRT_wchar_t
*format
, ... )
1589 __ms_va_start(ap
, format
);
1590 r
= MSVCRT_vsnwprintf_s(str
, numberOfElements
, INT_MAX
, format
, ap
);
1596 /*********************************************************************
1597 * _swprintf_s_l (MSVCRT.@)
1599 int WINAPIV
MSVCRT__swprintf_s_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t numberOfElements
,
1600 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1605 __ms_va_start(ap
, locale
);
1606 r
= MSVCRT_vsnwprintf_s_l(str
, numberOfElements
, INT_MAX
, format
, locale
, ap
);
1612 /*********************************************************************
1613 * _swprintf_c_l (MSVCRT.@)
1615 int WINAPIV
MSVCRT_swprintf_c_l(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1616 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ... )
1621 __ms_va_start(ap
, locale
);
1622 r
= MSVCRT_vswprintf_c_l(str
, len
, format
, locale
, ap
);
1628 /*********************************************************************
1629 * _swprintf_c (MSVCRT.@)
1631 int WINAPIV
MSVCRT_swprintf_c(MSVCRT_wchar_t
*str
, MSVCRT_size_t len
,
1632 const MSVCRT_wchar_t
*format
, ... )
1637 __ms_va_start(ap
, format
);
1638 r
= MSVCRT_vswprintf_c(str
, len
, format
, ap
);
1644 /*********************************************************************
1645 * _vswprintf (MSVCRT.@)
1647 int CDECL
MSVCRT_vswprintf( MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* format
, __ms_va_list args
)
1649 return MSVCRT_vsnwprintf( str
, INT_MAX
, format
, args
);
1652 /*********************************************************************
1653 * _vswprintf (MSVCRT.@)
1655 int CDECL
MSVCRT_vswprintf_l( MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* format
,
1656 MSVCRT__locale_t locale
, __ms_va_list args
)
1658 return MSVCRT_vsnwprintf_l( str
, INT_MAX
, format
, locale
, args
);
1661 /*********************************************************************
1662 * _vscwprintf (MSVCRT.@)
1664 int CDECL
MSVCRT__vscwprintf( const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1666 return MSVCRT_vsnwprintf( NULL
, INT_MAX
, format
, args
);
1669 /*********************************************************************
1670 * _vscwprintf_l (MSVCRT.@)
1672 int CDECL
MSVCRT__vscwprintf_l( const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1674 return MSVCRT_vsnwprintf_l( NULL
, INT_MAX
, format
, locale
, args
);
1677 /*********************************************************************
1678 * _vscwprintf_p_l (MSVCRT.@)
1680 int CDECL
MSVCRT__vscwprintf_p_l( const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1682 return MSVCRT_vswprintf_p_l_opt( NULL
, INT_MAX
, format
, 0, locale
, args
);
1686 /*********************************************************************
1687 * _vscwprintf_p (MSVCR80.@)
1689 int CDECL
MSVCRT__vscwprintf_p(const MSVCRT_wchar_t
*format
, __ms_va_list args
)
1691 return MSVCRT_vswprintf_p_l_opt(NULL
, INT_MAX
, format
, 0, NULL
, args
);
1695 /*********************************************************************
1696 * vswprintf_s (MSVCRT.@)
1698 int CDECL
MSVCRT_vswprintf_s(MSVCRT_wchar_t
* str
, MSVCRT_size_t numberOfElements
,
1699 const MSVCRT_wchar_t
* format
, __ms_va_list args
)
1701 return MSVCRT_vsnwprintf_s(str
, numberOfElements
, INT_MAX
, format
, args
);
1704 /*********************************************************************
1705 * _vswprintf_s_l (MSVCRT.@)
1707 int CDECL
MSVCRT_vswprintf_s_l(MSVCRT_wchar_t
* str
, MSVCRT_size_t numberOfElements
,
1708 const MSVCRT_wchar_t
* format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1710 return MSVCRT_vsnwprintf_s_l(str
, numberOfElements
, INT_MAX
,
1711 format
, locale
, args
);
1714 static int MSVCRT_vsprintf_p_l_opt(char *buffer
, MSVCRT_size_t length
, const char *format
,
1715 DWORD options
, MSVCRT__locale_t locale
, __ms_va_list args
)
1717 static const char nullbyte
= '\0';
1718 printf_arg args_ctx
[MSVCRT__ARGMAX
+1];
1719 struct _str_ctx_a puts_ctx
= {length
, buffer
};
1722 memset(args_ctx
, 0, sizeof(args_ctx
));
1724 ret
= create_positional_ctx_a(args_ctx
, format
, args
);
1726 MSVCRT__invalid_parameter(NULL
, NULL
, NULL
, 0, 0);
1727 *MSVCRT__errno() = MSVCRT_EINVAL
;
1730 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1731 MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
, arg_clbk_valist
, NULL
, &args
);
1733 ret
= pf_printf_a(puts_clbk_str_a
, &puts_ctx
, format
, locale
,
1734 MSVCRT_PRINTF_POSITIONAL_PARAMS
| MSVCRT_PRINTF_INVOKE_INVALID_PARAM_HANDLER
| options
,
1735 arg_clbk_positional
, args_ctx
, NULL
);
1737 puts_clbk_str_a(&puts_ctx
, 1, &nullbyte
);
1741 /*********************************************************************
1742 * _vsprintf_p_l (MSVCRT.@)
1744 int CDECL
MSVCRT_vsprintf_p_l(char *buffer
, MSVCRT_size_t length
, const char *format
,
1745 MSVCRT__locale_t locale
, __ms_va_list args
)
1747 return MSVCRT_vsprintf_p_l_opt(buffer
, length
, format
, 0, locale
, args
);
1750 /*********************************************************************
1751 * _vsprintf_p (MSVCRT.@)
1753 int CDECL
MSVCRT_vsprintf_p(char *buffer
, MSVCRT_size_t length
,
1754 const char *format
, __ms_va_list args
)
1756 return MSVCRT_vsprintf_p_l(buffer
, length
, format
, NULL
, args
);
1760 /*********************************************************************
1761 * __stdio_common_vsprintf_p (UCRTBASE.@)
1763 int CDECL
MSVCRT__stdio_common_vsprintf_p(unsigned __int64 options
, char *buffer
, MSVCRT_size_t length
,
1764 const char *format
, MSVCRT__locale_t locale
, __ms_va_list args
)
1766 if (options
& ~UCRTBASE_PRINTF_MASK
)
1767 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
1768 return MSVCRT_vsprintf_p_l_opt(buffer
, length
, format
, options
& UCRTBASE_PRINTF_MASK
, locale
, args
);
1772 /*********************************************************************
1773 * _sprintf_p_l (MSVCRT.@)
1775 int WINAPIV
MSVCRT_sprintf_p_l(char *buffer
, MSVCRT_size_t length
,
1776 const char *format
, MSVCRT__locale_t locale
, ...)
1778 __ms_va_list valist
;
1781 __ms_va_start(valist
, locale
);
1782 r
= MSVCRT_vsprintf_p_l(buffer
, length
, format
, locale
, valist
);
1783 __ms_va_end(valist
);
1788 /*********************************************************************
1789 * __swprintf_l (MSVCRT.@)
1791 int WINAPIV
MSVCRT___swprintf_l( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
,
1792 MSVCRT__locale_t locale
, ...)
1795 __ms_va_list valist
;
1796 __ms_va_start(valist
, locale
);
1797 retval
= MSVCRT_vswprintf_l(str
, format
, locale
, valist
);
1798 __ms_va_end(valist
);
1803 /*********************************************************************
1804 * _sprintf_p (MSVCR80.@)
1806 int WINAPIV
MSVCRT__sprintf_p(char *buffer
, MSVCRT_size_t length
, const char *format
, ...)
1808 __ms_va_list valist
;
1811 __ms_va_start(valist
, format
);
1812 r
= MSVCRT_vsprintf_p_l(buffer
, length
, format
, NULL
, valist
);
1813 __ms_va_end(valist
);
1819 /*********************************************************************
1820 * _swprintf_p_l (MSVCRT.@)
1822 int WINAPIV
MSVCRT_swprintf_p_l(MSVCRT_wchar_t
*buffer
, MSVCRT_size_t length
,
1823 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
1825 __ms_va_list valist
;
1828 __ms_va_start(valist
, locale
);
1829 r
= MSVCRT_vswprintf_p_l_opt(buffer
, length
, format
, 0, locale
, valist
);
1830 __ms_va_end(valist
);
1835 /*********************************************************************
1838 int CDECL
MSVCRT_wcscmp(const MSVCRT_wchar_t
*str1
, const MSVCRT_wchar_t
*str2
)
1840 while (*str1
&& (*str1
== *str2
))
1853 /*********************************************************************
1854 * _wcscoll_l (MSVCRT.@)
1856 int CDECL
MSVCRT__wcscoll_l(const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
, MSVCRT__locale_t locale
)
1858 MSVCRT_pthreadlocinfo locinfo
;
1861 locinfo
= get_locinfo();
1863 locinfo
= locale
->locinfo
;
1865 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
])
1866 return MSVCRT_wcscmp(str1
, str2
);
1867 return CompareStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
], 0, str1
, -1, str2
, -1)-CSTR_EQUAL
;
1870 /*********************************************************************
1871 * wcscoll (MSVCRT.@)
1873 int CDECL
MSVCRT_wcscoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
1875 return MSVCRT__wcscoll_l(str1
, str2
, NULL
);
1878 /*********************************************************************
1879 * wcspbrk (MSVCRT.@)
1881 MSVCRT_wchar_t
* CDECL
MSVCRT_wcspbrk( const MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* accept
)
1883 const MSVCRT_wchar_t
* p
;
1887 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (MSVCRT_wchar_t
*)str
;
1893 /*********************************************************************
1894 * wcstok_s (MSVCRT.@)
1896 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok_s( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
,
1897 MSVCRT_wchar_t
**next_token
)
1899 MSVCRT_wchar_t
*ret
;
1901 if (!MSVCRT_CHECK_PMT(delim
!= NULL
)) return NULL
;
1902 if (!MSVCRT_CHECK_PMT(next_token
!= NULL
)) return NULL
;
1903 if (!MSVCRT_CHECK_PMT(str
!= NULL
|| *next_token
!= NULL
)) return NULL
;
1905 if (!str
) str
= *next_token
;
1907 while (*str
&& MSVCRT_wcschr( delim
, *str
)) str
++;
1908 if (!*str
) return NULL
;
1910 while (*str
&& !MSVCRT_wcschr( delim
, *str
)) str
++;
1911 if (*str
) *str
++ = 0;
1916 /*********************************************************************
1920 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
, MSVCRT_wchar_t
**ctx
)
1923 ctx
= &msvcrt_get_thread_data()->wcstok_next
;
1924 return MSVCRT_wcstok_s(str
, delim
, ctx
);
1927 MSVCRT_wchar_t
* CDECL
MSVCRT_wcstok( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*delim
)
1929 return MSVCRT_wcstok_s(str
, delim
, &msvcrt_get_thread_data()->wcstok_next
);
1933 /*********************************************************************
1934 * _wctomb_s_l (MSVCRT.@)
1936 int CDECL
MSVCRT__wctomb_s_l(int *len
, char *mbchar
, MSVCRT_size_t size
,
1937 MSVCRT_wchar_t wch
, MSVCRT__locale_t locale
)
1939 MSVCRT_pthreadlocinfo locinfo
;
1944 if(!mbchar
&& size
>0) {
1953 if(!MSVCRT_CHECK_PMT(size
<= INT_MAX
))
1954 return MSVCRT_EINVAL
;
1957 locinfo
= get_locinfo();
1959 locinfo
= locale
->locinfo
;
1961 if(!locinfo
->lc_codepage
) {
1963 if(mbchar
&& size
>0)
1964 memset(mbchar
, 0, size
);
1965 *MSVCRT__errno() = MSVCRT_EILSEQ
;
1966 return MSVCRT_EILSEQ
;
1969 if(!MSVCRT_CHECK_PMT_ERR(size
>= 1, MSVCRT_ERANGE
))
1970 return MSVCRT_ERANGE
;
1978 perror
= (locinfo
->lc_codepage
!= CP_UTF8
? &error
: NULL
);
1979 mblen
= WideCharToMultiByte(locinfo
->lc_codepage
, 0, &wch
, 1, mbchar
, size
, NULL
, perror
);
1980 if(!mblen
|| error
) {
1981 if(!mblen
&& GetLastError()==ERROR_INSUFFICIENT_BUFFER
) {
1982 if(mbchar
&& size
>0)
1983 memset(mbchar
, 0, size
);
1985 MSVCRT_INVALID_PMT("insufficient buffer size", MSVCRT_ERANGE
);
1986 return MSVCRT_ERANGE
;
1989 *MSVCRT__errno() = MSVCRT_EILSEQ
;
1990 return MSVCRT_EILSEQ
;
1998 /*********************************************************************
1999 * wctomb_s (MSVCRT.@)
2001 int CDECL
MSVCRT_wctomb_s(int *len
, char *mbchar
, MSVCRT_size_t size
, MSVCRT_wchar_t wch
)
2003 return MSVCRT__wctomb_s_l(len
, mbchar
, size
, wch
, NULL
);
2006 /*********************************************************************
2007 * _wctomb_l (MSVCRT.@)
2009 int CDECL
MSVCRT__wctomb_l(char *dst
, MSVCRT_wchar_t ch
, MSVCRT__locale_t locale
)
2013 MSVCRT__wctomb_s_l(&len
, dst
, dst
? MSVCRT_MB_LEN_MAX
: 0, ch
, locale
);
2017 /*********************************************************************
2020 INT CDECL
MSVCRT_wctomb( char *dst
, MSVCRT_wchar_t ch
)
2022 return MSVCRT__wctomb_l(dst
, ch
, NULL
);
2025 /*********************************************************************
2028 INT CDECL
MSVCRT_wctob( MSVCRT_wint_t wchar
)
2033 UINT codepage
= get_locinfo()->lc_codepage
;
2035 perror
= (codepage
!= CP_UTF8
? &error
: NULL
);
2039 return (signed char)wchar
;
2042 } else if(WideCharToMultiByte( codepage
, 0, &wchar
, 1, &out
, 1, NULL
, perror
) && !error
)
2047 /*********************************************************************
2048 * wcrtomb_s (MSVCRT.@)
2050 INT CDECL
MSVCRT_wcrtomb_s(MSVCRT_size_t
*len
, char *mbchar
,
2051 MSVCRT_size_t size
, MSVCRT_wchar_t wch
, MSVCRT_mbstate_t
*s
)
2056 ret
= MSVCRT_wctomb_s(&ilen
, mbchar
, size
, wch
);
2057 if (len
) *len
= ilen
;
2061 /*********************************************************************
2062 * wcrtomb (MSVCRT.@)
2064 MSVCRT_size_t CDECL
MSVCRT_wcrtomb( char *dst
, MSVCRT_wchar_t ch
, MSVCRT_mbstate_t
*s
)
2068 return MSVCRT_wctomb(dst
, ch
);
2071 /*********************************************************************
2072 * _iswctype_l (MSVCRT.@)
2074 INT CDECL
MSVCRT__iswctype_l( MSVCRT_wchar_t wc
, MSVCRT_wctype_t type
, MSVCRT__locale_t locale
)
2078 if (wc
== MSVCRT_WEOF
) return 0;
2079 if (wc
< 256) return MSVCRT__pwctype
[wc
] & type
;
2081 if (!GetStringTypeW(CT_CTYPE1
, &wc
, 1, &ct
))
2083 ERR("GetStringTypeW failed for %x\n", wc
);
2089 /*********************************************************************
2090 * iswctype (MSVCRT.@)
2092 INT CDECL
MSVCRT_iswctype( MSVCRT_wchar_t wc
, MSVCRT_wctype_t type
)
2094 return MSVCRT__iswctype_l( wc
, type
, NULL
);
2097 /*********************************************************************
2098 * _iswalnum_l (MSVCRT.@)
2100 int CDECL
MSVCRT__iswalnum_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2102 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__DIGIT
, locale
);
2105 /*********************************************************************
2106 * iswalnum (MSVCRT.@)
2108 INT CDECL
MSVCRT_iswalnum( MSVCRT_wchar_t wc
)
2110 return MSVCRT__iswalnum_l( wc
, NULL
);
2113 /*********************************************************************
2114 * iswalpha_l (MSVCRT.@)
2116 INT CDECL
MSVCRT__iswalpha_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2118 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
, locale
);
2121 /*********************************************************************
2122 * iswalpha (MSVCRT.@)
2124 INT CDECL
MSVCRT_iswalpha( MSVCRT_wchar_t wc
)
2126 return MSVCRT__iswalpha_l( wc
, NULL
);
2129 /*********************************************************************
2130 * _iswcntrl_l (MSVCRT.@)
2132 int CDECL
MSVCRT__iswcntrl_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2134 return MSVCRT__iswctype_l( wc
, MSVCRT__CONTROL
, locale
);
2137 /*********************************************************************
2138 * iswcntrl (MSVCRT.@)
2140 INT CDECL
MSVCRT_iswcntrl( MSVCRT_wchar_t wc
)
2142 return MSVCRT__iswcntrl_l( wc
, NULL
);
2145 /*********************************************************************
2146 * _iswdigit_l (MSVCRT.@)
2148 INT CDECL
MSVCRT__iswdigit_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2150 return MSVCRT__iswctype_l( wc
, MSVCRT__DIGIT
, locale
);
2153 /*********************************************************************
2154 * iswdigit (MSVCRT.@)
2156 INT CDECL
MSVCRT_iswdigit( MSVCRT_wchar_t wc
)
2158 return MSVCRT__iswdigit_l( wc
, NULL
);
2161 /*********************************************************************
2162 * _iswgraph_l (MSVCRT.@)
2164 int CDECL
MSVCRT__iswgraph_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2166 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__DIGIT
| MSVCRT__PUNCT
, locale
);
2169 /*********************************************************************
2170 * iswgraph (MSVCRT.@)
2172 INT CDECL
MSVCRT_iswgraph( MSVCRT_wchar_t wc
)
2174 return MSVCRT__iswgraph_l( wc
, NULL
);
2177 /*********************************************************************
2178 * _iswlower_l (MSVCRT.@)
2180 int CDECL
MSVCRT__iswlower_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2182 return MSVCRT__iswctype_l( wc
, MSVCRT__LOWER
, locale
);
2185 /*********************************************************************
2186 * iswlower (MSVCRT.@)
2188 INT CDECL
MSVCRT_iswlower( MSVCRT_wchar_t wc
)
2190 return MSVCRT__iswlower_l( wc
, NULL
);
2193 /*********************************************************************
2194 * _iswprint_l (MSVCRT.@)
2196 int CDECL
MSVCRT__iswprint_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2198 return MSVCRT__iswctype_l( wc
, MSVCRT__ALPHA
| MSVCRT__BLANK
|
2199 MSVCRT__DIGIT
| MSVCRT__PUNCT
, locale
);
2202 /*********************************************************************
2203 * iswprint (MSVCRT.@)
2205 INT CDECL
MSVCRT_iswprint( MSVCRT_wchar_t wc
)
2207 return MSVCRT__iswprint_l( wc
, NULL
);
2210 /*********************************************************************
2211 * _iswpunct_l (MSVCRT.@)
2213 INT CDECL
MSVCRT__iswpunct_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2215 return MSVCRT__iswctype_l( wc
, MSVCRT__PUNCT
, locale
);
2218 /*********************************************************************
2219 * iswpunct (MSVCRT.@)
2221 INT CDECL
MSVCRT_iswpunct( MSVCRT_wchar_t wc
)
2223 return MSVCRT__iswpunct_l( wc
, NULL
);
2226 /*********************************************************************
2227 * _iswspace_l (MSVCRT.@)
2229 INT CDECL
MSVCRT__iswspace_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2231 return MSVCRT__iswctype_l( wc
, MSVCRT__SPACE
, locale
);
2234 /*********************************************************************
2235 * iswspace (MSVCRT.@)
2237 INT CDECL
MSVCRT_iswspace( MSVCRT_wchar_t wc
)
2239 return MSVCRT__iswspace_l( wc
, NULL
);
2242 /*********************************************************************
2243 * _iswupper_l (MSVCRT.@)
2245 int CDECL
MSVCRT__iswupper_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2247 return MSVCRT__iswctype_l( wc
, MSVCRT__UPPER
, locale
);
2250 /*********************************************************************
2251 * iswupper (MSVCRT.@)
2253 INT CDECL
MSVCRT_iswupper( MSVCRT_wchar_t wc
)
2255 return MSVCRT__iswupper_l( wc
, NULL
);
2258 /*********************************************************************
2259 * _iswxdigit_l (MSVCRT.@)
2261 int CDECL
MSVCRT__iswxdigit_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2263 return MSVCRT__iswctype_l( wc
, MSVCRT__HEX
, locale
);
2266 /*********************************************************************
2267 * iswxdigit (MSVCRT.@)
2269 INT CDECL
MSVCRT_iswxdigit( MSVCRT_wchar_t wc
)
2271 return MSVCRT__iswxdigit_l( wc
, NULL
);
2274 /*********************************************************************
2275 * _iswblank_l (MSVCRT.@)
2277 INT CDECL
MSVCRT__iswblank_l( MSVCRT_wchar_t wc
, MSVCRT__locale_t locale
)
2279 return wc
== '\t' || MSVCRT__iswctype_l( wc
, MSVCRT__BLANK
, locale
);
2282 /*********************************************************************
2283 * iswblank (MSVCRT.@)
2285 INT CDECL
MSVCRT_iswblank( MSVCRT_wchar_t wc
)
2287 return wc
== '\t' || MSVCRT__iswctype_l( wc
, MSVCRT__BLANK
, NULL
);
2290 /*********************************************************************
2291 * wcscpy_s (MSVCRT.@)
2293 INT CDECL
MSVCRT_wcscpy_s( MSVCRT_wchar_t
* wcDest
, MSVCRT_size_t numElement
, const MSVCRT_wchar_t
*wcSrc
)
2295 MSVCRT_size_t size
= 0;
2297 if(!MSVCRT_CHECK_PMT(wcDest
)) return MSVCRT_EINVAL
;
2298 if(!MSVCRT_CHECK_PMT(numElement
)) return MSVCRT_EINVAL
;
2300 if(!MSVCRT_CHECK_PMT(wcSrc
))
2303 return MSVCRT_EINVAL
;
2306 size
= MSVCRT_wcslen(wcSrc
) + 1;
2308 if(!MSVCRT_CHECK_PMT_ERR(size
<= numElement
, MSVCRT_ERANGE
))
2311 return MSVCRT_ERANGE
;
2314 memmove( wcDest
, wcSrc
, size
*sizeof(WCHAR
) );
2319 /***********************************************************************
2322 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcscpy( MSVCRT_wchar_t
*dst
, const MSVCRT_wchar_t
*src
)
2325 while ((*p
++ = *src
++));
2329 /******************************************************************
2330 * wcsncpy (MSVCRT.@)
2332 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcsncpy( MSVCRT_wchar_t
* s1
,
2333 const MSVCRT_wchar_t
*s2
, MSVCRT_size_t n
)
2338 if(!(s1
[i
] = s2
[i
])) break;
2344 /******************************************************************
2345 * wcsncpy_s (MSVCRT.@)
2347 INT CDECL
MSVCRT_wcsncpy_s( MSVCRT_wchar_t
* wcDest
, MSVCRT_size_t numElement
, const MSVCRT_wchar_t
*wcSrc
,
2348 MSVCRT_size_t count
)
2351 BOOL truncate
= (count
== MSVCRT__TRUNCATE
);
2353 if(!wcDest
&& !numElement
&& !count
)
2356 if (!wcDest
|| !numElement
)
2357 return MSVCRT_EINVAL
;
2362 return count
? MSVCRT_EINVAL
: 0;
2365 while (numElement
&& count
&& *wcSrc
)
2371 if (!numElement
&& truncate
)
2374 return MSVCRT_STRUNCATE
;
2376 else if (!numElement
)
2379 return MSVCRT_ERANGE
;
2386 /******************************************************************
2387 * wcscat_s (MSVCRT.@)
2390 INT CDECL
MSVCRT_wcscat_s(MSVCRT_wchar_t
* dst
, MSVCRT_size_t elem
, const MSVCRT_wchar_t
* src
)
2392 MSVCRT_wchar_t
* ptr
= dst
;
2394 if (!dst
|| elem
== 0) return MSVCRT_EINVAL
;
2398 return MSVCRT_EINVAL
;
2401 /* seek to end of dst string (or elem if no end of string is found */
2402 while (ptr
< dst
+ elem
&& *ptr
!= '\0') ptr
++;
2403 while (ptr
< dst
+ elem
)
2405 if ((*ptr
++ = *src
++) == '\0') return 0;
2407 /* not enough space */
2409 return MSVCRT_ERANGE
;
2412 /***********************************************************************
2415 MSVCRT_wchar_t
* __cdecl
MSVCRT_wcscat( MSVCRT_wchar_t
*dst
, const MSVCRT_wchar_t
*src
)
2417 MSVCRT_wcscpy( dst
+ MSVCRT_wcslen(dst
), src
);
2421 /*********************************************************************
2422 * wcsncat_s (MSVCRT.@)
2425 INT CDECL
MSVCRT_wcsncat_s(MSVCRT_wchar_t
*dst
, MSVCRT_size_t elem
,
2426 const MSVCRT_wchar_t
*src
, MSVCRT_size_t count
)
2428 MSVCRT_size_t srclen
;
2429 MSVCRT_wchar_t dststart
;
2432 if (!MSVCRT_CHECK_PMT(dst
!= NULL
)) return MSVCRT_EINVAL
;
2433 if (!MSVCRT_CHECK_PMT(elem
> 0)) return MSVCRT_EINVAL
;
2434 if (!MSVCRT_CHECK_PMT(src
!= NULL
|| count
== 0)) return MSVCRT_EINVAL
;
2439 for (dststart
= 0; dststart
< elem
; dststart
++)
2441 if (dst
[dststart
] == '\0')
2444 if (dststart
== elem
)
2446 MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", MSVCRT_EINVAL
);
2447 return MSVCRT_EINVAL
;
2450 if (count
== MSVCRT__TRUNCATE
)
2452 srclen
= MSVCRT_wcslen(src
);
2453 if (srclen
>= (elem
- dststart
))
2455 srclen
= elem
- dststart
- 1;
2456 ret
= MSVCRT_STRUNCATE
;
2460 srclen
= min(MSVCRT_wcslen(src
), count
);
2461 if (srclen
< (elem
- dststart
))
2463 memcpy(&dst
[dststart
], src
, srclen
*sizeof(MSVCRT_wchar_t
));
2464 dst
[dststart
+srclen
] = '\0';
2467 MSVCRT_INVALID_PMT("dst[elem] is too small", MSVCRT_ERANGE
);
2469 return MSVCRT_ERANGE
;
2472 /*********************************************************************
2473 * wctoint (INTERNAL)
2475 static int wctoint(WCHAR c
, int base
)
2478 if ('0' <= c
&& c
<= '9')
2480 else if ('A' <= c
&& c
<= 'Z')
2482 else if ('a' <= c
&& c
<= 'z')
2485 /* NOTE: wine_fold_string(MAP_FOLDDIGITS) supports too many things. */
2486 /* Unicode points that contain digits 0-9; keep this sorted! */
2487 static const WCHAR zeros
[] = {
2488 0x660, 0x6f0, 0x966, 0x9e6, 0xa66, 0xae6, 0xb66, 0xc66, 0xce6,
2489 0xd66, 0xe50, 0xed0, 0xf20, 0x1040, 0x17e0, 0x1810, 0xff10
2492 for (i
= 0; i
< ARRAY_SIZE(zeros
) && c
>= zeros
[i
]; ++i
) {
2493 if (zeros
[i
] <= c
&& c
<= zeros
[i
] + 9) {
2499 return v
< base
? v
: -1;
2502 /*********************************************************************
2503 * _wcstoi64_l (MSVCRT.@)
2505 * FIXME: locale parameter is ignored
2507 __int64 CDECL
MSVCRT__wcstoi64_l(const MSVCRT_wchar_t
*nptr
,
2508 MSVCRT_wchar_t
**endptr
, int base
, MSVCRT__locale_t locale
)
2510 BOOL negative
= FALSE
, empty
= TRUE
;
2513 TRACE("(%s %p %d %p)\n", debugstr_w(nptr
), endptr
, base
, locale
);
2515 if (!MSVCRT_CHECK_PMT(nptr
!= NULL
)) return 0;
2516 if (!MSVCRT_CHECK_PMT(base
== 0 || base
>= 2)) return 0;
2517 if (!MSVCRT_CHECK_PMT(base
<= 36)) return 0;
2520 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2522 while(MSVCRT__iswspace_l(*nptr
, locale
)) nptr
++;
2527 } else if(*nptr
== '+')
2530 if((base
==0 || base
==16) && wctoint(*nptr
, 1)==0 && (nptr
[1]=='x' || nptr
[1]=='X')) {
2536 if(wctoint(*nptr
, 1)==0)
2543 int v
= wctoint(*nptr
, base
);
2553 if(!negative
&& (ret
>MSVCRT_I64_MAX
/base
|| ret
*base
>MSVCRT_I64_MAX
-v
)) {
2554 ret
= MSVCRT_I64_MAX
;
2555 *MSVCRT__errno() = MSVCRT_ERANGE
;
2556 } else if(negative
&& (ret
<MSVCRT_I64_MIN
/base
|| ret
*base
<MSVCRT_I64_MIN
-v
)) {
2557 ret
= MSVCRT_I64_MIN
;
2558 *MSVCRT__errno() = MSVCRT_ERANGE
;
2563 if(endptr
&& !empty
)
2564 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2569 /*********************************************************************
2570 * _wcstoi64 (MSVCRT.@)
2572 __int64 CDECL
MSVCRT__wcstoi64(const MSVCRT_wchar_t
*nptr
,
2573 MSVCRT_wchar_t
**endptr
, int base
)
2575 return MSVCRT__wcstoi64_l(nptr
, endptr
, base
, NULL
);
2578 /*********************************************************************
2579 * _wcstol_l (MSVCRT.@)
2581 MSVCRT_long CDECL
MSVCRT__wcstol_l(const MSVCRT_wchar_t
*s
,
2582 MSVCRT_wchar_t
**end
, int base
, MSVCRT__locale_t locale
)
2584 __int64 ret
= MSVCRT__wcstoi64_l(s
, end
, base
, locale
);
2586 if(ret
> MSVCRT_LONG_MAX
) {
2587 ret
= MSVCRT_LONG_MAX
;
2588 *MSVCRT__errno() = MSVCRT_ERANGE
;
2589 }else if(ret
< MSVCRT_LONG_MIN
) {
2590 ret
= MSVCRT_LONG_MIN
;
2591 *MSVCRT__errno() = MSVCRT_ERANGE
;
2596 /*********************************************************************
2599 MSVCRT_long CDECL
MSVCRT_wcstol(const MSVCRT_wchar_t
*s
,
2600 MSVCRT_wchar_t
**end
, int base
)
2602 return MSVCRT__wcstol_l(s
, end
, base
, NULL
);
2605 /*********************************************************************
2606 * _wtoi_l (MSVCRT.@)
2608 int __cdecl
MSVCRT__wtoi_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2610 __int64 ret
= MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2614 *MSVCRT__errno() = MSVCRT_ERANGE
;
2615 } else if(ret
< INT_MIN
) {
2617 *MSVCRT__errno() = MSVCRT_ERANGE
;
2622 /*********************************************************************
2625 int __cdecl
MSVCRT__wtoi(const MSVCRT_wchar_t
*str
)
2627 return MSVCRT__wtoi_l(str
, NULL
);
2630 /*********************************************************************
2631 * _wtol_l (MSVCRT.@)
2633 MSVCRT_long __cdecl
MSVCRT__wtol_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2635 __int64 ret
= MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2637 if(ret
> MSVCRT_LONG_MAX
) {
2638 ret
= MSVCRT_LONG_MAX
;
2639 *MSVCRT__errno() = MSVCRT_ERANGE
;
2640 } else if(ret
< MSVCRT_LONG_MIN
) {
2641 ret
= MSVCRT_LONG_MIN
;
2642 *MSVCRT__errno() = MSVCRT_ERANGE
;
2647 /*********************************************************************
2650 MSVCRT_long __cdecl
MSVCRT__wtol(const MSVCRT_wchar_t
*str
)
2652 return MSVCRT__wtol_l(str
, NULL
);
2657 /*********************************************************************
2658 * _wtoll_l (MSVCR120.@)
2660 MSVCRT_longlong __cdecl
MSVCRT__wtoll_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2662 return MSVCRT__wcstoi64_l(str
, NULL
, 10, locale
);
2665 /*********************************************************************
2666 * _wtoll (MSVCR120.@)
2668 MSVCRT_longlong __cdecl
MSVCRT__wtoll(const MSVCRT_wchar_t
*str
)
2670 return MSVCRT__wtoll_l(str
, NULL
);
2673 #endif /* _MSVCR_VER>=120 */
2675 /*********************************************************************
2676 * _wcstoui64_l (MSVCRT.@)
2678 * FIXME: locale parameter is ignored
2680 unsigned __int64 CDECL
MSVCRT__wcstoui64_l(const MSVCRT_wchar_t
*nptr
,
2681 MSVCRT_wchar_t
**endptr
, int base
, MSVCRT__locale_t locale
)
2683 BOOL negative
= FALSE
, empty
= TRUE
;
2684 unsigned __int64 ret
= 0;
2686 TRACE("(%s %p %d %p)\n", debugstr_w(nptr
), endptr
, base
, locale
);
2688 if (!MSVCRT_CHECK_PMT(nptr
!= NULL
)) return 0;
2689 if (!MSVCRT_CHECK_PMT(base
== 0 || base
>= 2)) return 0;
2690 if (!MSVCRT_CHECK_PMT(base
<= 36)) return 0;
2693 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2695 while(MSVCRT__iswspace_l(*nptr
, locale
)) nptr
++;
2700 } else if(*nptr
== '+')
2703 if((base
==0 || base
==16) && wctoint(*nptr
, 1)==0 && (nptr
[1]=='x' || nptr
[1]=='X')) {
2709 if(wctoint(*nptr
, 1)==0)
2716 int v
= wctoint(*nptr
, base
);
2723 if(ret
>MSVCRT_UI64_MAX
/base
|| ret
*base
>MSVCRT_UI64_MAX
-v
) {
2724 ret
= MSVCRT_UI64_MAX
;
2725 *MSVCRT__errno() = MSVCRT_ERANGE
;
2730 if(endptr
&& !empty
)
2731 *endptr
= (MSVCRT_wchar_t
*)nptr
;
2733 return negative
? -ret
: ret
;
2736 /*********************************************************************
2737 * _wcstoui64 (MSVCRT.@)
2739 unsigned __int64 CDECL
MSVCRT__wcstoui64(const MSVCRT_wchar_t
*nptr
,
2740 MSVCRT_wchar_t
**endptr
, int base
)
2742 return MSVCRT__wcstoui64_l(nptr
, endptr
, base
, NULL
);
2745 /*********************************************************************
2746 * _wcstoul_l (MSVCRT.@)
2748 MSVCRT_ulong __cdecl
MSVCRT__wcstoul_l(const MSVCRT_wchar_t
*s
,
2749 MSVCRT_wchar_t
**end
, int base
, MSVCRT__locale_t locale
)
2751 __int64 ret
= MSVCRT__wcstoi64_l(s
, end
, base
, locale
);
2753 if(ret
> MSVCRT_ULONG_MAX
) {
2754 ret
= MSVCRT_ULONG_MAX
;
2755 *MSVCRT__errno() = MSVCRT_ERANGE
;
2756 }else if(ret
< -(__int64
)MSVCRT_ULONG_MAX
) {
2758 *MSVCRT__errno() = MSVCRT_ERANGE
;
2763 /*********************************************************************
2764 * wcstoul (MSVCRT.@)
2766 MSVCRT_ulong __cdecl
MSVCRT_wcstoul(const MSVCRT_wchar_t
*s
, MSVCRT_wchar_t
**end
, int base
)
2768 return MSVCRT__wcstoul_l(s
, end
, base
, NULL
);
2771 /******************************************************************
2772 * wcsnlen (MSVCRT.@)
2774 MSVCRT_size_t CDECL
MSVCRT_wcsnlen(const MSVCRT_wchar_t
*s
, MSVCRT_size_t maxlen
)
2778 for (i
= 0; i
< maxlen
; i
++)
2783 /*********************************************************************
2784 * _towupper_l (MSVCRT.@)
2786 int CDECL
MSVCRT__towupper_l(MSVCRT_wint_t c
, MSVCRT__locale_t locale
)
2788 MSVCRT_pthreadlocinfo locinfo
;
2792 locinfo
= get_locinfo();
2794 locinfo
= locale
->locinfo
;
2796 if(!locinfo
->lc_handle
[MSVCRT_LC_CTYPE
]) {
2797 if(c
>= 'a' && c
<= 'z')
2798 return c
+ 'A' - 'a';
2802 if(!LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_CTYPE
], LCMAP_UPPERCASE
, &c
, 1, &ret
, 1))
2807 /*********************************************************************
2808 * towupper (MSVCRT.@)
2810 int CDECL
MSVCRT_towupper(MSVCRT_wint_t c
)
2812 return MSVCRT__towupper_l(c
, NULL
);
2815 /*********************************************************************
2818 MSVCRT_wchar_t
* CDECL
MSVCRT_wcschr(const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t ch
)
2820 do { if (*str
== ch
) return (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
2824 /*********************************************************************
2825 * wcsrchr (MSVCRT.@)
2827 MSVCRT_wchar_t
* CDECL
MSVCRT_wcsrchr(const MSVCRT_wchar_t
*str
, MSVCRT_wchar_t ch
)
2830 do { if (*str
== ch
) ret
= (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
2834 /***********************************************************************
2837 MSVCRT_size_t CDECL
MSVCRT_wcslen(const MSVCRT_wchar_t
*str
)
2839 const MSVCRT_wchar_t
*s
= str
;
2844 /*********************************************************************
2847 MSVCRT_wchar_t
* CDECL
MSVCRT_wcsstr(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*sub
)
2851 const MSVCRT_wchar_t
*p1
= str
, *p2
= sub
;
2852 while(*p1
&& *p2
&& *p1
== *p2
)
2858 return (MSVCRT_wchar_t
*)str
;
2864 /*********************************************************************
2865 * _wtoi64_l (MSVCRT.@)
2867 __int64 CDECL
MSVCRT__wtoi64_l(const MSVCRT_wchar_t
*str
, MSVCRT__locale_t locale
)
2869 ULONGLONG RunningTotal
= 0;
2870 BOOL bMinus
= FALSE
;
2872 while (MSVCRT__iswspace_l(*str
, locale
)) {
2878 } else if (*str
== '-') {
2883 while (*str
>= '0' && *str
<= '9') {
2884 RunningTotal
= RunningTotal
* 10 + *str
- '0';
2888 return bMinus
? -RunningTotal
: RunningTotal
;
2891 /*********************************************************************
2892 * _wtoi64 (MSVCRT.@)
2894 __int64 CDECL
MSVCRT__wtoi64(const MSVCRT_wchar_t
*str
)
2896 return MSVCRT__wtoi64_l(str
, NULL
);
2899 /*********************************************************************
2900 * _wcsxfrm_l (MSVCRT.@)
2902 MSVCRT_size_t CDECL
MSVCRT__wcsxfrm_l(MSVCRT_wchar_t
*dest
, const MSVCRT_wchar_t
*src
,
2903 MSVCRT_size_t len
, MSVCRT__locale_t locale
)
2905 MSVCRT_pthreadlocinfo locinfo
;
2908 if(!MSVCRT_CHECK_PMT(src
)) return INT_MAX
;
2909 if(!MSVCRT_CHECK_PMT(dest
|| !len
)) return INT_MAX
;
2912 FIXME("len > INT_MAX not supported\n");
2917 locinfo
= get_locinfo();
2919 locinfo
= locale
->locinfo
;
2921 if(!locinfo
->lc_handle
[MSVCRT_LC_COLLATE
]) {
2922 MSVCRT_wcsncpy(dest
, src
, len
);
2923 return MSVCRT_wcslen(src
);
2926 ret
= LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
],
2927 LCMAP_SORTKEY
, src
, -1, NULL
, 0);
2929 if(len
) dest
[0] = 0;
2930 *MSVCRT__errno() = MSVCRT_EILSEQ
;
2933 if(!len
) return ret
-1;
2937 *MSVCRT__errno() = MSVCRT_ERANGE
;
2941 ret
= LCMapStringW(locinfo
->lc_handle
[MSVCRT_LC_COLLATE
],
2942 LCMAP_SORTKEY
, src
, -1, dest
, len
) - 1;
2943 for(i
=ret
; i
>=0; i
--)
2944 dest
[i
] = ((unsigned char*)dest
)[i
];
2948 /*********************************************************************
2949 * wcsxfrm (MSVCRT.@)
2951 MSVCRT_size_t CDECL
MSVCRT_wcsxfrm(MSVCRT_wchar_t
*dest
,
2952 const MSVCRT_wchar_t
*src
, MSVCRT_size_t len
)
2954 return MSVCRT__wcsxfrm_l(dest
, src
, len
, NULL
);