hbase

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

dc.c (35168B)


      1 /*	from 4.4BSD /usr/src/usr.bin/dc/dc.c	*/
      2 /*-
      3  * Copyright (c) 1991, 1993
      4  *	The Regents of the University of California.  All rights reserved.
      5  *
      6  * This module is believed to contain source code proprietary to AT&T.
      7  * Use and redistribution is subject to the Berkeley Software License
      8  * Agreement and your Software Agreement with AT&T (Western Electric).
      9  *
     10  *	from dc.c	8.1 (Berkeley) 6/6/93"
     11  */
     12 /*
     13  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  *   Redistributions of source code and documentation must retain the
     19  *    above copyright notice, this list of conditions and the following
     20  *    disclaimer.
     21  *   Redistributions in binary form must reproduce the above copyright
     22  *    notice, this list of conditions and the following disclaimer in the
     23  *    documentation and/or other materials provided with the distribution.
     24  *   All advertising materials mentioning features or use of this software
     25  *    must display the following acknowledgement:
     26  *      This product includes software developed or owned by Caldera
     27  *      International, Inc.
     28  *   Neither the name of Caldera International, Inc. nor the names of
     29  *    other contributors may be used to endorse or promote products
     30  *    derived from this software without specific prior written permission.
     31  *
     32  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
     33  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
     34  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     35  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     36  * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
     37  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
     38  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     39  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     40  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     41  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     42  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     43  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     44  */
     45 /*	Sccsid @(#)dc.c	1.21 (gritter) 12/25/06>	*/
     46 
     47 #include <sys/types.h>
     48 #include <sys/wait.h>
     49 #include <unistd.h>
     50 #include <stdio.h>
     51 #include <signal.h>
     52 #include "sigset.h"
     53 #include <stdlib.h>
     54 #include <inttypes.h>
     55 #include <limits.h>
     56 
     57 #include "dc.h"
     58 
     59 int
     60 main(int argc,char **argv)
     61 {
     62 	init(argc,argv);
     63 	commnds();
     64 	/*NOTREACHED*/
     65 	return(0);
     66 }
     67 
     68 void
     69 commnds(void){
     70 	register int c;
     71 	register struct blk *p,*q;
     72 	long l;
     73 	int sign;
     74 	struct blk **ptr,*s,*t;
     75 	struct sym *sp;
     76 	int sk,sk1,sk2;
     77 	int n,d;
     78 
     79 	while(1){
     80 		if(((c = readc())>='0' && c <= '9')|| (c>='A' && c <='F') || c == '.'){
     81 			unreadc(c);
     82 			p = readin();
     83 			pushp(p);
     84 			continue;
     85 		}
     86 		switch(c){
     87 		case ' ':
     88 		case '\n':
     89 		case 0377:
     90 		case EOF:
     91 			continue;
     92 		case 'Y':
     93 			sdump("stk",*stkptr);
     94 			printf("all %ld rel %ld headmor %ld\n",all,rel,headmor);
     95 			printf("nbytes %ld\n",nbytes);
     96 			continue;
     97 		case '_':
     98 			p = readin();
     99 			savk = sunputc(p);
    100 			chsign(p);
    101 			sputc(p,savk);
    102 			pushp(p);
    103 			continue;
    104 		case '-':
    105 			subt();
    106 			continue;
    107 		case '+':
    108 			if(eqk() != 0)continue;
    109 			binop('+');
    110 			continue;
    111 		case '*':
    112 			arg1 = pop();
    113 			EMPTY;
    114 			arg2 = pop();
    115 			EMPTYR(arg1);
    116 			sk1 = sunputc(arg1);
    117 			sk2 = sunputc(arg2);
    118 			binop('*');
    119 			p = pop();
    120 			sunputc(p);
    121 			savk = n = sk1+sk2;
    122 			if(n>k && n>sk1 && n>sk2){
    123 				sk = sk1;
    124 				if(sk<sk2)sk = sk2;
    125 				if(sk<k)sk = k;
    126 				p = removc(p,n-sk);
    127 				savk = sk;
    128 			}
    129 			sputc(p,savk);
    130 			pushp(p);
    131 			continue;
    132 		case '/':
    133 casediv:
    134 			if(dscale() != 0)continue;
    135 			binop('/');
    136 			if(irem != 0)release(irem);
    137 			release(rem);
    138 			continue;
    139 		case '%':
    140 			if(dscale() != 0)continue;
    141 			binop('/');
    142 			p = pop();
    143 			release(p);
    144 			if(irem == 0){
    145 				sputc(rem,skr+k);
    146 				pushp(rem);
    147 				continue;
    148 			}
    149 			p = add0(rem,skd-(skr+k));
    150 			q = add(p,irem);
    151 			release(p);
    152 			release(irem);
    153 			sputc(q,skd);
    154 			pushp(q);
    155 			continue;
    156 		case 'v':
    157 			p = pop();
    158 			EMPTY;
    159 			savk = sunputc(p);
    160 			if(length(p) == 0){
    161 				sputc(p,savk);
    162 				pushp(p);
    163 				continue;
    164 			}
    165 			if((c = sbackc(p))<0){
    166 				error("sqrt of neg number\n");
    167 			}
    168 			if(k<savk)n = savk;
    169 			else{
    170 				n = k*2-savk;
    171 				savk = k;
    172 			}
    173 			arg1 = add0(p,n);
    174 			arg2 = dcsqrt(arg1);
    175 			sputc(arg2,savk);
    176 			pushp(arg2);
    177 			continue;
    178 		case '^':
    179 			neg = 0;
    180 			arg1 = pop();
    181 			EMPTY;
    182 			if(sunputc(arg1) != 0)error("exp not an integer\n");
    183 			arg2 = pop();
    184 			EMPTYR(arg1);
    185 			if(sfbeg(arg1) == 0 && sbackc(arg1)<0){
    186 				neg++;
    187 				chsign(arg1);
    188 			}
    189 			if(length(arg1)>=3){
    190 				error("exp too big\n");
    191 			}
    192 			savk = sunputc(arg2);
    193 			p = dcexp(arg2,arg1);
    194 			release(arg2);
    195 			rewind(arg1);
    196 			c = sgetc(arg1);
    197 			if(sfeof(arg1) == 0)
    198 				c = sgetc(arg1)*100 + c;
    199 			d = c*savk;
    200 			release(arg1);
    201 			if(neg == 0){
    202 				if(k>=savk)n = k;
    203 				else n = savk;
    204 				if(n<d){
    205 					q = removc(p,d-n);
    206 					sputc(q,n);
    207 					pushp(q);
    208 				}
    209 				else {
    210 					sputc(p,d);
    211 					pushp(p);
    212 				}
    213 			}
    214 			else {
    215 				sputc(p,d);
    216 				pushp(p);
    217 			}
    218 			if(neg == 0)continue;
    219 			p = pop();
    220 			q = salloc(2);
    221 			sputc(q,1);
    222 			sputc(q,0);
    223 			pushp(q);
    224 			pushp(p);
    225 			goto casediv;
    226 		case 'z':
    227 			p = salloc(2);
    228 			n = stkptr - stkbeg;
    229 			if(n >= 100){
    230 				sputc(p,n/100);
    231 				n %= 100;
    232 			}
    233 			sputc(p,n);
    234 			sputc(p,0);
    235 			pushp(p);
    236 			continue;
    237 		case 'Z':
    238 			p = pop();
    239 			EMPTY;
    240 			n = (length(p)-1)<<1;
    241 			fsfile(p);
    242 			sbackc(p);
    243 			if(sfbeg(p) == 0){
    244 				if((c = sbackc(p))<0){
    245 					n -= 2;
    246 					if(sfbeg(p) == 1)n += 1;
    247 					else {
    248 						if((c = sbackc(p)) == 0)n += 1;
    249 						else if(c > 90)n -= 1;
    250 					}
    251 				}
    252 				else if(c < 10) n -= 1;
    253 			}
    254 			release(p);
    255 			q = salloc(1);
    256 			if(n >= 100){
    257 				sputc(q,n%100);
    258 				n /= 100;
    259 			}
    260 			sputc(q,n);
    261 			sputc(q,0);
    262 			pushp(q);
    263 			continue;
    264 		case 'i':
    265 			p = pop();
    266 			EMPTY;
    267 			p = scalint(p);
    268 			release(inbas);
    269 			inbas = p;
    270 			continue;
    271 		case 'I':
    272 			p = copy(inbas,length(inbas)+1);
    273 			sputc(p,0);
    274 			pushp(p);
    275 			continue;
    276 		case 'o':
    277 			p = pop();
    278 			EMPTY;
    279 			p = scalint(p);
    280 			sign = 0;
    281 			n = length(p);
    282 			q = copy(p,n);
    283 			fsfile(q);
    284 			l = c = sbackc(q);
    285 			if(n != 1){
    286 				if(c<0){
    287 					sign = 1;
    288 					chsign(q);
    289 					n = length(q);
    290 					fsfile(q);
    291 					l = c = sbackc(q);
    292 				}
    293 				if(n != 1){
    294 					while(sfbeg(q) == 0)l = l*100+sbackc(q);
    295 				}
    296 			}
    297 			if (l > BC_BASE_MAX)
    298 				error("output base is too large\n");
    299 			logo = log_2(l);
    300 			obase = l;
    301 			release(basptr);
    302 			if(sign == 1)obase = (long)-l;
    303 			basptr = p;
    304 			outdit = (int (*)(struct blk *, int, int))bigot;
    305 			if(n == 1 && sign == 0){
    306 				if(c <= 16){
    307 					outdit = (int (*)(struct blk *, int, int))hexot;
    308 					fw = 1;
    309 					fw1 = 0;
    310 					ll = 68;
    311 					release(q);
    312 					continue;
    313 				}
    314 			}
    315 			n = 0;
    316 			if(sign == 1)n++;
    317 			p = salloc(1);
    318 			sputc(p,-1);
    319 			t = add(p,q);
    320 			n += length(t)*2;
    321 			fsfile(t);
    322 			if((c = sbackc(t))>9)n++;
    323 			release(t);
    324 			release(q);
    325 			release(p);
    326 			fw = n;
    327 			fw1 = n-1;
    328 			ll = 68;
    329 			if(fw>=ll)continue;
    330 			ll = (68/fw)*fw;
    331 			continue;
    332 		case 'O':
    333 			p = copy(basptr,length(basptr)+1);
    334 			sputc(p,0);
    335 			pushp(p);
    336 			continue;
    337 		case '[':
    338 			n = 0;
    339 			p = salloc(0);
    340 			while(1){
    341 				if((c = readc()) == ']'){
    342 					if(n == 0)break;
    343 					n--;
    344 				}
    345 				sputc(p,c);
    346 				if(c == '[')n++;
    347 			}
    348 			pushp(p);
    349 			continue;
    350 		case 'k':
    351 			p = pop();
    352 			EMPTY;
    353 			p = scalint(p);
    354 			if(length(p)>1){
    355 				error("scale too big\n");
    356 			}
    357 			rewind(p);
    358 			k = sfeof(p)?0:sgetc(p);
    359 			release(scalptr);
    360 			scalptr = p;
    361 			continue;
    362 		case 'K':
    363 			p = copy(scalptr,length(scalptr)+1);
    364 			sputc(p,0);
    365 			pushp(p);
    366 			continue;
    367 		case 'X':
    368 			p = pop();
    369 			EMPTY;
    370 			fsfile(p);
    371 			n = sbackc(p);
    372 			release(p);
    373 			p = salloc(2);
    374 			sputc(p,n);
    375 			sputc(p,0);
    376 			pushp(p);
    377 			continue;
    378 		case 'Q':
    379 			p = pop();
    380 			EMPTY;
    381 			if(length(p)>2){
    382 				error("Q?\n");
    383 			}
    384 			rewind(p);
    385 			if((c =  sgetc(p))<0){
    386 				error("neg Q\n");
    387 			}
    388 			release(p);
    389 			while(c-- > 0){
    390 				if(readptr == &readstk[0]){
    391 					error("readstk?\n");
    392 				}
    393 				if(*readptr != 0)release(*readptr);
    394 				readptr--;
    395 			}
    396 			continue;
    397 		case 'q':
    398 			if(readptr <= &readstk[1])exit(0);
    399 			if(*readptr != 0)release(*readptr);
    400 			readptr--;
    401 			if(*readptr != 0)release(*readptr);
    402 			readptr--;
    403 			continue;
    404 		case 'f':
    405 			if(stkptr == &stack[0])printf("empty stack\n");
    406 			else {
    407 				for(ptr = stkptr; ptr > &stack[0];){
    408 					print(*ptr--);
    409 				}
    410 			}
    411 			continue;
    412 		case 'p':
    413 			if(stkptr == &stack[0])printf("empty stack\n");
    414 			else{
    415 				print(*stkptr);
    416 			}
    417 			continue;
    418 		case 'P':
    419 			p = pop();
    420 			EMPTY;
    421 			sputc(p,0);
    422 			printf("%s",p->beg);
    423 			release(p);
    424 			continue;
    425 		case 'd':
    426 			if(stkptr == &stack[0]){
    427 				printf("empty stack\n");
    428 				continue;
    429 			}
    430 			q = *stkptr;
    431 			n = length(q);
    432 			p = copy(*stkptr,n);
    433 			pushp(p);
    434 			continue;
    435 		case 'c':
    436 			while(stkerr == 0){
    437 				p = pop();
    438 				if(stkerr == 0)release(p);
    439 			}
    440 			continue;
    441 		case 'S':
    442 			if(stkptr == &stack[0]){
    443 				error("save: args\n");
    444 			}
    445 			c = readc() & 0377;
    446 			sptr = stable[c];
    447 			sp = stable[c] = sfree;
    448 			sfree = sfree->next;
    449 			if(sfree == 0)goto sempty;
    450 			sp->next = sptr;
    451 			p = pop();
    452 			EMPTY;
    453 			if(c >= ARRAYST){
    454 				q = copy(p,length(p));
    455 				for(n = 0;n < PTRSZ;n++)sputc(q,0);
    456 				release(p);
    457 				p = q;
    458 			}
    459 			sp->val = p;
    460 			continue;
    461 sempty:
    462 			error("symbol table overflow\n");
    463 		case 's':
    464 			if(stkptr == &stack[0]){
    465 				error("save:args\n");
    466 			}
    467 			c = readc() & 0377;
    468 			sptr = stable[c];
    469 			if(sptr != 0){
    470 				p = sptr->val;
    471 				if(c >= ARRAYST){
    472 					rewind(p);
    473 					while(sfeof(p) == 0)release(dcgetwd(p));
    474 				}
    475 				release(p);
    476 			}
    477 			else{
    478 				sptr = stable[c] = sfree;
    479 				sfree = sfree->next;
    480 				if(sfree == 0)goto sempty;
    481 				sptr->next = 0;
    482 			}
    483 			p = pop();
    484 			sptr->val = p;
    485 			continue;
    486 		case 'l':
    487 			load();
    488 			continue;
    489 		case 'L':
    490 			c = readc() & 0377;
    491 			sptr = stable[c];
    492 			if(sptr == 0){
    493 				error("L?\n");
    494 			}
    495 			stable[c] = sptr->next;
    496 			sptr->next = sfree;
    497 			sfree = sptr;
    498 			p = sptr->val;
    499 			if(c >= ARRAYST){
    500 				rewind(p);
    501 				while(sfeof(p) == 0){
    502 					q = dcgetwd(p);
    503 					if(q != 0)release(q);
    504 				}
    505 			}
    506 			pushp(p);
    507 			continue;
    508 		case ':':
    509 			p = pop();
    510 			EMPTY;
    511 			q = scalint(p);
    512 			fsfile(q);
    513 			c = 0;
    514 			if((sfbeg(q) == 0) && ((c = sbackc(q))<0)){
    515 				error("neg index\n");
    516 			}
    517 			if(length(q)>2){
    518 				error("index too big\n");
    519 			}
    520 			if(sfbeg(q) == 0)c = c*100+sbackc(q);
    521 			if(c >= BC_DIM_MAX){
    522 				error("index too big\n");
    523 			}
    524 			release(q);
    525 			n = readc() & 0377;
    526 			sptr = stable[n];
    527 			if(sptr == 0){
    528 				sptr = stable[n] = sfree;
    529 				sfree = sfree->next;
    530 				if(sfree == 0)goto sempty;
    531 				sptr->next = 0;
    532 				p = salloc((c+PTRSZ)*PTRSZ);
    533 				zero(p);
    534 			}
    535 			else{
    536 				p = sptr->val;
    537 				if(length(p)-PTRSZ < c*PTRSZ){
    538 					q = copy(p,(c+PTRSZ)*PTRSZ);
    539 					release(p);
    540 					p = q;
    541 				}
    542 			}
    543 			seekc(p,c*PTRSZ);
    544 			q = lookwd(p);
    545 			if (q!=NULL) release(q);
    546 			s = pop();
    547 			EMPTY;
    548 			salterwd((struct wblk *)p,s);
    549 			sptr->val = p;
    550 			continue;
    551 		case ';':
    552 			p = pop();
    553 			EMPTY;
    554 			q = scalint(p);
    555 			fsfile(q);
    556 			c = 0;
    557 			if((sfbeg(q) == 0) && ((c = sbackc(q))<0)){
    558 				error("neg index\n");
    559 			}
    560 			if(length(q)>2){
    561 				error("index too big\n");
    562 			}
    563 			if(sfbeg(q) == 0)c = c*100+sbackc(q);
    564 			if(c >= BC_DIM_MAX){
    565 				error("index too big\n");
    566 			}
    567 			release(q);
    568 			n = readc() & 0377;
    569 			sptr = stable[n];
    570 			if(sptr != 0){
    571 				p = sptr->val;
    572 				if(length(p)-PTRSZ >= c*PTRSZ){
    573 					seekc(p,c*PTRSZ);
    574 					s = dcgetwd(p);
    575 					if(s != 0){
    576 						q = copy(s,length(s));
    577 						pushp(q);
    578 						continue;
    579 					}
    580 				}
    581 			}
    582 			q = salloc(1);
    583 			sputc(q, 0);
    584 			pushp(q);
    585 			continue;
    586 		case 'x':
    587 execute:
    588 			p = pop();
    589 			EMPTY;
    590 			if((readptr != &readstk[0]) && (*readptr != 0)){
    591 				if((*readptr)->rd == (*readptr)->wt)
    592 					release(*readptr);
    593 				else{
    594 					if(readptr++ == &readstk[RDSKSZ]){
    595 						error("nesting depth\n");
    596 					}
    597 				}
    598 			}
    599 			else readptr++;
    600 			*readptr = p;
    601 			if(p != 0)rewind(p);
    602 			else{
    603 				if((c = readc()) != '\n')unreadc(c);
    604 			}
    605 			continue;
    606 		case '?':
    607 			if(++readptr == &readstk[RDSKSZ]){
    608 				error("nesting depth\n");
    609 			}
    610 			*readptr = 0;
    611 			fsave = curfile;
    612 			curfile = stdin;
    613 			while((c = readc()) == '!')command();
    614 			p = salloc(0);
    615 			sputc(p,c);
    616 			while((c = readc()) != '\n'){
    617 				sputc(p,c);
    618 				if(c == '\\')sputc(p,readc());
    619 			}
    620 			curfile = fsave;
    621 			*readptr = p;
    622 			continue;
    623 		case '!':
    624 			if(command() == 1)goto execute;
    625 			continue;
    626 		case '<':
    627 		case '>':
    628 		case '=':
    629 			if(cond(c) == 1)goto execute;
    630 			continue;
    631 		default:
    632 			printf("%o is unimplemented\n",c);
    633 		}
    634 	}
    635 }
    636 
    637 struct blk *
    638 div(struct blk *ddivd,struct blk *ddivr)
    639 {
    640 	int divsign,remsign,offset,divcarry = 0;
    641 	int carry, dig = 0,magic,d = 0,dd;
    642 	long c,td,cc;
    643 	struct blk *ps;
    644 	register struct blk *p,*divd,*divr;
    645 
    646 	rem = 0;
    647 	p = salloc(0);
    648 	if(length(ddivr) == 0){
    649 		pushp(ddivr);
    650 		printf("divide by 0\n");
    651 		return NULL;
    652 	}
    653 	divsign = remsign = 0;
    654 	divr = ddivr;
    655 	fsfile(divr);
    656 	if(sbackc(divr) == -1){
    657 		divr = copy(ddivr,length(ddivr));
    658 		chsign(divr);
    659 		divsign = ~divsign;
    660 	}
    661 	divd = copy(ddivd,length(ddivd));
    662 	fsfile(divd);
    663 	if(sfbeg(divd) == 0 && sbackc(divd) == -1){
    664 		chsign(divd);
    665 		divsign = ~divsign;
    666 		remsign = ~remsign;
    667 	}
    668 	offset = length(divd) - length(divr);
    669 	if(offset < 0)goto ddone;
    670 	seekc(p,offset+1);
    671 	sputc(divd,0);
    672 	magic = 0;
    673 	fsfile(divr);
    674 	c = sbackc(divr);
    675 	if(c<10)magic++;
    676 	c = c*100 + (sfbeg(divr)?0:sbackc(divr));
    677 	if(magic>0){
    678 		c = (c*100 +(sfbeg(divr)?0:sbackc(divr)))*2;
    679 		c /= 25;
    680 	}
    681 	while(offset >= 0){
    682 		fsfile(divd);
    683 		td = sbackc(divd)*100;
    684 		dd = sfbeg(divd)?0:sbackc(divd);
    685 		td = (td+dd)*100;
    686 		dd = sfbeg(divd)?0:sbackc(divd);
    687 		td = td+dd;
    688 		cc = c;
    689 		if(offset == 0)td += 1;
    690 		else cc += 1;
    691 		if(magic != 0)td = td<<3;
    692 		dig = td/cc;
    693 		rewind(divr);
    694 		rewind(divxyz);
    695 		carry = 0;
    696 		while(sfeof(divr) == 0){
    697 			d = sgetc(divr)*dig+carry;
    698 			carry = d / 100;
    699 			salterc(divxyz,d%100);
    700 		}
    701 		salterc(divxyz,carry);
    702 		rewind(divxyz);
    703 		seekc(divd,offset);
    704 		carry = 0;
    705 		while(sfeof(divd) == 0){
    706 			d = slookc(divd);
    707 			d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry;
    708 			carry = 0;
    709 			if(d < 0){
    710 				d += 100;
    711 				carry = 1;
    712 			}
    713 			salterc(divd,d);
    714 		}
    715 		divcarry = carry;
    716 		sbackc(p);
    717 		salterc(p,dig);
    718 		sbackc(p);
    719 		if(--offset >= 0){
    720 			if(d > 0){
    721 				sbackc(divd);
    722 				dd=sbackc(divd);
    723 				salterc(divd,dd+100);
    724 			}
    725 			divd->wt--;
    726 		}
    727 	}
    728 	if(divcarry != 0){
    729 		salterc(p,dig-1);
    730 		salterc(divd,-1);
    731 		ps = add(divr,divd);
    732 		release(divd);
    733 		divd = ps;
    734 	}
    735 
    736 	rewind(p);
    737 	divcarry = 0;
    738 	while(sfeof(p) == 0){
    739 		d = slookc(p)+divcarry;
    740 		divcarry = 0;
    741 		if(d >= 100){
    742 			d -= 100;
    743 			divcarry = 1;
    744 		}
    745 		salterc(p,d);
    746 	}
    747 	if(divcarry != 0)salterc(p,divcarry);
    748 	fsfile(p);
    749 	while(sfbeg(p) == 0){
    750 		if(sbackc(p) == 0)truncate(p);
    751 		else break;
    752 	}
    753 	if(divsign < 0)chsign(p);
    754 	fsfile(divd);
    755 	while(sfbeg(divd) == 0){
    756 		if(sbackc(divd) == 0)truncate(divd);
    757 		else break;
    758 	}
    759 ddone:
    760 	if(remsign<0)chsign(divd);
    761 	if(divr != ddivr)release(divr);
    762 	rem = divd;
    763 	return(p);
    764 }
    765 
    766 int
    767 dscale(void){
    768 	register struct blk *dd,*dr;
    769 	register struct blk *r;
    770 	int c;
    771 
    772 	dr = pop();
    773 	EMPTYS;
    774 	dd = pop();
    775 	EMPTYSR(dr);
    776 	fsfile(dd);
    777 	skd = sunputc(dd);
    778 	fsfile(dr);
    779 	skr = sunputc(dr);
    780 	if(sfbeg(dr) == 1 || (sfbeg(dr) == 0 && sbackc(dr) == 0)){
    781 		sputc(dr,skr);
    782 		pushp(dr);
    783 		errorrt("divide by 0\n");
    784 	}
    785 	c = k-skd+skr;
    786 	if(c < 0)r = removr(dd,-c);
    787 	else {
    788 		r = add0(dd,c);
    789 		irem = 0;
    790 	}
    791 	arg1 = r;
    792 	arg2 = dr;
    793 	savk = k;
    794 	return(0);
    795 }
    796 
    797 struct blk *
    798 removr(struct blk *p,int n)
    799 {
    800 	int nn;
    801 	register struct blk *q,*s,*r;
    802 
    803 	rewind(p);
    804 	nn = (n+1)/2;
    805 	q = salloc(nn);
    806 	while(n>1){
    807 		sputc(q,sgetc(p));
    808 		n -= 2;
    809 	}
    810 	r = salloc(2);
    811 	while(sfeof(p) == 0)sputc(r,sgetc(p));
    812 	release(p);
    813 	if(n == 1){
    814 		s = dcdiv(r,tenptr);
    815 		release(r);
    816 		rewind(rem);
    817 		if(sfeof(rem) == 0)sputc(q,sgetc(rem));
    818 		release(rem);
    819 		irem = q;
    820 		return(s);
    821 	}
    822 	irem = q;
    823 	return(r);
    824 }
    825 
    826 struct blk *
    827 sqrt(struct blk *p)
    828 {
    829 	struct blk *t;
    830 	struct blk *r,*q,*s;
    831 	int c,n,nn;
    832 
    833 	n = length(p);
    834 	fsfile(p);
    835 	c = sbackc(p);
    836 	if((n&1) != 1)c = c*100+(sfbeg(p)?0:sbackc(p));
    837 	n = (n+1)>>1;
    838 	r = salloc(n);
    839 	zero(r);
    840 	seekc(r,n);
    841 	nn=1;
    842 	while((c -= nn)>=0)nn+=2;
    843 	c=(nn+1)>>1;
    844 	fsfile(r);
    845 	sbackc(r);
    846 	if(c>=100){
    847 		c -= 100;
    848 		salterc(r,c);
    849 		sputc(r,1);
    850 	}
    851 	else salterc(r,c);
    852 	while(1){
    853 		q = dcdiv(p,r);
    854 		s = add(q,r);
    855 		release(q);
    856 		release(rem);
    857 		q = dcdiv(s,sqtemp);
    858 		release(s);
    859 		release(rem);
    860 		s = copy(r,length(r));
    861 		chsign(s);
    862 		t = add(s,q);
    863 		release(s);
    864 		fsfile(t);
    865 		nn = sfbeg(t)?0:sbackc(t);
    866 		if(nn>=0)break;
    867 		release(r);
    868 		release(t);
    869 		r = q;
    870 	}
    871 	release(t);
    872 	release(q);
    873 	release(p);
    874 	return(r);
    875 }
    876 
    877 struct blk *
    878 exp(struct blk *base,struct blk *ex)
    879 {
    880 	register struct blk *r,*e,*p;
    881 	struct blk *e1,*t,*cp;
    882 	int temp,c,n;
    883 	r = salloc(1);
    884 	sputc(r,1);
    885 	p = copy(base,length(base));
    886 	e = copy(ex,length(ex));
    887 	fsfile(e);
    888 	if(sfbeg(e) != 0)goto edone;
    889 	temp=0;
    890 	c = sbackc(e);
    891 	if(c<0){
    892 		temp++;
    893 		chsign(e);
    894 	}
    895 	while(length(e) != 0){
    896 		e1=dcdiv(e,sqtemp);
    897 		release(e);
    898 		e = e1;
    899 		n = length(rem);
    900 		release(rem);
    901 		if(n != 0){
    902 			e1=mult(p,r);
    903 			release(r);
    904 			r = e1;
    905 		}
    906 		t = copy(p,length(p));
    907 		cp = mult(p,t);
    908 		release(p);
    909 		release(t);
    910 		p = cp;
    911 	}
    912 	if(temp != 0){
    913 		if((c = length(base)) == 0){
    914 			goto edone;
    915 		}
    916 		if(c>1)create(r);
    917 		else{
    918 			rewind(base);
    919 			if((c = sgetc(base))<=1){
    920 				create(r);
    921 				sputc(r,c);
    922 			}
    923 			else create(r);
    924 		}
    925 	}
    926 edone:
    927 	release(p);
    928 	release(e);
    929 	return(r);
    930 }
    931 
    932 void
    933 init(int argc,char **argv)
    934 {
    935 	register struct sym *sp;
    936 
    937 	if (sigset(SIGINT, SIG_IGN) != SIG_IGN)
    938 		sigset(SIGINT,onintr);
    939 	setbuf(stdout,(char *)NULL);
    940 	svargc = --argc;
    941 	svargv = argv;
    942 	while(svargc>0 && svargv[1][0] == '-'){
    943 		switch(svargv[1][1]){
    944 		default:
    945 			dbg=1;
    946 		}
    947 		svargc--;
    948 		svargv++;
    949 	}
    950 	ifile=1;
    951 	if(svargc<=0)curfile = stdin;
    952 	else if((curfile = fopen(svargv[1],"r")) == NULL){
    953 		printf("can't open file %s\n",svargv[1]);
    954 		exit(1);
    955 		}
    956 	scalptr = salloc(1);
    957 	sputc(scalptr,0);
    958 	basptr = salloc(1);
    959 	sputc(basptr,10);
    960 	obase=10;
    961 	log_10=log_2(10L);
    962 	ll=68;
    963 	fw=1;
    964 	fw1=0;
    965 	tenptr = salloc(1);
    966 	sputc(tenptr,10);
    967 	obase=10;
    968 	inbas = salloc(1);
    969 	sputc(inbas,10);
    970 	sqtemp = salloc(1);
    971 	sputc(sqtemp,2);
    972 	chptr = salloc(0);
    973 	strptr = salloc(0);
    974 	divxyz = salloc(0);
    975 	stkbeg = stkptr = &stack[0];
    976 	stkend = &stack[STKSZ];
    977 	stkerr = 0;
    978 	readptr = &readstk[0];
    979 	k=0;
    980 	sp = sptr = &symlst[0];
    981 	while(sptr < &symlst[TBLSZ]){
    982 		sptr->next = ++sp;
    983 		sptr++;
    984 	}
    985 	sptr->next=0;
    986 	sfree = &symlst[0];
    987 	return;
    988 }
    989 
    990 void
    991 onintr(int signum){
    992 
    993 	sigset(SIGINT,onintr);
    994 	while(readptr != &readstk[0]){
    995 		if(*readptr != 0){release(*readptr);}
    996 		readptr--;
    997 	}
    998 	curfile = stdin;
    999 	commnds();
   1000 }
   1001 
   1002 void
   1003 pushp(struct blk *p)
   1004 {
   1005 	if(stkptr == stkend){
   1006 		printf("out of stack space\n");
   1007 		return;
   1008 	}
   1009 	stkerr=0;
   1010 	*++stkptr = p;
   1011 	return;
   1012 }
   1013 
   1014 struct blk *
   1015 pop(void){
   1016 	if(stkptr == stack){
   1017 		stkerr=1;
   1018 		return(0);
   1019 	}
   1020 	return(*stkptr--);
   1021 }
   1022 
   1023 struct blk *
   1024 readin(void){
   1025 	register struct blk *p,*q;
   1026 	int dp,dpct;
   1027 	register int c;
   1028 
   1029 	dp = dpct=0;
   1030 	p = salloc(0);
   1031 	while(1){
   1032 		c = readc();
   1033 		switch(c){
   1034 		case '.':
   1035 			if(dp != 0){
   1036 				unreadc(c);
   1037 				break;
   1038 			}
   1039 			dp++;
   1040 			continue;
   1041 		case '\\':
   1042 			readc();
   1043 			continue;
   1044 		default:
   1045 			if(c >= 'A' && c <= 'F')c = c - 'A' + 10;
   1046 			else if(c >= '0' && c <= '9')c -= '0';
   1047 			else goto gotnum;
   1048 			if(dp != 0){
   1049 				if(dpct >= 99)continue;
   1050 				dpct++;
   1051 			}
   1052 			create(chptr);
   1053 			if(c != 0)sputc(chptr,c);
   1054 			q = mult(p,inbas);
   1055 			release(p);
   1056 			p = add(chptr,q);
   1057 			release(q);
   1058 		}
   1059 	}
   1060 gotnum:
   1061 	unreadc(c);
   1062 	if(dp == 0){
   1063 		sputc(p,0);
   1064 		return(p);
   1065 	}
   1066 	else{
   1067 		q = scale(p,dpct);
   1068 		return(q);
   1069 	}
   1070 }
   1071 
   1072 struct blk *
   1073 add0(struct blk *p,int ct)
   1074 {
   1075 		/* returns pointer to struct with ct 0's & p */
   1076 	register struct blk *q,*t;
   1077 
   1078 	q = salloc(length(p)+(ct+1)/2);
   1079 	while(ct>1){
   1080 		sputc(q,0);
   1081 		ct -= 2;
   1082 	}
   1083 	rewind(p);
   1084 	while(sfeof(p) == 0){
   1085 		sputc(q,sgetc(p));
   1086 	}
   1087 	release(p);
   1088 	if(ct == 1){
   1089 		t = mult(tenptr,q);
   1090 		release(q);
   1091 		return(t);
   1092 	}
   1093 	return(q);
   1094 }
   1095 
   1096 struct blk *
   1097 mult(struct blk *p,struct blk *q)
   1098 {
   1099 	register struct blk *mp,*mq,*mr;
   1100 	int sign,offset,carry;
   1101 	int cq,cp,mt,mcr;
   1102 
   1103 	offset = sign = 0;
   1104 	fsfile(p);
   1105 	mp = p;
   1106 	if(sfbeg(p) == 0){
   1107 		if(sbackc(p)<0){
   1108 			mp = copy(p,length(p));
   1109 			chsign(mp);
   1110 			sign = ~sign;
   1111 		}
   1112 	}
   1113 	fsfile(q);
   1114 	mq = q;
   1115 	if(sfbeg(q) == 0){
   1116 		if(sbackc(q)<0){
   1117 			mq = copy(q,length(q));
   1118 			chsign(mq);
   1119 			sign = ~sign;
   1120 		}
   1121 	}
   1122 	mr = salloc(length(mp)+length(mq));
   1123 	zero(mr);
   1124 	rewind(mq);
   1125 	while(sfeof(mq) == 0){
   1126 		cq = sgetc(mq);
   1127 		rewind(mp);
   1128 		rewind(mr);
   1129 		mr->rd += offset;
   1130 		carry=0;
   1131 		while(sfeof(mp) == 0){
   1132 			cp = sgetc(mp);
   1133 			mcr = sfeof(mr)?0:slookc(mr);
   1134 			mt = cp*cq + carry + mcr;
   1135 			carry = mt/100;
   1136 			salterc(mr,mt%100);
   1137 		}
   1138 		offset++;
   1139 		if(carry != 0){
   1140 			mcr = sfeof(mr)?0:slookc(mr);
   1141 			salterc(mr,mcr+carry);
   1142 		}
   1143 	}
   1144 	if(sign < 0){
   1145 		chsign(mr);
   1146 	}
   1147 	if(mp != p)release(mp);
   1148 	if(mq != q)release(mq);
   1149 	return(mr);
   1150 }
   1151 
   1152 void
   1153 chsign(struct blk *p)
   1154 {
   1155 	register int carry;
   1156 	register char ct;
   1157 
   1158 	carry=0;
   1159 	rewind(p);
   1160 	while(sfeof(p) == 0){
   1161 		ct=100-slookc(p)-carry;
   1162 		carry=1;
   1163 		if(ct>=100){
   1164 			ct -= 100;
   1165 			carry=0;
   1166 		}
   1167 		salterc(p,ct);
   1168 	}
   1169 	if(carry != 0){
   1170 		sputc(p,-1);
   1171 		fsfile(p);
   1172 		sbackc(p);
   1173 		ct = sbackc(p);
   1174 		if(ct == 99){
   1175 			truncate(p);
   1176 			sputc(p,-1);
   1177 		}
   1178 	}
   1179 	else{
   1180 		fsfile(p);
   1181 		ct = sbackc(p);
   1182 		if(ct == 0)truncate(p);
   1183 	}
   1184 	return;
   1185 }
   1186 
   1187 int
   1188 readc(void){
   1189 loop:
   1190 	if((readptr != &readstk[0]) && (*readptr != 0)){
   1191 		if(sfeof(*readptr) == 0)return(lastchar = sgetc(*readptr));
   1192 		release(*readptr);
   1193 		readptr--;
   1194 		goto loop;
   1195 	}
   1196 	lastchar = getc(curfile);
   1197 	if(lastchar != EOF)return(lastchar);
   1198 	if(readptr != &readptr[0]){
   1199 		readptr--;
   1200 		if(*readptr == 0)curfile = stdin;
   1201 		goto loop;
   1202 	}
   1203 	if(curfile != stdin){
   1204 		fclose(curfile);
   1205 		curfile = stdin;
   1206 		goto loop;
   1207 	}
   1208 	exit(0);
   1209 }
   1210 
   1211 void
   1212 unreadc(char c)
   1213 {
   1214 
   1215 	if((readptr != &readstk[0]) && (*readptr != 0)){
   1216 		sungetc(*readptr,c);
   1217 	}
   1218 	else ungetc(c,curfile);
   1219 	return;
   1220 }
   1221 
   1222 void
   1223 binop(char c)
   1224 {
   1225 	register struct blk *r = NULL;
   1226 
   1227 	switch(c){
   1228 	case '+':
   1229 		r = add(arg1,arg2);
   1230 		break;
   1231 	case '*':
   1232 		r = mult(arg1,arg2);
   1233 		break;
   1234 	case '/':
   1235 		r = dcdiv(arg1,arg2);
   1236 		break;
   1237 	}
   1238 	release(arg1);
   1239 	release(arg2);
   1240 	sputc(r,savk);
   1241 	pushp(r);
   1242 	return;
   1243 }
   1244 
   1245 void
   1246 print(struct blk *hptr)
   1247 {
   1248 	int sc;
   1249 	register struct blk *p,*q,*dec;
   1250 	int dig,dout,ct;
   1251 
   1252 	rewind(hptr);
   1253 	while(sfeof(hptr) == 0){
   1254 		if(sgetc(hptr)>99){
   1255 			rewind(hptr);
   1256 			while(sfeof(hptr) == 0){
   1257 				printf("%c",sgetc(hptr));
   1258 			}
   1259 			printf("\n");
   1260 			return;
   1261 		}
   1262 	}
   1263 	fsfile(hptr);
   1264 	sc = sbackc(hptr);
   1265 	if(sfbeg(hptr) != 0){
   1266 		printf("0\n");
   1267 		return;
   1268 	}
   1269 	count = ll;
   1270 	p = copy(hptr,length(hptr));
   1271 	sunputc(p);
   1272 	fsfile(p);
   1273 	if(sbackc(p)<0){
   1274 		chsign(p);
   1275 		OUTC('-');
   1276 	}
   1277 	if((obase == 0) || (obase == -1)){
   1278 		oneot(p,sc,'d');
   1279 		return;
   1280 	}
   1281 	if(obase == 1){
   1282 		oneot(p,sc,'1');
   1283 		return;
   1284 	}
   1285 	if(obase == 10){
   1286 		tenot(p,sc);
   1287 		return;
   1288 	}
   1289 	create(strptr);
   1290 	dig = log_10*sc;
   1291 	dout = ((dig/10) + dig) /logo;
   1292 	dec = getdec(p,sc);
   1293 	p = removc(p,sc);
   1294 	while(length(p) != 0){
   1295 		q = dcdiv(p,basptr);
   1296 		release(p);
   1297 		p = q;
   1298 		(*outdit)(rem,0,1);
   1299 	}
   1300 	release(p);
   1301 	fsfile(strptr);
   1302 	while(sfbeg(strptr) == 0)OUTC(sbackc(strptr));
   1303 	if(sc == 0){
   1304 		release(dec);
   1305 		printf("\n");
   1306 		return;
   1307 	}
   1308 	create(strptr);
   1309 	OUTC('.');
   1310 	ct=0;
   1311 	do{
   1312 		q = mult(basptr,dec);
   1313 		release(dec);
   1314 		dec = getdec(q,sc);
   1315 		p = removc(q,sc);
   1316 		(*outdit)(p,1,ct+1<dout);
   1317 	}while(++ct < dout);
   1318 	release(dec);
   1319 	rewind(strptr);
   1320 	while(sfeof(strptr) == 0)OUTC(sgetc(strptr));
   1321 	printf("\n");
   1322 	return;
   1323 }
   1324 
   1325 struct blk *
   1326 getdec(struct blk *p,int sc)
   1327 {
   1328 	int cc;
   1329 	register struct blk *q,*t,*s;
   1330 
   1331 	rewind(p);
   1332 	if(length(p)*2 < sc){
   1333 		q = copy(p,length(p));
   1334 		return(q);
   1335 	}
   1336 	q = salloc(length(p));
   1337 	while(sc >= 1){
   1338 		sputc(q,sgetc(p));
   1339 		sc -= 2;
   1340 	}
   1341 	if(sc != 0){
   1342 		t = mult(q,tenptr);
   1343 		s = salloc(cc = length(q));
   1344 		release(q);
   1345 		rewind(t);
   1346 		while(cc-- > 0)sputc(s,sgetc(t));
   1347 		sputc(s,0);
   1348 		release(t);
   1349 		t = dcdiv(s,tenptr);
   1350 		release(s);
   1351 		release(rem);
   1352 		return(t);
   1353 	}
   1354 	return(q);
   1355 }
   1356 
   1357 void
   1358 tenot(struct blk *p,int sc)
   1359 {
   1360 	register int c,f;
   1361 	char	b[3];
   1362 
   1363 	fsfile(p);
   1364 	f=0;
   1365 	while((sfbeg(p) == 0) && ((p->rd-p->beg-1)*2 >= sc)){
   1366 		c = sbackc(p);
   1367 		if((c<10) && (f == 1))snprintf(b, sizeof b, "0%d",c);
   1368 		else snprintf(b, sizeof b, "%d",c);
   1369 		f=1;
   1370 		TEST2(b);
   1371 	}
   1372 	if(sc == 0){
   1373 		printf("\n");
   1374 		release(p);
   1375 		return;
   1376 	}
   1377 	if((p->rd-p->beg)*2 > sc){
   1378 		c = sbackc(p);
   1379 		snprintf(b, sizeof b, "%d.",c/10);
   1380 		TEST2(b);
   1381 		OUTC(c%10 +'0');
   1382 		sc--;
   1383 	}
   1384 	else {
   1385 		OUTC('.');
   1386 	}
   1387 	if(sc > (p->rd-p->beg)*2){
   1388 		while(sc>(p->rd-p->beg)*2){
   1389 			OUTC('0');
   1390 			sc--;
   1391 		}
   1392 	}
   1393 	while(sc > 1){
   1394 		c = sbackc(p);
   1395 		if(c<10)snprintf(b, sizeof b, "0%d",c);
   1396 		else snprintf(b, sizeof b, "%d",c);
   1397 		sc -= 2;
   1398 		TEST2(b);
   1399 	}
   1400 	if(sc == 1){
   1401 		OUTC(sbackc(p)/10 +'0');
   1402 	}
   1403 	printf("\n");
   1404 	release(p);
   1405 	return;
   1406 }
   1407 
   1408 void
   1409 oneot(struct blk *p,int sc,char ch)
   1410 {
   1411 	register struct blk *q;
   1412 
   1413 	q = removc(p,sc);
   1414 	create(strptr);
   1415 	sputc(strptr,-1);
   1416 	while(length(q)>0){
   1417 		p = add(strptr,q);
   1418 		release(q);
   1419 		q = p;
   1420 		OUTC(ch);
   1421 	}
   1422 	release(q);
   1423 	printf("\n");
   1424 	return;
   1425 }
   1426 
   1427 void
   1428 hexot(struct blk *p,int flg,int unused)
   1429 {
   1430 	register int c;
   1431 	rewind(p);
   1432 	if(sfeof(p) != 0){
   1433 		sputc(strptr,'0');
   1434 		release(p);
   1435 		return;
   1436 	}
   1437 	c = sgetc(p);
   1438 	release(p);
   1439 	if(c >= 16){
   1440 		printf("hex digit > 16");
   1441 		return;
   1442 	}
   1443 	sputc(strptr,c<10?c+'0':c-10+'A');
   1444 	return;
   1445 }
   1446 
   1447 void
   1448 bigot(struct blk *p,int flg,int putspc)
   1449 {
   1450 	register struct blk *t,*q;
   1451 	register int l = 0;
   1452 	int neg;
   1453 
   1454 	if(flg == 1)t = salloc(0);
   1455 	else{
   1456 		t = strptr;
   1457 		l = length(strptr)+fw-1;
   1458 	}
   1459 	neg=0;
   1460 	if(length(p) != 0){
   1461 		fsfile(p);
   1462 		if(sbackc(p)<0){
   1463 			neg=1;
   1464 			chsign(p);
   1465 		}
   1466 		while(length(p) != 0){
   1467 			q = dcdiv(p,tenptr);
   1468 			release(p);
   1469 			p = q;
   1470 			rewind(rem);
   1471 			sputc(t,sfeof(rem)?'0':sgetc(rem)+'0');
   1472 			release(rem);
   1473 		}
   1474 	}
   1475 	release(p);
   1476 	if(flg == 1){
   1477 		l = fw1-length(t);
   1478 		if(neg != 0){
   1479 			l--;
   1480 			sputc(strptr,'-');
   1481 		}
   1482 		fsfile(t);
   1483 		while(l-- > 0)sputc(strptr,'0');
   1484 		while(sfbeg(t) == 0)sputc(strptr,sbackc(t));
   1485 		release(t);
   1486 	}
   1487 	else{
   1488 		l -= length(strptr);
   1489 		while(l-- > 0)sputc(strptr,'0');
   1490 		if(neg != 0){
   1491 			sunputc(strptr);
   1492 			sputc(strptr,'-');
   1493 		}
   1494 	}
   1495 	if (putspc)
   1496 		sputc(strptr,' ');
   1497 	return;
   1498 }
   1499 
   1500 struct blk *
   1501 add(struct blk *a1,struct blk *a2)
   1502 {
   1503 	register struct blk *p;
   1504 	register int carry,n;
   1505 	int size;
   1506 	int c = 0,n1,n2;
   1507 
   1508 	size = length(a1)>length(a2)?length(a1):length(a2);
   1509 	p = salloc(size);
   1510 	rewind(a1);
   1511 	rewind(a2);
   1512 	carry=0;
   1513 	while(--size >= 0){
   1514 		n1 = sfeof(a1)?0:sgetc(a1);
   1515 		n2 = sfeof(a2)?0:sgetc(a2);
   1516 		n = n1 + n2 + carry;
   1517 		if(n>=100){
   1518 			carry=1;
   1519 			n -= 100;
   1520 		}
   1521 		else if(n<0){
   1522 			carry = -1;
   1523 			n += 100;
   1524 		}
   1525 		else carry = 0;
   1526 		sputc(p,n);
   1527 	}
   1528 	if(carry != 0)sputc(p,carry);
   1529 	fsfile(p);
   1530 	if(sfbeg(p) == 0){
   1531 		while(sfbeg(p) == 0 && (c = sbackc(p)) == 0);
   1532 		if(c != 0)salterc(p,c);
   1533 		truncate(p);
   1534 	}
   1535 	fsfile(p);
   1536 	if(sfbeg(p) == 0 && sbackc(p) == -1){
   1537 		while((c = sbackc(p)) == 99){
   1538 			if(c == EOF)break;
   1539 		}
   1540 		sgetc(p);
   1541 		salterc(p,-1);
   1542 		truncate(p);
   1543 	}
   1544 	return(p);
   1545 }
   1546 
   1547 int
   1548 eqk(void){
   1549 	register struct blk *p,*q;
   1550 	register int skp;
   1551 	int skq;
   1552 
   1553 	p = pop();
   1554 	EMPTYS;
   1555 	q = pop();
   1556 	EMPTYSR(p);
   1557 	skp = sunputc(p);
   1558 	skq = sunputc(q);
   1559 	if(skp == skq){
   1560 		arg1=p;
   1561 		arg2=q;
   1562 		savk = skp;
   1563 		return(0);
   1564 	}
   1565 	else if(skp < skq){
   1566 		savk = skq;
   1567 		p = add0(p,skq-skp);
   1568 	}
   1569 	else {
   1570 		savk = skp;
   1571 		q = add0(q,skp-skq);
   1572 	}
   1573 	arg1=p;
   1574 	arg2=q;
   1575 	return(0);
   1576 }
   1577 
   1578 struct blk *
   1579 removc(struct blk *p,int n)
   1580 {
   1581 	register struct blk *q,*r;
   1582 
   1583 	rewind(p);
   1584 	while(n>1){
   1585 		sgetc(p);
   1586 		n -= 2;
   1587 	}
   1588 	q = salloc(2);
   1589 	while(sfeof(p) == 0)sputc(q,sgetc(p));
   1590 	if(n == 1){
   1591 		r = dcdiv(q,tenptr);
   1592 		release(q);
   1593 		release(rem);
   1594 		q = r;
   1595 	}
   1596 	release(p);
   1597 	return(q);
   1598 }
   1599 
   1600 struct blk *
   1601 scalint(struct blk *p)
   1602 {
   1603 	register int n;
   1604 	n = sunputc(p);
   1605 	p = removc(p,n);
   1606 	return(p);
   1607 }
   1608 
   1609 struct blk *
   1610 scale(struct blk *p,int n)
   1611 {
   1612 	register struct blk *q,*s,*t;
   1613 
   1614 	t = add0(p,n);
   1615 	q = salloc(1);
   1616 	sputc(q,n);
   1617 	s = dcexp(inbas,q);
   1618 	release(q);
   1619 	q = dcdiv(t,s);
   1620 	release(t);
   1621 	release(s);
   1622 	release(rem);
   1623 	sputc(q,n);
   1624 	return(q);
   1625 }
   1626 
   1627 int
   1628 subt(void){
   1629 	arg1=pop();
   1630 	EMPTYS;
   1631 	savk = sunputc(arg1);
   1632 	chsign(arg1);
   1633 	sputc(arg1,savk);
   1634 	pushp(arg1);
   1635 	if(eqk() != 0)return(1);
   1636 	binop('+');
   1637 	return(0);
   1638 }
   1639 
   1640 int
   1641 command(void){
   1642 	int c;
   1643 	static char *line;
   1644 	static int linesize;
   1645 	char *sl;
   1646 	register void (*savint)(int);
   1647 	register int pid,rpid;
   1648 	int retcode;
   1649 
   1650 	switch(c = readc()){
   1651 	case '<':
   1652 		return(cond(NL));
   1653 	case '>':
   1654 		return(cond(NG));
   1655 	case '=':
   1656 		return(cond(NE));
   1657 	default:
   1658 		if (line == 0)
   1659 			line = srealloc(0, linesize = 10);
   1660 		sl = line;
   1661 		*sl++ = c;
   1662 		while((c = readc()) != '\n') {
   1663 			if (sl >= &line[linesize-2]) {
   1664 				int	diff = sl - line;
   1665 				line = srealloc(line, linesize += 10);
   1666 				sl = &line[diff];
   1667 			}
   1668 			*sl++ = c;
   1669 		}
   1670 		*sl = 0;
   1671 		if((pid = fork()) == 0){
   1672 			execl(SHELL,"sh","-c",line,NULL);
   1673 			exit(0100);
   1674 		}
   1675 		savint = sigset(SIGINT, SIG_IGN);
   1676 		while((rpid = wait(&retcode)) != pid && rpid != -1);
   1677 		sigset(SIGINT,savint);
   1678 		printf("!\n");
   1679 		return(0);
   1680 	}
   1681 }
   1682 
   1683 int
   1684 cond(char c)
   1685 {
   1686 	register struct blk *p;
   1687 	register int cc;
   1688 
   1689 	if(subt() != 0)return(1);
   1690 	p = pop();
   1691 	sunputc(p);
   1692 	if(length(p) == 0){
   1693 		release(p);
   1694 		if(c == '<' || c == '>' || c == NE){
   1695 			readc();
   1696 			return(0);
   1697 		}
   1698 		load();
   1699 		return(1);
   1700 	}
   1701 	else {
   1702 		if(c == '='){
   1703 			release(p);
   1704 			readc();
   1705 			return(0);
   1706 		}
   1707 	}
   1708 	if(c == NE){
   1709 		release(p);
   1710 		load();
   1711 		return(1);
   1712 	}
   1713 	fsfile(p);
   1714 	cc = sbackc(p);
   1715 	release(p);
   1716 	if((cc<0 && (c == '<' || c == NG)) ||
   1717 		(cc >0) && (c == '>' || c == NL)){
   1718 		readc();
   1719 		return(0);
   1720 	}
   1721 	load();
   1722 	return(1);
   1723 }
   1724 
   1725 void
   1726 load(void){
   1727 	register int c;
   1728 	register struct blk *p,*q;
   1729 	struct blk *t,*s;
   1730 	c = readc() & 0377;
   1731 	sptr = stable[c];
   1732 	if(sptr != 0){
   1733 		p = sptr->val;
   1734 		if(c >= ARRAYST){
   1735 			q = salloc(length(p));
   1736 			rewind(p);
   1737 			while(sfeof(p) == 0){
   1738 				s = dcgetwd(p);
   1739 				if(s == 0){putwd(q, (struct blk *)NULL);}
   1740 				else{
   1741 					t = copy(s,length(s));
   1742 					putwd(q,t);
   1743 				}
   1744 			}
   1745 			pushp(q);
   1746 		}
   1747 		else{
   1748 			q = copy(p,length(p));
   1749 			pushp(q);
   1750 		}
   1751 	}
   1752 	else{
   1753 		q = salloc(1);
   1754 		sputc(q,0);
   1755 		pushp(q);
   1756 	}
   1757 	return;
   1758 }
   1759 
   1760 int
   1761 log_2(long n)
   1762 {
   1763 	register int i;
   1764 
   1765 	if(n == 0)return(0);
   1766 	i=31;
   1767 	if(n<0)return(i);
   1768 	while((n= n<<1) >0)i--;
   1769 	return(--i);
   1770 }
   1771 
   1772 struct blk *
   1773 salloc(int size)
   1774 {
   1775 	register struct blk *hdr;
   1776 	register char *ptr;
   1777 	all++;
   1778 	nbytes += size;
   1779 	ptr = malloc((unsigned)(size?size:1));
   1780 	if(ptr == 0){
   1781 		garbage("salloc");
   1782 		if((ptr = malloc((unsigned)(size?size:1))) == 0)
   1783 			ospace("salloc");
   1784 	}
   1785 	if((hdr = hfree) == 0)hdr = morehd();
   1786 	hfree = (struct blk *)hdr->rd;
   1787 	hdr->rd = hdr->wt = hdr->beg = ptr;
   1788 	hdr->last = ptr+size;
   1789 	return(hdr);
   1790 }
   1791 
   1792 struct blk *
   1793 morehd(void){
   1794 	register struct blk *h,*kk;
   1795 	headmor++;
   1796 	nbytes += HEADSZ;
   1797 	hfree = h = (struct blk *)malloc(HEADSZ);
   1798 	if(hfree == 0){
   1799 		garbage("morehd");
   1800 		if((hfree = h = (struct blk *)malloc(HEADSZ)) == 0)
   1801 			ospace("headers");
   1802 	}
   1803 	kk = h;
   1804 	while(h<hfree+(HEADSZ/BLK))(h++)->rd = (char *)++kk;
   1805 	(--h)->rd=0;
   1806 	return(hfree);
   1807 }
   1808 
   1809 /*
   1810 sunputc(struct blk *hptr)
   1811 {
   1812 	hptr->wt--;
   1813 	hptr->rd = hptr->wt;
   1814 	return(*hptr->wt);
   1815 }
   1816 */
   1817 
   1818 struct blk *
   1819 copy(struct blk *hptr,int size)
   1820 {
   1821 	register struct blk *hdr;
   1822 	register unsigned sz;
   1823 	register char *ptr;
   1824 
   1825 	all++;
   1826 	nbytes += size;
   1827 	sz = length(hptr);
   1828 	ptr = nalloc(hptr->beg, (unsigned)size);
   1829 	if(ptr == 0){
   1830 		garbage("copy");
   1831 		if((ptr = nalloc(hptr->beg, (unsigned)size)) == NULL){
   1832 			printf("copy size %d\n",size);
   1833 			ospace("copy");
   1834 		}
   1835 	}
   1836 	if((hdr = hfree) == 0)hdr = morehd();
   1837 	hfree = (struct blk *)hdr->rd;
   1838 	hdr->rd = hdr->beg = ptr;
   1839 	hdr->last = ptr+size;
   1840 	hdr->wt = ptr+sz;
   1841 	ptr = hdr->wt;
   1842 	while(ptr<hdr->last)*ptr++ = '\0';
   1843 	return(hdr);
   1844 }
   1845 
   1846 void
   1847 sdump(char *s1,struct blk *hptr)
   1848 {
   1849 	char *p;
   1850 	printf("%s %lo rd %lo wt %lo beg %lo last %lo\n", s1,
   1851 			(long)(intptr_t)hptr,
   1852 			(long)(intptr_t)hptr->rd,
   1853 			(long)(intptr_t)hptr->wt,
   1854 			(long)(intptr_t)hptr->beg,
   1855 			(long)(intptr_t)hptr->last);
   1856 	p = hptr->beg;
   1857 	while(p < hptr->wt)printf("%d ",*p++);
   1858 	printf("\n");
   1859 }
   1860 
   1861 void
   1862 seekc(struct blk *hptr,int n)
   1863 {
   1864 	register char *nn,*p;
   1865 
   1866 	nn = hptr->beg+n;
   1867 	if(nn > hptr->last){
   1868 		nbytes += nn - hptr->last;
   1869 		/*free(hptr->beg);*/
   1870 		p = realloc(hptr->beg, (unsigned)n);
   1871 		if(p == 0){
   1872 			hptr->beg = realloc(hptr->beg, (unsigned)(hptr->last-hptr->beg));
   1873 			garbage("seekc");
   1874 			if((p = realloc(hptr->beg, (unsigned)n)) == 0)
   1875 				ospace("seekc");
   1876 		}
   1877 		hptr->beg = p;
   1878 		hptr->wt = hptr->last = hptr->rd = p+n;
   1879 		return;
   1880 	}
   1881 	hptr->rd = nn;
   1882 	if(nn>hptr->wt)hptr->wt = nn;
   1883 	return;
   1884 }
   1885 
   1886 void
   1887 salterwd(struct wblk *hptr,struct blk *n)
   1888 {
   1889 	if(hptr->rdw == hptr->lastw)more((struct blk *)hptr);
   1890 	*hptr->rdw++ = n;
   1891 	if(hptr->rdw > hptr->wtw)hptr->wtw = hptr->rdw;
   1892 	return;
   1893 }
   1894 
   1895 void
   1896 more(struct blk *hptr)
   1897 {
   1898 	register unsigned size;
   1899 	register char *p;
   1900 
   1901 	if((size=(hptr->last-hptr->beg)*2) == 0)size=1;
   1902 	nbytes += size/2;
   1903 	/*free(hptr->beg);*/
   1904 	p = realloc(hptr->beg, (unsigned)size);
   1905 	if(p == 0){
   1906 		hptr->beg = realloc(hptr->beg, (unsigned)(hptr->last-hptr->beg));
   1907 		garbage("more");
   1908 		if((p = realloc(hptr->beg,size)) == 0)
   1909 			ospace("more");
   1910 	}
   1911 	hptr->rd = hptr->rd-hptr->beg+p;
   1912 	hptr->wt = hptr->wt-hptr->beg+p;
   1913 	hptr->beg = p;
   1914 	hptr->last = p+size;
   1915 	return;
   1916 }
   1917 
   1918 void
   1919 ospace(char *s)
   1920 {
   1921 	printf("out of space: %s\n",s);
   1922 	printf("all %ld rel %ld headmor %ld\n",all,rel,headmor);
   1923 	printf("nbytes %ld\n",nbytes);
   1924 	sdump("stk",*stkptr);
   1925 	abort();
   1926 }
   1927 
   1928 void
   1929 garbage(char *s)
   1930 {
   1931 	int i;
   1932 	struct blk *p, *q;
   1933 	struct sym *tmps;
   1934 	int ct;
   1935 
   1936 /*	printf("got to garbage %s\n",s);	*/
   1937 	for(i=0;i<TBLSZ;i++){
   1938 		tmps = stable[i];
   1939 		if(tmps != 0){
   1940 			if(i < ARRAYST){
   1941 				do {
   1942 					p = tmps->val;
   1943 					if(((intptr_t)p->beg & 01)  != 0){
   1944 						printf("string %o\n",i);
   1945 						sdump("odd beg",p);
   1946 					}
   1947 					redef(p);
   1948 					tmps = tmps->next;
   1949 				} while(tmps != 0);
   1950 				continue;
   1951 			}
   1952 			else {
   1953 				do {
   1954 					p = tmps->val;
   1955 					rewind(p);
   1956 					ct = 0;
   1957 					while((q = dcgetwd(p)) != NULL){
   1958 						ct++;
   1959 						if(q != 0){
   1960 							if(((intptr_t)q->beg & 01) != 0){
   1961 								printf("array %o elt %d odd\n",i-ARRAYST,ct);
   1962 printf("tmps %lo p %lo\n",(long)(intptr_t)tmps,(long)(intptr_t)p);
   1963 								sdump("elt",q);
   1964 							}
   1965 							redef(q);
   1966 						}
   1967 					}
   1968 					tmps = tmps->next;
   1969 				} while(tmps != 0);
   1970 			}
   1971 		}
   1972 	}
   1973 }
   1974 
   1975 void
   1976 redef(struct blk *p)
   1977 {
   1978 	register int offset;
   1979 	register char *newp;
   1980 
   1981 	if ((intptr_t)p->beg&01) {
   1982 		printf("odd ptr %lo hdr %lo\n",(long)(intptr_t)p->beg,
   1983 				(long)(intptr_t)p);
   1984 		ospace("redef-bad");
   1985 	}
   1986 	/*free(p->beg);*/
   1987 	newp = realloc(p->beg, (unsigned)(p->last-p->beg));
   1988 	if(newp == NULL)ospace("redef");
   1989 	offset = newp - p->beg;
   1990 	p->beg = newp;
   1991 	p->rd += offset;
   1992 	p->wt += offset;
   1993 	p->last += offset;
   1994 }
   1995 
   1996 void
   1997 release(register struct blk *p)
   1998 {
   1999 	rel++;
   2000 	nbytes -= p->last - p->beg;
   2001 	p->rd = (char *)hfree;
   2002 	hfree = p;
   2003 	free(p->beg);
   2004 }
   2005 
   2006 struct blk *
   2007 dcgetwd(struct blk *p)
   2008 {
   2009 	register struct wblk *wp;
   2010 
   2011 	wp = (struct wblk *)p;
   2012 	if (wp->rdw == wp->wtw)
   2013 		return(NULL);
   2014 	return(*wp->rdw++);
   2015 }
   2016 
   2017 void
   2018 putwd(struct blk *p, struct blk *c)
   2019 {
   2020 	register struct wblk *wp;
   2021 
   2022 	wp = (struct wblk *)p;
   2023 	if (wp->wtw == wp->lastw)
   2024 		more(p);
   2025 	*wp->wtw++ = c;
   2026 }
   2027 
   2028 struct blk *
   2029 lookwd(struct blk *p)
   2030 {
   2031 	register struct wblk *wp;
   2032 
   2033 	wp = (struct wblk *)p;
   2034 	if (wp->rdw == wp->wtw)
   2035 		return(NULL);
   2036 	return(*wp->rdw);
   2037 }
   2038 
   2039 char *
   2040 nalloc(register char *p,unsigned nbytes)
   2041 {
   2042 	register char *q, *r;
   2043 	q = r = malloc(nbytes ? nbytes : 1);
   2044 	if(q==0)
   2045 		return(0);
   2046 	while(nbytes--)
   2047 		*q++ = *p++;
   2048 	return(r);
   2049 }
   2050 
   2051 void *
   2052 srealloc(void *op, size_t size)
   2053 {
   2054 	void	*np;
   2055 
   2056 	if ((np = realloc(op, size)) == 0) {
   2057 		write(2, "no memory\n", 10);
   2058 		_exit(077);
   2059 	}
   2060 	return np;
   2061 }