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 ****************************************************************/
26 /* ROUTINES CALLED DURING DATA AND PARAMETER STATEMENT PROCESSING */
28 static char datafmt[] = "%s\t%09ld\t%d";
29 static char *cur_varname;
31 /* another initializer, called from parser */
33 register expptr repp, valp;
40 if (parstate < INDATA) {
46 else if (ISICON(repp) && repp->constblock.Const.ci >= 0)
47 nrep = repp->constblock.Const.ci;
50 err("invalid repetition count in DATA statement");
58 err("non-constant initializer");
62 if(toomanyinit) goto ret;
63 for(i = 0 ; i < nrep ; ++i)
68 err("too many initializers");
72 setdata((Addrp)p, (Constp)valp, elen);
84 register struct Impldoblock *ip;
87 register struct Rplblock *rp;
96 p = (tagptr)curdtp->datap;
99 ip = &(p->impldoblock);
100 if(ip->implb==NULL || ip->impub==NULL || ip->varnp==NULL)
101 fatali("bad impldoblock 0%o", (int) ip);
103 ip->varvp->Const.ci += ip->impdiff;
106 q = fixtype(cpexpr(ip->implb));
109 ip->varvp = (Constp) q;
113 q = fixtype(cpexpr(ip->impstep));
116 ip->impdiff = q->constblock.Const.ci;
122 q = fixtype(cpexpr(ip->impub));
125 ip->implim = q->constblock.Const.ci;
129 rp = ALLOC(Rplblock);
130 rp->rplnextp = rpllist;
132 rp->rplnp = ip->varnp;
133 rp->rplvp = (expptr) (ip->varvp);
137 if( (ip->impdiff>0 && (ip->varvp->Const.ci <= ip->implim))
138 || (ip->impdiff<0 && (ip->varvp->Const.ci >= ip->implim)) )
139 { /* start new loop */
140 curdtp = ip->datalist;
149 rpllist = rpllist->rplnextp;
153 Fatal("rpllist empty");
155 frexpr((expptr)ip->varvp);
157 curdtp = curdtp->nextp;
161 pp = (struct Primblock *) p;
163 cur_varname = np->fvarname;
166 if(p->primblock.argsp==NULL && np->vdim!=NULL)
167 { /* array initialization */
168 q = (expptr) mkaddr(np);
169 off = typesize[np->vtype] * curdtelt;
170 if(np->vtype == TYCHAR)
171 off *= np->vleng->constblock.Const.ci;
172 q->addrblock.memoffset =
173 mkexpr(OPPLUS, q->addrblock.memoffset, mkintcon(off) );
174 if( (neltp = np->vdim->nelt) && ISCONST(neltp))
176 if(++curdtelt < neltp->constblock.Const.ci)
180 err("attempt to initialize adjustable array");
183 q = mklhs( (struct Primblock *)cpexpr((expptr)pp) );
186 curdtp = curdtp->nextp;
189 if(q->headblock.vtype == TYCHAR)
190 if(ISICON(q->headblock.vleng))
191 *elenp = q->headblock.vleng->constblock.Const.ci;
193 err("initialization of string of nonconstant length");
196 else *elenp = typesize[q->headblock.vtype];
198 if (np->vstg == STGBSS) {
199 vlen = np->vtype==TYCHAR
200 ? np->vleng->constblock.Const.ci
201 : typesize[np->vtype];
208 err("nonconstant implied DO parameter");
210 curdtp = curdtp->nextp;
224 setdata(varp, valp, elen)
227 register Constp valp;
229 struct Constblock con;
233 char *dataname(), *varname;
235 register unsigned char *s;
236 static int last_lineno;
237 static char *last_varname;
239 if (varp->vstg == STGCOMMON) {
240 if (!(dfile = blkdfile))
241 dfile = blkdfile = opf(blkdfname, textwrite);
244 if (procclass == CLBLOCK) {
245 if (varp != badvar) {
247 warn1("%s is not in a COMMON block",
248 varp->uname_tag == UNAM_NAME
249 ? varp->user.name->fvarname
254 if (!(dfile = initfile))
255 dfile = initfile = opf(initfname, textwrite);
257 varname = dataname(varp->vstg, varp->memno);
258 offset = varp->memoffset->constblock.Const.ci;
260 valtype = valp->vtype;
261 if(type!=TYCHAR && valtype==TYCHAR)
264 && (last_varname != cur_varname || last_lineno != lineno)) {
265 /* prevent multiple warnings */
266 last_lineno = lineno;
268 "non-character datum %.42s initialized with character string",
269 last_varname = cur_varname);
271 varp->vleng = ICON(typesize[type]);
272 varp->vtype = type = TYCHAR;
274 else if( (type==TYCHAR && valtype!=TYCHAR) ||
275 (cktype(OPASSIGN,type,valtype) == TYERROR) )
277 err("incompatible types in initialization");
281 con.Const.ci = valp->Const.ci;
282 else if(type != TYCHAR)
284 if(valtype == TYUNKNOWN)
285 con.Const.ci = valp->Const.ci;
286 else consconv(type, &con, valp);
294 if (tylogical != TYLONG)
298 dataline(varname, offset, type);
299 prconi(dfile, con.Const.ci);
303 dataline(varname, offset, type);
304 prcona(dfile, con.Const.ci);
312 dataline(varname, offset, type);
313 prconr(dfile, &con, k);
317 k = valp -> vleng -> constblock.Const.ci;
320 s = (unsigned char *)valp->Const.ccp;
321 for(i = 0 ; i < k ; ++i) {
322 dataline(varname, offset++, TYCHAR);
323 fprintf(dfile, "\t%d\n", *s++);
325 k = elen - valp->vleng->constblock.Const.ci;
327 dataline(varname, offset, TYBLANK);
328 fprintf(dfile, "\t%d\n", k);
333 badtype("setdata", type);
341 output form of name is padded with blanks and preceded
342 with a storage class digit
344 char *dataname(stg,memno)
348 static char varname[64];
349 register char *s, *t;
350 char buf[16], *memname();
352 if (stg == STGCOMMON) {
354 sprintf(s = buf, "Q.%ld", memno);
357 varname[0] = stg==STGEQUIV ? '1' : '0';
358 s = memname(stg, memno);
373 register struct Chain *p;
376 for(p = p0 ; p ; p = p->nextp)
378 q = (tagptr)p->datap;
379 if(q->tag == TIMPLDO)
381 if(q->impldoblock.isbusy)
382 return; /* circular chain completed */
383 q->impldoblock.isbusy = YES;
384 frdata(q->impldoblock.datalist);
396 dataline(varname, offset, type)
401 fprintf(dfile, datafmt, varname, offset, type);
406 register struct Paramblock *p;
413 p->paramval = q = mkconv(p->vtype, e);
414 if (p->vtype == TYCHAR) {
416 p->paramval = q = fixexpr(q);
417 if (!ISCONST(q) || q->constblock.vtype != TYCHAR) {
418 errstr("invalid value for character parameter %s",
423 p->vleng = ICON(q->constblock.vleng->constblock.Const.ci
424 + q->constblock.Const.ccp1.blanks);
425 else if (q->constblock.vleng->constblock.Const.ci
426 > e->constblock.Const.ci) {
427 q->constblock.vleng->constblock.Const.ci
428 = e->constblock.Const.ci;
429 q->constblock.Const.ccp1.blanks = 0;
432 q->constblock.Const.ccp1.blanks
433 = e->constblock.Const.ci
434 - q->constblock.vleng->constblock.Const.ci;