conv.c

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

C
959
字号
#ifndef lintstatic	char	*sccsid = "@(#)conv.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.	* *									* ************************************************************************//* * conv.c * * Routines for type conversions, f77 compiler pass 1. * * University of Utah CS Dept modification history: * * $Log:	conv.c,v $ * Revision 2.1  84/07/19  12:02:29  donn * Changed comment headers for UofU. *  * Revision 1.2  84/04/13  01:07:02  donn * Fixed value of dminreal to be -1.7e38 + epsilon instead of -2.59e33, per * Bob Corbett's approval. *  */#include "defs.h"#include "conv.h"int badvalue;/*  The following constants are used to check the limits of  *//*  conversions.  Dmaxword is the largest double precision   *//*  number which can be converted to a two-byte integer      *//*  without overflow.  Dminword is the smallest double       *//*  precision value which can be converted to a two-byte     *//*  integer without overflow.  Dmaxint and dminint are the   *//*  analogous values for four-byte integers.                 */LOCAL long dmaxword[] = { 0xfeff47ff, 0xffffffff };LOCAL long dminword[] = { 0x00ffc800, 0xffffffff };LOCAL long dmaxint[]  = { 0xffff4fff, 0xfffffeff };LOCAL long dminint[]  = { 0x0000d000, 0xffff00ff };LOCAL long dmaxreal[] = { 0xffff7fff, 0xffff7fff };LOCAL long dminreal[] = { 0xffffffff, 0xffff7fff };/*  The routines which follow are used to convert  *//*  constants into constants of other types.       */LOCAL char *grabbits(len, cp)int len;Constp cp;{  static char *toobig = "bit value too large";  register char *p;  register char *bits;  register int i;  register int k;  register int lenb;  bits = cp->const.ccp;  lenb = cp->vleng->constblock.const.ci;  p = (char *) ckalloc(len);  if (len >= lenb)    k = lenb;  else    {      k = len;      if ( badvalue == 0 )	{#if (TARGET == PDP11 || TARGET == VAX)	  i = len;	  while ( i < lenb && bits[i] == 0 )	    i++;	  if (i < lenb)	    badvalue = 1;#else	  i = lenb - len - 1;	  while ( i >= 0 && bits[i] == 0)	    i--;	  if (i >= 0)	    badvalue = 1;#endif	  if (badvalue)	    warn(toobig);	}    }#if (TARGET == PDP11 || TARGET == VAX)  i = 0;  while (i < k)    {      p[i] = bits[i];      i++;    }#else  i = lenb;  while (k > 0)    p[--k] = bits[--i];#endif  return (p);}LOCAL char *grabbytes(len, cp)int len;Constp cp;{  register char *p;  register char *bytes;  register int i;  register int k;  register int lenb;  bytes = cp->const.ccp;  lenb = cp->vleng->constblock.const.ci;  p = (char *) ckalloc(len);  if (len >= lenb)    k = lenb;  else    k = len;  i = 0;  while (i < k)    {      p[i] = bytes[i];      i++;    }  while (i < len)    p[i++] = BLANK;  return (p);}LOCAL expptrcshort(cp)Constp cp;{  static char *toobig = "data value too large";  static char *reserved = "reserved operand assigned to an integer";  static char *compat1 = "logical datum assigned to an integer variable";  static char *compat2 = "character datum assigned to an integer variable";  register expptr p;  register short *shortp;  register ftnint value;  register long *rp;  register double *minp;  register double *maxp;  realvalue x;  switch (cp->vtype)    {    case TYBITSTR:      shortp = (short *) grabbits(2, cp);      p = (expptr) mkconst(TYSHORT);      p->constblock.const.ci = *shortp;      free((char *) shortp);      break;    case TYSHORT:      p = (expptr) cpexpr(cp);      break;    case TYLONG:      value = cp->const.ci;      if (value >= MINWORD && value <= MAXWORD)	{	  p = (expptr) mkconst(TYSHORT);	  p->constblock.const.ci = value;	}      else	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(toobig);	    }	  p = errnode();	}      break;    case TYREAL:    case TYDREAL:    case TYCOMPLEX:    case TYDCOMPLEX:      minp = (double *) dminword;      maxp = (double *) dmaxword;      rp = (long *) &(cp->const.cd[0]);      x.q.word1 = rp[0];      x.q.word2 = rp[1];      if (x.f.sign == 1 && x.f.exp == 0)	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(reserved);	    }	  p = errnode();	}      else if (x.d >= *minp && x.d <= *maxp)	{	  p = (expptr) mkconst(TYSHORT);	  p->constblock.const.ci = x.d;	}      else	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(toobig);	    }	  p = errnode();	}      break;    case TYLOGICAL:      if (badvalue <= 1)	{	  badvalue = 2;	  err(compat1);	}      p = errnode();      break;    case TYCHAR:      if ( !ftn66flag && badvalue == 0 )	{	  badvalue = 1;	  warn(compat2);	}    case TYHOLLERITH:      shortp = (short *) grabbytes(2, cp);      p = (expptr) mkconst(TYSHORT);      p->constblock.const.ci = *shortp;      free((char *) shortp);      break;    case TYERROR:      p = errnode();      break;    }  return (p);}LOCAL expptrclong(cp)Constp cp;{  static char *toobig = "data value too large";  static char *reserved = "reserved operand assigned to an integer";  static char *compat1 = "logical datum assigned to an integer variable";  static char *compat2 = "character datum assigned to an integer variable";  register expptr p;  register ftnint *longp;  register long *rp;  register double *minp;  register double *maxp;  realvalue x;  switch (cp->vtype)    {    case TYBITSTR:      longp = (ftnint *) grabbits(4, cp);      p = (expptr) mkconst(TYLONG);      p->constblock.const.ci = *longp;      free((char *) longp);      break;    case TYSHORT:      p = (expptr) mkconst(TYLONG);      p->constblock.const.ci = cp->const.ci;      break;    case TYLONG:      p = (expptr) cpexpr(cp);      break;    case TYREAL:    case TYDREAL:    case TYCOMPLEX:    case TYDCOMPLEX:      minp = (double *) dminint;      maxp = (double *) dmaxint;      rp = (long *) &(cp->const.cd[0]);      x.q.word1 = rp[0];      x.q.word2 = rp[1];      if (x.f.sign == 1 && x.f.exp == 0)	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(reserved);	    }	  p = errnode();	}      else if (x.d >= *minp && x.d <= *maxp)	{	  p = (expptr) mkconst(TYLONG);	  p->constblock.const.ci = x.d;	}      else	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(toobig);	    }	  p = errnode();	}      break;    case TYLOGICAL:      if (badvalue <= 1)	{	  badvalue = 2;	  err(compat1);	}      p = errnode();      break;    case TYCHAR:      if ( !ftn66flag && badvalue == 0 )	{	  badvalue = 1;	  warn(compat2);	}    case TYHOLLERITH:      longp = (ftnint *) grabbytes(4, cp);      p = (expptr) mkconst(TYLONG);      p->constblock.const.ci = *longp;      free((char *) longp);      break;    case TYERROR:      p = errnode();      break;    }  return (p);}LOCAL expptrcreal(cp)Constp cp;{  static char *toobig = "data value too large";  static char *compat1 = "logical datum assigned to a real variable";  static char *compat2 = "character datum assigned to a real variable";  register expptr p;  register long *longp;  register long *rp;  register double *minp;  register double *maxp;  realvalue x;  float y;  switch (cp->vtype)    {    case TYBITSTR:      longp = (long *) grabbits(4, cp);      p = (expptr) mkconst(TYREAL);      rp = (long *) &(p->constblock.const.cd[0]);      rp[0] = *longp;      free((char *) longp);      break;    case TYSHORT:    case TYLONG:      p = (expptr) mkconst(TYREAL);      p->constblock.const.cd[0] = cp->const.ci;      break;    case TYREAL:    case TYDREAL:    case TYCOMPLEX:    case TYDCOMPLEX:      minp = (double *) dminreal;      maxp = (double *) dmaxreal;      rp = (long *) &(cp->const.cd[0]);      x.q.word1 = rp[0];      x.q.word2 = rp[1];      if (x.f.sign == 1 && x.f.exp == 0)	{	  p = (expptr) mkconst(TYREAL);	  rp = (long *) &(p->constblock.const.cd[0]);	  rp[0] = x.q.word1;	}      else if (x.d >= *minp && x.d <= *maxp)	{	  p = (expptr) mkconst(TYREAL);	  y = x.d;	  p->constblock.const.cd[0] = y;	}      else	{	  if (badvalue <= 1)	    {	      badvalue = 2;	      err(toobig);	    }	  p = errnode();	}      break;    case TYLOGICAL:      if (badvalue <= 1)	{	  badvalue = 2;	  err(compat1);	}      p = errnode();      break;    case TYCHAR:      if ( !ftn66flag && badvalue == 0)	{	  badvalue = 1;	  warn(compat2);	}    case TYHOLLERITH:      longp = (long *) grabbytes(4, cp);      p = (expptr) mkconst(TYREAL);      rp = (long *) &(p->constblock.const.cd[0]);      rp[0] = *longp;      free((char *) longp);      break;    case TYERROR:

⌨️ 快捷键说明

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