Sigrid Solveig Haflínudóttirmp: abort instead of exit, no printout5049eb811 months agoHistory
288 lines · 4.4 KB · C
RawDownload
#include "platform.h"#include "mp.h" #define between(x,min,max)	(((min-1-x) & (x-max-1))>>8) static intenc32chr(int o){	int c; 	c  = between(o,  0, 25) & ('A'+o);	c |= between(o, 26, 31) & ('2'+(o-26));	return c;} static intenc32x(char *dest, int ndest, const u8int *src, int nsrc, int (*chr)(int)){	char *start;	int j; 	if(ndest <= (8*nsrc+4)/5)		return -1;	start = dest;	while(nsrc>=5){		j = (0x1f & (src[0]>>3));		*dest++ = chr(j);		j = (0x1c & (src[0]<<2)) | (0x03 & (src[1]>>6));		*dest++ = chr(j);		j = (0x1f & (src[1]>>1));		*dest++ = chr(j);		j = (0x10 & (src[1]<<4)) | (0x0f & (src[2]>>4));		*dest++ = chr(j);		j = (0x1e & (src[2]<<1)) | (0x01 & (src[3]>>7));		*dest++ = chr(j);		j = (0x1f & (src[3]>>2));		*dest++ = chr(j);		j = (0x18 & (src[3]<<3)) | (0x07 & (src[4]>>5));		*dest++ = chr(j);		j = (0x1f & (src[4]));		*dest++ = chr(j);		src  += 5;		nsrc -= 5;	}	if(nsrc){		j = (0x1f & (src[0]>>3));		*dest++ = chr(j);		j = (0x1c & (src[0]<<2));		if(nsrc == 1)			goto out;		j |= (0x03 & (src[1]>>6));		*dest++ = chr(j);		j = (0x1f & (src[1]>>1));		*dest++ = chr(j);		j = (0x10 & (src[1]<<4));		if(nsrc == 2)			goto out;		j |= (0x0f & (src[2]>>4));		*dest++ = chr(j);		j = (0x1e & (src[2]<<1));		if(nsrc == 3)			goto out;		j |= (0x01 & (src[3]>>7));		*dest++ = chr(j);		j = (0x1f & (src[3]>>2));		*dest++ = chr(j);		j = (0x18 & (src[3]<<3));out:		*dest++ = chr(j);	}	*dest = 0;	return dest-start;} intenc32(char *dest, int ndest, const u8int *src, int nsrc){	return enc32x(dest, ndest, src, nsrc, enc32chr);} static inttoencx(mpint *b, char *buf, int len, int (*enc)(char*, int, const u8int*, int)){	u8int *p;	int n, rv; 	p = nil;	n = mptobe(b, nil, 0, &p);	if(n < 0)		return -1;	rv = enc(buf, len, p, n);	MEM_FREE(p);	return rv;} static inttopow2(mpint *b, char *buf, int len, int s){	mpdigit *p, x;	int i, j, sn;	char *out, *eout; 	if(len < 1)		return -1; 	sn = 1<<s;	out = buf;	eout = buf+len;	for(p = b->p+b->top-1; p >= b->p; p--){		x = *p;		for(i = Dbits-s; i >= 0; i -= s){			j = x >> i & (sn - 1);			if(j != 0 || out != buf){				if(out >= eout)					return -1;				*out++ = enc16chr(j);			}		}	}	if(out == buf)		*out++ = '0';	if(out >= eout)		return -1;	*out = 0;	return 0;} static char *modbillion(int rem, u32int r, char *out, char *buf){	u32int rr;	int i; 	for(i = 0; i < 9; i++){		rr = r%10;		r /= 10;		if(out <= buf)			return nil;		*--out = '0' + rr;		if(rem == 0 && r == 0)			break;	}	return out;} static intto10(mpint *b, char *buf, int len){	mpint *d, *r, *billion;	char *out; 	if(len < 1)		return -1; 	d = mpcopy(b);	d->flags &= ~MPtimesafe;	mpnorm(d);	r = mpnew(0);	billion = uitomp(1000000000, nil);	out = buf+len;	*--out = 0;	do {		mpdiv(d, billion, d, r);		out = modbillion(d->top, r->p[0], out, buf);		if(out == nil)			break;	} while(d->top != 0);	mpfree(d);	mpfree(r);	mpfree(billion); 	if(out == nil)		return -1;	len -= out-buf;	if(out != buf)		memmove(buf, out, len);	return 0;} static intto8(mpint *b, char *buf, int len){	mpdigit x, y;	char *out;	u32int j;	int i; 	if(len < 2)		return -1; 	out = buf+len;	*--out = 0; 	i = j = 0;	x = y = 0;	while(j < b->top){		y = b->p[j++];		if(i > 0)			x |= y << i;		else			x = y;		i += Dbits;		while(i >= 3){Digout:			i -= 3;			if(out > buf)				out--;			else if(x != 0)				return -1;			*out = '0' + (x & 7);			if((Dbits-i) >= 64)				x = 0;			else				x = y >> (Dbits-i);		}	}	if(i > 0)		goto Digout; 	while(*out == '0') out++;	if(*out == '\0')		*--out = '0'; 	len -= out-buf;	if(out != buf)		memmove(buf, out, len);	return 0;} char *mptoa(mpint *b, int base, char *buf, int len){	bool alloced;	char *out;	int rv; 	if(base == 0)		base = 16;	/* default */	alloced = false;	if(buf == nil){		/* rv <= log₂(base) */		for(rv=1; (base >> rv) > 1; rv++)			;		len = 10 + (b->top*Dbits / rv);		buf = MEM_ALLOC(len);		if(buf == nil)			return nil;		alloced = true;	} 	if(len < 2)		goto leave; 	out = buf;	if(b->sign < 0){		*out++ = '-';		len--;	}	switch(base){	case 32:		rv = toencx(b, out, len, enc32);		break;	case 16:		rv = topow2(b, out, len, 4);		break;	case 10:		rv = to10(b, out, len);		break;	case 8:		rv = to8(b, out, len);		break;	case 4:		rv = topow2(b, out, len, 2);		break;	case 2:		rv = topow2(b, out, len, 1);		break;	default:		abort();	}	if(rv < 0){leave:		if(alloced)			MEM_FREE(buf);		return nil;	}	return buf;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t