1 /****************************************************************
2 Copyright 1990 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) }
100 #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)
101 #define MAXIO SZFLAG + 10*SZIOINT + 15*SZADDR
103 /* #define IOSUNIT 1 */
104 /* #define IOSFMT 2 */
120 #define IOSSEQUENTIAL 18
122 #define IOSFORMATTED 20
123 #define IOSUNFORMATTED 21
124 #define IOSNEXTREC 22
126 #define IOSTP V(IOSIOSTAT)
129 /* offsets in generated structures */
131 #define SZFLAG SZIOINT
133 /* offsets for external READ and WRITE statements */
137 #define XEND SZFLAG + SZIOINT
138 #define XFMT 2*SZFLAG + SZIOINT
139 #define XREC 2*SZFLAG + SZIOINT + SZADDR
140 #define XRLEN 2*SZFLAG + 2*SZADDR
141 #define XRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
143 /* offsets for internal READ and WRITE statements */
146 #define XIUNIT SZFLAG
147 #define XIEND SZFLAG + SZADDR
148 #define XIFMT 2*SZFLAG + SZADDR
149 #define XIRLEN 2*SZFLAG + 2*SZADDR
150 #define XIRNUM 2*SZFLAG + 2*SZADDR + SZIOINT
151 #define XIREC 2*SZFLAG + 2*SZADDR + 2*SZIOINT
153 /* offsets for OPEN statements */
155 #define XFNAME SZFLAG + SZIOINT
156 #define XFNAMELEN SZFLAG + SZIOINT + SZADDR
157 #define XSTATUS SZFLAG + 2*SZIOINT + SZADDR
158 #define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR
159 #define XFORMATTED SZFLAG + 2*SZIOINT + 3*SZADDR
160 #define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR
161 #define XBLANK SZFLAG + 3*SZIOINT + 4*SZADDR
163 /* offset for CLOSE statement */
165 #define XCLSTATUS SZFLAG + SZIOINT
167 /* offsets for INQUIRE statement */
169 #define XFILE SZFLAG + SZIOINT
170 #define XFILELEN SZFLAG + SZIOINT + SZADDR
171 #define XEXISTS SZFLAG + 2*SZIOINT + SZADDR
172 #define XOPEN SZFLAG + 2*SZIOINT + 2*SZADDR
173 #define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR
174 #define XNAMED SZFLAG + 2*SZIOINT + 4*SZADDR
175 #define XNAME SZFLAG + 2*SZIOINT + 5*SZADDR
176 #define XNAMELEN SZFLAG + 2*SZIOINT + 6*SZADDR
177 #define XQACCESS SZFLAG + 3*SZIOINT + 6*SZADDR
178 #define XQACCLEN SZFLAG + 3*SZIOINT + 7*SZADDR
179 #define XSEQ SZFLAG + 4*SZIOINT + 7*SZADDR
180 #define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR
181 #define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR
182 #define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR
183 #define XFORM SZFLAG + 6*SZIOINT + 9*SZADDR
184 #define XFORMLEN SZFLAG + 6*SZIOINT + 10*SZADDR
185 #define XFMTED SZFLAG + 7*SZIOINT + 10*SZADDR
186 #define XFMTEDLEN SZFLAG + 7*SZIOINT + 11*SZADDR
187 #define XUNFMT SZFLAG + 8*SZIOINT + 11*SZADDR
188 #define XUNFMTLEN SZFLAG + 8*SZIOINT + 12*SZADDR
189 #define XQRECL SZFLAG + 9*SZIOINT + 12*SZADDR
190 #define XNEXTREC SZFLAG + 9*SZIOINT + 13*SZADDR
191 #define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR
192 #define XQBLANKLEN SZFLAG + 9*SZIOINT + 15*SZADDR
194 LOCAL char *cilist_names[] = {
202 LOCAL char *icilist_names[] = {
211 LOCAL char *olist_names[] = {
223 LOCAL char *cllist_names[] = {
229 LOCAL char *alist_names[] = {
234 LOCAL char *inlist_names[] = {
264 LOCAL char **io_fields;
266 #define zork(n,t) n, sizeof(n)/sizeof(char *) - 1, t
268 LOCAL io_setup io_stuff[] = {
269 zork(cilist_names, TYCILIST), /* external read/write */
270 zork(inlist_names, TYINLIST), /* inquire */
271 zork(olist_names, TYOLIST), /* open */
272 zork(cllist_names, TYCLLIST), /* close */
273 zork(alist_names, TYALIST), /* rewind */
274 zork(alist_names, TYALIST), /* backspace */
275 zork(alist_names, TYALIST), /* endfile */
276 zork(icilist_names,TYICILIST), /* internal read */
277 zork(icilist_names,TYICILIST) /* internal write */
284 register struct Labelblock *lp;
288 execerr("unlabeled format statement" , CNULL);
291 if(lp->labtype == LABUNKNOWN)
293 lp->labtype = LABFORMAT;
294 lp->labelno = newlabel();
296 else if(lp->labtype != LABFORMAT)
298 execerr("bad format number", CNULL);
306 struct Labelblock *lp;
309 char *s0, *lexline();
310 register char *s, *se, *t;
313 s0 = s = lexline(&n);
316 /* warn of trivial errors, e.g. " 11 CONTINUE" (one too few spaces) */
317 /* following FORMAT... */
320 warn("No (...) after FORMAT");
322 warni("%c rather than ( after FORMAT", *s);
323 else if (se[-1] != ')') {
325 while(--t > s && *t != ')') ;
327 warn("No ) at end of FORMAT statement");
328 else if (se - t > 30)
329 warn1("Extraneous text at end of FORMAT: ...%s", se-12);
331 warn1("Extraneous text at end of FORMAT: %s", t+1);
335 /* fix MYQUOTES (\002's) and \\'s */
346 lp->fmtstring = t = mem(t - s + 1, 0);
375 ioformatted = UNFORMATTED;
376 for(i = 1 ; i<=NIOS ; ++i)
384 skiplabel = mklabel(rv);
385 skiplabel->labdefined = 1;
394 struct io_setup *ios;
398 /* set up for error recovery */
400 ioerrlab = ioendlab = skiplab = jumplab = 0;
404 execlab(ioendlab = p->constblock.Const.ci);
406 err("bad end= clause");
410 execlab(ioerrlab = p->constblock.Const.ci);
412 err("bad err= clause");
415 if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )
417 err("iostat must be an integer variable");
426 if(ioerrlab && ioendlab && ioerrlab==ioendlab)
429 skiplab = jumplab = newiolabel();
432 if(ioerrlab && ioendlab && ioerrlab!=ioendlab)
434 IOSTP = (expptr) Mktemp(TYINT, ENULL);
435 skiplab = jumplab = newiolabel();
438 jumplab = (ioerrlab ? ioerrlab : ioendlab);
441 else if(iostmt == IOWRITE)
443 if(IOSTP && !ioerrlab)
444 skiplab = jumplab = newiolabel();
451 endbit = IOSTP!=NULL || ioendlab!=0; /* for use in startrw() */
452 errbit = IOSTP!=NULL || ioerrlab!=0;
453 if (jumplab && !IOSTP)
454 IOSTP = (expptr) Mktemp(TYINT, ENULL);
456 if(iostmt!=IOREAD && iostmt!=IOWRITE)
458 ios = io_stuff + iostmt;
459 io_fields = ios->fields;
460 ioblkp = io_structs[iostmt];
462 io_structs[iostmt] = ioblkp =
463 autovar(1, ios->type, ENULL, "");
464 ioset(TYIOINT, XERR, ICON(errbit));
499 fatali("impossible iostmt %d", iostmt);
501 for(i = 1 ; i<=NIOS ; ++i)
502 if(i!=IOSIOSTAT && V(i)!=NULL)
515 for(i = 1 ; i <= NIOS ; ++i)
516 if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))
517 if(ioc[i].iotype & mask)
521 errstr("invalid control %s for statement", ioc[found].iocname);
523 errstr("unknown iocontrol %s", token);
532 struct Ioclist *iocp;
537 if(n == IOSPOSITIONAL)
540 if (nioctl == IOSFMT) {
541 if (iostmt == IOOPEN) {
543 NOEXT("file= specifier omitted from open");
545 else if (iostmt < IOREAD)
548 else if(nioctl > IOSFMT)
551 err("illegal positional iocontrol");
559 p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);
562 err("illegal * iocontrol");
567 ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);
570 if(iocp->iocval == NULL)
572 if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )
577 errstr("iocontrol %s repeated", iocp->iocname);
587 if(ioformatted == NAMEDIRECTED)
590 err("no I/O list allowed in NAMELIST read/write");
597 putiocall( call0(TYINT, ioroutine) );
613 Addrp tp, mkscalar();
616 for (p = p0 ; p ; p = p->nextp)
618 q = (tagptr)p->datap;
619 if(q->tag == TIMPLDO)
621 exdo(range=newlabel(), (Namep)0,
622 q->impldoblock.impdospec);
623 doiolist(q->impldoblock.datalist);
628 if(q->tag==TPRIM && q->primblock.argsp==NULL
629 && q->primblock.namep->vdim!=NULL)
631 vardcl(qn = q->primblock.namep);
633 putio( fixtype(cpexpr(qn->vdim->nelt)),
634 (expptr)mkscalar(qn) );
638 err("attempt to i/o array of unknown size");
640 else if(q->tag==TPRIM && q->primblock.argsp==NULL &&
641 (qe = (expptr) memversion(q->primblock.namep)) )
643 else if(((qe = fixtype(cpexpr(q)))->tag==TADDR &&
644 (qe->addrblock.uname_tag != UNAM_CONST ||
645 !ISCOMPLEX(qe -> addrblock.vtype))) ||
646 (qe -> tag == TCONST && !ISCOMPLEX(qe ->
648 if (qe -> tag == TCONST)
649 qe = (expptr) putconst((Constp)qe);
652 else if(qe->headblock.vtype != TYERROR)
654 if(iostmt == IOWRITE)
662 cpexpr(qe->headblock.vleng);
663 tp = Mktemp(qe->headblock.vtype,
667 tp = Mktemp(qe->headblock.vtype,
668 qe->headblock.vleng);
669 puteq( cpexpr((expptr)tp), qe);
670 if(qvl) /* put right length on block */
675 putio(ICON(1), (expptr)tp);
678 err("non-left side in READ list");
686 int iocalladdr = TYADDR; /* for fixing TYADDR in saveargtypes */
691 register expptr addr;
695 extern Constp mkconst();
696 register Addrp c = 0;
698 type = addr->headblock.vtype;
699 if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )
701 nelt = mkexpr(OPSTAR, ICON(2), nelt);
702 type -= (TYCOMPLEX-TYREAL);
705 /* pass a length with every item. for noncharacter data, fake one */
710 addr = (expptr) putconst((Constp)addr);
711 c = ALLOC(Addrblock);
717 c->memoffset = ICON(0);
718 c->uname_tag = UNAM_IDENT;
720 sprintf(c->user.ident, "(ftnlen)sizeof(%s)", typename[type]);
721 addr = mkexpr(OPCHARCAST, addr, ENULL);
724 nelt = fixtype( mkconv(TYLENG,nelt) );
725 if(ioformatted == LISTDIRECTED) {
726 expptr mc = mkconv(TYLONG, ICON(type));
727 q = c ? call4(TYINT, "do_lio", mc, nelt, addr, (expptr)c)
728 : call3(TYINT, "do_lio", mc, nelt, addr);
731 char *s = ioformatted==FORMATTED ? "do_fio" : "do_uio";
732 q = c ? call3(TYINT, s, nelt, addr, (expptr)c)
733 : call2(TYINT, s, nelt, addr);
745 extern void p1_label();
749 p1_label((long)(skiplabel - labeltab));
751 exif( mkexpr(OPLT, cpexpr(IOSTP), ICON(0)));
752 exgoto(execlab(ioendlab));
756 exif( mkexpr(iostmt==IOREAD||iostmt==IOWRITE
758 cpexpr(IOSTP), ICON(0)));
759 exgoto(execlab(ioerrlab));
777 tyint = tyioint; /* for -I2 and -i2 */
781 q->headblock.vtype = TYINT;
782 q = fixexpr((Exprp)mkexpr(OPASSIGN, cpexpr(IOSTP), q));
786 exif(mkexpr(OPNE, cpexpr(IOSTP), ICON(0)));
787 exgoto(execlab(jumplab));
799 register char *s, *t;
800 extern chainp assigned_fmts;
804 assigned_fmts = mkchain((char *)np, assigned_fmts);
806 k = strlen(s = np->fvarname);
807 if (k < IDENT_LEN - 4) {
808 q->uname_tag = UNAM_IDENT;
812 q->uname_tag = UNAM_CHARP;
813 q->user.Charp = t = mem(k + 5,0);
815 sprintf(t, "%s_fmt", s);
818 LOCAL Addrp asg_addr(p)
824 badtag("asg_addr", p->tag);
825 q = ALLOC(Addrblock);
831 q->memoffset = ICON(0);
832 fmtname(p->primblock.namep, q);
840 register Addrp unitp, fmtp, recp;
841 register expptr nump;
845 flag intfile, sequential, ok, varfmt;
846 struct io_setup *ios;
848 /* First look at all the parameters and determine what is to be done */
856 if( ISINT(p->headblock.vtype) )
857 unitp = (Addrp) cpexpr(p);
858 else if(p->headblock.vtype == TYCHAR)
861 if(p->tag==TPRIM && p->primblock.argsp==NULL &&
862 (np = p->primblock.namep)->vdim!=NULL)
867 nump = (expptr) cpexpr(np->vdim->nelt);
868 if( ! ISCONST(nump) )
873 err("attempt to use internal unit array of unknown size");
877 unitp = mkscalar(np);
881 unitp = (Addrp /*pjw */) fixtype(cpexpr(p));
883 if(! isstatic((expptr)unitp) )
889 err("bad unit specifier");
895 if( ISINT(p->headblock.vtype) )
897 recp = (Addrp) cpexpr(p);
901 err("bad REC= clause");
912 if(p->tag==TPRIM && p->primblock.argsp==NULL)
914 np = p->primblock.namep;
915 if(np->vclass == CLNAMELIST)
917 ioformatted = NAMEDIRECTED;
918 fmtp = (Addrp) fixtype(p);
919 V(IOSFMT) = (expptr)fmtp;
925 if( ! ONEOF(np->vstg, MSKSTATIC) )
930 if( ISINT(np->vtype) ) /* ASSIGNed label */
938 p = V(IOSFMT) = fixtype(p);
939 if(p->headblock.vtype == TYCHAR
940 /* Since we allow write(6,n) */
941 /* we may as well allow write(6,n(2)) */
942 || p->tag == TADDR && ISINT(p->addrblock.vtype))
946 fmtp = (Addrp) cpexpr(p);
950 struct Labelblock *lp;
951 lp = mklabel(p->constblock.Const.ci);
954 fmtp = (Addrp)mkaddcon(lp->stateno);
955 /* lp->stateno for names fmt_nnn */
960 ioformatted = UNFORMATTED;
963 err("bad format descriptor");
964 ioformatted = UNFORMATTED;
973 if (ioformatted==UNFORMATTED) {
974 err("unformatted internal I/O not allowed");
978 err("direct internal I/O not allowed");
982 if(!sequential && ioformatted==LISTDIRECTED)
984 err("direct list-directed I/O not allowed");
987 if(!sequential && ioformatted==NAMEDIRECTED)
989 err("direct namelist I/O not allowed");
997 Now put out the I/O structure, statically if all the clauses
998 are constants, dynamically otherwise
1002 ios = io_stuff + iostmt;
1009 io_fields = ios->fields;
1012 ioblkp = ALLOC(Addrblock);
1013 ioblkp->tag = TADDR;
1014 ioblkp->vtype = ios->type;
1015 ioblkp->vclass = CLVAR;
1016 ioblkp->vstg = STGINIT;
1017 ioblkp->memno = ++lastvarno;
1018 ioblkp->memoffset = ICON(0);
1019 ioblkp -> uname_tag = UNAM_IDENT;
1021 temp_name("io_", lastvarno, ioblkp->user.ident)); }
1022 else if(!(ioblkp = io_structs[iostmt1]))
1023 io_structs[iostmt1] = ioblkp =
1024 autovar(1, ios->type, ENULL, "");
1026 ioset(TYIOINT, XERR, ICON(errbit));
1027 if(iostmt == IOREAD)
1028 ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );
1032 ioset(TYIOINT, XIRNUM, nump);
1033 ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );
1034 ioseta(XIUNIT, unitp);
1037 ioset(TYIOINT, XUNIT, (expptr) unitp);
1040 ioset(TYIOINT, /* intfile ? XIREC : */ XREC, (expptr) recp);
1043 ioseta( intfile ? XIFMT : XFMT , fmtp);
1045 ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);
1049 ioroutine[2] = iostmt==IOREAD ? 'r' : 'w';
1050 ioroutine[3] = "ds"[sequential];
1051 ioroutine[4] = "ufln"[ioformatted];
1052 ioroutine[5] = "ei"[intfile];
1053 ioroutine[6] = '\0';
1055 putiocall( call1(TYINT, ioroutine, cpexpr((expptr)ioblkp) ));
1059 frexpr((expptr)ioblkp);
1061 ioblkp = 0; /* unnecessary */
1072 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1073 ioset(TYIOINT, XUNIT, cpexpr(p) );
1075 err("bad unit in open");
1076 if( (p = V(IOSFILE)) )
1077 if(p->headblock.vtype == TYCHAR)
1078 ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );
1080 err("bad file in open");
1085 if( ISINT(p->headblock.vtype) )
1086 ioset(TYIOINT, XRECLEN, cpexpr(p) );
1090 ioset(TYIOINT, XRECLEN, ICON(0) );
1092 iosetc(XSTATUS, V(IOSSTATUS));
1093 iosetc(XACCESS, V(IOSACCESS));
1094 iosetc(XFORMATTED, V(IOSFORM));
1095 iosetc(XBLANK, V(IOSBLANK));
1097 putiocall( call1(TYINT, "f_open", cpexpr((expptr)ioblkp) ));
1106 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1108 ioset(TYIOINT, XUNIT, cpexpr(p) );
1109 iosetc(XCLSTATUS, V(IOSSTATUS));
1110 putiocall( call1(TYINT, "f_clos", cpexpr((expptr)ioblkp)) );
1113 err("bad unit in close statement");
1124 err("inquire by unit or by file, not both");
1125 ioset(TYIOINT, XUNIT, cpexpr(p) );
1127 else if( ! V(IOSFILE) )
1128 err("must inquire by unit or by file");
1129 iosetlc(IOSFILE, XFILE, XFILELEN);
1130 iosetip(IOSEXISTS, XEXISTS);
1131 iosetip(IOSOPENED, XOPEN);
1132 iosetip(IOSNUMBER, XNUMBER);
1133 iosetip(IOSNAMED, XNAMED);
1134 iosetlc(IOSNAME, XNAME, XNAMELEN);
1135 iosetlc(IOSACCESS, XQACCESS, XQACCLEN);
1136 iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);
1137 iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);
1138 iosetlc(IOSFORM, XFORM, XFORMLEN);
1139 iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);
1140 iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);
1141 iosetip(IOSRECL, XQRECL);
1142 iosetip(IOSNEXTREC, XNEXTREC);
1143 iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);
1145 putiocall( call1(TYINT, "f_inqu", cpexpr((expptr)ioblkp) ));
1156 if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )
1158 ioset(TYIOINT, XUNIT, cpexpr(p) );
1159 putiocall( call1(TYINT, subname, cpexpr((expptr)ioblkp) ));
1162 err("bad unit in I/O motion statement");
1165 static int ioset_assign = OPASSIGN;
1168 ioset(type, offset, p)
1173 if(statstruct && ISCONST(p)) {
1176 case TYADDR: /* stmt label */
1183 badtype("ioset", type);
1185 iob_list->fields[offset] =
1186 string_num(s, p->constblock.Const.ci);
1192 q = ALLOC(Addrblock);
1198 q->memoffset = ICON(0);
1199 q->uname_tag = UNAM_IDENT;
1200 sprintf(q->user.ident, "%s.%s",
1201 statstruct ? iob_list->name : ioblkp->user.ident,
1202 io_fields[offset + 1]);
1203 if (type == TYADDR && p->tag == TCONST
1204 && p->constblock.vtype == TYADDR) {
1207 p1 = ALLOC(Addrblock);
1210 p1->vstg = STGAUTO; /* wrong, but who cares? */
1213 p1->memoffset = ICON(0);
1214 p1->uname_tag = UNAM_IDENT;
1215 sprintf(p1->user.ident, "fmt_%ld",
1216 p->constblock.Const.ci);
1220 if (type == TYADDR && p->headblock.vtype == TYCHAR)
1222 putexpr(mkexpr(ioset_assign, (expptr)q, p));
1235 ioset(TYADDR, offset, ICON(0) );
1236 else if(p->headblock.vtype == TYCHAR)
1237 ioset(TYADDR, offset, addrof(cpexpr(p) ));
1239 err("non-character control clause");
1250 static char who[] = "ioseta";
1255 char buf[24], buf1[24];
1262 if (p->tag != TADDR)
1263 badtag(who, p->tag);
1265 switch(p->uname_tag) {
1268 if (mo->tag != TCONST)
1269 badtag("ioseta/memoffset", mo->tag);
1272 ci = mo->constblock.Const.ci - np->voffset;
1273 if (np->vstg == STGCOMMON && !np->vcommequiv) {
1274 comm = &extsymtab[np->vardesc.varno];
1275 sprintf(buf, "%d.", comm->curno);
1276 k = strlen(buf) + strlen(comm->cextname)
1277 + strlen(np->cvarname);
1279 sprintf(buf1, "+%ld", ci);
1285 sprintf(s, "%s%s%s%s", comm->cextname, buf,
1286 np->cvarname, buf1);
1289 sprintf(buf,"%ld", ci);
1290 s1 = p->user.name->cvarname;
1291 k = strlen(buf) + strlen(s1);
1292 sprintf(s = mem(k+2,0), "%s+%s", s1, buf);
1295 s = cpstring(p->user.name->cvarname);
1298 s = tostring(p->user.Const.ccp1.ccp0,
1299 (int)p->vleng->constblock.Const.ci);
1302 badthing("uname_tag", who, p->uname_tag);
1304 /* kludge for Hollerith */
1305 if (p->vtype != TYCHAR) {
1306 s1 = mem(strlen(s)+10,0);
1307 sprintf(s1, "(char *)%s%s", p->isarray ? "" : "&", s);
1310 iob_list->fields[offset] = s;
1315 else if (p->vtype != TYCHAR) {
1316 NOEXT("non-character variable as format or internal unit");
1317 e = mkexpr(OPCHARCAST, (expptr)p, ENULL);
1320 e = addrof((expptr)p);
1321 ioset(TYADDR, offset, e);
1336 ONEOF(p->addrblock.vtype, inqmask) ) {
1337 ioset_assign = OPASSIGNI;
1338 ioset(TYADDR, offset, addrof(cpexpr(p)) );
1339 ioset_assign = OPASSIGN;
1342 errstr("impossible inquire parameter %s", ioc[i].iocname);
1344 ioset(TYADDR, offset, ICON(0) );
1350 iosetlc(i, offp, offl)
1354 if( (p = V(i)) && p->headblock.vtype==TYCHAR)
1355 ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );