new utilities.
the .C files compile but are renamed to avoid building automatically.
diff --git a/src/cmd/dc.c b/src/cmd/dc.c
new file mode 100644
index 0000000..9fe4560
--- /dev/null
+++ b/src/cmd/dc.c
@@ -0,0 +1,2300 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+
+typedef	void*	pointer;
+
+#define div	dcdiv
+
+#define FATAL 0
+#define NFATAL 1
+#define BLK sizeof(Blk)
+#define PTRSZ sizeof(int*)
+#define HEADSZ 1024
+#define STKSZ 100
+#define RDSKSZ 100
+#define TBLSZ 256
+#define ARRAYST 221
+#define MAXIND 2048
+#define NL 1
+#define NG 2
+#define NE 3
+#define length(p)	((p)->wt-(p)->beg)
+#define rewind(p)	(p)->rd=(p)->beg
+#define create(p)	(p)->rd = (p)->wt = (p)->beg
+#define fsfile(p)	(p)->rd = (p)->wt
+#define truncate(p)	(p)->wt = (p)->rd
+#define sfeof(p)	(((p)->rd==(p)->wt)?1:0)
+#define sfbeg(p)	(((p)->rd==(p)->beg)?1:0)
+#define sungetc(p,c)	*(--(p)->rd)=c
+#define sgetc(p)	(((p)->rd==(p)->wt)?-1:*(p)->rd++)
+#define skipc(p)	{if((p)->rd<(p)->wt)(p)->rd++;}
+#define slookc(p)	(((p)->rd==(p)->wt)?-1:*(p)->rd)
+#define sbackc(p)	(((p)->rd==(p)->beg)?-1:*(--(p)->rd))
+#define backc(p)	{if((p)->rd>(p)->beg) --(p)->rd;}
+#define sputc(p,c)	{if((p)->wt==(p)->last)more(p);\
+				*(p)->wt++ = c; }
+#define salterc(p,c)	{if((p)->rd==(p)->last)more(p);\
+				*(p)->rd++ = c;\
+				if((p)->rd>(p)->wt)(p)->wt=(p)->rd;}
+#define sunputc(p)	(*((p)->rd = --(p)->wt))
+#define sclobber(p)	((p)->rd = --(p)->wt)
+#define zero(p)		for(pp=(p)->beg;pp<(p)->last;)\
+				*pp++='\0'
+#define OUTC(x)		{Bputc(&bout,x); if(--count == 0){Bprint(&bout,"\\\n"); count=ll;} }
+#define TEST2		{if((count -= 2) <=0){Bprint(&bout,"\\\n");count=ll;}}
+#define EMPTY		if(stkerr != 0){Bprint(&bout,"stack empty\n"); continue; }
+#define EMPTYR(x)	if(stkerr!=0){pushp(x);Bprint(&bout,"stack empty\n");continue;}
+#define EMPTYS		if(stkerr != 0){Bprint(&bout,"stack empty\n"); return(1);}
+#define EMPTYSR(x)	if(stkerr !=0){Bprint(&bout,"stack empty\n");pushp(x);return(1);}
+#define error(p)	{Bprint(&bout,p); continue; }
+#define errorrt(p)	{Bprint(&bout,p); return(1); }
+#define LASTFUN 026
+
+typedef	struct	Blk	Blk;
+struct	Blk
+{
+	char	*rd;
+	char	*wt;
+	char	*beg;
+	char	*last;
+};
+typedef	struct	Sym	Sym;
+struct	Sym
+{
+	Sym	*next;
+	Blk	*val;
+};
+typedef	struct	Wblk	Wblk;
+struct	Wblk
+{
+	Blk	**rdw;
+	Blk	**wtw;
+	Blk	**begw;
+	Blk	**lastw;
+};
+
+Biobuf	*curfile, *fsave;
+Blk	*arg1, *arg2;
+uchar	savk;
+int	dbg;
+int	ifile;
+Blk	*scalptr, *basptr, *tenptr, *inbas;
+Blk	*sqtemp, *chptr, *strptr, *divxyz;
+Blk	*stack[STKSZ];
+Blk	**stkptr,**stkbeg;
+Blk	**stkend;
+Blk	*hfree;
+int	stkerr;
+int	lastchar;
+Blk	*readstk[RDSKSZ];
+Blk	**readptr;
+Blk	*rem;
+int	k;
+Blk	*irem;
+int	skd,skr;
+int	neg;
+Sym	symlst[TBLSZ];
+Sym	*stable[TBLSZ];
+Sym	*sptr, *sfree;
+long	rel;
+long	nbytes;
+long	all;
+long	headmor;
+long	obase;
+int	fw,fw1,ll;
+void	(*outdit)(Blk *p, int flg);
+int	logo;
+int	logten;
+int	count;
+char	*pp;
+char	*dummy;
+long	longest, maxsize, active;
+int	lall, lrel, lcopy, lmore, lbytes;
+int	inside;
+Biobuf	bin;
+Biobuf	bout;
+
+void	main(int argc, char *argv[]);
+void	commnds(void);
+Blk*	readin(void);
+Blk*	div(Blk *ddivd, Blk *ddivr);
+int	dscale(void);
+Blk*	removr(Blk *p, int n);
+Blk*	dcsqrt(Blk *p);
+void	init(int argc, char *argv[]);
+void	onintr(void);
+void	pushp(Blk *p);
+Blk*	pop(void);
+Blk*	readin(void);
+Blk*	add0(Blk *p, int ct);
+Blk*	mult(Blk *p, Blk *q);
+void	chsign(Blk *p);
+int	readc(void);
+void	unreadc(char c);
+void	binop(char c);
+void	dcprint(Blk *hptr);
+Blk*	dcexp(Blk *base, Blk *ex);
+Blk*	getdec(Blk *p, int sc);
+void	tenot(Blk *p, int sc);
+void	oneot(Blk *p, int sc, char ch);
+void	hexot(Blk *p, int flg);
+void	bigot(Blk *p, int flg);
+Blk*	add(Blk *a1, Blk *a2);
+int	eqk(void);
+Blk*	removc(Blk *p, int n);
+Blk*	scalint(Blk *p);
+Blk*	scale(Blk *p, int n);
+int	subt(void);
+int	command(void);
+int	cond(char c);
+void	load(void);
+int	log2(long n);
+Blk*	salloc(int size);
+Blk*	morehd(void);
+Blk*	copy(Blk *hptr, int size);
+void	sdump(char *s1, Blk *hptr);
+void	seekc(Blk *hptr, int n);
+void	salterwd(Blk *hptr, Blk *n);
+void	more(Blk *hptr);
+void	ospace(char *s);
+void	garbage(char *s);
+void	release(Blk *p);
+Blk*	dcgetwd(Blk *p);
+void	putwd(Blk *p, Blk *c);
+Blk*	lookwd(Blk *p);
+char*	nalloc(char *p, unsigned nbytes);
+int	getstk(void);
+
+/********debug only**/
+void
+tpr(char *cp, Blk *bp)
+{
+	print("%s-> ", cp);
+	print("beg: %lx rd: %lx wt: %lx last: %lx\n", bp->beg, bp->rd,
+		bp->wt, bp->last);
+	for (cp = bp->beg; cp != bp->wt; cp++) {
+		print("%d", *cp);
+		if (cp != bp->wt-1)
+			print("/");
+	}
+	print("\n");
+}
+/************/
+
+void
+main(int argc, char *argv[])
+{
+	Binit(&bin, 0, OREAD);
+	Binit(&bout, 1, OWRITE);
+	init(argc,argv);
+	commnds();
+	exits(0);
+}
+
+void
+commnds(void)
+{
+	Blk *p, *q, **ptr, *s, *t;
+	long l;
+	Sym *sp;
+	int sk, sk1, sk2, c, sign, n, d;
+
+	while(1) {
+		Bflush(&bout);
+		if(((c = readc())>='0' && c <= '9') ||
+		    (c>='A' && c <='F') || c == '.') {
+			unreadc(c);
+			p = readin();
+			pushp(p);
+			continue;
+		}
+		switch(c) {
+		case ' ':
+		case '\n':
+		case -1:
+			continue;
+		case 'Y':
+			sdump("stk",*stkptr);
+			Bprint(&bout, "all %ld rel %ld headmor %ld\n",all,rel,headmor);
+			Bprint(&bout, "nbytes %ld\n",nbytes);
+			Bprint(&bout, "longest %ld active %ld maxsize %ld\n", longest,
+				active, maxsize);
+			Bprint(&bout, "new all %d rel %d copy %d more %d lbytes %d\n",
+				lall, lrel, lcopy, lmore, lbytes);
+			lall = lrel = lcopy = lmore = lbytes = 0;
+			continue;
+		case '_':
+			p = readin();
+			savk = sunputc(p);
+			chsign(p);
+			sputc(p,savk);
+			pushp(p);
+			continue;
+		case '-':
+			subt();
+			continue;
+		case '+':
+			if(eqk() != 0)
+				continue;
+			binop('+');
+			continue;
+		case '*':
+			arg1 = pop();
+			EMPTY;
+			arg2 = pop();
+			EMPTYR(arg1);
+			sk1 = sunputc(arg1);
+			sk2 = sunputc(arg2);
+			savk = sk1+sk2;
+			binop('*');
+			p = pop();
+			if(savk>k && savk>sk1 && savk>sk2) {
+				sclobber(p);
+				sk = sk1;
+				if(sk<sk2)
+					sk = sk2;
+				if(sk<k)
+					sk = k;
+				p = removc(p,savk-sk);
+				savk = sk;
+				sputc(p,savk);
+			}
+			pushp(p);
+			continue;
+		case '/':
+		casediv:
+			if(dscale() != 0)
+				continue;
+			binop('/');
+			if(irem != 0)
+				release(irem);
+			release(rem);
+			continue;
+		case '%':
+			if(dscale() != 0)
+				continue;
+			binop('/');
+			p = pop();
+			release(p);
+			if(irem == 0) {
+				sputc(rem,skr+k);
+				pushp(rem);
+				continue;
+			}
+			p = add0(rem,skd-(skr+k));
+			q = add(p,irem);
+			release(p);
+			release(irem);
+			sputc(q,skd);
+			pushp(q);
+			continue;
+		case 'v':
+			p = pop();
+			EMPTY;
+			savk = sunputc(p);
+			if(length(p) == 0) {
+				sputc(p,savk);
+				pushp(p);
+				continue;
+			}
+			if(sbackc(p)<0) {
+				error("sqrt of neg number\n");
+			}
+			if(k<savk)
+				n = savk;
+			else {
+				n = k*2-savk;
+				savk = k;
+			}
+			arg1 = add0(p,n);
+			arg2 = dcsqrt(arg1);
+			sputc(arg2,savk);
+			pushp(arg2);
+			continue;
+
+		case '^':
+			neg = 0;
+			arg1 = pop();
+			EMPTY;
+			if(sunputc(arg1) != 0)
+				error("exp not an integer\n");
+			arg2 = pop();
+			EMPTYR(arg1);
+			if(sfbeg(arg1) == 0 && sbackc(arg1)<0) {
+				neg++;
+				chsign(arg1);
+			}
+			if(length(arg1)>=3) {
+				error("exp too big\n");
+			}
+			savk = sunputc(arg2);
+			p = dcexp(arg2,arg1);
+			release(arg2);
+			rewind(arg1);
+			c = sgetc(arg1);
+			if(c == -1)
+				c = 0;
+			else
+			if(sfeof(arg1) == 0)
+				c = sgetc(arg1)*100 + c;
+			d = c*savk;
+			release(arg1);
+		/*	if(neg == 0) {		removed to fix -exp bug*/
+				if(k>=savk)
+					n = k;
+				else
+					n = savk;
+				if(n<d) {
+					q = removc(p,d-n);
+					sputc(q,n);
+					pushp(q);
+				} else {
+					sputc(p,d);
+					pushp(p);
+				}
+		/*	} else { this is disaster for exp <-127 */
+		/*		sputc(p,d);		*/
+		/*		pushp(p);		*/
+		/*	}				*/
+			if(neg == 0)
+				continue;
+			p = pop();
+			q = salloc(2);
+			sputc(q,1);
+			sputc(q,0);
+			pushp(q);
+			pushp(p);
+			goto casediv;
+		case 'z':
+			p = salloc(2);
+			n = stkptr - stkbeg;
+			if(n >= 100) {
+				sputc(p,n/100);
+				n %= 100;
+			}
+			sputc(p,n);
+			sputc(p,0);
+			pushp(p);
+			continue;
+		case 'Z':
+			p = pop();
+			EMPTY;
+			n = (length(p)-1)<<1;
+			fsfile(p);
+			backc(p);
+			if(sfbeg(p) == 0) {
+				if((c = sbackc(p))<0) {
+					n -= 2;
+					if(sfbeg(p) == 1)
+						n++;
+					else {
+						if((c = sbackc(p)) == 0)
+							n++;
+						else
+						if(c > 90)
+							n--;
+					}
+				} else
+				if(c < 10)
+					n--;
+			}
+			release(p);
+			q = salloc(1);
+			if(n >= 100) {
+				sputc(q,n%100);
+				n /= 100;
+			}
+			sputc(q,n);
+			sputc(q,0);
+			pushp(q);
+			continue;
+		case 'i':
+			p = pop();
+			EMPTY;
+			p = scalint(p);
+			release(inbas);
+			inbas = p;
+			continue;
+		case 'I':
+			p = copy(inbas,length(inbas)+1);
+			sputc(p,0);
+			pushp(p);
+			continue;
+		case 'o':
+			p = pop();
+			EMPTY;
+			p = scalint(p);
+			sign = 0;
+			n = length(p);
+			q = copy(p,n);
+			fsfile(q);
+			l = c = sbackc(q);
+			if(n != 1) {
+				if(c<0) {
+					sign = 1;
+					chsign(q);
+					n = length(q);
+					fsfile(q);
+					l = c = sbackc(q);
+				}
+				if(n != 1) {
+					while(sfbeg(q) == 0)
+						l = l*100+sbackc(q);
+				}
+			}
+			logo = log2(l);
+			obase = l;
+			release(basptr);
+			if(sign == 1)
+				obase = -l;
+			basptr = p;
+			outdit = bigot;
+			if(n == 1 && sign == 0) {
+				if(c <= 16) {
+					outdit = hexot;
+					fw = 1;
+					fw1 = 0;
+					ll = 70;
+					release(q);
+					continue;
+				}
+			}
+			n = 0;
+			if(sign == 1)
+				n++;
+			p = salloc(1);
+			sputc(p,-1);
+			t = add(p,q);
+			n += length(t)*2;
+			fsfile(t);
+			if(sbackc(t)>9)
+				n++;
+			release(t);
+			release(q);
+			release(p);
+			fw = n;
+			fw1 = n-1;
+			ll = 70;
+			if(fw>=ll)
+				continue;
+			ll = (70/fw)*fw;
+			continue;
+		case 'O':
+			p = copy(basptr,length(basptr)+1);
+			sputc(p,0);
+			pushp(p);
+			continue;
+		case '[':
+			n = 0;
+			p = salloc(0);
+			for(;;) {
+				if((c = readc()) == ']') {
+					if(n == 0)
+						break;
+					n--;
+				}
+				sputc(p,c);
+				if(c == '[')
+					n++;
+			}
+			pushp(p);
+			continue;
+		case 'k':
+			p = pop();
+			EMPTY;
+			p = scalint(p);
+			if(length(p)>1) {
+				error("scale too big\n");
+			}
+			rewind(p);
+			k = 0;
+			if(!sfeof(p))
+				k = sgetc(p);
+			release(scalptr);
+			scalptr = p;
+			continue;
+		case 'K':
+			p = copy(scalptr,length(scalptr)+1);
+			sputc(p,0);
+			pushp(p);
+			continue;
+		case 'X':
+			p = pop();
+			EMPTY;
+			fsfile(p);
+			n = sbackc(p);
+			release(p);
+			p = salloc(2);
+			sputc(p,n);
+			sputc(p,0);
+			pushp(p);
+			continue;
+		case 'Q':
+			p = pop();
+			EMPTY;
+			if(length(p)>2) {
+				error("Q?\n");
+			}
+			rewind(p);
+			if((c =  sgetc(p))<0) {
+				error("neg Q\n");
+			}
+			release(p);
+			while(c-- > 0) {
+				if(readptr == &readstk[0]) {
+					error("readstk?\n");
+				}
+				if(*readptr != 0)
+					release(*readptr);
+				readptr--;
+			}
+			continue;
+		case 'q':
+			if(readptr <= &readstk[1])
+				exits(0);
+			if(*readptr != 0)
+				release(*readptr);
+			readptr--;
+			if(*readptr != 0)
+				release(*readptr);
+			readptr--;
+			continue;
+		case 'f':
+			if(stkptr == &stack[0])
+				Bprint(&bout,"empty stack\n");
+			else {
+				for(ptr = stkptr; ptr > &stack[0];) {
+					dcprint(*ptr--);
+				}
+			}
+			continue;
+		case 'p':
+			if(stkptr == &stack[0])
+				Bprint(&bout,"empty stack\n");
+			else {
+				dcprint(*stkptr);
+			}
+			continue;
+		case 'P':
+			p = pop();
+			EMPTY;
+			sputc(p,0);
+			Bprint(&bout,"%s",p->beg);
+			release(p);
+			continue;
+		case 'd':
+			if(stkptr == &stack[0]) {
+				Bprint(&bout,"empty stack\n");
+				continue;
+			}
+			q = *stkptr;
+			n = length(q);
+			p = copy(*stkptr,n);
+			pushp(p);
+			continue;
+		case 'c':
+			while(stkerr == 0) {
+				p = pop();
+				if(stkerr == 0)
+					release(p);
+			}
+			continue;
+		case 'S':
+			if(stkptr == &stack[0]) {
+				error("save: args\n");
+			}
+			c = getstk() & 0377;
+			sptr = stable[c];
+			sp = stable[c] = sfree;
+			sfree = sfree->next;
+			if(sfree == 0)
+				goto sempty;
+			sp->next = sptr;
+			p = pop();
+			EMPTY;
+			if(c >= ARRAYST) {
+				q = copy(p,length(p)+PTRSZ);
+				for(n = 0;n < PTRSZ;n++) {
+					sputc(q,0);
+				}
+				release(p);
+				p = q;
+			}
+			sp->val = p;
+			continue;
+		sempty:
+			error("symbol table overflow\n");
+		case 's':
+			if(stkptr == &stack[0]) {
+				error("save:args\n");
+			}
+			c = getstk() & 0377;
+			sptr = stable[c];
+			if(sptr != 0) {
+				p = sptr->val;
+				if(c >= ARRAYST) {
+					rewind(p);
+					while(sfeof(p) == 0)
+						release(dcgetwd(p));
+				}
+				release(p);
+			} else {
+				sptr = stable[c] = sfree;
+				sfree = sfree->next;
+				if(sfree == 0)
+					goto sempty;
+				sptr->next = 0;
+			}
+			p = pop();
+			sptr->val = p;
+			continue;
+		case 'l':
+			load();
+			continue;
+		case 'L':
+			c = getstk() & 0377;
+			sptr = stable[c];
+			if(sptr == 0) {
+				error("L?\n");
+			}
+			stable[c] = sptr->next;
+			sptr->next = sfree;
+			sfree = sptr;
+			p = sptr->val;
+			if(c >= ARRAYST) {
+				rewind(p);
+				while(sfeof(p) == 0) {
+					q = dcgetwd(p);
+					if(q != 0)
+						release(q);
+				}
+			}
+			pushp(p);
+			continue;
+		case ':':
+			p = pop();
+			EMPTY;
+			q = scalint(p);
+			fsfile(q);
+			c = 0;
+			if((sfbeg(q) == 0) && ((c = sbackc(q))<0)) {
+				error("neg index\n");
+			}
+			if(length(q)>2) {
+				error("index too big\n");
+			}
+			if(sfbeg(q) == 0)
+				c = c*100+sbackc(q);
+			if(c >= MAXIND) {
+				error("index too big\n");
+			}
+			release(q);
+			n = getstk() & 0377;
+			sptr = stable[n];
+			if(sptr == 0) {
+				sptr = stable[n] = sfree;
+				sfree = sfree->next;
+				if(sfree == 0)
+					goto sempty;
+				sptr->next = 0;
+				p = salloc((c+PTRSZ)*PTRSZ);
+				zero(p);
+			} else {
+				p = sptr->val;
+				if(length(p)-PTRSZ < c*PTRSZ) {
+					q = copy(p,(c+PTRSZ)*PTRSZ);
+					release(p);
+					p = q;
+				}
+			}
+			seekc(p,c*PTRSZ);
+			q = lookwd(p);
+			if(q!=0)
+				release(q);
+			s = pop();
+			EMPTY;
+			salterwd(p, s);
+			sptr->val = p;
+			continue;
+		case ';':
+			p = pop();
+			EMPTY;
+			q = scalint(p);
+			fsfile(q);
+			c = 0;
+			if((sfbeg(q) == 0) && ((c = sbackc(q))<0)) {
+				error("neg index\n");
+			}
+			if(length(q)>2) {
+				error("index too big\n");
+			}
+			if(sfbeg(q) == 0)
+				c = c*100+sbackc(q);
+			if(c >= MAXIND) {
+				error("index too big\n");
+			}
+			release(q);
+			n = getstk() & 0377;
+			sptr = stable[n];
+			if(sptr != 0){
+				p = sptr->val;
+				if(length(p)-PTRSZ >= c*PTRSZ) {
+					seekc(p,c*PTRSZ);
+					s = dcgetwd(p);
+					if(s != 0) {
+						q = copy(s,length(s));
+						pushp(q);
+						continue;
+					}
+				}
+			}
+			q = salloc(1);	/*so uninitialized array elt prints as 0*/
+			sputc(q, 0);
+			pushp(q);
+			continue;
+		case 'x':
+		execute:
+			p = pop();
+			EMPTY;
+			if((readptr != &readstk[0]) && (*readptr != 0)) {
+				if((*readptr)->rd == (*readptr)->wt)
+					release(*readptr);
+				else {
+					if(readptr++ == &readstk[RDSKSZ]) {
+						error("nesting depth\n");
+					}
+				}
+			} else
+				readptr++;
+			*readptr = p;
+			if(p != 0)
+				rewind(p);
+			else {
+				if((c = readc()) != '\n')
+					unreadc(c);
+			}
+			continue;
+		case '?':
+			if(++readptr == &readstk[RDSKSZ]) {
+				error("nesting depth\n");
+			}
+			*readptr = 0;
+			fsave = curfile;
+			curfile = &bin;
+			while((c = readc()) == '!')
+				command();
+			p = salloc(0);
+			sputc(p,c);
+			while((c = readc()) != '\n') {
+				sputc(p,c);
+				if(c == '\\')
+					sputc(p,readc());
+			}
+			curfile = fsave;
+			*readptr = p;
+			continue;
+		case '!':
+			if(command() == 1)
+				goto execute;
+			continue;
+		case '<':
+		case '>':
+		case '=':
+			if(cond(c) == 1)
+				goto execute;
+			continue;
+		default:
+			Bprint(&bout,"%o is unimplemented\n",c);
+		}
+	}
+}
+
+Blk*
+div(Blk *ddivd, Blk *ddivr)
+{
+	int divsign, remsign, offset, divcarry,
+		carry, dig, magic, d, dd, under, first;
+	long c, td, cc;
+	Blk *ps, *px, *p, *divd, *divr;
+
+	dig = 0;
+	under = 0;
+	divcarry = 0;
+	rem = 0;
+	p = salloc(0);
+	if(length(ddivr) == 0) {
+		pushp(ddivr);
+		Bprint(&bout,"divide by 0\n");
+		return(p);
+	}
+	divsign = remsign = first = 0;
+	divr = ddivr;
+	fsfile(divr);
+	if(sbackc(divr) == -1) {
+		divr = copy(ddivr,length(ddivr));
+		chsign(divr);
+		divsign = ~divsign;
+	}
+	divd = copy(ddivd,length(ddivd));
+	fsfile(divd);
+	if(sfbeg(divd) == 0 && sbackc(divd) == -1) {
+		chsign(divd);
+		divsign = ~divsign;
+		remsign = ~remsign;
+	}
+	offset = length(divd) - length(divr);
+	if(offset < 0)
+		goto ddone;
+	seekc(p,offset+1);
+	sputc(divd,0);
+	magic = 0;
+	fsfile(divr);
+	c = sbackc(divr);
+	if(c < 10)
+		magic++;
+	c = c * 100 + (sfbeg(divr)?0:sbackc(divr));
+	if(magic>0){
+		c = (c * 100 +(sfbeg(divr)?0:sbackc(divr)))*2;
+		c /= 25;
+	}
+	while(offset >= 0) {
+		first++;
+		fsfile(divd);
+		td = sbackc(divd) * 100;
+		dd = sfbeg(divd)?0:sbackc(divd);
+		td = (td + dd) * 100;
+		dd = sfbeg(divd)?0:sbackc(divd);
+		td = td + dd;
+		cc = c;
+		if(offset == 0)
+			td++;
+		else
+			cc++;
+		if(magic != 0)
+			td = td<<3;
+		dig = td/cc;
+		under=0;
+		if(td%cc < 8  && dig > 0 && magic) {
+			dig--;
+			under=1;
+		}
+		rewind(divr);
+		rewind(divxyz);
+		carry = 0;
+		while(sfeof(divr) == 0) {
+			d = sgetc(divr)*dig+carry;
+			carry = d / 100;
+			salterc(divxyz,d%100);
+		}
+		salterc(divxyz,carry);
+		rewind(divxyz);
+		seekc(divd,offset);
+		carry = 0;
+		while(sfeof(divd) == 0) {
+			d = slookc(divd);
+			d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry;
+			carry = 0;
+			if(d < 0) {
+				d += 100;
+				carry = 1;
+			}
+			salterc(divd,d);
+		}
+		divcarry = carry;
+		backc(p);
+		salterc(p,dig);
+		backc(p);
+		fsfile(divd);
+		d=sbackc(divd);
+		if((d != 0) && /*!divcarry*/ (offset != 0)) {
+			d = sbackc(divd) + 100;
+			salterc(divd,d);
+		}
+		if(--offset >= 0)
+			divd->wt--;
+	}
+	if(under) {	/* undershot last - adjust*/
+		px = copy(divr,length(divr));	/*11/88 don't corrupt ddivr*/
+		chsign(px);
+		ps = add(px,divd);
+		fsfile(ps);
+		if(length(ps) > 0 && sbackc(ps) < 0) {
+			release(ps);	/*only adjust in really undershot*/
+		} else {
+			release(divd);
+			salterc(p, dig+1);
+			divd=ps;
+		}
+	}
+	if(divcarry != 0) {
+		salterc(p,dig-1);
+		salterc(divd,-1);
+		ps = add(divr,divd);
+		release(divd);
+		divd = ps;
+	}
+
+	rewind(p);
+	divcarry = 0;
+	while(sfeof(p) == 0){
+		d = slookc(p)+divcarry;
+		divcarry = 0;
+		if(d >= 100){
+			d -= 100;
+			divcarry = 1;
+		}
+		salterc(p,d);
+	}
+	if(divcarry != 0)salterc(p,divcarry);
+	fsfile(p);
+	while(sfbeg(p) == 0) {
+		if(sbackc(p) != 0)
+			break;
+		truncate(p);
+	}
+	if(divsign < 0)
+		chsign(p);
+	fsfile(divd);
+	while(sfbeg(divd) == 0) {
+		if(sbackc(divd) != 0)
+			break;
+		truncate(divd);
+	}
+ddone:
+	if(remsign<0)
+		chsign(divd);
+	if(divr != ddivr)
+		release(divr);
+	rem = divd;
+	return(p);
+}
+
+int
+dscale(void)
+{
+	Blk *dd, *dr, *r;
+	int c;
+
+	dr = pop();
+	EMPTYS;
+	dd = pop();
+	EMPTYSR(dr);
+	fsfile(dd);
+	skd = sunputc(dd);
+	fsfile(dr);
+	skr = sunputc(dr);
+	if(sfbeg(dr) == 1 || (sfbeg(dr) == 0 && sbackc(dr) == 0)) {
+		sputc(dr,skr);
+		pushp(dr);
+		Bprint(&bout,"divide by 0\n");
+		return(1);
+	}
+	if(sfbeg(dd) == 1 || (sfbeg(dd) == 0 && sbackc(dd) == 0)) {
+		sputc(dd,skd);
+		pushp(dd);
+		return(1);
+	}
+	c = k-skd+skr;
+	if(c < 0)
+		r = removr(dd,-c);
+	else {
+		r = add0(dd,c);
+		irem = 0;
+	}
+	arg1 = r;
+	arg2 = dr;
+	savk = k;
+	return(0);
+}
+
+Blk*
+removr(Blk *p, int n)
+{
+	int nn, neg;
+	Blk *q, *s, *r;
+
+	fsfile(p);
+	neg = sbackc(p);
+	if(neg < 0)
+		chsign(p);
+	rewind(p);
+	nn = (n+1)/2;
+	q = salloc(nn);
+	while(n>1) {
+		sputc(q,sgetc(p));
+		n -= 2;
+	}
+	r = salloc(2);
+	while(sfeof(p) == 0)
+		sputc(r,sgetc(p));
+	release(p);
+	if(n == 1){
+		s = div(r,tenptr);
+		release(r);
+		rewind(rem);
+		if(sfeof(rem) == 0)
+			sputc(q,sgetc(rem));
+		release(rem);
+		if(neg < 0){
+			chsign(s);
+			chsign(q);
+			irem = q;
+			return(s);
+		}
+		irem = q;
+		return(s);
+	}
+	if(neg < 0) {
+		chsign(r);
+		chsign(q);
+		irem = q;
+		return(r);
+	}
+	irem = q;
+	return(r);
+}
+
+Blk*
+dcsqrt(Blk *p)
+{
+	Blk *t, *r, *q, *s;
+	int c, n, nn;
+
+	n = length(p);
+	fsfile(p);
+	c = sbackc(p);
+	if((n&1) != 1)
+		c = c*100+(sfbeg(p)?0:sbackc(p));
+	n = (n+1)>>1;
+	r = salloc(n);
+	zero(r);
+	seekc(r,n);
+	nn=1;
+	while((c -= nn)>=0)
+		nn+=2;
+	c=(nn+1)>>1;
+	fsfile(r);
+	backc(r);
+	if(c>=100) {
+		c -= 100;
+		salterc(r,c);
+		sputc(r,1);
+	} else
+		salterc(r,c);
+	for(;;){
+		q = div(p,r);
+		s = add(q,r);
+		release(q);
+		release(rem);
+		q = div(s,sqtemp);
+		release(s);
+		release(rem);
+		s = copy(r,length(r));
+		chsign(s);
+		t = add(s,q);
+		release(s);
+		fsfile(t);
+		nn = sfbeg(t)?0:sbackc(t);
+		if(nn>=0)
+			break;
+		release(r);
+		release(t);
+		r = q;
+	}
+	release(t);
+	release(q);
+	release(p);
+	return(r);
+}
+
+Blk*
+dcexp(Blk *base, Blk *ex)
+{
+	Blk *r, *e, *p, *e1, *t, *cp;
+	int temp, c, n;
+
+	r = salloc(1);
+	sputc(r,1);
+	p = copy(base,length(base));
+	e = copy(ex,length(ex));
+	fsfile(e);
+	if(sfbeg(e) != 0)
+		goto edone;
+	temp=0;
+	c = sbackc(e);
+	if(c<0) {
+		temp++;
+		chsign(e);
+	}
+	while(length(e) != 0) {
+		e1=div(e,sqtemp);
+		release(e);
+		e = e1;
+		n = length(rem);
+		release(rem);
+		if(n != 0) {
+			e1=mult(p,r);
+			release(r);
+			r = e1;
+		}
+		t = copy(p,length(p));
+		cp = mult(p,t);
+		release(p);
+		release(t);
+		p = cp;
+	}
+	if(temp != 0) {
+		if((c = length(base)) == 0) {
+			goto edone;
+		}
+		if(c>1)
+			create(r);
+		else {
+			rewind(base);
+			if((c = sgetc(base))<=1) {
+				create(r);
+				sputc(r,c);
+			} else
+				create(r);
+		}
+	}
+edone:
+	release(p);
+	release(e);
+	return(r);
+}
+
+void
+init(int argc, char *argv[])
+{
+	Sym *sp;
+	Dir *d;
+
+	ARGBEGIN {
+	default:
+		dbg = 1;
+		break;
+	} ARGEND
+	ifile = 1;
+	curfile = &bin;
+	if(*argv){
+		d = dirstat(*argv);
+		if(d == nil) {
+			fprint(2, "dc: can't open file %s\n", *argv);
+			exits("open");
+		}
+		if(d->mode & DMDIR) {
+			fprint(2, "dc: file %s is a directory\n", *argv);
+			exits("open");
+		}
+		free(d);
+		if((curfile = Bopen(*argv, OREAD)) == 0) {
+			fprint(2,"dc: can't open file %s\n", *argv);
+			exits("open");
+		}
+	}
+/*	dummy = malloc(0);  *//* prepare for garbage-collection */
+	scalptr = salloc(1);
+	sputc(scalptr,0);
+	basptr = salloc(1);
+	sputc(basptr,10);
+	obase=10;
+	logten=log2(10L);
+	ll=70;
+	fw=1;
+	fw1=0;
+	tenptr = salloc(1);
+	sputc(tenptr,10);
+	obase=10;
+	inbas = salloc(1);
+	sputc(inbas,10);
+	sqtemp = salloc(1);
+	sputc(sqtemp,2);
+	chptr = salloc(0);
+	strptr = salloc(0);
+	divxyz = salloc(0);
+	stkbeg = stkptr = &stack[0];
+	stkend = &stack[STKSZ];
+	stkerr = 0;
+	readptr = &readstk[0];
+	k=0;
+	sp = sptr = &symlst[0];
+	while(sptr < &symlst[TBLSZ]) {
+		sptr->next = ++sp;
+		sptr++;
+	}
+	sptr->next=0;
+	sfree = &symlst[0];
+}
+
+void
+pushp(Blk *p)
+{
+	if(stkptr == stkend) {
+		Bprint(&bout,"out of stack space\n");
+		return;
+	}
+	stkerr=0;
+	*++stkptr = p;
+	return;
+}
+
+Blk*
+pop(void)
+{
+	if(stkptr == stack) {
+		stkerr=1;
+		return(0);
+	}
+	return(*stkptr--);
+}
+
+Blk*
+readin(void)
+{
+	Blk *p, *q;
+	int dp, dpct, c;
+
+	dp = dpct=0;
+	p = salloc(0);
+	for(;;){
+		c = readc();
+		switch(c) {
+		case '.':
+			if(dp != 0)
+				goto gotnum;
+			dp++;
+			continue;
+		case '\\':
+			readc();
+			continue;
+		default:
+			if(c >= 'A' && c <= 'F')
+				c = c - 'A' + 10;
+			else
+			if(c >= '0' && c <= '9')
+				c -= '0';
+			else
+				goto gotnum;
+			if(dp != 0) {
+				if(dpct >= 99)
+					continue;
+				dpct++;
+			}
+			create(chptr);
+			if(c != 0)
+				sputc(chptr,c);
+			q = mult(p,inbas);
+			release(p);
+			p = add(chptr,q);
+			release(q);
+		}
+	}
+gotnum:
+	unreadc(c);
+	if(dp == 0) {
+		sputc(p,0);
+		return(p);
+	} else {
+		q = scale(p,dpct);
+		return(q);
+	}
+}
+
+/*
+ * returns pointer to struct with ct 0's & p
+ */
+Blk*
+add0(Blk *p, int ct)
+{
+	Blk *q, *t;
+
+	q = salloc(length(p)+(ct+1)/2);
+	while(ct>1) {
+		sputc(q,0);
+		ct -= 2;
+	}
+	rewind(p);
+	while(sfeof(p) == 0) {
+		sputc(q,sgetc(p));
+	}
+	release(p);
+	if(ct == 1) {
+		t = mult(tenptr,q);
+		release(q);
+		return(t);
+	}
+	return(q);
+}
+
+Blk*
+mult(Blk *p, Blk *q)
+{
+	Blk *mp, *mq, *mr;
+	int sign, offset, carry;
+	int cq, cp, mt, mcr;
+
+	offset = sign = 0;
+	fsfile(p);
+	mp = p;
+	if(sfbeg(p) == 0) {
+		if(sbackc(p)<0) {
+			mp = copy(p,length(p));
+			chsign(mp);
+			sign = ~sign;
+		}
+	}
+	fsfile(q);
+	mq = q;
+	if(sfbeg(q) == 0){
+		if(sbackc(q)<0) {
+			mq = copy(q,length(q));
+			chsign(mq);
+			sign = ~sign;
+		}
+	}
+	mr = salloc(length(mp)+length(mq));
+	zero(mr);
+	rewind(mq);
+	while(sfeof(mq) == 0) {
+		cq = sgetc(mq);
+		rewind(mp);
+		rewind(mr);
+		mr->rd += offset;
+		carry=0;
+		while(sfeof(mp) == 0) {
+			cp = sgetc(mp);
+			mcr = sfeof(mr)?0:slookc(mr);
+			mt = cp*cq + carry + mcr;
+			carry = mt/100;
+			salterc(mr,mt%100);
+		}
+		offset++;
+		if(carry != 0) {
+			mcr = sfeof(mr)?0:slookc(mr);
+			salterc(mr,mcr+carry);
+		}
+	}
+	if(sign < 0) {
+		chsign(mr);
+	}
+	if(mp != p)
+		release(mp);
+	if(mq != q)
+		release(mq);
+	return(mr);
+}
+
+void
+chsign(Blk *p)
+{
+	int carry;
+	char ct;
+
+	carry=0;
+	rewind(p);
+	while(sfeof(p) == 0) {
+		ct=100-slookc(p)-carry;
+		carry=1;
+		if(ct>=100) {
+			ct -= 100;
+			carry=0;
+		}
+		salterc(p,ct);
+	}
+	if(carry != 0) {
+		sputc(p,-1);
+		fsfile(p);
+		backc(p);
+		ct = sbackc(p);
+		if(ct == 99 /*&& !sfbeg(p)*/) {
+			truncate(p);
+			sputc(p,-1);
+		}
+	} else{
+		fsfile(p);
+		ct = sbackc(p);
+		if(ct == 0)
+			truncate(p);
+	}
+	return;
+}
+
+int
+readc(void)
+{
+loop:
+	if((readptr != &readstk[0]) && (*readptr != 0)) {
+		if(sfeof(*readptr) == 0)
+			return(lastchar = sgetc(*readptr));
+		release(*readptr);
+		readptr--;
+		goto loop;
+	}
+	lastchar = Bgetc(curfile);
+	if(lastchar != -1)
+		return(lastchar);
+	if(readptr != &readptr[0]) {
+		readptr--;
+		if(*readptr == 0)
+			curfile = &bin;
+		goto loop;
+	}
+	if(curfile != &bin) {
+		Bterm(curfile);
+		curfile = &bin;
+		goto loop;
+	}
+	exits(0);
+	return 0;	/* shut up ken */
+}
+
+void
+unreadc(char c)
+{
+
+	if((readptr != &readstk[0]) && (*readptr != 0)) {
+		sungetc(*readptr,c);
+	} else
+		Bungetc(curfile);
+	return;
+}
+
+void
+binop(char c)
+{
+	Blk *r;
+
+	r = 0;
+	switch(c) {
+	case '+':
+		r = add(arg1,arg2);
+		break;
+	case '*':
+		r = mult(arg1,arg2);
+		break;
+	case '/':
+		r = div(arg1,arg2);
+		break;
+	}
+	release(arg1);
+	release(arg2);
+	sputc(r,savk);
+	pushp(r);
+}
+
+void
+dcprint(Blk *hptr)
+{
+	Blk *p, *q, *dec;
+	int dig, dout, ct, sc;
+
+	rewind(hptr);
+	while(sfeof(hptr) == 0) {
+		if(sgetc(hptr)>99) {
+			rewind(hptr);
+			while(sfeof(hptr) == 0) {
+				Bprint(&bout,"%c",sgetc(hptr));
+			}
+			Bprint(&bout,"\n");
+			return;
+		}
+	}
+	fsfile(hptr);
+	sc = sbackc(hptr);
+	if(sfbeg(hptr) != 0) {
+		Bprint(&bout,"0\n");
+		return;
+	}
+	count = ll;
+	p = copy(hptr,length(hptr));
+	sclobber(p);
+	fsfile(p);
+	if(sbackc(p)<0) {
+		chsign(p);
+		OUTC('-');
+	}
+	if((obase == 0) || (obase == -1)) {
+		oneot(p,sc,'d');
+		return;
+	}
+	if(obase == 1) {
+		oneot(p,sc,'1');
+		return;
+	}
+	if(obase == 10) {
+		tenot(p,sc);
+		return;
+	}
+	/* sleazy hack to scale top of stack - divide by 1 */
+	pushp(p);
+	sputc(p, sc);
+	p=salloc(0);
+	create(p);
+	sputc(p, 1);
+	sputc(p, 0);
+	pushp(p);
+	if(dscale() != 0)
+		return;
+	p = div(arg1, arg2);
+	release(arg1);
+	release(arg2);
+	sc = savk;
+
+	create(strptr);
+	dig = logten*sc;
+	dout = ((dig/10) + dig) / logo;
+	dec = getdec(p,sc);
+	p = removc(p,sc);
+	while(length(p) != 0) {
+		q = div(p,basptr);
+		release(p);
+		p = q;
+		(*outdit)(rem,0);
+	}
+	release(p);
+	fsfile(strptr);
+	while(sfbeg(strptr) == 0)
+		OUTC(sbackc(strptr));
+	if(sc == 0) {
+		release(dec);
+		Bprint(&bout,"\n");
+		return;
+	}
+	create(strptr);
+	OUTC('.');
+	ct=0;
+	do {
+		q = mult(basptr,dec);
+		release(dec);
+		dec = getdec(q,sc);
+		p = removc(q,sc);
+		(*outdit)(p,1);
+	} while(++ct < dout);
+	release(dec);
+	rewind(strptr);
+	while(sfeof(strptr) == 0)
+		OUTC(sgetc(strptr));
+	Bprint(&bout,"\n");
+}
+
+Blk*
+getdec(Blk *p, int sc)
+{
+	int cc;
+	Blk *q, *t, *s;
+
+	rewind(p);
+	if(length(p)*2 < sc) {
+		q = copy(p,length(p));
+		return(q);
+	}
+	q = salloc(length(p));
+	while(sc >= 1) {
+		sputc(q,sgetc(p));
+		sc -= 2;
+	}
+	if(sc != 0) {
+		t = mult(q,tenptr);
+		s = salloc(cc = length(q));
+		release(q);
+		rewind(t);
+		while(cc-- > 0)
+			sputc(s,sgetc(t));
+		sputc(s,0);
+		release(t);
+		t = div(s,tenptr);
+		release(s);
+		release(rem);
+		return(t);
+	}
+	return(q);
+}
+
+void
+tenot(Blk *p, int sc)
+{
+	int c, f;
+
+	fsfile(p);
+	f=0;
+	while((sfbeg(p) == 0) && ((p->rd-p->beg-1)*2 >= sc)) {
+		c = sbackc(p);
+		if((c<10) && (f == 1))
+			Bprint(&bout,"0%d",c);
+		else
+			Bprint(&bout,"%d",c);
+		f=1;
+		TEST2;
+	}
+	if(sc == 0) {
+		Bprint(&bout,"\n");
+		release(p);
+		return;
+	}
+	if((p->rd-p->beg)*2 > sc) {
+		c = sbackc(p);
+		Bprint(&bout,"%d.",c/10);
+		TEST2;
+		OUTC(c%10 +'0');
+		sc--;
+	} else {
+		OUTC('.');
+	}
+	while(sc>(p->rd-p->beg)*2) {
+		OUTC('0');
+		sc--;
+	}
+	while(sc > 1) {
+		c = sbackc(p);
+		if(c<10)
+			Bprint(&bout,"0%d",c);
+		else
+			Bprint(&bout,"%d",c);
+		sc -= 2;
+		TEST2;
+	}
+	if(sc == 1) {
+		OUTC(sbackc(p)/10 +'0');
+	}
+	Bprint(&bout,"\n");
+	release(p);
+}
+
+void
+oneot(Blk *p, int sc, char ch)
+{
+	Blk *q;
+
+	q = removc(p,sc);
+	create(strptr);
+	sputc(strptr,-1);
+	while(length(q)>0) {
+		p = add(strptr,q);
+		release(q);
+		q = p;
+		OUTC(ch);
+	}
+	release(q);
+	Bprint(&bout,"\n");
+}
+
+void
+hexot(Blk *p, int flg)
+{
+	int c;
+
+	USED(flg);
+	rewind(p);
+	if(sfeof(p) != 0) {
+		sputc(strptr,'0');
+		release(p);
+		return;
+	}
+	c = sgetc(p);
+	release(p);
+	if(c >= 16) {
+		Bprint(&bout,"hex digit > 16");
+		return;
+	}
+	sputc(strptr,c<10?c+'0':c-10+'a');
+}
+
+void
+bigot(Blk *p, int flg)
+{
+	Blk *t, *q;
+	int neg, l;
+
+	if(flg == 1) {
+		t = salloc(0);
+		l = 0;
+	} else {
+		t = strptr;
+		l = length(strptr)+fw-1;
+	}
+	neg=0;
+	if(length(p) != 0) {
+		fsfile(p);
+		if(sbackc(p)<0) {
+			neg=1;
+			chsign(p);
+		}
+		while(length(p) != 0) {
+			q = div(p,tenptr);
+			release(p);
+			p = q;
+			rewind(rem);
+			sputc(t,sfeof(rem)?'0':sgetc(rem)+'0');
+			release(rem);
+		}
+	}
+	release(p);
+	if(flg == 1) {
+		l = fw1-length(t);
+		if(neg != 0) {
+			l--;
+			sputc(strptr,'-');
+		}
+		fsfile(t);
+		while(l-- > 0)
+			sputc(strptr,'0');
+		while(sfbeg(t) == 0)
+			sputc(strptr,sbackc(t));
+		release(t);
+	} else {
+		l -= length(strptr);
+		while(l-- > 0)
+			sputc(strptr,'0');
+		if(neg != 0) {
+			sclobber(strptr);
+			sputc(strptr,'-');
+		}
+	}
+	sputc(strptr,' ');
+}
+
+Blk*
+add(Blk *a1, Blk *a2)
+{
+	Blk *p;
+	int carry, n, size, c, n1, n2;
+
+	size = length(a1)>length(a2)?length(a1):length(a2);
+	p = salloc(size);
+	rewind(a1);
+	rewind(a2);
+	carry=0;
+	while(--size >= 0) {
+		n1 = sfeof(a1)?0:sgetc(a1);
+		n2 = sfeof(a2)?0:sgetc(a2);
+		n = n1 + n2 + carry;
+		if(n>=100) {
+			carry=1;
+			n -= 100;
+		} else
+		if(n<0) {
+			carry = -1;
+			n += 100;
+		} else
+			carry = 0;
+		sputc(p,n);
+	}
+	if(carry != 0)
+		sputc(p,carry);
+	fsfile(p);
+	if(sfbeg(p) == 0) {
+		c = 0;
+		while(sfbeg(p) == 0 && (c = sbackc(p)) == 0)
+			;
+		if(c != 0)
+			salterc(p,c);
+		truncate(p);
+	}
+	fsfile(p);
+	if(sfbeg(p) == 0 && sbackc(p) == -1) {
+		while((c = sbackc(p)) == 99) {
+			if(c == -1)
+				break;
+		}
+		skipc(p);
+		salterc(p,-1);
+		truncate(p);
+	}
+	return(p);
+}
+
+int
+eqk(void)
+{
+	Blk *p, *q;
+	int skp, skq;
+
+	p = pop();
+	EMPTYS;
+	q = pop();
+	EMPTYSR(p);
+	skp = sunputc(p);
+	skq = sunputc(q);
+	if(skp == skq) {
+		arg1=p;
+		arg2=q;
+		savk = skp;
+		return(0);
+	}
+	if(skp < skq) {
+		savk = skq;
+		p = add0(p,skq-skp);
+	} else {
+		savk = skp;
+		q = add0(q,skp-skq);
+	}
+	arg1=p;
+	arg2=q;
+	return(0);
+}
+
+Blk*
+removc(Blk *p, int n)
+{
+	Blk *q, *r;
+
+	rewind(p);
+	while(n>1) {
+		skipc(p);
+		n -= 2;
+	}
+	q = salloc(2);
+	while(sfeof(p) == 0)
+		sputc(q,sgetc(p));
+	if(n == 1) {
+		r = div(q,tenptr);
+		release(q);
+		release(rem);
+		q = r;
+	}
+	release(p);
+	return(q);
+}
+
+Blk*
+scalint(Blk *p)
+{
+	int n;
+
+	n = sunputc(p);
+	p = removc(p,n);
+	return(p);
+}
+
+Blk*
+scale(Blk *p, int n)
+{
+	Blk *q, *s, *t;
+
+	t = add0(p,n);
+	q = salloc(1);
+	sputc(q,n);
+	s = dcexp(inbas,q);
+	release(q);
+	q = div(t,s);
+	release(t);
+	release(s);
+	release(rem);
+	sputc(q,n);
+	return(q);
+}
+
+int
+subt(void)
+{
+	arg1=pop();
+	EMPTYS;
+	savk = sunputc(arg1);
+	chsign(arg1);
+	sputc(arg1,savk);
+	pushp(arg1);
+	if(eqk() != 0)
+		return(1);
+	binop('+');
+	return(0);
+}
+
+int
+command(void)
+{
+	char line[100], *sl;
+	int pid, p, c;
+
+	switch(c = readc()) {
+	case '<':
+		return(cond(NL));
+	case '>':
+		return(cond(NG));
+	case '=':
+		return(cond(NE));
+	default:
+		sl = line;
+		*sl++ = c;
+		while((c = readc()) != '\n')
+			*sl++ = c;
+		*sl = 0;
+		if((pid = fork()) == 0) {
+			execl("/bin/rc","rc","-c",line,0);
+			exits("shell");
+		}
+		for(;;) {
+			if((p = waitpid()) < 0)
+				break;
+			if(p== pid)
+				break;
+		}
+		Bprint(&bout,"!\n");
+		return(0);
+	}
+}
+
+int
+cond(char c)
+{
+	Blk *p;
+	int cc;
+
+	if(subt() != 0)
+		return(1);
+	p = pop();
+	sclobber(p);
+	if(length(p) == 0) {
+		release(p);
+		if(c == '<' || c == '>' || c == NE) {
+			getstk();
+			return(0);
+		}
+		load();
+		return(1);
+	}
+	if(c == '='){
+		release(p);
+		getstk();
+		return(0);
+	}
+	if(c == NE) {
+		release(p);
+		load();
+		return(1);
+	}
+	fsfile(p);
+	cc = sbackc(p);
+	release(p);
+	if((cc<0 && (c == '<' || c == NG)) ||
+	   (cc >0) && (c == '>' || c == NL)) {
+		getstk();
+		return(0);
+	}
+	load();
+	return(1);
+}
+
+void
+load(void)
+{
+	int c;
+	Blk *p, *q, *t, *s;
+
+	c = getstk() & 0377;
+	sptr = stable[c];
+	if(sptr != 0) {
+		p = sptr->val;
+		if(c >= ARRAYST) {
+			q = salloc(length(p));
+			rewind(p);
+			while(sfeof(p) == 0) {
+				s = dcgetwd(p);
+				if(s == 0) {
+					putwd(q, (Blk*)0);
+				} else {
+					t = copy(s,length(s));
+					putwd(q,t);
+				}
+			}
+			pushp(q);
+		} else {
+			q = copy(p,length(p));
+			pushp(q);
+		}
+	} else {
+		q = salloc(1);
+		if(c <= LASTFUN) {
+			Bprint(&bout,"function %c undefined\n",c+'a'-1);
+			sputc(q,'c');
+			sputc(q,'0');
+			sputc(q,' ');
+			sputc(q,'1');
+			sputc(q,'Q');
+		}
+		else
+			sputc(q,0);
+		pushp(q);
+	}
+}
+
+int
+log2(long n)
+{
+	int i;
+
+	if(n == 0)
+		return(0);
+	i=31;
+	if(n<0)
+		return(i);
+	while((n= n<<1) >0)
+		i--;
+	return i-1;
+}
+
+Blk*
+salloc(int size)
+{
+	Blk *hdr;
+	char *ptr;
+
+	all++;
+	lall++;
+	if(all - rel > active)
+		active = all - rel;
+	nbytes += size;
+	lbytes += size;
+	if(nbytes >maxsize)
+		maxsize = nbytes;
+	if(size > longest)
+		longest = size;
+	ptr = malloc((unsigned)size);
+	if(ptr == 0){
+		garbage("salloc");
+		if((ptr = malloc((unsigned)size)) == 0)
+			ospace("salloc");
+	}
+	if((hdr = hfree) == 0)
+		hdr = morehd();
+	hfree = (Blk *)hdr->rd;
+	hdr->rd = hdr->wt = hdr->beg = ptr;
+	hdr->last = ptr+size;
+	return(hdr);
+}
+
+Blk*
+morehd(void)
+{
+	Blk *h, *kk;
+
+	headmor++;
+	nbytes += HEADSZ;
+	hfree = h = (Blk *)malloc(HEADSZ);
+	if(hfree == 0) {
+		garbage("morehd");
+		if((hfree = h = (Blk*)malloc(HEADSZ)) == 0)
+			ospace("headers");
+	}
+	kk = h;
+	while(h<hfree+(HEADSZ/BLK))
+		(h++)->rd = (char*)++kk;
+	(h-1)->rd=0;
+	return(hfree);
+}
+
+Blk*
+copy(Blk *hptr, int size)
+{
+	Blk *hdr;
+	unsigned sz;
+	char *ptr;
+
+	all++;
+	lall++;
+	lcopy++;
+	nbytes += size;
+	lbytes += size;
+	if(size > longest)
+		longest = size;
+	if(size > maxsize)
+		maxsize = size;
+	sz = length(hptr);
+	ptr = nalloc(hptr->beg, size);
+	if(ptr == 0) {
+		garbage("copy");
+		if((ptr = nalloc(hptr->beg, size)) == 0) {
+			Bprint(&bout,"copy size %d\n",size);
+			ospace("copy");
+		}
+	}
+	if((hdr = hfree) == 0)
+		hdr = morehd();
+	hfree = (Blk *)hdr->rd;
+	hdr->rd = hdr->beg = ptr;
+	hdr->last = ptr+size;
+	hdr->wt = ptr+sz;
+	ptr = hdr->wt;
+	while(ptr<hdr->last)
+		*ptr++ = '\0';
+	return(hdr);
+}
+
+void
+sdump(char *s1, Blk *hptr)
+{
+	char *p;
+
+	Bprint(&bout,"%s %lx rd %lx wt %lx beg %lx last %lx\n",
+		s1,hptr,hptr->rd,hptr->wt,hptr->beg,hptr->last);
+	p = hptr->beg;
+	while(p < hptr->wt)
+		Bprint(&bout,"%d ",*p++);
+	Bprint(&bout,"\n");
+}
+
+void
+seekc(Blk *hptr, int n)
+{
+	char *nn,*p;
+
+	nn = hptr->beg+n;
+	if(nn > hptr->last) {
+		nbytes += nn - hptr->last;
+		if(nbytes > maxsize)
+			maxsize = nbytes;
+		lbytes += nn - hptr->last;
+		if(n > longest)
+			longest = n;
+/*		free(hptr->beg); *//**/
+		p = realloc(hptr->beg, n);
+		if(p == 0) {
+/*			hptr->beg = realloc(hptr->beg, hptr->last-hptr->beg);
+**			garbage("seekc");
+**			if((p = realloc(hptr->beg, n)) == 0)
+*/				ospace("seekc");
+		}
+		hptr->beg = p;
+		hptr->wt = hptr->last = hptr->rd = p+n;
+		return;
+	}
+	hptr->rd = nn;
+	if(nn>hptr->wt)
+		hptr->wt = nn;
+}
+
+void
+salterwd(Blk *ahptr, Blk *n)
+{
+	Wblk *hptr;
+
+	hptr = (Wblk*)ahptr;
+	if(hptr->rdw == hptr->lastw)
+		more(ahptr);
+	*hptr->rdw++ = n;
+	if(hptr->rdw > hptr->wtw)
+		hptr->wtw = hptr->rdw;
+}
+
+void
+more(Blk *hptr)
+{
+	unsigned size;
+	char *p;
+
+	if((size=(hptr->last-hptr->beg)*2) == 0)
+		size=2;
+	nbytes += size/2;
+	if(nbytes > maxsize)
+		maxsize = nbytes;
+	if(size > longest)
+		longest = size;
+	lbytes += size/2;
+	lmore++;
+/*	free(hptr->beg);*//**/
+	p = realloc(hptr->beg, size);
+
+	if(p == 0) {
+/*		hptr->beg = realloc(hptr->beg, (hptr->last-hptr->beg));
+**		garbage("more");
+**		if((p = realloc(hptr->beg,size)) == 0)
+*/			ospace("more");
+	}
+	hptr->rd = p + (hptr->rd - hptr->beg);
+	hptr->wt = p + (hptr->wt - hptr->beg);
+	hptr->beg = p;
+	hptr->last = p+size;
+}
+
+void
+ospace(char *s)
+{
+	Bprint(&bout,"out of space: %s\n",s);
+	Bprint(&bout,"all %ld rel %ld headmor %ld\n",all,rel,headmor);
+	Bprint(&bout,"nbytes %ld\n",nbytes);
+	sdump("stk",*stkptr);
+	abort();
+}
+
+void
+garbage(char *s)
+{
+	USED(s);
+}
+
+void
+release(Blk *p)
+{
+	rel++;
+	lrel++;
+	nbytes -= p->last - p->beg;
+	p->rd = (char*)hfree;
+	hfree = p;
+	free(p->beg);
+}
+
+Blk*
+dcgetwd(Blk *p)
+{
+	Wblk *wp;
+
+	wp = (Wblk*)p;
+	if(wp->rdw == wp->wtw)
+		return(0);
+	return(*wp->rdw++);
+}
+
+void
+putwd(Blk *p, Blk *c)
+{
+	Wblk *wp;
+
+	wp = (Wblk*)p;
+	if(wp->wtw == wp->lastw)
+		more(p);
+	*wp->wtw++ = c;
+}
+
+Blk*
+lookwd(Blk *p)
+{
+	Wblk *wp;
+
+	wp = (Wblk*)p;
+	if(wp->rdw == wp->wtw)
+		return(0);
+	return(*wp->rdw);
+}
+
+char*
+nalloc(char *p, unsigned nbytes)
+{
+	char *q, *r;
+
+	q = r = malloc(nbytes);
+	if(q==0)
+		return(0);
+	while(nbytes--)
+		*q++ = *p++;
+	return(r);
+}
+
+int
+getstk(void)
+{
+	int n;
+	uchar c;
+
+	c = readc();
+	if(c != '<')
+		return c;
+	n = 0;
+	while(1) {
+		c = readc();
+		if(c == '>')
+			break;
+		n = n*10+c-'0';
+	}
+	return n;
+}