1*8d67ca89SAndroid Build Coastguard Worker /*-
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (c) 1990, 1993
3*8d67ca89SAndroid Build Coastguard Worker * The Regents of the University of California. All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker *
5*8d67ca89SAndroid Build Coastguard Worker * This code is derived from software contributed to Berkeley by
6*8d67ca89SAndroid Build Coastguard Worker * Chris Torek.
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
9*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
10*8d67ca89SAndroid Build Coastguard Worker * are met:
11*8d67ca89SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
12*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
13*8d67ca89SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
14*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
15*8d67ca89SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
16*8d67ca89SAndroid Build Coastguard Worker * 3. Neither the name of the University nor the names of its contributors
17*8d67ca89SAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
18*8d67ca89SAndroid Build Coastguard Worker * without specific prior written permission.
19*8d67ca89SAndroid Build Coastguard Worker *
20*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21*8d67ca89SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*8d67ca89SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*8d67ca89SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24*8d67ca89SAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*8d67ca89SAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*8d67ca89SAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*8d67ca89SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*8d67ca89SAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*8d67ca89SAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
31*8d67ca89SAndroid Build Coastguard Worker */
32*8d67ca89SAndroid Build Coastguard Worker
33*8d67ca89SAndroid Build Coastguard Worker #include <ctype.h>
34*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
35*8d67ca89SAndroid Build Coastguard Worker
36*8d67ca89SAndroid Build Coastguard Worker #include "local.h"
37*8d67ca89SAndroid Build Coastguard Worker
38*8d67ca89SAndroid Build Coastguard Worker #define BUF 513 /* Maximum length of numeric string. */
39*8d67ca89SAndroid Build Coastguard Worker
parsefloat(FILE * fp,char * buf,char * end)40*8d67ca89SAndroid Build Coastguard Worker size_t parsefloat(FILE *fp, char *buf, char *end) {
41*8d67ca89SAndroid Build Coastguard Worker char *commit, *p;
42*8d67ca89SAndroid Build Coastguard Worker int infnanpos = 0;
43*8d67ca89SAndroid Build Coastguard Worker enum {
44*8d67ca89SAndroid Build Coastguard Worker S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
45*8d67ca89SAndroid Build Coastguard Worker S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
46*8d67ca89SAndroid Build Coastguard Worker } state = S_START;
47*8d67ca89SAndroid Build Coastguard Worker unsigned char c;
48*8d67ca89SAndroid Build Coastguard Worker int gotmantdig = 0, ishex = 0;
49*8d67ca89SAndroid Build Coastguard Worker
50*8d67ca89SAndroid Build Coastguard Worker /*
51*8d67ca89SAndroid Build Coastguard Worker * We set commit = p whenever the string we have read so far
52*8d67ca89SAndroid Build Coastguard Worker * constitutes a valid representation of a floating point
53*8d67ca89SAndroid Build Coastguard Worker * number by itself. At some point, the parse will complete
54*8d67ca89SAndroid Build Coastguard Worker * or fail, and we will ungetc() back to the last commit point.
55*8d67ca89SAndroid Build Coastguard Worker * To ensure that the file offset gets updated properly, it is
56*8d67ca89SAndroid Build Coastguard Worker * always necessary to read at least one character that doesn't
57*8d67ca89SAndroid Build Coastguard Worker * match; thus, we can't short-circuit "infinity" or "nan(...)".
58*8d67ca89SAndroid Build Coastguard Worker */
59*8d67ca89SAndroid Build Coastguard Worker commit = buf - 1;
60*8d67ca89SAndroid Build Coastguard Worker for (p = buf; p < end; ) {
61*8d67ca89SAndroid Build Coastguard Worker c = *fp->_p;
62*8d67ca89SAndroid Build Coastguard Worker reswitch:
63*8d67ca89SAndroid Build Coastguard Worker switch (state) {
64*8d67ca89SAndroid Build Coastguard Worker case S_START:
65*8d67ca89SAndroid Build Coastguard Worker state = S_GOTSIGN;
66*8d67ca89SAndroid Build Coastguard Worker if (c == '-' || c == '+')
67*8d67ca89SAndroid Build Coastguard Worker break;
68*8d67ca89SAndroid Build Coastguard Worker else
69*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
70*8d67ca89SAndroid Build Coastguard Worker case S_GOTSIGN:
71*8d67ca89SAndroid Build Coastguard Worker switch (c) {
72*8d67ca89SAndroid Build Coastguard Worker case '0':
73*8d67ca89SAndroid Build Coastguard Worker state = S_MAYBEHEX;
74*8d67ca89SAndroid Build Coastguard Worker commit = p;
75*8d67ca89SAndroid Build Coastguard Worker break;
76*8d67ca89SAndroid Build Coastguard Worker case 'I':
77*8d67ca89SAndroid Build Coastguard Worker case 'i':
78*8d67ca89SAndroid Build Coastguard Worker state = S_INF;
79*8d67ca89SAndroid Build Coastguard Worker break;
80*8d67ca89SAndroid Build Coastguard Worker case 'N':
81*8d67ca89SAndroid Build Coastguard Worker case 'n':
82*8d67ca89SAndroid Build Coastguard Worker state = S_NAN;
83*8d67ca89SAndroid Build Coastguard Worker break;
84*8d67ca89SAndroid Build Coastguard Worker default:
85*8d67ca89SAndroid Build Coastguard Worker state = S_DIGITS;
86*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
87*8d67ca89SAndroid Build Coastguard Worker }
88*8d67ca89SAndroid Build Coastguard Worker break;
89*8d67ca89SAndroid Build Coastguard Worker case S_INF:
90*8d67ca89SAndroid Build Coastguard Worker if (infnanpos > 6 ||
91*8d67ca89SAndroid Build Coastguard Worker (c != "nfinity"[infnanpos] &&
92*8d67ca89SAndroid Build Coastguard Worker c != "NFINITY"[infnanpos]))
93*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
94*8d67ca89SAndroid Build Coastguard Worker if (infnanpos == 1 || infnanpos == 6)
95*8d67ca89SAndroid Build Coastguard Worker commit = p; /* inf or infinity */
96*8d67ca89SAndroid Build Coastguard Worker infnanpos++;
97*8d67ca89SAndroid Build Coastguard Worker break;
98*8d67ca89SAndroid Build Coastguard Worker case S_NAN:
99*8d67ca89SAndroid Build Coastguard Worker switch (infnanpos) {
100*8d67ca89SAndroid Build Coastguard Worker case -1: /* XXX kludge to deal with nan(...) */
101*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
102*8d67ca89SAndroid Build Coastguard Worker case 0:
103*8d67ca89SAndroid Build Coastguard Worker if (c != 'A' && c != 'a')
104*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
105*8d67ca89SAndroid Build Coastguard Worker break;
106*8d67ca89SAndroid Build Coastguard Worker case 1:
107*8d67ca89SAndroid Build Coastguard Worker if (c != 'N' && c != 'n')
108*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
109*8d67ca89SAndroid Build Coastguard Worker else
110*8d67ca89SAndroid Build Coastguard Worker commit = p;
111*8d67ca89SAndroid Build Coastguard Worker break;
112*8d67ca89SAndroid Build Coastguard Worker case 2:
113*8d67ca89SAndroid Build Coastguard Worker if (c != '(')
114*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
115*8d67ca89SAndroid Build Coastguard Worker break;
116*8d67ca89SAndroid Build Coastguard Worker default:
117*8d67ca89SAndroid Build Coastguard Worker if (c == ')') {
118*8d67ca89SAndroid Build Coastguard Worker commit = p;
119*8d67ca89SAndroid Build Coastguard Worker infnanpos = -2;
120*8d67ca89SAndroid Build Coastguard Worker } else if (!isalnum(c) && c != '_')
121*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
122*8d67ca89SAndroid Build Coastguard Worker break;
123*8d67ca89SAndroid Build Coastguard Worker }
124*8d67ca89SAndroid Build Coastguard Worker infnanpos++;
125*8d67ca89SAndroid Build Coastguard Worker break;
126*8d67ca89SAndroid Build Coastguard Worker case S_MAYBEHEX:
127*8d67ca89SAndroid Build Coastguard Worker state = S_DIGITS;
128*8d67ca89SAndroid Build Coastguard Worker if (c == 'X' || c == 'x') {
129*8d67ca89SAndroid Build Coastguard Worker ishex = 1;
130*8d67ca89SAndroid Build Coastguard Worker break;
131*8d67ca89SAndroid Build Coastguard Worker } else { /* we saw a '0', but no 'x' */
132*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
133*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
134*8d67ca89SAndroid Build Coastguard Worker }
135*8d67ca89SAndroid Build Coastguard Worker case S_DIGITS:
136*8d67ca89SAndroid Build Coastguard Worker if ((ishex && isxdigit(c)) || isdigit(c))
137*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
138*8d67ca89SAndroid Build Coastguard Worker else {
139*8d67ca89SAndroid Build Coastguard Worker state = S_FRAC;
140*8d67ca89SAndroid Build Coastguard Worker if (c != '.')
141*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
142*8d67ca89SAndroid Build Coastguard Worker }
143*8d67ca89SAndroid Build Coastguard Worker if (gotmantdig)
144*8d67ca89SAndroid Build Coastguard Worker commit = p;
145*8d67ca89SAndroid Build Coastguard Worker break;
146*8d67ca89SAndroid Build Coastguard Worker case S_FRAC:
147*8d67ca89SAndroid Build Coastguard Worker if (((c == 'E' || c == 'e') && !ishex) ||
148*8d67ca89SAndroid Build Coastguard Worker ((c == 'P' || c == 'p') && ishex)) {
149*8d67ca89SAndroid Build Coastguard Worker if (!gotmantdig)
150*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
151*8d67ca89SAndroid Build Coastguard Worker else
152*8d67ca89SAndroid Build Coastguard Worker state = S_EXP;
153*8d67ca89SAndroid Build Coastguard Worker } else if ((ishex && isxdigit(c)) || isdigit(c)) {
154*8d67ca89SAndroid Build Coastguard Worker commit = p;
155*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
156*8d67ca89SAndroid Build Coastguard Worker } else
157*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
158*8d67ca89SAndroid Build Coastguard Worker break;
159*8d67ca89SAndroid Build Coastguard Worker case S_EXP:
160*8d67ca89SAndroid Build Coastguard Worker state = S_EXPDIGITS;
161*8d67ca89SAndroid Build Coastguard Worker if (c == '-' || c == '+')
162*8d67ca89SAndroid Build Coastguard Worker break;
163*8d67ca89SAndroid Build Coastguard Worker else
164*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
165*8d67ca89SAndroid Build Coastguard Worker case S_EXPDIGITS:
166*8d67ca89SAndroid Build Coastguard Worker if (isdigit(c))
167*8d67ca89SAndroid Build Coastguard Worker commit = p;
168*8d67ca89SAndroid Build Coastguard Worker else
169*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
170*8d67ca89SAndroid Build Coastguard Worker break;
171*8d67ca89SAndroid Build Coastguard Worker default:
172*8d67ca89SAndroid Build Coastguard Worker abort();
173*8d67ca89SAndroid Build Coastguard Worker }
174*8d67ca89SAndroid Build Coastguard Worker *p++ = c;
175*8d67ca89SAndroid Build Coastguard Worker if (--fp->_r > 0)
176*8d67ca89SAndroid Build Coastguard Worker fp->_p++;
177*8d67ca89SAndroid Build Coastguard Worker else if (__srefill(fp))
178*8d67ca89SAndroid Build Coastguard Worker break; /* EOF */
179*8d67ca89SAndroid Build Coastguard Worker }
180*8d67ca89SAndroid Build Coastguard Worker
181*8d67ca89SAndroid Build Coastguard Worker parsedone:
182*8d67ca89SAndroid Build Coastguard Worker while (commit < --p)
183*8d67ca89SAndroid Build Coastguard Worker (void)ungetc(*(unsigned char *)p, fp);
184*8d67ca89SAndroid Build Coastguard Worker *++commit = '\0';
185*8d67ca89SAndroid Build Coastguard Worker return commit - buf;
186*8d67ca89SAndroid Build Coastguard Worker }
187*8d67ca89SAndroid Build Coastguard Worker
wparsefloat(FILE * fp,wchar_t * buf,wchar_t * end)188*8d67ca89SAndroid Build Coastguard Worker size_t wparsefloat(FILE *fp, wchar_t *buf, wchar_t *end) {
189*8d67ca89SAndroid Build Coastguard Worker wchar_t *commit, *p;
190*8d67ca89SAndroid Build Coastguard Worker int infnanpos = 0;
191*8d67ca89SAndroid Build Coastguard Worker enum {
192*8d67ca89SAndroid Build Coastguard Worker S_START, S_GOTSIGN, S_INF, S_NAN, S_MAYBEHEX,
193*8d67ca89SAndroid Build Coastguard Worker S_DIGITS, S_FRAC, S_EXP, S_EXPDIGITS
194*8d67ca89SAndroid Build Coastguard Worker } state = S_START;
195*8d67ca89SAndroid Build Coastguard Worker wint_t c;
196*8d67ca89SAndroid Build Coastguard Worker int gotmantdig = 0, ishex = 0;
197*8d67ca89SAndroid Build Coastguard Worker
198*8d67ca89SAndroid Build Coastguard Worker /*
199*8d67ca89SAndroid Build Coastguard Worker * We set commit = p whenever the string we have read so far
200*8d67ca89SAndroid Build Coastguard Worker * constitutes a valid representation of a floating point
201*8d67ca89SAndroid Build Coastguard Worker * number by itself. At some point, the parse will complete
202*8d67ca89SAndroid Build Coastguard Worker * or fail, and we will ungetc() back to the last commit point.
203*8d67ca89SAndroid Build Coastguard Worker * To ensure that the file offset gets updated properly, it is
204*8d67ca89SAndroid Build Coastguard Worker * always necessary to read at least one character that doesn't
205*8d67ca89SAndroid Build Coastguard Worker * match; thus, we can't short-circuit "infinity" or "nan(...)".
206*8d67ca89SAndroid Build Coastguard Worker */
207*8d67ca89SAndroid Build Coastguard Worker commit = buf - 1;
208*8d67ca89SAndroid Build Coastguard Worker c = WEOF;
209*8d67ca89SAndroid Build Coastguard Worker for (p = buf; p < end; ) {
210*8d67ca89SAndroid Build Coastguard Worker if ((c = __fgetwc_unlock(fp)) == WEOF)
211*8d67ca89SAndroid Build Coastguard Worker break;
212*8d67ca89SAndroid Build Coastguard Worker reswitch:
213*8d67ca89SAndroid Build Coastguard Worker switch (state) {
214*8d67ca89SAndroid Build Coastguard Worker case S_START:
215*8d67ca89SAndroid Build Coastguard Worker state = S_GOTSIGN;
216*8d67ca89SAndroid Build Coastguard Worker if (c == '-' || c == '+')
217*8d67ca89SAndroid Build Coastguard Worker break;
218*8d67ca89SAndroid Build Coastguard Worker else
219*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
220*8d67ca89SAndroid Build Coastguard Worker case S_GOTSIGN:
221*8d67ca89SAndroid Build Coastguard Worker switch (c) {
222*8d67ca89SAndroid Build Coastguard Worker case '0':
223*8d67ca89SAndroid Build Coastguard Worker state = S_MAYBEHEX;
224*8d67ca89SAndroid Build Coastguard Worker commit = p;
225*8d67ca89SAndroid Build Coastguard Worker break;
226*8d67ca89SAndroid Build Coastguard Worker case 'I':
227*8d67ca89SAndroid Build Coastguard Worker case 'i':
228*8d67ca89SAndroid Build Coastguard Worker state = S_INF;
229*8d67ca89SAndroid Build Coastguard Worker break;
230*8d67ca89SAndroid Build Coastguard Worker case 'N':
231*8d67ca89SAndroid Build Coastguard Worker case 'n':
232*8d67ca89SAndroid Build Coastguard Worker state = S_NAN;
233*8d67ca89SAndroid Build Coastguard Worker break;
234*8d67ca89SAndroid Build Coastguard Worker default:
235*8d67ca89SAndroid Build Coastguard Worker state = S_DIGITS;
236*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
237*8d67ca89SAndroid Build Coastguard Worker }
238*8d67ca89SAndroid Build Coastguard Worker break;
239*8d67ca89SAndroid Build Coastguard Worker case S_INF:
240*8d67ca89SAndroid Build Coastguard Worker if (infnanpos > 6 ||
241*8d67ca89SAndroid Build Coastguard Worker (c != (wint_t)"nfinity"[infnanpos] &&
242*8d67ca89SAndroid Build Coastguard Worker c != (wint_t)"NFINITY"[infnanpos]))
243*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
244*8d67ca89SAndroid Build Coastguard Worker if (infnanpos == 1 || infnanpos == 6)
245*8d67ca89SAndroid Build Coastguard Worker commit = p; /* inf or infinity */
246*8d67ca89SAndroid Build Coastguard Worker infnanpos++;
247*8d67ca89SAndroid Build Coastguard Worker break;
248*8d67ca89SAndroid Build Coastguard Worker case S_NAN:
249*8d67ca89SAndroid Build Coastguard Worker switch (infnanpos) {
250*8d67ca89SAndroid Build Coastguard Worker case -1: /* XXX kludge to deal with nan(...) */
251*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
252*8d67ca89SAndroid Build Coastguard Worker case 0:
253*8d67ca89SAndroid Build Coastguard Worker if (c != 'A' && c != 'a')
254*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
255*8d67ca89SAndroid Build Coastguard Worker break;
256*8d67ca89SAndroid Build Coastguard Worker case 1:
257*8d67ca89SAndroid Build Coastguard Worker if (c != 'N' && c != 'n')
258*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
259*8d67ca89SAndroid Build Coastguard Worker else
260*8d67ca89SAndroid Build Coastguard Worker commit = p;
261*8d67ca89SAndroid Build Coastguard Worker break;
262*8d67ca89SAndroid Build Coastguard Worker case 2:
263*8d67ca89SAndroid Build Coastguard Worker if (c != '(')
264*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
265*8d67ca89SAndroid Build Coastguard Worker break;
266*8d67ca89SAndroid Build Coastguard Worker default:
267*8d67ca89SAndroid Build Coastguard Worker if (c == ')') {
268*8d67ca89SAndroid Build Coastguard Worker commit = p;
269*8d67ca89SAndroid Build Coastguard Worker infnanpos = -2;
270*8d67ca89SAndroid Build Coastguard Worker } else if (!iswalnum(c) && c != '_')
271*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
272*8d67ca89SAndroid Build Coastguard Worker break;
273*8d67ca89SAndroid Build Coastguard Worker }
274*8d67ca89SAndroid Build Coastguard Worker infnanpos++;
275*8d67ca89SAndroid Build Coastguard Worker break;
276*8d67ca89SAndroid Build Coastguard Worker case S_MAYBEHEX:
277*8d67ca89SAndroid Build Coastguard Worker state = S_DIGITS;
278*8d67ca89SAndroid Build Coastguard Worker if (c == 'X' || c == 'x') {
279*8d67ca89SAndroid Build Coastguard Worker ishex = 1;
280*8d67ca89SAndroid Build Coastguard Worker break;
281*8d67ca89SAndroid Build Coastguard Worker } else { /* we saw a '0', but no 'x' */
282*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
283*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
284*8d67ca89SAndroid Build Coastguard Worker }
285*8d67ca89SAndroid Build Coastguard Worker case S_DIGITS:
286*8d67ca89SAndroid Build Coastguard Worker if ((ishex && iswxdigit(c)) || iswdigit(c))
287*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
288*8d67ca89SAndroid Build Coastguard Worker else {
289*8d67ca89SAndroid Build Coastguard Worker state = S_FRAC;
290*8d67ca89SAndroid Build Coastguard Worker if (c != L'.')
291*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
292*8d67ca89SAndroid Build Coastguard Worker }
293*8d67ca89SAndroid Build Coastguard Worker if (gotmantdig)
294*8d67ca89SAndroid Build Coastguard Worker commit = p;
295*8d67ca89SAndroid Build Coastguard Worker break;
296*8d67ca89SAndroid Build Coastguard Worker case S_FRAC:
297*8d67ca89SAndroid Build Coastguard Worker if (((c == 'E' || c == 'e') && !ishex) ||
298*8d67ca89SAndroid Build Coastguard Worker ((c == 'P' || c == 'p') && ishex)) {
299*8d67ca89SAndroid Build Coastguard Worker if (!gotmantdig)
300*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
301*8d67ca89SAndroid Build Coastguard Worker else
302*8d67ca89SAndroid Build Coastguard Worker state = S_EXP;
303*8d67ca89SAndroid Build Coastguard Worker } else if ((ishex && iswxdigit(c)) || iswdigit(c)) {
304*8d67ca89SAndroid Build Coastguard Worker commit = p;
305*8d67ca89SAndroid Build Coastguard Worker gotmantdig = 1;
306*8d67ca89SAndroid Build Coastguard Worker } else
307*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
308*8d67ca89SAndroid Build Coastguard Worker break;
309*8d67ca89SAndroid Build Coastguard Worker case S_EXP:
310*8d67ca89SAndroid Build Coastguard Worker state = S_EXPDIGITS;
311*8d67ca89SAndroid Build Coastguard Worker if (c == '-' || c == '+')
312*8d67ca89SAndroid Build Coastguard Worker break;
313*8d67ca89SAndroid Build Coastguard Worker else
314*8d67ca89SAndroid Build Coastguard Worker goto reswitch;
315*8d67ca89SAndroid Build Coastguard Worker case S_EXPDIGITS:
316*8d67ca89SAndroid Build Coastguard Worker if (iswdigit(c))
317*8d67ca89SAndroid Build Coastguard Worker commit = p;
318*8d67ca89SAndroid Build Coastguard Worker else
319*8d67ca89SAndroid Build Coastguard Worker goto parsedone;
320*8d67ca89SAndroid Build Coastguard Worker break;
321*8d67ca89SAndroid Build Coastguard Worker default:
322*8d67ca89SAndroid Build Coastguard Worker abort();
323*8d67ca89SAndroid Build Coastguard Worker }
324*8d67ca89SAndroid Build Coastguard Worker *p++ = c;
325*8d67ca89SAndroid Build Coastguard Worker c = WEOF;
326*8d67ca89SAndroid Build Coastguard Worker }
327*8d67ca89SAndroid Build Coastguard Worker
328*8d67ca89SAndroid Build Coastguard Worker parsedone:
329*8d67ca89SAndroid Build Coastguard Worker if (c != WEOF)
330*8d67ca89SAndroid Build Coastguard Worker ungetwc(c, fp);
331*8d67ca89SAndroid Build Coastguard Worker while (commit < --p)
332*8d67ca89SAndroid Build Coastguard Worker ungetwc(*p, fp);
333*8d67ca89SAndroid Build Coastguard Worker *++commit = '\0';
334*8d67ca89SAndroid Build Coastguard Worker return (int)(commit - buf);
335*8d67ca89SAndroid Build Coastguard Worker }
336