1 /* Copyright (C) 1991, 92, 93, 94, 95, 96 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. */
19 #include "../locale/localeinfo.h"
28 #include <libc-lock.h>
32 #define LONGLONG long long
37 /* Those are flags in the conversion format. */
38 # define LONG 0x001 /* l: long or double */
39 # define LONGDBL 0x002 /* L: long long or long double */
40 # define SHORT 0x004 /* h: short */
41 # define SUPPRESS 0x008 /* *: suppress assignment */
42 # define POINTER 0x010 /* weird %p pointer (`fake hex') */
43 # define NOSKIP 0x020 /* do not skip blanks */
44 # define WIDTH 0x040 /* width was given */
45 # define GROUP 0x080 /* ': group numbers */
46 # define MALLOC 0x100 /* a: malloc strings */
48 # define TYPEMOD (LONG|LONGDBL|SHORT)
56 # define va_list _IO_va_list
57 # define ungetc(c, s) (--read_in, _IO_ungetc (c, s))
58 # define inchar() ((c = _IO_getc_unlocked (s)), (void) ++read_in, c)
59 # define encode_error() do { \
60 if (errp != NULL) *errp |= 4; \
61 _IO_funlockfile (s); \
62 __set_errno (EILSEQ); \
65 # define conv_error() do { \
66 if (errp != NULL) *errp |= 2; \
67 _IO_funlockfile (s); \
70 # define input_error() do { \
71 _IO_funlockfile (s); \
72 if (errp != NULL) *errp |= 1; \
75 # define memory_error() do { \
76 _IO_funlockfile (s); \
77 __set_errno (ENOMEM); \
80 # define ARGCHECK(s, format) \
83 /* Check file argument for consistence. */ \
84 CHECK_FILE (s, EOF); \
85 if (s->_flags & _IO_NO_READS || format == NULL) \
91 # define LOCK_STREAM(S) \
92 __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S)); \
94 # define UNLOCK_STREAM __libc_cleanup_region_end (1)
96 # define ungetc(c, s) (--read_in, ungetc (c, s))
97 # define inchar() ((c = getc (s)), (void) ++read_in, c)
98 # define encode_error() do { \
99 _IO_funlockfile (s); \
100 __set_errno (EILSEQ); \
103 # define conv_error() do { \
107 # define input_error() do { \
109 return done ?: EOF; \
111 # define memory_error() do { \
113 __set_errno (ENOMEM); \
116 # define ARGCHECK(s, format) \
119 /* Check file argument for consistence. */ \
120 if (!__validfp (s) || !s->__mode.__read || format == NULL) \
122 __set_errno (EINVAL); \
127 /* XXX For now !!! */
128 # define flockfile(S) /* nothing */
129 # define funlockfile(S) /* nothing */
130 # define LOCK_STREAM(S)
131 # define UNLOCK_STREAM
133 # define LOCK_STREAM(S) \
134 __libc_cleanup_region_start (&__funlockfile, (S)); \
136 # define UNLOCK_STREAM __libc_cleanup_region_end (1)
141 /* Read formatted input from S according to the format string
142 FORMAT, using the argument list in ARG.
143 Return the number of assignments made, or -1 for an input error. */
146 _IO_vfscanf (s
, format
, argptr
, errp
)
153 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
156 va_list arg
= (va_list) argptr
;
158 register const char *f
= format
;
159 register unsigned char fc
; /* Current character of the format. */
160 register size_t done
= 0; /* Assignments done. */
161 register size_t read_in
= 0; /* Chars read in. */
162 register int c
; /* Last char read. */
163 register int width
; /* Maximum field width. */
164 register int flags
; /* Modifiers for current format element. */
166 /* Status for reading F-P nums. */
167 char got_dot
, got_e
, negative
;
168 /* If a [...] is a [^...]. */
170 /* Base for integral numbers. */
172 /* Signedness for integral numbers. */
174 /* Decimal point character. */
176 /* The thousands character of the current locale. */
178 /* Integral holding variables. */
182 unsigned long long int uq
;
184 unsigned long int ul
;
186 /* Character-buffer pointer. */
188 wchar_t *wstr
= NULL
;
189 char **strptr
= NULL
;
191 /* We must not react on white spaces immediately because they can
192 possibly be matched even if in the input stream no character is
193 available anymore. */
196 char *tw
; /* Temporary pointer. */
197 char *wp
= NULL
; /* Workspace. */
198 size_t wpmax
= 0; /* Maximal size of workspace. */
199 size_t wpsize
; /* Currently used bytes in workspace. */
203 if (wpsize == wpmax) \
206 wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax; \
207 wp = (char *) alloca (wpmax); \
209 memcpy (wp, old, wpsize); \
211 wp[wpsize++] = (Ch); \
215 ARGCHECK (s
, format
);
217 /* Figure out the decimal point character. */
218 if (mbtowc (&decimal
, _NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
),
219 strlen (_NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
))) <= 0)
220 decimal
= (wchar_t) *_NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
);
221 /* Figure out the thousands separator character. */
222 if (mbtowc (&thousands
, _NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
),
223 strlen (_NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
))) <= 0)
224 thousands
= (wchar_t) *_NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
);
226 /* Lock the stream. */
229 /* Run through the format string. */
233 /* Extract the next argument, which is of type TYPE.
234 For a %N$... spec, this is the Nth argument from the beginning;
235 otherwise it is the next argument after the state now in ARG. */
237 /* XXX Possible optimization. */
238 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
239 ({ va_list arg = (va_list) argptr; \
240 arg = (va_list) ((char *) arg \
242 * __va_rounded_size (void *)); \
243 va_arg (arg, type); \
246 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
247 ({ unsigned int pos = argpos; \
248 va_list arg = (va_list) argptr; \
250 (void) va_arg (arg, void *); \
251 va_arg (arg, type); \
257 /* Non-ASCII, may be a multibyte. */
258 int len
= mblen (f
, strlen (f
));
280 /* Remember to skip spaces. */
287 /* Read a character. */
290 /* Characters other than format specs must just match. */
294 /* We saw white space char as the last character in the format
295 string. Now it's time to skip all leading white space. */
312 /* This is the start of the conversion string. */
315 /* Initialize state of modifiers. */
318 /* Prepare temporary buffer. */
321 /* Check for a positional parameter specification. */
326 argpos
= argpos
* 10 + (*f
++ - '0');
331 /* Oops; that was actually the field width. */
339 /* Check for the assignment-suppressant and the number grouping flag. */
340 while (*f
== '*' || *f
== '\'')
351 /* We have seen width. */
355 /* Find the maximum field width. */
366 /* Check for type modifiers. */
367 while (*f
== 'h' || *f
== 'l' || *f
== 'L' || *f
== 'a' || *f
== 'q')
371 /* int's are short int's. */
373 /* Signal illegal format element. */
378 if (flags
& (SHORT
|LONGDBL
))
380 else if (flags
& LONG
)
382 /* A double `l' is equivalent to an `L'. */
387 /* int's are long int's. */
392 /* double's are long double's, and int's are long long int's. */
394 /* Signal illegal format element. */
400 /* Signal illegal format element. */
402 /* String conversions (%s, %[) take a `char **'
403 arg and fill it in with a malloc'd pointer. */
408 /* End of the format string? */
412 /* Find the conversion specifier. */
414 if (skip_space
|| (fc
!= '[' && fc
!= 'c' && fc
!= 'n'))
416 /* Eat whitespace. */
426 case '%': /* Must match a literal '%'. */
435 case 'n': /* Answer number of assignments done. */
436 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
437 with the 'n' conversion specifier. */
438 if (!(flags
& SUPPRESS
))
439 /* Don't count the read-ahead. */
441 *ARG (long long int *) = read_in
;
442 else if (flags
& LONG
)
443 *ARG (long int *) = read_in
;
444 else if (flags
& SHORT
)
445 *ARG (short int *) = read_in
;
447 *ARG (int *) = read_in
;
450 case 'c': /* Match characters. */
451 if ((flags
& LONG
) == 0)
453 if (!(flags
& SUPPRESS
))
467 if (!(flags
& SUPPRESS
))
471 while (--width
> 0 && inchar () != EOF
);
474 while (--width
> 0 && inchar () != EOF
);
477 /* I.e., EOF was read. */
480 if (!(flags
& SUPPRESS
))
487 /* Get UTF-8 encoded wide character. Here we assume (as in
488 other parts of the libc) that we only have to handle
495 if (!(flags
& SUPPRESS
))
497 wstr
= ARG (wchar_t *);
504 #define NEXT_WIDE_CHAR(First) \
507 /* EOF is only an error for the first character. */ \
515 if ((c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \
517 if ((c & 0xe0) == 0xc0) \
519 /* We expect two bytes. */ \
523 else if ((c & 0xf0) == 0xe0) \
525 /* We expect three bytes. */ \
529 else if ((c & 0xf8) == 0xf0) \
531 /* We expect four bytes. */ \
535 else if ((c & 0xfc) == 0xf8) \
537 /* We expect five bytes. */ \
543 /* We expect six bytes. */ \
552 || (c & 0xc0) == 0x80 || (c & 0xfe) == 0xfe) \
560 if (!(flags & SUPPRESS)) \
564 NEXT_WIDE_CHAR (first
);
569 /* I.e., EOF was read. */
572 if (!(flags
& SUPPRESS
))
577 case 's': /* Read a string. */
579 /* We have to process a wide character string. */
580 goto wide_char_string
;
582 #define STRING_ARG(Str, Type) \
583 if (!(flags & SUPPRESS)) \
585 if (flags & MALLOC) \
587 /* The string is to be stored in a malloc'd buffer. */ \
588 strptr = ARG (char **); \
589 if (strptr == NULL) \
591 /* Allocate an initial buffer. */ \
593 *strptr = malloc (strsize * sizeof (Type)); \
594 Str = (Type *) *strptr; \
597 Str = ARG (Type *); \
601 STRING_ARG (str
, char);
614 #define STRING_ADD_CHAR(Str, c, Type) \
615 if (!(flags & SUPPRESS)) \
618 if ((flags & MALLOC) && (char *) Str == *strptr + strsize) \
620 /* Enlarge the buffer. */ \
621 Str = realloc (*strptr, strsize * 2 * sizeof (Type)); \
624 /* Can't allocate that much. Last-ditch effort. */\
625 Str = realloc (*strptr, \
626 (strsize + 1) * sizeof (Type)); \
629 /* We lose. Oh well. \
630 Terminate the string and stop converting, \
631 so at least we don't skip any input. */ \
632 ((Type *) (*strptr))[strsize] = '\0'; \
638 *strptr = (char *) Str; \
639 Str = ((Type *) *strptr) + strsize; \
645 *strptr = (char *) Str; \
646 Str = ((Type *) *strptr) + strsize; \
651 STRING_ADD_CHAR (str
, c
, char);
652 } while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
654 if (!(flags
& SUPPRESS
))
662 /* Wide character string. */
667 STRING_ARG (wstr
, wchar_t);
672 NEXT_WIDE_CHAR (first
);
676 /* XXX We would have to push back the whole wide char
677 with possibly many bytes. But since scanf does
678 not make a difference for white space characters
679 we can simply push back a simple <SP> which is
680 guaranteed to be in the [:space:] class. */
685 STRING_ADD_CHAR (wstr
, val
, wchar_t);
688 while (width
<= 0 || --width
> 0);
690 if (!(flags
& SUPPRESS
))
698 case 'x': /* Hexadecimal integer. */
699 case 'X': /* Ditto. */
704 case 'o': /* Octal integer. */
709 case 'u': /* Unsigned decimal integer. */
714 case 'd': /* Signed decimal integer. */
719 case 'i': /* Generic number. */
728 /* Check for a sign. */
729 if (c
== '-' || c
== '+')
737 /* Look for a leading indication of base. */
738 if (width
!= 0 && c
== '0')
746 if (width
!= 0 && tolower (c
) == 'x')
764 /* Read the number into workspace. */
765 while (c
!= EOF
&& width
!= 0)
767 if (base
== 16 ? !isxdigit (c
) :
768 ((!isdigit (c
) || c
- '0' >= base
) &&
769 !((flags
& GROUP
) && base
== 10 && c
== thousands
)))
778 /* The just read character is not part of the number anymore. */
782 (wpsize
== 1 && (wp
[0] == '+' || wp
[0] == '-')))
783 /* There was no number. */
786 /* Convert the number. */
791 num
.q
= __strtoq_internal (wp
, &tw
, base
, flags
& GROUP
);
793 num
.uq
= __strtouq_internal (wp
, &tw
, base
, flags
& GROUP
);
798 num
.l
= __strtol_internal (wp
, &tw
, base
, flags
& GROUP
);
800 num
.ul
= __strtoul_internal (wp
, &tw
, base
, flags
& GROUP
);
805 if (!(flags
& SUPPRESS
))
810 *ARG (unsigned LONGLONG
int *) = num
.uq
;
811 else if (flags
& LONG
)
812 *ARG (unsigned long int *) = num
.ul
;
813 else if (flags
& SHORT
)
814 *ARG (unsigned short int *)
815 = (unsigned short int) num
.ul
;
817 *ARG (unsigned int *) = (unsigned int) num
.ul
;
822 *ARG (LONGLONG
int *) = num
.q
;
823 else if (flags
& LONG
)
824 *ARG (long int *) = num
.l
;
825 else if (flags
& SHORT
)
826 *ARG (short int *) = (short int) num
.l
;
828 *ARG (int *) = (int) num
.l
;
834 case 'e': /* Floating-point numbers. */
843 /* Check for a sign. */
844 if (c
== '-' || c
== '+')
847 if (inchar () == EOF
)
848 /* EOF is only an input error before we read any chars. */
861 else if (got_e
&& wp
[wpsize
- 1] == 'e'
862 && (c
== '-' || c
== '+'))
864 else if (wpsize
> 0 && !got_e
&& tolower (c
) == 'e')
869 else if (c
== decimal
&& !got_dot
)
874 else if ((flags
& GROUP
) && c
== thousands
&& !got_dot
)
881 while (inchar () != EOF
&& width
!= 0);
883 /* The last read character is not part of the number anymore. */
889 /* Convert the number. */
893 long double d
= __strtold_internal (wp
, &tw
, flags
& GROUP
);
894 if (!(flags
& SUPPRESS
) && tw
!= wp
)
895 *ARG (long double *) = negative
? -d
: d
;
897 else if (flags
& LONG
)
899 double d
= __strtod_internal (wp
, &tw
, flags
& GROUP
);
900 if (!(flags
& SUPPRESS
) && tw
!= wp
)
901 *ARG (double *) = negative
? -d
: d
;
905 float d
= __strtof_internal (wp
, &tw
, flags
& GROUP
);
906 if (!(flags
& SUPPRESS
) && tw
!= wp
)
907 *ARG (float *) = negative
? -d
: d
;
913 if (!(flags
& SUPPRESS
))
917 case '[': /* Character class. */
920 STRING_ARG (wstr
, wchar_t);
921 c
= '\0'; /* This is to keep gcc quiet. */
925 STRING_ARG (str
, char);
940 /* Fill WP with byte flags indexed by character.
941 We will use this flag map for matching input characters. */
942 if (wpmax
< UCHAR_MAX
)
945 wp
= (char *) alloca (wpmax
);
947 memset (wp
, 0, UCHAR_MAX
);
950 if (fc
== ']' || fc
== '-')
952 /* If ] or - appears before any char in the set, it is not
953 the terminator or separator, but the first char in the
959 while ((fc
= *f
++) != '\0' && fc
!= ']')
961 if (fc
== '-' && *f
!= '\0' && *f
!= ']' &&
962 (unsigned char) f
[-2] <= (unsigned char) *f
)
964 /* Add all characters from the one before the '-'
965 up to (but not including) the next format char. */
966 for (fc
= f
[-2]; fc
< *f
; ++fc
)
970 /* Add the character to the flag map. */
988 NEXT_WIDE_CHAR (first
);
989 if (val
> 255 || wp
[val
] == not_in
)
991 /* XXX We have a problem here. We read a wide
992 character and this possibly took several
993 bytes. But we can only push back one single
994 character. To be sure we don't create wrong
995 input we push it back only in case it is
996 representable within one byte. */
1001 STRING_ADD_CHAR (wstr
, val
, wchar_t);
1011 if (!(flags
& SUPPRESS
))
1019 num
.ul
= read_in
- 1; /* -1 because we already read one char. */
1022 if (wp
[c
] == not_in
)
1027 STRING_ADD_CHAR (str
, c
, char);
1031 while (width
!= 0 && inchar () != EOF
);
1033 if (read_in
== num
.ul
)
1036 if (!(flags
& SUPPRESS
))
1044 case 'p': /* Generic pointer. */
1046 /* A PTR must be the same size as a `long int'. */
1047 flags
&= ~(SHORT
|LONGDBL
);
1054 /* The last thing we saw int the format string was a white space.
1055 Consume the last white spaces. */
1060 while (isspace (c
));
1064 /* Unlock stream. */
1072 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
1074 return _IO_vfscanf (s
, format
, argptr
, NULL
);
1078 weak_alias (__vfscanf
, vfscanf
)