|
|
1.1 root 1: /* Routines to generate code for I/O statements.
2: Some corrections and improvements due to David Wasley, U. C. Berkeley
3: Compile with -DKOSHER to force exact conformity with the ANSI std.
4: */
5:
6: #ifdef KOSHER
7: #define IOSRETURN 1 /* to force ANSI std return on iostat= */
8: #endif
9:
10: /* TEMPORARY */
11: #define TYIOINT TYLONG
12: #define SZIOINT SZLONG
13:
14: #include "defs"
15:
16:
17: LOCAL char ioroutine[XL+1];
18:
19: LOCAL int ioendlab;
20: LOCAL int ioerrlab;
21: LOCAL int iostest;
22: LOCAL int iosreturn;
23: LOCAL int jumplab;
24: LOCAL int skiplab;
25: LOCAL int ioformatted;
26:
27: #define UNFORMATTED 0
28: #define FORMATTED 1
29: #define LISTDIRECTED 2
30:
31: #define V(z) ioc[z].iocval
32:
33: #define IOALL 07777
34:
35: LOCAL struct Ioclist
36: {
37: char *iocname;
38: int iotype;
39: expptr iocval;
40: } ioc[ ] =
41: {
42: { "", 0 },
43: { "unit", IOALL },
44: { "fmt", M(IOREAD) | M(IOWRITE) },
45: { "err", IOALL },
46: #ifdef KOSHER
47: { "end", M(IOREAD) },
48: #else
49: { "end", M(IOREAD) | M(IOWRITE) },
50: #endif
51: { "iostat", IOALL },
52: { "rec", M(IOREAD) | M(IOWRITE) },
53: { "recl", M(IOOPEN) | M(IOINQUIRE) },
54: { "file", M(IOOPEN) | M(IOINQUIRE) },
55: { "status", M(IOOPEN) | M(IOCLOSE) },
56: { "access", M(IOOPEN) | M(IOINQUIRE) },
57: { "form", M(IOOPEN) | M(IOINQUIRE) },
58: { "blank", M(IOOPEN) | M(IOINQUIRE) },
59: { "exist", M(IOINQUIRE) },
60: { "opened", M(IOINQUIRE) },
61: { "number", M(IOINQUIRE) },
62: { "named", M(IOINQUIRE) },
63: { "name", M(IOINQUIRE) },
64: { "sequential", M(IOINQUIRE) },
65: { "direct", M(IOINQUIRE) },
66: { "formatted", M(IOINQUIRE) },
67: { "unformatted", M(IOINQUIRE) },
68: { "nextrec", M(IOINQUIRE) }
69: } ;
70:
71: #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
72: #define MAXIO SZFLAG + 10*SZIOINT + 15*SZADDR
73:
74: #define IOSUNIT 1
75: #define IOSFMT 2
76: #define IOSERR 3
77: #define IOSEND 4
78: #define IOSIOSTAT 5
79: #define IOSREC 6
80: #define IOSRECL 7
81: #define IOSFILE 8
82: #define IOSSTATUS 9
83: #define IOSACCESS 10
84: #define IOSFORM 11
85: #define IOSBLANK 12
86: #define IOSEXIST 13
87: #define IOSOPENED 14
88: #define IOSNUMBER 15
89: #define IOSNAMED 16
90: #define IOSNAME 17
91: #define IOSSEQUENTIAL 18
92: #define IOSDIRECT 19
93: #define IOSFORMATTED 20
94: #define IOSUNFORMATTED 21
95: #define IOSNEXTREC 22
96:
97: #define IOSTP V(IOSIOSTAT)
98: #define IOSRW (iostmt==IOREAD || iostmt==IOWRITE)
99:
100:
101: /* offsets in generated structures */
102:
103: #define SZFLAG SZIOINT
104:
105: /* offsets for external READ and WRITE statements */
106:
107: #define XERR 0
108: #define XUNIT SZFLAG
109: #define XEND SZFLAG + SZIOINT
110: #define XFMT 2*SZFLAG + SZIOINT
111: #define XREC 2*SZFLAG + SZIOINT + SZADDR
112:
113: /* offsets for internal READ and WRITE statements */
114:
115: #define XIERR 0
116: #define XIUNIT SZFLAG
117: #define XIEND SZFLAG + SZADDR
118: #define XIFMT 2*SZFLAG + SZADDR
119: #define XIRLEN 2*SZFLAG + 2*SZADDR
120: #define XIRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
121: #define XIREC 2*SZFLAG + 2*SZADDR + 2*SZIOINT
122:
123: /* offsets for OPEN statements */
124:
125: #define XFNAME SZFLAG + SZIOINT
126: #define XFNAMELEN SZFLAG + SZIOINT + SZADDR
127: #define XSTATUS SZFLAG + 2*SZIOINT + SZADDR
128: #define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR
129: #define XFORMATTED SZFLAG + 2*SZIOINT + 3*SZADDR
130: #define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR
131: #define XBLANK SZFLAG + 3*SZIOINT + 4*SZADDR
132:
133: /* offset for CLOSE statement */
134:
135: #define XCLSTATUS SZFLAG + SZIOINT
136:
137: /* offsets for INQUIRE statement */
138:
139: #define XFILE SZFLAG + SZIOINT
140: #define XFILELEN SZFLAG + SZIOINT + SZADDR
141: #define XEXISTS SZFLAG + 2*SZIOINT + SZADDR
142: #define XOPEN SZFLAG + 2*SZIOINT + 2*SZADDR
143: #define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR
144: #define XNAMED SZFLAG + 2*SZIOINT + 4*SZADDR
145: #define XNAME SZFLAG + 2*SZIOINT + 5*SZADDR
146: #define XNAMELEN SZFLAG + 2*SZIOINT + 6*SZADDR
147: #define XQACCESS SZFLAG + 3*SZIOINT + 6*SZADDR
148: #define XQACCLEN SZFLAG + 3*SZIOINT + 7*SZADDR
149: #define XSEQ SZFLAG + 4*SZIOINT + 7*SZADDR
150: #define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR
151: #define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR
152: #define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR
153: #define XFORM SZFLAG + 6*SZIOINT + 9*SZADDR
154: #define XFORMLEN SZFLAG + 6*SZIOINT + 10*SZADDR
155: #define XFMTED SZFLAG + 7*SZIOINT + 10*SZADDR
156: #define XFMTEDLEN SZFLAG + 7*SZIOINT + 11*SZADDR
157: #define XUNFMT SZFLAG + 8*SZIOINT + 11*SZADDR
158: #define XUNFMTLEN SZFLAG + 8*SZIOINT + 12*SZADDR
159: #define XQRECL SZFLAG + 9*SZIOINT + 12*SZADDR
160: #define XNEXTREC SZFLAG + 9*SZIOINT + 13*SZADDR
161: #define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR
162: #define XQBLANKLEN SZFLAG + 9*SZIOINT + 15*SZADDR
163:
164: fmtstmt(lp)
165: register struct Labelblock *lp;
166: {
167: if(lp == NULL)
168: {
169: execerr("unlabeled format statement" , 0);
170: return(-1);
171: }
172: if(lp->labtype == LABUNKNOWN)
173: {
174: lp->labtype = LABFORMAT;
175: lp->labelno = newlabel();
176: }
177: else if(lp->labtype != LABFORMAT)
178: {
179: execerr("bad format number", 0);
180: return(-1);
181: }
182: return(lp->labelno);
183: }
184:
185:
186:
187: setfmt(lp)
188: struct Labelblock *lp;
189: {
190: ftnint n;
191: char *s, *lexline();
192:
193: s = lexline(&n);
194: preven(ALILONG);
195: prlabel(asmfile, lp->labelno);
196: putstr(asmfile, s, n);
197: flline();
198: }
199:
200:
201:
202: startioctl()
203: {
204: register int i;
205:
206: inioctl = YES;
207: nioctl = 0;
208: ioformatted = UNFORMATTED;
209: for(i = 1 ; i<=NIOS ; ++i)
210: V(i) = NULL;
211: }
212:
213:
214:
215: endioctl()
216: {
217: int i;
218: expptr p;
219:
220: inioctl = NO;
221: if(ioblkp == NULL)
222: ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, NULL);
223:
224: /* set up for error recovery */
225:
226: ioerrlab = ioendlab = jumplab = 0;
227: skiplab = iosreturn = NO;
228:
229: if(p = V(IOSEND))
230: if(ISICON(p))
231: ioendlab = mklabel(p->constblock.const.ci)->labelno;
232: else
233: err("bad end= clause");
234:
235: if(p = V(IOSERR))
236: if(ISICON(p))
237: ioerrlab = mklabel(p->constblock.const.ci)->labelno;
238: else
239: err("bad err= clause");
240:
241: if(IOSTP)
242: if(IOSTP->headblock.tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
243: {
244: err("iostat must be an integer variable");
245: frexpr(IOSTP);
246: IOSTP = NULL;
247: }
248: #ifdef IOSRETURN
249: else
250: iosreturn = YES;
251:
252: if(iosreturn && IOSRW && !(ioerrlab && ioendlab) )
253: {
254: jumplab = newlabel();
255: iostest = OPEQ;
256: if(ioerrlab || ioendlab) skiplab = YES;
257: }
258: else if(ioerrlab && !ioendlab)
259:
260: #else
261: if(ioerrlab && !ioendlab)
262: #endif
263: {
264: jumplab = ioerrlab;
265: iostest = IOSRW ? OPLE : OPEQ;
266: }
267: else if(!ioerrlab && ioendlab)
268: {
269: jumplab = ioendlab;
270: iostest = OPGE;
271: }
272: else if(ioerrlab && ioendlab)
273: {
274: iostest = OPEQ;
275: if(ioerrlab == ioendlab)
276: jumplab = ioerrlab;
277: else
278: {
279: if(!IOSTP) IOSTP = mktemp(TYINT, NULL);
280: jumplab = newlabel();
281: skiplab = YES;
282: }
283: }
284: /*else if(IOSTP) /* the standard requires this return! */
285: /* {
286: /* iosreturn = YES;
287: /* if(iostmt==IOREAD || iostmt==IOWRITE)
288: /* {
289: /* jumplab = newlabel();
290: /* iostest = OPEQ;
291: /* }
292: /* }
293: */
294:
295:
296: ioset(TYIOINT, XERR, ICON(ioerrlab!=0 || iosreturn) );
297:
298: switch(iostmt)
299: {
300: case IOOPEN:
301: dofopen(); break;
302:
303: case IOCLOSE:
304: dofclose(); break;
305:
306: case IOINQUIRE:
307: dofinquire(); break;
308:
309: case IOBACKSPACE:
310: dofmove("f_back"); break;
311:
312: case IOREWIND:
313: dofmove("f_rew"); break;
314:
315: case IOENDFILE:
316: dofmove("f_end"); break;
317:
318: case IOREAD:
319: case IOWRITE:
320: startrw(); break;
321:
322: default:
323: fatali("impossible iostmt %d", iostmt);
324: }
325: for(i = 1 ; i<=NIOS ; ++i)
326: if(i!=IOSIOSTAT && V(i)!=NULL)
327: frexpr(V(i));
328: }
329:
330:
331:
332: iocname()
333: {
334: register int i;
335: int found, mask;
336:
337: found = 0;
338: mask = M(iostmt);
339: for(i = 1 ; i <= NIOS ; ++i)
340: if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))
341: if(ioc[i].iotype & mask)
342: return(i);
343: else found = i;
344: if(found)
345: errstr("invalid control %s for statement", ioc[found].iocname);
346: else
347: errstr("unknown iocontrol %s", varstr(toklen, token) );
348: return(IOSBAD);
349: }
350:
351:
352: ioclause(n, p)
353: register int n;
354: register expptr p;
355: {
356: struct Ioclist *iocp;
357:
358: ++nioctl;
359: if(n == IOSBAD)
360: return;
361: if(n == IOSPOSITIONAL)
362: {
363: if(nioctl > IOSFMT)
364: {
365: err("illegal positional iocontrol");
366: return;
367: }
368: n = nioctl;
369: }
370:
371: if(p == NULL)
372: {
373: if(n == IOSUNIT)
374: p = (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
375: else if(n != IOSFMT)
376: {
377: err("illegal * iocontrol");
378: return;
379: }
380: }
381: if(n == IOSFMT)
382: ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
383:
384: iocp = & ioc[n];
385: if(iocp->iocval == NULL)
386: {
387: if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )
388: p = fixtype(p);
389: iocp->iocval = p;
390: }
391: else
392: errstr("iocontrol %s repeated", iocp->iocname);
393: }
394:
395: /* io list item */
396:
397: doio(list)
398: chainp list;
399: {
400: struct Exprblock *call0();
401: doiolist(list);
402: ioroutine[0] = 'e';
403: putiocall( call0(TYINT, ioroutine) );
404: }
405:
406:
407:
408:
409:
410: LOCAL doiolist(p0)
411: chainp p0;
412: {
413: chainp p;
414: register tagptr q;
415: register expptr qe;
416: register struct Nameblock *qn;
417: struct Addrblock *tp, *mkscalar();
418: int range;
419:
420: for (p = p0 ; p ; p = p->nextp)
421: {
422: q = p->datap;
423: if(q->headblock.tag == TIMPLDO)
424: {
425: exdo(range=newlabel(), q->impldoblock.varnp);
426: doiolist(q->impldoblock.datalist);
427: enddo(range);
428: free(q);
429: }
430: else {
431: if(q->headblock.tag==TPRIM && q->primblock.argsp==NULL
432: && q->primblock.namep->vdim!=NULL)
433: {
434: vardcl(qn = q->primblock.namep);
435: if(qn->vdim->nelt)
436: putio( fixtype(cpexpr(qn->vdim->nelt)),
437: mkscalar(qn) );
438: else
439: err("attempt to i/o array of unknown size");
440: }
441: else if(q->headblock.tag==TPRIM && q->primblock.argsp==NULL &&
442: (qe = memversion(q->primblock.namep)) )
443: putio(ICON(1),qe);
444: else if( (qe = fixtype(cpexpr(q)))->headblock.tag==TADDR)
445: putio(ICON(1), qe);
446: else if(qe->headblock.vtype != TYERROR)
447: {
448: if(iostmt == IOWRITE)
449: {
450: tp = mktemp(qe->headblock.vtype, qe->headblock.vleng);
451: puteq( cpexpr(tp), qe);
452: putio(ICON(1), tp);
453: }
454: else
455: err("non-left side in READ list");
456: }
457: frexpr(q);
458: }
459: }
460: frchain( &p0 );
461: }
462:
463:
464:
465:
466:
467: LOCAL putio(nelt, addr)
468: expptr nelt;
469: register expptr addr;
470: {
471: int type;
472: register struct Exprblock *q;
473:
474: type = addr->headblock.vtype;
475: if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
476: {
477: nelt = mkexpr(OPSTAR, ICON(2), nelt);
478: type -= (TYCOMPLEX-TYREAL);
479: }
480:
481: /* pass a length with every item. for noncharacter data, fake one */
482: if(type != TYCHAR)
483: {
484: if( ISCONST(addr) )
485: addr = putconst(addr);
486: addr->headblock.vtype = TYCHAR;
487: addr->headblock.vleng = ICON( typesize[type] );
488: }
489:
490: nelt = fixtype( mkconv(TYLENG,nelt) );
491: if(ioformatted == LISTDIRECTED)
492: q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr);
493: else
494: q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"),
495: nelt, addr);
496: putiocall(q);
497: }
498:
499:
500:
501:
502: endio()
503: {
504: if(skiplab)
505: {
506: putlabel(jumplab);
507: if(ioendlab) putif( mkexpr(OPGE, cpexpr(IOSTP), ICON(0)), ioendlab);
508: if(ioerrlab) putif( mkexpr(OPLE, cpexpr(IOSTP), ICON(0)), ioerrlab);
509: }
510: else if(iosreturn && jumplab)
511: putlabel(jumplab);
512: if(IOSTP)
513: frexpr(IOSTP);
514: }
515:
516:
517:
518: LOCAL putiocall(q)
519: register struct Exprblock *q;
520: {
521: if(IOSTP)
522: {
523: q->vtype = TYINT;
524: q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q));
525: }
526:
527: if(jumplab)
528: putif( mkexpr(iostest, q, ICON(0) ), jumplab);
529: else
530: putexpr(q);
531: }
532:
533:
534: startrw()
535: {
536: register expptr p;
537: register struct Nameblock *np;
538: register struct Addrblock *unitp, *nump;
539: struct Constblock *mkaddcon();
540: int k, fmtoff;
541: int intfile, sequential;
542:
543: intfile = NO;
544: if(p = V(IOSUNIT))
545: {
546: if( ISINT(p->headblock.vtype) )
547: ioset(TYIOINT, XUNIT, cpexpr(p) );
548: else if(p->headblock.vtype == TYCHAR)
549: {
550: intfile = YES;
551: if(p->headblock.tag==TPRIM && p->primblock.argsp==NULL &&
552: (np = p->primblock.namep)->vdim!=NULL)
553: {
554: vardcl(np);
555: if(np->vdim->nelt)
556: nump = cpexpr(np->vdim->nelt);
557: else
558: {
559: err("attempt to use internal unit array of unknown size");
560: nump = ICON(1);
561: }
562: unitp = mkscalar(np);
563: }
564: else {
565: nump = ICON(1);
566: unitp = fixtype(cpexpr(p));
567: }
568: ioset(TYIOINT, XIRNUM, nump);
569: ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
570: ioset(TYADDR, XIUNIT, addrof(unitp) );
571: }
572: }
573: else
574: err("bad unit specifier");
575:
576: sequential = YES;
577: if(p = V(IOSREC))
578: if( ISINT(p->headblock.vtype) )
579: {
580: ioset(TYIOINT, (intfile ? XIREC : XREC), cpexpr(p) );
581: sequential = NO;
582: }
583: else
584: err("bad REC= clause");
585:
586: ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(ioendlab!=0 || iosreturn) );
587:
588: fmtoff = (intfile ? XIFMT : XFMT);
589:
590: if(p = V(IOSFMT))
591: {
592: if(p->headblock.tag==TPRIM && p->primblock.argsp==NULL)
593: {
594: vardcl(np = p->primblock.namep);
595: if(np->vdim)
596: {
597: ioset(TYADDR, fmtoff, addrof(mkscalar(np)) );
598: goto endfmt;
599: }
600: if( ISINT(np->vtype) )
601: {
602: ioset(TYADDR, fmtoff, p);
603: goto endfmt;
604: }
605: }
606: p = V(IOSFMT) = fixtype(p);
607: if(p->headblock.vtype == TYCHAR)
608: ioset(TYADDR, fmtoff, addrof(cpexpr(p)) );
609: else if( ISICON(p) )
610: {
611: if( (k = fmtstmt( mklabel(p->constblock.const.ci) )) > 0 )
612: ioset(TYADDR, fmtoff, mkaddcon(k) );
613: else
614: ioformatted = UNFORMATTED;
615: }
616: else {
617: err("bad format descriptor");
618: ioformatted = UNFORMATTED;
619: }
620: }
621: else
622: ioset(TYADDR, fmtoff, ICON(0) );
623:
624: endfmt:
625: if(intfile && ioformatted==UNFORMATTED)
626: err("unformatted internal I/O not allowed");
627: if(!sequential && ioformatted==LISTDIRECTED)
628: err("direct list-directed I/O not allowed");
629:
630: ioroutine[0] = 's';
631: ioroutine[1] = '_';
632: ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w');
633: ioroutine[3] = (sequential ? 's' : 'd');
634: ioroutine[4] = "ufl" [ioformatted];
635: ioroutine[5] = (intfile ? 'i' : 'e');
636: ioroutine[6] = '\0';
637: putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) ));
638: }
639:
640:
641:
642: LOCAL dofopen()
643: {
644: register expptr p;
645:
646: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
647: ioset(TYIOINT, XUNIT, cpexpr(p) );
648: else
649: err("bad unit in open");
650: if( (p = V(IOSFILE)) )
651: if(p->headblock.vtype == TYCHAR)
652: ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
653: else
654: err("bad file in open");
655:
656: iosetc(XFNAME, p);
657:
658: if(p = V(IOSRECL))
659: if( ISINT(p->headblock.vtype) )
660: ioset(TYIOINT, XRECLEN, cpexpr(p) );
661: else
662: err("bad recl");
663: else
664: ioset(TYIOINT, XRECLEN, ICON(0) );
665:
666: iosetc(XSTATUS, V(IOSSTATUS));
667: iosetc(XACCESS, V(IOSACCESS));
668: iosetc(XFORMATTED, V(IOSFORM));
669: iosetc(XBLANK, V(IOSBLANK));
670:
671: putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) ));
672: }
673:
674:
675: LOCAL dofclose()
676: {
677: register expptr p;
678:
679: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
680: {
681: ioset(TYIOINT, XUNIT, cpexpr(p) );
682: iosetc(XCLSTATUS, V(IOSSTATUS));
683: putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) );
684: }
685: else
686: err("bad unit in close statement");
687: }
688:
689:
690: LOCAL dofinquire()
691: {
692: register expptr p;
693: if(p = V(IOSUNIT))
694: {
695: if( V(IOSFILE) )
696: err("inquire by unit or by file, not both");
697: ioset(TYIOINT, XUNIT, cpexpr(p) );
698: }
699: else if( ! V(IOSFILE) )
700: err("must inquire by unit or by file");
701: iosetlc(IOSFILE, XFILE, XFILELEN);
702: iosetip(IOSEXISTS, XEXISTS);
703: iosetip(IOSOPENED, XOPEN);
704: iosetip(IOSNUMBER, XNUMBER);
705: iosetip(IOSNAMED, XNAMED);
706: iosetlc(IOSNAME, XNAME, XNAMELEN);
707: iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
708: iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
709: iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
710: iosetlc(IOSFORM, XFORM, XFORMLEN);
711: iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
712: iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
713: iosetip(IOSRECL, XQRECL);
714: iosetip(IOSNEXTREC, XNEXTREC);
715: iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
716:
717: putiocall( call1(TYINT, "f_inqu", cpexpr(ioblkp) ));
718: }
719:
720:
721:
722: LOCAL dofmove(subname)
723: char *subname;
724: {
725: register expptr p;
726:
727: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
728: {
729: ioset(TYIOINT, XUNIT, cpexpr(p) );
730: putiocall( call1(TYINT, subname, cpexpr(ioblkp) ));
731: }
732: else
733: err("bad unit in I/O motion statement");
734: }
735:
736:
737:
738: LOCAL ioset(type, offset, p)
739: int type, offset;
740: expptr p;
741: {
742: register struct Addrblock *q;
743:
744: q = cpexpr(ioblkp);
745: q->vtype = type;
746: q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) );
747: puteq(q, p);
748: }
749:
750:
751:
752:
753: LOCAL iosetc(offset, p)
754: int offset;
755: register expptr p;
756: {
757: if(p == NULL)
758: ioset(TYADDR, offset, ICON(0) );
759: else if(p->headblock.vtype == TYCHAR)
760: ioset(TYADDR, offset, addrof(cpexpr(p) ));
761: else
762: err("non-character control clause");
763: }
764:
765:
766:
767: LOCAL iosetip(i, offset)
768: int i, offset;
769: {
770: register expptr p;
771:
772: if(p = V(i))
773: if(p->headblock.tag==TADDR &&
774: ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) )
775: ioset(TYADDR, offset, addrof(cpexpr(p)) );
776: else
777: errstr("impossible inquire parameter %s", ioc[i].iocname);
778: else
779: ioset(TYADDR, offset, ICON(0) );
780: }
781:
782:
783:
784: LOCAL iosetlc(i, offp, offl)
785: int i, offp, offl;
786: {
787: register expptr p;
788: if( (p = V(i)) && p->headblock.vtype==TYCHAR)
789: ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );
790: iosetc(offp, p);
791: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.