io.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,235 行 · 第 1/2 页

C
1,235
字号
		putif (mkexpr(OPEQ,q,ICON(0)),jumplab);else	if (optimflag)		optbuff (SKEQ, q, 0, 0);	else		putexpr(q);}startrw(){register expptr p;register Namep np;register Addrp unitp, fmtp, recp, tioblkp;register expptr nump;register ioblock *t;Addrp mkscalar();expptr mkaddcon();int k;flag intfile, sequential, ok, varfmt;/* First look at all the parameters and determine what is to be done */ok = YES;statstruct = YES;intfile = NO;if(p = V(IOSUNIT))	{	if( ISINT(p->headblock.vtype) )		unitp = (Addrp) cpexpr(p);	else if(p->headblock.vtype == TYCHAR)		{		intfile = YES;		if(p->tag==TPRIM && p->primblock.argsp==NULL &&		    (np = p->primblock.namep)->vdim!=NULL)			{			vardcl(np);			if(np->vdim->nelt)				{				nump = (expptr) cpexpr(np->vdim->nelt);				if( ! ISCONST(nump) )					statstruct = NO;				}			else				{				err("attempt to use internal unit array of unknown size");				ok = NO;				nump = ICON(1);				}			unitp = mkscalar(np);			}		else	{			nump = ICON(1);			unitp = (Addrp) fixtype(cpexpr(p));			}		if(! isstatic(unitp) )			statstruct = NO;		}	else		{		err("bad unit specifier type");		ok = NO;		}	}else	{	err("bad unit specifier");	ok = NO;	}sequential = YES;if(p = V(IOSREC))	if( ISINT(p->headblock.vtype) )		{		recp = (Addrp) cpexpr(p);		sequential = NO;		}	else	{		err("bad REC= clause");		ok = NO;		}else	recp = NULL;varfmt = YES;fmtp = NULL;if(p = V(IOSFMT))	{	if(p->tag==TPRIM && p->primblock.argsp==NULL)		{		np = p->primblock.namep;		if(np->vclass == CLNAMELIST)			{			ioformatted = NAMEDIRECTED;			fmtp = (Addrp) fixtype(cpexpr(p));			goto endfmt;			}		vardcl(np);		if(np->vdim)			{			if( ! ONEOF(np->vstg, MSKSTATIC) )				statstruct = NO;			fmtp = mkscalar(np);			goto endfmt;			}		if( ISINT(np->vtype) )	/* ASSIGNed label */			{			statstruct = NO;			varfmt = NO;			fmtp = (Addrp) fixtype(cpexpr(p));			goto endfmt;			}		}	p = V(IOSFMT) = fixtype(p);	if(p->headblock.vtype == TYCHAR)		{		if (p->tag == TCONST) p = (expptr) putconst(p);		if( ! isstatic(p) )			statstruct = NO;		fmtp = (Addrp) cpexpr(p);		}	else if( ISICON(p) )		{		if( (k = fmtstmt( mklabel(p->constblock.const.ci) )) > 0 )			{			fmtp = (Addrp) mkaddcon(k);			varfmt = NO;			}		else			ioformatted = UNFORMATTED;		}	else	{		err("bad format descriptor");		ioformatted = UNFORMATTED;		ok = NO;		}	}else	fmtp = NULL;endfmt:	if(intfile && ioformatted==UNFORMATTED)		{		err("unformatted internal I/O not allowed");		ok = NO;		}	if(!sequential && ioformatted==LISTDIRECTED)		{		err("direct list-directed I/O not allowed");		ok = NO;		}	if(!sequential && ioformatted==NAMEDIRECTED)		{		err("direct namelist I/O not allowed");		ok = NO;		}if( ! ok )	return;if (optimflag && ISCONST (fmtp))	fmtp = putconst ( (expptr) fmtp);/*   Now put out the I/O structure, statically if all the clauses   are constants, dynamically otherwise*/if(statstruct)	{	tioblkp = ioblkp;	ioblkp = ALLOC(Addrblock);	ioblkp->tag = TADDR;	ioblkp->vtype = TYIOINT;	ioblkp->vclass = CLVAR;	ioblkp->vstg = STGINIT;	ioblkp->memno = ++lastvarno;	ioblkp->memoffset = ICON(0);	blklen = (intfile ? XIREC+SZIOINT :			(sequential ? XFMT+SZADDR : XRNUM+SZIOINT) );	t = ALLOC(IoBlock);	t->blkno = ioblkp->memno;	t->len = blklen;	t->next = iodata;	iodata = t;	}else if(ioblkp == NULL)	ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);ioset(TYIOINT, XERR, ICON(errbit));if(iostmt == IOREAD)	ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) );if(intfile)	{	ioset(TYIOINT, XIRNUM, nump);	ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) );	ioseta(XIUNIT, unitp);	}else	ioset(TYIOINT, XUNIT, (expptr) unitp);if(recp)	ioset(TYIOINT, (intfile ? XIREC : XREC) , (expptr) recp);if(varfmt)	ioseta( intfile ? XIFMT : XFMT , fmtp);else	ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp);ioroutine[0] = 's';ioroutine[1] = '_';ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w');ioroutine[3] = (sequential ? 's' : 'd');ioroutine[4] = "ufln" [ioformatted];ioroutine[5] = (intfile ? 'i' : 'e');ioroutine[6] = '\0';putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) ));if(statstruct)	{	frexpr(ioblkp);	ioblkp = tioblkp;	statstruct = NO;	}}LOCAL dofopen(){register expptr p;if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )	ioset(TYIOINT, XUNIT, cpexpr(p) );else	err("bad unit in open");if( (p = V(IOSFILE)) )	if(p->headblock.vtype == TYCHAR)		ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) );	else		err("bad file in open");iosetc(XFNAME, p);if(p = V(IOSRECL))	if( ISINT(p->headblock.vtype) )		ioset(TYIOINT, XRECLEN, cpexpr(p) );	else		err("bad recl");else	ioset(TYIOINT, XRECLEN, ICON(0) );iosetc(XSTATUS, V(IOSSTATUS));iosetc(XACCESS, V(IOSACCESS));iosetc(XFORMATTED, V(IOSFORM));iosetc(XBLANK, V(IOSBLANK));putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) ));}LOCAL dofclose(){register expptr p;if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )	{	ioset(TYIOINT, XUNIT, cpexpr(p) );	iosetc(XCLSTATUS, V(IOSSTATUS));	putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) );	}else	err("bad unit in close statement");}LOCAL dofinquire(){register expptr p;if(p = V(IOSUNIT))	{	if( V(IOSFILE) )		err("inquire by unit or by file, not both");	ioset(TYIOINT, XUNIT, cpexpr(p) );	}else if( ! V(IOSFILE) )	err("must inquire by unit or by file");iosetlc(IOSFILE, XFILE, XFILELEN);iosetip(IOSEXISTS, XEXISTS);iosetip(IOSOPENED, XOPEN);iosetip(IOSNUMBER, XNUMBER);iosetip(IOSNAMED, XNAMED);iosetlc(IOSNAME, XNAME, XNAMELEN);iosetlc(IOSACCESS, XQACCESS, XQACCLEN);iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN);iosetlc(IOSDIRECT, XDIRECT, XDIRLEN);iosetlc(IOSFORM, XFORM, XFORMLEN);iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN);iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN);iosetip(IOSRECL, XQRECL);iosetip(IOSNEXTREC, XNEXTREC);iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN);putiocall( call1(TYINT,  "f_inqu", cpexpr(ioblkp) ));}LOCAL dofmove(subname)char *subname;{register expptr p;if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) )	{	ioset(TYIOINT, XUNIT, cpexpr(p) );	putiocall( call1(TYINT, subname, cpexpr(ioblkp) ));	}else	err("bad unit in I/O motion statement");}LOCALioset(type, offset, p)int type;int offset;register expptr p;{  static char *badoffset = "badoffset in ioset";  register Addrp q;  register offsetlist *op;  q = (Addrp) cpexpr(ioblkp);  q->vtype = type;  q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) );  if (statstruct && ISCONST(p))    {      if (!ISICON(q->memoffset))	fatal(badoffset);      op = mkiodata(q->memno, q->memoffset->constblock.const.ci, blklen);      if (op->tag != 0)	fatal(badoffset);      if (type == TYADDR)	{	  op->tag = NDLABEL;	  op->val.label = p->constblock.const.ci;	}      else	{	  op->tag = NDDATA;	  op->val.cp = (Constp) convconst(type, 0, p);	}      frexpr((tagptr) p);      frexpr((tagptr) q);    }  else    if (optimflag)      optbuff (SKEQ, mkexpr(OPASSIGN,q,p), 0,0);    else      puteq (q,p);  return;}LOCAL iosetc(offset, p)int offset;register expptr p;{if(p == NULL)	ioset(TYADDR, offset, ICON(0) );else if(p->headblock.vtype == TYCHAR)	ioset(TYADDR, offset, addrof(cpexpr(p) ));else	err("non-character control clause");}LOCAL ioseta(offset, p)int offset;register Addrp p;{  static char *badoffset = "bad offset in ioseta";  int blkno;  register offsetlist *op;  if(statstruct)    {      blkno = ioblkp->memno;      op = mkiodata(blkno, offset, blklen);      if (op->tag != 0)	fatal(badoffset);      if (p == NULL)	op->tag = NDNULL;      else if (p->tag == TADDR)	{	  op->tag = NDADDR;	  op->val.addr.stg = p->vstg;	  op->val.addr.memno = p->memno;	  op->val.addr.offset = p->memoffset->constblock.const.ci;	}      else	badtag("ioseta", p->tag);    }  else    ioset(TYADDR, offset, p ? addrof(p) : ICON(0) );  return;}LOCAL iosetip(i, offset)int i, offset;{register expptr p;if(p = V(i))	if(p->tag==TADDR &&	    ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) )		ioset(TYADDR, offset, addrof(cpexpr(p)) );	else		errstr("impossible inquire parameter %s", ioc[i].iocname);else	ioset(TYADDR, offset, ICON(0) );}LOCAL iosetlc(i, offp, offl)int i, offp, offl;{register expptr p;if( (p = V(i)) && p->headblock.vtype==TYCHAR)	ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) );iosetc(offp, p);}LOCAL offsetlist *mkiodata(blkno, offset, len)int blkno;ftnint offset;ftnint len;{  register offsetlist *p, *q;  register ioblock *t;  register int found;  found = NO;  t = iodata;  while (found == NO && t != NULL)    {      if (t->blkno == blkno)	found = YES;      else	t = t->next;    }  if (found == NO)    {      t = ALLOC(IoBlock);      t->blkno = blkno;      t->next = iodata;      iodata = t;    }  if (len > t->len)    t->len = len;  p = t->olist;  if (p == NULL)    {      p = ALLOC(OffsetList);      p->next = NULL;      p->offset = offset;      t->olist = p;      return (p);    }  for (;;)    {      if (p->offset == offset)	return (p);      else if (p->next != NULL &&	       p->next->offset <= offset)	p = p->next;      else	{	  q = ALLOC(OffsetList);	  q->next = p->next;	  p->next = q;	  q->offset = offset;	  return (q);	}    }}outiodata(){  static char *varfmt = "v.%d:\n";  register ioblock *p;  register ioblock *t;  if (iodata == NULL) return;  p = iodata;  while (p != NULL)    {      pralign(ALIDOUBLE);      fprintf(initfile, varfmt, p->blkno);      outolist(p->olist, p->len);      t = p;      p = t->next;      free((char *) t);    }  iodata = NULL;  return;}LOCALoutolist(op, len)register offsetlist *op;register int len;{  static char *overlap = "overlapping i/o fields in outolist";  static char *toolong = "offset too large in outolist";  register offsetlist *t;  register ftnint clen;  register Constp cp;  register int type;  clen = 0;  while (op != NULL)    {      if (clen > op->offset)	fatal(overlap);      if (clen < op->offset)	{	  prspace(op->offset - clen);	  clen = op->offset;	}      switch (op->tag)	{	default:	  badtag("outolist", op->tag);	case NDDATA:	  cp = op->val.cp;	  type = cp->vtype;	  if (type != TYIOINT)	    badtype("outolist", type);	  prconi(initfile, type, cp->const.ci);	  clen += typesize[type];	  frexpr((tagptr) cp);	  break;	case NDLABEL:	  prcona(initfile, op->val.label);	  clen += typesize[TYADDR];	  break;	case NDADDR:	  praddr(initfile, op->val.addr.stg, op->val.addr.memno,		 op->val.addr.offset);	  clen += typesize[TYADDR];	  break;	case NDNULL:	  praddr(initfile, STGNULL, 0, (ftnint) 0);	  clen += typesize[TYADDR];	  break;	}      t = op;      op = t->next;      free((char *) t);    }  if (clen > len)    fatal(toolong);  if (clen < len)    prspace(len - clen);  return;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?