1 /*-
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * and/or other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 /*
19  * Copyright (c) 2012-2014 ARM Ltd
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. The name of the company may not be used to endorse or promote
31  *    products derived from this software without specific prior written
32  *    permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
36  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
37  * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
39  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  */
45 
46 #ifndef VFSCANF_LOCAL
47 #define VFSCANF_LOCAL
48 
49 #ifndef NO_FLOATING_POINT
50 #define FLOATING_POINT
51 #endif
52 
53 #ifdef STRING_ONLY
54 #undef _newlib_flockfile_start
55 #undef _newlib_flockfile_exit
56 #undef _newlib_flockfile_end
57 #define _newlib_flockfile_start(x) {}
58 #define _newlib_flockfile_exit(x) {}
59 #define _newlib_flockfile_end(x) {}
60 #define ungetc sungetc
61 #define _srefill _ssrefill
62 #endif
63 
64 #ifdef FLOATING_POINT
65 #include <math.h>
66 #include <float.h>
67 
68 /* Currently a test is made to see if long double processing is warranted.
69    This could be changed in the future should the __ldtoa code be
70    preferred over __dtoa.  */
71 #define _NO_LONGDBL
72 
73 #include "floatio.h"
74 
75 #if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
76 /* "3 = sign + decimal point + NUL".  */
77 # define BUF (MAXEXP+MAXFRACT+3)
78 #else
79 # define BUF MB_LEN_MAX
80 #endif
81 
82 /* An upper bound for how long a long prints in decimal.  4 / 13 approximates
83    log (2).  Add one char for roundoff compensation and one for the sign.  */
84 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long)  - 1) * 4 / 13 + 2)
85 #else
86 #define	BUF	40
87 #endif
88 
89 
90 #define _NO_LONGLONG
91 #undef _WANT_IO_C99_FORMATS
92 #undef _WANT_IO_POS_ARGS
93 
94 #define _NO_POS_ARGS
95 
96 /* Macros for converting digits to letters and vice versa.  */
97 #define	to_digit(c)	((c) - '0')
98 #define is_digit(c)	((unsigned)to_digit (c) <= 9)
99 #define	to_char(n)	((n) + '0')
100 
101 /*
102  * Flags used during conversion.
103  */
104 
105 #define	SHORT		0x01	/* "h": short.  */
106 #define	LONG		0x02	/* "l": long or double.  */
107 #define	LONGDBL		0x04	/* "L/ll": long double or long long.  */
108 #define CHAR		0x08	/* "hh": 8 bit integer.  */
109 #define	SUPPRESS	0x10	/* Suppress assignment.  */
110 #define	POINTER		0x20	/* Weird %p pointer (`fake hex').  */
111 #define	NOSKIP		0x40	/* Do not skip blanks */
112 
113 /* The following are used in numeric conversions only:
114    SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
115    SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.  */
116 
117 #define	SIGNOK		0x80	/* "+/-" is (still) legal.  */
118 #define	NDIGITS		0x100	/* No digits detected.  */
119 
120 #define	DPTOK		0x200	/* (Float) decimal point is still legal.  */
121 #define	EXPOK		0x400	/* (Float) exponent (e+3, etc) still legal.  */
122 
123 #define	PFXOK		0x200	/* "0x" prefix is (still) legal.  */
124 #define	NZDIGITS	0x400	/* No zero digits detected.  */
125 #define	NNZDIGITS	0x800	/* No non-zero digits detected.  */
126 
127 /* Conversion types.  */
128 
129 #define	CT_CHAR		0	/* "%c" conversion.  */
130 #define	CT_CCL		1	/* "%[...]" conversion.  */
131 #define	CT_STRING	2	/* "%s" conversion.  */
132 #define	CT_INT		3	/* Integer, i.e., strtol.  */
133 #define	CT_UINT		4	/* Unsigned integer, i.e., strtoul.  */
134 #define	CT_FLOAT	5	/* Floating, i.e., strtod.  */
135 
136 #define u_char unsigned char
137 #define u_long unsigned long
138 
139 /* Macro to support positional arguments.  */
140 #define GET_ARG(n, ap, type) (va_arg ((ap), type))
141 
142 #define MATCH_FAILURE	1
143 #define INPUT_FAILURE	2
144 
145 
146 /* All data needed to decode format string are kept in below struct.  */
147 struct _scan_data_t
148 {
149   int flags;            /* Flags.  */
150   int base;             /* Base.  */
151   size_t width;         /* Width.  */
152   int nassigned;        /* Number of assignments so far.  */
153   int nread;            /* Number of chars read so far.  */
154   char *ccltab;         /* Table used for [ format.  */
155   int code;             /* Current conversion specifier.  */
156   char buf[BUF];        /* Internal buffer for scan.  */
157   /* Internal buffer for scan.  */
158   int (*pfn_ungetc)(int, FILE*);
159   /* Internal buffer for scan.  */
160   int (*pfn_refill)(FILE*);
161 };
162 
163 extern int
164 _scanf_chars (
165 	      struct _scan_data_t *pdata,
166 	      FILE *fp, va_list *ap);
167 extern int
168 _scanf_i (
169 	  struct _scan_data_t *pdata,
170 	  FILE *fp, va_list *ap);
171 /* Make _scanf_float weak symbol, so it won't be linked in if target program
172    does not need it.  */
173 extern int
174 _scanf_float (
175 	      struct _scan_data_t *pdata,
176 	      FILE *fp, va_list *ap) _ATTRIBUTE((__weak__));
177 
178 #endif
179