1 /* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
20 #include <msvcrt/stdarg.h> // robd
21 #include <msvcrt/crttypes.h> // robd
23 #include <msvcrt/errno.h>
25 #include <msvcrt/ctype.h>
26 #include <msvcrt/stdio.h>
27 #include <msvcrt/stdlib.h>
28 #include <msvcrt/string.h>
29 #include <msvcrt/wchar.h>
30 #include <msvcrt/malloc.h>
31 #include <msvcrt/mbstring.h>
32 #include <msvcrt/internal/file.h>
33 #include <msvcrt/internal/stdio.h>
35 /* The internal entry points for `strtoX' take an extra flag argument
36 saying whether or not to parse locale-dependent number grouping. */
38 double __strtod_internal (const char *__nptr
,char **__endptr
, int __group
);
39 float __strtof_internal (const char *__nptr
, char **__endptr
,int __group
);
40 long double __strtold_internal (const char *__nptr
,char **__endptr
, int __group
);
41 long int __strtol_internal (const char *__nptr
, char **__endptr
, int __base
, int __group
);
42 unsigned long int __strtoul_internal (const char *__nptr
, char **__endptr
, int __base
, int __group
);
45 #include <msvcrt/crttypes.h> // robd
47 //#define HAVE_LONGLONG
48 //#define LONGLONG LONGLONG
50 //#define LONGLONG long
53 /* Those are flags in the conversion format. */
54 # define LONG 0x001 /* l: long or double */
55 # define LONGDBL 0x002 /* L: LONGLONG or long double */
56 # define SHORT 0x004 /* h: short */
57 # define SUPPRESS 0x008 /* *: suppress assignment */
58 # define POINTER 0x010 /* weird %p pointer (`fake hex') */
59 # define NOSKIP 0x020 /* do not skip blanks */
60 # define WIDTH 0x040 /* width was given */
61 # define GROUP 0x080 /* ': group numbers */
62 # define MALLOC 0x100 /* a: malloc strings */
64 # define TYPEMOD (LONG|LONGDBL|SHORT)
67 # define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
68 # define inchar() ((c = getc (s)), (void) (c != EOF && ++read_in), c)
69 # define encode_error() do { \
71 __set_errno (EILSEQ); \
74 # define conv_error() do { \
78 # define input_error() do { \
80 return done ? 0 : EOF; \
82 # define memory_error() do { \
84 __set_errno (ENOMEM); \
87 # define ARGCHECK(s, format) \
90 /* Check file argument for consistence. */ \
91 if (!__validfp (s) || !s->__mode.__read) \
93 __set_errno (EBADF); \
96 else if (format == NULL) \
98 __set_errno (EINVAL); \
103 # define flockfile(S) /* nothing */
104 # define funlockfile(S) /* nothing */
106 char *wp
= NULL
; /* Workspace. */
107 size_t wpmax
= 0; /* Maximal size of workspace. */
108 size_t wpsize
= 0; /* Currently used bytes in workspace. */
116 wpmax
= UCHAR_MAX
> 2 * wpmax
? UCHAR_MAX
: 2 * wpmax
;
117 wp
= (char *) malloc (wpmax
);
119 memcpy (wp
, old
, wpsize
);
127 int __vfscanf (FILE *s
, const char *format
, va_list argptr
)
130 register const char *f
= format
;
131 register unsigned char fc
; /* Current character of the format. */
132 register size_t done
= 0; /* Assignments done. */
133 register size_t read_in
= 0; /* Chars read in. */
134 register int c
= 0; /* Last char read. */
135 register int width
; /* Maximum field width. */
136 register int flags
; /* Modifiers for current format element. */
138 /* Status for reading F-P nums. */
139 char got_dot
, got_e
, negative
;
140 /* If a [...] is a [^...]. */
142 /* Base for integral numbers. */
144 /* Signedness for integral numbers. */
146 /* Decimal point character. */
147 wchar_t decimal
= '.';
148 /* The thousands character of the current locale. */
149 wchar_t thousands
= ',';
150 /* Integral holding variables. */
156 unsigned long int ul
;
158 /* Character-buffer pointer. */
160 wchar_t *wstr
= NULL
;
161 char **strptr
= NULL
;
163 /* We must not react on white spaces immediately because they can
164 possibly be matched even if in the input stream no character is
165 available anymore. */
168 char *tw
; /* Temporary pointer. */
171 __va_copy (arg
, argptr
);
173 arg
= (va_list) argptr
;
178 /* Run through the format string. */
182 /* Extract the next argument, which is of type TYPE.
183 For a %N$... spec, this is the Nth argument from the beginning;
184 otherwise it is the next argument after the state now in ARG. */
185 #define ARG(type) va_arg(argptr,type)
189 /* Non-ASCII, may be a multibyte. */
190 // int len = mblen (f, strlen (f));
213 /* Remember to skip spaces. */
220 /* Read a character. */
223 /* Characters other than format specs must just match. */
227 /* We saw white space char as the last character in the format
228 string. Now it's time to skip all leading white space. */
232 if (inchar () == EOF
&& errno
== EINTR
)
246 /* This is the start of the conversion string. */
249 /* Initialize state of modifiers. */
252 /* Prepare temporary buffer. */
255 /* Check for a positional parameter specification. */
260 argpos
= argpos
* 10 + (*f
++ - '0');
265 /* Oops; that was actually the field width. */
273 /* Check for the assignment-suppressing and the number grouping flag. */
274 while (*f
== '*' || *f
== '\'')
285 /* We have seen width. */
289 /* Find the maximum field width. */
300 /* Check for type modifiers. */
301 while (*f
== 'h' || *f
== 'l' || *f
== 'L' || *f
== 'a' || *f
== 'q')
305 /* int's are short int's. */
307 /* Signal illegal format element. */
312 if (flags
& (SHORT
|LONGDBL
))
314 else if (flags
& LONG
)
316 /* A double `l' is equivalent to an `L'. */
321 /* int's are long int's. */
326 /* double's are long double's, and int's are LONGLONG int's. */
328 /* Signal illegal format element. */
334 /* Signal illegal format element. */
336 /* String conversions (%s, %[) take a `char **'
337 arg and fill it in with a malloc'd pointer. */
342 /* End of the format string? */
346 /* We must take care for EINTR errors. */
347 if (c
== EOF
&& errno
== EINTR
)
350 /* Find the conversion specifier. */
352 if (skip_space
|| (fc
!= '[' && fc
!= 'c' && fc
!= 'C' && fc
!= 'n'))
354 /* Eat whitespace. */
356 if (inchar () == EOF
&& errno
== EINTR
)
365 case '%': /* Must match a literal '%'. */
374 case 'n': /* Answer number of assignments done. */
375 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
376 with the 'n' conversion specifier. */
377 if (!(flags
& SUPPRESS
))
379 /* Don't count the read-ahead. */
381 *ARG (long int *) = read_in
;
382 else if (flags
& LONG
)
383 *ARG (long int *) = read_in
;
384 else if (flags
& SHORT
)
385 *ARG (short int *) = read_in
;
387 *ARG (int *) = read_in
;
389 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
390 /* We have a severe problem here. The ISO C standard
391 contradicts itself in explaining the effect of the %n
392 format in `scanf'. While in ISO C:1990 and the ISO C
393 Amendement 1:1995 the result is described as
395 Execution of a %n directive does not effect the
396 assignment count returned at the completion of
397 execution of the f(w)scanf function.
399 in ISO C Corrigendum 1:1994 the following was added:
402 Add the following fourth example:
405 int d1, d2, n1, n2, i;
406 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
407 the value 123 is assigned to d1 and the value3 to n1.
408 Because %n can never get an input failure the value
409 of 3 is also assigned to n2. The value of d2 is not
410 affected. The value 3 is assigned to i.
412 We go for now with the historically correct code fro ISO C,
413 i.e., we don't count the %n assignments. When it ever
414 should proof to be wrong just remove the #ifdef above. */
420 case 'c': /* Match characters. */
421 if ((flags
& LONG
) == 0)
423 if (!(flags
& SUPPRESS
))
437 if (!(flags
& SUPPRESS
))
441 while (--width
> 0 && inchar () != EOF
);
444 while (--width
> 0 && inchar () != EOF
);
447 /* I.e., EOF was read. */
450 if (!(flags
& SUPPRESS
))
457 /* Get UTF-8 encoded wide character. Here we assume (as in
458 other parts of the libc) that we only have to handle
465 if (!(flags
& SUPPRESS
))
467 wstr
= ARG (wchar_t *);
474 #define NEXT_WIDE_CHAR(First) \
477 /* EOF is only an error for the first character. */ \
490 if ((c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \
492 if ((c & 0xe0) == 0xc0) \
494 /* We expect two bytes. */ \
498 else if ((c & 0xf0) == 0xe0) \
500 /* We expect three bytes. */ \
504 else if ((c & 0xf8) == 0xf0) \
506 /* We expect four bytes. */ \
510 else if ((c & 0xfc) == 0xf8) \
512 /* We expect five bytes. */ \
518 /* We expect six bytes. */ \
527 || (c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \
535 if (!(flags & SUPPRESS)) \
539 NEXT_WIDE_CHAR (first
);
544 /* I.e., EOF was read. */
547 if (!(flags
& SUPPRESS
))
552 case 's': /* Read a string. */
554 /* We have to process a wide character string. */
555 goto wide_char_string
;
557 #define STRING_ARG(Str, Type) \
558 if (!(flags & SUPPRESS)) \
560 if (flags & MALLOC) \
562 /* The string is to be stored in a malloc'd buffer. */ \
563 strptr = ARG (char **); \
564 if (strptr == NULL) \
566 /* Allocate an initial buffer. */ \
568 *strptr = malloc (strsize * sizeof (Type)); \
569 Str = (Type *) *strptr; \
572 Str = ARG (Type *); \
576 STRING_ARG (str
, char);
589 #define STRING_ADD_CHAR(Str, c, Type) \
590 if (!(flags & SUPPRESS)) \
593 if ((flags & MALLOC) && (char *) Str == *strptr + strsize) \
595 /* Enlarge the buffer. */ \
596 Str = realloc (*strptr, strsize * 2 * sizeof (Type)); \
599 /* Can't allocate that much. Last-ditch effort. */\
600 Str = realloc (*strptr, \
601 (strsize + 1) * sizeof (Type)); \
604 /* We lose. Oh well. \
605 Terminate the string and stop converting, \
606 so at least we don't skip any input. */ \
607 ((Type *) (*strptr))[strsize] = '\0'; \
613 *strptr = (char *) Str; \
614 Str = ((Type *) *strptr) + strsize; \
620 *strptr = (char *) Str; \
621 Str = ((Type *) *strptr) + strsize; \
626 STRING_ADD_CHAR (str
, c
, char);
627 } while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
629 if (!(flags
& SUPPRESS
))
637 /* Wide character string. */
642 STRING_ARG (wstr
, wchar_t);
647 NEXT_WIDE_CHAR (first
);
651 /* XXX We would have to push back the whole wide char
652 with possibly many bytes. But since scanf does
653 not make a difference for white space characters
654 we can simply push back a simple <SP> which is
655 guaranteed to be in the [:space:] class. */
660 STRING_ADD_CHAR (wstr
, val
, wchar_t);
663 while (width
<= 0 || --width
> 0);
665 if (!(flags
& SUPPRESS
))
673 case 'x': /* Hexadecimal integer. */
674 case 'X': /* Ditto. */
679 case 'o': /* Octal integer. */
684 case 'u': /* Unsigned decimal integer. */
689 case 'd': /* Signed decimal integer. */
694 case 'i': /* Generic number. */
703 /* Check for a sign. */
704 if (c
== '-' || c
== '+')
712 /* Look for a leading indication of base. */
713 if (width
!= 0 && c
== '0')
721 if (width
!= 0 && tolower (c
) == 'x')
739 /* Read the number into workspace. */
740 while (c
!= EOF
&& width
!= 0)
742 if (base
== 16 ? !isxdigit (c
) :
743 ((!isdigit (c
) || c
- '0' >= base
) &&
744 !((flags
& GROUP
) && base
== 10 && c
== thousands
)))
753 /* The just read character is not part of the number anymore. */
757 (wpsize
== 1 && (wp
[0] == '+' || wp
[0] == '-')))
758 /* There was no number. */
761 /* Convert the number. */
765 // if (number_signed)
766 // num.q = __strtoq_internal (wp, &tw, base, flags & GROUP);
768 // num.uq = __strtouq_internal (wp, &tw, base, flags & GROUP);
773 num
.l
= __strtol_internal (wp
, &tw
, base
, flags
& GROUP
);
775 num
.ul
= __strtoul_internal (wp
, &tw
, base
, flags
& GROUP
);
780 if (!(flags
& SUPPRESS
))
784 if (flags
& LONGDBL
) {
785 *ARG (ULONGLONG
*) = num
.uq
;
787 else if (flags
& LONG
)
788 *ARG (unsigned long int*) = num
.ul
;
789 else if (flags
& SHORT
)
790 *ARG (unsigned short int*) = (unsigned short int) num
.ul
;
792 *ARG (unsigned int*) = (unsigned int) num
.ul
;
796 if (flags
& LONGDBL
) {
797 *ARG (LONGLONG
*) = num
.q
;
799 else if (flags
& LONG
)
800 *ARG (long int *) = num
.l
;
801 else if (flags
& SHORT
)
802 *ARG (short int *) = (short int) num
.l
;
804 *ARG (int *) = (int) num
.l
;
810 case 'e': /* Floating-point numbers. */
819 /* Check for a sign. */
820 if (c
== '-' || c
== '+')
823 if (inchar () == EOF
)
824 /* EOF is only an input error before we read any chars. */
837 else if (got_e
&& wp
[wpsize
- 1] == 'e'
838 && (c
== '-' || c
== '+'))
840 else if (wpsize
> 0 && !got_e
&& tolower (c
) == 'e')
845 else if (c
== decimal
&& !got_dot
)
850 else if ((flags
& GROUP
) && c
== thousands
&& !got_dot
)
854 /* The last read character is not part of the number
862 while (width
!= 0 && inchar () != EOF
);
867 /* Convert the number. */
871 long double d
= __strtold_internal (wp
, &tw
, flags
& GROUP
);
872 if (!(flags
& SUPPRESS
) && tw
!= wp
)
873 *ARG (long double *) = negative
? -d
: d
;
875 else if (flags
& LONG
)
877 double d
= __strtod_internal (wp
, &tw
, flags
& GROUP
);
878 if (!(flags
& SUPPRESS
) && tw
!= wp
)
879 *ARG (double *) = negative
? -d
: d
;
883 float d
= __strtof_internal (wp
, &tw
, flags
& GROUP
);
884 if (!(flags
& SUPPRESS
) && tw
!= wp
)
885 *ARG (float *) = negative
? -d
: d
;
891 if (!(flags
& SUPPRESS
))
895 case '[': /* Character class. */
898 STRING_ARG (wstr
, wchar_t);
899 c
= '\0'; /* This is to keep gcc quiet. */
903 STRING_ARG (str
, char);
918 /* Fill WP with byte flags indexed by character.
919 We will use this flag map for matching input characters. */
920 if (wpmax
< UCHAR_MAX
)
923 wp
= (char *) alloca (wpmax
);
925 memset (wp
, 0, UCHAR_MAX
);
928 if (fc
== ']' || fc
== '-')
930 /* If ] or - appears before any char in the set, it is not
931 the terminator or separator, but the first char in the
937 while ((fc
= *f
++) != '\0' && fc
!= ']')
939 if (fc
== '-' && *f
!= '\0' && *f
!= ']' &&
940 (unsigned char) f
[-2] <= (unsigned char) *f
)
942 /* Add all characters from the one before the '-'
943 up to (but not including) the next format char. */
944 for (fc
= f
[-2]; fc
< *f
; ++fc
)
948 /* Add the character to the flag map. */
966 NEXT_WIDE_CHAR (first
);
967 if (val
> 255 || wp
[val
] == not_in
)
969 /* XXX We have a problem here. We read a wide
970 character and this possibly took several
971 bytes. But we can only push back one single
972 character. To be sure we don't create wrong
973 input we push it back only in case it is
974 representable within one byte. */
979 STRING_ADD_CHAR (wstr
, val
, wchar_t);
989 if (!(flags
& SUPPRESS
))
997 num
.ul
= read_in
- 1; /* -1 because we already read one char. */
1000 if (wp
[c
] == not_in
)
1005 STRING_ADD_CHAR (str
, c
, char);
1009 while (width
!= 0 && inchar () != EOF
);
1011 if (read_in
== num
.ul
)
1014 if (!(flags
& SUPPRESS
))
1022 case 'p': /* Generic pointer. */
1024 /* A PTR must be the same size as a `long int'. */
1025 flags
&= ~(SHORT
|LONGDBL
);
1032 /* The last thing we saw int the format string was a white space.
1033 Consume the last white spaces. */
1038 while (isspace (c
));
1049 xfscanf(FILE *f
, const char *fmt
, ...)
1054 r
= __vfscanf(f
, fmt
, a
);
1060 double __strtod_internal (const char *__nptr
,char **__endptr
, int __group
)
1062 return strtod(__nptr
,__endptr
);
1064 float __strtof_internal (const char *__nptr
, char **__endptr
,int __group
)
1066 return (float)strtod(__nptr
,__endptr
);
1068 static double powten
[] =
1070 1e1L
, 1e2L
, 1e4L
, 1e8L
, 1e16L
, 1e32L
, 1e64L
, 1e128L
, 1e256L
,
1072 1e512L
, 1e512L
*1e512L
, 1e2048L
, 1e4096L
1074 1e256L
, 1e256L
, 1e256L
, 1e256L
1078 long double __strtold_internal (const char *s
,char **sret
, int __group
)
1081 long double r
; /* result */
1082 int e
, ne
; /* exponent */
1083 int sign
; /* +- 1.0 */
1093 while(*s
&& isspace(*s
))
1104 while ((*s
>= '0') && (*s
<= '9'))
1115 while ((*s
>= '0') && (*s
<= '9'))
1131 if ((*s
== 'e') || (*s
== 'E'))
1141 while ((*s
>= '0') && (*s
<= '9'))
1156 /* possibly subnormal number, 10^e would overflow */
1174 d
*= powten
[l2powm1
];
1189 long int __strtol_internal (const char *__nptr
, char **__endptr
, int __base
, int __group
)
1191 return strtol(__nptr
,__endptr
, __base
);
1193 unsigned long int __strtoul_internal (const char *__nptr
, char **__endptr
, int __base
, int __group
)
1195 return strtoul(__nptr
,__endptr
, __base
);