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