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