Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/libmp/port/strtomp.c – Rev 33

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "os.h"
2
#include <mp.h>
3
#include "dat.h"
4
 
33 7u83 5
#define between(x,min,max)	(((min-1-x) & (x-max-1))>>8)
2 - 6
 
33 7u83 7
static int
8
dec16chr(int c)
9
{
10
	int o;
2 - 11
 
33 7u83 12
	o  = between(c, '0', '9') & (1+(c-'0'));
13
	o |= between(c, 'A', 'F') & (1+10+(c-'A'));
14
	o |= between(c, 'a', 'f') & (1+10+(c-'a'));
15
	return o-1;
16
}
2 - 17
 
33 7u83 18
static int
19
dec32chr(int c)
2 - 20
{
33 7u83 21
	int o;
2 - 22
 
33 7u83 23
	o  = between(c, 'A', 'Z') & (1+(c-'A'));
24
	o |= between(c, 'a', 'z') & (1+(c-'a'));
25
	o |= between(c, '2', '7') & (1+26+(c-'2'));
26
	return o-1;
27
}
2 - 28
 
33 7u83 29
static int
30
dec64chr(int c)
31
{
32
	int o;
2 - 33
 
33 7u83 34
	o  = between(c, 'A', 'Z') & (1+(c-'A'));
35
	o |= between(c, 'a', 'z') & (1+26+(c-'a'));
36
	o |= between(c, '0', '9') & (1+52+(c-'0'));
37
	o |= between(c, '+', '+') & (1+62);
38
	o |= between(c, '/', '/') & (1+63);
39
	return o-1;
2 - 40
}
41
 
33 7u83 42
 
43
 
2 - 44
static char*
33 7u83 45
frompow2(char *a, mpint *b, int s)
2 - 46
{
47
	char *p, *next;
33 7u83 48
	mpdigit x;
2 - 49
	int i;
50
 
33 7u83 51
	i = 1<<s;
52
	for(p = a; (dec16chr(*p) & 255) < i; p++)
53
		;
54
 
55
	mpbits(b, (p-a)*s);
2 - 56
	b->top = 0;
57
	next = p;
33 7u83 58
 
2 - 59
	while(p > a){
60
		x = 0;
33 7u83 61
		for(i = 0; i < Dbits; i += s){
2 - 62
			if(p <= a)
63
				break;
33 7u83 64
			x |= dec16chr(*--p)<<i;
2 - 65
		}
66
		b->p[b->top++] = x;
67
	}
68
	return next;
69
}
70
 
33 7u83 71
static char*
72
from8(char *a, mpint *b)
73
{
74
	char *p, *next;
75
	mpdigit x, y;
76
	int i;
77
 
78
	for(p = a; ((*p - '0') & 255) < 8; p++)
79
		;
80
 
81
	mpbits(b, (p-a)*3);
82
	b->top = 0;
83
	next = p;
84
 
85
	i = 0;
86
	x = y = 0;
87
	while(p > a){
88
		y = *--p - '0';
89
		x |= y << i;
90
		i += 3;
91
		if(i >= Dbits){
92
Digout:
93
			i -= Dbits;
94
			b->p[b->top++] = x;
95
			x = y >> 3-i;
96
		}
97
	}
98
	if(i > 0)
99
		goto Digout;
100
 
101
	return next;
102
}
103
 
2 - 104
static ulong mppow10[] = {
105
	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
106
};
107
 
108
static char*
109
from10(char *a, mpint *b)
110
{
111
	ulong x, y;
112
	mpint *pow, *r;
113
	int i;
114
 
115
	pow = mpnew(0);
116
	r = mpnew(0);
117
 
118
	b->top = 0;
119
	for(;;){
120
		// do a billion at a time in native arithmetic
121
		x = 0;
122
		for(i = 0; i < 9; i++){
33 7u83 123
			y = *a - '0';
124
			if(y > 9)
2 - 125
				break;
126
			a++;
127
			x *= 10;
128
			x += y;
129
		}
130
		if(i == 0)
131
			break;
132
 
133
		// accumulate into mpint
134
		uitomp(mppow10[i], pow);
135
		uitomp(x, r);
136
		mpmul(b, pow, b);
137
		mpadd(b, r, b);
33 7u83 138
		if(i < 9)
2 - 139
			break;
140
	}
141
	mpfree(pow);
142
	mpfree(r);
143
	return a;
144
}
145
 
146
static char*
33 7u83 147
fromdecx(char *a, mpint *b, int (*chr)(int), int (*dec)(uchar*, int, char*, int))
2 - 148
{
149
	char *buf = a;
150
	uchar *p;
151
	int n, m;
152
 
33 7u83 153
	b->top = 0;
154
	for(; (*chr)(*a) >= 0; a++)
2 - 155
		;
156
	n = a-buf;
33 7u83 157
	if(n > 0){
158
		p = malloc(n);
159
		if(p == nil)
160
			sysfatal("malloc: %r");
161
		m = (*dec)(p, n, buf, n);
162
		if(m > 0)
163
			betomp(p, m, b);
164
		free(p);
165
	}
2 - 166
	return a;
167
}
168
 
169
mpint*
170
strtomp(char *a, char **pp, int base, mpint *b)
171
{
172
	int sign;
173
	char *e;
174
 
33 7u83 175
	if(b == nil){
2 - 176
		b = mpnew(0);
33 7u83 177
		setmalloctag(b, getcallerpc(&a));
178
	}
2 - 179
 
180
	while(*a==' ' || *a=='\t')
181
		a++;
182
 
183
	sign = 1;
184
	for(;; a++){
185
		switch(*a){
186
		case '-':
187
			sign *= -1;
188
			continue;
189
		}
190
		break;
191
	}
192
 
33 7u83 193
	if(base == 0){
194
		base = 10;
195
		if(a[0] == '0'){
196
			if(a[1] == 'x' || a[1] == 'X') {
197
				a += 2;
198
				base = 16;
199
			} else if(a[1] == 'b' || a[1] == 'B') {
200
				a += 2;
201
				base = 2;
202
			} else if(a[1] >= '0' && a[1] <= '7') {
203
				a++;
204
				base = 8;
205
			}
206
		}
207
	}
208
 
2 - 209
	switch(base){
33 7u83 210
	case 2:
211
		e = frompow2(a, b, 1);
212
		break;
213
	case 4:
214
		e = frompow2(a, b, 2);
215
		break;
216
	case 8:
217
		e = from8(a, b);
218
		break;
2 - 219
	case 10:
220
		e = from10(a, b);
221
		break;
222
	case 16:
33 7u83 223
		e = frompow2(a, b, 4);
2 - 224
		break;
225
	case 32:
33 7u83 226
		e = fromdecx(a, b, dec32chr, dec32);
2 - 227
		break;
228
	case 64:
33 7u83 229
		e = fromdecx(a, b, dec64chr, dec64);
2 - 230
		break;
33 7u83 231
	default:
232
		abort();
233
		return nil;
2 - 234
	}
235
 
33 7u83 236
	if(pp != nil)
237
		*pp = e;
238
 
2 - 239
	// if no characters parsed, there wasn't a number to convert
240
	if(e == a)
241
		return nil;
242
 
243
	b->sign = sign;
33 7u83 244
	return mpnorm(b);
2 - 245
}