2 * general implementation of scanf used by scanf, sscanf, fscanf,
3 * _cscanf, wscanf, swscanf and fwscanf
5 * Copyright 1996,1998 Marcus Meissner
6 * Copyright 1996 Jukka Iivonen
7 * Copyright 1997,2000 Uwe Bonnes
8 * Copyright 2000 Jon Griffiths
9 * Copyright 2002 Daniel Gudbjartsson
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
38 extern MSVCRT_FILE MSVCRT__iob
[];
40 /* helper function for *scanf. Returns the value of character c in the
41 * given base, or -1 if the given character is not a digit of the base.
43 static int char2digit(char c
, int base
) {
44 if ((c
>='0') && (c
<='9') && (c
<='0'+base
-1)) return (c
-'0');
45 if (base
<=10) return -1;
46 if ((c
>='A') && (c
<='Z') && (c
<='A'+base
-11)) return (c
-'A'+10);
47 if ((c
>='a') && (c
<='z') && (c
<='a'+base
-11)) return (c
-'a'+10);
51 /* helper function for *wscanf. Returns the value of character c in the
52 * given base, or -1 if the given character is not a digit of the base.
54 static int wchar2digit(MSVCRT_wchar_t c
, int base
) {
55 if ((c
>='0') && (c
<='9') && (c
<='0'+base
-1)) return (c
-'0');
56 if (base
<=10) return -1;
57 if ((c
>='A') && (c
<='Z') && (c
<='A'+base
-11)) return (c
-'A'+10);
58 if ((c
>='a') && (c
<='z') && (c
<='a'+base
-11)) return (c
-'a'+10);
148 /*********************************************************************
151 int WINAPIV
MSVCRT_fscanf(MSVCRT_FILE
*file
, const char *format
, ...)
156 __ms_va_start(valist
, format
);
157 res
= MSVCRT_vfscanf_l(file
, format
, NULL
, valist
);
162 /*********************************************************************
163 * _fscanf_l (MSVCRT.@)
165 int WINAPIV
MSVCRT__fscanf_l(MSVCRT_FILE
*file
, const char *format
,
166 MSVCRT__locale_t locale
, ...)
171 __ms_va_start(valist
, locale
);
172 res
= MSVCRT_vfscanf_l(file
, format
, locale
, valist
);
177 /*********************************************************************
178 * fscanf_s (MSVCRT.@)
180 int WINAPIV
MSVCRT_fscanf_s(MSVCRT_FILE
*file
, const char *format
, ...)
185 __ms_va_start(valist
, format
);
186 res
= MSVCRT_vfscanf_s_l(file
, format
, NULL
, valist
);
191 /*********************************************************************
192 * _fscanf_s_l (MSVCRT.@)
194 int WINAPIV
MSVCRT__fscanf_s_l(MSVCRT_FILE
*file
, const char *format
,
195 MSVCRT__locale_t locale
, ...)
200 __ms_va_start(valist
, locale
);
201 res
= MSVCRT_vfscanf_s_l(file
, format
, locale
, valist
);
206 /*********************************************************************
209 int WINAPIV
MSVCRT_scanf(const char *format
, ...)
214 __ms_va_start(valist
, format
);
215 res
= MSVCRT_vfscanf_l(MSVCRT_stdin
, format
, NULL
, valist
);
220 /*********************************************************************
221 * _scanf_l (MSVCRT.@)
223 int WINAPIV
MSVCRT__scanf_l(const char *format
, MSVCRT__locale_t locale
, ...)
228 __ms_va_start(valist
, locale
);
229 res
= MSVCRT_vfscanf_l(MSVCRT_stdin
, format
, locale
, valist
);
234 /*********************************************************************
237 int WINAPIV
MSVCRT_scanf_s(const char *format
, ...)
242 __ms_va_start(valist
, format
);
243 res
= MSVCRT_vfscanf_s_l(MSVCRT_stdin
, format
, NULL
, valist
);
248 /*********************************************************************
249 * _scanf_s_l (MSVCRT.@)
251 int WINAPIV
MSVCRT__scanf_s_l(const char *format
, MSVCRT__locale_t locale
, ...)
256 __ms_va_start(valist
, locale
);
257 res
= MSVCRT_vfscanf_s_l(MSVCRT_stdin
, format
, locale
, valist
);
262 /*********************************************************************
265 int WINAPIV
MSVCRT_fwscanf(MSVCRT_FILE
*file
, const MSVCRT_wchar_t
*format
, ...)
270 __ms_va_start(valist
, format
);
271 res
= MSVCRT_vfwscanf_l(file
, format
, NULL
, valist
);
276 /*********************************************************************
277 * _fwscanf_l (MSVCRT.@)
279 int WINAPIV
MSVCRT__fwscanf_l(MSVCRT_FILE
*file
, const MSVCRT_wchar_t
*format
,
280 MSVCRT__locale_t locale
, ...)
285 __ms_va_start(valist
, locale
);
286 res
= MSVCRT_vfwscanf_l(file
, format
, locale
, valist
);
291 /*********************************************************************
292 * fwscanf_s (MSVCRT.@)
294 int WINAPIV
MSVCRT_fwscanf_s(MSVCRT_FILE
*file
, const MSVCRT_wchar_t
*format
, ...)
299 __ms_va_start(valist
, format
);
300 res
= MSVCRT_vfwscanf_s_l(file
, format
, NULL
, valist
);
305 /*********************************************************************
306 * _fwscanf_s_l (MSVCRT.@)
308 int WINAPIV
MSVCRT__fwscanf_s_l(MSVCRT_FILE
*file
, const MSVCRT_wchar_t
*format
,
309 MSVCRT__locale_t locale
, ...)
314 __ms_va_start(valist
, locale
);
315 res
= MSVCRT_vfwscanf_s_l(file
, format
, locale
, valist
);
320 /*********************************************************************
323 int WINAPIV
MSVCRT_wscanf(const MSVCRT_wchar_t
*format
, ...)
328 __ms_va_start(valist
, format
);
329 res
= MSVCRT_vfwscanf_l(MSVCRT_stdin
, format
, NULL
, valist
);
334 /*********************************************************************
335 * _wscanf_l (MSVCRT.@)
337 int WINAPIV
MSVCRT__wscanf_l(const MSVCRT_wchar_t
*format
,
338 MSVCRT__locale_t locale
, ...)
343 __ms_va_start(valist
, locale
);
344 res
= MSVCRT_vfwscanf_l(MSVCRT_stdin
, format
, locale
, valist
);
349 /*********************************************************************
350 * wscanf_s (MSVCRT.@)
352 int WINAPIV
MSVCRT_wscanf_s(const MSVCRT_wchar_t
*format
, ...)
357 __ms_va_start(valist
, format
);
358 res
= MSVCRT_vfwscanf_s_l(MSVCRT_stdin
, format
, NULL
, valist
);
363 /*********************************************************************
364 * _wscanf_s_l (MSVCRT.@)
366 int WINAPIV
MSVCRT__wscanf_s_l(const MSVCRT_wchar_t
*format
,
367 MSVCRT__locale_t locale
, ...)
372 __ms_va_start(valist
, locale
);
373 res
= MSVCRT_vfwscanf_s_l(MSVCRT_stdin
, format
, locale
, valist
);
378 /*********************************************************************
381 int WINAPIV
MSVCRT_sscanf(const char *str
, const char *format
, ...)
386 __ms_va_start(valist
, format
);
387 res
= MSVCRT_vsscanf_l(str
, format
, NULL
, valist
);
392 /*********************************************************************
393 * _sscanf_l (MSVCRT.@)
395 int WINAPIV
MSVCRT__sscanf_l(const char *str
, const char *format
,
396 MSVCRT__locale_t locale
, ...)
401 __ms_va_start(valist
, locale
);
402 res
= MSVCRT_vsscanf_l(str
, format
, locale
, valist
);
407 /*********************************************************************
408 * sscanf_s (MSVCRT.@)
410 int WINAPIV
MSVCRT_sscanf_s(const char *str
, const char *format
, ...)
415 __ms_va_start(valist
, format
);
416 res
= MSVCRT_vsscanf_s_l(str
, format
, NULL
, valist
);
421 /*********************************************************************
422 * _sscanf_s_l (MSVCRT.@)
424 int WINAPIV
MSVCRT__sscanf_s_l(const char *str
, const char *format
,
425 MSVCRT__locale_t locale
, ...)
430 __ms_va_start(valist
, locale
);
431 res
= MSVCRT_vsscanf_s_l(str
, format
, locale
, valist
);
436 /*********************************************************************
439 int WINAPIV
MSVCRT_swscanf(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
, ...)
444 __ms_va_start(valist
, format
);
445 res
= MSVCRT_vswscanf_l(str
, format
, NULL
, valist
);
450 /*********************************************************************
451 * _swscanf_l (MSVCRT.@)
453 int WINAPIV
MSVCRT__swscanf_l(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
,
454 MSVCRT__locale_t locale
, ...)
459 __ms_va_start(valist
, locale
);
460 res
= MSVCRT_vswscanf_l(str
, format
, locale
, valist
);
465 /*********************************************************************
466 * swscanf_s (MSVCRT.@)
468 int WINAPIV
MSVCRT_swscanf_s(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
, ...)
473 __ms_va_start(valist
, format
);
474 res
= MSVCRT_vswscanf_s_l(str
, format
, NULL
, valist
);
479 /*********************************************************************
480 * _swscanf_s_l (MSVCRT.@)
482 int WINAPIV
MSVCRT__swscanf_s_l(const MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
,
483 MSVCRT__locale_t locale
, ...)
488 __ms_va_start(valist
, locale
);
489 res
= MSVCRT_vswscanf_s_l(str
, format
, locale
, valist
);
494 /*********************************************************************
497 int WINAPIV
_cscanf(const char *format
, ...)
502 __ms_va_start(valist
, format
);
503 res
= MSVCRT_vcscanf_l(format
, NULL
, valist
);
508 /*********************************************************************
509 * _cscanf_l (MSVCRT.@)
511 int WINAPIV
_cscanf_l(const char *format
, MSVCRT__locale_t locale
, ...)
516 __ms_va_start(valist
, locale
);
517 res
= MSVCRT_vcscanf_l(format
, locale
, valist
);
522 /*********************************************************************
523 * _cscanf_s (MSVCRT.@)
525 int WINAPIV
_cscanf_s(const char *format
, ...)
530 __ms_va_start(valist
, format
);
531 res
= MSVCRT_vcscanf_s_l(format
, NULL
, valist
);
536 /*********************************************************************
537 * _cscanf_s_l (MSVCRT.@)
539 int WINAPIV
_cscanf_s_l(const char *format
, MSVCRT__locale_t locale
, ...)
544 __ms_va_start(valist
, locale
);
545 res
= MSVCRT_vcscanf_s_l(format
, locale
, valist
);
550 /*********************************************************************
551 * _cwscanf (MSVCRT.@)
553 int WINAPIV
_cwscanf(const MSVCRT_wchar_t
*format
, ...)
558 __ms_va_start(valist
, format
);
559 res
= MSVCRT_vcwscanf_l(format
, NULL
, valist
);
564 /*********************************************************************
565 * _cwscanf_l (MSVCRT.@)
567 int WINAPIV
_cwscanf_l(const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
572 __ms_va_start(valist
, locale
);
573 res
= MSVCRT_vcwscanf_l(format
, locale
, valist
);
578 /*********************************************************************
579 * _cwscanf_s (MSVCRT.@)
581 int WINAPIV
_cwscanf_s(const MSVCRT_wchar_t
*format
, ...)
586 __ms_va_start(valist
, format
);
587 res
= MSVCRT_vcwscanf_s_l(format
, NULL
, valist
);
592 /*********************************************************************
593 * _cwscanf_s_l (MSVCRT.@)
595 int WINAPIV
_cwscanf_s_l(const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
600 __ms_va_start(valist
, locale
);
601 res
= MSVCRT_vcwscanf_s_l(format
, locale
, valist
);
606 /*********************************************************************
607 * _snscanf (MSVCRT.@)
609 int WINAPIV
MSVCRT__snscanf(char *input
, MSVCRT_size_t length
, const char *format
, ...)
614 __ms_va_start(valist
, format
);
615 res
= MSVCRT_vsnscanf_l(input
, length
, format
, NULL
, valist
);
620 /*********************************************************************
621 * _snscanf_l (MSVCRT.@)
623 int WINAPIV
MSVCRT__snscanf_l(char *input
, MSVCRT_size_t length
,
624 const char *format
, MSVCRT__locale_t locale
, ...)
629 __ms_va_start(valist
, locale
);
630 res
= MSVCRT_vsnscanf_l(input
, length
, format
, locale
, valist
);
635 /*********************************************************************
636 * _snscanf_s (MSVCRT.@)
638 int WINAPIV
MSVCRT__snscanf_s(char *input
, MSVCRT_size_t length
, const char *format
, ...)
643 __ms_va_start(valist
, format
);
644 res
= MSVCRT_vsnscanf_s_l(input
, length
, format
, NULL
, valist
);
649 /*********************************************************************
650 * _snscanf_s_l (MSVCRT.@)
652 int WINAPIV
MSVCRT__snscanf_s_l(char *input
, MSVCRT_size_t length
,
653 const char *format
, MSVCRT__locale_t locale
, ...)
658 __ms_va_start(valist
, locale
);
659 res
= MSVCRT_vsnscanf_s_l(input
, length
, format
, locale
, valist
);
665 /*********************************************************************
666 * __stdio_common_vsscanf (UCRTBASE.@)
668 int CDECL
MSVCRT__stdio_common_vsscanf(unsigned __int64 options
,
669 const char *input
, MSVCRT_size_t length
,
671 MSVCRT__locale_t locale
,
674 /* LEGACY_WIDE_SPECIFIERS only has got an effect on the wide
675 * scanf. LEGACY_MSVCRT_COMPATIBILITY affects parsing of nan/inf,
676 * but parsing of those isn't implemented at all yet. */
677 if (options
& ~UCRTBASE_SCANF_MASK
)
678 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
679 if (options
& UCRTBASE_SCANF_SECURECRT
)
680 return MSVCRT_vsnscanf_s_l(input
, length
, format
, locale
, valist
);
682 return MSVCRT_vsnscanf_l(input
, length
, format
, locale
, valist
);
685 /*********************************************************************
686 * __stdio_common_vswscanf (UCRTBASE.@)
688 int CDECL
MSVCRT__stdio_common_vswscanf(unsigned __int64 options
,
689 const MSVCRT_wchar_t
*input
, MSVCRT_size_t length
,
690 const MSVCRT_wchar_t
*format
,
691 MSVCRT__locale_t locale
,
694 /* LEGACY_WIDE_SPECIFIERS only has got an effect on the wide
695 * scanf. LEGACY_MSVCRT_COMPATIBILITY affects parsing of nan/inf,
696 * but parsing of those isn't implemented at all yet. */
697 if (options
& ~UCRTBASE_SCANF_MASK
)
698 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
699 if (options
& UCRTBASE_SCANF_SECURECRT
)
700 return MSVCRT_vsnwscanf_s_l(input
, length
, format
, locale
, valist
);
702 return MSVCRT_vsnwscanf_l(input
, length
, format
, locale
, valist
);
705 /*********************************************************************
706 * __stdio_common_vfscanf (UCRTBASE.@)
708 int CDECL
MSVCRT__stdio_common_vfscanf(unsigned __int64 options
,
711 MSVCRT__locale_t locale
,
714 if (options
& ~UCRTBASE_SCANF_SECURECRT
)
715 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
716 if (options
& UCRTBASE_SCANF_SECURECRT
)
717 return MSVCRT_vfscanf_s_l(file
, format
, locale
, valist
);
719 return MSVCRT_vfscanf_l(file
, format
, locale
, valist
);
722 /*********************************************************************
723 * __stdio_common_vfwscanf (UCRTBASE.@)
725 int CDECL
MSVCRT__stdio_common_vfwscanf(unsigned __int64 options
,
727 const MSVCRT_wchar_t
*format
,
728 MSVCRT__locale_t locale
,
731 if (options
& ~UCRTBASE_SCANF_SECURECRT
)
732 FIXME("options %s not handled\n", wine_dbgstr_longlong(options
));
733 if (options
& UCRTBASE_SCANF_SECURECRT
)
734 return MSVCRT_vfwscanf_s_l(file
, format
, locale
, valist
);
736 return MSVCRT_vfwscanf_l(file
, format
, locale
, valist
);
739 /*********************************************************************
740 * _snwscanf (MSVCRT.@)
742 int WINAPIV
MSVCRT__snwscanf(MSVCRT_wchar_t
*input
, MSVCRT_size_t length
,
743 const MSVCRT_wchar_t
*format
, ...)
748 __ms_va_start(valist
, format
);
749 res
= MSVCRT_vsnwscanf_l(input
, length
, format
, NULL
, valist
);
754 /*********************************************************************
755 * _snwscanf_l (MSVCRT.@)
757 int WINAPIV
MSVCRT__snwscanf_l(MSVCRT_wchar_t
*input
, MSVCRT_size_t length
,
758 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
763 __ms_va_start(valist
, locale
);
764 res
= MSVCRT_vsnwscanf_l(input
, length
, format
, locale
, valist
);
769 /*********************************************************************
770 * _snwscanf_s (MSVCRT.@)
772 int WINAPIV
MSVCRT__snwscanf_s(MSVCRT_wchar_t
*input
, MSVCRT_size_t length
,
773 const MSVCRT_wchar_t
*format
, ...)
778 __ms_va_start(valist
, format
);
779 res
= MSVCRT_vsnwscanf_s_l(input
, length
, format
, NULL
, valist
);
784 /*********************************************************************
785 * _snscanf_s_l (MSVCRT.@)
787 int WINAPIV
MSVCRT__snwscanf_s_l(MSVCRT_wchar_t
*input
, MSVCRT_size_t length
,
788 const MSVCRT_wchar_t
*format
, MSVCRT__locale_t locale
, ...)
793 __ms_va_start(valist
, locale
);
794 res
= MSVCRT_vsnwscanf_s_l(input
, length
, format
, locale
, valist
);
801 /*********************************************************************
802 * vsscanf (MSVCRT120.@)
804 int CDECL
MSVCRT_vsscanf(const char *buffer
, const char *format
, __ms_va_list valist
)
806 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
&& format
!= NULL
)) return -1;
808 return MSVCRT_vsscanf_l(buffer
, format
, NULL
, valist
);
811 /*********************************************************************
812 * vswscanf (MSVCRT120.@)
814 int CDECL
MSVCRT_vswscanf(const MSVCRT_wchar_t
*buffer
, const MSVCRT_wchar_t
*format
, __ms_va_list valist
)
816 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
&& format
!= NULL
)) return -1;
818 return MSVCRT_vswscanf_l(buffer
, format
, NULL
, valist
);
821 #endif /* _MSVCR_VER>=120 */