io.c

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

C
1,235
字号
#ifndef lintstatic char	*sccsid = " @(#)io.c	1.3	(ULTRIX)	1/15/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	David Metsky		14-Jan-86** 001	Replaced old version with BSD 4.3 version as part of upgrade.**	Based on:	io.c		5.1		85/06/07**************************************************************************//* * io.c * * Routines to generate code for I/O statements. * Some corrections and improvements due to David Wasley, U. C. Berkeley * * University of Utah CS Dept modification history: * * $Header: io.c,v 2.4 85/02/23 21:09:02 donn Exp $ * $Log:	io.c,v $ * Revision 2.4  85/02/23  21:09:02  donn * Jerry Berkman's compiled format fixes move setfmt into a separate file. *  * Revision 2.3  85/01/10  22:33:41  donn * Added some strategic cpexpr()s to prevent memory management bugs. *  * Revision 2.2  84/08/04  21:15:47  donn * Removed code that creates extra statement labels, per Jerry Berkman's * fixes to make ASSIGNs work right. *  * Revision 2.1  84/07/19  12:03:33  donn * Changed comment headers for UofU. *  * Revision 1.2  84/02/26  06:35:57  donn * Added Berkeley changes necessary for shortening offsets to data. *  *//* TEMPORARY */#define TYIOINT TYLONG#define SZIOINT SZLONG#include "defs.h"#include "io.h"LOCAL char ioroutine[XL+1];LOCAL int ioendlab;LOCAL int ioerrlab;LOCAL int endbit;LOCAL int errbit;LOCAL int jumplab;LOCAL int skiplab;LOCAL int ioformatted;LOCAL int statstruct = NO;LOCAL ftnint blklen;LOCAL offsetlist *mkiodata();#define UNFORMATTED 0#define FORMATTED 1#define LISTDIRECTED 2#define NAMEDIRECTED 3#define V(z)	ioc[z].iocval#define IOALL 07777LOCAL struct Ioclist	{	char *iocname;	int iotype;	expptr iocval;	} ioc[ ] =	{		{ "", 0 },		{ "unit", IOALL },		{ "fmt", M(IOREAD) | M(IOWRITE) },		{ "err", IOALL },		{ "end", M(IOREAD) },		{ "iostat", IOALL },		{ "rec", M(IOREAD) | M(IOWRITE) },		{ "recl", M(IOOPEN) | M(IOINQUIRE) },		{ "file", M(IOOPEN) | M(IOINQUIRE) },		{ "status", M(IOOPEN) | M(IOCLOSE) },		{ "access", M(IOOPEN) | M(IOINQUIRE) },		{ "form", M(IOOPEN) | M(IOINQUIRE) },		{ "blank", M(IOOPEN) | M(IOINQUIRE) },		{ "exist", M(IOINQUIRE) },		{ "opened", M(IOINQUIRE) },		{ "number", M(IOINQUIRE) },		{ "named", M(IOINQUIRE) },		{ "name", M(IOINQUIRE) },		{ "sequential", M(IOINQUIRE) },		{ "direct", M(IOINQUIRE) },		{ "formatted", M(IOINQUIRE) },		{ "unformatted", M(IOINQUIRE) },		{ "nextrec", M(IOINQUIRE) }	} ;#define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1)#define MAXIO	SZFLAG + 10*SZIOINT + 15*SZADDR#define IOSUNIT 1#define IOSFMT 2#define IOSERR 3#define IOSEND 4#define IOSIOSTAT 5#define IOSREC 6#define IOSRECL 7#define IOSFILE 8#define IOSSTATUS 9#define IOSACCESS 10#define IOSFORM 11#define IOSBLANK 12#define IOSEXISTS 13#define IOSOPENED 14#define IOSNUMBER 15#define IOSNAMED 16#define IOSNAME 17#define IOSSEQUENTIAL 18#define IOSDIRECT 19#define IOSFORMATTED 20#define IOSUNFORMATTED 21#define IOSNEXTREC 22#define IOSTP V(IOSIOSTAT)/* offsets in generated structures */#define SZFLAG SZIOINT/* offsets for external READ and WRITE statements */#define XERR 0#define XUNIT	SZFLAG#define XEND	SZFLAG + SZIOINT#define XFMT	2*SZFLAG + SZIOINT#define XREC	2*SZFLAG + SZIOINT + SZADDR#define XRLEN	2*SZFLAG + 2*SZADDR#define XRNUM	2*SZFLAG + 2*SZADDR + SZIOINT/* offsets for internal READ and WRITE statements */#define XIERR	0#define XIUNIT	SZFLAG#define XIEND	SZFLAG + SZADDR#define XIFMT	2*SZFLAG + SZADDR#define XIRLEN	2*SZFLAG + 2*SZADDR#define XIRNUM	2*SZFLAG + 2*SZADDR + SZIOINT#define XIREC	2*SZFLAG + 2*SZADDR + 2*SZIOINT/* offsets for OPEN statements */#define XFNAME	SZFLAG + SZIOINT#define XFNAMELEN	SZFLAG + SZIOINT + SZADDR#define XSTATUS	SZFLAG + 2*SZIOINT + SZADDR#define XACCESS	SZFLAG + 2*SZIOINT + 2*SZADDR#define XFORMATTED	SZFLAG + 2*SZIOINT + 3*SZADDR#define XRECLEN	SZFLAG + 2*SZIOINT + 4*SZADDR#define XBLANK	SZFLAG + 3*SZIOINT + 4*SZADDR/* offset for CLOSE statement */#define XCLSTATUS	SZFLAG + SZIOINT/* offsets for INQUIRE statement */#define XFILE	SZFLAG + SZIOINT#define XFILELEN	SZFLAG + SZIOINT + SZADDR#define XEXISTS	SZFLAG + 2*SZIOINT + SZADDR#define XOPEN	SZFLAG + 2*SZIOINT + 2*SZADDR#define XNUMBER	SZFLAG + 2*SZIOINT + 3*SZADDR#define XNAMED	SZFLAG + 2*SZIOINT + 4*SZADDR#define XNAME	SZFLAG + 2*SZIOINT + 5*SZADDR#define XNAMELEN	SZFLAG + 2*SZIOINT + 6*SZADDR#define XQACCESS	SZFLAG + 3*SZIOINT + 6*SZADDR#define XQACCLEN	SZFLAG + 3*SZIOINT + 7*SZADDR#define XSEQ	SZFLAG + 4*SZIOINT + 7*SZADDR#define XSEQLEN	SZFLAG + 4*SZIOINT + 8*SZADDR#define XDIRECT	SZFLAG + 5*SZIOINT + 8*SZADDR#define XDIRLEN	SZFLAG + 5*SZIOINT + 9*SZADDR#define XFORM	SZFLAG + 6*SZIOINT + 9*SZADDR#define XFORMLEN	SZFLAG + 6*SZIOINT + 10*SZADDR#define XFMTED	SZFLAG + 7*SZIOINT + 10*SZADDR#define XFMTEDLEN	SZFLAG + 7*SZIOINT + 11*SZADDR#define XUNFMT	SZFLAG + 8*SZIOINT + 11*SZADDR#define XUNFMTLEN	SZFLAG + 8*SZIOINT + 12*SZADDR#define XQRECL	SZFLAG + 9*SZIOINT + 12*SZADDR#define XNEXTREC	SZFLAG + 9*SZIOINT + 13*SZADDR#define XQBLANK	SZFLAG + 9*SZIOINT + 14*SZADDR#define XQBLANKLEN	SZFLAG + 9*SZIOINT + 15*SZADDRfmtstmt(lp)register struct Labelblock *lp;{if(lp == NULL)	{	execerr("unlabeled format statement" , CNULL);	return(-1);	}if(lp->labtype == LABUNKNOWN)	lp->labtype = LABFORMAT;else if(lp->labtype != LABFORMAT)	{	execerr("bad format number", CNULL);	return(-1);	}return(lp->labelno);}startioctl(){register int i;inioctl = YES;nioctl = 0;ioformatted = UNFORMATTED;for(i = 1 ; i<=NIOS ; ++i)	V(i) = NULL;}endioctl(){int i;expptr p;inioctl = NO;/* set up for error recovery */ioerrlab = ioendlab = skiplab = jumplab = 0;if(p = V(IOSEND))	if(ISICON(p))		ioendlab = execlab(p->constblock.const.ci) ->labelno;	else		err("bad end= clause");if(p = V(IOSERR))	if(ISICON(p))		ioerrlab = execlab(p->constblock.const.ci) ->labelno;	else		err("bad err= clause");if(IOSTP)	if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) )		{		err("iostat must be an integer variable");		frexpr(IOSTP);		IOSTP = NULL;		}if(iostmt == IOREAD)	{	if(IOSTP)		{		if(ioerrlab && ioendlab && ioerrlab==ioendlab)			jumplab = ioerrlab;		else			skiplab = jumplab = newlabel();		}	else	{		if(ioerrlab && ioendlab && ioerrlab!=ioendlab)			{			IOSTP = (expptr) mktemp(TYINT, PNULL);			skiplab = jumplab = newlabel();			}		else			jumplab = (ioerrlab ? ioerrlab : ioendlab);		}	}else if(iostmt == IOWRITE)	{	if(IOSTP && !ioerrlab)		skiplab = jumplab = newlabel();	else		jumplab = ioerrlab;	}else	jumplab = ioerrlab;endbit = IOSTP!=NULL || ioendlab!=0;	/* for use in startrw() */errbit = IOSTP!=NULL || ioerrlab!=0;if(iostmt!=IOREAD && iostmt!=IOWRITE)	{	if(ioblkp == NULL)		ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL);	ioset(TYIOINT, XERR, ICON(errbit));	}switch(iostmt)	{	case IOOPEN:		dofopen();  break;	case IOCLOSE:		dofclose();  break;	case IOINQUIRE:		dofinquire();  break;	case IOBACKSPACE:		dofmove("f_back"); break;	case IOREWIND:		dofmove("f_rew");  break;	case IOENDFILE:		dofmove("f_end");  break;	case IOREAD:	case IOWRITE:		startrw();  break;	default:		fatali("impossible iostmt %d", iostmt);	}for(i = 1 ; i<=NIOS ; ++i)	if(i!=IOSIOSTAT && V(i)!=NULL)		frexpr(V(i));}iocname(){register int i;int found, mask;found = 0;mask = M(iostmt);for(i = 1 ; i <= NIOS ; ++i)	if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname))		if(ioc[i].iotype & mask)			return(i);		else	found = i;if(found)	errstr("invalid control %s for statement", ioc[found].iocname);else	errstr("unknown iocontrol %s", varstr(toklen, token) );return(IOSBAD);}ioclause(n, p)register int n;register expptr p;{struct Ioclist *iocp;++nioctl;if(n == IOSBAD)	return;if(n == IOSPOSITIONAL)	{	if(nioctl > IOSFMT)		{		err("illegal positional iocontrol");		return;		}	n = nioctl;	}if(p == NULL)	{	if(n == IOSUNIT)		p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT);	else if(n != IOSFMT)		{		err("illegal * iocontrol");		return;		}	}if(n == IOSFMT)	ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED);iocp = & ioc[n];if(iocp->iocval == NULL)	{	p = (expptr) cpexpr(p);	if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) )		p = fixtype(p);	if(p!=NULL && ISCONST(p) && p->constblock.vtype==TYCHAR)		p = (expptr) putconst(p);	iocp->iocval = p;}else	errstr("iocontrol %s repeated", iocp->iocname);}/* io list item */doio(list)chainp list;{expptr call0();if(ioformatted == NAMEDIRECTED)	{	if(list)		err("no I/O list allowed in NAMELIST read/write");	}else	{	doiolist(list);	ioroutine[0] = 'e';	putiocall( call0(TYINT, ioroutine) );	}}LOCAL doiolist(p0)chainp p0;{chainp p;register tagptr q;register expptr qe;register Namep qn;Addrp tp, mkscalar();int range;expptr expr;for (p = p0 ; p ; p = p->nextp)	{	q = p->datap;	if(q->tag == TIMPLDO)		{		exdo(range=newlabel(), q->impldoblock.impdospec);		doiolist(q->impldoblock.datalist);		enddo(range);		free( (charptr) q);		}	else	{		if(q->tag==TPRIM && q->primblock.argsp==NULL		    && q->primblock.namep->vdim!=NULL)			{			vardcl(qn = q->primblock.namep);			if(qn->vdim->nelt)				putio( fixtype(cpexpr(qn->vdim->nelt)),					mkscalar(qn) );			else				err("attempt to i/o array of unknown size");			}		else if(q->tag==TPRIM && q->primblock.argsp==NULL &&		    (qe = (expptr) memversion(q->primblock.namep)) )			putio(ICON(1),qe);		else if( (qe = fixtype(cpexpr(q)))->tag==TADDR)			putio(ICON(1), qe);		else if(qe->headblock.vtype != TYERROR)			{			if(iostmt == IOWRITE)				{				ftnint lencat();				expptr qvl;				qvl = NULL;				if( ISCHAR(qe) )					{					qvl = (expptr)						cpexpr(qe->headblock.vleng);					tp = mktemp(qe->headblock.vtype,						     ICON(lencat(qe)));					}				else					tp = mktemp(qe->headblock.vtype,						qe->headblock.vleng);				if (optimflag)					{					expr = mkexpr(OPASSIGN,cpexpr(tp),qe);					optbuff (SKEQ,expr,0,0);					}				else					puteq (cpexpr(tp),qe);				if(qvl)	/* put right length on block */					{					frexpr(tp->vleng);					tp->vleng = qvl;					}				putio(ICON(1), tp);				}			else				err("non-left side in READ list");			}		frexpr(q);		}	}frchain( &p0 );}LOCAL putio(nelt, addr)expptr nelt;register expptr addr;{int type;register expptr q;type = addr->headblock.vtype;if(ioformatted!=LISTDIRECTED && ISCOMPLEX(type) )	{	nelt = mkexpr(OPSTAR, ICON(2), nelt);	type -= (TYCOMPLEX-TYREAL);	}/* pass a length with every item.  for noncharacter data, fake one */if(type != TYCHAR)	{	addr->headblock.vtype = TYCHAR;	addr->headblock.vleng = ICON( typesize[type] );	}nelt = fixtype( mkconv(TYLENG,nelt) );if(ioformatted == LISTDIRECTED)	q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr);else	q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"),		nelt, addr);putiocall(q);}endio(){if(skiplab)	{	if (optimflag)		optbuff (SKLABEL, 0, skiplab, 0);	else		putlabel (skiplab);	if(ioendlab)		{		expptr test;		test = mkexpr(OPGE, cpexpr(IOSTP), ICON(0));		if (optimflag)			optbuff (SKIOIFN,test,ioendlab,0);		else			putif (test,ioendlab);		}	if(ioerrlab)		{		expptr test;		test = mkexpr			( ((iostmt==IOREAD||iostmt==IOWRITE) ? OPLE : OPEQ),			cpexpr(IOSTP), ICON(0));		if (optimflag)			optbuff (SKIOIFN,test,ioerrlab,0);		else			putif (test,ioerrlab);		}	}if(IOSTP)	frexpr(IOSTP);}LOCAL putiocall(q)register expptr q;{if(IOSTP)	{	q->headblock.vtype = TYINT;	q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q));	}if(jumplab)	if (optimflag)		optbuff (SKIOIFN,mkexpr(OPEQ,q,ICON(0)),jumplab,0);	else

⌨️ 快捷键说明

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