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