⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#include <ctype.h>#include "defs"static int lastfmtchar;static int writeop;static int needcomma;ptr mkiost(kwd,unit,list)int kwd;ptr unit;ptr list;{register ptr p;if(unit!=NULL && unit->vtype!=TYINT)	{	execerr("I/O unit must be an integer", "");	return(NULL);	}p = allexpblock();p->tag = TIOSTAT;p->vtype = TYINT;p->iokwd = kwd;p->iounit = unit;p->iolist = list;return(p);}struct iogroup *mkiogroup(list, format, dop)ptr list;char *format;ptr dop;{register struct iogroup *p;p = ALLOC(iogroup);p->tag = TIOGROUP;p->doptr = dop;p->iofmt = format;p->ioitems = list;return(p);}ptr exio(iostp, errhandle)struct iostblock *iostp;int errhandle;{ptr unit, list;int fmtlabel, errlabel, endlabel, jumplabel;ptr errval;int fmtio;if(iostp == NULL)	return( errnode() );unit = iostp->iounit;list = iostp->iolist;/* kwd=	0  binary input 	2  formatted input	1  binary output	3  formatted output*/writeop = iostp->iokwd & 01;if( fmtio = (iostp->iokwd & 02) )	fmtlabel = nextlab() ;frexpblock(iostp);errval = 0;endlabel = 0;if(errhandle)	{	switch(tailor.errmode)		{		default:			execerr("no error handling ", "");			return( errnode() );		case IOERRIBM:	/* ibm: err=, end= */			jumplabel = nextlab();			break;		case IOERRFORT77:	/* New Fortran Standard: iostat= */			break;		}	errval = gent(TYINT, PNULL);	}if(unit)	unit = simple(RVAL, unit);else	unit = mkint(writeop ? tailor.ftnout : tailor.ftnin);if(unit->tag!=TCONST && (unit->tag!=TNAME || unit->vsubs!=0))	unit = simple(LVAL, mknode(TASGNOP,OPASGN,gent(TYINT,PNULL),unit));simlist(list);exlab(0);putic(ICKEYWORD, (writeop ? FWRITE : FREAD) );putic(ICOP, OPLPAR);prexpr(unit);frexpr(unit);if( fmtio )	{	putic(ICOP, OPCOMMA);	putic(ICLABEL, fmtlabel);	}if(errhandle) switch(tailor.errmode)	{	case IOERRIBM:		putic(ICOP,OPCOMMA);		putsii(ICCONST, "err =");		putic(ICLABEL, errlabel = nextlab() );		if(!writeop)			{			putic(ICOP,OPCOMMA);			putsii(ICCONST, "end =");			putic(ICLABEL, endlabel = nextlab() );			}		break;	case IOERRFORT77:		putic(ICOP,OPCOMMA);		putsii(ICCONST, "iostat =");		putname(errval);		break;	}putic(ICOP,OPRPAR);putic(ICBLANK, 1);needcomma = NO;doiolist(list);if(fmtio)	{	exlab(fmtlabel);	putic(ICKEYWORD, FFORMAT);	putic(ICOP, OPLPAR);	lastfmtchar = '(';	doformat(1, list);	putic(ICOP, OPRPAR);	}friolist(list);if(errhandle && tailor.errmode==IOERRIBM)	{	exasgn(cpexpr(errval), OPASGN, mkint(0) );	exgoto(jumplabel);	exlab(errlabel);	exasgn(cpexpr(errval), OPASGN, mkint(1) );	if(endlabel)		{		exgoto(jumplabel);		exlab(endlabel);		exasgn(cpexpr(errval), OPASGN,			mknode(TNEGOP,OPMINUS,mkint(1),PNULL) );		}	exlab(jumplabel);	}return( errval );}doiolist(list)ptr list;{register ptr p, q;register struct doblock *dop;for(p = list ; p ; p = p->nextp)	{	switch( (q = p->datap) ->tag)		{		case TIOGROUP:			if(dop = q->doptr)				{				if(needcomma)					putic(ICOP, OPCOMMA);				putic(ICOP, OPLPAR);				needcomma = NO;				}			doiolist(q->ioitems);			if(dop)				{				putic(ICOP,OPCOMMA);				prexpr(dop->dovar);				putic(ICOP, OPEQUALS);				prexpr(dop->dopar[0]);				putic(ICOP, OPCOMMA);				prexpr(dop->dopar[1]);				if(dop->dopar[2])					{					putic(ICOP, OPCOMMA);					prexpr(dop->dopar[2]);					}				putic(ICOP, OPRPAR);				needcomma = YES;				}			break;		case TIOITEM:			if(q->ioexpr)				{				if(needcomma)					putic(ICOP, OPCOMMA);				prexpr(q->ioexpr);				needcomma = YES;				}			break;		default:			badtag("doiolist", q->tag);		}	}}doformat(nrep, list)int nrep;ptr list;{register ptr p, q;int k;ptr arrsize();if(nrep > 1)	{	fmtnum(nrep);	fmtop(OPLPAR);	}for(p = list ; p ; p = p->nextp)	switch( (q = p->datap) ->tag)		{		case TIOGROUP:			if(q->iofmt)				prfmt(q->nrep, q->iofmt);			else	{				doformat(q->nrep>0 ? q->nrep :					(q->doptr ? repfac(q->doptr) : 1),					q->ioitems);				}			break;		case TIOITEM:			if(q->iofmt == NULL)				break;			if(q->nrep==0 && q->ioexpr && q->ioexpr->vdim)				{				if( ! isicon(arrsize(q->ioexpr), &k) )					execerr("io of adjustable array", "");				else					prfmt(k, q->iofmt);				}			else				prfmt(q->nrep, q->iofmt);		}if(nrep > 1)	fmtop(OPRPAR);}fmtop(op)register int op;{register c;c = (op==OPLPAR ? '(' : (op==OPRPAR ? ')' : 'x') );fmtcom(c);putic(ICOP, op);lastfmtchar = c;}fmtnum(k)int k;{fmtcom('1');prexpr( mkint(k) );lastfmtchar = ',';	/* prevent further comma after factor*/}/* separate formats with comma unless already a slash*/fmtcom(c)int c;{if( c!='/' && c!=')' && lastfmtchar!='/' && lastfmtchar!='(' && lastfmtchar!=',' )	{	putic(ICOP, OPCOMMA);	lastfmtchar = ',';	}}prfmt(nrep, str)int nrep;char *str;{char fmt[20];register int k, k0, k1, k2;register char *t;fmtcom(nrep>1 ? '1' : str[0]);if(nrep > 1)	{	fmtnum(nrep);	fmtop(OPLPAR);	}switch(str[0])	{	case 'd':	case 'e':	case 'g':		if(writeop)			{			putsii(ICCONST, "1p");			break;			}		case 'f':		putsii(ICCONST, "0p");		break;			case 'c':		k = convci(str+1);		k0 = tailor.ftnchwd;		k1 = k / k0;		k2 = k % k0;		if(k1>0 && k2>0)			sprintf(fmt, "(%da%d,a%d)",k1,k0,k2);		else if(k1>1)			sprintf(fmt, "(%da%d)", k1, k0);		else	sprintf(fmt, "a%d", k);		putsii(ICCONST, fmt);		lastfmtchar = 'f';	/* last char isnt operator */		goto close;	default:		break;	}putsii(ICCONST,str);/* if the format is an nH, act as if it ended with a non-operator character */if( isdigit(str[0]) )	{	for(t = str+1 ; isdigit(*t) ; ++t);		;	if(*t=='h' || *t=='H')		{		lastfmtchar = 'f';		goto close;		}	}lastfmtchar = str[ strlen(str)-1 ];close:	if(nrep > 1)		fmtop(OPRPAR);}friolist(list)ptr list;{register ptr p, q;register struct doblock *dop;for(p = list; p; p = p->nextp)	{	switch ( (q = p->datap) ->tag)		{		case TIOGROUP:			if(dop = q->doptr)				{				frexpr(dop->dovar);				frexpr(dop->dopar[0]);				frexpr(dop->dopar[1]);				if(dop->dopar[2])					frexpr(dop->dopar[2]);				cfree(dop);				}			friolist(q->ioitems);			break;		case TIOITEM:			if(q->ioexpr)				frexpr(q->ioexpr);			break;		default:			badtag("friolist", q->tag);		}	if(q->iofmt)		cfree(q->iofmt);	cfree(q);	}frchain( &list );}simlist(p)register ptr p;{register ptr q, ep;struct iogroup *enloop();for( ; p ; p = p->nextp)	switch( (q = p->datap) ->tag )		{		case TIOGROUP:			simlist(q->ioitems);			break;		case TIOITEM:			if(ep = q->ioexpr)				{				/* if element is a subaggregate, need				   an implied do loop */				if( (ep->voffset || ep->vsubs) &&				    (ep->vdim || ep->vtypep) )					p->datap = enloop(q);				else					q->ioexpr = simple(LVAL,ep);				}			break;		default:			badtag("ioblock", q->tag);		}}/* replace an aggregate by an implied do loop of elements */struct iogroup *enloop(p)struct ioitem *p;{register struct doblock *dop;struct iogroup *gp;ptr np, q, v, arrsize(), mkioitem();int nrep, k, nwd;q = p->ioexpr;np = arrsize(q);if( ! isicon(np, &nrep) )	nrep = 0;if(q->vtype == TYCHAR)	{	nwd = ceil(conval(q->vtypep), tailor.ftnchwd);	if(nwd != 1)		np = simple(LVAL, mknode(TAROP,OPSTAR,np,mkint(nwd)));	}else	nwd = 0;if( isicon(np, &k) && k==1)	return(p);dop = ALLOC(doblock);dop->tag = TDOBLOCK;dop->dovar = v = gent(TYINT, PNULL);dop->dopar[0] = mkint(1);dop->dopar[1] = simple(SUBVAL, np);dop->dopar[2] = NULL;q = simple(LVAL, q);if(q->vsubs == NULL)	q->vsubs = mknode(TLIST,0, mkchain(cpexpr(v),CHNULL), PNULL);else	q->vsubs->leftp->datap = simple(SUBVAL, mknode(TAROP,OPPLUS, cpexpr(v),		     mknode(TAROP,OPMINUS,q->vsubs->leftp->datap,mkint(1))));q->vdim = NULL;gp = mkiogroup( mkchain(mkioitem(q,CNULL), CHNULL), p->iofmt, dop);gp->nrep = nrep;cfree(p);return(gp);}ptr mkformat(letter, n1, n2)char letter;register ptr n1, n2;{char f[20], *fp, *s;int k;if(letter == 's')	{	if(n1)		{		k = conval(n1);		frexpr(n1);		}	else	k = 1;	for(fp = f; k-->0 ; )		*fp++ = '/';	*fp = '\0';	return( copys(f) );	}f[0] = letter;fp = f+1;if(n1)	{	n1 = simple(RVAL,n1);	if(n1->tag==TCONST && n1->vtype==TYINT)		{		for(s = n1->leftp ; *s; )			*fp++ = *s++;		}	else	execerr("bad format component %s", n1->leftp);	frexpr(n1);	}if(n2)	{	if(n2->tag==TCONST && n2->vtype==TYINT)		{		*fp++ = '.';		for(s = n2->leftp ; *s; )			*fp++ = *s++;		}	else	execerr("bad format component %s", n2->leftp);	frexpr(n2);	}if( letter == 'x' )	{	if(n1 == 0)		*fp++ = '1';	fp[0] = 'x';	fp[1] = '\0';	return( copys(f+1) );	}else	{	*fp = '\0';	return( copys(f) );	}}ptr mkioitem(e,f)register ptr e;char *f;{register ptr p;char fmt[10];ptr gentemp();p = ALLOC(ioitem);p->tag = TIOITEM;if(e!=NULL && e->tag==TCONST)	if(e->vtype==TYCHAR && (f==0 || (f[0]=='c' && f[1]=='\0') ))		{		p->ioexpr = 0;		sprintf(msg, "%dh%s", strlen(e->leftp), e->leftp);		p->iofmt = copys(msg);		frexpr(e);		return(p);		}	else	e = mknode(TASGNOP,OPASGN,gentemp(e),e);if(e && e->vtype==TYCHAR && f && f[0]=='c' && f[1]=='\0')	f = NULL;if(f == NULL)	{	switch(e->vtype)		{		case TYINT:		case TYREAL:		case TYLREAL:		case TYCOMPLEX:		case TYLOG:			f = copys( tailor.dfltfmt[e->vtype] );			break;		case TYCHAR:			if(e->vtypep->tag != TCONST)				{				execerr("no adjustable character formats", "");				f = 0;				}			else	{				sprintf(fmt, "c%s", e->vtypep->leftp);				f = copys(fmt);				}			break;		default:			execerr("cannot do I/O on structures", "");			f = 0;			break;		}	}p->ioexpr = e;p->iofmt = f;return(p);}ptr arrsize(p)ptr p;{register ptr b;ptr f, q;q = mkint(1);if(b = p->vdim)    for(b = b->datap ; b ; b = b->nextp)	{	if(b->upperb == 0) continue;	f = cpexpr(b->upperb);	if(b->lowerb)		f = mknode(TAROP,OPPLUS,f,			mknode(TAROP,OPMINUS,mkint(1),cpexpr(b->lowerb)));	q = simple(RVAL, mknode(TAROP,OPSTAR,q,f));	}return(q);}repfac(dop)register struct doblock *dop;{int m1, m2, m3;m3 = 1;if( isicon(dop->dopar[0],&m1) &&  isicon(dop->dopar[1],&m2) &&  (dop->dopar[2]==NULL || isicon(dop->dopar[2],&m3)) )	{	if(m3 > 0)		return(1 + (m2-m1)/m3);	}else	execerr("nonconstant implied do", "");return(1);}ioop(s)char *s;{if( equals(s, "backspace") )	return(FBACKSPACE);if( equals(s, "rewind") )	return(FREWIND);if( equals(s, "endfile") )	return(FENDFILE);return(0);}ptr exioop(p, errcheck)register struct exprblock *p;int errcheck;{register ptr q, t;if( (q = p->rightp)==NULL || (q = q->leftp)==NULL  )	{	execerr("bad I/O operation", "");	return(NULL);	}q = simple(LVAL, cpexpr(q->datap) );exlab(0);putic(ICKEYWORD, ioop(p->leftp->sthead->namep));if(errcheck)	{	if(tailor.errmode != IOERRFORT77)		{		execerr("cannot test value of IOOP without ftn77", "");		return( errnode() );		}	putic(ICOP, OPLPAR);	prexpr(q);	putic(ICOP, OPCOMMA);	putsii(ICCONST, "iostat =");	prexpr(cpexpr( t = gent(TYINT,PNULL)));	putic(ICOP, OPRPAR);	return( t );	}else	{	putic(ICBLANK, 1);	prexpr(q);	}}

⌨️ 快捷键说明

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