data.c

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

C
2,632
字号
#ifndef lintstatic	char	*sccsid = "@(#)data.c	4.1	(ULTRIX)	7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 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.	* *									* ************************************************************************//* * data.c * * Routines for handling DATA statements, f77 compiler, 4.2 BSD. * * University of Utah CS Dept modification history: * * $Log:	data.c,v $ * Revision 3.1  84/10/13  01:09:50  donn * Installed Jerry Berkman's version; added UofU comment header. *  */#include "defs.h"#include "data.h"/*  global variables  */flag overlapflag;/*  local variables  */LOCAL char rstatus;LOCAL ftnint rvalue;LOCAL dovars *dvlist;LOCAL int dataerror;LOCAL vallist *grvals;LOCAL int datafile;LOCAL int chkfile;LOCAL long base;/*  Copied from expr.c  */LOCAL letter(c)register int c;{if( isupper(c) )	c = tolower(c);return(c - 'a');}vexpr *cpdvalue(dp)vexpr *dp;{  register dvalue *p;  if (dp->tag != DVALUE)    badtag("cpdvalue", dp->tag);  p = ALLOC(Dvalue);  p->tag = DVALUE;  p->status = dp->dvalue.status;  p->value = dp->dvalue.value;  return ((vexpr *) p);}frvexpr(vp)register vexpr *vp;{  if (vp != NULL)    {      if (vp->tag == DNAME)	free(vp->dname.repr);      else if (vp->tag == DEXPR)	{	  frvexpr(vp->dexpr.left);	  frvexpr(vp->dexpr.right);	}      free((char *) vp);    }  return;}frvlist(vp)register vlist *vp;{  register vlist *t;  while (vp)    {      t = vp->next;      frvexpr(vp->val);      free((char *) vp);      vp = t;    }  return;}frelist(ep)elist *ep;{  register elist *p;  register elist *t;  register aelt *ap;  register dolist *dp;  p = ep;  while (p != NULL)    {      if (p->elt->tag == SIMPLE)	{	  ap = (aelt *) p->elt;	  frvlist(ap->subs);	  if (ap->range != NULL)	    {	      frvexpr(ap->range->low);	      frvexpr(ap->range->high);	      free((char *) ap->range);	    }	  free((char *) ap);	}      else	{	  dp = (dolist *) p->elt;	  frvexpr(dp->dovar);	  frvexpr(dp->init);	  frvexpr(dp->limit);	  frvexpr(dp->step);	  frelist(dp->elts);	  free((char *) dp);	}      t = p;      p = p->next;      free((char *) t);    }  return;}frvallist(vp)vallist *vp;{  register vallist *p;  register vallist *t;  p = vp;  while (p != NULL)    {      frexpr((tagptr) p->value);      t = p;      p = p->next;      free((char *) t);    }  return;}elist *revelist(ep)register elist *ep;{  register elist *next;  register elist *t;  if (ep != NULL)    {      next = ep->next;      ep->next = NULL;      while (next)	{	  t = next->next;	  next->next = ep;	  ep = next;	  next = t;	}    }  return (ep);}vlist *revvlist(vp)vlist *vp;{  register vlist *p;  register vlist *next;  register vlist *t;  if (vp == NULL)    p = NULL;  else    {      p = vp;      next = p->next;      p->next = NULL;      while (next)	{	  t = next->next;	  next->next = p;	  p = next;	  next = t;	}    }  return (p);}vallist *revrvals(vp)vallist *vp;{  register vallist *p;  register vallist *next;  register vallist *t;  if (vp == NULL)    p = NULL;  else    {      p = vp;      next = p->next;      p->next = NULL;      while (next)	{	  t = next->next;	  next->next = p;	  p = next;	  next = t;	}    }  return (p);}vlist *prepvexpr(tail, head)vlist *tail;vexpr *head;{  register vlist *p;  p = ALLOC(Vlist);  p->next = tail;  p->val = head;  return (p);}elist *preplval(tail, head)elist *tail;delt* head;{  register elist *p;  p = ALLOC(Elist);  p->next = tail;  p->elt = head;  return (p);}delt *mkdlval(name, subs, range)vexpr *name;vlist *subs;rpair *range;{  register aelt *p;  p = ALLOC(Aelt);  p->tag = SIMPLE;  p->var = mkname(name->dname.len, name->dname.repr);  p->subs = subs;  p->range = range;  return ((delt *) p);}delt *mkdatado(lvals, dovar, params)elist *lvals;vexpr *dovar;vlist *params;{  static char *toofew = "missing loop parameters";  static char *toomany = "too many loop parameters";  register dolist *p;  register vlist *vp;  register int pcnt;  register dvalue *one;  p = ALLOC(DoList);  p->tag = NESTED;  p->elts = revelist(lvals);  p->dovar = dovar;  vp = params;  pcnt = 0;  while (vp)    {      pcnt++;      vp = vp->next;    }  if (pcnt != 2 && pcnt != 3)    {      if (pcnt < 2)	err(toofew);      else	err(toomany);      p->init = (vexpr *) ALLOC(Derror);      p->init->tag = DERROR;      p->limit = (vexpr *) ALLOC(Derror);      p->limit->tag = DERROR;      p->step = (vexpr *) ALLOC(Derror);      p->step->tag = DERROR;    }  else    {      vp = params;      if (pcnt == 2)	{	  one = ALLOC(Dvalue);	  one->tag = DVALUE;	  one->status = NORMAL;	  one->value = 1;	  p->step = (vexpr *) one;	}      else	{	  p->step = vp->val;	  vp->val = NULL;	  vp = vp->next;	}      p->limit = vp->val;      vp->val = NULL;      vp = vp->next;      p->init = vp->val;      vp->val = NULL;    }  frvlist(params);  return ((delt *) p);}rpair *mkdrange(lb, ub)vexpr *lb, *ub;{  register rpair *p;  p = ALLOC(Rpair);  p->low = lb;  p->high = ub;  return (p);}vallist *mkdrval(repl, val)vexpr *repl;expptr val;{  static char *badtag = "bad tag in mkdrval";  static char *negrepl = "negative replicator";  static char *zerorepl = "zero replicator";  static char *toobig = "replicator too large";  static char *nonconst = "%s is not a constant";  register vexpr *vp;  register vallist *p;  register int status;  register ftnint value;  register int copied;  copied = 0;  if (repl->tag == DNAME)    {      vp = evaldname(repl);      copied = 1;    }  else    vp = repl;  p = ALLOC(ValList);  p->next = NULL;  p->value = (Constp) val;  if (vp->tag == DVALUE)    {      status = vp->dvalue.status;      value = vp->dvalue.value;      if ((status == NORMAL && value < 0) || status == MINLESS1)	{	  err(negrepl);	  p->status = ERRVAL;	}      else if (status == NORMAL)	{	  if (value == 0)	    warn(zerorepl);	  p->status = NORMAL;	  p->repl = value;	}      else if (status == MAXPLUS1)	{	  err(toobig);	  p->status = ERRVAL;	}      else	p->status = ERRVAL;    }  else if (vp->tag == DNAME)    {      errnm(nonconst, vp->dname.len, vp->dname.repr);      p->status = ERRVAL;    }  else if (vp->tag == DERROR)    p->status = ERRVAL;  else    fatal(badtag);  if (copied) frvexpr(vp);  return (p);}/*  Evicon returns the value of the integer constant  *//*  pointed to by token.                              */vexpr *evicon(len, token)register int len;register char *token;{  static char *badconst = "bad integer constant";  static char *overflow = "integer constant too large";  register int i;  register ftnint val;  register int digit;  register dvalue *p;  if (len <= 0)    fatal(badconst);  p = ALLOC(Dvalue);  p->tag = DVALUE;  i = 0;  val = 0;  while (i < len)    {      if (val > MAXINT/10)	{	  err(overflow);	  p->status = ERRVAL;	  goto ret;	}      val = 10*val;      digit = token[i++];      if (!isdigit(digit))	fatal(badconst);      digit = digit - '0';      if (MAXINT - val >= digit)	val = val + digit;      else	if (i == len && MAXINT - val + 1 == digit)	  {	    p->status = MAXPLUS1;	    goto ret;	  }	else	  {	    err(overflow);	    p->status = ERRVAL;	    goto ret;	  }    }  p->status = NORMAL;  p->value = val;ret:  return ((vexpr *) p);}/*  Ivaltoicon converts a dvalue into a constant block.  */expptr ivaltoicon(vp)register vexpr *vp;{  static char *badtag = "bad tag in ivaltoicon";  static char *overflow = "integer constant too large";  register int vs;  register expptr p;  if (vp->tag == DERROR)    return(errnode());  else if (vp->tag != DVALUE)    fatal(badtag);  vs = vp->dvalue.status;  if (vs == NORMAL)    p = mkintcon(vp->dvalue.value);  else if ((MAXINT + MININT == -1) && vs == MINLESS1)    p = mkintcon(MININT);  else if (vs == MAXPLUS1 || vs == MINLESS1)    {      err(overflow);      p = errnode();    }  else    p = errnode();  return (p);}/*  Mkdname stores an identifier as a dname  */vexpr *mkdname(len, str)int len;register char *str;{  register dname *p;  register int i;  register char *s;  s = (char *) ckalloc(len + 1);  i = len;  s[i] = '\0';  while (--i >= 0)    s[i] = str[i];  p = ALLOC(Dname);  p->tag = DNAME;  p->len = len;  p->repr = s;  return ((vexpr *) p);}/*  Getname gets the symbol table information associated with  *//*  a name.  Getname differs from mkname in that it will not   *//*  add the name to the symbol table if it is not already      *//*  present.                                                   */Namep getname(l, s)int l;register char *s;{  struct Hashentry *hp;  int hash;  register Namep q;  register int i;  char n[VL];  hash = 0;  for (i = 0; i < l && *s != '\0'; ++i)    {      hash += *s;      n[i] = *s++;    }  while (i < VL)    n[i++] = ' ';  hash %= maxhash;  hp = hashtab + hash;  while (q = hp->varp)    if (hash == hp->hashval	&& eqn(VL, n, q->varname))      goto ret;    else if (++hp >= lasthash)      hp = hashtab;ret:  return (q);}/*  Evparam returns the value of the constant named by name.  */expptr evparam(np)register vexpr *np;{  static char *badtag = "bad tag in evparam";  static char *undefined = "%s is undefined";  static char *nonconst = "%s is not constant";  register struct Paramblock *tp;  register expptr p;  register int len;  register char *repr;  if (np->tag != DNAME)    fatal(badtag);  len = np->dname.len;  repr = np->dname.repr;  tp = (struct Paramblock *) getname(len, repr);  if (tp == NULL)    {      errnm(undefined, len, repr);      p = errnode();    }  else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))    {      if (tp->paramval->tag != TERROR)        errnm(nonconst, len, repr);      p = errnode();    }  else    p = (expptr) cpexpr(tp->paramval);  return (p);}vexpr *evaldname(dp)vexpr *dp;{  static char *undefined = "%s is undefined";  static char *nonconst = "%s is not a constant";  static char *nonint = "%s is not an integer";  register dvalue *p;  register struct Paramblock *tp;  register int len;  register char *repr;  p = ALLOC(Dvalue);  p->tag = DVALUE;  len = dp->dname.len;  repr = dp->dname.repr;  tp = (struct Paramblock *) getname(len, repr);  if (tp == NULL)    {      errnm(undefined, len, repr);      p->status = ERRVAL;    }  else if (tp->vclass != CLPARAM || !ISCONST(tp->paramval))    {      if (tp->paramval->tag != TERROR)        errnm(nonconst, len, repr);      p->status = ERRVAL;    }  else if (!ISINT(tp->paramval->constblock.vtype))    {      errnm(nonint, len, repr);      p->status = ERRVAL;    }  else    {      if ((MAXINT + MININT == -1)	  && tp->paramval->constblock.const.ci == MININT)	p->status = MINLESS1;      else	{	  p->status = NORMAL;          p->value = tp->paramval->constblock.const.ci;	}    }  return ((vexpr *) p);}vexpr *mkdexpr(op, l, r)register int op;register vexpr *l;register vexpr *r;{  static char *badop = "bad operator in mkdexpr";  register vexpr *p;  switch (op)    {    default:      fatal(badop);    case OPNEG:    case OPPLUS:    case OPMINUS:    case OPSTAR:    case OPSLASH:    case OPPOWER:      break;    }  if ((l != NULL && l->tag == DERROR) || r->tag == DERROR)    {      frvexpr(l);      frvexpr(r);      p = (vexpr *) ALLOC(Derror);      p->tag = DERROR;    }  else if (op == OPNEG && r->tag == DVALUE)    {      p = negival(r);      frvexpr(r);    }  else if (op != OPNEG && l->tag == DVALUE && r->tag == DVALUE)    {      switch (op)	{	case OPPLUS:	  p = addivals(l, r);	  break;	case OPMINUS:	  p = subivals(l, r);	  break;	case OPSTAR:	  p = mulivals(l, r);	  break;	case OPSLASH:	  p = divivals(l, r);	  break;	case OPPOWER:	  p = powivals(l, r);	  break;	}      frvexpr(l);      frvexpr(r);    }  else    {      p = (vexpr *) ALLOC(Dexpr);      p->tag = DEXPR;      p->dexpr.opcode = op;      p->dexpr.left = l;      p->dexpr.right = r;    }  return (p);}vexpr *addivals(l, r)vexpr *l;vexpr *r;{  static char *badtag = "bad tag in addivals";  static char *overflow = "integer value too large";  register int ls, rs;  register ftnint lv, rv;  register dvalue *p;  register ftnint k;  if (l->tag != DVALUE || r->tag != DVALUE)    fatal(badtag);  ls = l->dvalue.status;  lv = l->dvalue.value;  rs = r->dvalue.status;  rv = r->dvalue.value;  p = ALLOC(Dvalue);  p->tag = DVALUE;  if (ls == ERRVAL || rs == ERRVAL)    p->status = ERRVAL;  else if (ls == NORMAL && rs == NORMAL)    {      addints(lv, rv);      if (rstatus == ERRVAL)	err(overflow);      p->status = rstatus;      p->value = rvalue;    }  else    {      if (rs == MAXPLUS1 || rs == MINLESS1)	{	  rs = ls;	  rv = lv;	  ls = r->dvalue.status;	}      if (rs == NORMAL && rv == 0)	p->status = ls;      else if (ls == MAXPLUS1)	{	  if (rs == NORMAL && rv < 0)	    {	      p->status = NORMAL;

⌨️ 快捷键说明

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