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