|
|
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[] = "@(#)data.c 5.1 (Berkeley) 6/7/85";
9: #endif not lint
10:
11: /*
12: * data.c
13: *
14: * Routines for handling DATA statements, f77 compiler, 4.2 BSD.
15: *
16: * University of Utah CS Dept modification history:
17: *
18: * Revision 3.1 84/10/13 01:09:50 donn
19: * Installed Jerry Berkman's version; added UofU comment header.
20: *
21: */
22:
23: #include "defs.h"
24: #include "data.h"
25:
26:
27: /* global variables */
28:
29: flag overlapflag;
30:
31:
32:
33: /* local variables */
34:
35: LOCAL char rstatus;
36: LOCAL ftnint rvalue;
37: LOCAL dovars *dvlist;
38: LOCAL int dataerror;
39: LOCAL vallist *grvals;
40: LOCAL int datafile;
41: LOCAL int chkfile;
42: LOCAL long base;
43:
44:
45:
46: /* Copied from expr.c */
47:
48: LOCAL letter(c)
49: register int c;
50: {
51: if( isupper(c) )
52: c = tolower(c);
53: return(c - 'a');
54: }
55:
56:
57:
58: vexpr *
59: cpdvalue(dp)
60: vexpr *dp;
61: {
62: register dvalue *p;
63:
64: if (dp->tag != DVALUE)
65: badtag("cpdvalue", dp->tag);
66:
67: p = ALLOC(Dvalue);
68: p->tag = DVALUE;
69: p->status = dp->dvalue.status;
70: p->value = dp->dvalue.value;
71:
72: return ((vexpr *) p);
73: }
74:
75:
76:
77: frvexpr(vp)
78: register vexpr *vp;
79: {
80: if (vp != NULL)
81: {
82: if (vp->tag == DNAME)
83: free(vp->dname.repr);
84: else if (vp->tag == DEXPR)
85: {
86: frvexpr(vp->dexpr.left);
87: frvexpr(vp->dexpr.right);
88: }
89:
90: free((char *) vp);
91: }
92:
93: return;
94: }
95:
96:
97:
98: frvlist(vp)
99: register vlist *vp;
100: {
101: register vlist *t;
102:
103: while (vp)
104: {
105: t = vp->next;
106: frvexpr(vp->val);
107: free((char *) vp);
108: vp = t;
109: }
110:
111: return;
112: }
113:
114:
115:
116: frelist(ep)
117: elist *ep;
118: {
119: register elist *p;
120: register elist *t;
121: register aelt *ap;
122: register dolist *dp;
123:
124: p = ep;
125:
126: while (p != NULL)
127: {
128: if (p->elt->tag == SIMPLE)
129: {
130: ap = (aelt *) p->elt;
131: frvlist(ap->subs);
132: if (ap->range != NULL)
133: {
134: frvexpr(ap->range->low);
135: frvexpr(ap->range->high);
136: free((char *) ap->range);
137: }
138: free((char *) ap);
139: }
140: else
141: {
142: dp = (dolist *) p->elt;
143: frvexpr(dp->dovar);
144: frvexpr(dp->init);
145: frvexpr(dp->limit);
146: frvexpr(dp->step);
147: frelist(dp->elts);
148: free((char *) dp);
149: }
150:
151: t = p;
152: p = p->next;
153: free((char *) t);
154: }
155:
156: return;
157: }
158:
159:
160:
161: frvallist(vp)
162: vallist *vp;
163: {
164: register vallist *p;
165: register vallist *t;
166:
167: p = vp;
168: while (p != NULL)
169: {
170: frexpr((tagptr) p->value);
171: t = p;
172: p = p->next;
173: free((char *) t);
174: }
175:
176: return;
177: }
178:
179:
180:
181: elist *revelist(ep)
182: register elist *ep;
183: {
184: register elist *next;
185: register elist *t;
186:
187: if (ep != NULL)
188: {
189: next = ep->next;
190: ep->next = NULL;
191:
192: while (next)
193: {
194: t = next->next;
195: next->next = ep;
196: ep = next;
197: next = t;
198: }
199: }
200:
201: return (ep);
202: }
203:
204:
205:
206: vlist *revvlist(vp)
207: vlist *vp;
208: {
209: register vlist *p;
210: register vlist *next;
211: register vlist *t;
212:
213: if (vp == NULL)
214: p = NULL;
215: else
216: {
217: p = vp;
218: next = p->next;
219: p->next = NULL;
220:
221: while (next)
222: {
223: t = next->next;
224: next->next = p;
225: p = next;
226: next = t;
227: }
228: }
229:
230: return (p);
231: }
232:
233:
234:
235: vallist *
236: revrvals(vp)
237: vallist *vp;
238: {
239: register vallist *p;
240: register vallist *next;
241: register vallist *t;
242:
243: if (vp == NULL)
244: p = NULL;
245: else
246: {
247: p = vp;
248: next = p->next;
249: p->next = NULL;
250: while (next)
251: {
252: t = next->next;
253: next->next = p;
254: p = next;
255: next = t;
256: }
257: }
258:
259: return (p);
260: }
261:
262:
263:
264: vlist *prepvexpr(tail, head)
265: vlist *tail;
266: vexpr *head;
267: {
268: register vlist *p;
269:
270: p = ALLOC(Vlist);
271: p->next = tail;
272: p->val = head;
273:
274: return (p);
275: }
276:
277:
278:
279: elist *preplval(tail, head)
280: elist *tail;
281: delt* head;
282: {
283: register elist *p;
284: p = ALLOC(Elist);
285: p->next = tail;
286: p->elt = head;
287:
288: return (p);
289: }
290:
291:
292:
293: delt *mkdlval(name, subs, range)
294: vexpr *name;
295: vlist *subs;
296: rpair *range;
297: {
298: register aelt *p;
299:
300: p = ALLOC(Aelt);
301: p->tag = SIMPLE;
302: p->var = mkname(name->dname.len, name->dname.repr);
303: p->subs = subs;
304: p->range = range;
305:
306: return ((delt *) p);
307: }
308:
309:
310:
311: delt *mkdatado(lvals, dovar, params)
312: elist *lvals;
313: vexpr *dovar;
314: vlist *params;
315: {
316: static char *toofew = "missing loop parameters";
317: static char *toomany = "too many loop parameters";
318:
319: register dolist *p;
320: register vlist *vp;
321: register int pcnt;
322: register dvalue *one;
323:
324: p = ALLOC(DoList);
325: p->tag = NESTED;
326: p->elts = revelist(lvals);
327: p->dovar = dovar;
328:
329: vp = params;
330: pcnt = 0;
331: while (vp)
332: {
333: pcnt++;
334: vp = vp->next;
335: }
336:
337: if (pcnt != 2 && pcnt != 3)
338: {
339: if (pcnt < 2)
340: err(toofew);
341: else
342: err(toomany);
343:
344: p->init = (vexpr *) ALLOC(Derror);
345: p->init->tag = DERROR;
346:
347: p->limit = (vexpr *) ALLOC(Derror);
348: p->limit->tag = DERROR;
349:
350: p->step = (vexpr *) ALLOC(Derror);
351: p->step->tag = DERROR;
352: }
353: else
354: {
355: vp = params;
356:
357: if (pcnt == 2)
358: {
359: one = ALLOC(Dvalue);
360: one->tag = DVALUE;
361: one->status = NORMAL;
362: one->value = 1;
363: p->step = (vexpr *) one;
364: }
365: else
366: {
367: p->step = vp->val;
368: vp->val = NULL;
369: vp = vp->next;
370: }
371:
372: p->limit = vp->val;
373: vp->val = NULL;
374: vp = vp->next;
375:
376: p->init = vp->val;
377: vp->val = NULL;
378: }
379:
380: frvlist(params);
381: return ((delt *) p);
382: }
383:
384:
385:
386: rpair *mkdrange(lb, ub)
387: vexpr *lb, *ub;
388: {
389: register rpair *p;
390:
391: p = ALLOC(Rpair);
392: p->low = lb;
393: p->high = ub;
394:
395: return (p);
396: }
397:
398:
399:
400: vallist *mkdrval(repl, val)
401: vexpr *repl;
402: expptr val;
403: {
404: static char *badtag = "bad tag in mkdrval";
405: static char *negrepl = "negative replicator";
406: static char *zerorepl = "zero replicator";
407: static char *toobig = "replicator too large";
408: static char *nonconst = "%s is not a constant";
409:
410: register vexpr *vp;
411: register vallist *p;
412: register int status;
413: register ftnint value;
414: register int copied;
415:
416: copied = 0;
417:
418: if (repl->tag == DNAME)
419: {
420: vp = evaldname(repl);
421: copied = 1;
422: }
423: else
424: vp = repl;
425:
426: p = ALLOC(ValList);
427: p->next = NULL;
428: p->value = (Constp) val;
429:
430: if (vp->tag == DVALUE)
431: {
432: status = vp->dvalue.status;
433: value = vp->dvalue.value;
434:
435: if ((status == NORMAL && value < 0) || status == MINLESS1)
436: {
437: err(negrepl);
438: p->status = ERRVAL;
439: }
440: else if (status == NORMAL)
441: {
442: if (value == 0)
443: warn(zerorepl);
444: p->status = NORMAL;
445: p->repl = value;
446: }
447: else if (status == MAXPLUS1)
448: {
449: err(toobig);
450: p->status = ERRVAL;
451: }
452: else
453: p->status = ERRVAL;
454: }
455: else if (vp->tag == DNAME)
456: {
457: errnm(nonconst, vp->dname.len, vp->dname.repr);
458: p->status = ERRVAL;
459: }
460: else if (vp->tag == DERROR)
461: p->status = ERRVAL;
462: else
463: fatal(badtag);
464:
465: if (copied) frvexpr(vp);
466: return (p);
467: }
468:
469:
470:
471: /* Evicon returns the value of the integer constant */
472: /* pointed to by token. */
473:
474: vexpr *evicon(len, token)
475: register int len;
476: register char *token;
477: {
478: static char *badconst = "bad integer constant";
479: static char *overflow = "integer constant too large";
480:
481: register int i;
482: register ftnint val;
483: register int digit;
484: register dvalue *p;
485:
486: if (len <= 0)
487: fatal(badconst);
488:
489: p = ALLOC(Dvalue);
490: p->tag = DVALUE;
491:
492: i = 0;
493: val = 0;
494: while (i < len)
495: {
496: if (val > MAXINT/10)
497: {
498: err(overflow);
499: p->status = ERRVAL;
500: goto ret;
501: }
502: val = 10*val;
503: digit = token[i++];
504: if (!isdigit(digit))
505: fatal(badconst);
506: digit = digit - '0';
507: if (MAXINT - val >= digit)
508: val = val + digit;
509: else
510: if (i == len && MAXINT - val + 1 == digit)
511: {
512: p->status = MAXPLUS1;
513: goto ret;
514: }
515: else
516: {
517: err(overflow);
518: p->status = ERRVAL;
519: goto ret;
520: }
521: }
522:
523: p->status = NORMAL;
524: p->value = val;
525:
526: ret:
527: return ((vexpr *) p);
528: }
529:
530:
531:
532: /* Ivaltoicon converts a dvalue into a constant block. */
533:
534: expptr ivaltoicon(vp)
535: register vexpr *vp;
536: {
537: static char *badtag = "bad tag in ivaltoicon";
538: static char *overflow = "integer constant too large";
539:
540: register int vs;
541: register expptr p;
542:
543: if (vp->tag == DERROR)
544: return(errnode());
545: else if (vp->tag != DVALUE)
546: fatal(badtag);
547:
548: vs = vp->dvalue.status;
549: if (vs == NORMAL)
550: p = mkintcon(vp->dvalue.value);
551: else if ((MAXINT + MININT == -1) && vs == MINLESS1)
552: p = mkintcon(MININT);
553: else if (vs == MAXPLUS1 || vs == MINLESS1)
554: {
555: err(overflow);
556: p = errnode();
557: }
558: else
559: p = errnode();
560:
561: return (p);
562: }
563:
564:
565:
566: /* Mkdname stores an identifier as a dname */
567:
568: vexpr *mkdname(len, str)
569: int len;
570: register char *str;
571: {
572: register dname *p;
573: register int i;
574: register char *s;
575:
576: s = (char *) ckalloc(len + 1);
577: i = len;
578: s[i] = '\0';
579:
580: while (--i >= 0)
581: s[i] = str[i];
582:
583: p = ALLOC(Dname);
584: p->tag = DNAME;
585: p->len = len;
586: p->repr = s;
587:
588: return ((vexpr *) p);
589: }
590:
591:
592:
593: /* Getname gets the symbol table information associated with */
594: /* a name. Getname differs from mkname in that it will not */
595: /* add the name to the symbol table if it is not already */
596: /* present. */
597:
598: Namep getname(l, s)
599: int l;
600: register char *s;
601: {
602: struct Hashentry *hp;
603: int hash;
604: register Namep q;
605: register int i;
606: char n[VL];
607:
608: hash = 0;
609: for (i = 0; i < l && *s != '\0'; ++i)
610: {
611: hash += *s;
612: n[i] = *s++;
613: }
614:
615: while (i < VL)
616: n[i++] = ' ';
617:
618: hash %= maxhash;
619: hp = hashtab + hash;
620:
621: while (q = hp->varp)
622: if (hash == hp->hashval
623: && eqn(VL, n, q->varname))
624: goto ret;
625: else if (++hp >= lasthash)
626: hp = hashtab;
627:
628: ret:
629: return (q);
630: }
631:
632:
633:
634: /* Evparam returns the value of the constant named by name. */
635:
636: expptr evparam(np)
637: register vexpr *np;
638: {
639: static char *badtag = "bad tag in evparam";
640: static char *undefined = "%s is undefined";
641: static char *nonconst = "%s is not constant";
642:
643: register struct Paramblock *tp;
644: register expptr p;
645: register int len;
646: register char *repr;
647:
648: if (np->tag != DNAME)
649: fatal(badtag);
650:
651: len = np->dname.len;
652: repr = np->dname.repr;
653:
654: tp = (struct Paramblock *) getname(len, repr);
655:
656: if (tp == NULL)
657: {
658: errnm(undefined, len, repr);
659: p = errnode();
660: }
661: else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
662: {
663: if (tp->paramval->tag != TERROR)
664: errnm(nonconst, len, repr);
665: p = errnode();
666: }
667: else
668: p = (expptr) cpexpr(tp->paramval);
669:
670: return (p);
671: }
672:
673:
674:
675: vexpr *evaldname(dp)
676: vexpr *dp;
677: {
678: static char *undefined = "%s is undefined";
679: static char *nonconst = "%s is not a constant";
680: static char *nonint = "%s is not an integer";
681:
682: register dvalue *p;
683: register struct Paramblock *tp;
684: register int len;
685: register char *repr;
686:
687: p = ALLOC(Dvalue);
688: p->tag = DVALUE;
689:
690: len = dp->dname.len;
691: repr = dp->dname.repr;
692:
693: tp = (struct Paramblock *) getname(len, repr);
694:
695: if (tp == NULL)
696: {
697: errnm(undefined, len, repr);
698: p->status = ERRVAL;
699: }
700: else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))
701: {
702: if (tp->paramval->tag != TERROR)
703: errnm(nonconst, len, repr);
704: p->status = ERRVAL;
705: }
706: else if (!ISINT(tp->paramval->constblock.vtype))
707: {
708: errnm(nonint, len, repr);
709: p->status = ERRVAL;
710: }
711: else
712: {
713: if ((MAXINT + MININT == -1)
714: && tp->paramval->constblock.const.ci == MININT)
715: p->status = MINLESS1;
716: else
717: {
718: p->status = NORMAL;
719: p->value = tp->paramval->constblock.const.ci;
720: }
721: }
722:
723: return ((vexpr *) p);
724: }
725:
726:
727:
728: vexpr *mkdexpr(op, l, r)
729: register int op;
730: register vexpr *l;
731: register vexpr *r;
732: {
733: static char *badop = "bad operator in mkdexpr";
734:
735: register vexpr *p;
736:
737: switch (op)
738: {
739: default:
740: fatal(badop);
741:
742: case OPNEG:
743: case OPPLUS:
744: case OPMINUS:
745: case OPSTAR:
746: case OPSLASH:
747: case OPPOWER:
748: break;
749: }
750:
751: if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)
752: {
753: frvexpr(l);
754: frvexpr(r);
755: p = (vexpr *) ALLOC(Derror);
756: p->tag = DERROR;
757: }
758: else if (op == OPNEG && r->tag == DVALUE)
759: {
760: p = negival(r);
761: frvexpr(r);
762: }
763: else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)
764: {
765: switch (op)
766: {
767: case OPPLUS:
768: p = addivals(l, r);
769: break;
770:
771: case OPMINUS:
772: p = subivals(l, r);
773: break;
774:
775: case OPSTAR:
776: p = mulivals(l, r);
777: break;
778:
779: case OPSLASH:
780: p = divivals(l, r);
781: break;
782:
783: case OPPOWER:
784: p = powivals(l, r);
785: break;
786: }
787:
788: frvexpr(l);
789: frvexpr(r);
790: }
791: else
792: {
793: p = (vexpr *) ALLOC(Dexpr);
794: p->tag = DEXPR;
795: p->dexpr.opcode = op;
796: p->dexpr.left = l;
797: p->dexpr.right = r;
798: }
799:
800: return (p);
801: }
802:
803:
804:
805: vexpr *addivals(l, r)
806: vexpr *l;
807: vexpr *r;
808: {
809: static char *badtag = "bad tag in addivals";
810: static char *overflow = "integer value too large";
811:
812: register int ls, rs;
813: register ftnint lv, rv;
814: register dvalue *p;
815: register ftnint k;
816:
817: if (l->tag != DVALUE || r->tag != DVALUE)
818: fatal(badtag);
819:
820: ls = l->dvalue.status;
821: lv = l->dvalue.value;
822: rs = r->dvalue.status;
823: rv = r->dvalue.value;
824:
825: p = ALLOC(Dvalue);
826: p->tag = DVALUE;
827:
828: if (ls == ERRVAL || rs == ERRVAL)
829: p->status = ERRVAL;
830:
831: else if (ls == NORMAL && rs == NORMAL)
832: {
833: addints(lv, rv);
834: if (rstatus == ERRVAL)
835: err(overflow);
836: p->status = rstatus;
837: p->value = rvalue;
838: }
839:
840: else
841: {
842: if (rs == MAXPLUS1 || rs == MINLESS1)
843: {
844: rs = ls;
845: rv = lv;
846: ls = r->dvalue.status;
847: }
848:
849: if (rs == NORMAL && rv == 0)
850: p->status = ls;
851: else if (ls == MAXPLUS1)
852: {
853: if (rs == NORMAL && rv < 0)
854: {
855: p->status = NORMAL;
856: k = MAXINT + rv;
857: p->value = k + 1;
858: }
859: else if (rs == MINLESS1)
860: {
861: p->status = NORMAL;
862: p->value = 0;
863: }
864: else
865: {
866: err(overflow);
867: p->status = ERRVAL;
868: }
869: }
870: else
871: {
872: if (rs == NORMAL && rv > 0)
873: {
874: p->status = NORMAL;
875: k = ( -MAXINT ) + rv;
876: p->value = k - 1;
877: }
878: else if (rs == MAXPLUS1)
879: {
880: p->status = NORMAL;
881: p->value = 0;
882: }
883: else
884: {
885: err(overflow);
886: p->status = ERRVAL;
887: }
888: }
889: }
890:
891: return ((vexpr *) p);
892: }
893:
894:
895:
896: vexpr *negival(vp)
897: vexpr *vp;
898: {
899: static char *badtag = "bad tag in negival";
900:
901: register int vs;
902: register dvalue *p;
903:
904: if (vp->tag != DVALUE)
905: fatal(badtag);
906:
907: vs = vp->dvalue.status;
908:
909: p = ALLOC(Dvalue);
910: p->tag = DVALUE;
911:
912: if (vs == ERRVAL)
913: p->status = ERRVAL;
914: else if (vs == NORMAL)
915: {
916: p->status = NORMAL;
917: p->value = -(vp->dvalue.value);
918: }
919: else if (vs == MAXPLUS1)
920: p->status = MINLESS1;
921: else
922: p->status = MAXPLUS1;
923:
924: return ((vexpr *) p);
925: }
926:
927:
928:
929: vexpr *subivals(l, r)
930: vexpr *l;
931: vexpr *r;
932: {
933: static char *badtag = "bad tag in subivals";
934:
935: register vexpr *p;
936: register vexpr *t;
937:
938: if (l->tag != DVALUE || r->tag != DVALUE)
939: fatal(badtag);
940:
941: t = negival(r);
942: p = addivals(l, t);
943: frvexpr(t);
944:
945: return (p);
946: }
947:
948:
949:
950: vexpr *mulivals(l, r)
951: vexpr *l;
952: vexpr *r;
953: {
954: static char *badtag = "bad tag in mulivals";
955: static char *overflow = "integer value too large";
956:
957: register int ls, rs;
958: register ftnint lv, rv;
959: register dvalue *p;
960:
961: if (l->tag != DVALUE || r->tag != DVALUE)
962: fatal(badtag);
963:
964: ls = l->dvalue.status;
965: lv = l->dvalue.value;
966: rs = r->dvalue.status;
967: rv = r->dvalue.value;
968:
969: p = ALLOC(Dvalue);
970: p->tag = DVALUE;
971:
972: if (ls == ERRVAL || rs == ERRVAL)
973: p->status = ERRVAL;
974:
975: else if (ls == NORMAL && rs == NORMAL)
976: {
977: mulints(lv, rv);
978: if (rstatus == ERRVAL)
979: err(overflow);
980: p->status = rstatus;
981: p->value = rvalue;
982: }
983: else
984: {
985: if (rs == MAXPLUS1 || rs == MINLESS1)
986: {
987: rs = ls;
988: rv = lv;
989: ls = r->dvalue.status;
990: }
991:
992: if (rs == NORMAL && rv == 0)
993: {
994: p->status = NORMAL;
995: p->value = 0;
996: }
997: else if (rs == NORMAL && rv == 1)
998: p->status = ls;
999: else if (rs == NORMAL && rv == -1)
1000: if (ls == MAXPLUS1)
1001: p->status = MINLESS1;
1002: else
1003: p->status = MAXPLUS1;
1004: else
1005: {
1006: err(overflow);
1007: p->status = ERRVAL;
1008: }
1009: }
1010:
1011: return ((vexpr *) p);
1012: }
1013:
1014:
1015:
1016: vexpr *divivals(l, r)
1017: vexpr *l;
1018: vexpr *r;
1019: {
1020: static char *badtag = "bad tag in divivals";
1021: static char *zerodivide = "division by zero";
1022:
1023: register int ls, rs;
1024: register ftnint lv, rv;
1025: register dvalue *p;
1026: register ftnint k;
1027: register int sign;
1028:
1029: if (l->tag != DVALUE && r->tag != DVALUE)
1030: fatal(badtag);
1031:
1032: ls = l->dvalue.status;
1033: lv = l->dvalue.value;
1034: rs = r->dvalue.status;
1035: rv = r->dvalue.value;
1036:
1037: p = ALLOC(Dvalue);
1038: p->tag = DVALUE;
1039:
1040: if (ls == ERRVAL || rs == ERRVAL)
1041: p->status = ERRVAL;
1042: else if (rs == NORMAL)
1043: {
1044: if (rv == 0)
1045: {
1046: err(zerodivide);
1047: p->status = ERRVAL;
1048: }
1049: else if (ls == NORMAL)
1050: {
1051: p->status = NORMAL;
1052: p->value = lv / rv;
1053: }
1054: else if (rv == 1)
1055: p->status = ls;
1056: else if (rv == -1)
1057: if (ls == MAXPLUS1)
1058: p->status = MINLESS1;
1059: else
1060: p->status = MAXPLUS1;
1061: else
1062: {
1063: p->status = NORMAL;
1064:
1065: if (ls == MAXPLUS1)
1066: sign = 1;
1067: else
1068: sign = -1;
1069:
1070: if (rv < 0)
1071: {
1072: rv = -rv;
1073: sign = -sign;
1074: }
1075:
1076: k = MAXINT - rv;
1077: p->value = sign * ((k + 1)/rv + 1);
1078: }
1079: }
1080: else
1081: {
1082: p->status = NORMAL;
1083: if (ls == NORMAL)
1084: p->value = 0;
1085: else if ((ls == MAXPLUS1 && rs == MAXPLUS1)
1086: || (ls == MINLESS1 && rs == MINLESS1))
1087: p->value = 1;
1088: else
1089: p->value = -1;
1090: }
1091:
1092: return ((vexpr *) p);
1093: }
1094:
1095:
1096:
1097: vexpr *powivals(l, r)
1098: vexpr *l;
1099: vexpr *r;
1100: {
1101: static char *badtag = "bad tag in powivals";
1102: static char *zerozero = "zero raised to the zero-th power";
1103: static char *zeroneg = "zero raised to a negative power";
1104: static char *overflow = "integer value too large";
1105:
1106: register int ls, rs;
1107: register ftnint lv, rv;
1108: register dvalue *p;
1109:
1110: if (l->tag != DVALUE || r->tag != DVALUE)
1111: fatal(badtag);
1112:
1113: ls = l->dvalue.status;
1114: lv = l->dvalue.value;
1115: rs = r->dvalue.status;
1116: rv = r->dvalue.value;
1117:
1118: p = ALLOC(Dvalue);
1119: p->tag = DVALUE;
1120:
1121: if (ls == ERRVAL || rs == ERRVAL)
1122: p->status = ERRVAL;
1123:
1124: else if (ls == NORMAL)
1125: {
1126: if (lv == 1)
1127: {
1128: p->status = NORMAL;
1129: p->value = 1;
1130: }
1131: else if (lv == 0)
1132: {
1133: if (rs == MAXPLUS1 || (rs == NORMAL && rv > 0))
1134: {
1135: p->status = NORMAL;
1136: p->value = 0;
1137: }
1138: else if (rs == NORMAL && rv == 0)
1139: {
1140: warn(zerozero);
1141: p->status = NORMAL;
1142: p->value = 1;
1143: }
1144: else
1145: {
1146: err(zeroneg);
1147: p->status = ERRVAL;
1148: }
1149: }
1150: else if (lv == -1)
1151: {
1152: p->status = NORMAL;
1153: if (rs == NORMAL)
1154: {
1155: if (rv < 0) rv = -rv;
1156: if (rv % 2 == 0)
1157: p->value = 1;
1158: else
1159: p->value = -1;
1160: }
1161: else
1162: # if (MAXINT % 2 == 1)
1163: p->value = 1;
1164: # else
1165: p->value = -1;
1166: # endif
1167: }
1168: else
1169: {
1170: if (rs == NORMAL && rv > 0)
1171: {
1172: rstatus = NORMAL;
1173: rvalue = lv;
1174: while (--rv && rstatus == NORMAL)
1175: mulints(rvalue, lv);
1176: if (rv == 0 && rstatus != ERRVAL)
1177: {
1178: p->status = rstatus;
1179: p->value = rvalue;
1180: }
1181: else
1182: {
1183: err(overflow);
1184: p->status = ERRVAL;
1185: }
1186: }
1187: else if (rs == MAXPLUS1)
1188: {
1189: err(overflow);
1190: p->status = ERRVAL;
1191: }
1192: else if (rs == NORMAL && rv == 0)
1193: {
1194: p->status = NORMAL;
1195: p->value = 1;
1196: }
1197: else
1198: {
1199: p->status = NORMAL;
1200: p->value = 0;
1201: }
1202: }
1203: }
1204:
1205: else
1206: {
1207: if (rs == MAXPLUS1 || (rs == NORMAL && rv > 1))
1208: {
1209: err(overflow);
1210: p->status = ERRVAL;
1211: }
1212: else if (rs == NORMAL && rv == 1)
1213: p->status = ls;
1214: else if (rs == NORMAL && rv == 0)
1215: {
1216: p->status = NORMAL;
1217: p->value = 1;
1218: }
1219: else
1220: {
1221: p->status = NORMAL;
1222: p->value = 0;
1223: }
1224: }
1225:
1226: return ((vexpr *) p);
1227: }
1228:
1229:
1230:
1231: /* Addints adds two integer values. */
1232:
1233: addints(i, j)
1234: register ftnint i, j;
1235: {
1236: register ftnint margin;
1237:
1238: if (i == 0)
1239: {
1240: rstatus = NORMAL;
1241: rvalue = j;
1242: }
1243: else if (i > 0)
1244: {
1245: margin = MAXINT - i;
1246: if (j <= margin)
1247: {
1248: rstatus = NORMAL;
1249: rvalue = i + j;
1250: }
1251: else if (j == margin + 1)
1252: rstatus = MAXPLUS1;
1253: else
1254: rstatus = ERRVAL;
1255: }
1256: else
1257: {
1258: margin = ( -MAXINT ) - i;
1259: if (j >= margin)
1260: {
1261: rstatus = NORMAL;
1262: rvalue = i + j;
1263: }
1264: else if (j == margin - 1)
1265: rstatus = MINLESS1;
1266: else
1267: rstatus = ERRVAL;
1268: }
1269:
1270: return;
1271: }
1272:
1273:
1274:
1275: /* Mulints multiplies two integer values */
1276:
1277: mulints(i, j)
1278: register ftnint i, j;
1279: {
1280: register ftnint sign;
1281: register ftnint margin;
1282:
1283: if (i == 0 || j == 0)
1284: {
1285: rstatus = NORMAL;
1286: rvalue = 0;
1287: }
1288: else
1289: {
1290: if ((i > 0 && j > 0) || (i < 0 && j < 0))
1291: sign = 1;
1292: else
1293: sign = -1;
1294:
1295: if (i < 0) i = -i;
1296: if (j < 0) j = -j;
1297:
1298: margin = MAXINT - i;
1299: margin = (margin + 1) / i;
1300:
1301: if (j <= margin)
1302: {
1303: rstatus = NORMAL;
1304: rvalue = i * j * sign;
1305: }
1306: else if (j - 1 == margin)
1307: {
1308: margin = i*margin - 1;
1309: if (margin == MAXINT - i)
1310: if (sign > 0)
1311: rstatus = MAXPLUS1;
1312: else
1313: rstatus = MINLESS1;
1314: else
1315: {
1316: rstatus = NORMAL;
1317: rvalue = i * j * sign;
1318: }
1319: }
1320: else
1321: rstatus = ERRVAL;
1322: }
1323:
1324: return;
1325: }
1326:
1327:
1328:
1329: vexpr *
1330: evalvexpr(ep)
1331: vexpr *ep;
1332: {
1333: register vexpr *p;
1334: register vexpr *l, *r;
1335:
1336: switch (ep->tag)
1337: {
1338: case DVALUE:
1339: p = cpdvalue(ep);
1340: break;
1341:
1342: case DVAR:
1343: p = cpdvalue((vexpr *) ep->dvar.valp);
1344: break;
1345:
1346: case DNAME:
1347: p = evaldname(ep);
1348: break;
1349:
1350: case DEXPR:
1351: if (ep->dexpr.left == NULL)
1352: l = NULL;
1353: else
1354: l = evalvexpr(ep->dexpr.left);
1355:
1356: if (ep->dexpr.right == NULL)
1357: r = NULL;
1358: else
1359: r = evalvexpr(ep->dexpr.right);
1360:
1361: switch (ep->dexpr.opcode)
1362: {
1363: case OPNEG:
1364: p = negival(r);
1365: break;
1366:
1367: case OPPLUS:
1368: p = addivals(l, r);
1369: break;
1370:
1371: case OPMINUS:
1372: p = subivals(l, r);
1373: break;
1374:
1375: case OPSTAR:
1376: p = mulivals(l, r);
1377: break;
1378:
1379: case OPSLASH:
1380: p = divivals(l, r);
1381: break;
1382:
1383: case OPPOWER:
1384: p = powivals(l, r);
1385: break;
1386: }
1387:
1388: frvexpr(l);
1389: frvexpr(r);
1390: break;
1391:
1392: case DERROR:
1393: p = (vexpr *) ALLOC(Dvalue);
1394: p->tag = DVALUE;
1395: p->dvalue.status = ERRVAL;
1396: break;
1397: }
1398:
1399: return (p);
1400: }
1401:
1402:
1403:
1404: vexpr *
1405: refrigdname(vp)
1406: vexpr *vp;
1407: {
1408: register vexpr *p;
1409: register int len;
1410: register char *repr;
1411: register int found;
1412: register dovars *dvp;
1413:
1414: len = vp->dname.len;
1415: repr = vp->dname.repr;
1416:
1417: found = NO;
1418: dvp = dvlist;
1419: while (found == NO && dvp != NULL)
1420: {
1421: if (len == dvp->len && eqn(len, repr, dvp->repr))
1422: found = YES;
1423: else
1424: dvp = dvp->next;
1425: }
1426:
1427: if (found == YES)
1428: {
1429: p = (vexpr *) ALLOC(Dvar);
1430: p->tag = DVAR;
1431: p->dvar.valp = dvp->valp;
1432: }
1433: else
1434: {
1435: p = evaldname(vp);
1436: if (p->dvalue.status == ERRVAL)
1437: dataerror = YES;
1438: }
1439:
1440: return (p);
1441: }
1442:
1443:
1444:
1445: refrigvexpr(vpp)
1446: vexpr **vpp;
1447: {
1448: register vexpr *vp;
1449:
1450: vp = *vpp;
1451:
1452: switch (vp->tag)
1453: {
1454: case DVALUE:
1455: case DVAR:
1456: case DERROR:
1457: break;
1458:
1459: case DEXPR:
1460: refrigvexpr( &(vp->dexpr.left) );
1461: refrigvexpr( &(vp->dexpr.right) );
1462: break;
1463:
1464: case DNAME:
1465: *(vpp) = refrigdname(vp);
1466: frvexpr(vp);
1467: break;
1468: }
1469:
1470: return;
1471: }
1472:
1473:
1474:
1475: int
1476: chkvar(np, sname)
1477: Namep np;
1478: char *sname;
1479: {
1480: static char *nonvar = "%s is not a variable";
1481: static char *arginit = "attempt to initialize a dummy argument: %s";
1482: static char *autoinit = "attempt to initialize an automatic variable: %s";
1483: static char *badclass = "bad class in chkvar";
1484:
1485: register int status;
1486: register struct Dimblock *dp;
1487: register int i;
1488:
1489: status = YES;
1490:
1491: if (np->vclass == CLUNKNOWN
1492: || (np->vclass == CLVAR && !np->vdcldone))
1493: vardcl(np);
1494:
1495: if (np->vstg == STGARG)
1496: {
1497: errstr(arginit, sname);
1498: dataerror = YES;
1499: status = NO;
1500: }
1501: else if (np->vclass != CLVAR)
1502: {
1503: errstr(nonvar, sname);
1504: dataerror = YES;
1505: status = NO;
1506: }
1507: else if (np->vstg == STGAUTO)
1508: {
1509: errstr(autoinit, sname);
1510: dataerror = YES;
1511: status = NO;
1512: }
1513: else if (np->vstg != STGBSS && np->vstg != STGINIT
1514: && np->vstg != STGCOMMON && np->vstg != STGEQUIV)
1515: {
1516: fatal(badclass);
1517: }
1518: else
1519: {
1520: switch (np->vtype)
1521: {
1522: case TYERROR:
1523: status = NO;
1524: dataerror = YES;
1525: break;
1526:
1527: case TYSHORT:
1528: case TYLONG:
1529: case TYREAL:
1530: case TYDREAL:
1531: case TYCOMPLEX:
1532: case TYDCOMPLEX:
1533: case TYLOGICAL:
1534: case TYCHAR:
1535: dp = np->vdim;
1536: if (dp != NULL)
1537: {
1538: if (dp->nelt == NULL || !ISICON(dp->nelt))
1539: {
1540: status = NO;
1541: dataerror = YES;
1542: }
1543: }
1544: break;
1545:
1546: default:
1547: badtype("chkvar", np->vtype);
1548: }
1549: }
1550:
1551: return (status);
1552: }
1553:
1554:
1555:
1556: refrigsubs(ap, sname)
1557: aelt *ap;
1558: char *sname;
1559: {
1560: static char *nonarray = "subscripts on a simple variable: %s";
1561: static char *toofew = "not enough subscripts on %s";
1562: static char *toomany = "too many subscripts on %s";
1563:
1564: register vlist *subp;
1565: register int nsubs;
1566: register Namep np;
1567: register struct Dimblock *dp;
1568: register int i;
1569:
1570: np = ap->var;
1571: dp = np->vdim;
1572:
1573: if (ap->subs != NULL)
1574: {
1575: if (np->vdim == NULL)
1576: {
1577: errstr(nonarray, sname);
1578: dataerror = YES;
1579: }
1580: else
1581: {
1582: nsubs = 0;
1583: subp = ap->subs;
1584: while (subp != NULL)
1585: {
1586: nsubs++;
1587: refrigvexpr( &(subp->val) );
1588: subp = subp->next;
1589: }
1590:
1591: if (dp->ndim != nsubs)
1592: {
1593: if (np->vdim->ndim > nsubs)
1594: errstr(toofew, sname);
1595: else
1596: errstr(toomany, sname);
1597: dataerror = YES;
1598: }
1599: else if (dp->baseoffset == NULL || !ISICON(dp->baseoffset))
1600: dataerror = YES;
1601: else
1602: {
1603: i = dp->ndim;
1604: while (i-- > 0)
1605: {
1606: if (dp->dims[i].dimsize == NULL
1607: || !ISICON(dp->dims[i].dimsize))
1608: dataerror = YES;
1609: }
1610: }
1611: }
1612: }
1613:
1614: return;
1615: }
1616:
1617:
1618:
1619: refrigrange(ap, sname)
1620: aelt *ap;
1621: char *sname;
1622: {
1623: static char *nonstr = "substring of a noncharacter variable: %s";
1624: static char *array = "substring applied to an array: %s";
1625:
1626: register Namep np;
1627: register dvalue *t;
1628: register rpair *rp;
1629:
1630: if (ap->range != NULL)
1631: {
1632: np = ap->var;
1633: if (np->vtype != TYCHAR)
1634: {
1635: errstr(nonstr, sname);
1636: dataerror = YES;
1637: }
1638: else if (ap->subs == NULL && np->vdim != NULL)
1639: {
1640: errstr(array, sname);
1641: dataerror = YES;
1642: }
1643: else
1644: {
1645: rp = ap->range;
1646:
1647: if (rp->low != NULL)
1648: refrigvexpr( &(rp->low) );
1649: else
1650: {
1651: t = ALLOC(Dvalue);
1652: t->tag = DVALUE;
1653: t->status = NORMAL;
1654: t->value = 1;
1655: rp->low = (vexpr *) t;
1656: }
1657:
1658: if (rp->high != NULL)
1659: refrigvexpr( &(rp->high) );
1660: else
1661: {
1662: if (!ISICON(np->vleng))
1663: {
1664: rp->high = (vexpr *) ALLOC(Derror);
1665: rp->high->tag = DERROR;
1666: }
1667: else
1668: {
1669: t = ALLOC(Dvalue);
1670: t->tag = DVALUE;
1671: t->status = NORMAL;
1672: t->value = np->vleng->constblock.const.ci;
1673: rp->high = (vexpr *) t;
1674: }
1675: }
1676: }
1677: }
1678:
1679: return;
1680: }
1681:
1682:
1683:
1684: refrigaelt(ap)
1685: aelt *ap;
1686: {
1687: register Namep np;
1688: register char *bp, *sp;
1689: register int len;
1690: char buff[VL+1];
1691:
1692: np = ap->var;
1693:
1694: len = 0;
1695: bp = buff;
1696: sp = np->varname;
1697: while (len < VL && *sp != ' ' && *sp != '\0')
1698: {
1699: *bp++ = *sp++;
1700: len++;
1701: }
1702: *bp = '\0';
1703:
1704: if (chkvar(np, buff))
1705: {
1706: refrigsubs(ap, buff);
1707: refrigrange(ap, buff);
1708: }
1709:
1710: return;
1711: }
1712:
1713:
1714:
1715: refrigdo(dp)
1716: dolist *dp;
1717: {
1718: static char *duplicates = "implied DO variable %s redefined";
1719: static char *nonvar = "%s is not a variable";
1720: static char *nonint = "%s is not integer";
1721:
1722: register int len;
1723: register char *repr;
1724: register int found;
1725: register dovars *dvp;
1726: register Namep np;
1727: register dovars *t;
1728:
1729: refrigvexpr( &(dp->init) );
1730: refrigvexpr( &(dp->limit) );
1731: refrigvexpr( &(dp->step) );
1732:
1733: len = dp->dovar->dname.len;
1734: repr = dp->dovar->dname.repr;
1735:
1736: found = NO;
1737: dvp = dvlist;
1738: while (found == NO && dvp != NULL)
1739: if (len == dvp->len && eqn(len, repr, dvp->repr))
1740: found = YES;
1741: else
1742: dvp = dvp->next;
1743:
1744: if (found == YES)
1745: {
1746: errnm(duplicates, len, repr);
1747: dataerror = YES;
1748: }
1749: else
1750: {
1751: np = getname(len, repr);
1752: if (np == NULL)
1753: {
1754: if (!ISINT(impltype[letter(*repr)]))
1755: warnnm(nonint, len, repr);
1756: }
1757: else
1758: {
1759: if (np->vclass == CLUNKNOWN)
1760: vardcl(np);
1761: if (np->vclass != CLVAR)
1762: warnnm(nonvar, len, repr);
1763: else if (!ISINT(np->vtype))
1764: warnnm(nonint, len, repr);
1765: }
1766: }
1767:
1768: t = ALLOC(DoVars);
1769: t->next = dvlist;
1770: t->len = len;
1771: t->repr = repr;
1772: t->valp = ALLOC(Dvalue);
1773: t->valp->tag = DVALUE;
1774: dp->dovar = (vexpr *) t->valp;
1775:
1776: dvlist = t;
1777:
1778: refriglvals(dp->elts);
1779:
1780: dvlist = t->next;
1781: free((char *) t);
1782:
1783: return;
1784: }
1785:
1786:
1787:
1788: refriglvals(lvals)
1789: elist *lvals;
1790: {
1791: register elist *top;
1792:
1793: top = lvals;
1794:
1795: while (top != NULL)
1796: {
1797: if (top->elt->tag == SIMPLE)
1798: refrigaelt((aelt *) top->elt);
1799: else
1800: refrigdo((dolist *) top->elt);
1801:
1802: top = top->next;
1803: }
1804:
1805: return;
1806: }
1807:
1808:
1809:
1810: /* Refrig freezes name/value bindings in the DATA name list */
1811:
1812:
1813: refrig(lvals)
1814: elist *lvals;
1815: {
1816: dvlist = NULL;
1817: refriglvals(lvals);
1818: return;
1819: }
1820:
1821:
1822:
1823: ftnint
1824: indexer(ap)
1825: aelt *ap;
1826: {
1827: static char *badvar = "bad variable in indexer";
1828: static char *boundserror = "subscript out of bounds";
1829:
1830: register ftnint index;
1831: register vlist *sp;
1832: register Namep np;
1833: register struct Dimblock *dp;
1834: register int i;
1835: register dvalue *vp;
1836: register ftnint size;
1837: ftnint sub[MAXDIM];
1838:
1839: sp = ap->subs;
1840: if (sp == NULL) return (0);
1841:
1842: np = ap->var;
1843: dp = np->vdim;
1844:
1845: if (dp == NULL)
1846: fatal(badvar);
1847:
1848: i = 0;
1849: while (sp != NULL)
1850: {
1851: vp = (dvalue *) evalvexpr(sp->val);
1852:
1853: if (vp->status == NORMAL)
1854: sub[i++] = vp->value;
1855: else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)
1856: sub[i++] = MININT;
1857: else
1858: {
1859: frvexpr((vexpr *) vp);
1860: return (-1);
1861: }
1862:
1863: frvexpr((vexpr *) vp);
1864: sp = sp->next;
1865: }
1866:
1867: index = sub[--i];
1868: while (i-- > 0)
1869: {
1870: size = dp->dims[i].dimsize->constblock.const.ci;
1871: index = sub[i] + index * size;
1872: }
1873:
1874: index -= dp->baseoffset->constblock.const.ci;
1875:
1876: if (index < 0 || index >= dp->nelt->constblock.const.ci)
1877: {
1878: err(boundserror);
1879: return (-1);
1880: }
1881:
1882: return (index);
1883: }
1884:
1885:
1886:
1887: savedata(lvals, rvals)
1888: elist *lvals;
1889: vallist *rvals;
1890: {
1891: static char *toomany = "more data values than data items";
1892:
1893: register elist *top;
1894:
1895: dataerror = NO;
1896: badvalue = NO;
1897:
1898: lvals = revelist(lvals);
1899: grvals = revrvals(rvals);
1900:
1901: refrig(lvals);
1902:
1903: if (!dataerror)
1904: outdata(lvals);
1905:
1906: frelist(lvals);
1907:
1908: while (grvals != NULL && dataerror == NO)
1909: {
1910: if (grvals->status != NORMAL)
1911: dataerror = YES;
1912: else if (grvals->repl <= 0)
1913: grvals = grvals->next;
1914: else
1915: {
1916: err(toomany);
1917: dataerror = YES;
1918: }
1919: }
1920:
1921: frvallist(grvals);
1922:
1923: return;
1924: }
1925:
1926:
1927:
1928: setdfiles(np)
1929: register Namep np;
1930: {
1931: register struct Extsym *cp;
1932: register struct Equivblock *ep;
1933: register int stg;
1934: register int type;
1935: register ftnint typelen;
1936: register ftnint nelt;
1937: register ftnint varsize;
1938:
1939: stg = np->vstg;
1940:
1941: if (stg == STGBSS || stg == STGINIT)
1942: {
1943: datafile = vdatafile;
1944: chkfile = vchkfile;
1945: if (np->init == YES)
1946: base = np->initoffset;
1947: else
1948: {
1949: np->init = YES;
1950: np->initoffset = base = vdatahwm;
1951: if (np->vdim != NULL)
1952: nelt = np->vdim->nelt->constblock.const.ci;
1953: else
1954: nelt = 1;
1955: type = np->vtype;
1956: if (type == TYCHAR)
1957: typelen = np->vleng->constblock.const.ci;
1958: else if (type == TYLOGICAL)
1959: typelen = typesize[tylogical];
1960: else
1961: typelen = typesize[type];
1962: varsize = nelt * typelen;
1963: vdatahwm += varsize;
1964: }
1965: }
1966: else if (stg == STGEQUIV)
1967: {
1968: datafile = vdatafile;
1969: chkfile = vchkfile;
1970: ep = &eqvclass[np->vardesc.varno];
1971: if (ep->init == YES)
1972: base = ep->initoffset;
1973: else
1974: {
1975: ep->init = YES;
1976: ep->initoffset = base = vdatahwm;
1977: vdatahwm += ep->eqvleng;
1978: }
1979: base += np->voffset;
1980: }
1981: else if (stg == STGCOMMON)
1982: {
1983: datafile = cdatafile;
1984: chkfile = cchkfile;
1985: cp = &extsymtab[np->vardesc.varno];
1986: if (cp->init == YES)
1987: base = cp->initoffset;
1988: else
1989: {
1990: cp->init = YES;
1991: cp->initoffset = base = cdatahwm;
1992: cdatahwm += cp->maxleng;
1993: }
1994: base += np->voffset;
1995: }
1996:
1997: return;
1998: }
1999:
2000:
2001:
2002: wrtdata(offset, repl, len, const)
2003: long offset;
2004: ftnint repl;
2005: ftnint len;
2006: char *const;
2007: {
2008: static char *badoffset = "bad offset in wrtdata";
2009: static char *toomuch = "too much data";
2010: static char *readerror = "read error on tmp file";
2011: static char *writeerror = "write error on tmp file";
2012: static char *seekerror = "seek error on tmp file";
2013:
2014: register ftnint k;
2015: long lastbyte;
2016: int bitpos;
2017: long chkoff;
2018: long lastoff;
2019: long chklen;
2020: long pos;
2021: int n;
2022: ftnint nbytes;
2023: int mask;
2024: register int i;
2025: char overlap;
2026: char allzero;
2027: char buff[BUFSIZ];
2028:
2029: if (offset < 0)
2030: fatal(badoffset);
2031:
2032: overlap = NO;
2033:
2034: k = repl * len;
2035: lastbyte = offset + k - 1;
2036: if (lastbyte < 0)
2037: {
2038: err(toomuch);
2039: dataerror = YES;
2040: return;
2041: }
2042:
2043: bitpos = offset % BYTESIZE;
2044: chkoff = offset/BYTESIZE;
2045: lastoff = lastbyte/BYTESIZE;
2046: chklen = lastoff - chkoff + 1;
2047:
2048: pos = lseek(chkfile, chkoff, 0);
2049: if (pos == -1)
2050: {
2051: err(seekerror);
2052: done(1);
2053: }
2054:
2055: while (k > 0)
2056: {
2057: if (chklen <= BUFSIZ)
2058: n = chklen;
2059: else
2060: {
2061: n = BUFSIZ;
2062: chklen -= BUFSIZ;
2063: }
2064:
2065: nbytes = read(chkfile, buff, n);
2066: if (nbytes < 0)
2067: {
2068: err(readerror);
2069: done(1);
2070: }
2071:
2072: if (nbytes == 0)
2073: buff[0] = '\0';
2074:
2075: if (nbytes < n)
2076: buff[ n-1 ] = '\0';
2077:
2078: i = 0;
2079:
2080: if (bitpos > 0)
2081: {
2082: while (k > 0 && bitpos < BYTESIZE)
2083: {
2084: mask = 1 << bitpos;
2085:
2086: if (mask & buff[0])
2087: overlap = YES;
2088: else
2089: buff[0] |= mask;
2090:
2091: k--;
2092: bitpos++;
2093: }
2094:
2095: if (bitpos == BYTESIZE)
2096: {
2097: bitpos = 0;
2098: i++;
2099: }
2100: }
2101:
2102: while (i < nbytes && overlap == NO)
2103: {
2104: if (buff[i] == 0 && k >= BYTESIZE)
2105: {
2106: buff[i++] = MAXBYTE;
2107: k -= BYTESIZE;
2108: }
2109: else if (k < BYTESIZE)
2110: {
2111: while (k-- > 0)
2112: {
2113: mask = 1 << k;
2114: if (mask & buff[i])
2115: overlap = YES;
2116: else
2117: buff[i] |= mask;
2118: }
2119: i++;
2120: }
2121: else
2122: {
2123: overlap = YES;
2124: buff[i++] = MAXBYTE;
2125: k -= BYTESIZE;
2126: }
2127: }
2128:
2129: while (i < n)
2130: {
2131: if (k >= BYTESIZE)
2132: {
2133: buff[i++] = MAXBYTE;
2134: k -= BYTESIZE;
2135: }
2136: else
2137: {
2138: while (k-- > 0)
2139: {
2140: mask = 1 << k;
2141: buff[i] |= mask;
2142: }
2143: i++;
2144: }
2145: }
2146:
2147: pos = lseek(chkfile, -nbytes, 1);
2148: if (pos == -1)
2149: {
2150: err(seekerror);
2151: done(1);
2152: }
2153:
2154: nbytes = write(chkfile, buff, n);
2155: if (nbytes != n)
2156: {
2157: err(writeerror);
2158: done(1);
2159: }
2160: }
2161:
2162: if (overlap == NO)
2163: {
2164: allzero = YES;
2165: k = len;
2166:
2167: while (k > 0 && allzero != NO)
2168: if (const[--k] != 0) allzero = NO;
2169:
2170: if (allzero == YES)
2171: return;
2172: }
2173:
2174: pos = lseek(datafile, offset, 0);
2175: if (pos == -1)
2176: {
2177: err(seekerror);
2178: done(1);
2179: }
2180:
2181: k = repl;
2182: while (k-- > 0)
2183: {
2184: nbytes = write(datafile, const, len);
2185: if (nbytes != len)
2186: {
2187: err(writeerror);
2188: done(1);
2189: }
2190: }
2191:
2192: if (overlap) overlapflag = YES;
2193:
2194: return;
2195: }
2196:
2197:
2198:
2199: Constp
2200: getdatum()
2201: {
2202: static char *toofew = "more data items than data values";
2203:
2204: register vallist *t;
2205:
2206: while (grvals != NULL)
2207: {
2208: if (grvals->status != NORMAL)
2209: {
2210: dataerror = YES;
2211: return (NULL);
2212: }
2213: else if (grvals->repl > 0)
2214: {
2215: grvals->repl--;
2216: return (grvals->value);
2217: }
2218: else
2219: {
2220: badvalue = 0;
2221: frexpr ((tagptr) grvals->value);
2222: t = grvals;
2223: grvals = t->next;
2224: free((char *) t);
2225: }
2226: }
2227:
2228: err(toofew);
2229: dataerror = YES;
2230: return (NULL);
2231: }
2232:
2233:
2234:
2235: outdata(lvals)
2236: elist *lvals;
2237: {
2238: register elist *top;
2239:
2240: top = lvals;
2241:
2242: while (top != NULL && dataerror == NO)
2243: {
2244: if (top->elt->tag == SIMPLE)
2245: outaelt((aelt *) top->elt);
2246: else
2247: outdolist((dolist *) top->elt);
2248:
2249: top = top->next;
2250: }
2251:
2252: return;
2253: }
2254:
2255:
2256:
2257: outaelt(ap)
2258: aelt *ap;
2259: {
2260: static char *toofew = "more data items than data values";
2261: static char *boundserror = "substring expression out of bounds";
2262: static char *order = "substring expressions out of order";
2263:
2264: register Namep np;
2265: register long soffset;
2266: register dvalue *lwb;
2267: register dvalue *upb;
2268: register Constp const;
2269: register int k;
2270: register vallist *t;
2271: register int type;
2272: register ftnint typelen;
2273: register ftnint repl;
2274:
2275: extern char *packbytes();
2276:
2277: np = ap->var;
2278: setdfiles(np);
2279:
2280: type = np->vtype;
2281:
2282: if (type == TYCHAR)
2283: typelen = np->vleng->constblock.const.ci;
2284: else if (type == TYLOGICAL)
2285: typelen = typesize[tylogical];
2286: else
2287: typelen = typesize[type];
2288:
2289: if (ap->subs != NULL || np->vdim == NULL)
2290: {
2291: soffset = indexer(ap);
2292: if (soffset == -1)
2293: {
2294: dataerror = YES;
2295: return;
2296: }
2297:
2298: soffset = soffset * typelen;
2299:
2300: if (ap->range != NULL)
2301: {
2302: lwb = (dvalue *) evalvexpr(ap->range->low);
2303: upb = (dvalue *) evalvexpr(ap->range->high);
2304: if (lwb->status == ERRVAL || upb->status == ERRVAL)
2305: {
2306: frvexpr((vexpr *) lwb);
2307: frvexpr((vexpr *) upb);
2308: dataerror = YES;
2309: return;
2310: }
2311:
2312: if (lwb->status != NORMAL ||
2313: lwb->value < 1 ||
2314: lwb->value > typelen ||
2315: upb->status != NORMAL ||
2316: upb->value < 1 ||
2317: upb->value > typelen)
2318: {
2319: err(boundserror);
2320: frvexpr((vexpr *) lwb);
2321: frvexpr((vexpr *) upb);
2322: dataerror = YES;
2323: return;
2324: }
2325:
2326: if (lwb->value > upb->value)
2327: {
2328: err(order);
2329: frvexpr((vexpr *) lwb);
2330: frvexpr((vexpr *) upb);
2331: dataerror = YES;
2332: return;
2333: }
2334:
2335: soffset = soffset + lwb->value - 1;
2336: typelen = upb->value - lwb->value + 1;
2337: frvexpr((vexpr *) lwb);
2338: frvexpr((vexpr *) upb);
2339: }
2340:
2341: const = getdatum();
2342: if (const == NULL || !ISCONST(const))
2343: return;
2344:
2345: const = (Constp) convconst(type, typelen, const);
2346: if (const == NULL || !ISCONST(const))
2347: {
2348: frexpr((tagptr) const);
2349: return;
2350: }
2351:
2352: if (type == TYCHAR)
2353: wrtdata(base + soffset, 1, typelen, const->const.ccp);
2354: else
2355: wrtdata(base + soffset, 1, typelen, packbytes(const));
2356:
2357: frexpr((tagptr) const);
2358: }
2359: else
2360: {
2361: soffset = 0;
2362: k = np->vdim->nelt->constblock.const.ci;
2363: while (k > 0 && dataerror == NO)
2364: {
2365: if (grvals == NULL)
2366: {
2367: err(toofew);
2368: dataerror = YES;
2369: }
2370: else if (grvals->status != NORMAL)
2371: dataerror = YES;
2372: else if (grvals-> repl <= 0)
2373: {
2374: badvalue = 0;
2375: frexpr((tagptr) grvals->value);
2376: t = grvals;
2377: grvals = t->next;
2378: free((char *) t);
2379: }
2380: else
2381: {
2382: const = grvals->value;
2383: if (const == NULL || !ISCONST(const))
2384: {
2385: dataerror = YES;
2386: }
2387: else
2388: {
2389: const = (Constp) convconst(type, typelen, const);
2390: if (const == NULL || !ISCONST(const))
2391: {
2392: dataerror = YES;
2393: frexpr((tagptr) const);
2394: }
2395: else
2396: {
2397: if (k > grvals->repl)
2398: repl = grvals->repl;
2399: else
2400: repl = k;
2401:
2402: grvals->repl -= repl;
2403: k -= repl;
2404:
2405: if (type == TYCHAR)
2406: wrtdata(base+soffset, repl, typelen, const->const.ccp);
2407: else
2408: wrtdata(base+soffset, repl, typelen, packbytes(const));
2409:
2410: soffset = soffset + repl * typelen;
2411:
2412: frexpr((tagptr) const);
2413: }
2414: }
2415: }
2416: }
2417: }
2418:
2419: return;
2420: }
2421:
2422:
2423:
2424: outdolist(dp)
2425: dolist *dp;
2426: {
2427: static char *zerostep = "zero step in implied-DO";
2428: static char *order = "zero iteration count in implied-DO";
2429:
2430: register dvalue *e1, *e2, *e3;
2431: register int direction;
2432: register dvalue *dv;
2433: register int done;
2434: register int addin;
2435: register int ts;
2436: register ftnint tv;
2437:
2438: e1 = (dvalue *) evalvexpr(dp->init);
2439: e2 = (dvalue *) evalvexpr(dp->limit);
2440: e3 = (dvalue *) evalvexpr(dp->step);
2441:
2442: if (e1->status == ERRVAL ||
2443: e2->status == ERRVAL ||
2444: e3->status == ERRVAL)
2445: {
2446: dataerror = YES;
2447: goto ret;
2448: }
2449:
2450: if (e1->status == NORMAL)
2451: {
2452: if (e2->status == NORMAL)
2453: {
2454: if (e1->value < e2->value)
2455: direction = 1;
2456: else if (e1->value > e2->value)
2457: direction = -1;
2458: else
2459: direction = 0;
2460: }
2461: else if (e2->status == MAXPLUS1)
2462: direction = 1;
2463: else
2464: direction = -1;
2465: }
2466: else if (e1->status == MAXPLUS1)
2467: {
2468: if (e2->status == MAXPLUS1)
2469: direction = 0;
2470: else
2471: direction = -1;
2472: }
2473: else
2474: {
2475: if (e2->status == MINLESS1)
2476: direction = 0;
2477: else
2478: direction = 1;
2479: }
2480:
2481: if (e3->status == NORMAL && e3->value == 0)
2482: {
2483: err(zerostep);
2484: dataerror = YES;
2485: goto ret;
2486: }
2487: else if (e3->status == MAXPLUS1 ||
2488: (e3->status == NORMAL && e3->value > 0))
2489: {
2490: if (direction == -1)
2491: {
2492: warn(order);
2493: goto ret;
2494: }
2495: }
2496: else
2497: {
2498: if (direction == 1)
2499: {
2500: warn(order);
2501: goto ret;
2502: }
2503: }
2504:
2505: dv = (dvalue *) dp->dovar;
2506: dv->status = e1->status;
2507: dv->value = e1->value;
2508:
2509: done = NO;
2510: while (done == NO && dataerror == NO)
2511: {
2512: outdata(dp->elts);
2513:
2514: if (e3->status == NORMAL && dv->status == NORMAL)
2515: {
2516: addints(e3->value, dv->value);
2517: dv->status = rstatus;
2518: dv->value = rvalue;
2519: }
2520: else
2521: {
2522: if (e3->status != NORMAL)
2523: {
2524: if (e3->status == MAXPLUS1)
2525: addin = MAXPLUS1;
2526: else
2527: addin = MINLESS1;
2528: ts = dv->status;
2529: tv = dv->value;
2530: }
2531: else
2532: {
2533: if (dv->status == MAXPLUS1)
2534: addin = MAXPLUS1;
2535: else
2536: addin = MINLESS1;
2537: ts = e3->status;
2538: tv = e3->value;
2539: }
2540:
2541: if (addin == MAXPLUS1)
2542: {
2543: if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))
2544: dv->status = ERRVAL;
2545: else if (ts == NORMAL && tv == 0)
2546: dv->status = MAXPLUS1;
2547: else if (ts == NORMAL)
2548: {
2549: dv->status = NORMAL;
2550: dv->value = tv + MAXINT;
2551: dv->value++;
2552: }
2553: else
2554: {
2555: dv->status = NORMAL;
2556: dv->value = 0;
2557: }
2558: }
2559: else
2560: {
2561: if (ts == MINLESS1 || (ts == NORMAL && tv < 0))
2562: dv->status = ERRVAL;
2563: else if (ts == NORMAL && tv == 0)
2564: dv->status = MINLESS1;
2565: else if (ts == NORMAL)
2566: {
2567: dv->status = NORMAL;
2568: dv->value = tv - MAXINT;
2569: dv->value--;
2570: }
2571: else
2572: {
2573: dv->status = NORMAL;
2574: dv->value = 0;
2575: }
2576: }
2577: }
2578:
2579: if (dv->status == ERRVAL)
2580: done = YES;
2581: else if (direction > 0)
2582: {
2583: if (e2->status == NORMAL)
2584: {
2585: if (dv->status == MAXPLUS1 ||
2586: (dv->status == NORMAL && dv->value > e2->value))
2587: done = YES;
2588: }
2589: }
2590: else if (direction < 0)
2591: {
2592: if (e2->status == NORMAL)
2593: {
2594: if (dv->status == MINLESS1 ||
2595: (dv->status == NORMAL && dv->value < e2->value))
2596: done = YES;
2597: }
2598: }
2599: else
2600: done = YES;
2601: }
2602:
2603: ret:
2604: frvexpr((vexpr *) e1);
2605: frvexpr((vexpr *) e2);
2606: frvexpr((vexpr *) e3);
2607: return;
2608: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.