水無瀬の部屋 > Programming > sample > atlnk > info.cpp |
---|
1: //*********************************************************
2: // プロジェクト: atlnk - @link.target
3: // ファイル名: info.cpp
4: //*********************************************************
5: #include "info.h"
6: #include "cmdline.h"
7: #include <relation/relation.h>
8:
9:
10: //---------------------------------------------------------
11: // テスト関数 の 宣言
12: //---------------------------------------------------------
13: DECLARE_TESTPROC( test_install );
14:
15:
16: //---------------------------------------------------------
17: // マクロ定数 の 定義
18: //---------------------------------------------------------
19: // 登録
20: #define APP_VERB "at.link.target" // 動詞
21: #define EXT_LNK ".lnk" // 拡張子
22: #define EXT_PIF ".pif" // 拡張子
23: //
24: #define MENUTITLE_DEFAULT "リンク先を探す(&F)" // メニュー名
25:
26:
27: //---------------------------------------------------------
28: // ファイルスコープ変数 の 定義
29: //---------------------------------------------------------
30: static const struct
31: {
32: id_t id;
33: DWORD flag;
34: const char *ext;
35: }
36: g_pair[] =
37: {
38: #define MAKE_TBL( name ) { ID_ ## name, FLAG_ ## name, EXT_ ## name }
39: MAKE_TBL( LNK ),
40: MAKE_TBL( PIF ),
41: #undef MAKE_TBL
42: };
43: COMPILE_ASSERT( numof(g_pair) == numof( ((install_t *)null)->reg ) );
44:
45:
46: //*********************************************************
47: // IsValidInstallInfo
48: //*********************************************************
49: bool
50: IsValidInstallInfo
51: (
52: const install_t *info
53: )
54: {
55: CALLONCE_TESTPROC( test_install ); // [テスト]
56:
57: // パラメタの仮定
58: VALID_TEST( IsValidReadPtr( info, sizeof( *info ) ) );
59: VALID_TEST( info->flags == (info->flags & ((1 << numof( info->reg )) - 1)) );
60:
61: {for( int i = 0; i < numof( info->reg ); ++i )
62: {
63: const size_t index = ID_INDEX( g_pair[ i ].id );
64: ASSERT( IS_VALID_INDEX( index ) );
65:
66: const relation_t *reg = &info->reg[ index ];
67:
68: // ASSERT( IsValidRegistryPathString( reg->regpath ) );
69: VALID_TEST( IsValidCommandLineString( reg->cmdline ) );
70:
71: VALID_TEST( strlen( reg->regpath ) < numof(reg->regpath) );
72: VALID_TEST( strlen( reg->cmdline ) < numof(reg->cmdline) );
73: VALID_TEST( strlen( reg->menu ) < numof(reg->menu) );
74: }}
75:
76: return true;
77: }//IsValidInstallInfo
78:
79: //*********************************************************
80: // LoadInstallInfo
81: //*********************************************************
82: bool
83: LoadInstallInfo
84: (
85: install_t *info
86: )
87: {
88: CALLONCE_TESTPROC( test_install ); // [テスト]
89:
90: // パラメタの仮定
91: ASSERT( IsValidPtr( info, sizeof( *info ) ) );
92: DESTROY_BUFFER( info, sizeof( *info ) ); // [破壊]
93:
94: //
95: info->flags = 0;
96: {for( int i = 0; i < numof( g_pair ); ++i )
97: {
98: const size_t index = ID_INDEX( g_pair[ i ].id );
99: ASSERT( IS_VALID_INDEX( index ) );
100:
101: //
102: relation_t *reg = &info->reg[ index ];
103:
104: //
105: reg->regpath[ 0 ] = '\0';
106:
107: //
108: if ( RegGetClassRelation( g_pair[ i ].ext, APP_VERB, reg->menu, numof( reg->menu ), reg->cmdline, numof( reg->cmdline ) ) )
109: {
110: info->flags |= g_pair[ i ].flag;
111: }
112: else
113: {
114: strcopy( reg->menu, numof( reg->menu ), MENUTITLE_DEFAULT );
115: VERIFY( make_cmdline( reg->cmdline, numof( reg->cmdline ), null ) );
116: }
117:
118: // ASSERT( IsValidRegistryPathString( reg->regpath ) );
119: ASSERT( IsValidCommandLineString( reg->cmdline ) );
120: ASSERT( IsValidStringPtr( reg->menu ) );
121: }}
122:
123: ASSERT( IsValidInstallInfo( info ) );
124: return true;
125: }//LoadInstallInfo
126:
127: //*********************************************************
128: // SaveInstallInfo
129: //*********************************************************
130: bool
131: SaveInstallInfo
132: (
133: const install_t *info,
134: DWORD mask // 値を反映させる項目を示すフラグ
135: )
136: {
137: CALLONCE_TESTPROC( test_install ); // [テスト]
138:
139: // パラメタの仮定
140: ASSERT( IsValidInstallInfo( info ) );
141:
142: //
143: {for( int i = 0; i < numof( g_pair ); ++i )
144: {
145: const size_t index = ID_INDEX( g_pair[ i ].id );
146: ASSERT( IS_VALID_INDEX( index ) );
147:
148: const relation_t *reg = &info->reg[ index ];
149: // ASSERT( IsValidRegistryPathString( reg->regpath ) );
150: ASSERT( IsValidCommandLineString( reg->cmdline ) );
151: ASSERT( IsValidStringPtr( reg->menu ) );
152:
153: if ( g_pair[ i ].flag == (mask & g_pair[ i ].flag) )
154: {
155: if ( g_pair[ i ].flag == (info->flags & g_pair[ i ].flag) )
156: {
157: VERIFY( RegSetClassRelation( g_pair[ i ].ext, APP_VERB, reg->menu, reg->cmdline ) );
158: }
159: else
160: {
161: VERIFY( RegResetClassRelation( g_pair[ i ].ext, APP_VERB ) );
162: }
163: }
164: }}
165:
166: return true;
167: }//SaveInstallInfo
168:
169: //*********************************************************
170: // GetModifiedFlags
171: //*********************************************************
172: DWORD
173: GetModifiedFlags
174: (
175: const install_t *a,
176: const install_t *b
177: )
178: {
179: CALLONCE_TESTPROC( test_install ); // [テスト]
180:
181: // パラメタの仮定
182: ASSERT( IsValidInstallInfo( a ) );
183: ASSERT( IsValidInstallInfo( b ) );
184:
185: // 関連づけが変更されているか?
186: DWORD modified = a->flags ^ b->flags;
187:
188: //
189: {for( int i = 0; i < numof( a->reg ); ++i )
190: {
191: // 設定の詳細が変更されているか?
192: // ・設定 -> 設定 …… 詳細の比較が必要
193: // ・設定 -> 削除 …… 不要 ( 削除 が確定済み )
194: // ・削除 -> 設定 …… 不要 ( 設定 が確定済み )
195: // ・削除 -> 削除 …… 不要 ( 無視 が確定済み )
196: if ( g_pair[ i ].flag == (g_pair[ i ].flag & (a->flags & b->flags)) )
197: {
198: const size_t index = ID_INDEX( g_pair[ i ].id );
199: ASSERT( IS_VALID_INDEX( index ) );
200:
201: if ( ! streql( a->reg[ index ].cmdline, b->reg[ index ].cmdline ) )
202: {
203: modified |= g_pair[ i ].flag;
204: }
205:
206: if ( ! streql( a->reg[ index ].menu, b->reg[ index ].menu ) )
207: {
208: modified |= g_pair[ i ].flag;
209: }
210: }
211: }}
212:
213: return modified;
214: }//GetModifiedFlags
215:
216:
217:
218: //******************************************************************************************************************
219: // TEST
220: //******************************************************************************************************************
221:
222:
223: #ifdef _DEBUG // デバッグ時のみ
224:
225:
226: //*********************************************************
227: // test_install
228: //*********************************************************
229: DEFINE_TESTPROC( test_install )
230: {
231: //---------------------------------------------------------
232: // 定数 の テスト
233: //---------------------------------------------------------
234:
235: // APP_VERB
236: ASSERT( IsValidCommandLineString( APP_VERB ) );
237:
238: //
239: {for( int i = 0; i < numof( g_pair ); ++i )
240: {
241: ASSERT( IS_VALID_ID( g_pair[ i ].id ) );
242: ASSERT( IS_VALID_INDEX( ID_INDEX( g_pair[ i ].id ) ) );
243: }}
244:
245: //
246: {for( int i = 0; i < numof( g_pair ) - 1; ++i )
247: {
248: {for( int j = i+1; j < numof( g_pair ); ++j )
249: {
250: ASSERT( i != j );
251: ASSERT( g_pair[ i ].id != g_pair[ j ].id );
252: ASSERT( 0 == (g_pair[ i ].flag & g_pair[ j ].flag) );
253: ASSERT( ! streqli( g_pair[ i ].ext, g_pair[ j ].ext ) );
254: }}
255: }}
256:
257:
258: //---------------------------------------------------------
259: // ファイルスコープ関数 の テスト
260: //---------------------------------------------------------
261:
262: //---------------------------------------------------------
263: // 公開関数 の テスト
264: //---------------------------------------------------------
265:
266: {
267: install_t a;
268: install_t b;
269: LoadInstallInfo( &a );
270: LoadInstallInfo( &b );
271: ASSERT( 0 == GetModifiedFlags( &a, &b ) );
272: }
273:
274: {
275: const struct
276: {
277: DWORD flag_a;
278: DWORD flag_b;
279: DWORD result;
280: DWORD lnk; // .lnk の詳細を変更した
281: DWORD pif; // .pif の詳細を変更した
282: }
283: testcase[] =
284: {
285: #define FLAG_BOTH (FLAG_LNK | FLAG_PIF)
286: #define MAKE_TESTCASE( flag_a, flag_b, result, lnk, pif ) { flag_a, flag_b, result, lnk, pif }
287: MAKE_TESTCASE( 0, 0, 0, 0, 0 ),
288: MAKE_TESTCASE( 0, FLAG_LNK, FLAG_LNK, FLAG_LNK , FLAG_LNK ),
289: MAKE_TESTCASE( 0, FLAG_PIF, FLAG_PIF, FLAG_PIF, FLAG_PIF ),
290: MAKE_TESTCASE( 0, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
291: MAKE_TESTCASE( FLAG_LNK, 0, FLAG_LNK, FLAG_LNK , FLAG_LNK ),
292: MAKE_TESTCASE( FLAG_LNK, FLAG_LNK, 0, FLAG_LNK, 0 ),
293: MAKE_TESTCASE( FLAG_LNK, FLAG_PIF, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
294: MAKE_TESTCASE( FLAG_LNK, FLAG_BOTH, FLAG_PIF, FLAG_BOTH, FLAG_PIF ),
295: MAKE_TESTCASE( FLAG_PIF, 0, FLAG_PIF, FLAG_PIF, FLAG_PIF ),
296: MAKE_TESTCASE( FLAG_PIF, FLAG_LNK, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
297: MAKE_TESTCASE( FLAG_PIF, FLAG_PIF, 0, 0, FLAG_PIF ),
298: MAKE_TESTCASE( FLAG_PIF, FLAG_BOTH, FLAG_LNK, FLAG_LNK, FLAG_BOTH ),
299: MAKE_TESTCASE( FLAG_BOTH, 0, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
300: MAKE_TESTCASE( FLAG_BOTH, FLAG_LNK, FLAG_PIF, FLAG_BOTH, FLAG_PIF ),
301: MAKE_TESTCASE( FLAG_BOTH, FLAG_PIF, FLAG_LNK, FLAG_LNK, FLAG_BOTH ),
302: MAKE_TESTCASE( FLAG_BOTH, FLAG_BOTH, 0, FLAG_LNK, FLAG_PIF ),
303: #undef MAKE_TESTCASE
304: #undef FLAG_BOTH
305: };
306: {for( int i = 0; i < numof( testcase ); ++i )
307: {
308: install_t a;
309: install_t b;
310: a.flags = testcase[ i ].flag_a;
311: b.flags = testcase[ i ].flag_b;
312:
313: {for( int j = 0; j < numof( a.reg ); ++j )
314: {
315: a.reg [ j ].regpath[ 0 ] = '\0';
316: b.reg [ j ].regpath[ 0 ] = '\0';
317: }}
318:
319: {
320: {for( int j = 0; j < numof( g_pair ); ++j )
321: {
322: const size_t idx = ID_INDEX( g_pair[ j ].id );
323: ASSERT( IS_VALID_INDEX( idx ) );
324:
325: strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
326: strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
327: strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
328: strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
329: }}
330:
331: const DWORD modified = GetModifiedFlags( &a, &b );
332: ASSERT( modified == testcase[ i ].result );
333: }
334:
335: // .lnk の詳細を変更した
336: {
337: const size_t index = ID_INDEX( ID_LNK );
338:
339: {for( int k = 0; k < 2; ++k )
340: {
341: {for( int j = 0; j < numof( g_pair ); ++j )
342: {
343: const size_t idx = ID_INDEX( g_pair[ j ].id );
344: ASSERT( IS_VALID_INDEX( idx ) );
345:
346: strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
347: strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
348: strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
349: strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
350: }}
351: ASSERT( testcase[ i ].result == GetModifiedFlags( &a, &b ) );
352:
353: if ( 0 == (k & 1) )
354: strcopy( a.reg[ index ].cmdline, numof(a.reg[ index ].cmdline), "modified" );
355: else
356: strcopy( a.reg[ index ].menu, numof(a.reg[ index ].menu), "modified" );
357:
358: const DWORD modified = GetModifiedFlags( &a, &b );
359: ASSERT( modified == testcase[ i ].lnk );
360: }}
361: }
362:
363: // .pif の詳細を変更した
364: {
365: const size_t index = ID_INDEX( ID_PIF );
366:
367: {for( int k = 0; k < 2; ++k )
368: {
369: {for( int j = 0; j < numof( g_pair ); ++j )
370: {
371: const size_t idx = ID_INDEX( g_pair[ j ].id );
372: ASSERT( IS_VALID_INDEX( idx ) );
373:
374: strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
375: strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
376: strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
377: strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
378: }}
379: ASSERT( testcase[ i ].result == GetModifiedFlags( &a, &b ) );
380:
381: if ( 0 == (k & 1) )
382: strcopy( a.reg[ index ].cmdline, numof(a.reg[ index ].cmdline), "modified" );
383: else
384: strcopy( a.reg[ index ].menu, numof(a.reg[ index ].menu), "modified" );
385:
386: const DWORD modified = GetModifiedFlags( &a, &b );
387: ASSERT( modified == testcase[ i ].pif );
388: }}
389: }
390: }}
391: }
392:
393: }//test_install
394:
395:
396: #endif // #ifdef _DEBUG
397:
398:
399: //** end **
参照:
水無瀬の部屋 > sample > atlnk > info.cpp |
---|
このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/atlnk/info_cpp.shtml