/* * Copyright (c) 2002 Larry Doolittle (larry@doolittle.boa.org) * * This source code is free software; you can redistribute it * and/or modify it in source code form under the terms of the GNU * General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT #ident "$Id: vpip_to_dec.cc,v 1.6 2002/08/12 01:35:09 steve Exp $" #endif # include "config.h" # include "vpi_priv.h" # include # include # include /* for CHAR_BIT */ # include # include #ifdef HAVE_MALLOC_H # include #endif # include /* If you are allergic to malloc, you can set a stack memory allocation * here. Otherwise, malloc() is used for the temporary array, so the * conversion length is unlimited. */ /* #define MAX_DIGITS 20 */ #if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 64 #define BDIGITS 9 #define BASE 1000000000 #define BBITS 32 #define BMASK 0xffffffff #else #if SIZEOF_UNSIGNED_LONG * CHAR_BIT >= 32 #define BDIGITS 4 #define BASE 10000 #define BBITS 16 #define BMASK 0xffff #else #error apparent non-conforming word length #endif #endif #define B_IS0(x) ((x) == 0) #define B_IS1(x) ((x) == 1) #define B_ISX(x) ((x) == 2) #define B_ISZ(x) ((x) == 3) /* The program works by building a base BASE representation of the number * in the valv array. BBITS bits of the number can be put in at a time. * Previous values of each valv element are always less than BASE, the * input val is less than or equal to 2^BBITS, so (valv[i]<=0; --i) { segment[i] = '0' + v%10; v=v/10; } for (i=0; i vlen_alloc) { if (valv) free(valv); valv = (unsigned long*) calloc( vlen+ALLOC_MARGIN, sizeof (*valv)); if (!valv) {perror("malloc"); return 0; } vlen_alloc=vlen+ALLOC_MARGIN; } else { memset(valv,0,vlen*sizeof(valv[0])); } for (idx = 0; idx < mbits; idx += 1) { /* printf("%c ",bits[mbits-idx-1]); */ if (B_ISZ(bits[mbits-idx-1])) count_z++; else if (B_ISX(bits[mbits-idx-1])) count_x++; else if (!comp && B_IS1(bits[mbits-idx-1])) ++val; else if ( comp && B_IS0(bits[mbits-idx-1])) ++val; if ((mbits-idx-1)%BBITS==0) { /* make negative 2's complement, not 1's complement */ if (comp && idx==mbits-1) ++val; shift_in(valv,vlen,val); val=0; } else { val=val+val; } } if (count_x == nbits) { len = 1; buf[0] = 'x'; buf[1] = 0; } else if (count_x > 0) { len = 1; buf[0] = 'X'; buf[1] = 0; } else if (count_z == nbits) { len = 1; buf[0] = 'z'; buf[1] = 0; } else if (count_z > 0) { len = 1; buf[0] = 'Z'; buf[1] = 0; } else { int i; int zero_suppress=1; if (comp) { *buf++='-'; nbuf--; /* printf("-"); */ } for (i=vlen-1; i>=0; i--) { zero_suppress = write_digits(valv[i], &buf,&nbuf,zero_suppress); /* printf(",%.4u",valv[i]); */ } /* Awkward special case, since we don't want to * zero suppress down to nothing at all. The only * way we can still have zero_suppress on in the * comp=1 case is if mbits==0, and therefore vlen==0. * We represent 1'sb1 as "-1". */ if (zero_suppress) *buf++='0'+comp; /* printf("\n"); */ *buf='\0'; } /* hold on to the memory, since we expect to be called again. */ /* free(valv); */ return 0; } void vpip_dec_str_to_bits(unsigned char*bits, unsigned nbits, const char*buf, bool signed_flag) { /* The str string is the decimal value with the least significant digit first. This loop creates that string by reversing the order of the buf string. For example, if the input is "1234", str gets "4321". */ unsigned slen = strlen(buf); char*str = new char[slen + 1]; for (unsigned idx = 0 ; idx < slen ; idx += 1) { if (isdigit(buf[slen-idx-1])) str[idx] = buf[slen-idx-1]; else str[idx] = '0'; } str[slen] = 0; for (unsigned idx = 0 ; idx < nbits ; idx += 1) { unsigned val = 0; switch (str[0]) { case '1': case '3': case '5': case '7': case '9': val = 1; break; } bits[idx] = val; /* Divide the str string by 2 in decimal. */ char*cp = str; while (*cp) { unsigned val = cp[0] - '0'; if ((val&1) && (cp > str)) cp[-1] += 5; cp[0] = '0' + val/2; cp += 1; } } delete[]str; } /* * $Log: vpip_to_dec.cc,v $ * Revision 1.6 2002/08/12 01:35:09 steve * conditional ident string using autoconfig. * * Revision 1.5 2002/05/17 04:05:38 steve * null terminate the reversed decimal string * * Revision 1.4 2002/05/11 04:39:36 steve * Set and get memory words by string value. * */