C:\home\SVGCats_src\src\Stdplus.c
1|/************************************************************************* 2|* 1. <<< 標準ライブラリ拡張 (StdPlus) >>> 3|**************************************************************************/ 4| 5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */ 6| 7|#define STDLIBS_INCLUDE_STRING_H 8|#define STDLIBS_INCLUDE_STDARG_H 9|#ifdef USES_MXP_AUTOINC 10| #include "stdplus.ah" /* Auto include header, Look at mixer-... folder */ 11|#endif 12| 13|#ifndef STDPLUS_NOT_ERRNO 14| #include <errno.h> 15|#endif 16| 17| 18|int StdPlus_chkAdr = 0x00000000; 19|int StdPlus_FreeChk_breakID = 0; 20| 21|static void StdPlus_breakFunc() {} /* ここにブレークポイントを張ってください */ 22| 23| 24|/*-----------------------------------------------------------------------*/ 25|/* 2. <<< ◆(StdPlus) 標準ライブラリ拡張 >>> */ 26|/*-----------------------------------------------------------------------*/ 27| 28|int StdPlus_mallocCount = 0; 29| 30| 31|/*********************************************************************** 32|* 3. <<< [StdPlus_malloc] 拡張 malloc >>> 33|* 4. <<< [StdPlus_malloc_imp] >>> 34|*【補足】 35|*・メモリ領域を確保できなかった場合、エラーになります。 36|*・StdPlus_free と呼出し回数をチェックすることができるようになります。 37|* (StdPlus_chkFree 関数) 38|*・StdPlus_malloc と StdPlus_free はなるべく直接呼び出さないようにし、 39|* STDPLUS_USES_STDNAME を #define して、malloc を StdPlus_malloc に 40|* 書きかえるようにします。さもなければ、StdPlus_malloc と標準ライブラリの 41|* free を呼び出すようなことが起きる可能性が出てしまい、呼び出し回数の 42|* チェックがおかしくなることがあります。 43|*・例外処理により確実に free するには次のようにします。 44|* Type* p = NULL; // NULL で初期化しておく 45|* try { 46|* p = malloc( 20 ); // try の中で StdPlus_malloc を呼び出す 47|* : 48|* } 49|* finally { // finally または catch の中で StdPlus_free を呼び出す。 50|* free( p ); // StdPlus_free 内部で、NULL ならフリーしない 51|* } end_finally; 52|************************************************************************/ 53|#ifdef STDPLUS_USES_STDLIB 54| 55|#ifndef STDPLUS_PRINT_NOT_FREE 56| void* StdPlus_malloc( int size ) 57|#else 58| void* StdPlus_malloc_imp( int size, char* file, int line ) 59|#endif 60|{ 61| #ifdef STDPLUS_USES_STDNAME 62| #undef malloc 63| #endif 64| 65| void* p = malloc( size ); 66| 67| #ifndef STDPLUS_PRINT_NOT_FREE 68| StdPlus_onMalloc_imp( p, NULL, 0 ); 69| #else 70| StdPlus_onMalloc_imp( p, file, line ); 71| #endif 72| 73| return p; 74| 75| #ifdef STDPLUS_USES_STDNAME 76| #define malloc StdPlus_malloc 77| #endif 78|} 79|#endif 80| 81| 82|/*********************************************************************** 83|* 5. <<< [StdPlus_onCoCreateInstance] ON_CO_CREATE_INSTANCE の関数部 >>> 84|************************************************************************/ 85|void StdPlus_onCoCreateInstance( void* p, int hr, char* file, int line ) 86|{ 87| if ( hr != 0 ) 88| { Errors_printf_release( "hr = 0x%08X in %s(%d)", hr, file, line ); error(); } 89| 90| StdPlus_onMalloc_imp( p, file, line ); 91|} 92| 93|/*********************************************************************** 94|* 6. <<< [StdPlus_onMalloc_imp] malloc/new 用・開放チェック >>> 95|*【引数】 96|* ・void* p; オブジェクトのアドレス 97|*【補足】 98|*・StdPlus_malloc(にオーバーライドした malloc)を使っているときは、 99|* 本関数が自動的に呼ばれますが、C++ では、コンストラクタから呼び出す 100|* 必要があります。 101|************************************************************************/ 102|#ifdef STDPLUS_USES_STDLIB 103| 104|void StdPlus_onMalloc_imp( void* p, char* file, int line ) 105|{ 106| #ifdef STDPLUS_PRINT_NOT_FREE 107| StdPlus_FreeChk_setMalloc( StdPlus_FreeChk_getGlobl(), p, file, line ); 108| #endif 109| 110| if ( p == NULL ) 111| error2_0( StdPlus_Err_MallocFailure, "malloc できません" ); 112| else 113| StdPlus_mallocCount ++; 114| 115| /* デバッグ用、malloc した位置を知るため */ 116| /* 次の free & malloc で同じアドレスを返すことがあるので注意 */ 117| #ifndef NDEBUG 118| if ( (int)p == StdPlus_chkAdr ) { /* ここに開放されていないアドレスを記述する(1) */ 119| StdPlus_breakFunc(); 120| Errors_printf( "malloc ( %p );", p ); 121| //COUNT(0) 122| // Errors_break(1); 123| } 124| #endif 125|} 126| 127|#endif 128| 129|/*********************************************************************** 130|* 7. <<< [StdPlus_free] 拡張 free >>> 131|* 8. <<< [StdPlus_free_imp] >>> 132|*【補足】 133|*・引数に NULL を指定した場合、何もしません。 134|*・StdPlus_malloc と呼出し回数をチェックすることができるようになります。 135|* (StdPlus_chkFree 関数) 136|*・STDPLUS_PRINT_NOT_FREE を #define すると、free していないアドレスを 137|* 表示できます。(Errors_chkDefault で) 138|*・STDPLUS_USES_STDNAME を #define すると、free を StdPlus_free に 139|* 書きかえるようになります。 140|************************************************************************/ 141|#ifdef STDPLUS_USES_STDLIB 142| 143|#ifndef STDPLUS_PRINT_NOT_FREE 144| void StdPlus_free( void* p ) 145|#else 146| void StdPlus_free_imp( void* p, char* file, int line ) 147|#endif 148|{ 149| #ifdef STDPLUS_USES_STDNAME 150| #undef free 151| #endif 152| 153| if ( p != NULL ) { 154| #ifndef STDPLUS_PRINT_NOT_FREE 155| StdPlus_onFree_imp( p, NULL, 0 ); 156| #else 157| StdPlus_onFree_imp( p, file, line ); 158| #endif 159| free( p ); 160| } 161| 162| #ifdef STDPLUS_USES_STDNAME 163| #define free StdPlus_free 164| #endif 165|} 166|#endif 167| 168| 169|/*********************************************************************** 170|* 9. <<< [StdPlus_onIUnknownRelease] ON_CO_CREATE_INSTANCE の関数部 >>> 171|************************************************************************/ 172|void StdPlus_onIUnknownRelease( void* p, int hr, char* file, int line ) 173|{ 174| StdPlus_onFree_imp( p, file, line ); 175|} 176| 177|/*********************************************************************** 178|* 10. <<< [StdPlus_onFree_imp] free/delete 用・開放チェック >>> 179|*【引数】 180|* ・void* p; オブジェクトのアドレス 181|*【補足】 182|*・StdPlus_free(にオーバーライドした free)を使っているときは、 183|* 本関数が自動的に呼ばれますが、C++ では、デストラクタから呼び出す 184|* 必要があります。 185|************************************************************************/ 186|#ifdef STDPLUS_USES_STDLIB 187| 188|void StdPlus_onFree_imp( void* p, char* file, int line ) 189|{ 190| #ifdef STDPLUS_PRINT_NOT_FREE 191| StdPlus_FreeChk_setFree( StdPlus_FreeChk_getGlobl(), p, file, line ); 192| #endif 193| 194| /* デバッグ用、free した位置を知るため */ 195| /* 次の free & malloc で同じアドレスを返すことがあるので注意 */ 196| #ifndef NDEBUG 197| if ( (int)p == StdPlus_chkAdr ) /* ここに開放されていないアドレスを記述する(2) */ 198| Errors_printf( "free ( %p );", p ); /* ここにブレークポイントを張る */ 199| #endif 200| 201| StdPlus_mallocCount --; 202|} 203| 204|#endif 205| 206|/*********************************************************************** 207|* 11. <<< [StdPlus_realloc] 拡張 realloc >>> 208|* 12. <<< [StdPlus_realloc_imp] >>> 209|************************************************************************/ 210|#ifdef STDPLUS_USES_STDLIB 211| 212|#ifndef STDPLUS_PRINT_NOT_FREE 213| void* StdPlus_realloc( void* p, int size ) 214|#else 215| void* StdPlus_realloc_imp( void* p, int size, char* file, int line ) 216|#endif 217|{ 218| #ifdef STDPLUS_USES_STDNAME 219| #undef realloc 220| #endif 221| 222| if ( p != NULL ) { 223| #ifndef STDPLUS_PRINT_NOT_FREE 224| StdPlus_onFree_imp( p, NULL, 0 ); 225| #else 226| StdPlus_onFree_imp( p, file, line ); 227| #endif 228| } 229| 230| p = realloc( p, size ); 231| 232| #ifndef STDPLUS_PRINT_NOT_FREE 233| StdPlus_onMalloc_imp( p, NULL, 0 ); 234| #else 235| StdPlus_onMalloc_imp( p, file, line ); 236| #endif 237| 238| return p; 239| 240| 241| #ifdef STDPLUS_USES_STDNAME 242| #define realloc StdPlus_realloc 243| #endif 244|} 245|#endif 246| 247| 248|/*********************************************************************** 249|* 13. <<< [StdPlus_chkMalloc] malloc したアドレスをチェックする >>> 250|*【引数】 251|* ・void* p1 ...; malloc したポインタの羅列(最後は StdPlus_End) 252|* ・int 返り値; Errors_NoError か StdPlus_Err_MallocFailure 253|*【例】 254|* StdPlus_chkMalloc( ptr, ptr2, StdPlus_End ); 255|*【補足】 256|*・例外処理と StdPlus_malloc を使用すれば、本関数を使わなくても 257|* 同じことができます。 258|*・第1引数以降は malloc したポインタを並べて、最後は StdPlus_End を 259|* 指定します。 260|*・指定したポインタの中に1つでも NULL があれば、エラーになります。 261|* その際、NULL 以外のポインタを free してからエラーハンドラを呼び出します。 262|* エラーハンドラから戻ったら StdPlus_Err_MallocFailure を返します。 263|************************************************************************/ 264|#ifdef STDPLUS_USES_STDLIB 265|int StdPlus_chkMalloc( void* p1, ... ) 266|{ 267| va_list va; 268| void* p; 269| bool err = false; 270| 271| /* NULL が1つでもあるかどうか */ 272| va_start( va, p1 ); 273| for (;;) { 274| p = va_arg( va, void* ); 275| if ( p == StdPlus_End ) break; 276| if ( p == NULL ) { err = true; break; } 277| } 278| va_end( va ); 279| 280| /* NULL があれば、NULL 以外を全て free してエラー */ 281| if ( err ) { 282| va_start( va, p1 ); 283| for (;;) { 284| p = va_arg( va, void* ); 285| if ( p == StdPlus_End ) break; 286| if ( p != NULL ) free( p ); 287| } 288| va_end( va ); 289| 290| error2_0( StdPlus_Err_MallocFailure, "malloc できませんでした" ); 291| return StdPlus_Err_MallocFailure; 292| } 293| else { 294| return Errors_NoError; 295| } 296|} 297|#endif 298| 299| 300|/*********************************************************************** 301|* 14. <<< [StdPlus_chkFree] free した回数をチェックする >>> 302|*【補足】 303|*・ERRORS_FINISHCHK から呼び出されます。 304|*・通常、プログラムの最後で呼び出します。 305|*・StdPlus_malloc と StdPlus_free の呼出し回数が異なるときは、 306|* エラーになります。 307|************************************************************************/ 308|void StdPlus_chkFree() 309|{ 310| if ( StdPlus_mallocCount != 0 ) { 311| #ifdef STDPLUS_PRINT_NOT_FREE 312| StdPlus_FreeChk_printNotFree( StdPlus_FreeChk_getGlobl() ); 313| #endif 314| Errors_printf_release( "malloc と free の回数が合いません。(%+d)", 315| StdPlus_mallocCount ); 316| } 317|} 318| 319| 320|/************************************************************************* 321|* 15. <<< [StdPlus_printErrno] errno 変数の値をエラー表示する >>> 322|**************************************************************************/ 323|#if !defined(STDPLUS_NOT_ERRNO) && ( defined(STDPLUS_USES_STDLIB) || defined(USES_FILEX) ) 324|void StdPlus_printErrno() 325|{ 326| char* s = "Unknown Error"; 327| 328| switch ( errno ) { 329| case ECHILD: s = "ECHILD 子プロセスが存在しない"; break; 330| case EAGAIN: s = "EAGAIN これ以上プロセスを生成できない。"; break; 331| case E2BIG: s = "E2BIG 引数リストが長すぎる"; break; 332| case EACCES: s = "EACCES アクセスが拒否された。"; break; 333| case EBADF: s = "EBADF 不正なファイル番号。"; break; 334| case EDEADLOCK: s = "EDEADLOCK リソースのデッドロックが発生する可能性がある。"; break; 335| case EDOM: s = "EDOM 数値演算関数の引数が関数のドメイン外の値である。"; break; 336| case EEXIST: s = "EXIST ファイルが存在する。"; break; 337| case EINVAL: s = "EINVAL 不正な引数。"; break; 338| case EMFILE: s = "EMFILE 開いているファイルが多すぎる。"; break; 339| case ENOENT: s = "ENOENT ファイルまたはディレクトリがない。"; break; 340| case ENOEXEC: s = "ENOEXEC 実行ファイルのエラー。"; break; 341| case ENOMEM: s = "ENOMEM メモリ不足。"; break; 342| case ENOSPC: s = "ENOSPC デバイスの空き領域不足。"; break; 343| case ERANGE: s = "ERANGE 結果が大きすぎる。"; break; 344| case EXDEV: s = "EXDEV デバイス間リンク。"; break; 345| } 346| 347| Errors_errPrintf( "errno = %d : %s", errno, s ); 348|} 349|#endif 350| 351| 352|/************************************************************************** 353|* 16. <<< [StdPlus_itoa] 数値を文字列に変換する >>> 354|*【引数】 355|* ・int value; 数値 356|* ・char* string; 文字列を格納する領域の先頭アドレス 357|* ・int radix; 進数 358|* ・char* 返り値; string と同じ 359|*【補足】 360|*・16進数などのアルファベット文字は大文字になります。 361|*・標準ライブラリに _itoa は存在しません。 362|***************************************************************************/ 363|char* StdPlus_itoa( int value, char* string, int radix ) 364|{ 365| char* p = string; 366| char* pp; 367| int m; 368| int bMinus; 369| 370| ASSERT( 1 <= radix && radix <= 36); 371| 372| bMinus = (value < 0 ); 373| if ( bMinus ) value = -value; 374| 375| /* 下の桁から数字を格納する */ 376| if ( radix <= 10 ) { 377| do { 378| m = value % radix; 379| *p = m + '0'; 380| value /= radix; 381| p++; 382| } while ( value != 0 ); 383| } 384| else { 385| do { 386| m = value % radix; 387| *p = m + ( m < 10 ? '0' : 'A'-10 ); 388| value /= radix; 389| p++; 390| } while ( value != 0 ); 391| } 392| if ( bMinus ) { 393| *p = '-'; p++; 394| } 395| *p = '\0'; 396| 397| /* 下の桁から上の桁を入れ替える */ 398| pp = string; p--; 399| while ( pp < p ) { 400| m = *pp; *pp = *p; *p = m; 401| pp++; p--; 402| } 403| 404| return string; 405|} 406| 407| 408| 409| 410|/************************************************************************** 411|* 17. <<< [StdPlus_utoa] 数値を文字列に変換する >>> 412|*【引数】 413|* ・unsigned int value; 数値 414|* ・char* string; 文字列を格納する領域の先頭アドレス 415|* ・int radix; 進数 416|* ・char* 返り値; string と同じ 417|*【補足】 418|*・16進数などのアルファベット文字は大文字になります。 419|*・標準ライブラリに _utoa は存在しません。 420|***************************************************************************/ 421|char* StdPlus_utoa( unsigned value, char* string, int radix ) 422|{ 423| char* p = string; 424| char* pp; 425| int m; 426| 427| ASSERT( 1 <= radix && radix <= 36); 428| 429| /* 下の桁から数字を格納する */ 430| if ( radix <= 10 ) { 431| do { 432| m = value % radix; 433| *p = m + '0'; 434| value /= radix; 435| p++; 436| } while ( value != 0 ); 437| } 438| else { 439| do { 440| m = value % radix; 441| *p = m + ( m < 10 ? '0' : 'A'-10 ); 442| value /= radix; 443| p++; 444| } while ( value != 0 ); 445| } 446| *p = '\0'; 447| 448| /* 下の桁から上の桁を入れ替える */ 449| pp = string; p--; 450| while ( pp < p ) { 451| m = *pp; *pp = *p; *p = m; 452| pp++; p--; 453| } 454| 455| return string; 456|} 457| 458| 459| 460| 461|/************************************************************************** 462|* 18. <<< [StdPlus_xtoi] 16進数文字列を数値に変換する >>> 463|*【引数】 464|* ・char* hex; 16進数文字列 465|* ・int 返り値; 数値 466|***************************************************************************/ 467|int StdPlus_xtoi( char* hex ) 468|{ 469| char* s = hex; 470| int c; 471| int num = 0; 472| 473| while ( *s != '\0' ) { 474| c = *s; 475| if ( c >= '0' && c < '9' ) num = num * 16 + (c - '0'); 476| else if ( c >= 'A' && c < 'F' ) num = num * 16 + (c - 'A' + 10); 477| else if ( c >= 'a' && c < 'f' ) num = num * 16 + (c - 'a' + 10); 478| else return num; 479| s++; 480| } 481| return num; 482|} 483| 484| 485| 486|/*********************************************************************** 487|* 19. <<< [StdPlus_inputS] 文字列の初期値の入力 >>> 488|*【引数】 489|* ・char* msg; プロンプト・メッセージ 490|* ・char* out; 入力結果(出力) 491|* ・int out_size; out のサイズ 492|* ・char* def; デフォルト値 493|*【補足】 494|*・sdvex を使用しています。 495|*・BS キーで入力しなおします。 496|*・リターンキーのみで、デフォルト値が入力結果に格納されます。 497|************************************************************************/ 498|#ifdef USES_SDVEX 499|void StdPlus_inputS( const char* msg, char* out, int out_size, const char* def ) 500|{ 501| int i = 0; 502| int c; 503| printf( "%s", msg ); 504| 505| for (;;) { 506| c = inkey(); 507| if ( c == 0 ) continue; 508| else if ( c == 13 ) break; 509| #ifdef USES_ERRORS 510| else if ( c == 0x1B ) 511| error2_0( 0, "ユーザ・ブレイク" ); 512| #endif 513| else if ( c == 8 ) { 514| printf( "\n%s", msg ); 515| i = 0; 516| } 517| else { 518| if ( i < out_size - 1 ) { 519| printf( "%c", c ); 520| out[i] = c; 521| i++; 522| } 523| } 524| } 525| 526| /* 値を設定する */ 527| if ( i == 0 ) { 528| strcpy( out, def ); 529| } 530| else { 531| out[i] = '\0'; 532| } 533| printf( "\n" ); 534|} 535|#endif 536| 537| 538| 539|/*********************************************************************** 540|* 20. <<< [StdPlus_inputX] 16進数の初期値の入力 >>> 541|************************************************************************/ 542|#ifdef USES_SDVEX 543|int StdPlus_inputX( const char* msg, int def ) 544|{ 545| enum { buf_size = 9 }; 546| char buf[buf_size]; 547| 548| StdPlus_inputS( msg, buf, buf_size, "" ); 549| 550| if ( buf[0] == '\0' ) return def; 551| else return _xtoi( buf ); 552|} 553|#endif 554| 555| 556| 557|/*-----------------------------------------------------------------------*/ 558|/* 21. <<< ◆(StdPlus_FreeChk) free のし忘れを追跡するツール >>> */ 559|/*-----------------------------------------------------------------------*/ 560| 561|#ifndef ERRORS_CUT_DEBUT_TOOL 562|#ifdef STDPLUS_PRINT_NOT_FREE 563| 564|bool StdPlus_FreeChk_inited = false; 565|StdPlus_FreeChk StdPlus_FreeChk_globl; 566| 567|/*********************************************************************** 568|* 22. <<< [StdPlus_FreeChk_init] 初期化する >>> 569|*【補足】 570|*・→StdPlus_FreeChk クラスの補足 571|************************************************************************/ 572|void StdPlus_FreeChk_init( StdPlus_FreeChk* m ) 573|{ 574| StdPlus_FreeChkE* p; 575| StdPlus_FreeChkE* p_over = m->rec + StdPlus_FreeChk_Depth; 576| 577| StdPlus_FreeChk_inited = true; 578| 579| Errors_printf_release( "free し忘れの追跡ツールを起動します。" ); 580| 581| m->count = 0; 582| for ( p = m->rec; p < p_over; p++ ) { 583| p->adr = NULL; 584| } 585|} 586| 587| 588| 589|/*********************************************************************** 590|* 23. <<< [StdPlus_FreeChk_setMalloc] malloc に関する記録をする >>> 591|*【内部補足】 592|*・StdPlus_malloc の内部で呼び出されます。 593|************************************************************************/ 594|void StdPlus_FreeChk_setMalloc( StdPlus_FreeChk* m, void* adr, char* file, int line ) 595|{ 596| StdPlus_FreeChkE* p; 597| StdPlus_FreeChkE* p_over; 598| m->count ++; 599| if ( StdPlus_FreeChk_breakID == m->count ) StdPlus_breakFunc(); 600| 601| if ( ! StdPlus_FreeChk_inited ) { 602| StdPlus_FreeChk_init( &StdPlus_FreeChk_globl ); 603| // Errors_printf( "StdPlus_FreeChk_init を呼び出してください" ); 604| // error(); 605| } 606| p_over = m->rec + StdPlus_FreeChk_Depth; 607| 608| for ( p = m->rec; p < p_over; p++ ) { 609| if ( p->adr == NULL ) { 610| #if ERRORS_DEBUG_FALSE 611| Errors_printf( "malloc (%p) in %s(%d)", adr, file, line ); 612| #endif 613| p->id = m->count; p->adr = adr; p->file = file; p->line = line; 614| return; 615| } 616| } 617| error2_0( StdPlus_Err_CannotContinueCheck, 618| "StdPlus_FreeChk_Depth を大きくしてください。" ); 619|} 620| 621| 622| 623|/*********************************************************************** 624|* 24. <<< [StdPlus_FreeChk_setFree] free に関する記録をする >>> 625|*【内部補足】 626|*・StdPlus_free の内部で呼び出されます。 627|************************************************************************/ 628|void StdPlus_FreeChk_setFree( StdPlus_FreeChk* m, void* adr, char* file, int line ) 629|{ 630| StdPlus_FreeChkE* p; 631| StdPlus_FreeChkE* p_over; 632| 633| if ( ! StdPlus_FreeChk_inited ) { 634| StdPlus_FreeChk_init( &StdPlus_FreeChk_globl ); 635| //Errors_printf( "StdPlus_FreeChk_init を呼び出してください" ); 636| //error(); 637| } 638| p_over = m->rec + StdPlus_FreeChk_Depth; 639| 640| if ( adr == NULL ) { 641| error2_2( StdPlus_Err_NullFree, "NULL がフリーされました in %s(%d)", file, line ); 642| } 643| 644| for ( p = m->rec; p < p_over; p++ ) { 645| if ( p->adr == adr ) { 646| p->adr = NULL; 647| return; 648| } 649| } 650| error(); 651|} 652| 653|/*********************************************************************** 654|* 25. <<< [StdPlus_FreeChk_printNotFree] free していないアドレスを表示する >>> 655|************************************************************************/ 656|void StdPlus_FreeChk_printNotFree( StdPlus_FreeChk* m ) 657|{ 658| StdPlus_FreeChkE* p; 659| StdPlus_FreeChkE* p_over = m->rec + StdPlus_FreeChk_Depth; 660| int count = 0; 661| 662| if ( ! StdPlus_FreeChk_inited ) { 663| Errors_printf( "StdPlus_FreeChk_init を呼び出してください" ); 664| error(); 665| } 666| 667| Errors_printf( "StdPlus_FreeChk result: Not free adress is ..." ); 668| for ( p = m->rec; p < p_over; p++ ) { 669| if ( p->adr != NULL ) { 670| Errors_printf( "id = %d, adr = %p in %s(%d)", p->id, p->adr, p->file, p->line ); 671| count++; 672| if ( count == 100 ) { 673| Errors_printf( "100件を超えたので続きの表示を中止します。" ); 674| break; 675| } 676| } 677| } 678| Errors_printf( "StdPlus_FreeChk Done." ); 679|} 680| 681|#endif 682|#endif 683| 684|