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
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
39 /* helper function for *scanf. Returns the value of character c in the
40 * given base, or -1 if the given character is not a digit of the base.
42 static int char2digit(char c
, int base
) {
43 if ((c
>='0') && (c
<='9') && (c
<='0'+base
-1)) return (c
-'0');
44 if (base
<=10) return -1;
45 if ((c
>='A') && (c
<='Z') && (c
<='A'+base
-11)) return (c
-'A'+10);
46 if ((c
>='a') && (c
<='z') && (c
<='a'+base
-11)) return (c
-'a'+10);
50 /* helper function for *wscanf. Returns the value of character c in the
51 * given base, or -1 if the given character is not a digit of the base.
53 static int wchar2digit(wchar_t c
, int base
) {
54 if ((c
>='0') && (c
<='9') && (c
<='0'+base
-1)) return (c
-'0');
55 if (base
<=10) return -1;
56 if ((c
>='A') && (c
<='Z') && (c
<='A'+base
-11)) return (c
-'A'+10);
57 if ((c
>='a') && (c
<='z') && (c
<='a'+base
-11)) return (c
-'a'+10);
147 /*********************************************************************
150 int WINAPIV
fscanf(FILE *file
, const char *format
, ...)
155 va_start(valist
, format
);
156 res
= vfscanf_l(file
, format
, NULL
, valist
);
161 /*********************************************************************
162 * _fscanf_l (MSVCRT.@)
164 int WINAPIV
_fscanf_l(FILE *file
, const char *format
,
165 _locale_t locale
, ...)
170 va_start(valist
, locale
);
171 res
= vfscanf_l(file
, format
, locale
, valist
);
176 /*********************************************************************
177 * fscanf_s (MSVCRT.@)
179 int WINAPIV
fscanf_s(FILE *file
, const char *format
, ...)
184 va_start(valist
, format
);
185 res
= vfscanf_s_l(file
, format
, NULL
, valist
);
190 /*********************************************************************
191 * _fscanf_s_l (MSVCRT.@)
193 int WINAPIV
_fscanf_s_l(FILE *file
, const char *format
,
194 _locale_t locale
, ...)
199 va_start(valist
, locale
);
200 res
= vfscanf_s_l(file
, format
, locale
, valist
);
205 /*********************************************************************
208 int WINAPIV
scanf(const char *format
, ...)
213 va_start(valist
, format
);
214 res
= vfscanf_l(MSVCRT_stdin
, format
, NULL
, valist
);
219 /*********************************************************************
220 * _scanf_l (MSVCRT.@)
222 int WINAPIV
_scanf_l(const char *format
, _locale_t locale
, ...)
227 va_start(valist
, locale
);
228 res
= vfscanf_l(MSVCRT_stdin
, format
, locale
, valist
);
233 /*********************************************************************
236 int WINAPIV
scanf_s(const char *format
, ...)
241 va_start(valist
, format
);
242 res
= vfscanf_s_l(MSVCRT_stdin
, format
, NULL
, valist
);
247 /*********************************************************************
248 * _scanf_s_l (MSVCRT.@)
250 int WINAPIV
_scanf_s_l(const char *format
, _locale_t locale
, ...)
255 va_start(valist
, locale
);
256 res
= vfscanf_s_l(MSVCRT_stdin
, format
, locale
, valist
);
261 /*********************************************************************
264 int WINAPIV
fwscanf(FILE *file
, const wchar_t *format
, ...)
269 va_start(valist
, format
);
270 res
= vfwscanf_l(file
, format
, NULL
, valist
);
275 /*********************************************************************
276 * _fwscanf_l (MSVCRT.@)
278 int WINAPIV
_fwscanf_l(FILE *file
, const wchar_t *format
,
279 _locale_t locale
, ...)
284 va_start(valist
, locale
);
285 res
= vfwscanf_l(file
, format
, locale
, valist
);
290 /*********************************************************************
291 * fwscanf_s (MSVCRT.@)
293 int WINAPIV
fwscanf_s(FILE *file
, const wchar_t *format
, ...)
298 va_start(valist
, format
);
299 res
= vfwscanf_s_l(file
, format
, NULL
, valist
);
304 /*********************************************************************
305 * _fwscanf_s_l (MSVCRT.@)
307 int WINAPIV
_fwscanf_s_l(FILE *file
, const wchar_t *format
,
308 _locale_t locale
, ...)
313 va_start(valist
, locale
);
314 res
= vfwscanf_s_l(file
, format
, locale
, valist
);
319 /*********************************************************************
322 int WINAPIV
wscanf(const wchar_t *format
, ...)
327 va_start(valist
, format
);
328 res
= vfwscanf_l(MSVCRT_stdin
, format
, NULL
, valist
);
333 /*********************************************************************
334 * _wscanf_l (MSVCRT.@)
336 int WINAPIV
_wscanf_l(const wchar_t *format
,
337 _locale_t locale
, ...)
342 va_start(valist
, locale
);
343 res
= vfwscanf_l(MSVCRT_stdin
, format
, locale
, valist
);
348 /*********************************************************************
349 * wscanf_s (MSVCRT.@)
351 int WINAPIV
wscanf_s(const wchar_t *format
, ...)
356 va_start(valist
, format
);
357 res
= vfwscanf_s_l(MSVCRT_stdin
, format
, NULL
, valist
);
362 /*********************************************************************
363 * _wscanf_s_l (MSVCRT.@)
365 int WINAPIV
_wscanf_s_l(const wchar_t *format
,
366 _locale_t locale
, ...)
371 va_start(valist
, locale
);
372 res
= vfwscanf_s_l(MSVCRT_stdin
, format
, locale
, valist
);
377 /*********************************************************************
380 int WINAPIV
sscanf(const char *str
, const char *format
, ...)
385 va_start(valist
, format
);
386 res
= vsscanf_l(str
, format
, NULL
, valist
);
391 /*********************************************************************
392 * _sscanf_l (MSVCRT.@)
394 int WINAPIV
_sscanf_l(const char *str
, const char *format
,
395 _locale_t locale
, ...)
400 va_start(valist
, locale
);
401 res
= vsscanf_l(str
, format
, locale
, valist
);
406 /*********************************************************************
407 * sscanf_s (MSVCRT.@)
409 int WINAPIV
sscanf_s(const char *str
, const char *format
, ...)
414 va_start(valist
, format
);
415 res
= vsscanf_s_l(str
, format
, NULL
, valist
);
420 /*********************************************************************
421 * _sscanf_s_l (MSVCRT.@)
423 int WINAPIV
_sscanf_s_l(const char *str
, const char *format
,
424 _locale_t locale
, ...)
429 va_start(valist
, locale
);
430 res
= vsscanf_s_l(str
, format
, locale
, valist
);
435 /*********************************************************************
438 int WINAPIV
swscanf(const wchar_t *str
, const wchar_t *format
, ...)
443 va_start(valist
, format
);
444 res
= vswscanf_l(str
, format
, NULL
, valist
);
449 /*********************************************************************
450 * _swscanf_l (MSVCRT.@)
452 int WINAPIV
_swscanf_l(const wchar_t *str
, const wchar_t *format
,
453 _locale_t locale
, ...)
458 va_start(valist
, locale
);
459 res
= vswscanf_l(str
, format
, locale
, valist
);
464 /*********************************************************************
465 * swscanf_s (MSVCRT.@)
467 int WINAPIV
swscanf_s(const wchar_t *str
, const wchar_t *format
, ...)
472 va_start(valist
, format
);
473 res
= vswscanf_s_l(str
, format
, NULL
, valist
);
478 /*********************************************************************
479 * _swscanf_s_l (MSVCRT.@)
481 int WINAPIV
_swscanf_s_l(const wchar_t *str
, const wchar_t *format
,
482 _locale_t locale
, ...)
487 va_start(valist
, locale
);
488 res
= vswscanf_s_l(str
, format
, locale
, valist
);
493 /*********************************************************************
496 int WINAPIV
_cscanf(const char *format
, ...)
501 va_start(valist
, format
);
502 res
= vcscanf_l(format
, NULL
, valist
);
507 /*********************************************************************
508 * _cscanf_l (MSVCRT.@)
510 int WINAPIV
_cscanf_l(const char *format
, _locale_t locale
, ...)
515 va_start(valist
, locale
);
516 res
= vcscanf_l(format
, locale
, valist
);
521 /*********************************************************************
522 * _cscanf_s (MSVCRT.@)
524 int WINAPIV
_cscanf_s(const char *format
, ...)
529 va_start(valist
, format
);
530 res
= vcscanf_s_l(format
, NULL
, valist
);
535 /*********************************************************************
536 * _cscanf_s_l (MSVCRT.@)
538 int WINAPIV
_cscanf_s_l(const char *format
, _locale_t locale
, ...)
543 va_start(valist
, locale
);
544 res
= vcscanf_s_l(format
, locale
, valist
);
549 /*********************************************************************
550 * _cwscanf (MSVCRT.@)
552 int WINAPIV
_cwscanf(const wchar_t *format
, ...)
557 va_start(valist
, format
);
558 res
= vcwscanf_l(format
, NULL
, valist
);
563 /*********************************************************************
564 * _cwscanf_l (MSVCRT.@)
566 int WINAPIV
_cwscanf_l(const wchar_t *format
, _locale_t locale
, ...)
571 va_start(valist
, locale
);
572 res
= vcwscanf_l(format
, locale
, valist
);
577 /*********************************************************************
578 * _cwscanf_s (MSVCRT.@)
580 int WINAPIV
_cwscanf_s(const wchar_t *format
, ...)
585 va_start(valist
, format
);
586 res
= vcwscanf_s_l(format
, NULL
, valist
);
591 /*********************************************************************
592 * _cwscanf_s_l (MSVCRT.@)
594 int WINAPIV
_cwscanf_s_l(const wchar_t *format
, _locale_t locale
, ...)
599 va_start(valist
, locale
);
600 res
= vcwscanf_s_l(format
, locale
, valist
);
605 /*********************************************************************
606 * _snscanf (MSVCRT.@)
608 int WINAPIV
_snscanf(const char *input
, size_t length
, const char *format
, ...)
613 va_start(valist
, format
);
614 res
= vsnscanf_l(input
, length
, format
, NULL
, valist
);
619 /*********************************************************************
620 * _snscanf_l (MSVCRT.@)
622 int WINAPIV
_snscanf_l(const char *input
, size_t length
,
623 const char *format
, _locale_t locale
, ...)
628 va_start(valist
, locale
);
629 res
= vsnscanf_l(input
, length
, format
, locale
, valist
);
634 /*********************************************************************
635 * _snscanf_s (MSVCRT.@)
637 int WINAPIV
_snscanf_s(const char *input
, size_t length
, const char *format
, ...)
642 va_start(valist
, format
);
643 res
= vsnscanf_s_l(input
, length
, format
, NULL
, valist
);
648 /*********************************************************************
649 * _snscanf_s_l (MSVCRT.@)
651 int WINAPIV
_snscanf_s_l(const char *input
, size_t length
,
652 const char *format
, _locale_t locale
, ...)
657 va_start(valist
, locale
);
658 res
= vsnscanf_s_l(input
, length
, format
, locale
, valist
);
664 /*********************************************************************
665 * __stdio_common_vsscanf (UCRTBASE.@)
667 int CDECL
__stdio_common_vsscanf(unsigned __int64 options
,
668 const char *input
, size_t length
,
673 /* LEGACY_WIDE_SPECIFIERS only has got an effect on the wide
674 * scanf. LEGACY_MSVCRT_COMPATIBILITY affects parsing of nan/inf,
675 * but parsing of those isn't implemented at all yet. */
676 if (options
& ~UCRTBASE_SCANF_MASK
)
677 FIXME("options %#I64x not handled\n", options
);
678 if (options
& _CRT_INTERNAL_SCANF_SECURECRT
)
679 return vsnscanf_s_l(input
, length
, format
, locale
, valist
);
681 return vsnscanf_l(input
, length
, format
, locale
, valist
);
684 /*********************************************************************
685 * __stdio_common_vswscanf (UCRTBASE.@)
687 int CDECL
__stdio_common_vswscanf(unsigned __int64 options
,
688 const wchar_t *input
, size_t length
,
689 const wchar_t *format
,
693 /* LEGACY_WIDE_SPECIFIERS only has got an effect on the wide
694 * scanf. LEGACY_MSVCRT_COMPATIBILITY affects parsing of nan/inf,
695 * but parsing of those isn't implemented at all yet. */
696 if (options
& ~UCRTBASE_SCANF_MASK
)
697 FIXME("options %#I64x not handled\n", options
);
698 if (options
& _CRT_INTERNAL_SCANF_SECURECRT
)
699 return vsnwscanf_s_l(input
, length
, format
, locale
, valist
);
701 return vsnwscanf_l(input
, length
, format
, locale
, valist
);
704 /*********************************************************************
705 * __stdio_common_vfscanf (UCRTBASE.@)
707 int CDECL
__stdio_common_vfscanf(unsigned __int64 options
,
713 if (options
& ~_CRT_INTERNAL_SCANF_SECURECRT
)
714 FIXME("options %#I64x not handled\n", options
);
715 if (options
& _CRT_INTERNAL_SCANF_SECURECRT
)
716 return vfscanf_s_l(file
, format
, locale
, valist
);
718 return vfscanf_l(file
, format
, locale
, valist
);
721 /*********************************************************************
722 * __stdio_common_vfwscanf (UCRTBASE.@)
724 int CDECL
__stdio_common_vfwscanf(unsigned __int64 options
,
726 const wchar_t *format
,
730 if (options
& ~_CRT_INTERNAL_SCANF_SECURECRT
)
731 FIXME("options %#I64x not handled\n", options
);
732 if (options
& _CRT_INTERNAL_SCANF_SECURECRT
)
733 return vfwscanf_s_l(file
, format
, locale
, valist
);
735 return vfwscanf_l(file
, format
, locale
, valist
);
738 /*********************************************************************
739 * _snwscanf (MSVCRT.@)
741 int WINAPIV
_snwscanf(wchar_t *input
, size_t length
,
742 const wchar_t *format
, ...)
747 va_start(valist
, format
);
748 res
= vsnwscanf_l(input
, length
, format
, NULL
, valist
);
753 /*********************************************************************
754 * _snwscanf_l (MSVCRT.@)
756 int WINAPIV
_snwscanf_l(wchar_t *input
, size_t length
,
757 const wchar_t *format
, _locale_t locale
, ...)
762 va_start(valist
, locale
);
763 res
= vsnwscanf_l(input
, length
, format
, locale
, valist
);
768 /*********************************************************************
769 * _snwscanf_s (MSVCRT.@)
771 int WINAPIV
_snwscanf_s(wchar_t *input
, size_t length
,
772 const wchar_t *format
, ...)
777 va_start(valist
, format
);
778 res
= vsnwscanf_s_l(input
, length
, format
, NULL
, valist
);
783 /*********************************************************************
784 * _snscanf_s_l (MSVCRT.@)
786 int WINAPIV
_snwscanf_s_l(wchar_t *input
, size_t length
,
787 const wchar_t *format
, _locale_t locale
, ...)
792 va_start(valist
, locale
);
793 res
= vsnwscanf_s_l(input
, length
, format
, locale
, valist
);
800 /*********************************************************************
801 * vsscanf (MSVCRT120.@)
803 int CDECL
MSVCRT_vsscanf(const char *buffer
, const char *format
, va_list valist
)
805 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
&& format
!= NULL
)) return -1;
807 return vsscanf_l(buffer
, format
, NULL
, valist
);
810 /*********************************************************************
811 * vswscanf (MSVCRT120.@)
813 int CDECL
vswscanf(const wchar_t *buffer
, const wchar_t *format
, va_list valist
)
815 if (!MSVCRT_CHECK_PMT(buffer
!= NULL
&& format
!= NULL
)) return -1;
817 return vswscanf_l(buffer
, format
, NULL
, valist
);
820 #endif /* _MSVCR_VER>=120 */