14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin /*
234887Schin * AT&T Research
244887Schin * Glenn Fowler
254887Schin * Phong Vo
264887Schin *
274887Schin * common header and implementation for
284887Schin *
294887Schin * strtol strtoul strton
304887Schin * strtoll strtoull strtonll
314887Schin * strntol strntoul strnton
324887Schin * strntoll strntoull strntonll
334887Schin *
344887Schin * define these macros to instantiate an implementation:
354887Schin *
364887Schin * S2I_function the function name
374887Schin * S2I_number the signed number type
384887Schin * S2I_unumber the unsigned number type
394887Schin * S2I_unsigned 1 for unsigned, 0 for signed
4010898Sroland.mainz@nrubsig.org * S2I_qualifier 1 for optional qualifier suffix, 0 otherwise
414887Schin * S2I_multiplier 1 for optional multiplier suffix, 0 otherwise
424887Schin * S2I_size the second argument is the input string size
434887Schin *
444887Schin * convert string to number
454887Schin * errno=ERANGE on overflow (LONG_MAX) or underflow (LONG_MIN)
464887Schin * if non-null e will point to first unrecognized char in s
474887Schin * if basep!=0 it points to the default base on input and
484887Schin * will point to the explicit base on return
494887Schin * a default base of 0 will determine the base from the input
504887Schin * a default base of 1 will determine the base from the input using bb#*
514887Schin * a base prefix in the string overrides *b
524887Schin * *b will not be set if the string has no base prefix
534887Schin * if m>1 and no multipler was specified then the result is multiplied by m
544887Schin * if m<0 then multipliers are not consumed
554887Schin * if a base arg or prefix is specified then multiplier is not consumed
564887Schin *
574887Schin * integer numbers are of the form:
584887Schin *
594887Schin * [sign][base][number[qualifier]][multiplier]
604887Schin *
614887Schin * base: nnn# base nnn
624887Schin * 0[xX] hex
634887Schin * 0 octal
644887Schin * [1-9] decimal
654887Schin *
664887Schin * number: [0-9a-zA-Z]*
674887Schin *
684887Schin * qualifier: [lL]
694887Schin * [uU]
704887Schin * [uU][lL]
714887Schin * [lL][uU]
724887Schin * [lL][lL][uU]
734887Schin * [uU][lL][lL]
744887Schin *
754887Schin * multiplier: . pseudo-float if m>1
764887Schin * [bB] block (512)
774887Schin * [cC] char (1)
784887Schin * [gG] giga (1024*1024*1024)
794887Schin * [kK] kilo (1024)
804887Schin * [mM] mega (1024*1024)
814887Schin */
824887Schin
834887Schin #include <ast.h>
844887Schin #include <ctype.h>
854887Schin
864887Schin #include "sfhdr.h"
874887Schin
884887Schin #if !__STD_C && !defined(const)
894887Schin #define const
904887Schin #endif
914887Schin
924887Schin #ifndef ERANGE
934887Schin #define ERANGE EINVAL
944887Schin #endif
954887Schin
964887Schin #define QL 01
974887Schin #define QU 02
984887Schin
994887Schin #define S2I_umax (~((S2I_unumber)0))
1004887Schin
1014887Schin #if S2I_unsigned
1024887Schin #define S2I_type S2I_unumber
1034887Schin #define S2I_min 0
1044887Schin #define S2I_max S2I_umax
1054887Schin #else
1064887Schin #define S2I_type S2I_number
1074887Schin #define S2I_min (-S2I_max-1)
1084887Schin #define S2I_max (S2I_umax>>1)
1094887Schin #endif
1104887Schin
1114887Schin #if S2I_size
1124887Schin #define S2I_valid(s) ((s)<(z))
1134887Schin #else
1144887Schin #define S2I_valid(s) 1
1154887Schin #endif
1164887Schin
1174887Schin #define ADDOVER(n,c,s) ((S2I_umax-(n))<((S2I_unumber)((c)+(s))))
1184887Schin #define MPYOVER(n,c) (((S2I_unumber)(n))>(S2I_umax/(c)))
1194887Schin
1204887Schin static const S2I_unumber mm[] =
1214887Schin {
1224887Schin 0,
1234887Schin S2I_umax / 1,
1244887Schin S2I_umax / 2,
1254887Schin S2I_umax / 3,
1264887Schin S2I_umax / 4,
1274887Schin S2I_umax / 5,
1284887Schin S2I_umax / 6,
1294887Schin S2I_umax / 7,
1304887Schin S2I_umax / 8,
1314887Schin S2I_umax / 9,
1324887Schin S2I_umax / 10,
1334887Schin S2I_umax / 11,
1344887Schin S2I_umax / 12,
1354887Schin S2I_umax / 13,
1364887Schin S2I_umax / 14,
1374887Schin S2I_umax / 15,
1384887Schin S2I_umax / 16,
1394887Schin S2I_umax / 17,
1404887Schin S2I_umax / 18,
1414887Schin S2I_umax / 19,
1424887Schin S2I_umax / 20,
1434887Schin S2I_umax / 21,
1444887Schin S2I_umax / 22,
1454887Schin S2I_umax / 23,
1464887Schin S2I_umax / 24,
1474887Schin S2I_umax / 25,
1484887Schin S2I_umax / 26,
1494887Schin S2I_umax / 27,
1504887Schin S2I_umax / 28,
1514887Schin S2I_umax / 29,
1524887Schin S2I_umax / 30,
1534887Schin S2I_umax / 31,
1544887Schin S2I_umax / 32,
1554887Schin S2I_umax / 33,
1564887Schin S2I_umax / 34,
1574887Schin S2I_umax / 35,
1584887Schin S2I_umax / 36,
1594887Schin S2I_umax / 37,
1604887Schin S2I_umax / 38,
1614887Schin S2I_umax / 39,
1624887Schin S2I_umax / 40,
1634887Schin S2I_umax / 41,
1644887Schin S2I_umax / 42,
1654887Schin S2I_umax / 43,
1664887Schin S2I_umax / 44,
1674887Schin S2I_umax / 45,
1684887Schin S2I_umax / 46,
1694887Schin S2I_umax / 47,
1704887Schin S2I_umax / 48,
1714887Schin S2I_umax / 49,
1724887Schin S2I_umax / 50,
1734887Schin S2I_umax / 51,
1744887Schin S2I_umax / 52,
1754887Schin S2I_umax / 53,
1764887Schin S2I_umax / 54,
1774887Schin S2I_umax / 55,
1784887Schin S2I_umax / 56,
1794887Schin S2I_umax / 57,
1804887Schin S2I_umax / 58,
1814887Schin S2I_umax / 59,
1824887Schin S2I_umax / 60,
1834887Schin S2I_umax / 61,
1844887Schin S2I_umax / 62,
1854887Schin S2I_umax / 63,
1864887Schin S2I_umax / 64,
1874887Schin };
1884887Schin
1894887Schin #if defined(__EXPORT__)
1904887Schin #define extern __EXPORT__
1914887Schin #endif
1924887Schin extern S2I_type
1934887Schin #undef extern
1944887Schin #if S2I_size
1954887Schin #if S2I_multiplier
1964887Schin #if __STD_C
S2I_function(const char * a,size_t size,char ** e,char * basep,int m)1974887Schin S2I_function(const char* a, size_t size, char** e, char* basep, int m)
1984887Schin #else
1994887Schin S2I_function(a, size, e, basep, m) const char* a; size_t size; char** e; char* basep; int m;
2004887Schin #endif
2014887Schin #else
2024887Schin #if __STD_C
2034887Schin S2I_function(const char* a, size_t size, char** e, int base)
2044887Schin #else
2054887Schin S2I_function(a, size, e, base) const char* a; size_t size; char** e; int base;
2064887Schin #endif
2074887Schin #endif
2084887Schin #else
2094887Schin #if S2I_multiplier
2104887Schin #if __STD_C
2114887Schin S2I_function(const char* a, char** e, char* basep, int m)
2124887Schin #else
2134887Schin S2I_function(a, e, basep, m) const char* a; char** e; char* basep; int m;
2144887Schin #endif
2154887Schin #else
2164887Schin #if __STD_C
2174887Schin S2I_function(const char* a, char** e, int base)
2184887Schin #else
2194887Schin S2I_function(a, e, base) const char* a; char** e; int base;
2204887Schin #endif
2214887Schin #endif
2224887Schin #endif
2234887Schin {
2244887Schin register unsigned char* s = (unsigned char*)a;
2254887Schin #if S2I_size
2264887Schin register unsigned char* z = s + size;
2274887Schin #endif
2284887Schin register S2I_unumber n;
2294887Schin register S2I_unumber x;
2304887Schin register int c;
2314887Schin register int shift;
2324887Schin register unsigned char* p;
2334887Schin register unsigned char* cv;
2344887Schin unsigned char* b;
2354887Schin unsigned char* k;
2364887Schin S2I_unumber v;
2374887Schin #if S2I_multiplier
2384887Schin register int base;
2394887Schin #endif
2404887Schin int negative;
2414887Schin int overflow = 0;
2424887Schin int decimal = 0;
2434887Schin int thousand = 0;
2444887Schin #if !S2I_unsigned
2454887Schin int qualifier = 0;
2464887Schin #endif
2474887Schin
2484887Schin #if S2I_multiplier
2494887Schin base = basep ? *((unsigned char*)basep) : 0;
2504887Schin #else
2514887Schin if (base > 36 && base <= SF_RADIX)
2524887Schin {
2534887Schin static int conformance = -1;
2544887Schin
2554887Schin if (conformance < 0)
2564887Schin conformance = !strcmp(astconf("CONFORMANCE", NiL, NiL), "standard");
2574887Schin if (conformance)
2584887Schin base = 1;
2594887Schin }
2604887Schin #endif
2614887Schin if (base && (base < 2 || base > SF_RADIX))
2624887Schin {
2634887Schin errno = EINVAL;
2644887Schin return 0;
2654887Schin }
2664887Schin while (S2I_valid(s) && isspace(*s))
2674887Schin s++;
2684887Schin if ((negative = S2I_valid(s) && (*s == '-')) || S2I_valid(s) && *s == '+')
2694887Schin k = ++s;
2704887Schin else
2714887Schin k = 0;
2724887Schin p = s;
2734887Schin if (!base)
2744887Schin {
2754887Schin if (S2I_valid(p) && (c = *p++) >= '0' && c <= '9')
2764887Schin {
2774887Schin n = c - '0';
2784887Schin if (S2I_valid(p) && (c = *p) >= '0' && c <= '9')
2794887Schin {
2804887Schin n = (n << 3) + (n << 1) + c - '0';
2814887Schin p++;
2824887Schin }
2834887Schin if (S2I_valid(p) && *p == '#')
2844887Schin {
2854887Schin if (n >= 2 && n <= 64)
2864887Schin {
2874887Schin k = s = p + 1;
2884887Schin base = n;
2894887Schin }
2904887Schin }
2914887Schin else if (base)
2924887Schin base = 0;
2934887Schin else if (S2I_valid(s) && *s == '0' && S2I_valid(s + 1))
2944887Schin {
2954887Schin if ((c = *(s + 1)) == 'x' || c == 'X')
2964887Schin {
2974887Schin k = s += 2;
2984887Schin base = 16;
2994887Schin }
3004887Schin else if (c >= '0' && c <= '7')
3014887Schin {
3024887Schin s++;
3034887Schin base = 8;
3044887Schin }
3054887Schin }
3064887Schin }
3074887Schin if (!base)
3084887Schin base = 10;
3094887Schin else if (base < 2 || base > SF_RADIX)
3104887Schin {
3114887Schin errno = EINVAL;
3124887Schin return 0;
3134887Schin }
3144887Schin #if S2I_multiplier
3154887Schin else
3164887Schin {
3174887Schin if (basep)
3184887Schin *basep = base;
3194887Schin m = -1;
3204887Schin }
3214887Schin #endif
3224887Schin }
3234887Schin #if S2I_multiplier
3244887Schin else
3254887Schin m = -1;
3264887Schin #endif
3274887Schin
3284887Schin /*
3294887Schin * this part transcribed from sfvscanf()
3304887Schin */
3314887Schin
3324887Schin SFSETLOCALE(&decimal, &thousand);
3334887Schin x = mm[base];
3344887Schin n = 0;
3354887Schin if (base == 10)
3364887Schin {
3374887Schin b = s;
3384887Schin p = 0;
3394887Schin for (;;)
3404887Schin {
3414887Schin if (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
3424887Schin {
3434887Schin if (n > x)
3444887Schin overflow = 1;
3454887Schin else
3464887Schin {
3474887Schin n = (n << 3) + (n << 1);
3484887Schin c -= '0';
3494887Schin if (ADDOVER(n, c, negative))
3504887Schin overflow = 1;
3514887Schin n += c;
3524887Schin }
3534887Schin }
3544887Schin else if (p && (s - p) != (3 + S2I_valid(s)))
3554887Schin {
3564887Schin s = p;
3574887Schin n = v;
3584887Schin c = 0;
3594887Schin break;
3604887Schin }
3618462SApril.Chin@Sun.COM else if (!S2I_valid(s) || c != thousand)
3624887Schin break;
3634887Schin else if (!p && (s - b) > 4)
3644887Schin {
3654887Schin if (e)
3664887Schin *e = (char*)s - 1;
3674887Schin if (overflow)
3684887Schin {
3694887Schin errno = ERANGE;
3704887Schin #if S2I_unsigned
3714887Schin n = S2I_max;
3724887Schin #else
3734887Schin n = negative ? S2I_min : S2I_max;
3744887Schin #endif
3754887Schin }
3764887Schin return n;
3774887Schin }
3784887Schin else
3794887Schin {
3804887Schin p = s;
3814887Schin v = n;
3824887Schin }
3834887Schin }
3844887Schin }
3854887Schin else
3864887Schin {
3874887Schin SFCVINIT();
3884887Schin cv = base <= 36 ? _Sfcv36 : _Sfcv64;
3894887Schin if ((base & ~(base - 1)) == base)
3904887Schin {
3914887Schin #if !S2I_unsigned
3924887Schin qualifier |= QU;
3934887Schin #endif
3944887Schin if (base < 8)
3954887Schin shift = base < 4 ? 1 : 2;
3964887Schin else if (base < 32)
3974887Schin shift = base < 16 ? 3 : 4;
3984887Schin else
3994887Schin shift = base < 64 ? 5 : 6;
4004887Schin while (S2I_valid(s) && (c = cv[*s++]) < base)
4014887Schin {
4024887Schin if (n > x)
4034887Schin overflow = 1;
4044887Schin else
4054887Schin {
4064887Schin n <<= shift;
4074887Schin if (ADDOVER(n, c, negative))
4084887Schin overflow = 1;
4094887Schin n += c;
4104887Schin }
4114887Schin }
4124887Schin }
4134887Schin else
4144887Schin while (S2I_valid(s) && (c = cv[*s++]) < base)
4154887Schin {
4164887Schin if (n > x)
4174887Schin overflow = 1;
4184887Schin else
4194887Schin {
4204887Schin n *= base;
4214887Schin if (ADDOVER(n, c, negative))
4224887Schin overflow = 1;
4234887Schin n += c;
4244887Schin }
4254887Schin }
4264887Schin c = *(s - 1);
4274887Schin }
4284887Schin
42910898Sroland.mainz@nrubsig.org #if S2I_qualifier
43010898Sroland.mainz@nrubsig.org
4314887Schin /*
4324887Schin * optional qualifier suffix
4334887Schin */
4344887Schin
4354887Schin if (S2I_valid(s) && s > (unsigned char*)(a + 1))
4364887Schin {
4374887Schin base = 0;
4384887Schin for (;;)
4394887Schin {
4404887Schin if (!(base & QL) && (c == 'l' || c == 'L'))
4414887Schin {
4424887Schin base |= QL;
4434887Schin if (!S2I_valid(s))
4444887Schin break;
4454887Schin c = *s++;
4464887Schin if (c == 'l' || c == 'L')
4474887Schin {
4484887Schin if (!S2I_valid(s))
4494887Schin break;
4504887Schin c = *s++;
4514887Schin }
4524887Schin }
4534887Schin else if (!(base & QU) && (c == 'u' || c == 'U'))
4544887Schin {
4554887Schin base |= QU;
4564887Schin #if !S2I_unsigned
4574887Schin qualifier |= QU;
4584887Schin #endif
4594887Schin if (!S2I_valid(s))
4604887Schin break;
4614887Schin c = *s++;
4624887Schin }
4634887Schin else
4644887Schin break;
4654887Schin }
4664887Schin }
46710898Sroland.mainz@nrubsig.org #endif
4684887Schin if (S2I_valid(s))
4694887Schin {
4704887Schin #if S2I_multiplier
4714887Schin /*
4724887Schin * optional multiplier suffix
4734887Schin */
4744887Schin
4754887Schin if (m < 0 || s == (unsigned char*)(a + 1))
4764887Schin s--;
4774887Schin else
4784887Schin {
4794887Schin switch (c)
4804887Schin {
4814887Schin case 'b':
4824887Schin case 'B':
4834887Schin shift = 9;
4844887Schin break;
4854887Schin case 'k':
4864887Schin case 'K':
4874887Schin shift = 10;
4884887Schin break;
4894887Schin case 'm':
4904887Schin case 'M':
4914887Schin shift = 20;
4924887Schin break;
4934887Schin case 'g':
4944887Schin case 'G':
4954887Schin shift = 30;
4964887Schin break;
4974887Schin case 't':
4984887Schin case 'T':
4994887Schin shift = 40;
5004887Schin break;
5014887Schin case 'p':
5024887Schin case 'P':
5034887Schin shift = 50;
5044887Schin break;
5054887Schin case 'e':
5064887Schin case 'E':
5074887Schin shift = 60;
5084887Schin break;
5094887Schin default:
5104887Schin if (m <= 1)
5114887Schin v = 0;
5124887Schin else if (c == decimal && S2I_valid(s))
5134887Schin {
5144887Schin if (MPYOVER(n, m))
5154887Schin overflow = 1;
5164887Schin n *= m;
5174887Schin v = 0;
5184887Schin while (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
5194887Schin v += (m /= 10) * (c - '0');
5204887Schin if (ADDOVER(n, v, negative))
5214887Schin overflow = 1;
5224887Schin n += v;
5234887Schin v = 0;
5244887Schin }
5254887Schin else
5264887Schin v = m;
5274887Schin s--;
5284887Schin shift = 0;
5294887Schin break;
5304887Schin }
5314887Schin if (shift)
5324887Schin {
5334887Schin if (S2I_valid(s))
5344887Schin switch (*s)
5354887Schin {
5364887Schin case 'b':
5374887Schin case 'B':
5384887Schin case 'i':
5394887Schin case 'I':
5404887Schin s++;
5414887Schin break;
5424887Schin }
5434887Schin #if S2I_unsigned
5444887Schin if (shift >= (sizeof(S2I_type) * CHAR_BIT))
5454887Schin #else
5464887Schin if (shift >= (sizeof(S2I_type) * CHAR_BIT - 1))
5474887Schin #endif
5484887Schin {
5494887Schin v = 0;
5504887Schin overflow = 1;
5514887Schin }
5524887Schin else
5534887Schin v = ((S2I_unumber)1) << shift;
5544887Schin }
5554887Schin if (v)
5564887Schin {
5574887Schin if (MPYOVER(n, v))
5584887Schin overflow = 1;
5594887Schin n *= v;
5604887Schin }
5614887Schin }
5624887Schin #else
5634887Schin s--;
5644887Schin #endif
5654887Schin }
5664887Schin if (s == k)
5674887Schin {
5684887Schin s--;
5694887Schin #if S2I_multiplier
5704887Schin if (basep)
5714887Schin *basep = 10;
5724887Schin #endif
5734887Schin }
5744887Schin #if !S2I_unsigned
5754887Schin else if (!(qualifier & QU))
5764887Schin {
5774887Schin if (negative)
5784887Schin {
5794887Schin if (!n)
5804887Schin {
5814887Schin b = k;
5824887Schin do
5834887Schin {
5844887Schin if (b >= s)
5854887Schin {
5864887Schin negative = 0;
5874887Schin break;
5884887Schin }
5894887Schin } while (*b++ == '0');
5904887Schin }
5914887Schin if (negative && (n - 1) > S2I_max)
5924887Schin overflow = 1;
5934887Schin }
5944887Schin else if (n > S2I_max)
5954887Schin overflow = 1;
5964887Schin }
5974887Schin #endif
5984887Schin if (e)
5994887Schin *e = (char*)s;
6004887Schin if (overflow)
6014887Schin {
6024887Schin #if !S2I_unsigned
6034887Schin if (negative)
6044887Schin {
6054887Schin if (x << 1)
6064887Schin errno = ERANGE;
6074887Schin return (S2I_type)S2I_min;
6084887Schin }
6094887Schin #endif
6104887Schin errno = ERANGE;
6114887Schin return (S2I_type)S2I_max;
6124887Schin }
6134887Schin return negative ? -n : n;
6144887Schin }
615