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