2 Copyright (C) 1993 Free Software Foundation
4 This file is part of the GNU IO Library. This library is free
5 software; you can redistribute it and/or modify it under the
6 terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option)
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this library; see the file COPYING. If not, write to the Free
17 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 As a special exception, if you link this library with files
20 compiled with a GNU compiler to produce an executable, this does not cause
21 the resulting executable to be covered by the GNU General Public License.
22 This exception does not however invalidate any other reasons why
23 the executable file might be covered by the GNU General Public License. */
26 * Copyright (c) 1990 The Regents of the University of California.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms are permitted
30 * provided that the above copyright notice and this paragraph are
31 * duplicated in all such forms and that any documentation,
32 * advertising materials, and other materials related to such
33 * distribution and use acknowledge that the software was developed
34 * by the University of California, Berkeley. The name of the
35 * University may not be used to endorse or promote products derived
36 * from this software without specific prior written permission.
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
38 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
39 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
42 /* Extensively hacked for GNU iostream by Per Bothner 1991, 1992, 1993.
43 Changes copyright Free Software Foundation 1992, 1993. */
45 #if defined(LIBC_SCCS) && !defined(lint)
46 static char sccsid
[] = "%W% (Berkeley) %G%";
47 #endif /* LIBC_SCCS and not lint */
57 #ifndef NO_FLOATING_POINT
58 #define FLOATING_POINT
63 #define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
69 * Flags used during conversion.
71 #define LONG 0x01 /* l: long or double */
72 #define LONGDBL 0x02 /* L: long double; unimplemented */
73 #define SHORT 0x04 /* h: short */
74 #define SUPPRESS 0x08 /* suppress assignment */
75 #define POINTER 0x10 /* weird %p pointer (`fake hex') */
76 #define NOSKIP 0x20 /* do not skip blanks */
77 #define WIDTH 0x40 /* width */
80 * The following are used in numeric conversions only:
81 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
82 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
84 #define SIGNOK 0x40 /* +/- is (still) legal */
85 #define NDIGITS 0x80 /* no digits detected */
87 #define DPTOK 0x100 /* (float) decimal point is still legal */
88 #define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
90 #define PFXOK 0x100 /* 0x prefix is (still) legal */
91 #define NZDIGITS 0x200 /* no zero digits detected */
96 #define CT_CHAR 0 /* %c conversion */
97 #define CT_CCL 1 /* %[...] conversion */
98 #define CT_STRING 2 /* %s conversion */
99 #define CT_INT 3 /* integer, i.e., strtol or strtoul */
100 #define CT_FLOAT 4 /* floating, i.e., strtod */
102 #define u_char unsigned char
103 #define u_long unsigned long
108 extern u_long strtoul
__P((const char*, char**, int));
109 extern long strtol
__P((const char*, char**, int));
110 static const u_char
*__sccl
__P((char *tab
, const u_char
*fmt
));
112 extern double atof();
118 /* If errp != NULL, *errp|=1 if we see a premature EOF;
119 *errp|=2 if we an invalid character. */
122 _IO_vfscanf (fp
, fmt0
, ap
, errp
)
128 register const u_char
*fmt
= (const u_char
*)fmt0
;
129 register int c
; /* character from format, or conversion */
130 register _IO_ssize_t width
; /* field width, or 0 */
131 register char *p
; /* points into all kinds of strings */
132 register int n
; /* handy integer */
133 register int flags
= 0; /* flags as defined above */
134 register char *p0
; /* saves original value of p when necessary */
135 int nassigned
; /* number of fields assigned */
136 int nread
; /* number of characters consumed from fp */
137 /* Assignments to base and ccfn are just to suppress warnings from gcc.*/
138 int base
= 0; /* base argument to strtol/strtoul */
139 typedef u_long (*strtoulfn
) __P((const char*, char**, int));
141 /* conversion function (strtol/strtoul) */
142 char ccltab
[256]; /* character class table for %[...] */
143 char buf
[BUF
]; /* buffer for numeric conversions */
146 /* `basefix' is used to avoid `if' tests in the integer scanner */
147 static short basefix
[17] =
148 { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
176 * switch on the format. continue if done;
177 * break once format type is derived.
194 if (flags
) goto control_failure
;
198 if (flags
& ~(SUPPRESS
| WIDTH
)) goto control_failure
;
202 if (flags
& ~(SUPPRESS
| WIDTH
)) goto control_failure
;
206 if (flags
& ~(SUPPRESS
| WIDTH
)) goto control_failure
;
210 case '0': case '1': case '2': case '3': case '4':
211 case '5': case '6': case '7': case '8': case '9':
212 if (flags
& ~(SUPPRESS
| WIDTH
)) goto control_failure
;
214 width
= width
* 10 + c
- '0';
219 * Those marked `compat' are for 4.[123]BSD compatibility.
221 * (According to ANSI, E and X formats are supposed
222 * to the same as e and x. Sorry about that.)
224 case 'D': /* compat */
229 ccfn
= (strtoulfn
)strtol
;
235 ccfn
= (strtoulfn
)strtol
;
239 case 'O': /* compat */
256 flags
|= PFXOK
; /* enable 0x prefixing */
262 #ifdef FLOATING_POINT
264 case 'e': case 'f': case 'g':
274 fmt
= __sccl(ccltab
, fmt
);
284 case 'p': /* pointer format is like hex */
285 flags
|= POINTER
| PFXOK
;
292 if (flags
& SUPPRESS
) /* ??? */
295 *va_arg(ap
, short *) = nread
;
296 else if (flags
& LONG
)
297 *va_arg(ap
, long *) = nread
;
299 *va_arg(ap
, int *) = nread
;
303 * Disgusting backwards compatibility hacks. XXX
305 case '\0': /* compat */
309 default: /* compat */
313 ccfn
= (strtoulfn
)strtol
;
319 * We have a conversion that requires input.
321 if (_IO_peekc(fp
) == EOF
)
325 * Consume leading white space, except for formats
326 * that suppress this.
328 if ((flags
& NOSKIP
) == 0) {
329 n
= (unsigned char)*fp
->_IO_read_ptr
;
337 /* Note that there is at least one character in
338 the buffer, so conversions that do not set NOSKIP
339 can no longer result in an input failure. */
348 /* scan arbitrary characters (sets NOSKIP) */
349 if (width
== 0) /* FIXME! */
351 if (flags
& SUPPRESS
) {
354 n
= fp
->_IO_read_end
- fp
->_IO_read_ptr
;
355 if (n
< (int)width
) {
358 fp
->_IO_read_ptr
+= n
;
359 if (__underflow(fp
) == EOF
)
368 fp
->_IO_read_ptr
+= width
;
376 _IO_XSGETN (fp
, (char*)va_arg(ap
, char*), width
);
385 /* scan a (nonempty) character class (sets NOSKIP) */
387 width
= ~0; /* `infinity' */
388 /* take only those things in the class */
389 if (flags
& SUPPRESS
) {
391 while (ccltab
[(unsigned char)*fp
->_IO_read_ptr
]) {
392 n
++, fp
->_IO_read_ptr
++;
395 if (_IO_peekc(fp
) == EOF
) {
405 p0
= p
= va_arg(ap
, char *);
406 while (ccltab
[(unsigned char)*fp
->_IO_read_ptr
]) {
407 *p
++ = *fp
->_IO_read_ptr
++;
410 if (_IO_peekc(fp
) == EOF
) {
427 /* like CCL, but zero-length string OK, & no NOSKIP */
430 if (flags
& SUPPRESS
) {
432 while (!isspace((unsigned char)*fp
->_IO_read_ptr
)) {
433 n
++, fp
->_IO_read_ptr
++;
436 if (_IO_peekc(fp
) == EOF
) {
443 p0
= p
= va_arg(ap
, char *);
444 while (!isspace((unsigned char)*fp
->_IO_read_ptr
)) {
445 *p
++ = *fp
->_IO_read_ptr
++;
448 if (_IO_peekc(fp
) == EOF
) {
460 /* scan an integer as if by strtol/strtoul */
461 if (width
== 0 || width
> sizeof(buf
) - 1)
462 width
= sizeof(buf
) - 1;
463 flags
|= SIGNOK
| NDIGITS
| NZDIGITS
;
464 for (p
= buf
; width
; width
--) {
465 c
= (unsigned char)*fp
->_IO_read_ptr
;
467 * Switch on the character; `goto ok'
468 * if we accept it as a part of number.
473 * The digit 0 is always legal, but is
474 * special. For %i conversions, if no
475 * digits (zero or nonzero) have been
476 * scanned (only signs), we will have
477 * base==0. In that case, we should set
478 * it to 8 and enable 0x prefixing.
479 * Also, if we have not scanned zero digits
480 * before this, do not turn off prefixing
481 * (someone else will turn it off if we
482 * have scanned any nonzero digits).
489 if (flags
& NZDIGITS
)
490 flags
&= ~(SIGNOK
|NZDIGITS
|NDIGITS
);
492 flags
&= ~(SIGNOK
|PFXOK
|NDIGITS
);
495 /* 1 through 7 always legal */
496 case '1': case '2': case '3':
497 case '4': case '5': case '6': case '7':
498 base
= basefix
[base
];
499 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
502 /* digits 8 and 9 ok iff decimal or hex */
504 base
= basefix
[base
];
506 break; /* not legal here */
507 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
510 /* letters ok iff hex */
511 case 'A': case 'B': case 'C':
512 case 'D': case 'E': case 'F':
513 case 'a': case 'b': case 'c':
514 case 'd': case 'e': case 'f':
515 /* no need to fix base here */
517 break; /* not legal here */
518 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
521 /* sign ok only as first character */
523 if (flags
& SIGNOK
) {
529 /* x ok iff flag still set & 2nd char */
531 if (flags
& PFXOK
&& p
== buf
+ 1) {
532 base
= 16; /* if %i */
540 * If we got here, c is not a legal character
541 * for a number. Stop accumulating digits.
546 * c is legal: store it and look at the next.
550 if (_IO_peekc(fp
) == EOF
) {
556 * If we had only a sign, it is no good; push
557 * back the sign. If the number ends in `x',
558 * it was [sign] '0' 'x', so push back the x
559 * and treat it as [sign] '0'.
561 if (flags
& NDIGITS
) {
563 (void) _IO_ungetc(*(u_char
*)--p
, fp
);
566 c
= ((u_char
*)p
)[-1];
567 if (c
== 'x' || c
== 'X') {
569 (void) _IO_ungetc (c
, fp
);
571 if ((flags
& SUPPRESS
) == 0) {
575 res
= (*ccfn
)(buf
, (char **)NULL
, base
);
577 *va_arg(ap
, void **) = (void *)res
;
578 else if (flags
& SHORT
)
579 *va_arg(ap
, short *) = res
;
580 else if (flags
& LONG
)
581 *va_arg(ap
, long *) = res
;
583 *va_arg(ap
, int *) = res
;
589 #ifdef FLOATING_POINT
591 /* scan a floating point number as if by strtod */
592 if (width
== 0 || width
> sizeof(buf
) - 1)
593 width
= sizeof(buf
) - 1;
594 flags
|= SIGNOK
| NDIGITS
| DPTOK
| EXPOK
;
595 for (p
= buf
; width
; width
--) {
596 c
= (unsigned char)*fp
->_IO_read_ptr
;
598 * This code mimicks the integer conversion
599 * code, but is much simpler.
603 case '0': case '1': case '2': case '3':
604 case '4': case '5': case '6': case '7':
606 flags
&= ~(SIGNOK
| NDIGITS
);
610 if (flags
& SIGNOK
) {
617 flags
&= ~(SIGNOK
| DPTOK
);
622 /* no exponent without some digits */
623 if ((flags
&(NDIGITS
|EXPOK
)) == EXPOK
) {
625 (flags
& ~(EXPOK
|DPTOK
)) |
635 if (_IO_peekc(fp
) == EOF
) {
641 * If no digits, might be missing exponent digits
642 * (just give back the exponent) or might be missing
643 * regular digits, but had sign and/or decimal point.
645 if (flags
& NDIGITS
) {
647 /* no digits at all */
649 _IO_ungetc (*(u_char
*)--p
, fp
);
652 /* just a bad exponent (e and maybe sign) */
654 if (c
!= 'e' && c
!= 'E') {
655 (void) _IO_ungetc (c
, fp
);/* sign */
658 (void) _IO_ungetc (c
, fp
);
660 if ((flags
& SUPPRESS
) == 0) {
664 res
= _IO_strtod(buf
, NULL
);
669 *va_arg(ap
, double *) = res
;
671 *va_arg(ap
, float *) = res
;
676 #endif /* FLOATING_POINT */
689 if (errp
&& seen_eof
)
695 * Fill in the given table from the scanset at the given format
696 * (just after `['). Return a pointer to the character past the
697 * closing `]'. The table has a 1 wherever characters should be
698 * considered part of the scanset.
700 static const u_char
*
705 register int c
, n
, v
;
707 /* first `clear' the whole table */
708 c
= *fmt
++; /* first char hat => negated scanset */
710 v
= 1; /* default => accept */
711 c
= *fmt
++; /* get new first char */
713 v
= 0; /* default => reject */
714 /* should probably use memset here */
715 for (n
= 0; n
< 256; n
++)
718 return (fmt
- 1);/* format ended before closing ] */
721 * Now set the entries corresponding to the actual scanset
722 * to the opposite of the above.
724 * The first character may be ']' (or '-') without being special;
725 * the last character may be '-'.
729 tab
[c
] = v
; /* take character c */
731 n
= *fmt
++; /* and examine the next */
734 case 0: /* format ended too soon */
739 * A scanset of the form
741 * is defined as `the digit 0, the digit 1,
742 * the character +, the character -', but
743 * the effect of a scanset such as
745 * is implementation defined. The V7 Unix
746 * scanf treats `a-z' as `the letters a through
747 * z', but treats `a-a' as `the letter a, the
748 * character -, and the letter a'.
750 * For compatibility, the `-' is not considerd
751 * to define a range if the character following
752 * it is either a close bracket (required by ANSI)
753 * or is not numerically greater than the character
754 * we just stored in the table (c).
757 if (n
== ']' || n
< c
) {
759 break; /* resume the for(;;) */
762 do { /* fill in the range */
765 #if 1 /* XXX another disgusting compatibility hack */
767 * Alas, the V7 Unix scanf also treats formats
768 * such as [a-c-e] as `the letters a through e'.
769 * This too is permitted by the standard....
781 case ']': /* end of scanset */
784 default: /* just another character */