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*SZADDRfmtstmt(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 + -
显示快捷键?