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 }