diff options
Diffstat (limited to 'mixlib')
| -rw-r--r-- | mixlib/mix_types.c | 165 | 
1 files changed, 83 insertions, 82 deletions
| diff --git a/mixlib/mix_types.c b/mixlib/mix_types.c index 3c1cbb8..7f523f3 100644 --- a/mixlib/mix_types.c +++ b/mixlib/mix_types.c @@ -1,35 +1,36 @@  /* -*-c-*- ------------------ mix_types.c :   *  Implementation file for mix_types.h declarations.   * ------------------------------------------------------------------ - * $Id: mix_types.c,v 1.2 2002/04/09 23:53:52 jao Exp $  + * $Id: mix_types.c,v 1.3 2004/06/07 00:01:03 jao Exp $   * ------------------------------------------------------------------ - * Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. - *   + * Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc. + *   * This program is free software; you can redistribute it and/or modify   * it 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. - *   + *   */  #include "mix.h"  #include <limits.h> +#include <ctype.h>  #include "mix_types.h"  /*------------------------ initialisation stuff ------------------------*/  /* flag telling whether a field spec is valid */  static gboolean is_bad_field_[MIX_BYTE_MAX + 1]; -/* shift associated with a fspec */   +/* shift associated with a fspec */  static guint shift_[MIX_BYTE_MAX + 1];  /* mask associated with a fspec */  static glong mask_[MIX_BYTE_MAX + 1]; @@ -52,18 +53,18 @@ mix_init_types (void)  {    guint lt, rt;    for (lt = 0; lt < 8; ++lt) -    for (rt = 0; rt < 8; ++rt)  +    for (rt = 0; rt < 8; ++rt)        {  	guint F = 8 * lt + rt;  	is_bad_field_[F] = rt < lt || 5 < rt;  	if ( is_bad_field_[F] )  	  shift_[F] = 0, mask_[F] = 0; -	else  +	else  	  {  	    guint width = rt - (lt == 0 ? 1 : lt) + 1;  	    shift_[F] = 6 * (5 - rt);  	    mask_[F] = ((1L << (6 * width)) - 1) << shift_[F]; -	  }  +	  }        }    for ( lt = 0; lt < UCHAR_MAX + 1; ++lt ) @@ -75,7 +76,7 @@ mix_init_types (void)  mix_char_t  mix_ascii_to_char (guchar c)  { -  return ascii_to_mix_char_[c]; +  return ascii_to_mix_char_[toupper (c)];  } @@ -94,10 +95,10 @@ mix_bytes_to_word (mix_byte_t *bytes, guint byteno)  {    mix_word_t result = 0;    guint k; -   +    g_return_val_if_fail (bytes != NULL, MIX_WORD_ZERO);    g_return_val_if_fail (byteno != 0, MIX_WORD_ZERO); -   +    if ( byteno > 5 ) byteno = 5;    for ( k = 0; k < byteno; k++ )      result |= ((gulong)bytes[k]) << (6*(byteno-k-1)); @@ -113,7 +114,7 @@ mix_word_get_field (mix_fspec_t f, mix_word_t word)    mix_word_t result;    g_return_val_if_fail (!is_bad_field_[f],MIX_WORD_ZERO); -   +    result = ( (word & mask_[f]) >> shift_[f] );    if (f < 8)      /* if f is of the form (0:R), retain the sign of word */      result |= mix_word_sign (word); @@ -129,13 +130,13 @@ mix_word_set_field (mix_fspec_t f, mix_word_t from, mix_word_t to)    glong m = mask_[f];    g_return_val_if_fail (!is_bad_field_[f],to); -   +    if (f < 8)      /* if F is of the form (0:R), use the sign of -from- */ -    result =  (to & ~m & ~MIX_WORD_SIGN_BIT)  +    result =  (to & ~m & ~MIX_WORD_SIGN_BIT)        | ((from /*<< shift_[f]*/) & m) | mix_word_sign (from);    else      result = (to & ~m) | ((from /*<< shift_[f]*/) & m); -   +    return result;  } @@ -146,16 +147,16 @@ mix_word_store_field (mix_fspec_t f, mix_word_t from, mix_word_t to)    glong m = mask_[f];    g_return_val_if_fail (!is_bad_field_[f],to); -   +    if (f < 8)      /* if F is of the form (0:R), use the sign of -from- */ -    result =  (to & ~m & ~MIX_WORD_SIGN_BIT)  +    result =  (to & ~m & ~MIX_WORD_SIGN_BIT)        | ((from << shift_[f]) & m) | mix_word_sign (from);    else      result = (to & ~m) | ((from << shift_[f]) & m); -   +    return result;  } -   +  gboolean @@ -164,19 +165,19 @@ mix_fspec_is_valid (mix_fspec_t f)    return !(is_bad_field_[f]);  } -mix_byte_t  -mix_word_get_byte (mix_word_t word,   /* word parsed */  +mix_byte_t +mix_word_get_byte (mix_word_t word,   /* word parsed */  		   guint idx          /* byte: 1 to 5 */	  )  {    mix_byte_t fspec = mix_fspec_new (idx,idx);    g_return_val_if_fail ((idx > 0 && idx < 6), MIX_BYTE_ZERO); -   +    return mix_byte_new (mix_word_get_field (fspec,word));  } -extern void  +extern void  mix_word_set_byte (mix_word_t *into, guint idx,  mix_byte_t value)  {    mix_word_t from = value; @@ -184,17 +185,17 @@ mix_word_set_byte (mix_word_t *into, guint idx,  mix_byte_t value)    g_return_if_fail (into != NULL);    g_return_if_fail (idx > 0 && idx < 6); -   +    from <<= shift_[fspec];    *into = mix_word_set_field (fspec,from,*into);  }  /* Arithmetic operations */ -mix_word_t  +mix_word_t  mix_word_add (mix_word_t x, mix_word_t y)  {    static const gulong MIX_WORD_MAX_SIM = 2*MIX_WORD_MAX + 1; -   +    gint32 result;    if ( mix_word_sign (x) == mix_word_sign (y) )      { @@ -203,7 +204,7 @@ mix_word_add (mix_word_t x, mix_word_t y)  	/* for instance MIX_WORD_MAX + 1 = - MIX_WORD_MAX */  	result = MIX_WORD_MAX_SIM - result;  	result |= mix_word_sign (mix_word_negative (x)); -      } else if ( result != 0 )       +      } else if ( result != 0 )  	result |= mix_word_sign (x);        /* keep positive sign for 0 so that w - w == -w + w */      } @@ -216,9 +217,9 @@ mix_word_add (mix_word_t x, mix_word_t y)  	result = result|mix_word_sign (x);        /* keep positive sign for 0 so that w - w == -w + w */      } -  +    g_assert ( result >= 0 ); -   +    return (mix_word_t)result;  } @@ -227,29 +228,29 @@ mix_word_add_and_carry (mix_word_t x, mix_word_t y,  			mix_word_t *h, mix_word_t *l)  {    gboolean result; -     +    if ( mix_word_sign (x) == mix_word_sign (y) )      {        guint32 sum = (mix_word_magnitude (x) + mix_word_magnitude (y)); -      if ( sum >  MIX_WORD_MAX )  +      if ( sum >  MIX_WORD_MAX )  	{  	  result = TRUE; -	  if ( l != NULL )  +	  if ( l != NULL )  	    {  	      *l = sum - MIX_WORD_MAX -1;  	      *l |= mix_word_sign (x);  	    } -	  if ( h != NULL )  +	  if ( h != NULL )  	    {  	      *h = sum >> 30;  	      *h |= mix_word_sign (x);  	    } -	}  +	}        else /* sum <= MIX_WORD_MAX */  	{  	  result = FALSE;  	  if ( h != NULL ) *h = 0; -	  if ( l != NULL )  +	  if ( l != NULL )  	    {  	      *l = sum;  	      if ( sum != 0 ) @@ -262,7 +263,7 @@ mix_word_add_and_carry (mix_word_t x, mix_word_t y,      {        result = FALSE;        if ( h != NULL ) *h = 0; -      if ( l != NULL )  +      if ( l != NULL )  	{  	  gint32 dif = mix_word_magnitude (x) -  mix_word_magnitude (y);  	  if ( dif < 0) @@ -273,17 +274,17 @@ mix_word_add_and_carry (mix_word_t x, mix_word_t y,  	    *l = MIX_WORD_ZERO;  	}      } -  +    return result;  } -   -void  -mix_word_mul (mix_word_t x, mix_word_t y,  + +void +mix_word_mul (mix_word_t x, mix_word_t y,  	      mix_word_t *high_word, mix_word_t *low_word)  {    guint32 sign = mix_word_sign (x) ^ mix_word_sign (y); -   +    /*      x = x0 + x1 * 2 ^ 10 + x2 * 2 ^ 20      y = y0 + y1 * 2 ^ 10 + y2 * 2 ^ 20 @@ -295,7 +296,7 @@ mix_word_mul (mix_word_t x, mix_word_t y,    guint32 y0 = (y & 0x000003FF);    guint32 y1 = (y & 0x000FFC00) >> 10;    guint32 y2 = (y & 0x3FF00000) >> 20; -   +    /*      x * y = partial0 +      partial1 * 2 ^ 10 + @@ -311,21 +312,21 @@ mix_word_mul (mix_word_t x, mix_word_t y,    guint32 partial2 = x0 * y2 + x1 * y1 + x2 * y0;    guint32 partial3 = x1 * y2 + x2 * y1;    guint32 partial4 = x2 * y2; -   +    /*  sum1 has a place value of 1 and is < 2 ^ 32 */    guint32 sum1   = partial0 + (partial1 << 10);    guint32 carry1 = (sum1 & 0xFFF00000) >> 20; -   +    /* sum2 has a place value of 2 ^ 20 and is < 2 ^ 32 */    guint32 sum2   = partial2 + (partial3 << 10) + carry1;    guint32 carry2 = (sum2 & 0xFFF00000) >> 20; -   +    /* sum3 has a place value of 2 ^ 40 and is < 2 ^ 20 */    guint32 sum3   = partial4 + carry2; -   +    sum1 &= ~0xFFF00000;    sum2 &= ~0xFFF00000; -   +    /*      Now paste the three values back into two.    */ @@ -340,36 +341,36 @@ mix_word_mul (mix_word_t x, mix_word_t y,  } -gboolean  -mix_word_div (mix_word_t n1, mix_word_t n0, mix_word_t d,  +gboolean +mix_word_div (mix_word_t n1, mix_word_t n0, mix_word_t d,  	      mix_word_t *quotient, mix_word_t *remainder)  { -  gboolean overflow = FALSE;   +  gboolean overflow = FALSE;    long magn1 = mix_word_magnitude (n1);    long magd = mix_word_magnitude (d); -   -  if (magd == 0)  + +  if (magd == 0)      {        overflow = TRUE;        /* just so they have -some- valid value */        if ( quotient != NULL ) *quotient = 0; -      if ( remainder != NULL )  *remainder = 0;   -    }  -  else if (magn1 == 0)  +      if ( remainder != NULL )  *remainder = 0; +    } +  else if (magn1 == 0)      {    /* special-cased for speed */ -      if ( quotient != NULL )  -	*quotient = (mix_word_sign (n1) ^ mix_word_sign (d))  +      if ( quotient != NULL ) +	*quotient = (mix_word_sign (n1) ^ mix_word_sign (d))  	  | (mix_word_magnitude (n0) / magd);        if ( remainder != NULL )  	*remainder = mix_word_sign (n1) | (mix_word_magnitude (n0) % magd); -    }  -  else if (magd <= magn1)  +    } +  else if (magd <= magn1)      {        overflow = TRUE;        if ( quotient != NULL ) *quotient = 0;        if ( remainder != NULL )  *remainder = 0; -    }  -  else  +    } +  else      {        long q = mix_word_magnitude (n0);        long r = magn1; @@ -390,8 +391,8 @@ mix_word_div (mix_word_t n1, mix_word_t n0, mix_word_t d,    return overflow;  } -void  -mix_word_shift_right (mix_word_t A, mix_word_t X, gulong count,  +void +mix_word_shift_right (mix_word_t A, mix_word_t X, gulong count,  		      mix_word_t *pA, mix_word_t *pX)  {    if ( pX != NULL ) *pX = mix_word_sign (X); @@ -400,7 +401,7 @@ mix_word_shift_right (mix_word_t A, mix_word_t X, gulong count,      if ( pA != NULL )        *pA |= mix_word_magnitude (A) >> (6 * count);      if ( pX != NULL ) -      *pX |= MIX_WORD_MAX & ( (mix_word_magnitude (X) >> (6 * count))  +      *pX |= MIX_WORD_MAX & ( (mix_word_magnitude (X) >> (6 * count))  			      | (A << (30 - 6 * count)) );    } else if (count < 10 && pX != NULL)      *pX |= mix_word_magnitude (A) >> (6 * count - 30); @@ -409,8 +410,8 @@ mix_word_shift_right (mix_word_t A, mix_word_t X, gulong count,  } -void  -mix_word_shift_left (mix_word_t A, mix_word_t X, gulong count,  +void +mix_word_shift_left (mix_word_t A, mix_word_t X, gulong count,  		     mix_word_t *pA, mix_word_t *pX)  {    if ( pX != NULL ) *pX = mix_word_sign (X); @@ -426,13 +427,13 @@ mix_word_shift_left (mix_word_t A, mix_word_t X, gulong count,      ;  } -void  -mix_word_shift_left_circular (mix_word_t A, mix_word_t X, gulong count,  +void +mix_word_shift_left_circular (mix_word_t A, mix_word_t X, gulong count,  			      mix_word_t *pA, mix_word_t *pX)  {    mix_word_t A1, X1;    guint c; -   +    count %= 10;    A1 = count < 5 ? A : X;    X1 = count < 5 ? X : A; @@ -445,13 +446,13 @@ mix_word_shift_left_circular (mix_word_t A, mix_word_t X, gulong count,        | ( MIX_WORD_MAX & (A1 << c) ) | ( mix_word_magnitude (X1) >> (30 - c) );  } -void  -mix_word_shift_right_circular (mix_word_t A, mix_word_t X, gulong count,  +void +mix_word_shift_right_circular (mix_word_t A, mix_word_t X, gulong count,  			       mix_word_t *pA, mix_word_t *pX)  {    mix_word_t A1, X1;    guint c; -   +    count %= 10;    A1 = count < 5 ? A : X;    X1 = count < 5 ? X : A; @@ -466,7 +467,7 @@ mix_word_shift_right_circular (mix_word_t A, mix_word_t X, gulong count,  /* Printable representation */ -void  +void  mix_word_print_to_file (mix_word_t word, const char *message, FILE *f)  {    guint k; @@ -478,7 +479,7 @@ mix_word_print_to_file (mix_word_t word, const char *message, FILE *f)    fprintf (f, "(%010ld)", mix_word_magnitude (word));  } -void  +void  mix_word_print_to_buffer (mix_word_t word, gchar *buf)  {    g_return_if_fail (buf != NULL); @@ -495,7 +496,7 @@ mix_word_print_to_buffer (mix_word_t word, gchar *buf)  mix_short_t  mix_word_to_short (mix_word_t word)  { -  if  ( mix_word_is_negative (word) )  +  if  ( mix_word_is_negative (word) )      return ( (word & MIX_SHORT_MAX) | MIX_SHORT_SIGN_BIT );    else      return (word & MIX_SHORT_MAX); @@ -510,11 +511,11 @@ mix_short_to_word (mix_short_t s)      return ((mix_word_t)s);  } -mix_short_t  +mix_short_t  mix_short_add (mix_short_t x, mix_short_t y)  {    static const guint16 MIX_SHORT_MAX_SIM = 2*MIX_SHORT_MAX + 1; -   +    gint16 result;    if ( mix_short_sign (x) == mix_short_sign (y) )      { @@ -523,7 +524,7 @@ mix_short_add (mix_short_t x, mix_short_t y)  	/* for instance MIX_SHORT_MAX + 1 = - MIX_SHORT_MAX */  	result = MIX_SHORT_MAX_SIM - result;  	result |= mix_short_sign (mix_short_negative (x)); -      } else if ( result != 0 )       +      } else if ( result != 0 )  	result |= mix_short_sign (x);        /* keep positive sign for 0 so that w - w == -w + w */      } @@ -536,9 +537,9 @@ mix_short_add (mix_short_t x, mix_short_t y)  	result = result|mix_short_sign (x);        /* keep positive sign for 0 so that w - w == -w + w */      } -  +    g_assert ( result >= 0 ); -   +    return (mix_short_t)result;  } | 
