sxba_2op.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *                                S Y N T A X
00003  *-----------------------------------------------------------------------------
00004  *   Copyright (C) 1972-2008 INRIA (Institut National de Recherche en
00005  *   Informatique et Automatique)
00006  *-----------------------------------------------------------------------------
00007  *   URL: http://syntax.gforge.inria.fr
00008  *-----------------------------------------------------------------------------
00009  *   The source code of SYNTAX is distributed with two different licenses,
00010  *   depending on the files:
00011  *   - The recursive content of src/ and incl/ and the non-recursive content
00012  *     of SYNTAX's root directory are distributed under the CeCILL-C license
00013  *   - The recursive content of all other repertories is distributed under
00014  *     the CeCILL license
00015  *   All code produced by SYNTAX must be considered as being under the
00016  *   CeCILL-C license. Information about the CeCILL and CeCILL-C licenses
00017  *   can be found at, e.g., http://www.cecill.fr
00018  *****************************************************************************/
00019 
00020 
00021 
00022 
00023 
00024 /* 
00025    sxba_2op : lhs op1 rhs1 op2 rhs2
00026    sxba_incr: lhs = {i+incr | i \in rhs}
00027    sxba_decr: lhs = {i-decr | i \in rhs}
00028    sxba_or_with_test: lhs U= rhs + retourne vrai ssi la lhs a change'
00029 */
00030 
00031 
00032 
00033 
00034 #include "sxversion.h"
00035 #include "sxcommon.h"
00036 #include "sxba.h"
00037 
00038 char WHAT_SXBA_2OP[] = "@(#)SYNTAX - $Id: sxba_2op.c 1416 2008-06-25 14:42:55Z rlacroix $" WHAT_DEBUG;
00039 
00040 extern void sxperror (char *);
00041 extern void sxtrap (char *caller, char *message);
00042 
00043 /* Realise lhs op1= rhs1 op2 rhs2 */
00044 /* Retourne SXTRUE ssi lhs est non vide */
00045 /* Attention, on peut avoir lhs == rhs1 */
00046 SXBOOLEAN
00047 sxba_2op (SXBA lhs, SXINT op1, SXBA rhs1, SXINT op2, SXBA rhs2)
00048 {
00049   SXBA     lhs_bits_ptr, rhs_bits_ptr1, rhs_bits_ptr2;
00050   SXBA_ELT slices_number = SXNBLONGS (SXBASIZE (rhs2));
00051   SXBA_ELT result = (SXBA_ELT)0, operand2;
00052 
00053   sxinitialise(lhs_bits_ptr); /* pour faire taire "gcc -Wuninitialized" */
00054   sxinitialise(rhs_bits_ptr1); /* pour faire taire "gcc -Wuninitialized" */
00055 #if EBUG
00056     sxbassert (rhs2 != NULL, "2op (rhs2 == NULL)");
00057     if (rhs1) {sxbassert (*rhs1 == *rhs2, "2op (|rhs1|!=|rhs2|)");}
00058     if (lhs) {sxbassert (*lhs == *rhs2, "2op (|lhs|!=|rhs2|)");}
00059     if (lhs) {sxbassert ((*(lhs+SXNBLONGS (SXBASIZE (lhs))) & ((~((SXBA_ELT)0)) << 1 << MOD (SXBASIZE (lhs) - 1))) == 0, "2op");}
00060     if (rhs1) {sxbassert ((*(rhs1+SXNBLONGS (SXBASIZE (rhs1))) & ((~((SXBA_ELT)0)) << 1 << MOD (SXBASIZE (rhs1) - 1))) == 0, "2op");}
00061     sxbassert ((*(rhs2+SXNBLONGS (SXBASIZE (rhs2))) & ((~((SXBA_ELT)0)) << 1 << MOD (SXBASIZE (rhs2) - 1))) == 0, "2op");
00062 #endif /* EBUG */
00063 
00064     if (lhs) lhs_bits_ptr = lhs + slices_number;
00065     if (rhs1) rhs_bits_ptr1 = rhs1 + slices_number;
00066     rhs_bits_ptr2 = rhs2 + slices_number;
00067 
00068   while (slices_number-- > 0) {
00069     operand2 = *rhs_bits_ptr2--;
00070 
00071     switch (op2) {
00072     case SXBA_OP_AND:
00073 #if EBUG
00074       sxbassert (rhs1 != NULL, "2op (rhs1 == NULL)");
00075 #endif /* EBUG */
00076       operand2 &= *rhs_bits_ptr1--;
00077       break;
00078 
00079     case SXBA_OP_OR:
00080 #if EBUG
00081       sxbassert (rhs1 != NULL, "2op (rhs1 == NULL)");
00082 #endif /* EBUG */
00083       operand2 |= *rhs_bits_ptr1--;
00084       break;
00085 
00086     case SXBA_OP_XOR:
00087 #if EBUG
00088       sxbassert (rhs1 != NULL, "2op (rhs1 == NULL)");
00089 #endif /* EBUG */
00090       operand2 ^= *rhs_bits_ptr1--;
00091       break;
00092 
00093     case SXBA_OP_MINUS:
00094 #if EBUG
00095       sxbassert (rhs1 != NULL, "2op (rhs1 == NULL)");
00096 #endif /* EBUG */
00097       operand2 = *rhs_bits_ptr1-- & (~operand2);
00098       break;
00099 
00100     case SXBA_OP_NOT:
00101       operand2 = ~operand2;
00102       break;
00103 
00104 #if EBUG
00105     case SXBA_OP_NULL:
00106     case SXBA_OP_COPY:
00107     case SXBA_OP_IS:
00108       sxbassert (SXFALSE, "2op (bad op2)");
00109       break;
00110 #endif /* EBUG */
00111     default: /* pour faire taire gcc -Wswitch-default */
00112 #if EBUG
00113       sxtrap("sxba_2op","unknown switch case #1");
00114 #endif
00115       break;
00116     }
00117 
00118     switch (op1) {
00119 #if EBUG
00120     case SXBA_OP_NULL:
00121       sxbassert (lhs == NULL, "2op (lhs != NULL)");
00122 #endif /* EBUG */
00123 
00124     case SXBA_OP_AND:
00125 #if EBUG
00126       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00127 #endif /* EBUG */
00128       operand2 = (*lhs_bits_ptr-- &= operand2);
00129       break;
00130 
00131     case SXBA_OP_OR:
00132 #if EBUG
00133       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00134 #endif /* EBUG */
00135       operand2 = (*lhs_bits_ptr-- |= operand2);
00136       break;
00137 
00138     case SXBA_OP_XOR:
00139 #if EBUG
00140       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00141 #endif /* EBUG */
00142       operand2 = (*lhs_bits_ptr-- ^= operand2);
00143       break;
00144 
00145     case SXBA_OP_MINUS:
00146 #if EBUG
00147       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00148 #endif /* EBUG */
00149       operand2 = (*lhs_bits_ptr-- &= ~operand2);
00150       break;
00151     case SXBA_OP_NOT:
00152 #if EBUG
00153       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00154 #endif /* EBUG */
00155       operand2 = (*lhs_bits_ptr-- = ~operand2);
00156 
00157     case SXBA_OP_COPY:
00158 #if EBUG
00159       sxbassert (lhs != NULL, "2op (lhs == NULL)");
00160 #endif /* EBUG */
00161       operand2 = (*lhs_bits_ptr-- = operand2);
00162       break;
00163 
00164     case SXBA_OP_IS:
00165       /* Rien  */
00166 #if EBUG
00167       sxbassert (lhs == NULL, "2op (lhs != NULL)");
00168 #endif /* EBUG */
00169       break;
00170     default: /* pour faire taire gcc -Wswitch-default */
00171 #if EBUG
00172       sxtrap("sxba_2op","unknown switch case #2");
00173 #endif
00174       break;
00175     }
00176 
00177     result |= operand2;
00178   }
00179 
00180   return result != 0;
00181 }
00182 
00183 /* lhs = {i+incr | i \in rhs} 
00184    On peut avoir lhs == rhs
00185 */
00186 SXBOOLEAN
00187 sxba_incr (SXBA lhs, SXBA rhs, SXBA_INDEX incr)
00188 {
00189   SXBA                  source_bits_ptr, object_bits_ptr;
00190   SXBA_INDEX        delta = DIV (incr); /* decalage en mots */
00191   SXBA_INDEX            size = sxba_cast (SXBASIZE (lhs));
00192   SXBA_ELT              slices_number = SXNBLONGS (size);
00193   SXBA_INDEX        left_shift = MOD (incr);
00194   SXBA_INDEX        right_shift = SXBITS_PER_LONG - left_shift;
00195   SXBA_ELT      source, prev_source, result = (SXBA_ELT)0;
00196 
00197 #if EBUG
00198   sxbassert (*lhs == *rhs, "sxba_incr (|X|!=|Y|)");
00199   sxbassert (sxba_1_rlscan (rhs, size+1) + incr < size, "sxba_incr (|X|+incr>|X|");
00200   sxbassert ((*(lhs+slices_number) & ((~((SXBA_ELT)0)) << 1 << MOD (size-1))) == 0, "sxba_incr");
00201   sxbassert ((*(rhs+slices_number) & ((~((SXBA_ELT)0)) << 1 << MOD (size-1))) == 0, "sxba_incr");
00202 #endif
00203        
00204   object_bits_ptr = lhs + slices_number;
00205   source_bits_ptr = rhs + slices_number - delta; 
00206 
00207   source = *source_bits_ptr--;
00208   
00209   while (source_bits_ptr >= rhs) {
00210     prev_source = source;
00211     source = *source_bits_ptr--;
00212       
00213     /* On met :
00214        la partie basse de prev_source ds la partie haute de objet
00215        et la partie haute de source ds la partie basse de objet  */
00216     result |= (*object_bits_ptr-- = (prev_source << left_shift) | (source >> right_shift));
00217   }
00218 
00219   /* ... et la partie basse de source ds la partie haute de objet */
00220   result |= (*object_bits_ptr-- = (source << left_shift));
00221 
00222   while (object_bits_ptr >= lhs)
00223     *object_bits_ptr-- = (SXBA_ELT)0;
00224 
00225   return result != 0;
00226 }
00227 
00228 
00229 /* lhs = {i-decr | i \in rhs} 
00230    On peut avoir lhs == rhs
00231 */
00232 SXBOOLEAN
00233 sxba_decr (SXBA lhs, SXBA rhs, SXBA_INDEX decr)
00234 {
00235   SXBA                  source_bits_ptr, object_bits_ptr;
00236   SXBA_INDEX        delta = DIV (decr); /* decalage en mots */
00237   SXBA_ELT              size = SXBASIZE (lhs);
00238   SXBA_ELT              slices_number = SXNBLONGS (size);
00239   SXBA_INDEX        right_shift = MOD (decr);
00240   SXBA_INDEX        left_shift = SXBITS_PER_LONG - right_shift;
00241   SXBA_ELT      source, prev_source, result = (SXBA_ELT)0;
00242 
00243 #if EBUG
00244   sxbassert (*lhs == *rhs, "sxba_decr (|X|!=|Y|)");
00245   sxbassert (sxba_scan (rhs, -1) - decr >= 0, "sxba_decr (|X|-decr>|X|");
00246   sxbassert ((*(lhs+slices_number) & ((~((SXBA_ELT)0)) << 1 << MOD (size-1))) == 0, "sxba_decr");
00247   sxbassert ((*(rhs+slices_number) & ((~((SXBA_ELT)0)) << 1 << MOD (size-1))) == 0, "sxba_decr");
00248 #endif
00249        
00250   object_bits_ptr = lhs + slices_number - delta;
00251   source_bits_ptr = rhs + slices_number;
00252 
00253   source = *source_bits_ptr--;
00254   /* la partie haute de source ds la partie basse de objet  */
00255   result |= (*object_bits_ptr-- = (source >> right_shift));
00256   
00257   while (object_bits_ptr >= lhs) {
00258     prev_source = source;
00259     source = *source_bits_ptr--;
00260       
00261     /* On met :
00262        la partie basse de prev_source ds la partie haute de objet
00263        et la partie haute de source ds la partie basse de objet  */
00264     result |= (*object_bits_ptr-- = (prev_source << left_shift) | (source >> right_shift));
00265   }
00266   
00267   if (delta) {
00268     object_bits_ptr = lhs + slices_number;
00269 
00270     do {
00271       *object_bits_ptr-- = (SXBA_ELT)0;
00272     } while (--delta > 0);
00273   }
00274 
00275   return result != 0;
00276 }
00277 
00278 
00279 /* Analogue a sxba_or mais retourne vrai ssi la lhs change */
00280 SXBOOLEAN
00281 sxba_or_with_test (SXBA lhs_bits_array, SXBA rhs_bits_array)
00282 {
00283   SXBA                lhs_bits_ptr, rhs_bits_ptr;
00284   SXBA_ELT            slices_number = SXNBLONGS (SXBASIZE (rhs_bits_array));
00285   SXBA_ELT            lwork, work;
00286   SXBOOLEAN             ret_val = SXFALSE;
00287     
00288   lhs_bits_ptr = lhs_bits_array + slices_number, rhs_bits_ptr = rhs_bits_array + slices_number;
00289 
00290 #if EBUG
00291   sxbassert (*lhs_bits_array == *rhs_bits_array, "sxba_or_with_test (|X|!=|Y|)");
00292   sxbassert ((*lhs_bits_ptr & ((~((SXBA_ELT)0)) << 1 << MOD (SXBASIZE (lhs_bits_array) - 1))) == 0, "sxba_or_with_test");
00293   sxbassert ((*rhs_bits_ptr & ((~((SXBA_ELT)0)) << 1 << MOD (SXBASIZE (rhs_bits_array) - 1))) == 0, "sxba_or_with_test");
00294 #endif
00295 
00296   while (slices_number-- > 0) {
00297     work = (*rhs_bits_ptr-- | (lwork = *lhs_bits_ptr));
00298 
00299     if (lwork /* ancienne valeur */ != work /* nouvelle valeur */) {
00300       /* A change' */
00301       ret_val = SXTRUE;
00302       *lhs_bits_ptr = work;
00303     }
00304 
00305     lhs_bits_ptr--;
00306   }
00307 
00308   return ret_val;
00309 }

Generated on Wed Apr 21 16:39:34 2010 for syntax-6.0b7 by  doxygen 1.6.1