## modules/ma/bitmask.c

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following functions.

1. MA_isset
2. MA_set
3. MA_clear
4. MA_new
5. MA_prt
6. MA_and
7. MA_xor
8. MA_or
9. MA_not
10. MA_bitcount
11. MA_to_string
12. main

       1 /***************************************
       2   $Revision: 1.15 $
       3
       4   bitmask (ma) - bitmask.c - library for manipulating fixed size bitmasks.
       5
       6   Status: NOT REVUED, TESTED, INCOMPLETE
       7
       8   Design and implementation by: Marek Bukowy, Chris Ottrey.
       9
      10   ******************/ /******************
      11   Copyright (c) 1999,2000,2001,2002               RIPE NCC
      12
      13   All Rights Reserved
      14
      15   Permission to use, copy, modify, and distribute this software and its
      16   documentation for any purpose and without fee is hereby granted,
      17   provided that the above copyright notice appear in all copies and that
      18   both that copyright notice and this permission notice appear in
      19   supporting documentation, and that the name of the author not be
      20   used in advertising or publicity pertaining to distribution of the
      21   software without specific, written prior permission.
      22
      23   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
      24   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
      25   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
      26   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
      27   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      28   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      29   ***************************************/
      30
      31
      32
      33 #include "rip.h"
      34
      35 #include <stdio.h>
      36 #include <stdarg.h>
      37 #include <stdlib.h>
      38 #include <assert.h>
      39
      40 #include <string.h>
      41
      42 int MA_isset(mask_t d, unsigned b) {
         /* [<][>][^][v][top][bottom][index][help] */
      43   return(
      44  (d.data[b / MASK_BITS_BASESIZE] &(1 <<(b % MASK_BITS_BASESIZE)))
      45    > 0);
      46 }
      47
      48 void MA_set(mask_t *m_ptr, unsigned b, unsigned v) {
         /* [<][>][^][v][top][bottom][index][help] */
      49   assert(b < MASK_MAX);
      50   assert(v == 0 || v == 1);
      51
      52   if(v == 1)
      53     m_ptr->data[b / MASK_BITS_BASESIZE] |=(1 <<(b % MASK_BITS_BASESIZE));
      54   else
      55     m_ptr->data[b / MASK_BITS_BASESIZE] &= ~(1 <<(b % MASK_BITS_BASESIZE));
      56 }
      57
      58 void MA_clear(mask_t *m_ptr) {
         /* [<][>][^][v][top][bottom][index][help] */
      59   memset(m_ptr, 0, sizeof(mask_t));
      60 } /* MA_clear() */
      61
      62
      63 /* set bits in dptr. variable number of args, terminated by MA_END
      64
      65    MA_END is -1, so the arguments are of type signed int
      66  */
      67 mask_t MA_new(int n,...) {
         /* [<][>][^][v][top][bottom][index][help] */
      68   va_list         ap;
      69   mask_t d;
      70
      71   MA_clear(&d);
      72
      73   /* cover the "empty mask" case => MA_new(MA_END) invoked */
      74   for ( va_start(ap, n); n != MA_END; n = va_arg(ap, int) ) {
      75       MA_set(&d, (unsigned) n, 1);
      76   }
      77   va_end(ap);
      78
      79   return d;
      80 }
      81
      82
      83 void MA_prt(mask_t m) {
         /* [<][>][^][v][top][bottom][index][help] */
      84   unsigned i;
      85
      86   for (i = 0; i < MASK_MAX; i++) {
      87     printf("%d", MA_isset(m, i));
      88   }
      89
      90   printf("\n");
      91
      92   for (i = 0; i < MASK_BITS_WORDS; i++) {
      93     printf("0x%0*X ", 2 * (int)sizeof(MASK_BITS_BASETYPE), m.data[i]);
      94   }
      95
      96   printf("\n");
      97 }
      98
      99 /* Perform a logical AND on two masks.
     100    Author: ottrey
     101    Date: Tue Jul  6 13:28:24 CEST 1999
     102    NB: This operation could/should be done a word at a time?
     103 */
     104 mask_t MA_and(mask_t a, mask_t b) {
         /* [<][>][^][v][top][bottom][index][help] */
     105   mask_t c;
     106   unsigned i;
     107
     108   for (i=0; i < MASK_BITS_WORDS; i++ )  {
     109     c.data[i] = a.data[i] & b.data[i];
     110   }
     111   return c;
     112 } /* MA_and() */
     113
     114 /* Perform a logical XOR on two masks.
     115    Author: ottrey
     116    Date: Thu Jul  8 14:50:14 CEST 1999
     117    NB: This operation could/should be done a word at a time?
     118 */
     119 mask_t MA_xor(mask_t a, mask_t b) {
         /* [<][>][^][v][top][bottom][index][help] */
     120   mask_t c;
     121   unsigned i;
     122
     123   for (i=0; i < MASK_BITS_WORDS; i++ )  {
     124     c.data[i] = a.data[i] ^ b.data[i];
     125   }
     126
     127   return c;
     128
     129 } /* MA_xor() */
     130
     131 /* Perform a logical OR on two masks.
     132    Author: ottrey
     133    Date: Thu Jul  8 16:34:34 CEST 1999
     134    NB: This operation could/should be done a word at a time?
     135 */
     136 mask_t MA_or(mask_t a, mask_t b) {
         /* [<][>][^][v][top][bottom][index][help] */
     137   mask_t c;
     138   unsigned  i;
     139
     140   for (i=0; i < MASK_BITS_WORDS; i++ )  {
     141     c.data[i] = a.data[i] | b.data[i];
     142   }
     143
     144   return c;
     145
     146 } /* MA_or() */
     147
     148 /* Perform a logical NOT operation on a mask.
     149    Author: marek
     150    Date: Fri Jan 14 17:15:00 MET 2000
     151    NB: This operation is done a word at a time.
     152 */
     153 mask_t MA_not(mask_t a) {
         /* [<][>][^][v][top][bottom][index][help] */
     154   mask_t c;
     155   unsigned i;
     156
     157   for (i=0; i < MASK_BITS_WORDS; i++ )  {
     158     c.data[i] = ~a.data[i];
     159   }
     160   return c;
     161 }
     162
     163 /* Counts the number of bits set. */
     164 int MA_bitcount(mask_t m) {
         /* [<][>][^][v][top][bottom][index][help] */
     165   unsigned i;
     166   int count=0;
     167
     168   for (i=0; i < MASK_MAX; i++) {
     169     count += MA_isset(m, i);
     170   }
     171
     172   return count;
     173
     174 } /* MA_bitcount() */
     175
     176 /* Convert the bitmap to a string comprising of tokens from an array of tokens.
     177    Author: ottrey
     178    Date: Tue Jul  6 13:28:24 CEST 1999
     179 */
     180 char *MA_to_string(mask_t mask, char * const *tokens) {
         /* [<][>][^][v][top][bottom][index][help] */
     181   char str_buf[STR_L];
     182   int count;
     183   unsigned i;
     184   int length;
     185
     186   count=0;
     187   strcpy(str_buf, "{");
     188   for (i=0;  tokens[i] != NULL; i++) {
     189     if ( MA_isset(mask, i) != 0) {
     190       strcat(str_buf, tokens[i]);
     191       strcat(str_buf, ",");
     192       count++;
     193     }
     194   }
     195   if (count == 0) {
     196     strcat(str_buf, "NULL ");
     197   }
     198   length = strlen(str_buf);
     199   str_buf[length-1] = '}';
     200
     201   return UT_strdup(str_buf);
     202
     203 } /* MA_to_string() */
     204
     205 #ifdef MODULE_TEST
     206 void
     207 main() {
         /* [<][>][^][v][top][bottom][index][help] */
     208   mask_t  d;
     209
     210   d = MA_new(1, 4, 56, 3, 5, 7, 19, MA_END);
     211
     212   MA_prt(d);
     213
     214   MA_set(&d, 3, 0);
     215   MA_set(&d, 7, 0);
     216   MA_set(&d, 9, 0);
     217   MA_set(&d, 19, 0);
     218
     219   MA_prt(d);
     220 }
     221 #endif

/* [<][>][^][v][top][bottom][index][help] */