1 /****************************************************************
2 Copyright 1990, 1991 by AT&T Bell Laboratories and Bellcore.
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T Bell Laboratories or
10 Bellcore or any of their entities not be used in advertising or
11 publicity pertaining to distribution of the software without
12 specific, written prior permission.
14 AT&T and Bellcore disclaim all warranties with regard to this
15 software, including all implied warranties of merchantability
16 and fitness. In no event shall AT&T or Bellcore be liable for
17 any special, indirect or consequential damages or any damages
18 whatsoever resulting from loss of use, data or profits, whether
19 in an action of contract, negligence or other tortious action,
20 arising out of or in connection with the use or performance of
22 ****************************************************************/
24 /* Routines to generate code for I/O statements.
25 Some corrections and improvements due to David Wasley, U. C. Berkeley
29 #define TYIOINT TYLONG
30 #define SZIOINT SZLONG
38 LOCAL void dofclose(), dofinquire(), dofinquire(), dofmove(), dofopen(),
39 doiolist(), ioset(), ioseta(), iosetc(), iosetip(), iosetlc(),
45 LOCAL char ioroutine[12];
53 LOCAL int ioformatted;
54 LOCAL int statstruct = NO;
55 LOCAL struct Labelblock *skiplabel;
60 #define LISTDIRECTED 2
61 #define NAMEDIRECTED 3
63 #define V(z) ioc[z].iocval
77 { "fmt", M(IOREAD) | M(IOWRITE) },
81 { "rec", M(IOREAD) | M(IOWRITE) },
82 { "recl", M(IOOPEN) | M(IOINQUIRE) },
83 { "file", M(IOOPEN) | M(IOINQUIRE) },
84 { "status", M(IOOPEN) | M(IOCLOSE) },
85 { "access", M(IOOPEN) | M(IOINQUIRE) },
86 { "form", M(IOOPEN) | M(IOINQUIRE) },
87 { "blank", M(IOOPEN) | M(IOINQUIRE) },
88 { "exist", M(IOINQUIRE) },
89 { "opened", M(IOINQUIRE) },
90 { "number", M(IOINQUIRE) },
91 { "named", M(IOINQUIRE) },
92 { "name", M(IOINQUIRE) },
93 { "sequential", M(IOINQUIRE) },
94 { "direct", M(IOINQUIRE) },
95 { "formatted", M(IOINQUIRE) },
96 { "unformatted", M(IOINQUIRE) },
97 { "nextrec", M(IOINQUIRE) },
98 { "nml", M(IOREAD) | M(IOWRITE) }
101 #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
102 #define MAXIO SZFLAG + 10*SZIOINT + 15*SZADDR
104 /* #define IOSUNIT 1 */
105 /* #define IOSFMT 2 */
121 #define IOSSEQUENTIAL 18
123 #define IOSFORMATTED 20
124 #define IOSUNFORMATTED 21
125 #define IOSNEXTREC 22
128 #define IOSTP V(IOSIOSTAT)
131 /* offsets in generated structures */
133 #define SZFLAG SZIOINT
135 /* offsets for external READ and WRITE statements */
139 #define XEND SZFLAG + SZIOINT
140 #define XFMT 2*SZFLAG + SZIOINT
141 #define XREC 2*SZFLAG + SZIOINT + SZADDR
142 #define XRLEN 2*SZFLAG + 2*SZADDR
143 #define XRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
145 /* offsets for internal READ and WRITE statements */
148 #define XIUNIT SZFLAG
149 #define XIEND SZFLAG + SZADDR
150 #define XIFMT 2*SZFLAG + SZADDR
151 #define XIRLEN 2*SZFLAG + 2*SZADDR
152 #define XIRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
153 #define XIREC 2*SZFLAG + 2*SZADDR + 2*SZIOINT
155 /* offsets for OPEN statements */
157 #define XFNAME SZFLAG + SZIOINT
158 #define XFNAMELEN SZFLAG + SZIOINT + SZADDR
159 #define XSTATUS SZFLAG + 2*SZIOINT + SZADDR
160 #define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR
161 #define XFORMATTED SZFLAG + 2*SZIOINT + 3*SZADDR
162 #define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR
163 #define XBLANK SZFLAG + 3*SZIOINT + 4*SZADDR
165 /* offset for CLOSE statement */
167 #define XCLSTATUS SZFLAG + SZIOINT
169 /* offsets for INQUIRE statement */
171 #define XFILE SZFLAG + SZIOINT
172 #define XFILELEN SZFLAG + SZIOINT + SZADDR
173 #define XEXISTS SZFLAG + 2*SZIOINT + SZADDR
174 #define XOPEN SZFLAG + 2*SZIOINT + 2*SZADDR
175 #define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR
176 #define XNAMED SZFLAG + 2*SZIOINT + 4*SZADDR
177 #define XNAME SZFLAG + 2*SZIOINT + 5*SZADDR
178 #define XNAMELEN SZFLAG + 2*SZIOINT + 6*SZADDR
179 #define XQACCESS SZFLAG + 3*SZIOINT + 6*SZADDR
180 #define XQACCLEN SZFLAG + 3*SZIOINT + 7*SZADDR
181 #define XSEQ SZFLAG + 4*SZIOINT + 7*SZADDR
182 #define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR
183 #define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR
184 #define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR
185 #define XFORM SZFLAG + 6*SZIOINT + 9*SZADDR
186 #define XFORMLEN SZFLAG + 6*SZIOINT + 10*SZADDR
187 #define XFMTED SZFLAG + 7*SZIOINT + 10*SZADDR
188 #define XFMTEDLEN SZFLAG + 7*SZIOINT + 11*SZADDR
189 #define XUNFMT SZFLAG + 8*SZIOINT + 11*SZADDR
190 #define XUNFMTLEN SZFLAG + 8*SZIOINT + 12*SZADDR
191 #define XQRECL SZFLAG + 9*SZIOINT + 12*SZADDR
192 #define XNEXTREC SZFLAG + 9*SZIOINT + 13*SZADDR
193 #define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR
194 #define XQBLANKLEN SZFLAG + 9*SZIOINT + 15*SZADDR
196 LOCAL char *cilist_names[] = {
204 LOCAL char *icilist_names[] = {
213 LOCAL char *olist_names[] = {
225 LOCAL char *cllist_names[] = {
231 LOCAL char *alist_names[] = {
236 LOCAL char *inlist_names[] = {
266 LOCAL char **io_fields;
268 #define zork(n,t) n, sizeof(n)/sizeof(char *) - 1, t
270 LOCAL io_setup io_stuff[] = {
271 zork(cilist_names, TYCILIST), /* external read/write */
272 zork(inlist_names, TYINLIST), /* inquire */
273 zork(olist_names, TYOLIST), /* open */
274 zork(cllist_names, TYCLLIST), /* close */
275 zork(alist_names, TYALIST), /* rewind */
276 zork(alist_names, TYALIST), /* backspace */
277 zork(alist_names, TYALIST), /* endfile */
278 zork(icilist_names,TYICILIST), /* internal read */
279 zork(icilist_names,TYICILIST) /* internal write */
286 register struct Labelblock *lp;
290 execerr("unlabeled format statement" , CNULL);
293 if(lp->labtype == LABUNKNOWN)
295 lp->labtype = LABFORMAT;
296 lp->labelno = newlabel();
298 else if(lp->labtype != LABFORMAT)
300 execerr("bad format number", CNULL);
308 struct Labelblock *lp;
311 char *s0, *lexline();
312 register char *s, *se, *t;
315 s0 = s = lexline(&n);
318 /* warn of trivial errors, e.g. " 11 CONTINUE" (one too few spaces) */
319 /* following FORMAT... */
322 warn("No (...) after FORMAT");
324 warni("%c rather than ( after FORMAT", *s);
325 else if (se[-1] != ')') {
327 while(--t > s && *t != ')') ;
329 warn("No ) at end of FORMAT statement");
330 else if (se - t > 30)
331 warn1("Extraneous text at end of FORMAT: ...%s", se-12);
333 warn1("Extraneous text at end of FORMAT: %s", t+1);
337 /* fix MYQUOTES (\002's) and \\'s */
349 lp->fmtstring = t = mem((int)(t - s + 1), 0);
379 ioformatted = UNFORMATTED;
380 for(i = 1 ; i<=NIOS ; ++i)
388 skiplabel = mklabel(rv);
389 skiplabel->labdefined = 1;
398 struct io_setup *ios;
402 /* set up for error recovery */
404 ioerrlab = ioendlab = skiplab = jumplab = 0;
408 execlab(ioendlab = p->constblock.Const.ci);
410 err("bad end= clause");
414 execlab(ioerrlab = p->constblock.Const.ci);
416 err("bad err= clause");
419 if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
421 err("iostat must be an integer variable");
430 if(ioerrlab && ioendlab && ioerrlab==ioendlab)
433 skiplab = jumplab = newiolabel();
436 if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
438 IOSTP = (expptr) mktmp(TYINT, ENULL);
439 skiplab = jumplab = newiolabel();
442 jumplab = (ioerrlab ? ioerrlab : ioendlab);
445 else if(iostmt == IOWRITE)
447 if(IOSTP && !ioerrlab)
448 skiplab = jumplab = newiolabel();
455 endbit = IOSTP!=NULL || ioendlab!=0; /* for use in startrw() */
456 errbit = IOSTP!=NULL || ioerrlab!=0;
457 if (jumplab && !IOSTP)
458 IOSTP = (expptr) mktmp(TYINT, ENULL);
460 if(iostmt!=IOREAD && iostmt!=IOWRITE)
462 ios = io_stuff + iostmt;
463 io_fields = ios->fields;
464 ioblkp = io_structs[iostmt];
466 io_structs[iostmt] = ioblkp =
467 autovar(1, ios->type, ENULL, "");
468 ioset(TYIOINT, XERR, ICON(errbit));
503 fatali("impossible iostmt %d", iostmt);
505 for(i = 1 ; i<=NIOS ; ++i)
506 if(i!=IOSIOSTAT && V(i)!=NULL)
519 for(i = 1 ; i <= NIOS ; ++i)
520 if(!strcmp(ioc[i].iocname, token))
521 if(ioc[i].iotype & mask)
528 if (iostmt == IOOPEN && !strcmp(ioc[i].iocname, "name")) {
529 NOEXT("open with \"name=\" treated as \"file=\"");
530 for(i = 1; strcmp(ioc[i].iocname, "file"); i++);
533 errstr("invalid control %s for statement", ioc[found].iocname);
536 errstr("unknown iocontrol %s", token);
545 struct Ioclist *iocp;
550 if(n == IOSPOSITIONAL)
554 if (iostmt == IOOPEN) {
556 NOEXT("file= specifier omitted from open");
558 else if (iostmt < IOREAD)
564 err("illegal positional iocontrol");
568 else if (n == IOSNML)
574 p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
577 err("illegal * iocontrol");
582 ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
585 if(iocp->iocval == NULL)
587 if(n!=IOSFMT && ( n!=IOSUNIT || (p && p->headblock.vtype!=TYCHAR) ) )
589 else if (p && p->tag == TPRIM
590 && p->primblock.namep->vclass == CLUNKNOWN) {
591 /* kludge made necessary by attempt to infer types
592 * for untyped external parameters: given an error
593 * in calling sequences, an integer argument might
594 * tentatively be assumed TYCHAR; this would otherwise
595 * be corrected too late in startrw after startrw
596 * had decided this to be an internal file.
598 vardcl(p->primblock.namep);
599 p->primblock.vtype = p->primblock.namep->vtype;
604 errstr("iocontrol %s repeated", iocp->iocname);
614 if(ioformatted == NAMEDIRECTED)
617 err("no I/O list allowed in NAMELIST read/write");
623 if (skiplab || ioroutine[4] == 'l')
625 putiocall( call0(TYINT, ioroutine) );
641 Addrp tp, mkscalar();
643 extern char *ohalign;
645 for (p = p0 ; p ; p = p->nextp)
647 q = (tagptr)p->datap;
648 if(q->tag == TIMPLDO)
650 exdo(range=newlabel(), (Namep)0,
651 q->impldoblock.impdospec);
652 doiolist(q->impldoblock.datalist);
657 if(q->tag==TPRIM && q->primblock.argsp==NULL
658 && q->primblock.namep->vdim!=NULL)
660 vardcl(qn = q->primblock.namep);
662 putio( fixtype(cpexpr(qn->vdim->nelt)),
663 (expptr)mkscalar(qn) );
667 err("attempt to i/o array of unknown size");
669 else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
670 (qe = (expptr) memversion(q->primblock.namep)) )
672 else if (ISCONST(q) && q->constblock.vtype == TYCHAR) {
674 putio(ICON(1), qe = fixtype(cpexpr(q)));
677 else if(((qe = fixtype(cpexpr(q)))->tag==TADDR &&
678 (qe->addrblock.uname_tag != UNAM_CONST ||
679 !ISCOMPLEX(qe -> addrblock.vtype))) ||
680 (qe -> tag == TCONST && !ISCOMPLEX(qe ->
682 if (qe -> tag == TCONST)
683 qe = (expptr) putconst((Constp)qe);
686 else if(qe->headblock.vtype != TYERROR)
688 if(iostmt == IOWRITE)
696 cpexpr(qe->headblock.vleng);
697 tp = mktmp(qe->headblock.vtype,
701 tp = mktmp(qe->headblock.vtype,
702 qe->headblock.vleng);
703 puteq( cpexpr((expptr)tp), qe);
704 if(qvl) /* put right length on block */
709 putio(ICON(1), (expptr)tp);
712 err("non-left side in READ list");
720 int iocalladdr = TYADDR; /* for fixing TYADDR in saveargtypes */
725 register expptr addr;
729 extern Constp mkconst();
730 register Addrp c = 0;
732 type = addr->headblock.vtype;
733 if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
735 nelt = mkexpr(OPSTAR, ICON(2), nelt);
736 type -= (TYCOMPLEX-TYREAL);
739 /* pass a length with every item. for noncharacter data, fake one */
744 addr = (expptr) putconst((Constp)addr);
745 c = ALLOC(Addrblock);
751 c->memoffset = ICON(0);
752 c->uname_tag = UNAM_IDENT;
754 sprintf(c->user.ident, "(ftnlen)sizeof(%s)", typename[type]);
755 addr = mkexpr(OPCHARCAST, addr, ENULL);
758 nelt = fixtype( mkconv(tyioint,nelt) );
759 if(ioformatted == LISTDIRECTED) {
760 expptr mc = mkconv(tyioint, ICON(type));
761 q = c ? call4(TYINT, "do_lio", mc, nelt, addr, (expptr)c)
762 : call3(TYINT, "do_lio", mc, nelt, addr);
765 char *s = ioformatted==FORMATTED ? "do_fio" : "do_uio";
766 q = c ? call3(TYINT, s, nelt, addr, (expptr)c)
767 : call2(TYINT, s, nelt, addr);
779 extern void p1_label();
783 if (ioformatted != NAMEDIRECTED)
784 p1_label((long)(skiplabel - labeltab));
786 exif( mkexpr(OPLT, cpexpr(IOSTP), ICON(0)));
787 exgoto(execlab(ioendlab));
791 exif( mkexpr(iostmt==IOREAD||iostmt==IOWRITE
793 cpexpr(IOSTP), ICON(0)));
794 exgoto(execlab(ioerrlab));
812 tyint = tyioint; /* for -I2 and -i2 */
816 q->headblock.vtype = TYINT;
817 q = fixexpr((Exprp)mkexpr(OPASSIGN, cpexpr(IOSTP), q));
821 exif(mkexpr(OPNE, cpexpr(IOSTP), ICON(0)));
822 exgoto(execlab(jumplab));
834 register char *s, *t;
835 extern chainp assigned_fmts;
839 assigned_fmts = mkchain((char *)np, assigned_fmts);
841 k = strlen(s = np->fvarname);
842 if (k < IDENT_LEN - 4) {
843 q->uname_tag = UNAM_IDENT;
847 q->uname_tag = UNAM_CHARP;
848 q->user.Charp = t = mem(k + 5,0);
850 sprintf(t, "%s_fmt", s);
853 LOCAL Addrp asg_addr(p)
859 badtag("asg_addr", p->tag);
860 q = ALLOC(Addrblock);
866 q->memoffset = ICON(0);
867 fmtname(p->primblock.namep, q);
875 register Addrp unitp, fmtp, recp;
876 register expptr nump;
880 flag intfile, sequential, ok, varfmt;
881 struct io_setup *ios;
883 /* First look at all the parameters and determine what is to be done */
891 if( ISINT(p->headblock.vtype) ) {
893 unitp = (Addrp) cpexpr(p);
895 else if(p->headblock.vtype == TYCHAR)
897 if (nioctl == 1 && iostmt == IOREAD) {
898 /* kludge to recognize READ(format expr) */
900 V(IOSUNIT) = p = (expptr) IOSTDIN;
901 ioformatted = FORMATTED;
905 if(p->tag==TPRIM && p->primblock.argsp==NULL &&
906 (np = p->primblock.namep)->vdim!=NULL)
911 nump = (expptr) cpexpr(np->vdim->nelt);
912 if( ! ISCONST(nump) )
917 err("attempt to use internal unit array of unknown size");
921 unitp = mkscalar(np);
925 unitp = (Addrp /*pjw */) fixtype(cpexpr(p));
927 if(! isstatic((expptr)unitp) )
931 err("unit specifier not of type integer or character");
937 err("bad unit specifier");
943 if( ISINT(p->headblock.vtype) )
945 recp = (Addrp) cpexpr(p);
949 err("bad REC= clause");
960 if(p->tag==TPRIM && p->primblock.argsp==NULL)
962 np = p->primblock.namep;
963 if(np->vclass == CLNAMELIST)
965 ioformatted = NAMEDIRECTED;
966 fmtp = (Addrp) fixtype(p);
967 V(IOSFMT) = (expptr)fmtp;
975 if( ! ONEOF(np->vstg, MSKSTATIC) )
980 if( ISINT(np->vtype) ) /* ASSIGNed label */
988 p = V(IOSFMT) = fixtype(p);
989 if(p->headblock.vtype == TYCHAR
990 /* Since we allow write(6,n) */
991 /* we may as well allow write(6,n(2)) */
992 || p->tag == TADDR && ISINT(p->addrblock.vtype))
996 fmtp = (Addrp) cpexpr(p);
1000 struct Labelblock *lp;
1001 lp = mklabel(p->constblock.Const.ci);
1002 if (fmtstmt(lp) > 0)
1004 fmtp = (Addrp)mkaddcon(lp->stateno);
1005 /* lp->stateno for names fmt_nnn */
1010 ioformatted = UNFORMATTED;
1013 err("bad format descriptor");
1014 ioformatted = UNFORMATTED;
1023 if (ioformatted==UNFORMATTED) {
1024 err("unformatted internal I/O not allowed");
1028 err("direct internal I/O not allowed");
1032 if(!sequential && ioformatted==LISTDIRECTED)
1034 err("direct list-directed I/O not allowed");
1037 if(!sequential && ioformatted==NAMEDIRECTED)
1039 err("direct namelist I/O not allowed");
1049 Now put out the I/O structure, statically if all the clauses
1050 are constants, dynamically otherwise
1054 ios = io_stuff + iostmt;
1061 io_fields = ios->fields;
1064 ioblkp = ALLOC(Addrblock);
1065 ioblkp->tag = TADDR;
1066 ioblkp->vtype = ios->type;
1067 ioblkp->vclass = CLVAR;
1068 ioblkp->vstg = STGINIT;
1069 ioblkp->memno = ++lastvarno;
1070 ioblkp->memoffset = ICON(0);
1071 ioblkp -> uname_tag = UNAM_IDENT;
1073 temp_name("io_", lastvarno, ioblkp->user.ident)); }
1074 else if(!(ioblkp = io_structs[iostmt1]))
1075 io_structs[iostmt1] = ioblkp =
1076 autovar(1, ios->type, ENULL, "");
1078 ioset(TYIOINT, XERR, ICON(errbit));
1079 if(iostmt == IOREAD)
1080 ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
1084 ioset(TYIOINT, XIRNUM, nump);
1085 ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
1086 ioseta(XIUNIT, unitp);
1089 ioset(TYIOINT, XUNIT, (expptr) unitp);
1092 ioset(TYIOINT, /* intfile ? XIREC : */ XREC, (expptr) recp);
1095 ioseta( intfile ? XIFMT : XFMT , fmtp);
1097 ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
1101 ioroutine[2] = iostmt==IOREAD ? 'r' : 'w';
1102 ioroutine[3] = "ds"[sequential];
1103 ioroutine[4] = "ufln"[ioformatted];
1104 ioroutine[5] = "ei"[intfile];
1105 ioroutine[6] = '\0';
1107 putiocall( call1(TYINT, ioroutine, cpexpr((expptr)ioblkp) ));
1111 frexpr((expptr)ioblkp);
1113 ioblkp = 0; /* unnecessary */
1124 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1125 ioset(TYIOINT, XUNIT, cpexpr(p) );
1127 err("bad unit in open");
1128 if( (p = V(IOSFILE)) )
1129 if(p->headblock.vtype == TYCHAR)
1130 ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
1132 err("bad file in open");
1137 if( ISINT(p->headblock.vtype) )
1138 ioset(TYIOINT, XRECLEN, cpexpr(p) );
1142 ioset(TYIOINT, XRECLEN, ICON(0) );
1144 iosetc(XSTATUS, V(IOSSTATUS));
1145 iosetc(XACCESS, V(IOSACCESS));
1146 iosetc(XFORMATTED, V(IOSFORM));
1147 iosetc(XBLANK, V(IOSBLANK));
1149 putiocall( call1(TYINT, "f_open", cpexpr((expptr)ioblkp) ));
1158 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1160 ioset(TYIOINT, XUNIT, cpexpr(p) );
1161 iosetc(XCLSTATUS, V(IOSSTATUS));
1162 putiocall( call1(TYINT, "f_clos", cpexpr((expptr)ioblkp)) );
1165 err("bad unit in close statement");
1176 err("inquire by unit or by file, not both");
1177 ioset(TYIOINT, XUNIT, cpexpr(p) );
1179 else if( ! V(IOSFILE) )
1180 err("must inquire by unit or by file");
1181 iosetlc(IOSFILE, XFILE, XFILELEN);
1182 iosetip(IOSEXISTS, XEXISTS);
1183 iosetip(IOSOPENED, XOPEN);
1184 iosetip(IOSNUMBER, XNUMBER);
1185 iosetip(IOSNAMED, XNAMED);
1186 iosetlc(IOSNAME, XNAME, XNAMELEN);
1187 iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
1188 iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
1189 iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
1190 iosetlc(IOSFORM, XFORM, XFORMLEN);
1191 iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
1192 iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
1193 iosetip(IOSRECL, XQRECL);
1194 iosetip(IOSNEXTREC, XNEXTREC);
1195 iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
1197 putiocall( call1(TYINT, "f_inqu", cpexpr((expptr)ioblkp) ));
1208 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1210 ioset(TYIOINT, XUNIT, cpexpr(p) );
1211 putiocall( call1(TYINT, subname, cpexpr((expptr)ioblkp) ));
1214 err("bad unit in I/O motion statement");
1217 static int ioset_assign = OPASSIGN;
1220 ioset(type, offset, p)
1225 if(statstruct && ISCONST(p)) {
1228 case TYADDR: /* stmt label */
1235 badtype("ioset", type);
1237 iob_list->fields[offset] =
1238 string_num(s, p->constblock.Const.ci);
1244 q = ALLOC(Addrblock);
1250 q->memoffset = ICON(0);
1251 q->uname_tag = UNAM_IDENT;
1252 sprintf(q->user.ident, "%s.%s",
1253 statstruct ? iob_list->name : ioblkp->user.ident,
1254 io_fields[offset + 1]);
1255 if (type == TYADDR && p->tag == TCONST
1256 && p->constblock.vtype == TYADDR) {
1259 p1 = ALLOC(Addrblock);
1262 p1->vstg = STGAUTO; /* wrong, but who cares? */
1265 p1->memoffset = ICON(0);
1266 p1->uname_tag = UNAM_IDENT;
1267 sprintf(p1->user.ident, "fmt_%ld",
1268 p->constblock.Const.ci);
1272 if (type == TYADDR && p->headblock.vtype == TYCHAR)
1274 putexpr(mkexpr(ioset_assign, (expptr)q, p));
1286 extern Addrp putchop();
1289 ioset(TYADDR, offset, ICON(0) );
1290 else if(p->headblock.vtype == TYCHAR) {
1291 p = putx(fixtype((expptr)putchop(cpexpr(p))));
1292 ioset(TYADDR, offset, addrof(p));
1295 err("non-character control clause");
1306 static char who[] = "ioseta";
1311 char buf[24], buf1[24];
1313 extern int usedefsforcommon;
1319 if (p->tag != TADDR)
1320 badtag(who, p->tag);
1322 switch(p->uname_tag) {
1325 if (mo->tag != TCONST)
1326 badtag("ioseta/memoffset", mo->tag);
1329 ci = mo->constblock.Const.ci - np->voffset;
1330 if (np->vstg == STGCOMMON
1332 && !usedefsforcommon) {
1333 comm = &extsymtab[np->vardesc.varno];
1334 sprintf(buf, "%d.", comm->curno);
1335 k = strlen(buf) + strlen(comm->cextname)
1336 + strlen(np->cvarname);
1338 sprintf(buf1, "+%ld", ci);
1344 sprintf(s, "%s%s%s%s", comm->cextname, buf,
1345 np->cvarname, buf1);
1348 sprintf(buf,"%ld", ci);
1349 s1 = p->user.name->cvarname;
1350 k = strlen(buf) + strlen(s1);
1351 sprintf(s = mem(k+2,0), "%s+%s", s1, buf);
1354 s = cpstring(np->cvarname);
1357 s = tostring(p->user.Const.ccp1.ccp0,
1358 (int)p->vleng->constblock.Const.ci);
1361 badthing("uname_tag", who, p->uname_tag);
1363 /* kludge for Hollerith */
1364 if (p->vtype != TYCHAR) {
1365 s1 = mem(strlen(s)+10,0);
1366 sprintf(s1, "(char *)%s%s", p->isarray ? "" : "&", s);
1369 iob_list->fields[offset] = s;
1374 else if (p->vtype != TYCHAR) {
1375 NOEXT("non-character variable as format or internal unit");
1376 e = mkexpr(OPCHARCAST, (expptr)p, ENULL);
1379 e = addrof((expptr)p);
1380 ioset(TYADDR, offset, e);
1395 ONEOF(p->addrblock.vtype, inqmask) ) {
1396 ioset_assign = OPASSIGNI;
1397 ioset(TYADDR, offset, addrof(cpexpr(p)) );
1398 ioset_assign = OPASSIGN;
1401 errstr("impossible inquire parameter %s", ioc[i].iocname);
1403 ioset(TYADDR, offset, ICON(0) );
1409 iosetlc(i, offp, offl)
1413 if( (p = V(i)) && p->headblock.vtype==TYCHAR)
1414 ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );