xref: /inferno-os/lib9/strtoll.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth #include "lib9.h"
2*37da2899SCharles.Forsyth 
3*37da2899SCharles.Forsyth vlong
strtoll(const char * nptr,char ** endptr,int base)4*37da2899SCharles.Forsyth strtoll(const char *nptr, char **endptr, int base)
5*37da2899SCharles.Forsyth {
6*37da2899SCharles.Forsyth 	const char *p;
7*37da2899SCharles.Forsyth 	vlong n;
8*37da2899SCharles.Forsyth 	int c, v, neg, ndig;
9*37da2899SCharles.Forsyth 
10*37da2899SCharles.Forsyth 	p = nptr;
11*37da2899SCharles.Forsyth 	neg = 0;
12*37da2899SCharles.Forsyth 	n = 0;
13*37da2899SCharles.Forsyth 	ndig = 0;
14*37da2899SCharles.Forsyth 
15*37da2899SCharles.Forsyth 	/*
16*37da2899SCharles.Forsyth 	 * White space
17*37da2899SCharles.Forsyth 	 */
18*37da2899SCharles.Forsyth 	for(;;p++){
19*37da2899SCharles.Forsyth 		switch(*p){
20*37da2899SCharles.Forsyth 		case ' ':
21*37da2899SCharles.Forsyth 		case '\t':
22*37da2899SCharles.Forsyth 		case '\n':
23*37da2899SCharles.Forsyth 		case '\f':
24*37da2899SCharles.Forsyth 		case '\r':
25*37da2899SCharles.Forsyth 		case '\v':
26*37da2899SCharles.Forsyth 			continue;
27*37da2899SCharles.Forsyth 		}
28*37da2899SCharles.Forsyth 		break;
29*37da2899SCharles.Forsyth 	}
30*37da2899SCharles.Forsyth 
31*37da2899SCharles.Forsyth 	/*
32*37da2899SCharles.Forsyth 	 * Sign
33*37da2899SCharles.Forsyth 	 */
34*37da2899SCharles.Forsyth 	if(*p=='-' || *p=='+')
35*37da2899SCharles.Forsyth 		if(*p++ == '-')
36*37da2899SCharles.Forsyth 			neg = 1;
37*37da2899SCharles.Forsyth 
38*37da2899SCharles.Forsyth 	/*
39*37da2899SCharles.Forsyth 	 * Base
40*37da2899SCharles.Forsyth 	 */
41*37da2899SCharles.Forsyth 	if(base==0){
42*37da2899SCharles.Forsyth 		if(*p != '0')
43*37da2899SCharles.Forsyth 			base = 10;
44*37da2899SCharles.Forsyth 		else{
45*37da2899SCharles.Forsyth 			base = 8;
46*37da2899SCharles.Forsyth 			if(p[1]=='x' || p[1]=='X'){
47*37da2899SCharles.Forsyth 				p += 2;
48*37da2899SCharles.Forsyth 				base = 16;
49*37da2899SCharles.Forsyth 			}
50*37da2899SCharles.Forsyth 		}
51*37da2899SCharles.Forsyth 	}else if(base==16 && *p=='0'){
52*37da2899SCharles.Forsyth 		if(p[1]=='x' || p[1]=='X')
53*37da2899SCharles.Forsyth 			p += 2;
54*37da2899SCharles.Forsyth 	}else if(base<0 || 36<base)
55*37da2899SCharles.Forsyth 		goto Return;
56*37da2899SCharles.Forsyth 
57*37da2899SCharles.Forsyth 	/*
58*37da2899SCharles.Forsyth 	 * Non-empty sequence of digits
59*37da2899SCharles.Forsyth 	 */
60*37da2899SCharles.Forsyth 	for(;; p++,ndig++){
61*37da2899SCharles.Forsyth 		c = *p;
62*37da2899SCharles.Forsyth 		v = base;
63*37da2899SCharles.Forsyth 		if('0'<=c && c<='9')
64*37da2899SCharles.Forsyth 			v = c - '0';
65*37da2899SCharles.Forsyth 		else if('a'<=c && c<='z')
66*37da2899SCharles.Forsyth 			v = c - 'a' + 10;
67*37da2899SCharles.Forsyth 		else if('A'<=c && c<='Z')
68*37da2899SCharles.Forsyth 			v = c - 'A' + 10;
69*37da2899SCharles.Forsyth 		if(v >= base)
70*37da2899SCharles.Forsyth 			break;
71*37da2899SCharles.Forsyth 		n = n*base + v;
72*37da2899SCharles.Forsyth 	}
73*37da2899SCharles.Forsyth     Return:
74*37da2899SCharles.Forsyth 	if(ndig == 0)
75*37da2899SCharles.Forsyth 		p = nptr;
76*37da2899SCharles.Forsyth 	if(endptr)
77*37da2899SCharles.Forsyth 		*endptr = (char*) p;
78*37da2899SCharles.Forsyth 	if(neg)
79*37da2899SCharles.Forsyth 		return -n;
80*37da2899SCharles.Forsyth 	return n;
81*37da2899SCharles.Forsyth }
82