|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)misc.c 5.1 (Berkeley) 6/7/85"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * misc.c ! 13: * ! 14: * Miscellaneous routines for the f77 compiler, 4.2 BSD. ! 15: * ! 16: * University of Utah CS Dept modification history: ! 17: * ! 18: * $Log: misc.c,v $ ! 19: * Revision 1.2 86/02/12 15:28:35 rcs ! 20: * 4.3 F77. C. Keating. ! 21: * ! 22: * Revision 3.1 84/10/13 01:53:26 donn ! 23: * Installed Jerry Berkman's version; added UofU comment header. ! 24: * ! 25: */ ! 26: ! 27: #include "defs.h" ! 28: ! 29: ! 30: ! 31: cpn(n, a, b) ! 32: register int n; ! 33: register char *a, *b; ! 34: { ! 35: while(--n >= 0) ! 36: *b++ = *a++; ! 37: } ! 38: ! 39: ! 40: ! 41: eqn(n, a, b) ! 42: register int n; ! 43: register char *a, *b; ! 44: { ! 45: while(--n >= 0) ! 46: if(*a++ != *b++) ! 47: return(NO); ! 48: return(YES); ! 49: } ! 50: ! 51: ! 52: ! 53: ! 54: ! 55: ! 56: ! 57: cmpstr(a, b, la, lb) /* compare two strings */ ! 58: register char *a, *b; ! 59: ftnint la, lb; ! 60: { ! 61: register char *aend, *bend; ! 62: aend = a + la; ! 63: bend = b + lb; ! 64: ! 65: ! 66: if(la <= lb) ! 67: { ! 68: while(a < aend) ! 69: if(*a != *b) ! 70: return( *a - *b ); ! 71: else ! 72: { ++a; ++b; } ! 73: ! 74: while(b < bend) ! 75: if(*b != ' ') ! 76: return(' ' - *b); ! 77: else ! 78: ++b; ! 79: } ! 80: ! 81: else ! 82: { ! 83: while(b < bend) ! 84: if(*a != *b) ! 85: return( *a - *b ); ! 86: else ! 87: { ++a; ++b; } ! 88: while(a < aend) ! 89: if(*a != ' ') ! 90: return(*a - ' '); ! 91: else ! 92: ++a; ! 93: } ! 94: return(0); ! 95: } ! 96: ! 97: ! 98: ! 99: ! 100: ! 101: chainp hookup(x,y) ! 102: register chainp x, y; ! 103: { ! 104: register chainp p; ! 105: ! 106: if(x == NULL) ! 107: return(y); ! 108: ! 109: for(p = x ; p->nextp ; p = p->nextp) ! 110: ; ! 111: p->nextp = y; ! 112: return(x); ! 113: } ! 114: ! 115: ! 116: ! 117: struct Listblock *mklist(p) ! 118: chainp p; ! 119: { ! 120: register struct Listblock *q; ! 121: ! 122: q = ALLOC(Listblock); ! 123: q->tag = TLIST; ! 124: q->listp = p; ! 125: return(q); ! 126: } ! 127: ! 128: ! 129: chainp mkchain(p,q) ! 130: register tagptr p; ! 131: register chainp q; ! 132: { ! 133: register chainp r; ! 134: ! 135: if(chains) ! 136: { ! 137: r = chains; ! 138: chains = chains->nextp; ! 139: } ! 140: else ! 141: r = ALLOC(Chain); ! 142: ! 143: r->datap = p; ! 144: r->nextp = q; ! 145: return(r); ! 146: } ! 147: ! 148: ! 149: ! 150: char * varstr(n, s) ! 151: register int n; ! 152: register char *s; ! 153: { ! 154: register int i; ! 155: static char name[XL+1]; ! 156: ! 157: for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i) ! 158: name[i] = *s++; ! 159: ! 160: name[i] = '\0'; ! 161: ! 162: return( name ); ! 163: } ! 164: ! 165: ! 166: ! 167: ! 168: char * varunder(n, s) ! 169: register int n; ! 170: register char *s; ! 171: { ! 172: register int i; ! 173: static char name[XL+1]; ! 174: ! 175: for(i=0; i<n && *s!=' ' && *s!='\0' ; ++i) ! 176: name[i] = *s++; ! 177: ! 178: #if TARGET != GCOS ! 179: name[i++] = '_'; ! 180: #endif ! 181: ! 182: name[i] = '\0'; ! 183: ! 184: return( name ); ! 185: } ! 186: ! 187: ! 188: ! 189: ! 190: ! 191: char * nounder(n, s) ! 192: register int n; ! 193: register char *s; ! 194: { ! 195: register int i; ! 196: static char name[XL+1]; ! 197: ! 198: for(i=0; i<n && *s!=' ' && *s!='\0' ; ++s) ! 199: if(*s != '_') ! 200: name[i++] = *s; ! 201: ! 202: name[i] = '\0'; ! 203: ! 204: return( name ); ! 205: } ! 206: ! 207: ! 208: ! 209: char *copyn(n, s) ! 210: register int n; ! 211: register char *s; ! 212: { ! 213: register char *p, *q; ! 214: ! 215: p = q = (char *) ckalloc(n); ! 216: while(--n >= 0) ! 217: *q++ = *s++; ! 218: return(p); ! 219: } ! 220: ! 221: ! 222: ! 223: char *copys(s) ! 224: char *s; ! 225: { ! 226: return( copyn( strlen(s)+1 , s) ); ! 227: } ! 228: ! 229: ! 230: ! 231: ftnint convci(n, s) ! 232: register int n; ! 233: register char *s; ! 234: { ! 235: ftnint sum; ! 236: ftnint digval; ! 237: sum = 0; ! 238: while(n-- > 0) ! 239: { ! 240: if (sum > MAXINT/10 ) { ! 241: err("integer constant too large"); ! 242: return(sum); ! 243: } ! 244: sum *= 10; ! 245: digval = *s++ - '0'; ! 246: #if (TARGET == TAHOE) ! 247: sum += digval; ! 248: #endif ! 249: #if (TARGET == VAX) ! 250: if ( MAXINT - sum >= digval ) { ! 251: sum += digval; ! 252: } else { ! 253: /* KLUDGE. On VAXs, MININT is (-MAXINT)-1 , i.e., there ! 254: is one more neg. integer than pos. integer. The ! 255: following code returns MININT whenever (MAXINT+1) ! 256: is seen. On VAXs, such statements as: i = MININT ! 257: work, although this generates garbage for ! 258: such statements as: i = MPLUS1 where MPLUS1 is MAXINT+1 ! 259: or: i = 5 - 2147483647/2 . ! 260: The only excuse for this kludge is it keeps all legal ! 261: programs running and flags most illegal constants, unlike ! 262: the previous version which flaged nothing outside data stmts! ! 263: */ ! 264: if ( n == 0 && MAXINT - sum + 1 == digval ) { ! 265: warn("minimum negative integer compiled - possibly bad code"); ! 266: sum = MININT; ! 267: } else { ! 268: err("integer constant too large"); ! 269: return(sum); ! 270: } ! 271: } ! 272: #endif ! 273: } ! 274: return(sum); ! 275: } ! 276: ! 277: char *convic(n) ! 278: ftnint n; ! 279: { ! 280: static char s[20]; ! 281: register char *t; ! 282: ! 283: s[19] = '\0'; ! 284: t = s+19; ! 285: ! 286: do { ! 287: *--t = '0' + n%10; ! 288: n /= 10; ! 289: } while(n > 0); ! 290: ! 291: return(t); ! 292: } ! 293: ! 294: ! 295: ! 296: double convcd(n, s) ! 297: int n; ! 298: register char *s; ! 299: { ! 300: double atof(); ! 301: char v[100]; ! 302: register char *t; ! 303: if(n > 90) ! 304: { ! 305: err("too many digits in floating constant"); ! 306: n = 90; ! 307: } ! 308: for(t = v ; n-- > 0 ; s++) ! 309: *t++ = (*s=='d' ? 'e' : *s); ! 310: *t = '\0'; ! 311: return( atof(v) ); ! 312: } ! 313: ! 314: ! 315: ! 316: Namep mkname(l, s) ! 317: int l; ! 318: register char *s; ! 319: { ! 320: struct Hashentry *hp; ! 321: int hash; ! 322: register Namep q; ! 323: register int i; ! 324: char n[VL]; ! 325: ! 326: hash = 0; ! 327: for(i = 0 ; i<l && *s!='\0' ; ++i) ! 328: { ! 329: hash += *s; ! 330: n[i] = *s++; ! 331: } ! 332: hash %= maxhash; ! 333: while( i < VL ) ! 334: n[i++] = ' '; ! 335: ! 336: hp = hashtab + hash; ! 337: while(q = hp->varp) ! 338: if( hash==hp->hashval && eqn(VL,n,q->varname) ) ! 339: return(q); ! 340: else if(++hp >= lasthash) ! 341: hp = hashtab; ! 342: ! 343: if(++nintnames >= maxhash-1) ! 344: many("names", 'n'); ! 345: hp->varp = q = ALLOC(Nameblock); ! 346: hp->hashval = hash; ! 347: q->tag = TNAME; ! 348: cpn(VL, n, q->varname); ! 349: return(q); ! 350: } ! 351: ! 352: ! 353: ! 354: struct Labelblock *mklabel(l) ! 355: ftnint l; ! 356: { ! 357: register struct Labelblock *lp; ! 358: ! 359: if(l <= 0 || l > 99999 ) { ! 360: errstr("illegal label %d", l); ! 361: return(NULL); ! 362: } ! 363: ! 364: for(lp = labeltab ; lp < highlabtab ; ++lp) ! 365: if(lp->stateno == l) ! 366: return(lp); ! 367: ! 368: if(++highlabtab > labtabend) ! 369: many("statement numbers", 's'); ! 370: ! 371: lp->stateno = l; ! 372: lp->labelno = newlabel(); ! 373: lp->blklevel = 0; ! 374: lp->labused = NO; ! 375: lp->labdefined = NO; ! 376: lp->labinacc = NO; ! 377: lp->labtype = LABUNKNOWN; ! 378: return(lp); ! 379: } ! 380: ! 381: ! 382: newlabel() ! 383: { ! 384: return( ++lastlabno ); ! 385: } ! 386: ! 387: ! 388: /* this label appears in a branch context */ ! 389: ! 390: struct Labelblock *execlab(stateno) ! 391: ftnint stateno; ! 392: { ! 393: register struct Labelblock *lp; ! 394: ! 395: if(lp = mklabel(stateno)) ! 396: { ! 397: if(lp->labinacc) ! 398: warn1("illegal branch to inner block, statement %s", ! 399: convic(stateno) ); ! 400: else if(lp->labdefined == NO) ! 401: lp->blklevel = blklevel; ! 402: lp->labused = YES; ! 403: if(lp->labtype == LABFORMAT) ! 404: err("may not branch to a format"); ! 405: else ! 406: lp->labtype = LABEXEC; ! 407: } ! 408: ! 409: return(lp); ! 410: } ! 411: ! 412: ! 413: ! 414: ! 415: ! 416: /* find or put a name in the external symbol table */ ! 417: ! 418: struct Extsym *mkext(s) ! 419: char *s; ! 420: { ! 421: int i; ! 422: register char *t; ! 423: char n[XL]; ! 424: struct Extsym *p; ! 425: ! 426: i = 0; ! 427: t = n; ! 428: while(i<XL && *s) ! 429: *t++ = *s++; ! 430: while(t < n+XL) ! 431: *t++ = ' '; ! 432: ! 433: for(p = extsymtab ; p<nextext ; ++p) ! 434: if(eqn(XL, n, p->extname)) ! 435: return( p ); ! 436: ! 437: if(nextext >= lastext) ! 438: many("external symbols", 'x'); ! 439: ! 440: cpn(XL, n, nextext->extname); ! 441: nextext->extstg = STGUNKNOWN; ! 442: nextext->extsave = NO; ! 443: nextext->extp = 0; ! 444: nextext->extleng = 0; ! 445: nextext->maxleng = 0; ! 446: nextext->extinit = NO; ! 447: return( nextext++ ); ! 448: } ! 449: ! 450: ! 451: ! 452: ! 453: ! 454: ! 455: ! 456: ! 457: Addrp builtin(t, s) ! 458: int t; ! 459: char *s; ! 460: { ! 461: register struct Extsym *p; ! 462: register Addrp q; ! 463: ! 464: p = mkext(s); ! 465: if(p->extstg == STGUNKNOWN) ! 466: p->extstg = STGEXT; ! 467: else if(p->extstg != STGEXT) ! 468: { ! 469: errstr("improper use of builtin %s", s); ! 470: return(0); ! 471: } ! 472: ! 473: q = ALLOC(Addrblock); ! 474: q->tag = TADDR; ! 475: q->vtype = t; ! 476: q->vclass = CLPROC; ! 477: q->vstg = STGEXT; ! 478: q->memno = p - extsymtab; ! 479: return(q); ! 480: } ! 481: ! 482: ! 483: ! 484: frchain(p) ! 485: register chainp *p; ! 486: { ! 487: register chainp q; ! 488: ! 489: if(p==0 || *p==0) ! 490: return; ! 491: ! 492: for(q = *p; q->nextp ; q = q->nextp) ! 493: ; ! 494: q->nextp = chains; ! 495: chains = *p; ! 496: *p = 0; ! 497: } ! 498: ! 499: ! 500: tagptr cpblock(n,p) ! 501: register int n; ! 502: register char * p; ! 503: { ! 504: register char *q; ! 505: ptr q0; ! 506: ! 507: q0 = ckalloc(n); ! 508: q = (char *) q0; ! 509: while(n-- > 0) ! 510: *q++ = *p++; ! 511: return( (tagptr) q0); ! 512: } ! 513: ! 514: ! 515: ! 516: max(a,b) ! 517: int a,b; ! 518: { ! 519: return( a>b ? a : b); ! 520: } ! 521: ! 522: ! 523: ftnint lmax(a, b) ! 524: ftnint a, b; ! 525: { ! 526: return( a>b ? a : b); ! 527: } ! 528: ! 529: ftnint lmin(a, b) ! 530: ftnint a, b; ! 531: { ! 532: return(a < b ? a : b); ! 533: } ! 534: ! 535: ! 536: ! 537: ! 538: maxtype(t1, t2) ! 539: int t1, t2; ! 540: { ! 541: int t; ! 542: ! 543: t = max(t1, t2); ! 544: if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) ) ! 545: t = TYDCOMPLEX; ! 546: return(t); ! 547: } ! 548: ! 549: ! 550: ! 551: /* return log base 2 of n if n a power of 2; otherwise -1 */ ! 552: #if FAMILY == PCC ! 553: log2(n) ! 554: ftnint n; ! 555: { ! 556: int k; ! 557: ! 558: /* trick based on binary representation */ ! 559: ! 560: if(n<=0 || (n & (n-1))!=0) ! 561: return(-1); ! 562: ! 563: for(k = 0 ; n >>= 1 ; ++k) ! 564: ; ! 565: return(k); ! 566: } ! 567: #endif ! 568: ! 569: ! 570: ! 571: frrpl() ! 572: { ! 573: struct Rplblock *rp; ! 574: ! 575: while(rpllist) ! 576: { ! 577: rp = rpllist->rplnextp; ! 578: free( (charptr) rpllist); ! 579: rpllist = rp; ! 580: } ! 581: } ! 582: ! 583: ! 584: ! 585: expptr callk(type, name, args) ! 586: int type; ! 587: char *name; ! 588: chainp args; ! 589: { ! 590: register expptr p; ! 591: ! 592: p = mkexpr(OPCALL, builtin(type,name), args); ! 593: p->exprblock.vtype = type; ! 594: return(p); ! 595: } ! 596: ! 597: ! 598: ! 599: expptr call4(type, name, arg1, arg2, arg3, arg4) ! 600: int type; ! 601: char *name; ! 602: expptr arg1, arg2, arg3, arg4; ! 603: { ! 604: struct Listblock *args; ! 605: args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, ! 606: mkchain(arg4, CHNULL)) ) ) ); ! 607: return( callk(type, name, args) ); ! 608: } ! 609: ! 610: ! 611: ! 612: ! 613: expptr call3(type, name, arg1, arg2, arg3) ! 614: int type; ! 615: char *name; ! 616: expptr arg1, arg2, arg3; ! 617: { ! 618: struct Listblock *args; ! 619: args = mklist( mkchain(arg1, mkchain(arg2, mkchain(arg3, CHNULL) ) ) ); ! 620: return( callk(type, name, args) ); ! 621: } ! 622: ! 623: ! 624: ! 625: ! 626: ! 627: expptr call2(type, name, arg1, arg2) ! 628: int type; ! 629: char *name; ! 630: expptr arg1, arg2; ! 631: { ! 632: struct Listblock *args; ! 633: ! 634: args = mklist( mkchain(arg1, mkchain(arg2, CHNULL) ) ); ! 635: return( callk(type,name, args) ); ! 636: } ! 637: ! 638: ! 639: ! 640: ! 641: expptr call1(type, name, arg) ! 642: int type; ! 643: char *name; ! 644: expptr arg; ! 645: { ! 646: return( callk(type,name, mklist(mkchain(arg,CHNULL)) )); ! 647: } ! 648: ! 649: ! 650: expptr call0(type, name) ! 651: int type; ! 652: char *name; ! 653: { ! 654: return( callk(type, name, PNULL) ); ! 655: } ! 656: ! 657: ! 658: ! 659: struct Impldoblock *mkiodo(dospec, list) ! 660: chainp dospec, list; ! 661: { ! 662: register struct Impldoblock *q; ! 663: ! 664: q = ALLOC(Impldoblock); ! 665: q->tag = TIMPLDO; ! 666: q->impdospec = dospec; ! 667: q->datalist = list; ! 668: return(q); ! 669: } ! 670: ! 671: ! 672: ! 673: ! 674: ptr ckalloc(n) ! 675: register int n; ! 676: { ! 677: register ptr p; ! 678: ptr calloc(); ! 679: ! 680: if( p = calloc(1, (unsigned) n) ) ! 681: return(p); ! 682: ! 683: fatal("out of memory"); ! 684: /* NOTREACHED */ ! 685: } ! 686: ! 687: ! 688: ! 689: ! 690: ! 691: isaddr(p) ! 692: register expptr p; ! 693: { ! 694: if(p->tag == TADDR) ! 695: return(YES); ! 696: if(p->tag == TEXPR) ! 697: switch(p->exprblock.opcode) ! 698: { ! 699: case OPCOMMA: ! 700: return( isaddr(p->exprblock.rightp) ); ! 701: ! 702: case OPASSIGN: ! 703: case OPPLUSEQ: ! 704: return( isaddr(p->exprblock.leftp) ); ! 705: } ! 706: return(NO); ! 707: } ! 708: ! 709: ! 710: ! 711: ! 712: isstatic(p) ! 713: register expptr p; ! 714: { ! 715: if(p->headblock.vleng && !ISCONST(p->headblock.vleng)) ! 716: return(NO); ! 717: ! 718: switch(p->tag) ! 719: { ! 720: case TCONST: ! 721: return(YES); ! 722: ! 723: case TADDR: ! 724: if(ONEOF(p->addrblock.vstg,MSKSTATIC) && ! 725: ISCONST(p->addrblock.memoffset)) ! 726: return(YES); ! 727: ! 728: default: ! 729: return(NO); ! 730: } ! 731: } ! 732: ! 733: ! 734: ! 735: addressable(p) ! 736: register expptr p; ! 737: { ! 738: switch(p->tag) ! 739: { ! 740: case TCONST: ! 741: return(YES); ! 742: ! 743: case TADDR: ! 744: return( addressable(p->addrblock.memoffset) ); ! 745: ! 746: default: ! 747: return(NO); ! 748: } ! 749: } ! 750: ! 751: ! 752: ! 753: hextoi(c) ! 754: register int c; ! 755: { ! 756: register char *p; ! 757: static char p0[17] = "0123456789abcdef"; ! 758: ! 759: for(p = p0 ; *p ; ++p) ! 760: if(*p == c) ! 761: return( p-p0 ); ! 762: return(16); ! 763: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.