INTX.C

[目次 | 関数]

目次

関数一覧


   1|/*************************************************************************
   2|*  1. <<< IntX >>> 
   3|**************************************************************************/
   4|
   5|#include "mixer_precomp.h"  /* Auto precompiled header, Look at mixer-... folder */
   6|// #pragma hdrstop
   7|
   8|#if defined(USES_MXP_AUTOINC)
   9| #include "intx.ah"  /* Auto include header, Look at mixer-... folder */
  10|#endif
  11|
  12| 
  13|/*************************************************************************
  14|*  2. <<< [IntX_unitUp2_f] IntX_unitUp2 の関数版 >>> 
  15|**************************************************************************/
  16|#ifndef  NDEBUG
  17|int  IntX_unitUp2_f( int n, int unit )
  18|{
  19|  ASSERT( unit == 1 || unit == 2 || unit == 4 || unit == 8 ||
  20|    unit == 0x10 || unit == 0x20 || unit == 0x40 || unit == 0x80 ||
  21|    unit == 0x100 || unit == 0x200 || unit == 0x400 || unit == 0x800 ||
  22|    unit == 0x1000 || unit == 0x2000 || unit == 0x4000 || unit == 0x8000 );
  23|
  24|  return  IntX_unitUp2_m( n, unit );
  25|}
  26|#endif
  27|
  28| 
  29|/*************************************************************************
  30|*  3. <<< [IntX_isSameRange] アドレスが重なっているか判定する >>> 
  31|*【引数】
  32|*  ・int*  ranges;   開始アドレスと領域サイズの配列
  33|*  ・int   n;        領域の数
  34|*  ・bool  返り値;   重なっているかどうか
  35|*【例】
  36|*・ranges[] = { 0x200, 0x50, 0x1C0, 0x60 };
  37|*  IntX_isSameRange( ranges, 2 ) == true
  38|*
  39|*       +----------+
  40|*               +---------+
  41|*      1C0    200  20F   24F
  42|**************************************************************************/
  43|bool  IntX_isSameRange( int* ranges, int n )
  44|{
  45|  int  i,j;
  46|  int  a,b,c,d;  /* a〜b, c〜d */
  47|
  48|  for ( i = 0; i < n-1; i++ ) {
  49|    a = ranges[i*2];  b = a + ranges[i*2+1] - 1;
  50|    for ( j = i+1; j < n; j++ ) {
  51|      c = ranges[j*2];  d = c + ranges[j*2+1] - 1;
  52|
  53|      if ( ( a < c && c < b ) || ( a < d && d < b ) )
  54|        return  true;
  55|    }
  56|  }
  57|  return  false;
  58|}
  59|
  60| 
  61|/***********************************************************************
  62|*  4. <<< [IntX_RingChk_init] 初期化 >>> 
  63|*【補足】
  64|*・id に必要な領域のサイズは、(循環の最大長)×(1つの参照元が
  65|*  持つことができる最大の参照先の数)にします。
  66|************************************************************************/
  67|void  IntX_RingChk_init( IntX_RingChk* m, int* id, int id_size )
  68|{
  69|  ASSERT( id_size > sizeof(int) * 4 );
  70|  ASSERT( id_size % (sizeof(int)*2) == 0 );
  71|
  72|  m->id = id;
  73|  m->id_over = (int*)( (char*)id + id_size );
  74|  IntX_RingChk_reset( m );
  75|}
  76|
  77| 
  78|/***********************************************************************
  79|*  5. <<< [IntX_RingChk_reset] リセットする >>> 
  80|*【補足】
  81|*・初期化した直後は呼び出す必要ありません。
  82|************************************************************************/
  83|void  IntX_RingChk_reset( IntX_RingChk* m )
  84|{
  85|  m->id[1] = 0;
  86|  m->id[3] = (int)&m->id[0];
  87|  m->id_last = m->id;
  88|  m->lastBase = NULL;
  89|}
  90|
  91| 
  92|/***********************************************************************
  93|*  6. <<< [IntX_RingChk_add] 参照情報を入力して、循環しているか判定する >>> 
  94|*【補足】
  95|*・base_id, ref_id には、アドレス値を int 型にキャストした値を指定しても
  96|*  構いません。
  97|************************************************************************/
  98|int   IntX_RingChk_add( IntX_RingChk* m, int base_id, int ref_id )
  99|{
 100|  int*  p;
 101|  int*  pp;
 102|  bool  f;
 103|
 104|  /* p に base_id と同じ番号の要素へのアドレスを入れる */
 105|  f = false;
 106|  for ( p = m->id; p < m->id_last; p += 2 ) {
 107|    if ( *p == base_id )  { f = true;  break; }
 108|  }
 109|
 110|  /* ... が無ければ、リセットして、最初の要素を入れる */
 111|  if ( ! f ) {
 112|    IntX_RingChk_reset( m );
 113|    m->id[0] = base_id;
 114|    m->id[2] = ref_id;
 115|    m->id_last = &m->id[4];
 116|    if ( base_id == ref_id ) {  /* base_id と ref_id が同じなら循環 */
 117|      m->lastBase = &m->id[2];
 118|      return  IntX_RingChk_Ring;
 119|    }
 120|    else
 121|      return  IntX_RingChk_OK;
 122|  }
 123|
 124|  /* p から参照元へリンクをたどり、ref_id と同じ番号の要素があれば循環 */
 125|  pp = p;
 126|  do {
 127|    if ( *pp == ref_id ) {
 128|      m->lastBase = p;
 129|      return  IntX_RingChk_Ring;
 130|    }
 131|    pp = (int*)(*(pp + 1));
 132|  } while ( pp != NULL );
 133|
 134|  /* ... が無ければ、ref_id を登録する */
 135|  for ( pp = m->id; pp < m->id_last; pp += 2 ) {
 136|    if ( *pp == ref_id )  return  IntX_RingChk_OK;
 137|  }
 138|  if ( m->id_last == m->id_over )  return  IntX_RingChk_Over;
 139|  *pp =  ref_id;
 140|  *(pp + 1) = (int)p;
 141|  m->id_last += 2;
 142|
 143|  return  IntX_RingChk_OK;
 144|}
 145|
 146| 
 147|/***********************************************************************
 148|*  7. <<< [IntX_RingChk_forEachRing_imp] IntX_RingChk_forEachRing の実装部 >>> 
 149|************************************************************************/
 150|int  IntX_RingChk_forEachRing_imp( IntX_RingChk* m, int** pp )
 151|{
 152|  if ( m->lastBase == NULL )  return  0;
 153|
 154|  if ( *pp == NULL ) {
 155|    int*  p00;  /* 更なる参照元 */
 156|    int*  p0 = (int*) *( m->lastBase + 1 );  /* 参照元 */
 157|    int*  p1 = m->lastBase;  /* 参照先 */
 158|
 159|    /* リストを逆順にする */
 160|    *(p1 + 1) = 0;
 161|    for (;;) {
 162|      p00 = (int*) *( p0 + 1 );   *( p0 + 1 ) = (int)p1;
 163|      if ( p00 == NULL )  break;
 164|      p1 = p0;  p0 = p00;
 165|    }
 166|    *pp = p0;  return  1;
 167|  }
 168|  else {
 169|    *pp = (int*) *( *pp + 1 );
 170|    if ( *pp == NULL ) {
 171|      m->lastBase = NULL;  return  0;
 172|    }
 173|    else
 174|      return  1;
 175|  }
 176|}
 177|
 178|
 179| 
 180|