[PR]

水無瀬の部屋 > Programming > sample > atlnk > info.cpp
最終更新日: 2007/03/30

   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 **

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > sample > atlnk > info.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/atlnk/info_cpp.shtml
>> Amazon.co.jp 『たまゆら童子』 へ
>> 楽天ブックス 『たまゆら童子』 へ