data.c

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

C
2,632
字号
  repr = dp->dovar->dname.repr;  found = NO;  dvp = dvlist;  while (found == NO && dvp != NULL)    if (len == dvp->len && eqn(len, repr, dvp->repr))      found = YES;    else      dvp = dvp->next;  if (found == YES)    {      errnm(duplicates, len, repr);      dataerror = YES;    }  else    {      np = getname(len, repr);      if (np == NULL)	{	  if (!ISINT(impltype[letter(*repr)]))	    warnnm(nonint, len, repr);	}      else	{	  if (np->vclass == CLUNKNOWN)	    vardcl(np);	  if (np->vclass != CLVAR)	    warnnm(nonvar, len, repr);	  else if (!ISINT(np->vtype))	    warnnm(nonint, len, repr);	}    }  t = ALLOC(DoVars);  t->next = dvlist;  t->len = len;  t->repr = repr;  t->valp = ALLOC(Dvalue);  t->valp->tag = DVALUE;  dp->dovar = (vexpr *) t->valp;  dvlist = t;  refriglvals(dp->elts);  dvlist = t->next;  free((char *) t);  return;}refriglvals(lvals)elist *lvals;{  register elist *top;  top = lvals;  while (top != NULL)    {      if (top->elt->tag == SIMPLE)	refrigaelt((aelt *) top->elt);      else	refrigdo((dolist *) top->elt);      top = top->next;    }  return;}/*  Refrig freezes name/value bindings in the DATA name list  */refrig(lvals)elist *lvals;{  dvlist = NULL;  refriglvals(lvals);  return;}ftnintindexer(ap)aelt *ap;{  static char *badvar = "bad variable in indexer";  static char *boundserror = "subscript out of bounds";  register ftnint index;  register vlist *sp;  register Namep np;  register struct Dimblock *dp;  register int i;  register dvalue *vp;  register ftnint size;  ftnint sub[MAXDIM];  sp = ap->subs;  if (sp == NULL) return (0);  np = ap->var;  dp = np->vdim;  if (dp == NULL)    fatal(badvar);  i = 0;  while (sp != NULL)    {      vp = (dvalue *) evalvexpr(sp->val);      if (vp->status == NORMAL)	sub[i++] = vp->value;      else if ((MININT + MAXINT == -1) && vp->status == MINLESS1)	sub[i++] = MININT;      else	{	  frvexpr((vexpr *) vp);	  return (-1);	}      frvexpr((vexpr *) vp);      sp = sp->next;    }  index = sub[--i];  while (i-- > 0)    {      size = dp->dims[i].dimsize->constblock.const.ci;      index = sub[i] + index * size;    }  index -= dp->baseoffset->constblock.const.ci;  if (index < 0 || index >= dp->nelt->constblock.const.ci)    {      err(boundserror);      return (-1);    }  return (index);}savedata(lvals, rvals)elist *lvals;vallist *rvals;{  static char *toomany = "more data values than data items";  register elist *top;  dataerror = NO;  badvalue = NO;  lvals = revelist(lvals);  grvals = revrvals(rvals);  refrig(lvals);  if (!dataerror)    outdata(lvals);  frelist(lvals);  while (grvals != NULL && dataerror == NO)    {      if (grvals->status != NORMAL)	dataerror = YES;      else if (grvals->repl <= 0)        grvals = grvals->next;      else	{	  err(toomany);	  dataerror = YES;	}    }      frvallist(grvals);  return;}setdfiles(np)register Namep np;{  register struct Extsym *cp;  register struct Equivblock *ep;  register int stg;  register int type;  register ftnint typelen;  register ftnint nelt;  register ftnint varsize;  stg = np->vstg;  if (stg == STGBSS || stg == STGINIT)    {      datafile = vdatafile;      chkfile = vchkfile;      if (np->init == YES)	base = np->initoffset;      else	{	  np->init = YES;	  np->initoffset = base = vdatahwm;	  if (np->vdim != NULL)	    nelt = np->vdim->nelt->constblock.const.ci;	  else	    nelt = 1;	  type = np->vtype;	  if (type == TYCHAR)	    typelen = np->vleng->constblock.const.ci;	  else if (type == TYLOGICAL)	    typelen = typesize[tylogical];	  else	    typelen = typesize[type];	  varsize = nelt * typelen;	  vdatahwm += varsize;	}    }  else if (stg == STGEQUIV)    {      datafile = vdatafile;      chkfile = vchkfile;      ep = &eqvclass[np->vardesc.varno];      if (ep->init == YES)	base = ep->initoffset;      else	{	  ep->init = YES;	  ep->initoffset = base = vdatahwm;	  vdatahwm += ep->eqvleng;	}      base += np->voffset;    }  else if (stg == STGCOMMON)    {      datafile = cdatafile;      chkfile = cchkfile;      cp = &extsymtab[np->vardesc.varno];      if (cp->init == YES)	base = cp->initoffset;      else	{	  cp->init = YES;	  cp->initoffset = base = cdatahwm;	  cdatahwm += cp->maxleng;	}      base += np->voffset;    }  return;}wrtdata(offset, repl, len, const)long offset;ftnint repl;ftnint len;char *const;{  static char *badoffset = "bad offset in wrtdata";  static char *toomuch = "too much data";  static char *readerror = "read error on tmp file";  static char *writeerror = "write error on tmp file";  static char *seekerror = "seek error on tmp file";  register ftnint k;  long lastbyte;  int bitpos;  long chkoff;  long lastoff;  long chklen;  long pos;  int n;  ftnint nbytes;  int mask;  register int i;  char overlap;  char allzero;  char buff[BUFSIZ];  if (offset < 0)    fatal(badoffset);  overlap = NO;  k = repl * len;  lastbyte = offset + k - 1;  if (lastbyte < 0)    {      err(toomuch);      dataerror = YES;      return;    }  bitpos = offset % BYTESIZE;  chkoff = offset/BYTESIZE;  lastoff = lastbyte/BYTESIZE;  chklen = lastoff - chkoff + 1;  pos = lseek(chkfile, chkoff, 0);  if (pos == -1)    {      err(seekerror);      done(1);    }  while (k > 0)    {      if (chklen <= BUFSIZ)	n = chklen;      else	{	  n = BUFSIZ;	  chklen -= BUFSIZ;	}      nbytes = read(chkfile, buff, n);      if (nbytes < 0)	{	  err(readerror);	  done(1);	}      if (nbytes == 0)	buff[0] = '\0';      if (nbytes < n)	buff[ n-1 ] = '\0';      i = 0;      if (bitpos > 0)	{	  while (k > 0 && bitpos < BYTESIZE)	    {	      mask = 1 << bitpos;	      if (mask & buff[0])		overlap = YES;	      else		buff[0] |= mask;	      k--;	      bitpos++;	    }	  if (bitpos == BYTESIZE)	    {	      bitpos = 0;	      i++;	    }	}      while (i < nbytes && overlap == NO)	{	  if (buff[i] == 0 && k >= BYTESIZE)	    {	      buff[i++] = MAXBYTE;	      k -= BYTESIZE;	    }	  else if (k < BYTESIZE)	    {	      while (k-- > 0)		{		  mask = 1 << k;		  if (mask & buff[i])		    overlap = YES;		  else		    buff[i] |= mask;		}	      i++;	    }	  else	    {	      overlap = YES;	      buff[i++] = MAXBYTE;	      k -= BYTESIZE;	    }	}      while (i < n)	{	  if (k >= BYTESIZE)	    {	      buff[i++] = MAXBYTE;	      k -= BYTESIZE;	    }	  else	    {	      while (k-- > 0)		{		  mask = 1 << k;		  buff[i] |= mask;		}	      i++;	    }	}      pos = lseek(chkfile, -nbytes, 1);      if (pos == -1)	{	  err(seekerror);	  done(1);	}      nbytes = write(chkfile, buff, n);      if (nbytes != n)	{	  err(writeerror);	  done(1);	}    }  if (overlap == NO)    {      allzero = YES;      k = len;      while (k > 0 && allzero != NO)	if (const[--k] != 0) allzero = NO;      if (allzero == YES)	return;    }  pos = lseek(datafile, offset, 0);  if (pos == -1)    {      err(seekerror);      done(1);    }  k = repl;  while (k-- > 0)    {      nbytes = write(datafile, const, len);      if (nbytes != len)	{	  err(writeerror);	  done(1);	}    }  if (overlap) overlapflag = YES;  return;}Constpgetdatum(){  static char *toofew = "more data items than data values";  register vallist *t;  while (grvals != NULL)    {      if (grvals->status != NORMAL)	{	  dataerror = YES;	  return (NULL);	}      else if (grvals->repl > 0)	{	  grvals->repl--;	  return (grvals->value);	}      else	{	  badvalue = 0;	  frexpr ((tagptr) grvals->value);	  t = grvals;	  grvals = t->next;	  free((char *) t);	}    }  err(toofew);  dataerror = YES;  return (NULL);}outdata(lvals)elist *lvals;{  register elist *top;  top = lvals;  while (top != NULL && dataerror == NO)    {      if (top->elt->tag == SIMPLE)	outaelt((aelt *) top->elt);      else	outdolist((dolist *) top->elt);      top = top->next;    }  return;}outaelt(ap)aelt *ap;{  static char *toofew = "more data items than data values";  static char *boundserror = "substring expression out of bounds";  static char *order = "substring expressions out of order";  register Namep np;  register long soffset;  register dvalue *lwb;  register dvalue *upb;  register Constp const;  register int k;  register vallist *t;  register int type;  register ftnint typelen;  register ftnint repl;  extern char *packbytes();  np = ap->var;  setdfiles(np);  type = np->vtype;  if (type == TYCHAR)    typelen = np->vleng->constblock.const.ci;  else if (type == TYLOGICAL)    typelen = typesize[tylogical];  else    typelen = typesize[type];  if (ap->subs != NULL || np->vdim == NULL)    {      soffset = indexer(ap);      if (soffset == -1)	{	  dataerror = YES;	  return;	}      soffset = soffset * typelen;      if (ap->range != NULL)	{	  lwb = (dvalue *) evalvexpr(ap->range->low);	  upb = (dvalue *) evalvexpr(ap->range->high);	  if (lwb->status == ERRVAL || upb->status == ERRVAL)	    {	      frvexpr((vexpr *) lwb);	      frvexpr((vexpr *) upb);	      dataerror = YES;	      return;	    }	  if (lwb->status != NORMAL ||	      lwb->value < 1 ||	      lwb->value > typelen ||	      upb->status != NORMAL ||	      upb->value < 1 ||	      upb->value > typelen)	    {	      err(boundserror);	      frvexpr((vexpr *) lwb);	      frvexpr((vexpr *) upb);	      dataerror = YES;	      return;	    }	  if (lwb->value > upb->value)	    {	      err(order);	      frvexpr((vexpr *) lwb);	      frvexpr((vexpr *) upb);	      dataerror = YES;	      return;	    }	  soffset = soffset + lwb->value - 1;	  typelen = upb->value - lwb->value + 1;	  frvexpr((vexpr *) lwb);	  frvexpr((vexpr *) upb);	}      const = getdatum();      if (const == NULL || !ISCONST(const))	return;      const = (Constp) convconst(type, typelen, const);      if (const == NULL || !ISCONST(const))	{	  frexpr((tagptr) const);	  return;	}      if (type == TYCHAR)	wrtdata(base + soffset, 1, typelen, const->const.ccp);      else	wrtdata(base + soffset, 1, typelen, packbytes(const));      frexpr((tagptr) const);    }  else    {      soffset = 0;      k = np->vdim->nelt->constblock.const.ci;      while (k > 0 && dataerror == NO)	{	  if (grvals == NULL)	    {	      err(toofew);	      dataerror = YES;	    }	  else if (grvals->status != NORMAL)	    dataerror = YES;	  else if (grvals-> repl <= 0)	    {	      badvalue = 0;	      frexpr((tagptr) grvals->value);	      t = grvals;	      grvals = t->next;	      free((char *) t);	    }	  else	    {	      const = grvals->value;	      if (const == NULL || !ISCONST(const))		{		  dataerror = YES;		}	      else		{		  const = (Constp) convconst(type, typelen, const);		  if (const == NULL || !ISCONST(const))		    {		      dataerror = YES;		      frexpr((tagptr) const);		    }		  else		    {		      if (k > grvals->repl)			repl = grvals->repl;		      else			repl = k;		      grvals->repl -= repl;		      k -= repl;		      if (type == TYCHAR)			wrtdata(base+soffset, repl, typelen, const->const.ccp);		      else			wrtdata(base+soffset, repl, typelen, packbytes(const));		      soffset = soffset + repl * typelen;		      frexpr((tagptr) const);		    }		}	    }	}    }  return;}outdolist(dp)dolist *dp;{  static char *zerostep = "zero step in implied-DO";  static char *order = "zero iteration count in implied-DO";  register dvalue *e1, *e2, *e3;  register int direction;  register dvalue *dv;  register int done;  register int addin;  register int ts;  register ftnint tv;  e1 = (dvalue *) evalvexpr(dp->init);  e2 = (dvalue *) evalvexpr(dp->limit);  e3 = (dvalue *) evalvexpr(dp->step);  if (e1->status == ERRVAL ||      e2->status == ERRVAL ||      e3->status == ERRVAL)    {      dataerror = YES;      goto ret;    }  if (e1->status == NORMAL)    {      if (e2->status == NORMAL)	{	  if (e1->value < e2->value)	    direction = 1;	  else if (e1->value > e2->value)	    direction = -1;	  else	    direction = 0;	}      else if (e2->status == MAXPLUS1)	direction = 1;      else	direction = -1;    }  else if (e1->status == MAXPLUS1)    {      if (e2->status == MAXPLUS1)	direction = 0;      else	direction = -1;    }  else    {      if (e2->status == MINLESS1)	direction = 0;      else	direction = 1;    }  if (e3->status == NORMAL && e3->value == 0)    {      err(zerostep);      dataerror = YES;      goto ret;    }  else if (e3->status == MAXPLUS1 ||	   (e3->status == NORMAL && e3->value > 0))    {      if (direction == -1)	{	  warn(order);	  goto ret;	}    }  else    {      if (direction == 1)	{	  warn(order);	  goto ret;	}    }  dv = (dvalue *) dp->dovar;  dv->status = e1->status;  dv->value = e1->value;  done = NO;  while (done == NO && dataerror == NO)    {      outdata(dp->elts);      if (e3->status == NORMAL && dv->status == NORMAL)	{	  addints(e3->value, dv->value);	  dv->status = rstatus;	  dv->value = rvalue;	}      else	{	  if (e3->status != NORMAL)	    {	      if (e3->status == MAXPLUS1)		addin = MAXPLUS1;	      else		addin = MINLESS1;	      ts = dv->status;	      tv = dv->value;	    }	  else	    {	      if (dv->status == MAXPLUS1)		addin = MAXPLUS1;	      else		addin = MINLESS1;	      ts = e3->status;	      tv = e3->value;	    }	  if (addin == MAXPLUS1)	    {	      if (ts == MAXPLUS1 || (ts == NORMAL && tv > 0))		dv->status = ERRVAL;	      else if (ts == NORMAL && tv == 0)		dv->status = MAXPLUS1;	      else if (ts == NORMAL)		{		  dv->status = NORMAL;		  dv->value = tv + MAXINT;		  dv->value++;		}	      else		{		  dv->status = NORMAL;		  dv->value = 0;		}	    }	  else	    {	      if (ts == MINLESS1 || (ts == NORMAL && tv < 0))		dv->status = ERRVAL;	      else if (ts == NORMAL && tv == 0)		dv->status = MINLESS1;	      else if (ts == NORMAL)		{		  dv->status = NORMAL;		  dv->value = tv - MAXINT;		  dv->value--;		}	      else		{		  dv->status = NORMAL;		  dv->value = 0;		}	    }	}      if (dv->status == ERRVAL)	done = YES;      else if (direction > 0)	{	  if (e2->status == NORMAL)	    {	      if (dv->status == MAXPLUS1 ||		  (dv->status == NORMAL && dv->value > e2->value))		done = YES;	    }	}      else if (direction < 0)	{	  if (e2->status == NORMAL)	    {	      if (dv->status == MINLESS1 ||		  (dv->status == NORMAL && dv->value < e2->value))		done = YES;	    }	}      else	done = YES;    }ret:  frvexpr((vexpr *) e1);  frvexpr((vexpr *) e2);  frvexpr((vexpr *) e3);  return;}

⌨️ 快捷键说明

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