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|