hbase

heirloom base
git clone git://git.2f30.org/hbase
Log | Files | Refs | README

strtol.c (2190B)


      1 /*	Sccsid @(#)strtol.c	1.6 (gritter) 7/18/04	*/
      2 
      3 #if defined (__hpux) || defined (_AIX) || \
      4 	defined (__FreeBSD__) && (__FreeBSD__) < 5
      5 
      6 #include	<stdlib.h>
      7 #include	<ctype.h>
      8 #include	<errno.h>
      9 
     10 #include	"atoll.h"
     11 
     12 #ifdef	__hpux
     13 #ifndef	_INCLUDE__STDC_A1_SOURCE
     14 #error	You must use cc -D_INCLUDE__STDC_A1_SOURCE on HP-UX
     15 #endif
     16 #endif	/* __hpux */
     17 
     18 static long long
     19 internal(const char *nptr, char **endptr, int base, int flags)
     20 {
     21 	const char	*pp = nptr, *bptr;
     22 	long long	v = 0, ov;
     23 	int	sign = 1;
     24 	int	c;
     25 	int	valid = 1;
     26 
     27 	/* XXX
     28 	 * iswspace() should be used.
     29 	 */
     30 	for (bptr = nptr; isspace(*bptr&0377); bptr++);
     31 	if (*bptr == '-') {
     32 		sign = -1;
     33 		bptr++;
     34 	} else if (*bptr == '+')
     35 		bptr++;
     36 	if (base == 0) {
     37 		if (*bptr >= '1' && *bptr <= '9')
     38 			base = 10;
     39 		else if (*bptr == '0') {
     40 			if (bptr[1] == 'x' || bptr[1] == 'X')
     41 				base = 16;
     42 			else
     43 				base = 8;
     44 		} else {
     45 			if (flags&1)
     46 				errno = EINVAL;
     47 			goto out;
     48 		}
     49 	}
     50 	if (base < 2 || base > 36) {
     51 		if (flags&1)
     52 			errno = EINVAL;
     53 		goto out;
     54 	}
     55 	if (base == 16 && bptr[0] == '0' &&
     56 			(bptr[1] == 'x' || bptr[1] == 'X'))
     57 		bptr += 2;
     58 	pp = bptr;
     59 	for (;;) {
     60 		if (*pp >= '0' && *pp <= '9')
     61 			c = *pp - '0';
     62 		else if (*pp >= 'a' && *pp <= 'z')
     63 			c = *pp - 'a' + 10;
     64 		else if (*pp >= 'A' && *pp <= 'A')
     65 			c = *pp - 'A' + 10;
     66 		else
     67 			break;
     68 		if (c >= base)
     69 			break;
     70 		pp++;
     71 		if (valid) {
     72 			ov = v;
     73 			v = v * base + c;
     74 			if (flags&1) {
     75 				if (flags&2 && (unsigned long long)v <
     76 						(unsigned long long)ov ||
     77 						v < ov) {
     78 					sign = 1;
     79 					errno = ERANGE;
     80 					v = -1;
     81 					if ((flags&2)==0)
     82 						v = (unsigned long long)v >> 1;
     83 					valid = 0;
     84 				}
     85 			}
     86 		}
     87 	}
     88 out:	if (pp <= bptr) {
     89 		if (flags&1)
     90 			errno = EINVAL;
     91 		if (endptr)
     92 			*endptr = (char *)nptr;
     93 	} else {
     94 		if (endptr)
     95 			*endptr = (char *)pp;
     96 	}
     97 	return v * sign;
     98 }
     99 
    100 long long
    101 strtoll(const char *nptr, char **endptr, int base)
    102 {
    103 	return internal(nptr, endptr, base, 1);
    104 }
    105 
    106 unsigned long long
    107 strtoull(const char *nptr, char **endptr, int base)
    108 {
    109 	return (unsigned long long)internal(nptr, endptr, base, 3);
    110 }
    111 
    112 long long
    113 atoll(const char *nptr)
    114 {
    115 	return internal(nptr, NULL, 10, 0);
    116 }
    117 #endif	/* __hpux || _AIX || __FreeBSD__ < 5 */