1*8d67ca89SAndroid Build Coastguard Worker /* $OpenBSD: vfwscanf.c,v 1.4 2014/03/19 05:17:01 guenther Exp $ */
2*8d67ca89SAndroid Build Coastguard Worker /*-
3*8d67ca89SAndroid Build Coastguard Worker * Copyright (c) 1990, 1993
4*8d67ca89SAndroid Build Coastguard Worker * The Regents of the University of California. All rights reserved.
5*8d67ca89SAndroid Build Coastguard Worker *
6*8d67ca89SAndroid Build Coastguard Worker * This code is derived from software contributed to Berkeley by
7*8d67ca89SAndroid Build Coastguard Worker * Chris Torek.
8*8d67ca89SAndroid Build Coastguard Worker *
9*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
10*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
11*8d67ca89SAndroid Build Coastguard Worker * are met:
12*8d67ca89SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
13*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
14*8d67ca89SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
15*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
16*8d67ca89SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
17*8d67ca89SAndroid Build Coastguard Worker * 3. Neither the name of the University nor the names of its contributors
18*8d67ca89SAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
19*8d67ca89SAndroid Build Coastguard Worker * without specific prior written permission.
20*8d67ca89SAndroid Build Coastguard Worker *
21*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*8d67ca89SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*8d67ca89SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*8d67ca89SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*8d67ca89SAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*8d67ca89SAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*8d67ca89SAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*8d67ca89SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*8d67ca89SAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*8d67ca89SAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
32*8d67ca89SAndroid Build Coastguard Worker */
33*8d67ca89SAndroid Build Coastguard Worker
34*8d67ca89SAndroid Build Coastguard Worker #include "scanf_common.h"
35*8d67ca89SAndroid Build Coastguard Worker
36*8d67ca89SAndroid Build Coastguard Worker // An interpretive version of __sccl from vfscanf.c --- a table of all wchar_t values would
37*8d67ca89SAndroid Build Coastguard Worker // be a little too expensive, and some kind of compressed version isn't worth the trouble.
in_ccl(wchar_t wc,const wchar_t * ccl)38*8d67ca89SAndroid Build Coastguard Worker static inline bool in_ccl(wchar_t wc, const wchar_t* ccl) {
39*8d67ca89SAndroid Build Coastguard Worker // Is this a negated set?
40*8d67ca89SAndroid Build Coastguard Worker bool member_result = true;
41*8d67ca89SAndroid Build Coastguard Worker if (*ccl == '^') {
42*8d67ca89SAndroid Build Coastguard Worker member_result = false;
43*8d67ca89SAndroid Build Coastguard Worker ++ccl;
44*8d67ca89SAndroid Build Coastguard Worker }
45*8d67ca89SAndroid Build Coastguard Worker
46*8d67ca89SAndroid Build Coastguard Worker // The first character may be ']' or '-' without being special.
47*8d67ca89SAndroid Build Coastguard Worker if (*ccl == '-' || *ccl == ']') {
48*8d67ca89SAndroid Build Coastguard Worker // A literal match?
49*8d67ca89SAndroid Build Coastguard Worker if (*ccl == wc) return member_result;
50*8d67ca89SAndroid Build Coastguard Worker ++ccl;
51*8d67ca89SAndroid Build Coastguard Worker }
52*8d67ca89SAndroid Build Coastguard Worker
53*8d67ca89SAndroid Build Coastguard Worker while (*ccl && *ccl != ']') {
54*8d67ca89SAndroid Build Coastguard Worker // The last character may be '-' without being special.
55*8d67ca89SAndroid Build Coastguard Worker if (*ccl == '-' && ccl[1] != '\0' && ccl[1] != ']') {
56*8d67ca89SAndroid Build Coastguard Worker wchar_t first = *(ccl - 1);
57*8d67ca89SAndroid Build Coastguard Worker wchar_t last = *(ccl + 1);
58*8d67ca89SAndroid Build Coastguard Worker if (first <= last) {
59*8d67ca89SAndroid Build Coastguard Worker // In the range?
60*8d67ca89SAndroid Build Coastguard Worker if (wc >= first && wc <= last) return member_result;
61*8d67ca89SAndroid Build Coastguard Worker ccl += 2;
62*8d67ca89SAndroid Build Coastguard Worker continue;
63*8d67ca89SAndroid Build Coastguard Worker }
64*8d67ca89SAndroid Build Coastguard Worker // A '-' is not considered to be part of a range if the character after
65*8d67ca89SAndroid Build Coastguard Worker // is not greater than the character before, so fall through...
66*8d67ca89SAndroid Build Coastguard Worker }
67*8d67ca89SAndroid Build Coastguard Worker // A literal match?
68*8d67ca89SAndroid Build Coastguard Worker if (*ccl == wc) return member_result;
69*8d67ca89SAndroid Build Coastguard Worker ++ccl;
70*8d67ca89SAndroid Build Coastguard Worker }
71*8d67ca89SAndroid Build Coastguard Worker return !member_result;
72*8d67ca89SAndroid Build Coastguard Worker }
73*8d67ca89SAndroid Build Coastguard Worker
74*8d67ca89SAndroid Build Coastguard Worker #pragma GCC diagnostic push
75*8d67ca89SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wframe-larger-than="
76*8d67ca89SAndroid Build Coastguard Worker
77*8d67ca89SAndroid Build Coastguard Worker /*
78*8d67ca89SAndroid Build Coastguard Worker * vfwscanf
79*8d67ca89SAndroid Build Coastguard Worker */
__vfwscanf(FILE * __restrict fp,const wchar_t * __restrict fmt,__va_list ap)80*8d67ca89SAndroid Build Coastguard Worker int __vfwscanf(FILE* __restrict fp, const wchar_t* __restrict fmt, __va_list ap) {
81*8d67ca89SAndroid Build Coastguard Worker wint_t c; /* character from format, or conversion */
82*8d67ca89SAndroid Build Coastguard Worker size_t width; /* field width, or 0 */
83*8d67ca89SAndroid Build Coastguard Worker wchar_t* p; /* points into all kinds of strings */
84*8d67ca89SAndroid Build Coastguard Worker int n; /* handy integer */
85*8d67ca89SAndroid Build Coastguard Worker int flags; /* flags as defined above */
86*8d67ca89SAndroid Build Coastguard Worker wchar_t* p0; /* saves original value of p when necessary */
87*8d67ca89SAndroid Build Coastguard Worker int nassigned; /* number of fields assigned */
88*8d67ca89SAndroid Build Coastguard Worker int nconversions; /* number of conversions */
89*8d67ca89SAndroid Build Coastguard Worker int nread; /* number of characters consumed from fp */
90*8d67ca89SAndroid Build Coastguard Worker int base; /* base argument to strtoimax/strtouimax */
91*8d67ca89SAndroid Build Coastguard Worker wchar_t buf[BUF]; /* buffer for numeric conversions */
92*8d67ca89SAndroid Build Coastguard Worker const wchar_t* ccl;
93*8d67ca89SAndroid Build Coastguard Worker wint_t wi; /* handy wint_t */
94*8d67ca89SAndroid Build Coastguard Worker char* mbp; /* multibyte string pointer for %c %s %[ */
95*8d67ca89SAndroid Build Coastguard Worker size_t nconv; /* number of bytes in mb. conversion */
96*8d67ca89SAndroid Build Coastguard Worker char mbbuf[MB_LEN_MAX]; /* temporary mb. character buffer */
97*8d67ca89SAndroid Build Coastguard Worker mbstate_t mbs;
98*8d67ca89SAndroid Build Coastguard Worker
99*8d67ca89SAndroid Build Coastguard Worker _SET_ORIENTATION(fp, ORIENT_CHARS);
100*8d67ca89SAndroid Build Coastguard Worker
101*8d67ca89SAndroid Build Coastguard Worker nassigned = 0;
102*8d67ca89SAndroid Build Coastguard Worker nconversions = 0;
103*8d67ca89SAndroid Build Coastguard Worker nread = 0;
104*8d67ca89SAndroid Build Coastguard Worker base = 0; /* XXX just to keep gcc happy */
105*8d67ca89SAndroid Build Coastguard Worker for (;;) {
106*8d67ca89SAndroid Build Coastguard Worker c = *fmt++;
107*8d67ca89SAndroid Build Coastguard Worker if (c == 0) {
108*8d67ca89SAndroid Build Coastguard Worker return (nassigned);
109*8d67ca89SAndroid Build Coastguard Worker }
110*8d67ca89SAndroid Build Coastguard Worker if (iswspace(c)) {
111*8d67ca89SAndroid Build Coastguard Worker while ((c = __fgetwc_unlock(fp)) != WEOF && iswspace(c))
112*8d67ca89SAndroid Build Coastguard Worker ;
113*8d67ca89SAndroid Build Coastguard Worker if (c != WEOF) __ungetwc(c, fp);
114*8d67ca89SAndroid Build Coastguard Worker continue;
115*8d67ca89SAndroid Build Coastguard Worker }
116*8d67ca89SAndroid Build Coastguard Worker if (c != '%') goto literal;
117*8d67ca89SAndroid Build Coastguard Worker width = 0;
118*8d67ca89SAndroid Build Coastguard Worker flags = 0;
119*8d67ca89SAndroid Build Coastguard Worker /*
120*8d67ca89SAndroid Build Coastguard Worker * switch on the format. continue if done;
121*8d67ca89SAndroid Build Coastguard Worker * break once format type is derived.
122*8d67ca89SAndroid Build Coastguard Worker */
123*8d67ca89SAndroid Build Coastguard Worker again:
124*8d67ca89SAndroid Build Coastguard Worker c = *fmt++;
125*8d67ca89SAndroid Build Coastguard Worker reswitch:
126*8d67ca89SAndroid Build Coastguard Worker switch (c) {
127*8d67ca89SAndroid Build Coastguard Worker case '%':
128*8d67ca89SAndroid Build Coastguard Worker literal:
129*8d67ca89SAndroid Build Coastguard Worker if ((wi = __fgetwc_unlock(fp)) == WEOF) goto input_failure;
130*8d67ca89SAndroid Build Coastguard Worker if (wi != c) {
131*8d67ca89SAndroid Build Coastguard Worker __ungetwc(wi, fp);
132*8d67ca89SAndroid Build Coastguard Worker goto match_failure;
133*8d67ca89SAndroid Build Coastguard Worker }
134*8d67ca89SAndroid Build Coastguard Worker nread++;
135*8d67ca89SAndroid Build Coastguard Worker continue;
136*8d67ca89SAndroid Build Coastguard Worker
137*8d67ca89SAndroid Build Coastguard Worker case '*':
138*8d67ca89SAndroid Build Coastguard Worker flags |= SUPPRESS;
139*8d67ca89SAndroid Build Coastguard Worker goto again;
140*8d67ca89SAndroid Build Coastguard Worker case 'j':
141*8d67ca89SAndroid Build Coastguard Worker flags |= MAXINT;
142*8d67ca89SAndroid Build Coastguard Worker goto again;
143*8d67ca89SAndroid Build Coastguard Worker case 'L':
144*8d67ca89SAndroid Build Coastguard Worker flags |= LONGDBL;
145*8d67ca89SAndroid Build Coastguard Worker goto again;
146*8d67ca89SAndroid Build Coastguard Worker case 'h':
147*8d67ca89SAndroid Build Coastguard Worker if (*fmt == 'h') {
148*8d67ca89SAndroid Build Coastguard Worker fmt++;
149*8d67ca89SAndroid Build Coastguard Worker flags |= SHORTSHORT;
150*8d67ca89SAndroid Build Coastguard Worker } else {
151*8d67ca89SAndroid Build Coastguard Worker flags |= SHORT;
152*8d67ca89SAndroid Build Coastguard Worker }
153*8d67ca89SAndroid Build Coastguard Worker goto again;
154*8d67ca89SAndroid Build Coastguard Worker case 'l':
155*8d67ca89SAndroid Build Coastguard Worker if (*fmt == 'l') {
156*8d67ca89SAndroid Build Coastguard Worker fmt++;
157*8d67ca89SAndroid Build Coastguard Worker flags |= LLONG;
158*8d67ca89SAndroid Build Coastguard Worker } else {
159*8d67ca89SAndroid Build Coastguard Worker flags |= LONG;
160*8d67ca89SAndroid Build Coastguard Worker }
161*8d67ca89SAndroid Build Coastguard Worker goto again;
162*8d67ca89SAndroid Build Coastguard Worker case 'q':
163*8d67ca89SAndroid Build Coastguard Worker flags |= LLONG; /* deprecated */
164*8d67ca89SAndroid Build Coastguard Worker goto again;
165*8d67ca89SAndroid Build Coastguard Worker case 't':
166*8d67ca89SAndroid Build Coastguard Worker flags |= PTRINT;
167*8d67ca89SAndroid Build Coastguard Worker goto again;
168*8d67ca89SAndroid Build Coastguard Worker case 'z':
169*8d67ca89SAndroid Build Coastguard Worker flags |= SIZEINT;
170*8d67ca89SAndroid Build Coastguard Worker goto again;
171*8d67ca89SAndroid Build Coastguard Worker
172*8d67ca89SAndroid Build Coastguard Worker case '0':
173*8d67ca89SAndroid Build Coastguard Worker case '1':
174*8d67ca89SAndroid Build Coastguard Worker case '2':
175*8d67ca89SAndroid Build Coastguard Worker case '3':
176*8d67ca89SAndroid Build Coastguard Worker case '4':
177*8d67ca89SAndroid Build Coastguard Worker case '5':
178*8d67ca89SAndroid Build Coastguard Worker case '6':
179*8d67ca89SAndroid Build Coastguard Worker case '7':
180*8d67ca89SAndroid Build Coastguard Worker case '8':
181*8d67ca89SAndroid Build Coastguard Worker case '9':
182*8d67ca89SAndroid Build Coastguard Worker width = width * 10 + c - '0';
183*8d67ca89SAndroid Build Coastguard Worker goto again;
184*8d67ca89SAndroid Build Coastguard Worker
185*8d67ca89SAndroid Build Coastguard Worker /*
186*8d67ca89SAndroid Build Coastguard Worker * Conversions.
187*8d67ca89SAndroid Build Coastguard Worker * Those marked `compat' are for 4.[123]BSD compatibility.
188*8d67ca89SAndroid Build Coastguard Worker */
189*8d67ca89SAndroid Build Coastguard Worker case 'b':
190*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
191*8d67ca89SAndroid Build Coastguard Worker base = 2;
192*8d67ca89SAndroid Build Coastguard Worker flags |= PFBOK; /* enable 0b prefixing */
193*8d67ca89SAndroid Build Coastguard Worker break;
194*8d67ca89SAndroid Build Coastguard Worker
195*8d67ca89SAndroid Build Coastguard Worker case 'D': /* compat */
196*8d67ca89SAndroid Build Coastguard Worker flags |= LONG;
197*8d67ca89SAndroid Build Coastguard Worker __BIONIC_FALLTHROUGH;
198*8d67ca89SAndroid Build Coastguard Worker case 'd':
199*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
200*8d67ca89SAndroid Build Coastguard Worker base = 10;
201*8d67ca89SAndroid Build Coastguard Worker break;
202*8d67ca89SAndroid Build Coastguard Worker
203*8d67ca89SAndroid Build Coastguard Worker case 'i':
204*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
205*8d67ca89SAndroid Build Coastguard Worker base = 0;
206*8d67ca89SAndroid Build Coastguard Worker break;
207*8d67ca89SAndroid Build Coastguard Worker
208*8d67ca89SAndroid Build Coastguard Worker case 'O': /* compat */
209*8d67ca89SAndroid Build Coastguard Worker flags |= LONG;
210*8d67ca89SAndroid Build Coastguard Worker __BIONIC_FALLTHROUGH;
211*8d67ca89SAndroid Build Coastguard Worker case 'o':
212*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
213*8d67ca89SAndroid Build Coastguard Worker flags |= UNSIGNED;
214*8d67ca89SAndroid Build Coastguard Worker base = 8;
215*8d67ca89SAndroid Build Coastguard Worker break;
216*8d67ca89SAndroid Build Coastguard Worker
217*8d67ca89SAndroid Build Coastguard Worker case 'u':
218*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
219*8d67ca89SAndroid Build Coastguard Worker flags |= UNSIGNED;
220*8d67ca89SAndroid Build Coastguard Worker base = 10;
221*8d67ca89SAndroid Build Coastguard Worker break;
222*8d67ca89SAndroid Build Coastguard Worker
223*8d67ca89SAndroid Build Coastguard Worker case 'w': {
224*8d67ca89SAndroid Build Coastguard Worker int size = 0;
225*8d67ca89SAndroid Build Coastguard Worker bool fast = false;
226*8d67ca89SAndroid Build Coastguard Worker c = *fmt++;
227*8d67ca89SAndroid Build Coastguard Worker if (c == 'f') {
228*8d67ca89SAndroid Build Coastguard Worker fast = true;
229*8d67ca89SAndroid Build Coastguard Worker c = *fmt++;
230*8d67ca89SAndroid Build Coastguard Worker }
231*8d67ca89SAndroid Build Coastguard Worker while (is_digit(c)) {
232*8d67ca89SAndroid Build Coastguard Worker APPEND_DIGIT(size, c);
233*8d67ca89SAndroid Build Coastguard Worker c = *fmt++;
234*8d67ca89SAndroid Build Coastguard Worker }
235*8d67ca89SAndroid Build Coastguard Worker flags |= w_to_flag(size, fast);
236*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
237*8d67ca89SAndroid Build Coastguard Worker }
238*8d67ca89SAndroid Build Coastguard Worker
239*8d67ca89SAndroid Build Coastguard Worker case 'X':
240*8d67ca89SAndroid Build Coastguard Worker case 'x':
241*8d67ca89SAndroid Build Coastguard Worker flags |= PFXOK; /* enable 0x prefixing */
242*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
243*8d67ca89SAndroid Build Coastguard Worker flags |= UNSIGNED;
244*8d67ca89SAndroid Build Coastguard Worker base = 16;
245*8d67ca89SAndroid Build Coastguard Worker break;
246*8d67ca89SAndroid Build Coastguard Worker
247*8d67ca89SAndroid Build Coastguard Worker case 'e':
248*8d67ca89SAndroid Build Coastguard Worker case 'E':
249*8d67ca89SAndroid Build Coastguard Worker case 'f':
250*8d67ca89SAndroid Build Coastguard Worker case 'F':
251*8d67ca89SAndroid Build Coastguard Worker case 'g':
252*8d67ca89SAndroid Build Coastguard Worker case 'G':
253*8d67ca89SAndroid Build Coastguard Worker case 'a':
254*8d67ca89SAndroid Build Coastguard Worker case 'A':
255*8d67ca89SAndroid Build Coastguard Worker c = CT_FLOAT;
256*8d67ca89SAndroid Build Coastguard Worker break;
257*8d67ca89SAndroid Build Coastguard Worker
258*8d67ca89SAndroid Build Coastguard Worker case 's':
259*8d67ca89SAndroid Build Coastguard Worker c = CT_STRING;
260*8d67ca89SAndroid Build Coastguard Worker break;
261*8d67ca89SAndroid Build Coastguard Worker
262*8d67ca89SAndroid Build Coastguard Worker case '[':
263*8d67ca89SAndroid Build Coastguard Worker ccl = fmt;
264*8d67ca89SAndroid Build Coastguard Worker if (*fmt == '^') fmt++;
265*8d67ca89SAndroid Build Coastguard Worker if (*fmt == ']') fmt++;
266*8d67ca89SAndroid Build Coastguard Worker while (*fmt != '\0' && *fmt != ']') fmt++;
267*8d67ca89SAndroid Build Coastguard Worker fmt++;
268*8d67ca89SAndroid Build Coastguard Worker flags |= NOSKIP;
269*8d67ca89SAndroid Build Coastguard Worker c = CT_CCL;
270*8d67ca89SAndroid Build Coastguard Worker break;
271*8d67ca89SAndroid Build Coastguard Worker
272*8d67ca89SAndroid Build Coastguard Worker case 'c':
273*8d67ca89SAndroid Build Coastguard Worker flags |= NOSKIP;
274*8d67ca89SAndroid Build Coastguard Worker c = CT_CHAR;
275*8d67ca89SAndroid Build Coastguard Worker break;
276*8d67ca89SAndroid Build Coastguard Worker
277*8d67ca89SAndroid Build Coastguard Worker case 'p': /* pointer format is like hex */
278*8d67ca89SAndroid Build Coastguard Worker flags |= POINTER | PFXOK;
279*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
280*8d67ca89SAndroid Build Coastguard Worker flags |= UNSIGNED;
281*8d67ca89SAndroid Build Coastguard Worker base = 16;
282*8d67ca89SAndroid Build Coastguard Worker break;
283*8d67ca89SAndroid Build Coastguard Worker
284*8d67ca89SAndroid Build Coastguard Worker case 'n':
285*8d67ca89SAndroid Build Coastguard Worker nconversions++;
286*8d67ca89SAndroid Build Coastguard Worker if (flags & SUPPRESS) continue;
287*8d67ca89SAndroid Build Coastguard Worker if (flags & SHORTSHORT)
288*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, signed char*) = nread;
289*8d67ca89SAndroid Build Coastguard Worker else if (flags & SHORT)
290*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, short*) = nread;
291*8d67ca89SAndroid Build Coastguard Worker else if (flags & LONG)
292*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, long*) = nread;
293*8d67ca89SAndroid Build Coastguard Worker else if (flags & SIZEINT)
294*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, ssize_t*) = nread;
295*8d67ca89SAndroid Build Coastguard Worker else if (flags & PTRINT)
296*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, ptrdiff_t*) = nread;
297*8d67ca89SAndroid Build Coastguard Worker else if (flags & LLONG)
298*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, long long*) = nread;
299*8d67ca89SAndroid Build Coastguard Worker else if (flags & MAXINT)
300*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, intmax_t*) = nread;
301*8d67ca89SAndroid Build Coastguard Worker else
302*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, int*) = nread;
303*8d67ca89SAndroid Build Coastguard Worker continue;
304*8d67ca89SAndroid Build Coastguard Worker
305*8d67ca89SAndroid Build Coastguard Worker /*
306*8d67ca89SAndroid Build Coastguard Worker * Disgusting backwards compatibility hacks. XXX
307*8d67ca89SAndroid Build Coastguard Worker */
308*8d67ca89SAndroid Build Coastguard Worker case '\0': /* compat */
309*8d67ca89SAndroid Build Coastguard Worker return (EOF);
310*8d67ca89SAndroid Build Coastguard Worker
311*8d67ca89SAndroid Build Coastguard Worker default: /* compat */
312*8d67ca89SAndroid Build Coastguard Worker if (iswupper(c)) flags |= LONG;
313*8d67ca89SAndroid Build Coastguard Worker c = CT_INT;
314*8d67ca89SAndroid Build Coastguard Worker base = 10;
315*8d67ca89SAndroid Build Coastguard Worker break;
316*8d67ca89SAndroid Build Coastguard Worker }
317*8d67ca89SAndroid Build Coastguard Worker
318*8d67ca89SAndroid Build Coastguard Worker /*
319*8d67ca89SAndroid Build Coastguard Worker * Consume leading white space, except for formats
320*8d67ca89SAndroid Build Coastguard Worker * that suppress this.
321*8d67ca89SAndroid Build Coastguard Worker */
322*8d67ca89SAndroid Build Coastguard Worker if ((flags & NOSKIP) == 0) {
323*8d67ca89SAndroid Build Coastguard Worker while ((wi = __fgetwc_unlock(fp)) != WEOF && iswspace(wi)) nread++;
324*8d67ca89SAndroid Build Coastguard Worker if (wi == WEOF) goto input_failure;
325*8d67ca89SAndroid Build Coastguard Worker __ungetwc(wi, fp);
326*8d67ca89SAndroid Build Coastguard Worker }
327*8d67ca89SAndroid Build Coastguard Worker
328*8d67ca89SAndroid Build Coastguard Worker /*
329*8d67ca89SAndroid Build Coastguard Worker * Do the conversion.
330*8d67ca89SAndroid Build Coastguard Worker */
331*8d67ca89SAndroid Build Coastguard Worker switch (c) {
332*8d67ca89SAndroid Build Coastguard Worker case CT_CHAR:
333*8d67ca89SAndroid Build Coastguard Worker /* scan arbitrary characters (sets NOSKIP) */
334*8d67ca89SAndroid Build Coastguard Worker if (width == 0) width = 1;
335*8d67ca89SAndroid Build Coastguard Worker if (flags & LONG) {
336*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) p = va_arg(ap, wchar_t*);
337*8d67ca89SAndroid Build Coastguard Worker n = 0;
338*8d67ca89SAndroid Build Coastguard Worker while (width-- != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
339*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) *p++ = static_cast<wchar_t>(wi);
340*8d67ca89SAndroid Build Coastguard Worker n++;
341*8d67ca89SAndroid Build Coastguard Worker }
342*8d67ca89SAndroid Build Coastguard Worker if (n == 0) goto input_failure;
343*8d67ca89SAndroid Build Coastguard Worker nread += n;
344*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) nassigned++;
345*8d67ca89SAndroid Build Coastguard Worker } else {
346*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) mbp = va_arg(ap, char*);
347*8d67ca89SAndroid Build Coastguard Worker n = 0;
348*8d67ca89SAndroid Build Coastguard Worker memset(&mbs, 0, sizeof(mbs));
349*8d67ca89SAndroid Build Coastguard Worker while (width != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
350*8d67ca89SAndroid Build Coastguard Worker if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
351*8d67ca89SAndroid Build Coastguard Worker nconv = wcrtomb(mbp, wi, &mbs);
352*8d67ca89SAndroid Build Coastguard Worker if (nconv == static_cast<size_t>(-1)) goto input_failure;
353*8d67ca89SAndroid Build Coastguard Worker } else {
354*8d67ca89SAndroid Build Coastguard Worker nconv = wcrtomb(mbbuf, wi, &mbs);
355*8d67ca89SAndroid Build Coastguard Worker if (nconv == static_cast<size_t>(-1)) goto input_failure;
356*8d67ca89SAndroid Build Coastguard Worker if (nconv > width) {
357*8d67ca89SAndroid Build Coastguard Worker __ungetwc(wi, fp);
358*8d67ca89SAndroid Build Coastguard Worker break;
359*8d67ca89SAndroid Build Coastguard Worker }
360*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
361*8d67ca89SAndroid Build Coastguard Worker }
362*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) mbp += nconv;
363*8d67ca89SAndroid Build Coastguard Worker width -= nconv;
364*8d67ca89SAndroid Build Coastguard Worker n++;
365*8d67ca89SAndroid Build Coastguard Worker }
366*8d67ca89SAndroid Build Coastguard Worker if (n == 0) goto input_failure;
367*8d67ca89SAndroid Build Coastguard Worker nread += n;
368*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) nassigned++;
369*8d67ca89SAndroid Build Coastguard Worker }
370*8d67ca89SAndroid Build Coastguard Worker nconversions++;
371*8d67ca89SAndroid Build Coastguard Worker break;
372*8d67ca89SAndroid Build Coastguard Worker
373*8d67ca89SAndroid Build Coastguard Worker case CT_CCL:
374*8d67ca89SAndroid Build Coastguard Worker case CT_STRING:
375*8d67ca89SAndroid Build Coastguard Worker // CT_CCL: scan a (nonempty) character class (sets NOSKIP).
376*8d67ca89SAndroid Build Coastguard Worker // CT_STRING: like CCL, but zero-length string OK, & no NOSKIP.
377*8d67ca89SAndroid Build Coastguard Worker if (width == 0) width = SIZE_MAX; // 'infinity'.
378*8d67ca89SAndroid Build Coastguard Worker if ((flags & SUPPRESS) && (flags & LONG)) {
379*8d67ca89SAndroid Build Coastguard Worker n = 0;
380*8d67ca89SAndroid Build Coastguard Worker while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) n++;
381*8d67ca89SAndroid Build Coastguard Worker if (wi != WEOF) __ungetwc(wi, fp);
382*8d67ca89SAndroid Build Coastguard Worker } else if (flags & LONG) {
383*8d67ca89SAndroid Build Coastguard Worker p0 = p = va_arg(ap, wchar_t*);
384*8d67ca89SAndroid Build Coastguard Worker while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) {
385*8d67ca89SAndroid Build Coastguard Worker *p++ = static_cast<wchar_t>(wi);
386*8d67ca89SAndroid Build Coastguard Worker }
387*8d67ca89SAndroid Build Coastguard Worker if (wi != WEOF) __ungetwc(wi, fp);
388*8d67ca89SAndroid Build Coastguard Worker n = p - p0;
389*8d67ca89SAndroid Build Coastguard Worker } else {
390*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) mbp = va_arg(ap, char*);
391*8d67ca89SAndroid Build Coastguard Worker n = 0;
392*8d67ca89SAndroid Build Coastguard Worker memset(&mbs, 0, sizeof(mbs));
393*8d67ca89SAndroid Build Coastguard Worker while ((wi = __fgetwc_unlock(fp)) != WEOF && width != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) {
394*8d67ca89SAndroid Build Coastguard Worker if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
395*8d67ca89SAndroid Build Coastguard Worker nconv = wcrtomb(mbp, wi, &mbs);
396*8d67ca89SAndroid Build Coastguard Worker if (nconv == static_cast<size_t>(-1)) goto input_failure;
397*8d67ca89SAndroid Build Coastguard Worker } else {
398*8d67ca89SAndroid Build Coastguard Worker nconv = wcrtomb(mbbuf, wi, &mbs);
399*8d67ca89SAndroid Build Coastguard Worker if (nconv == static_cast<size_t>(-1)) goto input_failure;
400*8d67ca89SAndroid Build Coastguard Worker if (nconv > width) break;
401*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
402*8d67ca89SAndroid Build Coastguard Worker }
403*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) mbp += nconv;
404*8d67ca89SAndroid Build Coastguard Worker width -= nconv;
405*8d67ca89SAndroid Build Coastguard Worker n++;
406*8d67ca89SAndroid Build Coastguard Worker }
407*8d67ca89SAndroid Build Coastguard Worker if (wi != WEOF) __ungetwc(wi, fp);
408*8d67ca89SAndroid Build Coastguard Worker }
409*8d67ca89SAndroid Build Coastguard Worker if (c == CT_CCL && n == 0) goto match_failure;
410*8d67ca89SAndroid Build Coastguard Worker if (!(flags & SUPPRESS)) {
411*8d67ca89SAndroid Build Coastguard Worker if (flags & LONG) {
412*8d67ca89SAndroid Build Coastguard Worker *p = L'\0';
413*8d67ca89SAndroid Build Coastguard Worker } else {
414*8d67ca89SAndroid Build Coastguard Worker *mbp = '\0';
415*8d67ca89SAndroid Build Coastguard Worker }
416*8d67ca89SAndroid Build Coastguard Worker ++nassigned;
417*8d67ca89SAndroid Build Coastguard Worker }
418*8d67ca89SAndroid Build Coastguard Worker nread += n;
419*8d67ca89SAndroid Build Coastguard Worker nconversions++;
420*8d67ca89SAndroid Build Coastguard Worker break;
421*8d67ca89SAndroid Build Coastguard Worker
422*8d67ca89SAndroid Build Coastguard Worker case CT_INT:
423*8d67ca89SAndroid Build Coastguard Worker /* scan an integer as if by strtoimax/strtoumax */
424*8d67ca89SAndroid Build Coastguard Worker if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1)
425*8d67ca89SAndroid Build Coastguard Worker width = sizeof(buf) / sizeof(*buf) - 1;
426*8d67ca89SAndroid Build Coastguard Worker flags |= SIGNOK | NDIGITS | NZDIGITS;
427*8d67ca89SAndroid Build Coastguard Worker for (p = buf; width; width--) {
428*8d67ca89SAndroid Build Coastguard Worker c = __fgetwc_unlock(fp);
429*8d67ca89SAndroid Build Coastguard Worker /*
430*8d67ca89SAndroid Build Coastguard Worker * Switch on the character; `goto ok'
431*8d67ca89SAndroid Build Coastguard Worker * if we accept it as a part of number.
432*8d67ca89SAndroid Build Coastguard Worker */
433*8d67ca89SAndroid Build Coastguard Worker switch (c) {
434*8d67ca89SAndroid Build Coastguard Worker /*
435*8d67ca89SAndroid Build Coastguard Worker * The digit 0 is always legal, but is
436*8d67ca89SAndroid Build Coastguard Worker * special. For %i conversions, if no
437*8d67ca89SAndroid Build Coastguard Worker * digits (zero or nonzero) have been
438*8d67ca89SAndroid Build Coastguard Worker * scanned (only signs), we will have
439*8d67ca89SAndroid Build Coastguard Worker * base==0. In that case, we should set
440*8d67ca89SAndroid Build Coastguard Worker * it to 8 and enable 0b/0x prefixing.
441*8d67ca89SAndroid Build Coastguard Worker * Also, if we have not scanned zero digits
442*8d67ca89SAndroid Build Coastguard Worker * before this, do not turn off prefixing
443*8d67ca89SAndroid Build Coastguard Worker * (someone else will turn it off if we
444*8d67ca89SAndroid Build Coastguard Worker * have scanned any nonzero digits).
445*8d67ca89SAndroid Build Coastguard Worker */
446*8d67ca89SAndroid Build Coastguard Worker case '0':
447*8d67ca89SAndroid Build Coastguard Worker if (base == 0) {
448*8d67ca89SAndroid Build Coastguard Worker base = 8;
449*8d67ca89SAndroid Build Coastguard Worker flags |= PFBOK | PFXOK;
450*8d67ca89SAndroid Build Coastguard Worker }
451*8d67ca89SAndroid Build Coastguard Worker if (flags & NZDIGITS) {
452*8d67ca89SAndroid Build Coastguard Worker flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
453*8d67ca89SAndroid Build Coastguard Worker } else {
454*8d67ca89SAndroid Build Coastguard Worker flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
455*8d67ca89SAndroid Build Coastguard Worker }
456*8d67ca89SAndroid Build Coastguard Worker goto ok;
457*8d67ca89SAndroid Build Coastguard Worker
458*8d67ca89SAndroid Build Coastguard Worker /* 1 through 7 always legal */
459*8d67ca89SAndroid Build Coastguard Worker case 'B':
460*8d67ca89SAndroid Build Coastguard Worker case 'b':
461*8d67ca89SAndroid Build Coastguard Worker // Is this 'b' potentially part of an "0b" prefix?
462*8d67ca89SAndroid Build Coastguard Worker if ((flags & PFBOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
463*8d67ca89SAndroid Build Coastguard Worker base = 2;
464*8d67ca89SAndroid Build Coastguard Worker flags &= ~PFBOK;
465*8d67ca89SAndroid Build Coastguard Worker goto ok;
466*8d67ca89SAndroid Build Coastguard Worker }
467*8d67ca89SAndroid Build Coastguard Worker // No? Fall through and see if it's a hex digit instead then...
468*8d67ca89SAndroid Build Coastguard Worker __BIONIC_FALLTHROUGH;
469*8d67ca89SAndroid Build Coastguard Worker case '1':
470*8d67ca89SAndroid Build Coastguard Worker case '2':
471*8d67ca89SAndroid Build Coastguard Worker case '3':
472*8d67ca89SAndroid Build Coastguard Worker case '4':
473*8d67ca89SAndroid Build Coastguard Worker case '5':
474*8d67ca89SAndroid Build Coastguard Worker case '6':
475*8d67ca89SAndroid Build Coastguard Worker case '7':
476*8d67ca89SAndroid Build Coastguard Worker case '8':
477*8d67ca89SAndroid Build Coastguard Worker case '9':
478*8d67ca89SAndroid Build Coastguard Worker case 'A':
479*8d67ca89SAndroid Build Coastguard Worker case 'C':
480*8d67ca89SAndroid Build Coastguard Worker case 'D':
481*8d67ca89SAndroid Build Coastguard Worker case 'E':
482*8d67ca89SAndroid Build Coastguard Worker case 'F':
483*8d67ca89SAndroid Build Coastguard Worker case 'a':
484*8d67ca89SAndroid Build Coastguard Worker case 'c':
485*8d67ca89SAndroid Build Coastguard Worker case 'd':
486*8d67ca89SAndroid Build Coastguard Worker case 'e':
487*8d67ca89SAndroid Build Coastguard Worker case 'f':
488*8d67ca89SAndroid Build Coastguard Worker if (base == 0) base = 10;
489*8d67ca89SAndroid Build Coastguard Worker if (base != 16 && static_cast<int>(c - '0') >= base) break; /* not legal here */
490*8d67ca89SAndroid Build Coastguard Worker flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
491*8d67ca89SAndroid Build Coastguard Worker goto ok;
492*8d67ca89SAndroid Build Coastguard Worker
493*8d67ca89SAndroid Build Coastguard Worker /* sign ok only as first character */
494*8d67ca89SAndroid Build Coastguard Worker case '+':
495*8d67ca89SAndroid Build Coastguard Worker case '-':
496*8d67ca89SAndroid Build Coastguard Worker if (flags & SIGNOK) {
497*8d67ca89SAndroid Build Coastguard Worker flags &= ~SIGNOK;
498*8d67ca89SAndroid Build Coastguard Worker flags |= HAVESIGN;
499*8d67ca89SAndroid Build Coastguard Worker goto ok;
500*8d67ca89SAndroid Build Coastguard Worker }
501*8d67ca89SAndroid Build Coastguard Worker break;
502*8d67ca89SAndroid Build Coastguard Worker
503*8d67ca89SAndroid Build Coastguard Worker /*
504*8d67ca89SAndroid Build Coastguard Worker * x ok iff flag still set and 2nd char (or
505*8d67ca89SAndroid Build Coastguard Worker * 3rd char if we have a sign).
506*8d67ca89SAndroid Build Coastguard Worker */
507*8d67ca89SAndroid Build Coastguard Worker case 'x':
508*8d67ca89SAndroid Build Coastguard Worker case 'X':
509*8d67ca89SAndroid Build Coastguard Worker if ((flags & PFXOK) && p == buf + 1 + !!(flags & HAVESIGN)) {
510*8d67ca89SAndroid Build Coastguard Worker base = 16; /* if %i */
511*8d67ca89SAndroid Build Coastguard Worker flags &= ~PFXOK;
512*8d67ca89SAndroid Build Coastguard Worker goto ok;
513*8d67ca89SAndroid Build Coastguard Worker }
514*8d67ca89SAndroid Build Coastguard Worker break;
515*8d67ca89SAndroid Build Coastguard Worker }
516*8d67ca89SAndroid Build Coastguard Worker
517*8d67ca89SAndroid Build Coastguard Worker /*
518*8d67ca89SAndroid Build Coastguard Worker * If we got here, c is not a legal character
519*8d67ca89SAndroid Build Coastguard Worker * for a number. Stop accumulating digits.
520*8d67ca89SAndroid Build Coastguard Worker */
521*8d67ca89SAndroid Build Coastguard Worker if (c != WEOF) __ungetwc(c, fp);
522*8d67ca89SAndroid Build Coastguard Worker break;
523*8d67ca89SAndroid Build Coastguard Worker ok:
524*8d67ca89SAndroid Build Coastguard Worker /*
525*8d67ca89SAndroid Build Coastguard Worker * c is legal: store it and look at the next.
526*8d67ca89SAndroid Build Coastguard Worker */
527*8d67ca89SAndroid Build Coastguard Worker *p++ = static_cast<wchar_t>(c);
528*8d67ca89SAndroid Build Coastguard Worker }
529*8d67ca89SAndroid Build Coastguard Worker /*
530*8d67ca89SAndroid Build Coastguard Worker * If we had only a sign, it is no good; push back the sign.
531*8d67ca89SAndroid Build Coastguard Worker * If the number was `[-+]0[BbXx]`, push back and treat it
532*8d67ca89SAndroid Build Coastguard Worker * as `[-+]0`.
533*8d67ca89SAndroid Build Coastguard Worker */
534*8d67ca89SAndroid Build Coastguard Worker if (flags & NDIGITS) {
535*8d67ca89SAndroid Build Coastguard Worker if (p > buf) __ungetwc(*--p, fp);
536*8d67ca89SAndroid Build Coastguard Worker goto match_failure;
537*8d67ca89SAndroid Build Coastguard Worker }
538*8d67ca89SAndroid Build Coastguard Worker c = p[-1];
539*8d67ca89SAndroid Build Coastguard Worker if ((base == 2 && (c == 'b' || c == 'B')) || c == 'x' || c == 'X') {
540*8d67ca89SAndroid Build Coastguard Worker --p;
541*8d67ca89SAndroid Build Coastguard Worker __ungetwc(c, fp);
542*8d67ca89SAndroid Build Coastguard Worker }
543*8d67ca89SAndroid Build Coastguard Worker if ((flags & SUPPRESS) == 0) {
544*8d67ca89SAndroid Build Coastguard Worker uintmax_t res;
545*8d67ca89SAndroid Build Coastguard Worker
546*8d67ca89SAndroid Build Coastguard Worker *p = '\0';
547*8d67ca89SAndroid Build Coastguard Worker if (flags & UNSIGNED)
548*8d67ca89SAndroid Build Coastguard Worker res = wcstoimax(buf, NULL, base);
549*8d67ca89SAndroid Build Coastguard Worker else
550*8d67ca89SAndroid Build Coastguard Worker res = wcstoumax(buf, NULL, base);
551*8d67ca89SAndroid Build Coastguard Worker if (flags & POINTER)
552*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, void**) = reinterpret_cast<void*>(res);
553*8d67ca89SAndroid Build Coastguard Worker else if (flags & MAXINT)
554*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, intmax_t*) = res;
555*8d67ca89SAndroid Build Coastguard Worker else if (flags & LLONG)
556*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, long long*) = res;
557*8d67ca89SAndroid Build Coastguard Worker else if (flags & SIZEINT)
558*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, ssize_t*) = res;
559*8d67ca89SAndroid Build Coastguard Worker else if (flags & PTRINT)
560*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, ptrdiff_t*) = res;
561*8d67ca89SAndroid Build Coastguard Worker else if (flags & LONG)
562*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, long*) = res;
563*8d67ca89SAndroid Build Coastguard Worker else if (flags & SHORT)
564*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, short*) = res;
565*8d67ca89SAndroid Build Coastguard Worker else if (flags & SHORTSHORT)
566*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, signed char*) = res;
567*8d67ca89SAndroid Build Coastguard Worker else
568*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, int*) = res;
569*8d67ca89SAndroid Build Coastguard Worker nassigned++;
570*8d67ca89SAndroid Build Coastguard Worker }
571*8d67ca89SAndroid Build Coastguard Worker nread += p - buf;
572*8d67ca89SAndroid Build Coastguard Worker nconversions++;
573*8d67ca89SAndroid Build Coastguard Worker break;
574*8d67ca89SAndroid Build Coastguard Worker
575*8d67ca89SAndroid Build Coastguard Worker case CT_FLOAT:
576*8d67ca89SAndroid Build Coastguard Worker /* scan a floating point number as if by strtod */
577*8d67ca89SAndroid Build Coastguard Worker if (width == 0 || width > sizeof(buf) / sizeof(*buf) - 1)
578*8d67ca89SAndroid Build Coastguard Worker width = sizeof(buf) / sizeof(*buf) - 1;
579*8d67ca89SAndroid Build Coastguard Worker if ((width = wparsefloat(fp, buf, buf + width)) == 0) goto match_failure;
580*8d67ca89SAndroid Build Coastguard Worker if ((flags & SUPPRESS) == 0) {
581*8d67ca89SAndroid Build Coastguard Worker if (flags & LONGDBL) {
582*8d67ca89SAndroid Build Coastguard Worker long double res = wcstold(buf, &p);
583*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, long double*) = res;
584*8d67ca89SAndroid Build Coastguard Worker } else if (flags & LONG) {
585*8d67ca89SAndroid Build Coastguard Worker double res = wcstod(buf, &p);
586*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, double*) = res;
587*8d67ca89SAndroid Build Coastguard Worker } else {
588*8d67ca89SAndroid Build Coastguard Worker float res = wcstof(buf, &p);
589*8d67ca89SAndroid Build Coastguard Worker *va_arg(ap, float*) = res;
590*8d67ca89SAndroid Build Coastguard Worker }
591*8d67ca89SAndroid Build Coastguard Worker if (static_cast<size_t>(p - buf) != width) abort();
592*8d67ca89SAndroid Build Coastguard Worker nassigned++;
593*8d67ca89SAndroid Build Coastguard Worker }
594*8d67ca89SAndroid Build Coastguard Worker nread += width;
595*8d67ca89SAndroid Build Coastguard Worker nconversions++;
596*8d67ca89SAndroid Build Coastguard Worker break;
597*8d67ca89SAndroid Build Coastguard Worker }
598*8d67ca89SAndroid Build Coastguard Worker }
599*8d67ca89SAndroid Build Coastguard Worker input_failure:
600*8d67ca89SAndroid Build Coastguard Worker return (nconversions != 0 ? nassigned : EOF);
601*8d67ca89SAndroid Build Coastguard Worker match_failure:
602*8d67ca89SAndroid Build Coastguard Worker return (nassigned);
603*8d67ca89SAndroid Build Coastguard Worker }
604*8d67ca89SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
605