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