1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin /*
23da2e3ebdSchin * AT&T Research
24da2e3ebdSchin * Glenn Fowler
25da2e3ebdSchin * Phong Vo
26da2e3ebdSchin *
27da2e3ebdSchin * common header and implementation for
28da2e3ebdSchin *
29da2e3ebdSchin * strtol strtoul strton
30da2e3ebdSchin * strtoll strtoull strtonll
31da2e3ebdSchin * strntol strntoul strnton
32da2e3ebdSchin * strntoll strntoull strntonll
33da2e3ebdSchin *
34da2e3ebdSchin * define these macros to instantiate an implementation:
35da2e3ebdSchin *
36da2e3ebdSchin * S2I_function the function name
37da2e3ebdSchin * S2I_number the signed number type
38da2e3ebdSchin * S2I_unumber the unsigned number type
39da2e3ebdSchin * S2I_unsigned 1 for unsigned, 0 for signed
4034f9b3eeSRoland Mainz * S2I_qualifier 1 for optional qualifier suffix, 0 otherwise
41da2e3ebdSchin * S2I_multiplier 1 for optional multiplier suffix, 0 otherwise
42da2e3ebdSchin * S2I_size the second argument is the input string size
43da2e3ebdSchin *
44da2e3ebdSchin * convert string to number
45da2e3ebdSchin * errno=ERANGE on overflow (LONG_MAX) or underflow (LONG_MIN)
46da2e3ebdSchin * if non-null e will point to first unrecognized char in s
47da2e3ebdSchin * if basep!=0 it points to the default base on input and
48da2e3ebdSchin * will point to the explicit base on return
49da2e3ebdSchin * a default base of 0 will determine the base from the input
50da2e3ebdSchin * a default base of 1 will determine the base from the input using bb#*
51da2e3ebdSchin * a base prefix in the string overrides *b
52da2e3ebdSchin * *b will not be set if the string has no base prefix
53da2e3ebdSchin * if m>1 and no multipler was specified then the result is multiplied by m
54da2e3ebdSchin * if m<0 then multipliers are not consumed
55da2e3ebdSchin * if a base arg or prefix is specified then multiplier is not consumed
56da2e3ebdSchin *
57da2e3ebdSchin * integer numbers are of the form:
58da2e3ebdSchin *
59da2e3ebdSchin * [sign][base][number[qualifier]][multiplier]
60da2e3ebdSchin *
61da2e3ebdSchin * base: nnn# base nnn
62da2e3ebdSchin * 0[xX] hex
63da2e3ebdSchin * 0 octal
64da2e3ebdSchin * [1-9] decimal
65da2e3ebdSchin *
66da2e3ebdSchin * number: [0-9a-zA-Z]*
67da2e3ebdSchin *
68da2e3ebdSchin * qualifier: [lL]
69da2e3ebdSchin * [uU]
70da2e3ebdSchin * [uU][lL]
71da2e3ebdSchin * [lL][uU]
72da2e3ebdSchin * [lL][lL][uU]
73da2e3ebdSchin * [uU][lL][lL]
74da2e3ebdSchin *
75da2e3ebdSchin * multiplier: . pseudo-float if m>1
76da2e3ebdSchin * [bB] block (512)
77da2e3ebdSchin * [cC] char (1)
78da2e3ebdSchin * [gG] giga (1024*1024*1024)
79da2e3ebdSchin * [kK] kilo (1024)
80da2e3ebdSchin * [mM] mega (1024*1024)
81da2e3ebdSchin */
82da2e3ebdSchin
83da2e3ebdSchin #include <ast.h>
84da2e3ebdSchin #include <ctype.h>
85da2e3ebdSchin
86da2e3ebdSchin #include "sfhdr.h"
87da2e3ebdSchin
88da2e3ebdSchin #if !__STD_C && !defined(const)
89da2e3ebdSchin #define const
90da2e3ebdSchin #endif
91da2e3ebdSchin
92da2e3ebdSchin #ifndef ERANGE
93da2e3ebdSchin #define ERANGE EINVAL
94da2e3ebdSchin #endif
95da2e3ebdSchin
96da2e3ebdSchin #define QL 01
97da2e3ebdSchin #define QU 02
98da2e3ebdSchin
99da2e3ebdSchin #define S2I_umax (~((S2I_unumber)0))
100da2e3ebdSchin
101da2e3ebdSchin #if S2I_unsigned
102da2e3ebdSchin #define S2I_type S2I_unumber
103da2e3ebdSchin #define S2I_min 0
104da2e3ebdSchin #define S2I_max S2I_umax
105da2e3ebdSchin #else
106da2e3ebdSchin #define S2I_type S2I_number
107da2e3ebdSchin #define S2I_min (-S2I_max-1)
108da2e3ebdSchin #define S2I_max (S2I_umax>>1)
109da2e3ebdSchin #endif
110da2e3ebdSchin
111da2e3ebdSchin #if S2I_size
112da2e3ebdSchin #define S2I_valid(s) ((s)<(z))
113da2e3ebdSchin #else
114da2e3ebdSchin #define S2I_valid(s) 1
115da2e3ebdSchin #endif
116da2e3ebdSchin
117da2e3ebdSchin #define ADDOVER(n,c,s) ((S2I_umax-(n))<((S2I_unumber)((c)+(s))))
118da2e3ebdSchin #define MPYOVER(n,c) (((S2I_unumber)(n))>(S2I_umax/(c)))
119da2e3ebdSchin
120da2e3ebdSchin static const S2I_unumber mm[] =
121da2e3ebdSchin {
122da2e3ebdSchin 0,
123da2e3ebdSchin S2I_umax / 1,
124da2e3ebdSchin S2I_umax / 2,
125da2e3ebdSchin S2I_umax / 3,
126da2e3ebdSchin S2I_umax / 4,
127da2e3ebdSchin S2I_umax / 5,
128da2e3ebdSchin S2I_umax / 6,
129da2e3ebdSchin S2I_umax / 7,
130da2e3ebdSchin S2I_umax / 8,
131da2e3ebdSchin S2I_umax / 9,
132da2e3ebdSchin S2I_umax / 10,
133da2e3ebdSchin S2I_umax / 11,
134da2e3ebdSchin S2I_umax / 12,
135da2e3ebdSchin S2I_umax / 13,
136da2e3ebdSchin S2I_umax / 14,
137da2e3ebdSchin S2I_umax / 15,
138da2e3ebdSchin S2I_umax / 16,
139da2e3ebdSchin S2I_umax / 17,
140da2e3ebdSchin S2I_umax / 18,
141da2e3ebdSchin S2I_umax / 19,
142da2e3ebdSchin S2I_umax / 20,
143da2e3ebdSchin S2I_umax / 21,
144da2e3ebdSchin S2I_umax / 22,
145da2e3ebdSchin S2I_umax / 23,
146da2e3ebdSchin S2I_umax / 24,
147da2e3ebdSchin S2I_umax / 25,
148da2e3ebdSchin S2I_umax / 26,
149da2e3ebdSchin S2I_umax / 27,
150da2e3ebdSchin S2I_umax / 28,
151da2e3ebdSchin S2I_umax / 29,
152da2e3ebdSchin S2I_umax / 30,
153da2e3ebdSchin S2I_umax / 31,
154da2e3ebdSchin S2I_umax / 32,
155da2e3ebdSchin S2I_umax / 33,
156da2e3ebdSchin S2I_umax / 34,
157da2e3ebdSchin S2I_umax / 35,
158da2e3ebdSchin S2I_umax / 36,
159da2e3ebdSchin S2I_umax / 37,
160da2e3ebdSchin S2I_umax / 38,
161da2e3ebdSchin S2I_umax / 39,
162da2e3ebdSchin S2I_umax / 40,
163da2e3ebdSchin S2I_umax / 41,
164da2e3ebdSchin S2I_umax / 42,
165da2e3ebdSchin S2I_umax / 43,
166da2e3ebdSchin S2I_umax / 44,
167da2e3ebdSchin S2I_umax / 45,
168da2e3ebdSchin S2I_umax / 46,
169da2e3ebdSchin S2I_umax / 47,
170da2e3ebdSchin S2I_umax / 48,
171da2e3ebdSchin S2I_umax / 49,
172da2e3ebdSchin S2I_umax / 50,
173da2e3ebdSchin S2I_umax / 51,
174da2e3ebdSchin S2I_umax / 52,
175da2e3ebdSchin S2I_umax / 53,
176da2e3ebdSchin S2I_umax / 54,
177da2e3ebdSchin S2I_umax / 55,
178da2e3ebdSchin S2I_umax / 56,
179da2e3ebdSchin S2I_umax / 57,
180da2e3ebdSchin S2I_umax / 58,
181da2e3ebdSchin S2I_umax / 59,
182da2e3ebdSchin S2I_umax / 60,
183da2e3ebdSchin S2I_umax / 61,
184da2e3ebdSchin S2I_umax / 62,
185da2e3ebdSchin S2I_umax / 63,
186da2e3ebdSchin S2I_umax / 64,
187da2e3ebdSchin };
188da2e3ebdSchin
189da2e3ebdSchin #if defined(__EXPORT__)
190da2e3ebdSchin #define extern __EXPORT__
191da2e3ebdSchin #endif
192da2e3ebdSchin extern S2I_type
193da2e3ebdSchin #undef extern
194da2e3ebdSchin #if S2I_size
195da2e3ebdSchin #if S2I_multiplier
196da2e3ebdSchin #if __STD_C
S2I_function(const char * a,size_t size,char ** e,char * basep,int m)197da2e3ebdSchin S2I_function(const char* a, size_t size, char** e, char* basep, int m)
198da2e3ebdSchin #else
199da2e3ebdSchin S2I_function(a, size, e, basep, m) const char* a; size_t size; char** e; char* basep; int m;
200da2e3ebdSchin #endif
201da2e3ebdSchin #else
202da2e3ebdSchin #if __STD_C
203da2e3ebdSchin S2I_function(const char* a, size_t size, char** e, int base)
204da2e3ebdSchin #else
205da2e3ebdSchin S2I_function(a, size, e, base) const char* a; size_t size; char** e; int base;
206da2e3ebdSchin #endif
207da2e3ebdSchin #endif
208da2e3ebdSchin #else
209da2e3ebdSchin #if S2I_multiplier
210da2e3ebdSchin #if __STD_C
211da2e3ebdSchin S2I_function(const char* a, char** e, char* basep, int m)
212da2e3ebdSchin #else
213da2e3ebdSchin S2I_function(a, e, basep, m) const char* a; char** e; char* basep; int m;
214da2e3ebdSchin #endif
215da2e3ebdSchin #else
216da2e3ebdSchin #if __STD_C
217da2e3ebdSchin S2I_function(const char* a, char** e, int base)
218da2e3ebdSchin #else
219da2e3ebdSchin S2I_function(a, e, base) const char* a; char** e; int base;
220da2e3ebdSchin #endif
221da2e3ebdSchin #endif
222da2e3ebdSchin #endif
223da2e3ebdSchin {
224da2e3ebdSchin register unsigned char* s = (unsigned char*)a;
225da2e3ebdSchin #if S2I_size
226da2e3ebdSchin register unsigned char* z = s + size;
227da2e3ebdSchin #endif
228da2e3ebdSchin register S2I_unumber n;
229da2e3ebdSchin register S2I_unumber x;
230da2e3ebdSchin register int c;
231da2e3ebdSchin register int shift;
232da2e3ebdSchin register unsigned char* p;
233da2e3ebdSchin register unsigned char* cv;
234da2e3ebdSchin unsigned char* b;
235da2e3ebdSchin unsigned char* k;
236da2e3ebdSchin S2I_unumber v;
237da2e3ebdSchin #if S2I_multiplier
238da2e3ebdSchin register int base;
239da2e3ebdSchin #endif
240da2e3ebdSchin int negative;
241da2e3ebdSchin int overflow = 0;
242da2e3ebdSchin int decimal = 0;
243da2e3ebdSchin int thousand = 0;
244da2e3ebdSchin #if !S2I_unsigned
245da2e3ebdSchin int qualifier = 0;
246da2e3ebdSchin #endif
247da2e3ebdSchin
248da2e3ebdSchin #if S2I_multiplier
249da2e3ebdSchin base = basep ? *((unsigned char*)basep) : 0;
250da2e3ebdSchin #else
251da2e3ebdSchin if (base > 36 && base <= SF_RADIX)
252da2e3ebdSchin {
253da2e3ebdSchin static int conformance = -1;
254da2e3ebdSchin
255da2e3ebdSchin if (conformance < 0)
256da2e3ebdSchin conformance = !strcmp(astconf("CONFORMANCE", NiL, NiL), "standard");
257da2e3ebdSchin if (conformance)
258da2e3ebdSchin base = 1;
259da2e3ebdSchin }
260da2e3ebdSchin #endif
261da2e3ebdSchin if (base && (base < 2 || base > SF_RADIX))
262da2e3ebdSchin {
263da2e3ebdSchin errno = EINVAL;
264da2e3ebdSchin return 0;
265da2e3ebdSchin }
266da2e3ebdSchin while (S2I_valid(s) && isspace(*s))
267da2e3ebdSchin s++;
268da2e3ebdSchin if ((negative = S2I_valid(s) && (*s == '-')) || S2I_valid(s) && *s == '+')
269da2e3ebdSchin k = ++s;
270da2e3ebdSchin else
271da2e3ebdSchin k = 0;
272da2e3ebdSchin p = s;
273da2e3ebdSchin if (!base)
274da2e3ebdSchin {
275da2e3ebdSchin if (S2I_valid(p) && (c = *p++) >= '0' && c <= '9')
276da2e3ebdSchin {
277da2e3ebdSchin n = c - '0';
278da2e3ebdSchin if (S2I_valid(p) && (c = *p) >= '0' && c <= '9')
279da2e3ebdSchin {
280da2e3ebdSchin n = (n << 3) + (n << 1) + c - '0';
281da2e3ebdSchin p++;
282da2e3ebdSchin }
283da2e3ebdSchin if (S2I_valid(p) && *p == '#')
284da2e3ebdSchin {
285da2e3ebdSchin if (n >= 2 && n <= 64)
286da2e3ebdSchin {
287da2e3ebdSchin k = s = p + 1;
288da2e3ebdSchin base = n;
289da2e3ebdSchin }
290da2e3ebdSchin }
291da2e3ebdSchin else if (base)
292da2e3ebdSchin base = 0;
293da2e3ebdSchin else if (S2I_valid(s) && *s == '0' && S2I_valid(s + 1))
294da2e3ebdSchin {
295da2e3ebdSchin if ((c = *(s + 1)) == 'x' || c == 'X')
296da2e3ebdSchin {
297da2e3ebdSchin k = s += 2;
298da2e3ebdSchin base = 16;
299da2e3ebdSchin }
300da2e3ebdSchin else if (c >= '0' && c <= '7')
301da2e3ebdSchin {
302da2e3ebdSchin s++;
303da2e3ebdSchin base = 8;
304da2e3ebdSchin }
305da2e3ebdSchin }
306da2e3ebdSchin }
307da2e3ebdSchin if (!base)
308da2e3ebdSchin base = 10;
309da2e3ebdSchin else if (base < 2 || base > SF_RADIX)
310da2e3ebdSchin {
311da2e3ebdSchin errno = EINVAL;
312da2e3ebdSchin return 0;
313da2e3ebdSchin }
314da2e3ebdSchin #if S2I_multiplier
315da2e3ebdSchin else
316da2e3ebdSchin {
317da2e3ebdSchin if (basep)
318da2e3ebdSchin *basep = base;
319da2e3ebdSchin m = -1;
320da2e3ebdSchin }
321da2e3ebdSchin #endif
322da2e3ebdSchin }
323da2e3ebdSchin #if S2I_multiplier
324da2e3ebdSchin else
325da2e3ebdSchin m = -1;
326da2e3ebdSchin #endif
327da2e3ebdSchin
328da2e3ebdSchin /*
329da2e3ebdSchin * this part transcribed from sfvscanf()
330da2e3ebdSchin */
331da2e3ebdSchin
332da2e3ebdSchin SFSETLOCALE(&decimal, &thousand);
333da2e3ebdSchin x = mm[base];
334da2e3ebdSchin n = 0;
335da2e3ebdSchin if (base == 10)
336da2e3ebdSchin {
337da2e3ebdSchin b = s;
338da2e3ebdSchin p = 0;
339da2e3ebdSchin for (;;)
340da2e3ebdSchin {
341da2e3ebdSchin if (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
342da2e3ebdSchin {
343da2e3ebdSchin if (n > x)
344da2e3ebdSchin overflow = 1;
345da2e3ebdSchin else
346da2e3ebdSchin {
347da2e3ebdSchin n = (n << 3) + (n << 1);
348da2e3ebdSchin c -= '0';
349da2e3ebdSchin if (ADDOVER(n, c, negative))
350da2e3ebdSchin overflow = 1;
351da2e3ebdSchin n += c;
352da2e3ebdSchin }
353da2e3ebdSchin }
354da2e3ebdSchin else if (p && (s - p) != (3 + S2I_valid(s)))
355da2e3ebdSchin {
356da2e3ebdSchin s = p;
357da2e3ebdSchin n = v;
358da2e3ebdSchin c = 0;
359da2e3ebdSchin break;
360da2e3ebdSchin }
3617c2fbfb3SApril Chin else if (!S2I_valid(s) || c != thousand)
362da2e3ebdSchin break;
363da2e3ebdSchin else if (!p && (s - b) > 4)
364da2e3ebdSchin {
365da2e3ebdSchin if (e)
366da2e3ebdSchin *e = (char*)s - 1;
367da2e3ebdSchin if (overflow)
368da2e3ebdSchin {
369da2e3ebdSchin errno = ERANGE;
370da2e3ebdSchin #if S2I_unsigned
371da2e3ebdSchin n = S2I_max;
372da2e3ebdSchin #else
373da2e3ebdSchin n = negative ? S2I_min : S2I_max;
374da2e3ebdSchin #endif
375da2e3ebdSchin }
376da2e3ebdSchin return n;
377da2e3ebdSchin }
378da2e3ebdSchin else
379da2e3ebdSchin {
380da2e3ebdSchin p = s;
381da2e3ebdSchin v = n;
382da2e3ebdSchin }
383da2e3ebdSchin }
384da2e3ebdSchin }
385da2e3ebdSchin else
386da2e3ebdSchin {
387da2e3ebdSchin SFCVINIT();
388da2e3ebdSchin cv = base <= 36 ? _Sfcv36 : _Sfcv64;
389da2e3ebdSchin if ((base & ~(base - 1)) == base)
390da2e3ebdSchin {
391da2e3ebdSchin #if !S2I_unsigned
392da2e3ebdSchin qualifier |= QU;
393da2e3ebdSchin #endif
394da2e3ebdSchin if (base < 8)
395da2e3ebdSchin shift = base < 4 ? 1 : 2;
396da2e3ebdSchin else if (base < 32)
397da2e3ebdSchin shift = base < 16 ? 3 : 4;
398da2e3ebdSchin else
399da2e3ebdSchin shift = base < 64 ? 5 : 6;
400da2e3ebdSchin while (S2I_valid(s) && (c = cv[*s++]) < base)
401da2e3ebdSchin {
402da2e3ebdSchin if (n > x)
403da2e3ebdSchin overflow = 1;
404da2e3ebdSchin else
405da2e3ebdSchin {
406da2e3ebdSchin n <<= shift;
407da2e3ebdSchin if (ADDOVER(n, c, negative))
408da2e3ebdSchin overflow = 1;
409da2e3ebdSchin n += c;
410da2e3ebdSchin }
411da2e3ebdSchin }
412da2e3ebdSchin }
413da2e3ebdSchin else
414da2e3ebdSchin while (S2I_valid(s) && (c = cv[*s++]) < base)
415da2e3ebdSchin {
416da2e3ebdSchin if (n > x)
417da2e3ebdSchin overflow = 1;
418da2e3ebdSchin else
419da2e3ebdSchin {
420da2e3ebdSchin n *= base;
421da2e3ebdSchin if (ADDOVER(n, c, negative))
422da2e3ebdSchin overflow = 1;
423da2e3ebdSchin n += c;
424da2e3ebdSchin }
425da2e3ebdSchin }
426da2e3ebdSchin c = *(s - 1);
427da2e3ebdSchin }
428da2e3ebdSchin
42934f9b3eeSRoland Mainz #if S2I_qualifier
43034f9b3eeSRoland Mainz
431da2e3ebdSchin /*
432da2e3ebdSchin * optional qualifier suffix
433da2e3ebdSchin */
434da2e3ebdSchin
435da2e3ebdSchin if (S2I_valid(s) && s > (unsigned char*)(a + 1))
436da2e3ebdSchin {
437da2e3ebdSchin base = 0;
438da2e3ebdSchin for (;;)
439da2e3ebdSchin {
440da2e3ebdSchin if (!(base & QL) && (c == 'l' || c == 'L'))
441da2e3ebdSchin {
442da2e3ebdSchin base |= QL;
443da2e3ebdSchin if (!S2I_valid(s))
444da2e3ebdSchin break;
445da2e3ebdSchin c = *s++;
446da2e3ebdSchin if (c == 'l' || c == 'L')
447da2e3ebdSchin {
448da2e3ebdSchin if (!S2I_valid(s))
449da2e3ebdSchin break;
450da2e3ebdSchin c = *s++;
451da2e3ebdSchin }
452da2e3ebdSchin }
453da2e3ebdSchin else if (!(base & QU) && (c == 'u' || c == 'U'))
454da2e3ebdSchin {
455da2e3ebdSchin base |= QU;
456da2e3ebdSchin #if !S2I_unsigned
457da2e3ebdSchin qualifier |= QU;
458da2e3ebdSchin #endif
459da2e3ebdSchin if (!S2I_valid(s))
460da2e3ebdSchin break;
461da2e3ebdSchin c = *s++;
462da2e3ebdSchin }
463da2e3ebdSchin else
464da2e3ebdSchin break;
465da2e3ebdSchin }
466da2e3ebdSchin }
46734f9b3eeSRoland Mainz #endif
468da2e3ebdSchin if (S2I_valid(s))
469da2e3ebdSchin {
470da2e3ebdSchin #if S2I_multiplier
471da2e3ebdSchin /*
472da2e3ebdSchin * optional multiplier suffix
473da2e3ebdSchin */
474da2e3ebdSchin
475da2e3ebdSchin if (m < 0 || s == (unsigned char*)(a + 1))
476da2e3ebdSchin s--;
477da2e3ebdSchin else
478da2e3ebdSchin {
479da2e3ebdSchin switch (c)
480da2e3ebdSchin {
481da2e3ebdSchin case 'b':
482da2e3ebdSchin case 'B':
483da2e3ebdSchin shift = 9;
484da2e3ebdSchin break;
485da2e3ebdSchin case 'k':
486da2e3ebdSchin case 'K':
487da2e3ebdSchin shift = 10;
488da2e3ebdSchin break;
489da2e3ebdSchin case 'm':
490da2e3ebdSchin case 'M':
491da2e3ebdSchin shift = 20;
492da2e3ebdSchin break;
493da2e3ebdSchin case 'g':
494da2e3ebdSchin case 'G':
495da2e3ebdSchin shift = 30;
496da2e3ebdSchin break;
497da2e3ebdSchin case 't':
498da2e3ebdSchin case 'T':
499da2e3ebdSchin shift = 40;
500da2e3ebdSchin break;
501da2e3ebdSchin case 'p':
502da2e3ebdSchin case 'P':
503da2e3ebdSchin shift = 50;
504da2e3ebdSchin break;
505da2e3ebdSchin case 'e':
506da2e3ebdSchin case 'E':
507da2e3ebdSchin shift = 60;
508da2e3ebdSchin break;
509da2e3ebdSchin default:
510da2e3ebdSchin if (m <= 1)
511da2e3ebdSchin v = 0;
512da2e3ebdSchin else if (c == decimal && S2I_valid(s))
513da2e3ebdSchin {
514da2e3ebdSchin if (MPYOVER(n, m))
515da2e3ebdSchin overflow = 1;
516da2e3ebdSchin n *= m;
517da2e3ebdSchin v = 0;
518da2e3ebdSchin while (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
519da2e3ebdSchin v += (m /= 10) * (c - '0');
520da2e3ebdSchin if (ADDOVER(n, v, negative))
521da2e3ebdSchin overflow = 1;
522da2e3ebdSchin n += v;
523da2e3ebdSchin v = 0;
524da2e3ebdSchin }
525da2e3ebdSchin else
526da2e3ebdSchin v = m;
527da2e3ebdSchin s--;
528da2e3ebdSchin shift = 0;
529da2e3ebdSchin break;
530da2e3ebdSchin }
531da2e3ebdSchin if (shift)
532da2e3ebdSchin {
533da2e3ebdSchin if (S2I_valid(s))
534da2e3ebdSchin switch (*s)
535da2e3ebdSchin {
536da2e3ebdSchin case 'b':
537da2e3ebdSchin case 'B':
538da2e3ebdSchin case 'i':
539da2e3ebdSchin case 'I':
540da2e3ebdSchin s++;
541da2e3ebdSchin break;
542da2e3ebdSchin }
543da2e3ebdSchin #if S2I_unsigned
544da2e3ebdSchin if (shift >= (sizeof(S2I_type) * CHAR_BIT))
545da2e3ebdSchin #else
546da2e3ebdSchin if (shift >= (sizeof(S2I_type) * CHAR_BIT - 1))
547da2e3ebdSchin #endif
548da2e3ebdSchin {
549da2e3ebdSchin v = 0;
550da2e3ebdSchin overflow = 1;
551da2e3ebdSchin }
552da2e3ebdSchin else
553da2e3ebdSchin v = ((S2I_unumber)1) << shift;
554da2e3ebdSchin }
555da2e3ebdSchin if (v)
556da2e3ebdSchin {
557da2e3ebdSchin if (MPYOVER(n, v))
558da2e3ebdSchin overflow = 1;
559da2e3ebdSchin n *= v;
560da2e3ebdSchin }
561da2e3ebdSchin }
562da2e3ebdSchin #else
563da2e3ebdSchin s--;
564da2e3ebdSchin #endif
565da2e3ebdSchin }
566da2e3ebdSchin if (s == k)
567da2e3ebdSchin {
568da2e3ebdSchin s--;
569da2e3ebdSchin #if S2I_multiplier
570da2e3ebdSchin if (basep)
571da2e3ebdSchin *basep = 10;
572da2e3ebdSchin #endif
573da2e3ebdSchin }
574da2e3ebdSchin #if !S2I_unsigned
575da2e3ebdSchin else if (!(qualifier & QU))
576da2e3ebdSchin {
577da2e3ebdSchin if (negative)
578da2e3ebdSchin {
579da2e3ebdSchin if (!n)
580da2e3ebdSchin {
581da2e3ebdSchin b = k;
582da2e3ebdSchin do
583da2e3ebdSchin {
584da2e3ebdSchin if (b >= s)
585da2e3ebdSchin {
586da2e3ebdSchin negative = 0;
587da2e3ebdSchin break;
588da2e3ebdSchin }
589da2e3ebdSchin } while (*b++ == '0');
590da2e3ebdSchin }
591da2e3ebdSchin if (negative && (n - 1) > S2I_max)
592da2e3ebdSchin overflow = 1;
593da2e3ebdSchin }
594da2e3ebdSchin else if (n > S2I_max)
595da2e3ebdSchin overflow = 1;
596da2e3ebdSchin }
597da2e3ebdSchin #endif
598da2e3ebdSchin if (e)
599da2e3ebdSchin *e = (char*)s;
600da2e3ebdSchin if (overflow)
601da2e3ebdSchin {
602da2e3ebdSchin #if !S2I_unsigned
603da2e3ebdSchin if (negative)
604da2e3ebdSchin {
605da2e3ebdSchin if (x << 1)
606da2e3ebdSchin errno = ERANGE;
607da2e3ebdSchin return (S2I_type)S2I_min;
608da2e3ebdSchin }
609da2e3ebdSchin #endif
610da2e3ebdSchin errno = ERANGE;
611da2e3ebdSchin return (S2I_type)S2I_max;
612da2e3ebdSchin }
613da2e3ebdSchin return negative ? -n : n;
614da2e3ebdSchin }
615